All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers
@ 2020-01-08 11:41 Mika Westerberg
  2020-01-08 11:41 ` [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata Mika Westerberg
                   ` (37 more replies)
  0 siblings, 38 replies; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Hi,

Currently both intel_scu_ipc.c and intel_pmc_ipc.c implement the same SCU
IPC communications with minor differences. This duplication does not make
much sense so this series reworks the two drivers so that there is only a
single implementation of the SCU IPC. In addition to that the API will be
updated to take SCU instance pointer as an argument, and most of the
callers will be converted to this new API. The old API is left there but
the plan is to get rid the callers and then the old API as well (this is
something we are working with Andy Shevchenko).

The intel_pmc_ipc.c is then moved under MFD which suits better for this
kind of a driver that pretty much sets up the SCU IPC and then creates a
bunch of platform devices for the things sitting behind the PMC. The driver
is renamed to intel_pmc_bxt.c which should follow the existing conventions
under drivers/mfd (and it is only meant for Intel Broxton derivatives).

Previous version of the series:

  https://www.spinics.net/lists/platform-driver-x86/msg20359.html

Changes from the previous version:

  * Update changelog of patch 16 according to what the patch actually does.
  * Add kernel-doc for struct intel_soc_pmic.
  * Move octal permission patch to be before MFD conversion.
  * Convert the intel_pmc_bxt.c to MFD APIs whilst it is being moved under
    drivers/mfd.

I'm including all x86 maintainers just to be sure they are aware of this as
I'm not sure if x86@kernel.org reaches them all. Let me know if you have
issues with this series.

I would prefer this to be merged through platform/x86 or MFD trees assuming
there are no objections.

I have tested this on Intel Edison (Merrifield) and Joule (Broxton-M).

Mika Westerberg (36):
  platform/x86: intel_mid_powerbtn: Take a copy of ddata
  platform/x86: intel_scu_ipcutil: Remove default y from Kconfig
  platform/x86: intel_scu_ipc: Add constants for register offsets
  platform/x86: intel_scu_ipc: Remove Lincroft support
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl()
  platform/x86: intel_scu_ipc: Fix interrupt support
  platform/x86: intel_scu_ipc: Sleeping is fine when polling
  platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update()
  platform/x86: intel_scu_ipc: Drop unused macros
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]()
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command()
  platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver
  platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions
  platform/x86: intel_scu_ipc: Introduce new SCU IPC API
  platform/x86: intel_mid_powerbtn: Convert to use new SCU IPC API
  watchdog: intel-mid_wdt: Convert to use new SCU IPC API
  platform/x86: intel_scu_ipcutil: Convert to use new SCU IPC API
  platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static
  platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static
  platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static
  platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write()
  platform/x86: intel_pmc_ipc: Drop ipc_data_readb()
  platform/x86: intel_pmc_ipc: Get rid of unnecessary includes
  platform/x86: intel_scu_ipc: Add function to remove SCU IPC
  platform/x86: intel_pmc_ipc: Start using SCU IPC
  mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic
  mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API
  mfd: intel_soc_pmic_mrfld: Convert to use new SCU IPC API
  platform/x86: intel_telemetry: Convert to use new SCU IPC API
  platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command()
  x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]()
  platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c
  platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes
  platform/x86: intel_pmc_ipc: Convert to MFD
  mfd: intel_pmc_bxt: Switch to use driver->dev_groups
  MAINTAINERS: Update entry for Intel Broxton PMC driver

 MAINTAINERS                                   |   13 +-
 arch/x86/Kconfig                              |    2 +-
 arch/x86/include/asm/intel-mid.h              |    9 +-
 arch/x86/include/asm/intel_pmc_ipc.h          |   91 --
 arch/x86/include/asm/intel_scu_ipc.h          |  104 +-
 arch/x86/include/asm/intel_scu_ipc_legacy.h   |   76 ++
 arch/x86/include/asm/intel_telemetry.h        |    3 +
 drivers/mfd/Kconfig                           |   18 +-
 drivers/mfd/Makefile                          |    1 +
 drivers/mfd/intel_pmc_bxt.c                   |  539 +++++++++
 drivers/mfd/intel_soc_pmic_bxtwc.c            |   22 +-
 drivers/mfd/intel_soc_pmic_mrfld.c            |   10 +-
 drivers/platform/x86/Kconfig                  |   49 +-
 drivers/platform/x86/Makefile                 |    2 +-
 drivers/platform/x86/intel_mid_powerbtn.c     |   20 +-
 drivers/platform/x86/intel_pmc_ipc.c          | 1031 -----------------
 drivers/platform/x86/intel_scu_ipc.c          |  681 +++++------
 drivers/platform/x86/intel_scu_ipcutil.c      |   43 +-
 drivers/platform/x86/intel_scu_pcidrv.c       |   75 ++
 .../platform/x86/intel_telemetry_debugfs.c    |    2 +-
 drivers/platform/x86/intel_telemetry_pltdrv.c |  101 +-
 drivers/usb/typec/tcpm/Kconfig                |    2 +-
 drivers/watchdog/intel-mid_wdt.c              |   53 +-
 include/linux/mfd/intel_pmc_bxt.h             |   50 +
 include/linux/mfd/intel_soc_pmic.h            |   15 +
 25 files changed, 1319 insertions(+), 1693 deletions(-)
 delete mode 100644 arch/x86/include/asm/intel_pmc_ipc.h
 create mode 100644 arch/x86/include/asm/intel_scu_ipc_legacy.h
 create mode 100644 drivers/mfd/intel_pmc_bxt.c
 delete mode 100644 drivers/platform/x86/intel_pmc_ipc.c
 create mode 100644 drivers/platform/x86/intel_scu_pcidrv.c
 create mode 100644 include/linux/mfd/intel_pmc_bxt.h

-- 
2.24.1


^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:37   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig Mika Westerberg
                   ` (36 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The driver gets driver_data from memory that is marked as const (which
is probably put to read-only memory) and it then modifies it. This
likely causes some sort of fault to happen.

Fix this by taking a copy of the structure.

Fixes: c94a8ff14de3 ("platform/x86: intel_mid_powerbtn: make mid_pb_ddata const")
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_mid_powerbtn.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
index 292bace83f1e..6f436836fe50 100644
--- a/drivers/platform/x86/intel_mid_powerbtn.c
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -146,9 +146,10 @@ static int mid_pb_probe(struct platform_device *pdev)
 
 	input_set_capability(input, EV_KEY, KEY_POWER);
 
-	ddata = (struct mid_pb_ddata *)id->driver_data;
+	ddata = devm_kmemdup(&pdev->dev, (void *)id->driver_data,
+			     sizeof(*ddata), GFP_KERNEL);
 	if (!ddata)
-		return -ENODATA;
+		return -ENOMEM;
 
 	ddata->dev = &pdev->dev;
 	ddata->irq = irq;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
  2020-01-08 11:41 ` [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:38   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets Mika Westerberg
                   ` (35 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This driver is by no means essential for system to boot up so remove
default y from it.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 27d5b40fb717..dd4326736d11 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -997,7 +997,6 @@ config INTEL_SCU_IPC
 config INTEL_SCU_IPC_UTIL
 	tristate "Intel SCU IPC utility driver"
 	depends on INTEL_SCU_IPC
-	default y
 	---help---
 	  The IPC Util driver provides an interface with the SCU enabling
 	  low level access for debug work and updating the firmware. Say
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
  2020-01-08 11:41 ` [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata Mika Westerberg
  2020-01-08 11:41 ` [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:39   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support Mika Westerberg
                   ` (34 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This makes the code more readable. These are taken from intel_pmc_ipc.c
which implements the same thing.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index cdab916fbf92..a8be5bcb9832 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -99,11 +99,15 @@ struct intel_scu_ipc_dev {
 
 static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
 
+#define IPC_STATUS		0x04
+#define IPC_STATUS_ERR		BIT(1)
+#define IPC_STATUS_BUSY		BIT(0)
+
 /*
- * IPC Read Buffer (Read Only):
- * 16 byte buffer for receiving data from SCU, if IPC command
- * processing results in response data
+ * IPC Write/Read Buffers:
+ * 16 byte buffer for sending and receiving data to and from SCU.
  */
+#define IPC_WRITE_BUFFER	0x80
 #define IPC_READ_BUFFER		0x90
 
 #define IPC_I2C_CNTRL_ADDR	0
@@ -135,7 +139,7 @@ static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
  */
 static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32 offset)
 {
-	writel(data, scu->ipc_base + 0x80 + offset);
+	writel(data, scu->ipc_base + IPC_WRITE_BUFFER + offset);
 }
 
 /*
@@ -147,7 +151,7 @@ static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32
  */
 static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu)
 {
-	return __raw_readl(scu->ipc_base + 0x04);
+	return __raw_readl(scu->ipc_base + IPC_STATUS);
 }
 
 /* Read ipc byte data */
@@ -169,17 +173,17 @@ static inline int busy_loop(struct intel_scu_ipc_dev *scu)
 	u32 loop_count = 100000;
 
 	/* break if scu doesn't reset busy bit after huge retry */
-	while ((status & BIT(0)) && --loop_count) {
+	while ((status & IPC_STATUS_BUSY) && --loop_count) {
 		udelay(1); /* scu processing time is in few u secods */
 		status = ipc_read_status(scu);
 	}
 
-	if (status & BIT(0)) {
+	if (status & IPC_STATUS_BUSY) {
 		dev_err(scu->dev, "IPC timed out");
 		return -ETIMEDOUT;
 	}
 
-	if (status & BIT(1))
+	if (status & IPC_STATUS_ERR)
 		return -EIO;
 
 	return 0;
@@ -196,7 +200,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
 	}
 
 	status = ipc_read_status(scu);
-	if (status & BIT(1))
+	if (status & IPC_STATUS_ERR)
 		return -EIO;
 
 	return 0;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (2 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:39   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl() Mika Westerberg
                   ` (33 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Moorestown support was removed years ago with by the commit 1a8359e411eb
("x86/mid: Remove Intel Moorestown"). Lincroft is the CPU side chip of
Moorestown and not supported anymore so remove the code from the driver.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index a8be5bcb9832..6c44fe5e55b5 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -58,7 +58,6 @@
 #define IPC_RWBUF_SIZE    20		/* IPC Read buffer Size */
 #define IPC_IOC	          0x100		/* IPC command register IOC bit */
 
-#define PCI_DEVICE_ID_LINCROFT		0x082a
 #define PCI_DEVICE_ID_PENWELL		0x080e
 #define PCI_DEVICE_ID_CLOVERVIEW	0x08ea
 #define PCI_DEVICE_ID_TANGIER		0x11a0
@@ -70,12 +69,6 @@ struct intel_scu_ipc_pdata_t {
 	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,
@@ -677,7 +670,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 #define SCU_DEVICE(id, pdata)	{PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&pdata}
 
 static const struct pci_device_id pci_ids[] = {
-	SCU_DEVICE(PCI_DEVICE_ID_LINCROFT,	intel_scu_ipc_lincroft_pdata),
 	SCU_DEVICE(PCI_DEVICE_ID_PENWELL,	intel_scu_ipc_penwell_pdata),
 	SCU_DEVICE(PCI_DEVICE_ID_CLOVERVIEW,	intel_scu_ipc_penwell_pdata),
 	SCU_DEVICE(PCI_DEVICE_ID_TANGIER,	intel_scu_ipc_tangier_pdata),
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (3 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:39   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support Mika Westerberg
                   ` (32 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There are no existing users for this functionality so drop it from the
driver completely.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h |  3 --
 drivers/platform/x86/intel_scu_ipc.c | 62 ----------------------------
 2 files changed, 65 deletions(-)

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index 4a8c6e817398..d7bbebf4b729 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -53,9 +53,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
 int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
 			      u32 *out, int outlen, u32 dptr, u32 sptr);
 
-/* I2C control api */
-int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data);
-
 /* Update FW version */
 int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
 
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 6c44fe5e55b5..b39680b53387 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -64,28 +64,21 @@
 
 /* intel scu ipc driver data */
 struct intel_scu_ipc_pdata_t {
-	u32 i2c_base;
-	u32 i2c_len;
 	u8 irq_mode;
 };
 
 /* 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 {
 	struct device *dev;
 	void __iomem *ipc_base;
-	void __iomem *i2c_base;
 	struct completion cmd_complete;
 	u8 irq_mode;
 };
@@ -103,9 +96,6 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
 #define IPC_WRITE_BUFFER	0x80
 #define IPC_READ_BUFFER		0x90
 
-#define IPC_I2C_CNTRL_ADDR	0
-#define I2C_DATA_ADDR		0x04
-
 static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
 
 /*
@@ -549,54 +539,6 @@ int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
 }
 EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
 
-/* I2C commands */
-#define IPC_I2C_WRITE 1 /* I2C Write command */
-#define IPC_I2C_READ  2 /* I2C Read command */
-
-/**
- *	intel_scu_ipc_i2c_cntrl		-	I2C read/write operations
- *	@addr: I2C address + command bits
- *	@data: data to read/write
- *
- *	Perform an an I2C read/write operation via the SCU. All locking is
- *	handled for the caller. This function may sleep.
- *
- *	Returns an error code or 0 on success.
- *
- *	This has to be in the IPC driver for the locking.
- */
-int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
-{
-	struct intel_scu_ipc_dev *scu = &ipcdev;
-	u32 cmd = 0;
-
-	mutex_lock(&ipclock);
-	if (scu->dev == NULL) {
-		mutex_unlock(&ipclock);
-		return -ENODEV;
-	}
-	cmd = (addr >> 24) & 0xFF;
-	if (cmd == IPC_I2C_READ) {
-		writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
-		/* Write not getting updated without delay */
-		usleep_range(1000, 2000);
-		*data = readl(scu->i2c_base + I2C_DATA_ADDR);
-	} else if (cmd == IPC_I2C_WRITE) {
-		writel(*data, scu->i2c_base + I2C_DATA_ADDR);
-		usleep_range(1000, 2000);
-		writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
-	} else {
-		dev_err(scu->dev,
-			"intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
-
-		mutex_unlock(&ipclock);
-		return -EIO;
-	}
-	mutex_unlock(&ipclock);
-	return 0;
-}
-EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
-
 /*
  * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
  * When ioc bit is set to 1, caller api must wait for interrupt handler called
@@ -649,10 +591,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	scu->ipc_base = pcim_iomap_table(pdev)[0];
 
-	scu->i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
-	if (!scu->i2c_base)
-		return -ENOMEM;
-
 	err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
 			       scu);
 	if (err)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (4 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:40   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling Mika Westerberg
                   ` (31 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

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>
---
 drivers/platform/x86/intel_scu_ipc.c | 48 ++++++----------------------
 1 file changed, 10 insertions(+), 38 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index b39680b53387..43eaf9400c67 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -58,24 +58,6 @@
 #define IPC_RWBUF_SIZE    20		/* IPC Read buffer Size */
 #define IPC_IOC	          0x100		/* IPC command register IOC bit */
 
-#define PCI_DEVICE_ID_PENWELL		0x080e
-#define PCI_DEVICE_ID_CLOVERVIEW	0x08ea
-#define PCI_DEVICE_ID_TANGIER		0x11a0
-
-/* intel scu ipc driver data */
-struct intel_scu_ipc_pdata_t {
-	u8 irq_mode;
-};
-
-/* Penwell and Cloverview */
-static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
-	.irq_mode = 1,
-};
-
-static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
-	.irq_mode = 0,
-};
-
 struct intel_scu_ipc_dev {
 	struct device *dev;
 	void __iomem *ipc_base;
@@ -86,6 +68,7 @@ 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)
 #define IPC_STATUS_ERR		BIT(1)
 #define IPC_STATUS_BUSY		BIT(0)
 
@@ -107,11 +90,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);
 }
 
 /*
@@ -549,9 +529,10 @@ EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
 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;
 }
@@ -568,17 +549,10 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	int err;
 	struct intel_scu_ipc_dev *scu = &ipcdev;
-	struct intel_scu_ipc_pdata_t *pdata;
 
 	if (scu->dev)		/* We support only one SCU */
 		return -EBUSY;
 
-	pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data;
-	if (!pdata)
-		return -ENODEV;
-
-	scu->irq_mode = pdata->irq_mode;
-
 	err = pcim_enable_device(pdev);
 	if (err)
 		return err;
@@ -605,13 +579,11 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	return 0;
 }
 
-#define SCU_DEVICE(id, pdata)	{PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&pdata}
-
 static const struct pci_device_id pci_ids[] = {
-	SCU_DEVICE(PCI_DEVICE_ID_PENWELL,	intel_scu_ipc_penwell_pdata),
-	SCU_DEVICE(PCI_DEVICE_ID_CLOVERVIEW,	intel_scu_ipc_penwell_pdata),
-	SCU_DEVICE(PCI_DEVICE_ID_TANGIER,	intel_scu_ipc_tangier_pdata),
-	{}
+	{ PCI_VDEVICE(INTEL, 0x080e) },
+	{ PCI_VDEVICE(INTEL, 0x08ea) },
+	{ PCI_VDEVICE(INTEL, 0x11a0) },
+	{ }
 };
 
 static struct pci_driver ipc_driver = {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (5 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:12   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update() Mika Westerberg
                   ` (30 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There is no reason why the driver would need to block other threads from
running the CPU while it is waiting for the SCU IPC to complete its
work. For this reason switch the driver to use usleep_range() instead
with a bit more relaxed polling loop.

Also add constant for the timeout and use the same value for both
polling and interrupt modes.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 29 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 43eaf9400c67..8db0644900a3 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
 #define IPC_WRITE_BUFFER	0x80
 #define IPC_READ_BUFFER		0x90
 
+/* Timeout in jiffies */
+#define IPC_TIMEOUT		(3 * HZ)
+
 static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
 
 /*
@@ -132,24 +135,20 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
 /* Wait till scu status is busy */
 static inline int busy_loop(struct intel_scu_ipc_dev *scu)
 {
-	u32 status = ipc_read_status(scu);
-	u32 loop_count = 100000;
+	unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT);
 
-	/* break if scu doesn't reset busy bit after huge retry */
-	while ((status & IPC_STATUS_BUSY) && --loop_count) {
-		udelay(1); /* scu processing time is in few u secods */
-		status = ipc_read_status(scu);
-	}
+	do {
+		u32 status;
 
-	if (status & IPC_STATUS_BUSY) {
-		dev_err(scu->dev, "IPC timed out");
-		return -ETIMEDOUT;
-	}
+		status = ipc_read_status(scu);
+		if (!(status & IPC_STATUS_BUSY))
+			return (status & IPC_STATUS_ERR) ? -EIO : 0;
 
-	if (status & IPC_STATUS_ERR)
-		return -EIO;
+		usleep_range(50, 100);
+	} while (time_before(jiffies, end));
 
-	return 0;
+	dev_err(scu->dev, "IPC timed out");
+	return -ETIMEDOUT;
 }
 
 /* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
@@ -157,7 +156,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
 {
 	int status;
 
-	if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) {
+	if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) {
 		dev_err(scu->dev, "IPC timed out\n");
 		return -ETIMEDOUT;
 	}
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (6 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:41   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros Mika Westerberg
                   ` (29 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There is no implementation for that anymore so drop the prototype.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index d7bbebf4b729..b2dde96e0611 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -53,9 +53,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
 int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
 			      u32 *out, int outlen, u32 dptr, u32 sptr);
 
-/* Update FW version */
-int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
-
 extern struct blocking_notifier_head intel_scu_notifier;
 
 static inline void intel_scu_notifier_add(struct notifier_block *nb)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (7 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:41   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]() Mika Westerberg
                   ` (28 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

These macros are not used anywhere in the driver so drop them.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 8db0644900a3..997fdac920c6 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -26,11 +26,7 @@
 #include <asm/intel_scu_ipc.h>
 
 /* IPC defines the following message types */
-#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */
-#define IPCMSG_BATTERY        0xEF /* Coulomb Counter Accumulator */
-#define IPCMSG_FW_UPDATE      0xFE /* Firmware update */
-#define IPCMSG_PCNTRL         0xFF /* Power controller unit read/write */
-#define IPCMSG_FW_REVISION    0xF4 /* Get firmware revision */
+#define IPCMSG_PCNTRL         0xff /* Power controller unit read/write */
 
 /* Command id associated with message IPCMSG_PCNTRL */
 #define IPC_CMD_PCNTRL_W      0 /* Register write */
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (8 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:41   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command() Mika Westerberg
                   ` (27 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There are no users for these so we can remove them.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h | 12 -----
 drivers/platform/x86/intel_scu_ipc.c | 68 ----------------------------
 2 files changed, 80 deletions(-)

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index b2dde96e0611..b59afa59a4cb 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -22,24 +22,12 @@
 /* Read single register */
 int intel_scu_ipc_ioread8(u16 addr, u8 *data);
 
-/* Read two sequential registers */
-int intel_scu_ipc_ioread16(u16 addr, u16 *data);
-
-/* Read four sequential registers */
-int intel_scu_ipc_ioread32(u16 addr, u32 *data);
-
 /* Read a vector */
 int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
 
 /* Write single register */
 int intel_scu_ipc_iowrite8(u16 addr, u8 data);
 
-/* Write two sequential registers */
-int intel_scu_ipc_iowrite16(u16 addr, u16 data);
-
-/* Write four sequential registers */
-int intel_scu_ipc_iowrite32(u16 addr, u32 data);
-
 /* Write a vector */
 int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
 
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 997fdac920c6..ba857e54800b 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -237,40 +237,6 @@ int intel_scu_ipc_ioread8(u16 addr, u8 *data)
 }
 EXPORT_SYMBOL(intel_scu_ipc_ioread8);
 
-/**
- *	intel_scu_ipc_ioread16		-	read a word via the SCU
- *	@addr: register on SCU
- *	@data: return pointer for read word
- *
- *	Read a register pair. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
- *
- *	This function may sleep.
- */
-int intel_scu_ipc_ioread16(u16 addr, u16 *data)
-{
-	u16 x[2] = {addr, addr + 1};
-	return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
-}
-EXPORT_SYMBOL(intel_scu_ipc_ioread16);
-
-/**
- *	intel_scu_ipc_ioread32		-	read a dword via the SCU
- *	@addr: register on SCU
- *	@data: return pointer for read dword
- *
- *	Read four registers. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
- *
- *	This function may sleep.
- */
-int intel_scu_ipc_ioread32(u16 addr, u32 *data)
-{
-	u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
-	return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
-}
-EXPORT_SYMBOL(intel_scu_ipc_ioread32);
-
 /**
  *	intel_scu_ipc_iowrite8		-	write a byte via the SCU
  *	@addr: register on SCU
@@ -287,40 +253,6 @@ int intel_scu_ipc_iowrite8(u16 addr, u8 data)
 }
 EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
 
-/**
- *	intel_scu_ipc_iowrite16		-	write a word via the SCU
- *	@addr: register on SCU
- *	@data: word to write
- *
- *	Write two registers. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
- *
- *	This function may sleep.
- */
-int intel_scu_ipc_iowrite16(u16 addr, u16 data)
-{
-	u16 x[2] = {addr, addr + 1};
-	return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
-}
-EXPORT_SYMBOL(intel_scu_ipc_iowrite16);
-
-/**
- *	intel_scu_ipc_iowrite32		-	write a dword via the SCU
- *	@addr: register on SCU
- *	@data: dword to write
- *
- *	Write four registers. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
- *
- *	This function may sleep.
- */
-int intel_scu_ipc_iowrite32(u16 addr, u32 data)
-{
-	u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
-	return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
-}
-EXPORT_SYMBOL(intel_scu_ipc_iowrite32);
-
 /**
  *	intel_scu_ipc_readvv		-	read a set of registers
  *	@addr: register list
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (9 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:42   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver Mika Westerberg
                   ` (26 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There is no user for this function so we can drop it from the driver.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h |  2 -
 drivers/platform/x86/intel_scu_ipc.c | 63 ----------------------------
 2 files changed, 65 deletions(-)

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index b59afa59a4cb..2a1442ba6e78 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -38,8 +38,6 @@ int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
 int intel_scu_ipc_simple_command(int cmd, int sub);
 int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
 			  u32 *out, int outlen);
-int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
-			      u32 *out, int outlen, u32 dptr, u32 sptr);
 
 extern struct blocking_notifier_head intel_scu_notifier;
 
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index ba857e54800b..93a810fa6c8a 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -383,69 +383,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
 }
 EXPORT_SYMBOL(intel_scu_ipc_command);
 
-#define IPC_SPTR		0x08
-#define IPC_DPTR		0x0C
-
-/**
- * intel_scu_ipc_raw_command() - IPC command with data and pointers
- * @cmd:	IPC command code.
- * @sub:	IPC command sub type.
- * @in:		input data of this IPC command.
- * @inlen:	input data length in dwords.
- * @out:	output data of this IPC command.
- * @outlen:	output data length in dwords.
- * @sptr:	data writing to SPTR register.
- * @dptr:	data writing to DPTR register.
- *
- * Send an IPC command to SCU with input/output data and source/dest pointers.
- *
- * Return:	an IPC error code or 0 on success.
- */
-int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
-			      u32 *out, int outlen, u32 dptr, u32 sptr)
-{
-	struct intel_scu_ipc_dev *scu = &ipcdev;
-	int inbuflen = DIV_ROUND_UP(inlen, 4);
-	u32 inbuf[4];
-	int i, err;
-
-	/* Up to 16 bytes */
-	if (inbuflen > 4)
-		return -EINVAL;
-
-	mutex_lock(&ipclock);
-	if (scu->dev == NULL) {
-		mutex_unlock(&ipclock);
-		return -ENODEV;
-	}
-
-	writel(dptr, scu->ipc_base + IPC_DPTR);
-	writel(sptr, scu->ipc_base + IPC_SPTR);
-
-	/*
-	 * SRAM controller doesn't support 8-bit writes, it only
-	 * supports 32-bit writes, so we have to copy input data into
-	 * the temporary buffer, and SCU FW will use the inlen to
-	 * determine the actual input data length in the temporary
-	 * buffer.
-	 */
-	memcpy(inbuf, in, inlen);
-
-	for (i = 0; i < inbuflen; i++)
-		ipc_data_writel(scu, inbuf[i], 4 * i);
-
-	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(scu, 4 * i);
-	}
-
-	mutex_unlock(&ipclock);
-	return err;
-}
-EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
-
 /*
  * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
  * When ioc bit is set to 1, caller api must wait for interrupt handler called
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (10 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:22   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions Mika Westerberg
                   ` (25 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The SCU IPC functionality is usable outside of Intel MID devices. For
example modern Intel CPUs include the same thing but now it is called
PMC (Power Management Controller) instead of SCU. To make the IPC
available for those split the driver into library part (intel_scu_ipc.c)
and the SCU PCI driver part (intel_scu_pcidrv.c) which then calls the
former before it goes and creates rest of the SCU devices.

We also split the Kconfig symbols so that INTEL_SCU_IPC enables the SCU
IPC library and INTEL_SCU_PCI the SCU driver and convert the users
accordingly. While there remove default y from the INTEL_SCU_PCI symbol
as it is already selected by X86_INTEL_MID.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/Kconfig                        |  2 +-
 arch/x86/include/asm/intel_scu_ipc.h    | 15 +++++
 drivers/mfd/Kconfig                     |  4 +-
 drivers/platform/x86/Kconfig            | 26 ++++++---
 drivers/platform/x86/Makefile           |  1 +
 drivers/platform/x86/intel_scu_ipc.c    | 77 +++++++++----------------
 drivers/platform/x86/intel_scu_pcidrv.c | 61 ++++++++++++++++++++
 7 files changed, 125 insertions(+), 61 deletions(-)
 create mode 100644 drivers/platform/x86/intel_scu_pcidrv.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5e8949953660..aca17d1583c4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -594,7 +594,7 @@ config X86_INTEL_MID
 	select I2C
 	select DW_APB_TIMER
 	select APB_TIMER
-	select INTEL_SCU_IPC
+	select INTEL_SCU_PCI
 	select MFD_INTEL_MSIC
 	---help---
 	  Select to build a kernel capable of supporting Intel MID (Mobile
diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index 2a1442ba6e78..405c47bf0965 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -19,6 +19,21 @@
 	#define IPC_CMD_VRTC_SETTIME      1 /* Set time */
 	#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
 
+struct device;
+
+/**
+ * struct intel_scu_ipc_pdata - Platform data for SCU IPC
+ * @ipc_regs: IPC regs MMIO address
+ * @irq: The IRQ number used for SCU (optional)
+ */
+struct intel_scu_ipc_pdata {
+	void __iomem *ipc_regs;
+	int irq;
+};
+
+int intel_scu_ipc_probe(struct device *dev,
+			const struct intel_scu_ipc_pdata *pdata);
+
 /* Read single register */
 int intel_scu_ipc_ioread8(u16 addr, u8 *data);
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 420900852166..59515142438e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -593,7 +593,7 @@ config INTEL_SOC_PMIC_MRFLD
 	tristate "Support for Intel Merrifield Basin Cove PMIC"
 	depends on GPIOLIB
 	depends on ACPI
-	depends on INTEL_SCU_IPC
+	depends on INTEL_SCU
 	select MFD_CORE
 	select REGMAP_IRQ
 	help
@@ -625,7 +625,7 @@ config MFD_INTEL_LPSS_PCI
 
 config MFD_INTEL_MSIC
 	bool "Intel MSIC"
-	depends on INTEL_SCU_IPC
+	depends on INTEL_SCU
 	select MFD_CORE
 	help
 	  Select this option to enable access to Intel MSIC (Avatele
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index dd4326736d11..e9ba81fc1770 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -986,25 +986,33 @@ config INTEL_VBTN
 	  be called intel_vbtn.
 
 config INTEL_SCU_IPC
-	bool "Intel SCU IPC Support"
+	bool
+
+config INTEL_SCU
+	bool
+	select INTEL_SCU_IPC
+
+config INTEL_SCU_PCI
+	bool "Intel SCU PCI driver"
 	depends on X86_INTEL_MID
-	default y
-	---help---
-	  IPC is used to bridge the communications between kernel and SCU on
-	  some embedded Intel x86 platforms. This is not needed for PC-type
-	  machines.
+	select INTEL_SCU
+	help
+	  SCU is used to bridge the communications between kernel and
+	  SCU on some embedded Intel x86 platforms. It also creates
+	  devices that are connected to the SoC through the SCU. This is
+	  not needed for PC-type machines.
 
 config INTEL_SCU_IPC_UTIL
 	tristate "Intel SCU IPC utility driver"
-	depends on INTEL_SCU_IPC
-	---help---
+	depends on INTEL_SCU
+	help
 	  The IPC Util driver provides an interface with the SCU enabling
 	  low level access for debug work and updating the firmware. Say
 	  N unless you will be doing this on an Intel MID platform.
 
 config INTEL_MID_POWER_BUTTON
 	tristate "power button driver for Intel MID platforms"
-	depends on INTEL_SCU_IPC && INPUT
+	depends on INTEL_SCU && INPUT
 	help
 	  This driver handles the power button on the Intel MID platforms.
 
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 42d85a00be4e..c7a42feaa521 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -68,6 +68,7 @@ intel_cht_int33fe-objs		:= intel_cht_int33fe_common.o \
 obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
 obj-$(CONFIG_INTEL_HID_EVENT)	+= intel-hid.o
 obj-$(CONFIG_INTEL_VBTN)	+= intel-vbtn.o
+obj-$(CONFIG_INTEL_SCU_PCI)	+= intel_scu_pcidrv.o
 obj-$(CONFIG_INTEL_SCU_IPC)	+= intel_scu_ipc.o
 obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
 obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 93a810fa6c8a..e3f658f1b40a 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -18,11 +18,8 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/sfi.h>
+#include <linux/io.h>
 
-#include <asm/intel-mid.h>
 #include <asm/intel_scu_ipc.h>
 
 /* IPC defines the following message types */
@@ -58,7 +55,7 @@ struct intel_scu_ipc_dev {
 	struct device *dev;
 	void __iomem *ipc_base;
 	struct completion cmd_complete;
-	u8 irq_mode;
+	int irq;
 };
 
 static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
@@ -166,7 +163,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
 
 static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
 {
-	return scu->irq_mode ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
+	return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
 }
 
 /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
@@ -402,60 +399,42 @@ static irqreturn_t ioc(int irq, void *dev_id)
 }
 
 /**
- *	ipc_probe	-	probe an Intel SCU IPC
- *	@pdev: the PCI device matching
- *	@id: entry in the match table
+ * intel_scu_ipc_probe() - Initializes SCU IPC mechanism
+ * @dev: SCU device
+ * @pdata: Platform specific data
  *
- *	Enable and install an intel SCU IPC. This appears in the PCI space
- *	but uses some hard coded addresses as well.
+ * Call this function to initialize SCU IPC mechanism. It is removed
+ * automatically when the calling driver is unbound from @dev.
  */
-static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+int intel_scu_ipc_probe(struct device *dev,
+			const struct intel_scu_ipc_pdata *pdata)
 {
 	int err;
 	struct intel_scu_ipc_dev *scu = &ipcdev;
 
-	if (scu->dev)		/* We support only one SCU */
+	mutex_lock(&ipclock);
+	/* We support only one IPC */
+	if (scu->dev) {
+		mutex_unlock(&ipclock);
 		return -EBUSY;
+	}
 
-	err = pcim_enable_device(pdev);
-	if (err)
-		return err;
-
-	err = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
-	if (err)
-		return err;
-
+	scu->ipc_base = pdata->ipc_regs;
+	scu->irq = pdata->irq;
 	init_completion(&scu->cmd_complete);
 
-	scu->ipc_base = pcim_iomap_table(pdev)[0];
-
-	err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
-			       scu);
-	if (err)
-		return err;
+	if (scu->irq > 0) {
+		err = devm_request_irq(dev, scu->irq, ioc, 0, "intel_scu_ipc",
+				       scu);
+		if (err)
+			goto unlock;
+	}
 
 	/* Assign device at last */
-	scu->dev = &pdev->dev;
-
-	intel_scu_devices_create();
+	scu->dev = dev;
 
-	pci_set_drvdata(pdev, scu);
-	return 0;
+unlock:
+	mutex_unlock(&ipclock);
+	return err;
 }
-
-static const struct pci_device_id pci_ids[] = {
-	{ PCI_VDEVICE(INTEL, 0x080e) },
-	{ PCI_VDEVICE(INTEL, 0x08ea) },
-	{ PCI_VDEVICE(INTEL, 0x11a0) },
-	{ }
-};
-
-static struct pci_driver ipc_driver = {
-	.driver = {
-		.suppress_bind_attrs = true,
-	},
-	.name = "intel_scu_ipc",
-	.id_table = pci_ids,
-	.probe = ipc_probe,
-};
-builtin_pci_driver(ipc_driver);
+EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
new file mode 100644
index 000000000000..47dd4d85bf2a
--- /dev/null
+++ b/drivers/platform/x86/intel_scu_pcidrv.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI driver for the Intel SCU.
+ *
+ * Copyright (C) 2008-2010, 2015, 2020 Intel Corporation
+ * Authors: Sreedhara DS (sreedhara.ds@intel.com)
+ *	    Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/intel-mid.h>
+#include <asm/intel_scu_ipc.h>
+
+static int intel_scu_pci_probe(struct pci_dev *pdev,
+			       const struct pci_device_id *id)
+{
+	struct intel_scu_ipc_pdata *pdata;
+	int ret;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	ret = pcim_enable_device(pdev);
+	if (ret)
+		return ret;
+
+	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
+	if (ret)
+		return ret;
+
+	pdata->ipc_regs = pcim_iomap_table(pdev)[0];
+	pdata->irq = pdev->irq;
+
+	ret = intel_scu_ipc_probe(&pdev->dev, pdata);
+	if (ret)
+		return ret;
+
+	intel_scu_devices_create();
+	return 0;
+}
+
+static const struct pci_device_id pci_ids[] = {
+	{ PCI_VDEVICE(INTEL, 0x080e) },
+	{ PCI_VDEVICE(INTEL, 0x08ea) },
+	{ PCI_VDEVICE(INTEL, 0x11a0) },
+	{}
+};
+
+static struct pci_driver intel_scu_pci_driver = {
+	.driver = {
+		.suppress_bind_attrs = true,
+	},
+	.name = "intel_scu",
+	.id_table = pci_ids,
+	.probe = intel_scu_pci_probe,
+};
+builtin_pci_driver(intel_scu_pci_driver);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (11 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:42   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API Mika Westerberg
                   ` (24 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Format kernel-doc comments of the exported functions to follow the
typical format that does not have tab indentation. Also capitalize
parameter descriptions and add a missing period.

No functional changes intended.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 112 +++++++++++++--------------
 1 file changed, 55 insertions(+), 57 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index e3f658f1b40a..b1ac381bb7dd 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -219,14 +219,14 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 }
 
 /**
- *	intel_scu_ipc_ioread8		-	read a word via the SCU
- *	@addr: register on SCU
- *	@data: return pointer for read byte
+ * intel_scu_ipc_ioread8		-	read a word via the SCU
+ * @addr: Register on SCU
+ * @data: Return pointer for read byte
  *
- *	Read a single register. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
+ * Read a single register. Returns %0 on success or an error code. All
+ * locking between SCU accesses is handled for the caller.
  *
- *	This function may sleep.
+ * This function may sleep.
  */
 int intel_scu_ipc_ioread8(u16 addr, u8 *data)
 {
@@ -235,14 +235,14 @@ int intel_scu_ipc_ioread8(u16 addr, u8 *data)
 EXPORT_SYMBOL(intel_scu_ipc_ioread8);
 
 /**
- *	intel_scu_ipc_iowrite8		-	write a byte via the SCU
- *	@addr: register on SCU
- *	@data: byte to write
+ * intel_scu_ipc_iowrite8		-	write a byte via the SCU
+ * @addr: Register on SCU
+ * @data: Byte to write
  *
- *	Write a single register. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
+ * Write a single register. Returns %0 on success or an error code. All
+ * locking between SCU accesses is handled for the caller.
  *
- *	This function may sleep.
+ * This function may sleep.
  */
 int intel_scu_ipc_iowrite8(u16 addr, u8 data)
 {
@@ -251,17 +251,17 @@ int intel_scu_ipc_iowrite8(u16 addr, u8 data)
 EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
 
 /**
- *	intel_scu_ipc_readvv		-	read a set of registers
- *	@addr: register list
- *	@data: bytes to return
- *	@len: length of array
+ * intel_scu_ipc_readvv		-	read a set of registers
+ * @addr: Register list
+ * @data: Bytes to return
+ * @len: Length of array
  *
- *	Read registers. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
+ * Read registers. Returns %0 on success or an error code. All locking
+ * between SCU accesses is handled for the caller.
  *
- *	The largest array length permitted by the hardware is 5 items.
+ * The largest array length permitted by the hardware is 5 items.
  *
- *	This function may sleep.
+ * This function may sleep.
  */
 int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
 {
@@ -270,18 +270,17 @@ int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
 EXPORT_SYMBOL(intel_scu_ipc_readv);
 
 /**
- *	intel_scu_ipc_writev		-	write a set of registers
- *	@addr: register list
- *	@data: bytes to write
- *	@len: length of array
+ * intel_scu_ipc_writev		-	write a set of registers
+ * @addr: Register list
+ * @data: Bytes to write
+ * @len: Length of array
  *
- *	Write registers. Returns 0 on success or an error code. All
- *	locking between SCU accesses is handled for the caller.
+ * Write registers. Returns %0 on success or an error code. All locking
+ * between SCU accesses is handled for the caller.
  *
- *	The largest array length permitted by the hardware is 5 items.
- *
- *	This function may sleep.
+ * The largest array length permitted by the hardware is 5 items.
  *
+ * This function may sleep.
  */
 int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
 {
@@ -290,19 +289,18 @@ int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
 EXPORT_SYMBOL(intel_scu_ipc_writev);
 
 /**
- *	intel_scu_ipc_update_register	-	r/m/w a register
- *	@addr: register address
- *	@bits: bits to update
- *	@mask: mask of bits to update
+ * intel_scu_ipc_update_register	-	r/m/w a register
+ * @addr: Register address
+ * @bits: Bits to update
+ * @mask: Mask of bits to update
  *
- *	Read-modify-write power control unit register. The first data argument
- *	must be register value and second is mask value
- *	mask is a bitmap that indicates which bits to update.
- *	0 = masked. Don't modify this bit, 1 = modify this bit.
- *	returns 0 on success or an error code.
+ * Read-modify-write power control unit register. The first data argument
+ * must be register value and second is mask value mask is a bitmap that
+ * indicates which bits to update. %0 = masked. Don't modify this bit, %1 =
+ * modify this bit. returns %0 on success or an error code.
  *
- *	This function may sleep. Locking between SCU accesses is handled
- *	for the caller.
+ * This function may sleep. Locking between SCU accesses is handled
+ * for the caller.
  */
 int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
 {
@@ -312,16 +310,16 @@ int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
 EXPORT_SYMBOL(intel_scu_ipc_update_register);
 
 /**
- *	intel_scu_ipc_simple_command	-	send a simple command
- *	@cmd: command
- *	@sub: sub type
+ * intel_scu_ipc_simple_command	-	send a simple command
+ * @cmd: Command
+ * @sub: Sub type
  *
- *	Issue a simple command to the SCU. Do not use this interface if
- *	you must then access data as any data values may be overwritten
- *	by another SCU access by the time this function returns.
+ * Issue a simple command to the SCU. Do not use this interface if you must
+ * then access data as any data values may be overwritten by another SCU
+ * access by the time this function returns.
  *
- *	This function may sleep. Locking for SCU accesses is handled for
- *	the caller.
+ * This function may sleep. Locking for SCU accesses is handled for the
+ * caller.
  */
 int intel_scu_ipc_simple_command(int cmd, int sub)
 {
@@ -341,16 +339,16 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
 EXPORT_SYMBOL(intel_scu_ipc_simple_command);
 
 /**
- *	intel_scu_ipc_command	-	command with data
- *	@cmd: command
- *	@sub: sub type
- *	@in: input data
- *	@inlen: input length in dwords
- *	@out: output data
- *	@outlein: output length in dwords
+ * intel_scu_ipc_command	-	command with data
+ * @cmd: Command
+ * @sub: Sub type
+ * @in: Input data
+ * @inlen: Input length in dwords
+ * @out: Output data
+ * @outlen: Output length in dwords
  *
- *	Issue a command to the SCU which involves data transfers. Do the
- *	data copies under the lock but leave it for the caller to interpret
+ * Issue a command to the SCU which involves data transfers. Do the
+ * data copies under the lock but leave it for the caller to interpret.
  */
 int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
 			  u32 *out, int outlen)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (12 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-09 11:30   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use " Mika Westerberg
                   ` (23 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The current SCU IPC API has been operating on a single instance and
there has been no way to pin the providing module in place when the SCU
IPC is in use.

This implements a new API that takes the SCU IPC instance as first
parameter (NULL means the single instance is being used). The SCU IPC
instance can be retrieved by calling new function
intel_scu_ipc_dev_get() that take care of pinning the providing module
in place as long as intel_scu_ipc_dev_put() is not called.

The old API is left there to support existing users which cannot be
converted easily but it is put to a separate header that is subject to
be removed eventually. Subsequent patches will convert most of the users
to the new API.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h        |  74 +++----
 arch/x86/include/asm/intel_scu_ipc_legacy.h |  76 +++++++
 drivers/platform/x86/intel_scu_ipc.c        | 228 +++++++++++++++-----
 drivers/platform/x86/intel_scu_pcidrv.c     |   7 +-
 4 files changed, 291 insertions(+), 94 deletions(-)
 create mode 100644 arch/x86/include/asm/intel_scu_ipc_legacy.h

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index 405c47bf0965..9895b60386c5 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -1,8 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _ASM_X86_INTEL_SCU_IPC_H_
-#define  _ASM_X86_INTEL_SCU_IPC_H_
-
-#include <linux/notifier.h>
+#define _ASM_X86_INTEL_SCU_IPC_H_
 
 #define IPCMSG_INDIRECT_READ	0x02
 #define IPCMSG_INDIRECT_WRITE	0x05
@@ -20,6 +18,7 @@
 	#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
 
 struct device;
+struct intel_scu_ipc_dev;
 
 /**
  * struct intel_scu_ipc_pdata - Platform data for SCU IPC
@@ -31,47 +30,38 @@ struct intel_scu_ipc_pdata {
 	int irq;
 };
 
-int intel_scu_ipc_probe(struct device *dev,
-			const struct intel_scu_ipc_pdata *pdata);
-
-/* Read single register */
-int intel_scu_ipc_ioread8(u16 addr, u8 *data);
-
-/* Read a vector */
-int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
-
-/* Write single register */
-int intel_scu_ipc_iowrite8(u16 addr, u8 data);
-
-/* Write a vector */
-int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
-
-/* Update single register based on the mask */
-int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
-
-/* Issue commands to the SCU with or without data */
-int intel_scu_ipc_simple_command(int cmd, int sub);
-int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
-			  u32 *out, int outlen);
-
-extern struct blocking_notifier_head intel_scu_notifier;
-
-static inline void intel_scu_notifier_add(struct notifier_block *nb)
-{
-	blocking_notifier_chain_register(&intel_scu_notifier, nb);
-}
-
-static inline void intel_scu_notifier_remove(struct notifier_block *nb)
-{
-	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
-}
-
-static inline int intel_scu_notifier_post(unsigned long v, void *p)
+struct intel_scu_ipc_dev *
+intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata);
+
+struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void);
+void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu);
+struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev);
+
+int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr,
+			      u8 *data);
+int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr,
+			       u8 data);
+int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr,
+			    u8 *data, size_t len);
+int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr,
+			     u8 *data, size_t len);
+int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 data,
+			     u8 mask);
+
+int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
+				     int sub);
+int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
+					int sub, const void *in, size_t inlen,
+					size_t size, void *out, size_t outlen);
+
+static inline int intel_scu_ipc_dev_command(struct intel_scu_ipc_dev *scu, int cmd,
+					    int sub, const void *in, size_t inlen,
+					    void *out, size_t outlen)
 {
-	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
+	return intel_scu_ipc_dev_command_with_size(scu, cmd, sub, in, inlen,
+						   inlen, out, outlen);
 }
 
-#define		SCU_AVAILABLE		1
-#define		SCU_DOWN		2
+#include <asm/intel_scu_ipc_legacy.h>
 
 #endif
diff --git a/arch/x86/include/asm/intel_scu_ipc_legacy.h b/arch/x86/include/asm/intel_scu_ipc_legacy.h
new file mode 100644
index 000000000000..3399ea8eea48
--- /dev/null
+++ b/arch/x86/include/asm/intel_scu_ipc_legacy.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
+#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
+
+#include <linux/notifier.h>
+
+/* Don't call these in new code - they will be removed eventually */
+
+/* Read single register */
+static inline int intel_scu_ipc_ioread8(u16 addr, u8 *data)
+{
+	return intel_scu_ipc_dev_ioread8(NULL, addr, data);
+}
+
+/* Read a vector */
+static inline int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
+{
+	return intel_scu_ipc_dev_readv(NULL, addr, data, len);
+}
+
+/* Write single register */
+static inline int intel_scu_ipc_iowrite8(u16 addr, u8 data)
+{
+	return intel_scu_ipc_dev_iowrite8(NULL, addr, data);
+}
+
+/* Write a vector */
+static inline int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
+{
+	return intel_scu_ipc_dev_writev(NULL, addr, data, len);
+}
+
+/* Update single register based on the mask */
+static inline int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask)
+{
+	return intel_scu_ipc_dev_update(NULL, addr, data, mask);
+}
+
+/* Issue commands to the SCU with or without data */
+static inline int intel_scu_ipc_simple_command(int cmd, int sub)
+{
+	return intel_scu_ipc_dev_simple_command(NULL, cmd, sub);
+}
+
+static inline int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
+					u32 *out, int outlen)
+{
+	/* New API takes both inlen and outlen as bytes so convert here */
+	size_t inbytes = inlen * sizeof(u32);
+	size_t outbytes = outlen * sizeof(u32);
+
+	return intel_scu_ipc_dev_command_with_size(NULL, cmd, sub, in, inbytes,
+						   inlen, out, outbytes);
+}
+
+extern struct blocking_notifier_head intel_scu_notifier;
+
+static inline void intel_scu_notifier_add(struct notifier_block *nb)
+{
+	blocking_notifier_chain_register(&intel_scu_notifier, nb);
+}
+
+static inline void intel_scu_notifier_remove(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
+}
+
+static inline int intel_scu_notifier_post(unsigned long v, void *p)
+{
+	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
+}
+
+#define		SCU_AVAILABLE		1
+#define		SCU_DOWN		2
+
+#endif
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index b1ac381bb7dd..cc29f504adcf 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <asm/intel_scu_ipc.h>
 
@@ -77,6 +78,99 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
 
 static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
 
+/**
+ * intel_scu_ipc_dev_get() - Get SCU IPC instance
+ *
+ * The recommended new API takes SCU IPC instance as parameter and this
+ * function can be called by driver to get the instance. This also makes
+ * sure the driver providing the IPC functionality cannot be unloaded
+ * while the caller has the intance.
+ *
+ * Call intel_scu_ipc_dev_put() to release the instance.
+ *
+ * Returns %NULL if SCU IPC is not currently available.
+ */
+struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void)
+{
+	struct intel_scu_ipc_dev *scu = &ipcdev;
+
+	mutex_lock(&ipclock);
+	if (!scu->dev)
+		goto err_unlock;
+	if (!try_module_get(scu->dev->driver->owner))
+		goto err_unlock;
+	mutex_unlock(&ipclock);
+	return scu;
+
+err_unlock:
+	mutex_unlock(&ipclock);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_get);
+
+/**
+ * intel_scu_ipc_dev_put() - Put SCU IPC instance
+ * @scu: SCU IPC instance
+ *
+ * This function releases the SCU IPC instance retrieved from
+ * intel_scu_ipc_dev_get() and allows the driver providing IPC to be
+ * unloaded.
+ */
+void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu)
+{
+	mutex_lock(&ipclock);
+	if (scu->dev)
+		module_put(scu->dev->driver->owner);
+	mutex_unlock(&ipclock);
+}
+EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_put);
+
+struct intel_scu_ipc_devres {
+	struct intel_scu_ipc_dev *scu;
+};
+
+static void devm_intel_scu_ipc_dev_release(struct device *dev, void *res)
+{
+	struct intel_scu_ipc_devres *devres = res;
+	struct intel_scu_ipc_dev *scu = devres->scu;
+
+	intel_scu_ipc_dev_put(scu);
+}
+
+/**
+ * devm_intel_scu_ipc_dev_get() - Allocate managed SCU IPC device
+ * @dev: Device requesting the SCU IPC device
+ *
+ * The recommended new API takes SCU IPC instance as parameter and this
+ * function can be called by driver to get the instance. This also makes
+ * sure the driver providing the IPC functionality cannot be unloaded
+ * while the caller has the intance.
+ *
+ * Returns %NULL if SCU IPC is not currently available.
+ */
+struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev)
+{
+	struct intel_scu_ipc_devres *devres;
+	struct intel_scu_ipc_dev *scu;
+
+	devres = devres_alloc(devm_intel_scu_ipc_dev_release, sizeof(*devres),
+			      GFP_KERNEL);
+	if (!devres)
+		return NULL;
+
+	scu = intel_scu_ipc_dev_get();
+	if (!scu) {
+		devres_free(devres);
+		return NULL;
+	}
+
+	devres->scu = scu;
+	devres_add(dev, devres);
+
+	return scu;
+}
+EXPORT_SYMBOL_GPL(devm_intel_scu_ipc_dev_get);
+
 /*
  * Send ipc command
  * Command Register (Write Only):
@@ -167,15 +261,18 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *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)
+static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
+			u32 count, u32 op, u32 id)
 {
-	struct intel_scu_ipc_dev *scu = &ipcdev;
 	int nc;
 	u32 offset = 0;
 	int err;
 	u8 cbuf[IPC_WWBUF_SIZE];
 	u32 *wbuf = (u32 *)&cbuf;
 
+	if (!scu)
+		scu = &ipcdev;
+
 	memset(cbuf, 0, sizeof(cbuf));
 
 	mutex_lock(&ipclock);
@@ -219,7 +316,8 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 }
 
 /**
- * intel_scu_ipc_ioread8		-	read a word via the SCU
+ * intel_scu_ipc_dev_ioread8() - Read a byte via the SCU
+ * @scu: Optional SCU IPC instance
  * @addr: Register on SCU
  * @data: Return pointer for read byte
  *
@@ -228,14 +326,15 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
  *
  * This function may sleep.
  */
-int intel_scu_ipc_ioread8(u16 addr, u8 *data)
+int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr, u8 *data)
 {
-	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
+	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
 }
-EXPORT_SYMBOL(intel_scu_ipc_ioread8);
+EXPORT_SYMBOL(intel_scu_ipc_dev_ioread8);
 
 /**
- * intel_scu_ipc_iowrite8		-	write a byte via the SCU
+ * intel_scu_ipc_dev_iowrite8() - Write a byte via the SCU
+ * @scu: Optional SCU IPC instance
  * @addr: Register on SCU
  * @data: Byte to write
  *
@@ -244,14 +343,15 @@ EXPORT_SYMBOL(intel_scu_ipc_ioread8);
  *
  * This function may sleep.
  */
-int intel_scu_ipc_iowrite8(u16 addr, u8 data)
+int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr, u8 data)
 {
-	return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
+	return pwr_reg_rdwr(scu, &addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
 }
-EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
+EXPORT_SYMBOL(intel_scu_ipc_dev_iowrite8);
 
 /**
- * intel_scu_ipc_readvv		-	read a set of registers
+ * intel_scu_ipc_dev_readv() - Read a set of registers
+ * @scu: Optional SCU IPC instance
  * @addr: Register list
  * @data: Bytes to return
  * @len: Length of array
@@ -263,14 +363,16 @@ EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
  *
  * This function may sleep.
  */
-int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
+int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
+			    size_t len)
 {
-	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
+	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
 }
-EXPORT_SYMBOL(intel_scu_ipc_readv);
+EXPORT_SYMBOL(intel_scu_ipc_dev_readv);
 
 /**
- * intel_scu_ipc_writev		-	write a set of registers
+ * intel_scu_ipc_dev_writev() - Write a set of registers
+ * @scu: Optional SCU IPC instance
  * @addr: Register list
  * @data: Bytes to write
  * @len: Length of array
@@ -282,14 +384,16 @@ EXPORT_SYMBOL(intel_scu_ipc_readv);
  *
  * This function may sleep.
  */
-int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
+int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
+			     size_t len)
 {
-	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
+	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
 }
-EXPORT_SYMBOL(intel_scu_ipc_writev);
+EXPORT_SYMBOL(intel_scu_ipc_dev_writev);
 
 /**
- * intel_scu_ipc_update_register	-	r/m/w a register
+ * intel_scu_ipc_dev_update() - Update a register
+ * @scu: Optional SCU IPC instance
  * @addr: Register address
  * @bits: Bits to update
  * @mask: Mask of bits to update
@@ -302,15 +406,17 @@ EXPORT_SYMBOL(intel_scu_ipc_writev);
  * This function may sleep. Locking between SCU accesses is handled
  * for the caller.
  */
-int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
+int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 bits,
+			     u8 mask)
 {
 	u8 data[2] = { bits, mask };
-	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
+	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
 }
-EXPORT_SYMBOL(intel_scu_ipc_update_register);
+EXPORT_SYMBOL(intel_scu_ipc_dev_update);
 
 /**
- * intel_scu_ipc_simple_command	-	send a simple command
+ * intel_scu_ipc_dev_simple_command() - Send a simple command
+ * @scu: Optional SCU IPC instance
  * @cmd: Command
  * @sub: Sub type
  *
@@ -321,11 +427,14 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register);
  * This function may sleep. Locking for SCU accesses is handled for the
  * caller.
  */
-int intel_scu_ipc_simple_command(int cmd, int sub)
+int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
+				     int sub)
 {
-	struct intel_scu_ipc_dev *scu = &ipcdev;
 	int err;
 
+	if (!scu)
+		scu = &ipcdev;
+
 	mutex_lock(&ipclock);
 	if (scu->dev == NULL) {
 		mutex_unlock(&ipclock);
@@ -336,47 +445,65 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
 	mutex_unlock(&ipclock);
 	return err;
 }
-EXPORT_SYMBOL(intel_scu_ipc_simple_command);
+EXPORT_SYMBOL(intel_scu_ipc_dev_simple_command);
 
 /**
- * intel_scu_ipc_command	-	command with data
+ * intel_scu_ipc_command_with_size() - Command with data
+ * @scu: Optional SCU IPC instance
  * @cmd: Command
  * @sub: Sub type
  * @in: Input data
- * @inlen: Input length in dwords
+ * @inlen: Input length in bytes
+ * @size: Input size written to the IPC command register in whatever
+ *	  units (dword, byte) the particular firmware requires. Normally
+ *	  should be the same as @inlen.
  * @out: Output data
- * @outlen: Output length in dwords
+ * @outlen: Output length in bytes
  *
  * Issue a command to the SCU which involves data transfers. Do the
  * data copies under the lock but leave it for the caller to interpret.
  */
-int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
-			  u32 *out, int outlen)
+int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
+					int sub, const void *in, size_t inlen,
+					size_t size, void *out, size_t outlen)
 {
-	struct intel_scu_ipc_dev *scu = &ipcdev;
+	size_t outbuflen = DIV_ROUND_UP(outlen, sizeof(u32));
+	size_t inbuflen = DIV_ROUND_UP(inlen, sizeof(u32));
+	u32 inbuf[4] = {};
 	int i, err;
 
+	if (inbuflen > 4 || outbuflen > 4)
+		return -EINVAL;
+
+	if (!scu)
+		scu = &ipcdev;
+
 	mutex_lock(&ipclock);
 	if (scu->dev == NULL) {
 		mutex_unlock(&ipclock);
 		return -ENODEV;
 	}
 
-	for (i = 0; i < inlen; i++)
-		ipc_data_writel(scu, *in++, 4 * i);
+	memcpy(inbuf, in, inlen);
+	for (i = 0; i < inbuflen; i++)
+		ipc_data_writel(scu, inbuf[i], 4 * i);
 
-	ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
+	ipc_command(scu, (size << 16) | (sub << 12) | cmd);
 	err = intel_scu_ipc_check_status(scu);
 
-	if (!err) {
-		for (i = 0; i < outlen; i++)
-			*out++ = ipc_data_readl(scu, 4 * i);
+	if (!err && outlen) {
+		u32 outbuf[4] = {};
+
+		for (i = 0; i < outbuflen; i++)
+			outbuf[i] = ipc_data_readl(scu, 4 * i);
+
+		memcpy(out, outbuf, outlen);
 	}
 
 	mutex_unlock(&ipclock);
 	return err;
 }
-EXPORT_SYMBOL(intel_scu_ipc_command);
+EXPORT_SYMBOL(intel_scu_ipc_dev_command_with_size);
 
 /*
  * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
@@ -401,20 +528,20 @@ static irqreturn_t ioc(int irq, void *dev_id)
  * @dev: SCU device
  * @pdata: Platform specific data
  *
- * Call this function to initialize SCU IPC mechanism. It is removed
- * automatically when the calling driver is unbound from @dev.
+ * Call this function to initialize SCU IPC mechanism. Returns SCU IPC
+ * instance or ERR_PTR() if there was an error. The caller may use the
+ * returned instance if it needs to do SCU IPC calls itself.
  */
-int intel_scu_ipc_probe(struct device *dev,
-			const struct intel_scu_ipc_pdata *pdata)
+struct intel_scu_ipc_dev *
+intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata)
 {
-	int err;
 	struct intel_scu_ipc_dev *scu = &ipcdev;
 
 	mutex_lock(&ipclock);
 	/* We support only one IPC */
 	if (scu->dev) {
 		mutex_unlock(&ipclock);
-		return -EBUSY;
+		return ERR_PTR(-EBUSY);
 	}
 
 	scu->ipc_base = pdata->ipc_regs;
@@ -422,17 +549,20 @@ int intel_scu_ipc_probe(struct device *dev,
 	init_completion(&scu->cmd_complete);
 
 	if (scu->irq > 0) {
+		int err;
+
 		err = devm_request_irq(dev, scu->irq, ioc, 0, "intel_scu_ipc",
 				       scu);
-		if (err)
-			goto unlock;
+		if (err) {
+			mutex_unlock(&ipclock);
+			return ERR_PTR(err);
+		}
 	}
 
 	/* Assign device at last */
 	scu->dev = dev;
 
-unlock:
 	mutex_unlock(&ipclock);
-	return err;
+	return scu;
 }
 EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
index 47dd4d85bf2a..42030bdb3e08 100644
--- a/drivers/platform/x86/intel_scu_pcidrv.c
+++ b/drivers/platform/x86/intel_scu_pcidrv.c
@@ -18,6 +18,7 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
 			       const struct pci_device_id *id)
 {
 	struct intel_scu_ipc_pdata *pdata;
+	struct intel_scu_ipc_dev *scu;
 	int ret;
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -35,9 +36,9 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
 	pdata->ipc_regs = pcim_iomap_table(pdev)[0];
 	pdata->irq = pdev->irq;
 
-	ret = intel_scu_ipc_probe(&pdev->dev, pdata);
-	if (ret)
-		return ret;
+	scu = intel_scu_ipc_probe(&pdev->dev, pdata);
+	if (IS_ERR(scu))
+		return PTR_ERR(scu);
 
 	intel_scu_devices_create();
 	return 0;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (13 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:43   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 16/36] watchdog: intel-mid_wdt: " Mika Westerberg
                   ` (22 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This converts the power button driver to use the new SCU IPC API where
the SCU IPC instance is passed to the functions.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_mid_powerbtn.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
index 6f436836fe50..1fdcdef1d89f 100644
--- a/drivers/platform/x86/intel_mid_powerbtn.c
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -46,6 +46,7 @@ struct mid_pb_ddata {
 	unsigned short mirqlvl1_addr;
 	unsigned short pbstat_addr;
 	u8 pbstat_mask;
+	struct intel_scu_ipc_dev *scu;
 	int (*setup)(struct mid_pb_ddata *ddata);
 };
 
@@ -55,7 +56,8 @@ static int mid_pbstat(struct mid_pb_ddata *ddata, int *value)
 	int ret;
 	u8 pbstat;
 
-	ret = intel_scu_ipc_ioread8(ddata->pbstat_addr, &pbstat);
+	ret = intel_scu_ipc_dev_ioread8(ddata->scu, ddata->pbstat_addr,
+					&pbstat);
 	if (ret)
 		return ret;
 
@@ -67,14 +69,15 @@ static int mid_pbstat(struct mid_pb_ddata *ddata, int *value)
 
 static int mid_irq_ack(struct mid_pb_ddata *ddata)
 {
-	return intel_scu_ipc_update_register(ddata->mirqlvl1_addr, 0, MSIC_PWRBTNM);
+	return intel_scu_ipc_dev_update(ddata->scu, ddata->mirqlvl1_addr, 0,
+					MSIC_PWRBTNM);
 }
 
 static int mrfld_setup(struct mid_pb_ddata *ddata)
 {
 	/* Unmask the PBIRQ and MPBIRQ on Tangier */
-	intel_scu_ipc_update_register(BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
-	intel_scu_ipc_update_register(BCOVE_PBIRQMASK, 0, MSIC_PWRBTNM);
+	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
+	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQMASK, 0, MSIC_PWRBTNM);
 
 	return 0;
 }
@@ -161,6 +164,10 @@ static int mid_pb_probe(struct platform_device *pdev)
 			return error;
 	}
 
+	ddata->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
+	if (!ddata->scu)
+		return -EPROBE_DEFER;
+
 	error = devm_request_threaded_irq(&pdev->dev, irq, NULL, mid_pb_isr,
 					  IRQF_ONESHOT, DRIVER_NAME, ddata);
 	if (error) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 16/36] watchdog: intel-mid_wdt: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (14 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 15:37   ` Guenter Roeck
  2020-01-08 17:38   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: " Mika Westerberg
                   ` (21 subsequent siblings)
  37 siblings, 2 replies; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This converts the Intel MID watchdog driver over the new SCU IPC API
where the SCU IPC instance is passed to the functions.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/watchdog/intel-mid_wdt.c | 53 ++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 470213abfd3d..1ae03b64ef8b 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -33,14 +33,24 @@ enum {
 	SCU_WATCHDOG_KEEPALIVE,
 };
 
-static inline int wdt_command(int sub, u32 *in, int inlen)
+struct mid_wdt {
+	struct watchdog_device wd;
+	struct device *dev;
+	struct intel_scu_ipc_dev *scu;
+};
+
+static inline int
+wdt_command(struct mid_wdt *mid, int sub, const void *in, size_t inlen, size_t size)
 {
-	return intel_scu_ipc_command(IPC_WATCHDOG, sub, in, inlen, NULL, 0);
+	struct intel_scu_ipc_dev *scu = mid->scu;
+
+	return intel_scu_ipc_dev_command_with_size(scu, IPC_WATCHDOG, sub, in,
+						   inlen, size, NULL, 0);
 }
 
 static int wdt_start(struct watchdog_device *wd)
 {
-	struct device *dev = watchdog_get_drvdata(wd);
+	struct mid_wdt *mid = watchdog_get_drvdata(wd);
 	int ret, in_size;
 	int timeout = wd->timeout;
 	struct ipc_wd_start {
@@ -49,38 +59,41 @@ static int wdt_start(struct watchdog_device *wd)
 	} ipc_wd_start = { timeout - MID_WDT_PRETIMEOUT, timeout };
 
 	/*
-	 * SCU expects the input size for watchdog IPC to
-	 * be based on 4 bytes
+	 * SCU expects the input size for watchdog IPC to be 2 which is the
+	 * size of the structure in dwords. SCU IPC normally takes bytes
+	 * but this is a special case where we specify size to be different
+	 * than inlen.
 	 */
 	in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
 
-	ret = wdt_command(SCU_WATCHDOG_START, (u32 *)&ipc_wd_start, in_size);
+	ret = wdt_command(mid, SCU_WATCHDOG_START, &ipc_wd_start,
+			  sizeof(ipc_wd_start), in_size);
 	if (ret)
-		dev_crit(dev, "error starting watchdog: %d\n", ret);
+		dev_crit(mid->dev, "error starting watchdog: %d\n", ret);
 
 	return ret;
 }
 
 static int wdt_ping(struct watchdog_device *wd)
 {
-	struct device *dev = watchdog_get_drvdata(wd);
+	struct mid_wdt *mid = watchdog_get_drvdata(wd);
 	int ret;
 
-	ret = wdt_command(SCU_WATCHDOG_KEEPALIVE, NULL, 0);
+	ret = wdt_command(mid, SCU_WATCHDOG_KEEPALIVE, NULL, 0, 0);
 	if (ret)
-		dev_crit(dev, "Error executing keepalive: %d\n", ret);
+		dev_crit(mid->dev, "Error executing keepalive: %d\n", ret);
 
 	return ret;
 }
 
 static int wdt_stop(struct watchdog_device *wd)
 {
-	struct device *dev = watchdog_get_drvdata(wd);
+	struct mid_wdt *mid = watchdog_get_drvdata(wd);
 	int ret;
 
-	ret = wdt_command(SCU_WATCHDOG_STOP, NULL, 0);
+	ret = wdt_command(mid, SCU_WATCHDOG_STOP, NULL, 0, 0);
 	if (ret)
-		dev_crit(dev, "Error stopping watchdog: %d\n", ret);
+		dev_crit(mid->dev, "Error stopping watchdog: %d\n", ret);
 
 	return ret;
 }
@@ -110,6 +123,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct watchdog_device *wdt_dev;
 	struct intel_mid_wdt_pdata *pdata = dev->platform_data;
+	struct mid_wdt *mid;
 	int ret;
 
 	if (!pdata) {
@@ -123,10 +137,13 @@ static int mid_wdt_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	wdt_dev = devm_kzalloc(dev, sizeof(*wdt_dev), GFP_KERNEL);
-	if (!wdt_dev)
+	mid = devm_kzalloc(dev, sizeof(*mid), GFP_KERNEL);
+	if (!mid)
 		return -ENOMEM;
 
+	mid->dev = dev;
+	wdt_dev = &mid->wd;
+
 	wdt_dev->info = &mid_wdt_info;
 	wdt_dev->ops = &mid_wdt_ops;
 	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
@@ -135,7 +152,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
 	wdt_dev->parent = dev;
 
 	watchdog_set_nowayout(wdt_dev, WATCHDOG_NOWAYOUT);
-	watchdog_set_drvdata(wdt_dev, dev);
+	watchdog_set_drvdata(wdt_dev, mid);
 
 	ret = devm_request_irq(dev, pdata->irq, mid_wdt_irq,
 			       IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog",
@@ -145,6 +162,10 @@ static int mid_wdt_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	mid->scu = devm_intel_scu_ipc_dev_get(dev);
+	if (!mid->scu)
+		return -EPROBE_DEFER;
+
 	/*
 	 * The firmware followed by U-Boot leaves the watchdog running
 	 * with the default threshold which may vary. When we get here
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (15 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 16/36] watchdog: intel-mid_wdt: " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:45   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static Mika Westerberg
                   ` (20 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Convert the IPC util to use the new SCU IPC API where the SCU IPC
instance is passed to the functions.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipcutil.c | 43 +++++++++++++++++++++---
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
index 8afe6fa06d7b..b7c10c15a3d6 100644
--- a/drivers/platform/x86/intel_scu_ipcutil.c
+++ b/drivers/platform/x86/intel_scu_ipcutil.c
@@ -22,6 +22,9 @@
 
 static int major;
 
+struct intel_scu_ipc_dev *scu;
+static DEFINE_MUTEX(scu_lock);
+
 /* IOCTL commands */
 #define	INTE_SCU_IPC_REGISTER_READ	0
 #define INTE_SCU_IPC_REGISTER_WRITE	1
@@ -52,12 +55,12 @@ static int scu_reg_access(u32 cmd, struct scu_ipc_data  *data)
 
 	switch (cmd) {
 	case INTE_SCU_IPC_REGISTER_READ:
-		return intel_scu_ipc_readv(data->addr, data->data, count);
+		return intel_scu_ipc_dev_readv(scu, data->addr, data->data, count);
 	case INTE_SCU_IPC_REGISTER_WRITE:
-		return intel_scu_ipc_writev(data->addr, data->data, count);
+		return intel_scu_ipc_dev_writev(scu, data->addr, data->data, count);
 	case INTE_SCU_IPC_REGISTER_UPDATE:
-		return intel_scu_ipc_update_register(data->addr[0],
-						    data->data[0], data->mask);
+		return intel_scu_ipc_dev_update(scu, data->addr[0], data->data[0],
+						data->mask);
 	default:
 		return -ENOTTY;
 	}
@@ -91,8 +94,40 @@ static long scu_ipc_ioctl(struct file *fp, unsigned int cmd,
 	return 0;
 }
 
+static int scu_ipc_open(struct inode *inode, struct file *file)
+{
+	int ret = 0;
+
+	/* Only single open at the time */
+	mutex_lock(&scu_lock);
+	if (scu) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	scu = intel_scu_ipc_dev_get();
+	if (!scu)
+		ret = -ENODEV;
+
+unlock:
+	mutex_unlock(&scu_lock);
+	return ret;
+}
+
+static int scu_ipc_release(struct inode *inode, struct file *file)
+{
+	mutex_lock(&scu_lock);
+	intel_scu_ipc_dev_put(scu);
+	scu = NULL;
+	mutex_unlock(&scu_lock);
+
+	return 0;
+}
+
 static const struct file_operations scu_ipc_fops = {
 	.unlocked_ioctl = scu_ipc_ioctl,
+	.open = scu_ipc_open,
+	.release = scu_ipc_release,
 };
 
 static int __init ipc_module_init(void)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (16 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:46   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static Mika Westerberg
                   ` (19 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This function is not called outside of intel_pmc_ipc.c so we can make it
static instead.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h | 6 ------
 drivers/platform/x86/intel_pmc_ipc.c | 3 +--
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index 9e7adcdbe031..3b2e8b461520 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -40,7 +40,6 @@ int intel_pmc_s0ix_counter_read(u64 *data);
 int intel_pmc_gcr_read(u32 offset, u32 *data);
 int intel_pmc_gcr_read64(u32 offset, u64 *data);
 int intel_pmc_gcr_write(u32 offset, u32 data);
-int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val);
 
 #else
 
@@ -81,11 +80,6 @@ static inline int intel_pmc_gcr_write(u32 offset, u32 data)
 	return -EINVAL;
 }
 
-static inline int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
-{
-	return -EINVAL;
-}
-
 #endif /*CONFIG_INTEL_PMC_IPC*/
 
 #endif
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 5c1da2bb1435..9229c7a16536 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -309,7 +309,7 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
  *
  * Return:	negative value on error or 0 on success.
  */
-int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
+static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
 {
 	u32 new_val;
 	int ret = 0;
@@ -339,7 +339,6 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
 	spin_unlock(&ipcdev.gcr_lock);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
 
 static int update_no_reboot_bit(void *priv, bool set)
 {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (17 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:46   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static Mika Westerberg
                   ` (18 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This function is not called outside of intel_pmc_ipc.c so we can make it
static instead.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h | 6 ------
 drivers/platform/x86/intel_pmc_ipc.c | 3 +--
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index 3b2e8b461520..b4f804877651 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -31,7 +31,6 @@
 
 #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
 
-int intel_pmc_ipc_simple_command(int cmd, int sub);
 int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen, u32 dptr, u32 sptr);
 int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
@@ -43,11 +42,6 @@ int intel_pmc_gcr_write(u32 offset, u32 data);
 
 #else
 
-static inline int intel_pmc_ipc_simple_command(int cmd, int sub)
-{
-	return -EINVAL;
-}
-
 static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen, u32 dptr, u32 sptr)
 {
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 9229c7a16536..53551f5474a7 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -404,7 +404,7 @@ static int intel_pmc_ipc_check_status(void)
  *
  * Return:	an IPC error code or 0 on success.
  */
-int intel_pmc_ipc_simple_command(int cmd, int sub)
+static int intel_pmc_ipc_simple_command(int cmd, int sub)
 {
 	int ret;
 
@@ -419,7 +419,6 @@ int intel_pmc_ipc_simple_command(int cmd, int sub)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);
 
 /**
  * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (18 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:46   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write() Mika Westerberg
                   ` (17 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This function is not called outside of intel_pmc_ipc.c so we can make it
static instead.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h | 8 --------
 drivers/platform/x86/intel_pmc_ipc.c | 5 ++---
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index b4f804877651..966ff2171ff9 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -31,8 +31,6 @@
 
 #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
 
-int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
-		u32 *out, u32 outlen, u32 dptr, u32 sptr);
 int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen);
 int intel_pmc_s0ix_counter_read(u64 *data);
@@ -42,12 +40,6 @@ int intel_pmc_gcr_write(u32 offset, u32 data);
 
 #else
 
-static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
-		u32 *out, u32 outlen, u32 dptr, u32 sptr)
-{
-	return -EINVAL;
-}
-
 static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen)
 {
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 53551f5474a7..83f47df1c4a5 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -435,8 +435,8 @@ static int intel_pmc_ipc_simple_command(int cmd, int sub)
  *
  * Return:	an IPC error code or 0 on success.
  */
-int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
-			  u32 outlen, u32 dptr, u32 sptr)
+static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
+				 u32 outlen, u32 dptr, u32 sptr)
 {
 	u32 wbuf[4] = { 0 };
 	int ret;
@@ -468,7 +468,6 @@ int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd);
 
 /**
  * intel_pmc_ipc_command() -  IPC command with input/output data
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (19 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:47   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb() Mika Westerberg
                   ` (16 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

These functions are not used anywhere so drop them completely.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h | 12 ------
 drivers/platform/x86/intel_pmc_ipc.c | 59 ----------------------------
 2 files changed, 71 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index 966ff2171ff9..e6da1ce26256 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -34,9 +34,7 @@
 int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen);
 int intel_pmc_s0ix_counter_read(u64 *data);
-int intel_pmc_gcr_read(u32 offset, u32 *data);
 int intel_pmc_gcr_read64(u32 offset, u64 *data);
-int intel_pmc_gcr_write(u32 offset, u32 data);
 
 #else
 
@@ -51,21 +49,11 @@ static inline int intel_pmc_s0ix_counter_read(u64 *data)
 	return -EINVAL;
 }
 
-static inline int intel_pmc_gcr_read(u32 offset, u32 *data)
-{
-	return -EINVAL;
-}
-
 static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
 {
 	return -EINVAL;
 }
 
-static inline int intel_pmc_gcr_write(u32 offset, u32 data)
-{
-	return -EINVAL;
-}
-
 #endif /*CONFIG_INTEL_PMC_IPC*/
 
 #endif
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 83f47df1c4a5..677ed470e14e 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -210,35 +210,6 @@ static inline int is_gcr_valid(u32 offset)
 	return 0;
 }
 
-/**
- * intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
- * @offset:	offset of GCR register from GCR address base
- * @data:	data pointer for storing the register output
- *
- * Reads the 32-bit PMC GCR register at given offset.
- *
- * Return:	negative value on error or 0 on success.
- */
-int intel_pmc_gcr_read(u32 offset, u32 *data)
-{
-	int ret;
-
-	spin_lock(&ipcdev.gcr_lock);
-
-	ret = is_gcr_valid(offset);
-	if (ret < 0) {
-		spin_unlock(&ipcdev.gcr_lock);
-		return ret;
-	}
-
-	*data = readl(ipcdev.gcr_mem_base + offset);
-
-	spin_unlock(&ipcdev.gcr_lock);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
-
 /**
  * intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
  * @offset:	offset of GCR register from GCR address base
@@ -268,36 +239,6 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data)
 }
 EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
 
-/**
- * intel_pmc_gcr_write() - Write PMC GCR register
- * @offset:	offset of GCR register from GCR address base
- * @data:	register update value
- *
- * Writes the PMC GCR register of given offset with given
- * value.
- *
- * Return:	negative value on error or 0 on success.
- */
-int intel_pmc_gcr_write(u32 offset, u32 data)
-{
-	int ret;
-
-	spin_lock(&ipcdev.gcr_lock);
-
-	ret = is_gcr_valid(offset);
-	if (ret < 0) {
-		spin_unlock(&ipcdev.gcr_lock);
-		return ret;
-	}
-
-	writel(data, ipcdev.gcr_mem_base + offset);
-
-	spin_unlock(&ipcdev.gcr_lock);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
-
 /**
  * intel_pmc_gcr_update() - Update PMC GCR register bits
  * @offset:	offset of GCR register from GCR address base
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (20 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:47   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes Mika Westerberg
                   ` (15 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This function is not used anywhere so drop it completely.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_pmc_ipc.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 677ed470e14e..83b106f66fa6 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -184,11 +184,6 @@ static inline void ipc_data_writel(u32 data, u32 offset)
 	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
 }
 
-static inline u8 __maybe_unused ipc_data_readb(u32 offset)
-{
-	return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
-}
-
 static inline u32 ipc_data_readl(u32 offset)
 {
 	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (21 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:47   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC Mika Westerberg
                   ` (14 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

There is no point including headers that are not needed in the driver so
drop them.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_pmc_ipc.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 83b106f66fa6..8527327d88c7 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -12,23 +12,13 @@
  */
 
 #include <linux/acpi.h>
-#include <linux/atomic.h>
-#include <linux/bitops.h>
 #include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/notifier.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
-#include <linux/pm.h>
-#include <linux/pm_qos.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/suspend.h>
 
 #include <asm/intel_pmc_ipc.h>
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (22 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:28   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using " Mika Westerberg
                   ` (13 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Drivers such as intel_pmc_ipc.c can be unloaded as well so in order to
support those in this driver add a new function that can be called to
remove the SCU IPC if the driver is unloaded.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_scu_ipc.h |  1 +
 drivers/platform/x86/intel_scu_ipc.c | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
index 9895b60386c5..250127eb1e38 100644
--- a/arch/x86/include/asm/intel_scu_ipc.h
+++ b/arch/x86/include/asm/intel_scu_ipc.h
@@ -32,6 +32,7 @@ struct intel_scu_ipc_pdata {
 
 struct intel_scu_ipc_dev *
 intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata);
+void intel_scu_ipc_remove(struct intel_scu_ipc_dev *scu);
 
 struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void);
 void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu);
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index cc29f504adcf..9fa0ea95198b 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -566,3 +566,21 @@ intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata)
 	return scu;
 }
 EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
+
+/**
+ * intel_scu_ipc_remove() - Remove SCU IPC
+ * @scu: SCU IPC handle
+ *
+ * This unregisters the SCU IPC device and releases the interrupt.
+ */
+void intel_scu_ipc_remove(struct intel_scu_ipc_dev *scu)
+{
+	mutex_lock(&ipclock);
+	if (!WARN_ON(!scu->dev)) {
+		if (scu->irq > 0)
+			devm_free_irq(scu->dev, scu->irq, scu);
+		scu->dev = NULL;
+	}
+	mutex_unlock(&ipclock);
+}
+EXPORT_SYMBOL_GPL(intel_scu_ipc_remove);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using SCU IPC
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (23 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:52   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic Mika Westerberg
                   ` (12 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

SCU IPC is pretty much the same IPC implemented in the intel_pmc_ipc
driver so drop the duplicate implementation and call directly the SCU
IPC.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/Kconfig         |   1 +
 drivers/platform/x86/intel_pmc_ipc.c | 299 +++++----------------------
 2 files changed, 48 insertions(+), 252 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index e9ba81fc1770..797683c5d005 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1193,6 +1193,7 @@ config INTEL_SMARTCONNECT
 config INTEL_PMC_IPC
 	tristate "Intel PMC IPC Driver"
 	depends on ACPI && PCI
+	select INTEL_SCU_IPC
 	---help---
 	This driver provides support for PMC control on some Intel platforms.
 	The PMC is an ARC processor which defines IPC commands for communication
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 8527327d88c7..10505fbd01b5 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -21,28 +21,10 @@
 #include <linux/platform_device.h>
 
 #include <asm/intel_pmc_ipc.h>
+#include <asm/intel_scu_ipc.h>
 
 #include <linux/platform_data/itco_wdt.h>
 
-/*
- * IPC registers
- * The IA write to IPC_CMD command register triggers an interrupt to the ARC,
- * The ARC handles the interrupt and services it, writing optional data to
- * the IPC1 registers, updates the IPC_STS response register with the status.
- */
-#define IPC_CMD			0x00
-#define		IPC_CMD_MSI		BIT(8)
-#define		IPC_CMD_SIZE		16
-#define		IPC_CMD_SUBCMD		12
-#define IPC_STATUS		0x04
-#define		IPC_STATUS_IRQ		BIT(2)
-#define		IPC_STATUS_ERR		BIT(1)
-#define		IPC_STATUS_BUSY		BIT(0)
-#define IPC_SPTR		0x08
-#define IPC_DPTR		0x0C
-#define IPC_WRITE_BUFFER	0x80
-#define IPC_READ_BUFFER		0x90
-
 /* Residency with clock rate at 19.2MHz to usecs */
 #define S0IX_RESIDENCY_IN_USECS(d, s)		\
 ({						\
@@ -51,16 +33,6 @@
 	result;					\
 })
 
-/*
- * 16-byte buffer for sending data associated with IPC command.
- */
-#define IPC_DATA_BUFFER_SIZE	16
-
-#define IPC_LOOP_CNT		3000000
-#define IPC_MAX_SEC		3
-
-#define IPC_TRIGGER_MODE_IRQ		true
-
 /* exported resources from IFWI */
 #define PLAT_RESOURCE_IPC_INDEX		0
 #define PLAT_RESOURCE_IPC_SIZE		0x1000
@@ -103,11 +75,6 @@
 
 static struct intel_pmc_ipc_dev {
 	struct device *dev;
-	void __iomem *ipc_base;
-	bool irq_mode;
-	int irq;
-	int cmd;
-	struct completion cmd_complete;
 
 	/* The following PMC BARs share the same ACPI device with the IPC */
 	resource_size_t acpi_io_base;
@@ -132,53 +99,6 @@ static struct intel_pmc_ipc_dev {
 	struct platform_device *telemetry_dev;
 } ipcdev;
 
-static char *ipc_err_sources[] = {
-	[IPC_ERR_NONE] =
-		"no error",
-	[IPC_ERR_CMD_NOT_SUPPORTED] =
-		"command not supported",
-	[IPC_ERR_CMD_NOT_SERVICED] =
-		"command not serviced",
-	[IPC_ERR_UNABLE_TO_SERVICE] =
-		"unable to service",
-	[IPC_ERR_CMD_INVALID] =
-		"command invalid",
-	[IPC_ERR_CMD_FAILED] =
-		"command failed",
-	[IPC_ERR_EMSECURITY] =
-		"Invalid Battery",
-	[IPC_ERR_UNSIGNEDKERNEL] =
-		"Unsigned kernel",
-};
-
-/* Prevent concurrent calls to the PMC */
-static DEFINE_MUTEX(ipclock);
-
-static inline void ipc_send_command(u32 cmd)
-{
-	ipcdev.cmd = cmd;
-	if (ipcdev.irq_mode) {
-		reinit_completion(&ipcdev.cmd_complete);
-		cmd |= IPC_CMD_MSI;
-	}
-	writel(cmd, ipcdev.ipc_base + IPC_CMD);
-}
-
-static inline u32 ipc_read_status(void)
-{
-	return readl(ipcdev.ipc_base + IPC_STATUS);
-}
-
-static inline void ipc_data_writel(u32 data, u32 offset)
-{
-	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
-}
-
-static inline u32 ipc_data_readl(u32 offset)
-{
-	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
-}
-
 static inline u64 gcr_data_readq(u32 offset)
 {
 	return readq(ipcdev.gcr_mem_base + offset);
@@ -274,127 +194,6 @@ static int update_no_reboot_bit(void *priv, bool set)
 				    PMC_CFG_NO_REBOOT_MASK, value);
 }
 
-static int intel_pmc_ipc_check_status(void)
-{
-	int status;
-	int ret = 0;
-
-	if (ipcdev.irq_mode) {
-		if (0 == wait_for_completion_timeout(
-				&ipcdev.cmd_complete, IPC_MAX_SEC * HZ))
-			ret = -ETIMEDOUT;
-	} else {
-		int loop_count = IPC_LOOP_CNT;
-
-		while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count)
-			udelay(1);
-		if (loop_count == 0)
-			ret = -ETIMEDOUT;
-	}
-
-	status = ipc_read_status();
-	if (ret == -ETIMEDOUT) {
-		dev_err(ipcdev.dev,
-			"IPC timed out, TS=0x%x, CMD=0x%x\n",
-			status, ipcdev.cmd);
-		return ret;
-	}
-
-	if (status & IPC_STATUS_ERR) {
-		int i;
-
-		ret = -EIO;
-		i = (status >> IPC_CMD_SIZE) & 0xFF;
-		if (i < ARRAY_SIZE(ipc_err_sources))
-			dev_err(ipcdev.dev,
-				"IPC failed: %s, STS=0x%x, CMD=0x%x\n",
-				ipc_err_sources[i], status, ipcdev.cmd);
-		else
-			dev_err(ipcdev.dev,
-				"IPC failed: unknown, STS=0x%x, CMD=0x%x\n",
-				status, ipcdev.cmd);
-		if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY))
-			ret = -EACCES;
-	}
-
-	return ret;
-}
-
-/**
- * intel_pmc_ipc_simple_command() - Simple IPC command
- * @cmd:	IPC command code.
- * @sub:	IPC command sub type.
- *
- * Send a simple IPC command to PMC when don't need to specify
- * input/output data and source/dest pointers.
- *
- * Return:	an IPC error code or 0 on success.
- */
-static int intel_pmc_ipc_simple_command(int cmd, int sub)
-{
-	int ret;
-
-	mutex_lock(&ipclock);
-	if (ipcdev.dev == NULL) {
-		mutex_unlock(&ipclock);
-		return -ENODEV;
-	}
-	ipc_send_command(sub << IPC_CMD_SUBCMD | cmd);
-	ret = intel_pmc_ipc_check_status();
-	mutex_unlock(&ipclock);
-
-	return ret;
-}
-
-/**
- * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
- * @cmd:	IPC command code.
- * @sub:	IPC command sub type.
- * @in:		input data of this IPC command.
- * @inlen:	input data length in bytes.
- * @out:	output data of this IPC command.
- * @outlen:	output data length in dwords.
- * @sptr:	data writing to SPTR register.
- * @dptr:	data writing to DPTR register.
- *
- * Send an IPC command to PMC with input/output data and source/dest pointers.
- *
- * Return:	an IPC error code or 0 on success.
- */
-static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
-				 u32 outlen, u32 dptr, u32 sptr)
-{
-	u32 wbuf[4] = { 0 };
-	int ret;
-	int i;
-
-	if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4)
-		return -EINVAL;
-
-	mutex_lock(&ipclock);
-	if (ipcdev.dev == NULL) {
-		mutex_unlock(&ipclock);
-		return -ENODEV;
-	}
-	memcpy(wbuf, in, inlen);
-	writel(dptr, ipcdev.ipc_base + IPC_DPTR);
-	writel(sptr, ipcdev.ipc_base + IPC_SPTR);
-	/* The input data register is 32bit register and inlen is in Byte */
-	for (i = 0; i < ((inlen + 3) / 4); i++)
-		ipc_data_writel(wbuf[i], 4 * i);
-	ipc_send_command((inlen << IPC_CMD_SIZE) |
-			(sub << IPC_CMD_SUBCMD) | cmd);
-	ret = intel_pmc_ipc_check_status();
-	if (!ret) {
-		/* out is read from 32bit register and outlen is in 32bit */
-		for (i = 0; i < outlen; i++)
-			*out++ = ipc_data_readl(4 * i);
-	}
-	mutex_unlock(&ipclock);
-
-	return ret;
-}
-
 /**
  * intel_pmc_ipc_command() -  IPC command with input/output data
  * @cmd:	IPC command code.
@@ -411,34 +210,23 @@ static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
 int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 			  u32 *out, u32 outlen)
 {
-	return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0);
+	return intel_scu_ipc_dev_command(NULL, cmd, sub, in, inlen, out,
+					 outlen);
 }
 EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);
 
-static irqreturn_t ioc(int irq, void *dev_id)
-{
-	int status;
-
-	if (ipcdev.irq_mode) {
-		status = ipc_read_status();
-		writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS);
-	}
-	complete(&ipcdev.cmd_complete);
-
-	return IRQ_HANDLED;
-}
-
 static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct intel_pmc_ipc_dev *pmc = &ipcdev;
+	struct intel_scu_ipc_pdata pdata;
+	struct intel_scu_ipc_dev *scu;
 	int ret;
 
 	/* Only one PMC is supported */
 	if (pmc->dev)
 		return -EBUSY;
 
-	pmc->irq_mode = IPC_TRIGGER_MODE_IRQ;
-
+	memset(&pdata, 0, sizeof(pdata));
 	spin_lock_init(&ipcdev.gcr_lock);
 
 	ret = pcim_enable_device(pdev);
@@ -449,24 +237,25 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (ret)
 		return ret;
 
-	init_completion(&pmc->cmd_complete);
-
-	pmc->ipc_base = pcim_iomap_table(pdev)[0];
+	pdata.ipc_regs = pcim_iomap_table(pdev)[0];
 
-	ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc",
-				pmc);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to request irq\n");
-		return ret;
-	}
+	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
+	if (IS_ERR(scu))
+		return PTR_ERR(scu);
 
 	pmc->dev = &pdev->dev;
 
-	pci_set_drvdata(pdev, pmc);
+	pci_set_drvdata(pdev, scu);
 
 	return 0;
 }
 
+static void ipc_pci_remove(struct pci_dev *pdev)
+{
+	intel_scu_ipc_remove(pci_get_drvdata(pdev));
+	ipcdev.dev = NULL;
+}
+
 static const struct pci_device_id ipc_pci_ids[] = {
 	{PCI_VDEVICE(INTEL, 0x0a94), 0},
 	{PCI_VDEVICE(INTEL, 0x1a94), 0},
@@ -479,12 +268,14 @@ static struct pci_driver ipc_pci_driver = {
 	.name = "intel_pmc_ipc",
 	.id_table = ipc_pci_ids,
 	.probe = ipc_pci_probe,
+	.remove = ipc_pci_remove,
 };
 
 static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 					      struct device_attribute *attr,
 					      const char *buf, size_t count)
 {
+	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
 	int subcmd;
 	int cmd;
 	int ret;
@@ -495,7 +286,7 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 		return -EINVAL;
 	}
 
-	ret = intel_pmc_ipc_simple_command(cmd, subcmd);
+	ret = intel_scu_ipc_dev_simple_command(scu, cmd, subcmd);
 	if (ret) {
 		dev_err(dev, "command %d error with %d\n", cmd, ret);
 		return ret;
@@ -507,6 +298,7 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 					     struct device_attribute *attr,
 					     const char *buf, size_t count)
 {
+	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
 	unsigned long val;
 	int subcmd;
 	int ret;
@@ -518,7 +310,8 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 		subcmd = 1;
 	else
 		subcmd = 0;
-	ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd);
+	ret = intel_scu_ipc_dev_simple_command(scu, PMC_IPC_NORTHPEAK_CTRL,
+					       subcmd);
 	if (ret) {
 		dev_err(dev, "command north %d error with %d\n", subcmd, ret);
 		return ret;
@@ -711,7 +504,8 @@ static int ipc_create_pmc_devices(void)
 	return ret;
 }
 
-static int ipc_plat_get_res(struct platform_device *pdev)
+static int ipc_plat_get_res(struct platform_device *pdev,
+			    struct intel_scu_ipc_pdata *pdata)
 {
 	struct resource *res, *punit_res = punit_res_array;
 	void __iomem *addr;
@@ -795,7 +589,7 @@ static int ipc_plat_get_res(struct platform_device *pdev)
 	if (IS_ERR(addr))
 		return PTR_ERR(addr);
 
-	ipcdev.ipc_base = addr;
+	pdata->ipc_regs = addr;
 
 	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
 	dev_info(&pdev->dev, "ipc res: %pR\n", res);
@@ -851,49 +645,50 @@ MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
 
 static int ipc_plat_probe(struct platform_device *pdev)
 {
+	struct intel_scu_ipc_pdata pdata;
+	struct intel_scu_ipc_dev *scu;
 	int ret;
 
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.irq = platform_get_irq(pdev, 0);
+	if (pdata.irq < 0)
+		return -EINVAL;
+
 	ipcdev.dev = &pdev->dev;
-	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
-	init_completion(&ipcdev.cmd_complete);
 	spin_lock_init(&ipcdev.gcr_lock);
 
-	ipcdev.irq = platform_get_irq(pdev, 0);
-	if (ipcdev.irq < 0)
-		return -EINVAL;
-
-	ret = ipc_plat_get_res(pdev);
+	ret = ipc_plat_get_res(pdev, &pdata);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request resource\n");
 		return ret;
 	}
 
+	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
+	if (IS_ERR(scu))
+		return PTR_ERR(scu);
+
+	platform_set_drvdata(pdev, scu);
+
 	ret = ipc_create_pmc_devices();
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
-		return ret;
-	}
-
-	if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
-			     "intel_pmc_ipc", &ipcdev)) {
-		dev_err(&pdev->dev, "Failed to request irq\n");
-		ret = -EBUSY;
-		goto err_irq;
+		goto err_ipc;
 	}
 
 	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
 			ret);
-		goto err_sys;
+		goto err_devs;
 	}
 
 	ipcdev.has_gcr_regs = true;
 
 	return 0;
-err_sys:
-	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
-err_irq:
+
+err_ipc:
+	intel_scu_ipc_remove(scu);
+err_devs:
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
 	platform_device_unregister(ipcdev.telemetry_dev);
@@ -904,10 +699,10 @@ static int ipc_plat_probe(struct platform_device *pdev)
 static int ipc_plat_remove(struct platform_device *pdev)
 {
 	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
-	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
 	platform_device_unregister(ipcdev.telemetry_dev);
+	intel_scu_ipc_remove(platform_get_drvdata(pdev));
 	ipcdev.dev = NULL;
 	return 0;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (24 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:31   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API Mika Westerberg
                   ` (11 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Both PMIC drivers (intel_soc_pmic_mrfld and intel_soc_pmic_bxtwc) will
be using this field going forward to access the SCU IPC instance.

While there add kernel-doc for the intel_soc_pmic structure.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 include/linux/mfd/intel_soc_pmic.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h
index bfecd6bd4990..bda22d750be6 100644
--- a/include/linux/mfd/intel_soc_pmic.h
+++ b/include/linux/mfd/intel_soc_pmic.h
@@ -13,6 +13,20 @@
 
 #include <linux/regmap.h>
 
+/**
+ * struct intel_soc_pmic - Intel SoC PMIC data
+ * @irq: Interrupt number
+ * @regmap: Pointer to the regmap structure
+ * @irq_chip_data: IRQ chip data for the PMIC itself
+ * @irq_chip_data_pwrbtn: Chained IRQ chip data for the power button
+ * @irq_chip_data_tmu: Chained IRQ chip data for the TMU
+ * @irq_chip_data_bcu: Chained IRQ chip data for the BCU
+ * @irq_chip_data_adc: Chained IRQ chip data for the ADC
+ * @irq_chip_data_chgr: Chained IRQ chip data for the CHGR
+ * @irq_chip_data_crit: Chained IRQ chip data for the CRIT
+ * @dev: Pointer to the PMIC device
+ * @scu: SCU IPC pointer used for IPC operations
+ */
 struct intel_soc_pmic {
 	int irq;
 	struct regmap *regmap;
@@ -24,6 +38,7 @@ struct intel_soc_pmic {
 	struct regmap_irq_chip_data *irq_chip_data_chgr;
 	struct regmap_irq_chip_data *irq_chip_data_crit;
 	struct device *dev;
+	struct intel_scu_ipc_dev *scu;
 };
 
 int intel_soc_pmic_exec_mipi_pmic_seq_element(u16 i2c_address, u32 reg_address,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (25 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:32   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: " Mika Westerberg
                   ` (10 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Convert the Intel Broxton Whiskey Cover PMIC driver to use the new SCU
IPC API. This allows us to get rid of the PMC IPC implementation which
is now covered in SCU IPC driver.

Also move PMIC specific IPC message constants to the PMIC driver from
the intel_pmc_ipc.h header.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h |  3 ---
 drivers/mfd/intel_soc_pmic_bxtwc.c   | 22 +++++++++++++++-------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index e6da1ce26256..b438a488f613 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -3,9 +3,6 @@
 #define  _ASM_X86_INTEL_PMC_IPC_H_
 
 /* Commands */
-#define PMC_IPC_PMIC_ACCESS		0xFF
-#define		PMC_IPC_PMIC_ACCESS_READ	0x0
-#define		PMC_IPC_PMIC_ACCESS_WRITE	0x1
 #define PMC_IPC_USB_PWR_CTRL		0xF0
 #define PMC_IPC_PMIC_BLACKLIST_SEL	0xEF
 #define PMC_IPC_PHY_CONFIG		0xEE
diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
index 739cfb5b69fe..60aba2a1561c 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -15,7 +15,7 @@
 #include <linux/mfd/intel_soc_pmic_bxtwc.h>
 #include <linux/module.h>
 
-#include <asm/intel_pmc_ipc.h>
+#include <asm/intel_scu_ipc.h>
 
 /* PMIC device registers */
 #define REG_ADDR_MASK		0xFF00
@@ -58,6 +58,10 @@
 /* Whiskey Cove PMIC share same ACPI ID between different platforms */
 #define BROXTON_PMIC_WC_HRV	4
 
+#define PMC_PMIC_ACCESS		0xFF
+#define PMC_PMIC_READ		0x0
+#define PMC_PMIC_WRITE		0x1
+
 enum bxtwc_irqs {
 	BXTWC_PWRBTN_LVL1_IRQ = 0,
 	BXTWC_TMU_LVL1_IRQ,
@@ -288,9 +292,9 @@ static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
 
 	ipc_in[0] = reg;
 	ipc_in[1] = i2c_addr;
-	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
-			PMC_IPC_PMIC_ACCESS_READ,
-			ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
+	ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
+					PMC_PMIC_READ, ipc_in, sizeof(ipc_in),
+					ipc_out, sizeof(ipc_out));
 	if (ret) {
 		dev_err(pmic->dev, "Failed to read from PMIC\n");
 		return ret;
@@ -321,9 +325,9 @@ static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
 	ipc_in[0] = reg;
 	ipc_in[1] = i2c_addr;
 	ipc_in[2] = val;
-	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
-			PMC_IPC_PMIC_ACCESS_WRITE,
-			ipc_in, sizeof(ipc_in), NULL, 0);
+	ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
+					PMC_PMIC_WRITE, ipc_in, sizeof(ipc_in),
+					NULL, 0);
 	if (ret) {
 		dev_err(pmic->dev, "Failed to write to PMIC\n");
 		return ret;
@@ -457,6 +461,10 @@ static int bxtwc_probe(struct platform_device *pdev)
 	dev_set_drvdata(&pdev->dev, pmic);
 	pmic->dev = &pdev->dev;
 
+	pmic->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
+	if (!pmic->scu)
+		return -EPROBE_DEFER;
+
 	pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
 					&bxtwc_regmap_config);
 	if (IS_ERR(pmic->regmap)) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (26 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:35   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 29/36] platform/x86: intel_telemetry: " Mika Westerberg
                   ` (9 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This converts the Intel Merrifield PMIC driver over the new SCU IPC API
where the SCU IPC instance is passed to the functions.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/mfd/intel_soc_pmic_mrfld.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/intel_soc_pmic_mrfld.c b/drivers/mfd/intel_soc_pmic_mrfld.c
index 26a1551c5faf..bd94c989d232 100644
--- a/drivers/mfd/intel_soc_pmic_mrfld.c
+++ b/drivers/mfd/intel_soc_pmic_mrfld.c
@@ -74,10 +74,11 @@ static const struct mfd_cell bcove_dev[] = {
 static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
 				    unsigned int *val)
 {
+	struct intel_soc_pmic *pmic = context;
 	u8 ipc_out;
 	int ret;
 
-	ret = intel_scu_ipc_ioread8(reg, &ipc_out);
+	ret = intel_scu_ipc_dev_ioread8(pmic->scu, reg, &ipc_out);
 	if (ret)
 		return ret;
 
@@ -88,10 +89,11 @@ static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
 static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
 				     unsigned int val)
 {
+	struct intel_soc_pmic *pmic = context;
 	u8 ipc_in = val;
 	int ret;
 
-	ret = intel_scu_ipc_iowrite8(reg, ipc_in);
+	ret = intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
 	if (ret)
 		return ret;
 
@@ -117,6 +119,10 @@ static int bcove_probe(struct platform_device *pdev)
 	if (!pmic)
 		return -ENOMEM;
 
+	pmic->scu = devm_intel_scu_ipc_dev_get(dev);
+	if (!pmic->scu)
+		return -ENOMEM;
+
 	platform_set_drvdata(pdev, pmic);
 	pmic->dev = &pdev->dev;
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 29/36] platform/x86: intel_telemetry: Convert to use new SCU IPC API
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (27 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:54   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command() Mika Westerberg
                   ` (8 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Convert the Intel Apollo Lake telemetry driver to use the new SCU IPC
API. This allows us to get rid of the duplicate PMC IPC implementation
which is now covered in SCU IPC driver.

Also move telemetry specific IPC message constant to the telementry
driver where it belongs.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h          |   1 -
 arch/x86/include/asm/intel_telemetry.h        |   3 +
 drivers/platform/x86/intel_telemetry_pltdrv.c | 101 +++++++++---------
 3 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index b438a488f613..ddc964b9c78c 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -8,7 +8,6 @@
 #define PMC_IPC_PHY_CONFIG		0xEE
 #define PMC_IPC_NORTHPEAK_CTRL		0xED
 #define PMC_IPC_PM_DEBUG		0xEC
-#define PMC_IPC_PMC_TELEMTRY		0xEB
 #define PMC_IPC_PMC_FW_MSG_CTRL		0xEA
 
 /* IPC return code */
diff --git a/arch/x86/include/asm/intel_telemetry.h b/arch/x86/include/asm/intel_telemetry.h
index 214394860632..e19deb776003 100644
--- a/arch/x86/include/asm/intel_telemetry.h
+++ b/arch/x86/include/asm/intel_telemetry.h
@@ -10,6 +10,8 @@
 #define TELEM_MAX_EVENTS_SRAM		28
 #define TELEM_MAX_OS_ALLOCATED_EVENTS	20
 
+#include <asm/intel_scu_ipc.h>
+
 enum telemetry_unit {
 	TELEM_PSS = 0,
 	TELEM_IOSS,
@@ -54,6 +56,7 @@ struct telemetry_plt_config {
 	struct telemetry_unit_config ioss_config;
 	struct mutex telem_trace_lock;
 	struct mutex telem_lock;
+	struct intel_scu_ipc_dev *scu;
 	bool telem_in_use;
 };
 
diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c
index df8565bad595..d39dde634866 100644
--- a/drivers/platform/x86/intel_telemetry_pltdrv.c
+++ b/drivers/platform/x86/intel_telemetry_pltdrv.c
@@ -15,7 +15,6 @@
 
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
-#include <asm/intel_pmc_ipc.h>
 #include <asm/intel_punit_ipc.h>
 #include <asm/intel_telemetry.h>
 
@@ -35,6 +34,7 @@
 #define TELEM_SSRAM_STARTTIME_OFFSET	8
 #define TELEM_SSRAM_EVTLOG_OFFSET	16
 
+#define IOSS_TELEM			0xeb
 #define IOSS_TELEM_EVENT_READ		0x0
 #define IOSS_TELEM_EVENT_WRITE		0x1
 #define IOSS_TELEM_INFO_READ		0x2
@@ -42,9 +42,6 @@
 #define IOSS_TELEM_TRACE_CTL_WRITE	0x6
 #define IOSS_TELEM_EVENT_CTL_READ	0x7
 #define IOSS_TELEM_EVENT_CTL_WRITE	0x8
-#define IOSS_TELEM_EVT_CTRL_WRITE_SIZE	0x4
-#define IOSS_TELEM_READ_WORD		0x1
-#define IOSS_TELEM_WRITE_FOURBYTES	0x4
 #define IOSS_TELEM_EVT_WRITE_SIZE	0x3
 
 #define TELEM_INFO_SRAMEVTS_MASK	0xFF00
@@ -253,17 +250,14 @@ static int telemetry_check_evtid(enum telemetry_unit telem_unit,
 static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
 {
 	u32 write_buf;
-	int ret;
 
 	write_buf = evt_id | TELEM_EVENT_ENABLE;
 	write_buf <<= BITS_PER_BYTE;
 	write_buf |= index;
 
-	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-				    IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf,
-				    IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
-
-	return ret;
+	return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+					 IOSS_TELEM_EVENT_WRITE, &write_buf,
+					 IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
 }
 
 static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
@@ -281,6 +275,7 @@ static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
 static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 					 enum telemetry_action action)
 {
+	struct intel_scu_ipc_dev *scu = telm_conf->scu;
 	u8 num_ioss_evts, ioss_period;
 	int ret, index, idx;
 	u32 *ioss_evtmap;
@@ -291,9 +286,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 	ioss_evtmap = evtconfig.evtmap;
 
 	/* Get telemetry EVENT CTL */
-	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
 				    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
-				    &telem_ctrl, IOSS_TELEM_READ_WORD);
+				    &telem_ctrl, sizeof(telem_ctrl));
 	if (ret) {
 		pr_err("IOSS TELEM_CTRL Read Failed\n");
 		return ret;
@@ -302,11 +297,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 	/* Disable Telemetry */
 	TELEM_DISABLE(telem_ctrl);
 
-	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-				    IOSS_TELEM_EVENT_CTL_WRITE,
-				    (u8 *)&telem_ctrl,
-				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
-				    NULL, 0);
+	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+				    IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
+				    sizeof(telem_ctrl), NULL, 0);
 	if (ret) {
 		pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 		return ret;
@@ -318,10 +311,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 		/* Clear All Events */
 		TELEM_CLEAR_EVENTS(telem_ctrl);
 
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
 					    IOSS_TELEM_EVENT_CTL_WRITE,
-					    (u8 *)&telem_ctrl,
-					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    &telem_ctrl, sizeof(telem_ctrl),
 					    NULL, 0);
 		if (ret) {
 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
@@ -347,10 +339,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 		/* Clear All Events */
 		TELEM_CLEAR_EVENTS(telem_ctrl);
 
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
 					    IOSS_TELEM_EVENT_CTL_WRITE,
-					    (u8 *)&telem_ctrl,
-					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    &telem_ctrl, sizeof(telem_ctrl),
 					    NULL, 0);
 		if (ret) {
 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
@@ -399,10 +390,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 	TELEM_ENABLE_PERIODIC(telem_ctrl);
 	telem_ctrl |= ioss_period;
 
-	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
 				    IOSS_TELEM_EVENT_CTL_WRITE,
-				    (u8 *)&telem_ctrl,
-				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0);
+				    &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
 	if (ret) {
 		pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
 		return ret;
@@ -589,8 +579,9 @@ static int telemetry_setup(struct platform_device *pdev)
 	u32 read_buf, events, event_regs;
 	int ret;
 
-	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ,
-				    NULL, 0, &read_buf, IOSS_TELEM_READ_WORD);
+	ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+					IOSS_TELEM_INFO_READ, NULL, 0,
+					&read_buf, sizeof(read_buf));
 	if (ret) {
 		dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
 		return ret;
@@ -684,6 +675,8 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
 
 	mutex_lock(&(telm_conf->telem_lock));
 	if (ioss_period) {
+		struct intel_scu_ipc_dev *scu = telm_conf->scu;
+
 		if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
 			pr_err("IOSS Sampling Period Out of Range\n");
 			ret = -EINVAL;
@@ -691,9 +684,9 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
 		}
 
 		/* Get telemetry EVENT CTL */
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
 					    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
-					    &telem_ctrl, IOSS_TELEM_READ_WORD);
+					    &telem_ctrl, sizeof(telem_ctrl));
 		if (ret) {
 			pr_err("IOSS TELEM_CTRL Read Failed\n");
 			goto out;
@@ -702,11 +695,10 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
 		/* Disable Telemetry */
 		TELEM_DISABLE(telem_ctrl);
 
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-					    IOSS_TELEM_EVENT_CTL_WRITE,
-					    (u8 *)&telem_ctrl,
-					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
-					    NULL, 0);
+		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+						IOSS_TELEM_EVENT_CTL_WRITE,
+						&telem_ctrl, sizeof(telem_ctrl),
+						NULL, 0);
 		if (ret) {
 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 			goto out;
@@ -718,11 +710,10 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
 		TELEM_ENABLE_PERIODIC(telem_ctrl);
 		telem_ctrl |= ioss_period;
 
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-					    IOSS_TELEM_EVENT_CTL_WRITE,
-					    (u8 *)&telem_ctrl,
-					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
-					    NULL, 0);
+		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+						IOSS_TELEM_EVENT_CTL_WRITE,
+						&telem_ctrl, sizeof(telem_ctrl),
+						NULL, 0);
 		if (ret) {
 			pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
 			goto out;
@@ -1017,9 +1008,9 @@ static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
 		break;
 
 	case TELEM_IOSS:
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
-				IOSS_TELEM_READ_WORD);
+		ret = intel_scu_ipc_dev_command(telm_conf->scu,
+				IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
+				NULL, 0, &temp, sizeof(temp));
 		if (ret) {
 			pr_err("IOSS TRACE_CTL Read Failed\n");
 			goto out;
@@ -1071,9 +1062,9 @@ static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
 		break;
 
 	case TELEM_IOSS:
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
-				IOSS_TELEM_READ_WORD);
+		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+						IOSS_TELEM_TRACE_CTL_READ,
+						NULL, 0, &temp, sizeof(temp));
 		if (ret) {
 			pr_err("IOSS TRACE_CTL Read Failed\n");
 			goto out;
@@ -1082,9 +1073,9 @@ static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
 		TELEM_CLEAR_VERBOSITY_BITS(temp);
 		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
 
-		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
-				IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp,
-				IOSS_TELEM_WRITE_FOURBYTES, NULL, 0);
+		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+						IOSS_TELEM_TRACE_CTL_WRITE,
+						&temp, sizeof(temp), NULL, 0);
 		if (ret) {
 			pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
 			goto out;
@@ -1172,6 +1163,12 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
 		goto out;
 	}
 
+	telm_conf->scu = intel_scu_ipc_dev_get();
+	if (!telm_conf->scu) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
 	mutex_init(&telm_conf->telem_lock);
 	mutex_init(&telm_conf->telem_trace_lock);
 
@@ -1196,6 +1193,10 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
 		iounmap(telm_conf->pss_config.regmap);
 	if (telm_conf->ioss_config.regmap)
 		iounmap(telm_conf->ioss_config.regmap);
+	if (telm_conf->scu) {
+		intel_scu_ipc_dev_put(telm_conf->scu);
+		telm_conf->scu = NULL;
+	}
 	dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
 
 	return ret;
@@ -1204,6 +1205,8 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
 static int telemetry_pltdrv_remove(struct platform_device *pdev)
 {
 	telemetry_clear_pltdata();
+	intel_scu_ipc_dev_put(telm_conf->scu);
+	telm_conf->scu = NULL;
 	iounmap(telm_conf->pss_config.regmap);
 	iounmap(telm_conf->ioss_config.regmap);
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (28 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 29/36] platform/x86: intel_telemetry: " Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:57   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]() Mika Westerberg
                   ` (7 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

Now that all callers have been converted over to the SCU IPC API we can
drop intel_pmc_ipc_command().

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel_pmc_ipc.h |  8 --------
 drivers/platform/x86/intel_pmc_ipc.c | 21 ---------------------
 2 files changed, 29 deletions(-)

diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index ddc964b9c78c..22848df5faaf 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -27,19 +27,11 @@
 
 #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
 
-int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
-		u32 *out, u32 outlen);
 int intel_pmc_s0ix_counter_read(u64 *data);
 int intel_pmc_gcr_read64(u32 offset, u64 *data);
 
 #else
 
-static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
-		u32 *out, u32 outlen)
-{
-	return -EINVAL;
-}
-
 static inline int intel_pmc_s0ix_counter_read(u64 *data)
 {
 	return -EINVAL;
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 10505fbd01b5..241bce603183 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -194,27 +194,6 @@ static int update_no_reboot_bit(void *priv, bool set)
 				    PMC_CFG_NO_REBOOT_MASK, value);
 }
 
-/**
- * intel_pmc_ipc_command() -  IPC command with input/output data
- * @cmd:	IPC command code.
- * @sub:	IPC command sub type.
- * @in:		input data of this IPC command.
- * @inlen:	input data length in bytes.
- * @out:	output data of this IPC command.
- * @outlen:	output data length in dwords.
- *
- * Send an IPC command to PMC with input/output data.
- *
- * Return:	an IPC error code or 0 on success.
- */
-int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
-			  u32 *out, u32 outlen)
-{
-	return intel_scu_ipc_dev_command(NULL, cmd, sub, in, inlen, out,
-					 outlen);
-}
-EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);
-
 static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct intel_pmc_ipc_dev *pmc = &ipcdev;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]()
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (29 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:36   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c Mika Westerberg
                   ` (6 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This allows to call the functions even when CONFIG_X86_INTEL_MID is not
enabled.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 arch/x86/include/asm/intel-mid.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h
index 8e5af119dc2d..de58391bdee0 100644
--- a/arch/x86/include/asm/intel-mid.h
+++ b/arch/x86/include/asm/intel-mid.h
@@ -88,11 +88,17 @@ static inline bool intel_mid_has_msic(void)
 	return (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL);
 }
 
+extern void intel_scu_devices_create(void);
+extern void intel_scu_devices_destroy(void);
+
 #else /* !CONFIG_X86_INTEL_MID */
 
 #define intel_mid_identify_cpu()	0
 #define intel_mid_has_msic()		0
 
+static inline void intel_scu_devices_create(void) { }
+static inline void intel_scu_devices_destroy(void) { }
+
 #endif /* !CONFIG_X86_INTEL_MID */
 
 enum intel_mid_timer_options {
@@ -115,9 +121,6 @@ extern enum intel_mid_timer_options intel_mid_timer_options;
 #define SFI_MTMR_MAX_NUM		8
 #define SFI_MRTC_MAX			8
 
-extern void intel_scu_devices_create(void);
-extern void intel_scu_devices_destroy(void);
-
 /* VRTC timer */
 #define MRST_VRTC_MAP_SZ		1024
 /* #define MRST_VRTC_PGOFFSET		0xc00 */
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (30 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]() Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 17:03   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes Mika Westerberg
                   ` (5 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The PCI probe driver in intel_pmc_ipc.c is a duplicate of what we
already have in intel_scu_pcidrv.c with the exception that the later also
creates SCU specific devices. Move the PCI IDs from the intel_pmc_ipc.c
to intel_scu.c and use driver_data to detect whether SCU devices need to
be created or not.

Also update Kconfig entry to mention all platforms supported by the
Intel SCU PCI driver.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/Kconfig            | 13 +++--
 drivers/platform/x86/intel_pmc_ipc.c    | 73 +------------------------
 drivers/platform/x86/intel_scu_pcidrv.c | 21 +++++--
 3 files changed, 27 insertions(+), 80 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 797683c5d005..1c5afb9e4965 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -994,13 +994,18 @@ config INTEL_SCU
 
 config INTEL_SCU_PCI
 	bool "Intel SCU PCI driver"
-	depends on X86_INTEL_MID
+	depends on X86_INTEL_MID || PCI
 	select INTEL_SCU
 	help
 	  SCU is used to bridge the communications between kernel and
 	  SCU on some embedded Intel x86 platforms. It also creates
-	  devices that are connected to the SoC through the SCU. This is
-	  not needed for PC-type machines.
+	  devices that are connected to the SoC through the SCU.
+	  Platforms supported:
+	    Medfield
+	    Clovertrail
+	    Merrifield
+	    Broxton
+	    Apollo Lake
 
 config INTEL_SCU_IPC_UTIL
 	tristate "Intel SCU IPC utility driver"
@@ -1192,7 +1197,7 @@ config INTEL_SMARTCONNECT
 
 config INTEL_PMC_IPC
 	tristate "Intel PMC IPC Driver"
-	depends on ACPI && PCI
+	depends on ACPI
 	select INTEL_SCU_IPC
 	---help---
 	This driver provides support for PMC control on some Intel platforms.
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 241bce603183..acec1c6d2069 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -17,7 +17,6 @@
 #include <linux/interrupt.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/module.h>
-#include <linux/pci.h>
 #include <linux/platform_device.h>
 
 #include <asm/intel_pmc_ipc.h>
@@ -194,62 +193,6 @@ static int update_no_reboot_bit(void *priv, bool set)
 				    PMC_CFG_NO_REBOOT_MASK, value);
 }
 
-static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct intel_pmc_ipc_dev *pmc = &ipcdev;
-	struct intel_scu_ipc_pdata pdata;
-	struct intel_scu_ipc_dev *scu;
-	int ret;
-
-	/* Only one PMC is supported */
-	if (pmc->dev)
-		return -EBUSY;
-
-	memset(&pdata, 0, sizeof(pdata));
-	spin_lock_init(&ipcdev.gcr_lock);
-
-	ret = pcim_enable_device(pdev);
-	if (ret)
-		return ret;
-
-	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
-	if (ret)
-		return ret;
-
-	pdata.ipc_regs = pcim_iomap_table(pdev)[0];
-
-	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
-	if (IS_ERR(scu))
-		return PTR_ERR(scu);
-
-	pmc->dev = &pdev->dev;
-
-	pci_set_drvdata(pdev, scu);
-
-	return 0;
-}
-
-static void ipc_pci_remove(struct pci_dev *pdev)
-{
-	intel_scu_ipc_remove(pci_get_drvdata(pdev));
-	ipcdev.dev = NULL;
-}
-
-static const struct pci_device_id ipc_pci_ids[] = {
-	{PCI_VDEVICE(INTEL, 0x0a94), 0},
-	{PCI_VDEVICE(INTEL, 0x1a94), 0},
-	{PCI_VDEVICE(INTEL, 0x5a94), 0},
-	{ 0,}
-};
-MODULE_DEVICE_TABLE(pci, ipc_pci_ids);
-
-static struct pci_driver ipc_pci_driver = {
-	.name = "intel_pmc_ipc",
-	.id_table = ipc_pci_ids,
-	.probe = ipc_pci_probe,
-	.remove = ipc_pci_remove,
-};
-
 static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 					      struct device_attribute *attr,
 					      const char *buf, size_t count)
@@ -697,25 +640,11 @@ static struct platform_driver ipc_plat_driver = {
 
 static int __init intel_pmc_ipc_init(void)
 {
-	int ret;
-
-	ret = platform_driver_register(&ipc_plat_driver);
-	if (ret) {
-		pr_err("Failed to register PMC ipc platform driver\n");
-		return ret;
-	}
-	ret = pci_register_driver(&ipc_pci_driver);
-	if (ret) {
-		pr_err("Failed to register PMC ipc pci driver\n");
-		platform_driver_unregister(&ipc_plat_driver);
-		return ret;
-	}
-	return ret;
+	return platform_driver_register(&ipc_plat_driver);
 }
 
 static void __exit intel_pmc_ipc_exit(void)
 {
-	pci_unregister_driver(&ipc_pci_driver);
 	platform_driver_unregister(&ipc_plat_driver);
 }
 
diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
index 42030bdb3e08..4f2a7ca5c5f7 100644
--- a/drivers/platform/x86/intel_scu_pcidrv.c
+++ b/drivers/platform/x86/intel_scu_pcidrv.c
@@ -17,6 +17,7 @@
 static int intel_scu_pci_probe(struct pci_dev *pdev,
 			       const struct pci_device_id *id)
 {
+	void (*setup_fn)(void) = (void (*)(void))id->driver_data;
 	struct intel_scu_ipc_pdata *pdata;
 	struct intel_scu_ipc_dev *scu;
 	int ret;
@@ -40,14 +41,26 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
 	if (IS_ERR(scu))
 		return PTR_ERR(scu);
 
-	intel_scu_devices_create();
+	if (setup_fn)
+		setup_fn();
 	return 0;
 }
 
+static void intel_mid_scu_setup(void)
+{
+	intel_scu_devices_create();
+}
+
 static const struct pci_device_id pci_ids[] = {
-	{ PCI_VDEVICE(INTEL, 0x080e) },
-	{ PCI_VDEVICE(INTEL, 0x08ea) },
-	{ PCI_VDEVICE(INTEL, 0x11a0) },
+	{ PCI_VDEVICE(INTEL, 0x080e),
+	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
+	{ PCI_VDEVICE(INTEL, 0x08ea),
+	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
+	{ PCI_VDEVICE(INTEL, 0x0a94) },
+	{ PCI_VDEVICE(INTEL, 0x11a0),
+	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
+	{ PCI_VDEVICE(INTEL, 0x1a94) },
+	{ PCI_VDEVICE(INTEL, 0x5a94) },
 	{}
 };
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (31 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-08 16:58   ` Andy Shevchenko
  2020-01-08 11:41 ` [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD Mika Westerberg
                   ` (4 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This is the current preferred way so replace the S_IWUSR with the
corresponding octal value. While there move the attributes to follow
directly their store functions.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/platform/x86/intel_pmc_ipc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index acec1c6d2069..20a4bb72aeac 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -215,6 +215,7 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 	}
 	return (ssize_t)count;
 }
+static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store);
 
 static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 					     struct device_attribute *attr,
@@ -240,11 +241,7 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 	}
 	return (ssize_t)count;
 }
-
-static DEVICE_ATTR(simplecmd, S_IWUSR,
-		   NULL, intel_pmc_ipc_simple_cmd_store);
-static DEVICE_ATTR(northpeak, S_IWUSR,
-		   NULL, intel_pmc_ipc_northpeak_store);
+static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store);
 
 static struct attribute *intel_ipc_attrs[] = {
 	&dev_attr_northpeak.attr,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (32 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes Mika Westerberg
@ 2020-01-08 11:41 ` Mika Westerberg
  2020-01-09 11:43   ` Andy Shevchenko
  2020-01-08 11:42 ` [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups Mika Westerberg
                   ` (3 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:41 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

This driver only creates a bunch of platform devices sharing resources
belonging to the PMC device. This is pretty much what MFD subsystem is
for so move the driver there, renaming it to intel_pmc_bxt.c which
should be more clear what it is.

MFD subsystem provides nice helper APIs for subdevice creation so
convert the driver to use those. Unfortunately the ACPI device includes
separate resources for most of the subdevices so we cannot simply call
mfd_add_devices() to create all of them but instead we need to call it
separately for each device.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/mfd/Kconfig                           |  14 +-
 drivers/mfd/Makefile                          |   1 +
 .../intel_pmc_ipc.c => mfd/intel_pmc_bxt.c}   | 394 +++++++-----------
 drivers/platform/x86/Kconfig                  |  16 +-
 drivers/platform/x86/Makefile                 |   1 -
 .../platform/x86/intel_telemetry_debugfs.c    |   2 +-
 drivers/usb/typec/tcpm/Kconfig                |   2 +-
 .../linux/mfd/intel_pmc_bxt.h                 |  11 +-
 8 files changed, 171 insertions(+), 270 deletions(-)
 rename drivers/{platform/x86/intel_pmc_ipc.c => mfd/intel_pmc_bxt.c} (50%)
 rename arch/x86/include/asm/intel_pmc_ipc.h => include/linux/mfd/intel_pmc_bxt.h (83%)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 59515142438e..04542feffe25 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -551,7 +551,7 @@ config INTEL_SOC_PMIC
 
 config INTEL_SOC_PMIC_BXTWC
 	tristate "Support for Intel Broxton Whiskey Cove PMIC"
-	depends on INTEL_PMC_IPC
+	depends on MFD_INTEL_PMC_BXT
 	select MFD_CORE
 	select REGMAP_IRQ
 	help
@@ -632,6 +632,18 @@ config MFD_INTEL_MSIC
 	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
 	  devices used in Intel Medfield platforms.
 
+config MFD_INTEL_PMC_BXT
+	tristate "Intel PMC Driver for Broxton"
+	depends on X86 && X86_PLATFORM_DEVICES && ACPI
+	select INTEL_SCU_IPC
+	select MFD_CORE
+	help
+	  This driver provides support for PMC (Power Management
+	  Controller) on Intel Broxton and Apollo Lake. PMC is a
+	  multi-function device that exposes IPC, General Control
+	  Register and P-unit access. In addition this creates devices
+	  for iTCO watchdog and telemetry that are part of the PMC.
+
 config MFD_IPAQ_MICRO
 	bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support"
 	depends on SA1100_H3100 || SA1100_H3600
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index aed99f08739f..34563a6a047b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -211,6 +211,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS)	+= intel-lpss.o
 obj-$(CONFIG_MFD_INTEL_LPSS_PCI)	+= intel-lpss-pci.o
 obj-$(CONFIG_MFD_INTEL_LPSS_ACPI)	+= intel-lpss-acpi.o
 obj-$(CONFIG_MFD_INTEL_MSIC)	+= intel_msic.o
+obj-$(CONFIG_MFD_INTEL_PMC_BXT)	+= intel_pmc_bxt.o
 obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/mfd/intel_pmc_bxt.c
similarity index 50%
rename from drivers/platform/x86/intel_pmc_ipc.c
rename to drivers/mfd/intel_pmc_bxt.c
index 20a4bb72aeac..76f166c1455b 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/mfd/intel_pmc_bxt.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Driver for the Intel PMC IPC mechanism
+ * Driver for the Intel Broxton PMC
  *
- * (C) Copyright 2014-2015 Intel Corporation
+ * (C) Copyright 2014-2015, 2020 Intel Corporation
  *
  * This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by
  *     Sreedhara DS <sreedhara.ds@intel.com>
@@ -16,10 +16,11 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/intel_pmc_bxt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <asm/intel_pmc_ipc.h>
 #include <asm/intel_scu_ipc.h>
 
 #include <linux/platform_data/itco_wdt.h>
@@ -62,8 +63,6 @@
 #define TELEM_SSRAM_SIZE		240
 #define TELEM_PMC_SSRAM_OFFSET		0x1B00
 #define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
-#define TCO_PMC_OFFSET			0x08
-#define TCO_PMC_SIZE			0x04
 
 /* PMC register bit definitions */
 
@@ -72,40 +71,32 @@
 #define PMC_CFG_NO_REBOOT_EN		(1 << 4)
 #define PMC_CFG_NO_REBOOT_DIS		(0 << 4)
 
-static struct intel_pmc_ipc_dev {
+static struct intel_pmc_dev {
 	struct device *dev;
 
-	/* The following PMC BARs share the same ACPI device with the IPC */
-	resource_size_t acpi_io_base;
-	int acpi_io_size;
-	struct platform_device *tco_dev;
+	/* iTCO */
+	struct resource tco_res[2];
 
 	/* gcr */
 	void __iomem *gcr_mem_base;
-	bool has_gcr_regs;
 	spinlock_t gcr_lock;
 
 	/* punit */
-	struct platform_device *punit_dev;
+	struct resource punit_res[6];
 	unsigned int punit_res_count;
 
 	/* Telemetry */
-	resource_size_t telem_pmc_ssram_base;
-	resource_size_t telem_punit_ssram_base;
-	int telem_pmc_ssram_size;
-	int telem_punit_ssram_size;
-	u8 telem_res_inval;
-	struct platform_device *telemetry_dev;
-} ipcdev;
+	struct resource *telem_base;
+} pmcdev;
 
 static inline u64 gcr_data_readq(u32 offset)
 {
-	return readq(ipcdev.gcr_mem_base + offset);
+	return readq(pmcdev.gcr_mem_base + offset);
 }
 
 static inline int is_gcr_valid(u32 offset)
 {
-	if (!ipcdev.has_gcr_regs)
+	if (!pmcdev.gcr_mem_base)
 		return -EACCES;
 
 	if (offset > PLAT_RESOURCE_GCR_SIZE)
@@ -127,17 +118,17 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data)
 {
 	int ret;
 
-	spin_lock(&ipcdev.gcr_lock);
+	spin_lock(&pmcdev.gcr_lock);
 
 	ret = is_gcr_valid(offset);
 	if (ret < 0) {
-		spin_unlock(&ipcdev.gcr_lock);
+		spin_unlock(&pmcdev.gcr_lock);
 		return ret;
 	}
 
-	*data = readq(ipcdev.gcr_mem_base + offset);
+	*data = readq(pmcdev.gcr_mem_base + offset);
 
-	spin_unlock(&ipcdev.gcr_lock);
+	spin_unlock(&pmcdev.gcr_lock);
 
 	return 0;
 }
@@ -159,29 +150,29 @@ static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
 	u32 new_val;
 	int ret = 0;
 
-	spin_lock(&ipcdev.gcr_lock);
+	spin_lock(&pmcdev.gcr_lock);
 
 	ret = is_gcr_valid(offset);
 	if (ret < 0)
-		goto gcr_ipc_unlock;
+		goto gcr_unlock;
 
-	new_val = readl(ipcdev.gcr_mem_base + offset);
+	new_val = readl(pmcdev.gcr_mem_base + offset);
 
 	new_val &= ~mask;
 	new_val |= val & mask;
 
-	writel(new_val, ipcdev.gcr_mem_base + offset);
+	writel(new_val, pmcdev.gcr_mem_base + offset);
 
-	new_val = readl(ipcdev.gcr_mem_base + offset);
+	new_val = readl(pmcdev.gcr_mem_base + offset);
 
 	/* check whether the bit update is successful */
 	if ((new_val & mask) != (val & mask)) {
 		ret = -EIO;
-		goto gcr_ipc_unlock;
+		goto gcr_unlock;
 	}
 
-gcr_ipc_unlock:
-	spin_unlock(&ipcdev.gcr_lock);
+gcr_unlock:
+	spin_unlock(&pmcdev.gcr_lock);
 	return ret;
 }
 
@@ -193,9 +184,9 @@ static int update_no_reboot_bit(void *priv, bool set)
 				    PMC_CFG_NO_REBOOT_MASK, value);
 }
 
-static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
-					      struct device_attribute *attr,
-					      const char *buf, size_t count)
+static ssize_t intel_pmc_simple_cmd_store(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
 {
 	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
 	int subcmd;
@@ -215,11 +206,11 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 	}
 	return (ssize_t)count;
 }
-static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store);
+static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_simple_cmd_store);
 
-static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
-					     struct device_attribute *attr,
-					     const char *buf, size_t count)
+static ssize_t intel_pmc_northpeak_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
 {
 	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
 	unsigned long val;
@@ -241,264 +232,183 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 	}
 	return (ssize_t)count;
 }
-static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store);
+static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_northpeak_store);
 
-static struct attribute *intel_ipc_attrs[] = {
+static struct attribute *intel_pmc_attrs[] = {
 	&dev_attr_northpeak.attr,
 	&dev_attr_simplecmd.attr,
 	NULL
 };
 
-static const struct attribute_group intel_ipc_group = {
-	.attrs = intel_ipc_attrs,
+static const struct attribute_group intel_pmc_group = {
+	.attrs = intel_pmc_attrs,
 };
 
-static struct resource punit_res_array[] = {
-	/* Punit BIOS */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	/* Punit ISP */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	/* Punit GTD */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-#define TCO_RESOURCE_ACPI_IO		0
-#define TCO_RESOURCE_SMI_EN_IO		1
-#define TCO_RESOURCE_GCR_MEM		2
-static struct resource tco_res[] = {
-	/* ACPI - TCO */
-	{
-		.flags = IORESOURCE_IO,
-	},
-	/* ACPI - SMI */
-	{
-		.flags = IORESOURCE_IO,
-	},
-};
-
-static struct itco_wdt_platform_data tco_info = {
-	.name = "Apollo Lake SoC",
-	.version = 5,
-	.no_reboot_priv = &ipcdev,
-	.update_no_reboot_bit = update_no_reboot_bit,
-};
-
-#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
-#define TELEMETRY_RESOURCE_PMC_SSRAM	1
-static struct resource telemetry_res[] = {
-	/*Telemetry*/
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static int ipc_create_punit_device(void)
+static int pmc_create_punit_device(void)
 {
-	struct platform_device *pdev;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
+	struct mfd_cell punit = {
 		.name = PUNIT_DEVICE_NAME,
-		.id = -1,
-		.res = punit_res_array,
-		.num_res = ipcdev.punit_res_count,
-		};
+		.resources = pmcdev.punit_res,
+		.num_resources = pmcdev.punit_res_count,
+	};
 
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
+	if (!pmcdev.punit_res_count)
+		return 0;
 
-	ipcdev.punit_dev = pdev;
-
-	return 0;
+	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &punit, 1,
+				    NULL, 0, NULL);
 }
 
-static int ipc_create_tco_device(void)
+static int pmc_create_tco_device(void)
 {
-	struct platform_device *pdev;
-	struct resource *res;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
+	struct itco_wdt_platform_data tco_info = {
+		.name = "Apollo Lake SoC",
+		.version = 5,
+		.no_reboot_priv = &pmcdev,
+		.update_no_reboot_bit = update_no_reboot_bit,
+	};
+	struct mfd_cell tco = {
 		.name = TCO_DEVICE_NAME,
-		.id = -1,
-		.res = tco_res,
-		.num_res = ARRAY_SIZE(tco_res),
-		.data = &tco_info,
-		.size_data = sizeof(tco_info),
-		};
-
-	res = tco_res + TCO_RESOURCE_ACPI_IO;
-	res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET;
-	res->end = res->start + TCO_REGS_SIZE - 1;
-
-	res = tco_res + TCO_RESOURCE_SMI_EN_IO;
-	res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
-	res->end = res->start + SMI_EN_SIZE - 1;
-
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ipcdev.tco_dev = pdev;
-
-	return 0;
+		.ignore_resource_conflicts = true,
+		.platform_data = &tco_info,
+		.pdata_size = sizeof(tco_info),
+		.resources = pmcdev.tco_res,
+		.num_resources = ARRAY_SIZE(pmcdev.tco_res),
+	};
+
+	if (!pmcdev.tco_res[0].start)
+		return 0;
+
+	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &tco, 1,
+				    NULL, 0, NULL);
 }
 
-static int ipc_create_telemetry_device(void)
+static int pmc_create_telemetry_device(void)
 {
-	struct platform_device *pdev;
-	struct resource *res;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
+	struct resource telem_res[] = {
+		DEFINE_RES_MEM(TELEM_PUNIT_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
+		DEFINE_RES_MEM(TELEM_PMC_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
+	};
+	struct mfd_cell telem  = {
 		.name = TELEMETRY_DEVICE_NAME,
-		.id = -1,
-		.res = telemetry_res,
-		.num_res = ARRAY_SIZE(telemetry_res),
-		};
-
-	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
-	res->start = ipcdev.telem_punit_ssram_base;
-	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
+		.resources = telem_res,
+		.num_resources = ARRAY_SIZE(telem_res),
+	};
 
-	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
-	res->start = ipcdev.telem_pmc_ssram_base;
-	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
+	if (!pmcdev.telem_base)
+		return 0;
 
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ipcdev.telemetry_dev = pdev;
-
-	return 0;
+	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &telem, 1,
+				    pmcdev.telem_base, 0, NULL);
 }
 
-static int ipc_create_pmc_devices(void)
+static int pmc_create_devices(void)
 {
 	int ret;
 
 	/* If we have ACPI based watchdog use that instead */
 	if (!acpi_has_watchdog()) {
-		ret = ipc_create_tco_device();
+		ret = pmc_create_tco_device();
 		if (ret) {
-			dev_err(ipcdev.dev, "Failed to add tco platform device\n");
+			dev_err(pmcdev.dev, "Failed to add tco platform device\n");
 			return ret;
 		}
 	}
 
-	ret = ipc_create_punit_device();
+	ret = pmc_create_punit_device();
 	if (ret) {
-		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
-		platform_device_unregister(ipcdev.tco_dev);
+		dev_err(pmcdev.dev, "Failed to add punit platform device\n");
 		return ret;
 	}
 
-	if (!ipcdev.telem_res_inval) {
-		ret = ipc_create_telemetry_device();
-		if (ret) {
-			dev_warn(ipcdev.dev,
-				"Failed to add telemetry platform device\n");
-			platform_device_unregister(ipcdev.punit_dev);
-			platform_device_unregister(ipcdev.tco_dev);
-		}
-	}
+	ret = pmc_create_telemetry_device();
+	if (ret)
+		dev_warn(pmcdev.dev, "Failed to add telemetry platform device\n");
 
 	return ret;
 }
 
-static int ipc_plat_get_res(struct platform_device *pdev,
+static int pmc_plat_get_res(struct platform_device *pdev,
 			    struct intel_scu_ipc_pdata *pdata)
 {
-	struct resource *res, *punit_res = punit_res_array;
+	struct resource *res, *punit_res = pmcdev.punit_res;
+	struct resource *tco_res = pmcdev.tco_res;
 	void __iomem *addr;
 	int size;
 
 	res = platform_get_resource(pdev, IORESOURCE_IO,
 				    PLAT_RESOURCE_ACPI_IO_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get io resource\n");
+		dev_err(&pdev->dev, "Failed to get IO resource\n");
 		return -ENXIO;
+
 	}
-	size = resource_size(res);
-	ipcdev.acpi_io_base = res->start;
-	ipcdev.acpi_io_size = size;
-	dev_info(&pdev->dev, "io res: %pR\n", res);
+	tco_res[0].flags = IORESOURCE_IO;
+	tco_res[0].start = res->start + TCO_BASE_OFFSET;
+	tco_res[0].end = tco_res[0].start + TCO_REGS_SIZE - 1;
+	tco_res[1].flags = IORESOURCE_IO;
+	tco_res[1].start = res->start + SMI_EN_OFFSET;
+	tco_res[1].end = tco_res[1].start + SMI_EN_SIZE - 1;
+	dev_dbg(&pdev->dev, "IO: %pR\n", res);
 
-	ipcdev.punit_res_count = 0;
+	pmcdev.punit_res_count = 0;
 
 	/* This is index 0 to cover BIOS data register */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_BIOS_DATA_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
+		dev_err(&pdev->dev, "Failed to get res of P-unit BIOS data\n");
 		return -ENXIO;
 	}
-	punit_res[ipcdev.punit_res_count++] = *res;
-	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
+	punit_res[pmcdev.punit_res_count++] = *res;
+	dev_dbg(&pdev->dev, "P-unit BIOS data: %pR\n", res);
 
 	/* This is index 1 to cover BIOS interface register */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
+		dev_err(&pdev->dev, "Failed to get res of P-unit BIOS iface\n");
 		return -ENXIO;
 	}
-	punit_res[ipcdev.punit_res_count++] = *res;
-	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
+	punit_res[pmcdev.punit_res_count++] = *res;
+	dev_dbg(&pdev->dev, "P-unit BIOS interface: %pR\n", res);
 
 	/* This is index 2 to cover ISP data register, optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_ISP_DATA_INDEX);
 	if (res) {
-		punit_res[ipcdev.punit_res_count++] = *res;
-		dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
+		punit_res[pmcdev.punit_res_count++] = *res;
+		dev_dbg(&pdev->dev, "P-unit ISP data: %pR\n", res);
 	}
 
 	/* This is index 3 to cover ISP interface register, optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_ISP_IFACE_INDEX);
 	if (res) {
-		punit_res[ipcdev.punit_res_count++] = *res;
-		dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
+		punit_res[pmcdev.punit_res_count++] = *res;
+		dev_dbg(&pdev->dev, "P-unit ISP interface: %pR\n", res);
 	}
 
 	/* This is index 4 to cover GTD data register, optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_GTD_DATA_INDEX);
 	if (res) {
-		punit_res[ipcdev.punit_res_count++] = *res;
-		dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
+		punit_res[pmcdev.punit_res_count++] = *res;
+		dev_dbg(&pdev->dev, "P-unit GTD data: %pR\n", res);
 	}
 
 	/* This is index 5 to cover GTD interface register, optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_GTD_IFACE_INDEX);
 	if (res) {
-		punit_res[ipcdev.punit_res_count++] = *res;
-		dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
+		punit_res[pmcdev.punit_res_count++] = *res;
+		dev_dbg(&pdev->dev, "P-unit GTD interface: %pR\n", res);
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_IPC_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get ipc resource\n");
+		dev_err(&pdev->dev, "Failed to get IPC resource\n");
 		return -ENXIO;
 	}
 	size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE;
@@ -510,23 +420,16 @@ static int ipc_plat_get_res(struct platform_device *pdev,
 
 	pdata->ipc_regs = addr;
 
-	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
-	dev_info(&pdev->dev, "ipc res: %pR\n", res);
+	pmcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
+	dev_dbg(&pdev->dev, "IPC: %pR\n", res);
 
-	ipcdev.telem_res_inval = 0;
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
-		ipcdev.telem_res_inval = 1;
+		dev_err(&pdev->dev, "Failed to get telemetry SSRAM resource\n");
 	} else {
-		ipcdev.telem_punit_ssram_base = res->start +
-						TELEM_PUNIT_SSRAM_OFFSET;
-		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
-		ipcdev.telem_pmc_ssram_base = res->start +
-						TELEM_PMC_SSRAM_OFFSET;
-		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
-		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
+		dev_dbg(&pdev->dev, "Telemetry SSRAM: %pR\n", res);
+		pmcdev.telem_base = res;
 	}
 
 	return 0;
@@ -542,7 +445,7 @@ int intel_pmc_s0ix_counter_read(u64 *data)
 {
 	u64 deep, shlw;
 
-	if (!ipcdev.has_gcr_regs)
+	if (!pmcdev.gcr_mem_base)
 		return -EACCES;
 
 	deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG);
@@ -554,15 +457,13 @@ int intel_pmc_s0ix_counter_read(u64 *data)
 }
 EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read);
 
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id ipc_acpi_ids[] = {
+static const struct acpi_device_id intel_pmc_acpi_ids[] = {
 	{ "INT34D2", 0},
 	{ }
 };
-MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
-#endif
+MODULE_DEVICE_TABLE(acpi, intel_pmc_acpi_ids);
 
-static int ipc_plat_probe(struct platform_device *pdev)
+static int intel_pmc_probe(struct platform_device *pdev)
 {
 	struct intel_scu_ipc_pdata pdata;
 	struct intel_scu_ipc_dev *scu;
@@ -573,10 +474,10 @@ static int ipc_plat_probe(struct platform_device *pdev)
 	if (pdata.irq < 0)
 		return -EINVAL;
 
-	ipcdev.dev = &pdev->dev;
-	spin_lock_init(&ipcdev.gcr_lock);
+	pmcdev.dev = &pdev->dev;
+	spin_lock_init(&pmcdev.gcr_lock);
 
-	ret = ipc_plat_get_res(pdev, &pdata);
+	ret = pmc_plat_get_res(pdev, &pdata);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request resource\n");
 		return ret;
@@ -588,67 +489,58 @@ static int ipc_plat_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, scu);
 
-	ret = ipc_create_pmc_devices();
+	ret = pmc_create_devices();
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
 		goto err_ipc;
 	}
 
-	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
+	ret = sysfs_create_group(&pdev->dev.kobj, &intel_pmc_group);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
 			ret);
-		goto err_devs;
+		goto err_ipc;
 	}
 
-	ipcdev.has_gcr_regs = true;
-
 	return 0;
 
 err_ipc:
 	intel_scu_ipc_remove(scu);
-err_devs:
-	platform_device_unregister(ipcdev.tco_dev);
-	platform_device_unregister(ipcdev.punit_dev);
-	platform_device_unregister(ipcdev.telemetry_dev);
 
 	return ret;
 }
 
-static int ipc_plat_remove(struct platform_device *pdev)
+static int intel_pmc_remove(struct platform_device *pdev)
 {
-	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
-	platform_device_unregister(ipcdev.tco_dev);
-	platform_device_unregister(ipcdev.punit_dev);
-	platform_device_unregister(ipcdev.telemetry_dev);
+	sysfs_remove_group(&pdev->dev.kobj, &intel_pmc_group);
 	intel_scu_ipc_remove(platform_get_drvdata(pdev));
-	ipcdev.dev = NULL;
+	pmcdev.dev = NULL;
 	return 0;
 }
 
-static struct platform_driver ipc_plat_driver = {
-	.remove = ipc_plat_remove,
-	.probe = ipc_plat_probe,
+static struct platform_driver intel_pmc_driver = {
+	.remove = intel_pmc_remove,
+	.probe = intel_pmc_probe,
 	.driver = {
-		.name = "pmc-ipc-plat",
-		.acpi_match_table = ACPI_PTR(ipc_acpi_ids),
+		.name = "intel_pmc_bxt",
+		.acpi_match_table = ACPI_PTR(intel_pmc_acpi_ids),
 	},
 };
 
-static int __init intel_pmc_ipc_init(void)
+static int __init intel_pmc_init(void)
 {
-	return platform_driver_register(&ipc_plat_driver);
+	return platform_driver_register(&intel_pmc_driver);
 }
 
-static void __exit intel_pmc_ipc_exit(void)
+static void __exit intel_pmc_exit(void)
 {
-	platform_driver_unregister(&ipc_plat_driver);
+	platform_driver_unregister(&intel_pmc_driver);
 }
 
 MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
-MODULE_DESCRIPTION("Intel PMC IPC driver");
+MODULE_DESCRIPTION("Intel Broxton PMC driver");
 MODULE_LICENSE("GPL v2");
 
 /* Some modules are dependent on this, so init earlier */
-fs_initcall(intel_pmc_ipc_init);
-module_exit(intel_pmc_ipc_exit);
+fs_initcall(intel_pmc_init);
+module_exit(intel_pmc_exit);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 1c5afb9e4965..e01aba797656 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1195,19 +1195,11 @@ config INTEL_SMARTCONNECT
 	  This driver checks to determine whether the device has Intel Smart
 	  Connect enabled, and if so disables it.
 
-config INTEL_PMC_IPC
-	tristate "Intel PMC IPC Driver"
-	depends on ACPI
-	select INTEL_SCU_IPC
-	---help---
-	This driver provides support for PMC control on some Intel platforms.
-	The PMC is an ARC processor which defines IPC commands for communication
-	with other entities in the CPU.
-
 config INTEL_BXTWC_PMIC_TMU
 	tristate "Intel BXT Whiskey Cove TMU Driver"
 	depends on REGMAP
-	depends on INTEL_SOC_PMIC_BXTWC && INTEL_PMC_IPC
+	depends on MFD_INTEL_PMC_BXT
+	depends on INTEL_SOC_PMIC_BXTWC
 	---help---
 	  Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
 	  This driver enables the alarm wakeup functionality in the TMU unit
@@ -1233,7 +1225,9 @@ config INTEL_PUNIT_IPC
 
 config INTEL_TELEMETRY
 	tristate "Intel SoC Telemetry Driver"
-	depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
+	depends on X86_64
+	depends on MFD_INTEL_PMC_BXT
+	depends on INTEL_PUNIT_IPC
 	---help---
 	  This driver provides interfaces to configure and use
 	  telemetry for INTEL SoC from APL onwards. It is also
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index c7a42feaa521..f1abce3e1720 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -86,7 +86,6 @@ obj-$(CONFIG_INTEL_RST)		+= intel-rst.o
 obj-$(CONFIG_INTEL_SMARTCONNECT)	+= intel-smartconnect.o
 
 obj-$(CONFIG_ALIENWARE_WMI)	+= alienware-wmi.o
-obj-$(CONFIG_INTEL_PMC_IPC)	+= intel_pmc_ipc.o
 obj-$(CONFIG_TOUCHSCREEN_DMI)	+= touchscreen_dmi.o
 obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
 obj-$(CONFIG_SURFACE_3_BUTTON)	+= surface3_button.o
diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c
index e84d3e983e0c..7b7a766a6cb8 100644
--- a/drivers/platform/x86/intel_telemetry_debugfs.c
+++ b/drivers/platform/x86/intel_telemetry_debugfs.c
@@ -16,13 +16,13 @@
 #include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/mfd/intel_pmc_bxt.h>
 #include <linux/pci.h>
 #include <linux/seq_file.h>
 #include <linux/suspend.h>
 
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
-#include <asm/intel_pmc_ipc.h>
 #include <asm/intel_telemetry.h>
 
 #define DRIVER_NAME			"telemetry_soc_debugfs"
diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index 5b986d6c801d..fa3f39336246 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -41,8 +41,8 @@ config TYPEC_FUSB302
 config TYPEC_WCOVE
 	tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
 	depends on ACPI
+	depends on MFD_INTEL_PMC_BXT
 	depends on INTEL_SOC_PMIC
-	depends on INTEL_PMC_IPC
 	depends on BXT_WC_PMIC_OPREGION
 	help
 	  This driver adds support for USB Type-C on Intel Broxton platforms
diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/include/linux/mfd/intel_pmc_bxt.h
similarity index 83%
rename from arch/x86/include/asm/intel_pmc_ipc.h
rename to include/linux/mfd/intel_pmc_bxt.h
index 22848df5faaf..f03a80df0728 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/include/linux/mfd/intel_pmc_bxt.h
@@ -1,6 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_INTEL_PMC_IPC_H_
-#define  _ASM_X86_INTEL_PMC_IPC_H_
+#ifndef MFD_INTEL_PMC_BXT_H
+#define MFD_INTEL_PMC_BXT_H
+
+#include <linux/errno.h>
+#include <linux/types.h>
 
 /* Commands */
 #define PMC_IPC_USB_PWR_CTRL		0xF0
@@ -25,7 +28,7 @@
 #define PMC_GCR_TELEM_DEEP_S0IX_REG	0x78
 #define PMC_GCR_TELEM_SHLW_S0IX_REG	0x80
 
-#if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
+#if IS_ENABLED(CONFIG_MFD_INTEL_PMC_BXT)
 
 int intel_pmc_s0ix_counter_read(u64 *data);
 int intel_pmc_gcr_read64(u32 offset, u64 *data);
@@ -42,6 +45,6 @@ static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
 	return -EINVAL;
 }
 
-#endif /*CONFIG_INTEL_PMC_IPC*/
+#endif /* CONFIG_MFD_INTEL_PMC_BXT */
 
 #endif
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (33 preceding siblings ...)
  2020-01-08 11:41 ` [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD Mika Westerberg
@ 2020-01-08 11:42 ` Mika Westerberg
  2020-01-08 17:30   ` Andy Shevchenko
  2020-01-08 11:42 ` [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver Mika Westerberg
                   ` (2 subsequent siblings)
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:42 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The driver core provides support for adding additional attributes for
devices via new ->dev_groups member of struct device_driver. Convert the
driver to use that instead of adding the attributes manually.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/mfd/intel_pmc_bxt.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/mfd/intel_pmc_bxt.c b/drivers/mfd/intel_pmc_bxt.c
index 76f166c1455b..9f2eb75bdf78 100644
--- a/drivers/mfd/intel_pmc_bxt.c
+++ b/drivers/mfd/intel_pmc_bxt.c
@@ -244,6 +244,11 @@ static const struct attribute_group intel_pmc_group = {
 	.attrs = intel_pmc_attrs,
 };
 
+static const struct attribute_group *intel_pmc_groups[] = {
+	&intel_pmc_group,
+	NULL,
+};
+
 static int pmc_create_punit_device(void)
 {
 	struct mfd_cell punit = {
@@ -492,27 +497,14 @@ static int intel_pmc_probe(struct platform_device *pdev)
 	ret = pmc_create_devices();
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
-		goto err_ipc;
-	}
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &intel_pmc_group);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
-			ret);
-		goto err_ipc;
+		intel_scu_ipc_remove(scu);
 	}
 
-	return 0;
-
-err_ipc:
-	intel_scu_ipc_remove(scu);
-
 	return ret;
 }
 
 static int intel_pmc_remove(struct platform_device *pdev)
 {
-	sysfs_remove_group(&pdev->dev.kobj, &intel_pmc_group);
 	intel_scu_ipc_remove(platform_get_drvdata(pdev));
 	pmcdev.dev = NULL;
 	return 0;
@@ -524,6 +516,7 @@ static struct platform_driver intel_pmc_driver = {
 	.driver = {
 		.name = "intel_pmc_bxt",
 		.acpi_match_table = ACPI_PTR(intel_pmc_acpi_ids),
+		.dev_groups = intel_pmc_groups,
 	},
 };
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (34 preceding siblings ...)
  2020-01-08 11:42 ` [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups Mika Westerberg
@ 2020-01-08 11:42 ` Mika Westerberg
  2020-01-08 17:06   ` Andy Shevchenko
  2020-01-08 17:34 ` [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Andy Shevchenko
  2020-01-13 10:38 ` Lee Jones
  37 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-08 11:42 UTC (permalink / raw)
  To: Andy Shevchenko, Darren Hart, Lee Jones
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	x86, Zha Qipeng, Rajneesh Bhardwaj, David E . Box, Guenter Roeck,
	Heikki Krogerus, Greg Kroah-Hartman, Wim Van Sebroeck,
	Mika Westerberg, platform-driver-x86, linux-kernel

The driver lives now under MFD so split the current entry into two parts
and add me as co-maintainer of the Intel Broxton PMC driver. While there
correct formatting of Zha Qipeng's email address.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 MAINTAINERS | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8982c6e013b3..11b8bb4e2867 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8280,6 +8280,13 @@ L:	platform-driver-x86@vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/intel_atomisp2_pm.c
 
+INTEL BROXTON PMC DRIVER
+M:	Mika Westerberg <mika.westerberg@linux.intel.com>
+M:	Zha Qipeng <qipeng.zha@intel.com>
+S:	Maintained
+F:	drivers/mfd/intel_pmc_bxt.c
+F:	include/linux/mfd/intel_pmc_bxt.h
+
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:	Intel SCU Linux support <intel-linux-scu@intel.com>
 M:	Artur Paszkiewicz <artur.paszkiewicz@intel.com>
@@ -8488,13 +8495,11 @@ L:	platform-driver-x86@vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/intel_pmc_core*
 
-INTEL PMC/P-Unit IPC DRIVER
-M:	Zha Qipeng<qipeng.zha@intel.com>
+INTEL P-Unit IPC DRIVER
+M:	Zha Qipeng <qipeng.zha@intel.com>
 L:	platform-driver-x86@vger.kernel.org
 S:	Maintained
-F:	drivers/platform/x86/intel_pmc_ipc.c
 F:	drivers/platform/x86/intel_punit_ipc.c
-F:	arch/x86/include/asm/intel_pmc_ipc.h
 F:	arch/x86/include/asm/intel_punit_ipc.h
 
 INTEL PMIC GPIO DRIVERS
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 16/36] watchdog: intel-mid_wdt: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 16/36] watchdog: intel-mid_wdt: " Mika Westerberg
@ 2020-01-08 15:37   ` Guenter Roeck
  2020-01-08 17:38   ` Andy Shevchenko
  1 sibling, 0 replies; 81+ messages in thread
From: Guenter Roeck @ 2020-01-08 15:37 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Shevchenko, Darren Hart, Lee Jones, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:41PM +0300, Mika Westerberg wrote:
> This converts the Intel MID watchdog driver over the new SCU IPC API
> where the SCU IPC instance is passed to the functions.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Guenter Roeck <linux@roeck-us.net>

> ---
>  drivers/watchdog/intel-mid_wdt.c | 53 ++++++++++++++++++++++----------
>  1 file changed, 37 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
> index 470213abfd3d..1ae03b64ef8b 100644
> --- a/drivers/watchdog/intel-mid_wdt.c
> +++ b/drivers/watchdog/intel-mid_wdt.c
> @@ -33,14 +33,24 @@ enum {
>  	SCU_WATCHDOG_KEEPALIVE,
>  };
>  
> -static inline int wdt_command(int sub, u32 *in, int inlen)
> +struct mid_wdt {
> +	struct watchdog_device wd;
> +	struct device *dev;
> +	struct intel_scu_ipc_dev *scu;
> +};
> +
> +static inline int
> +wdt_command(struct mid_wdt *mid, int sub, const void *in, size_t inlen, size_t size)
>  {
> -	return intel_scu_ipc_command(IPC_WATCHDOG, sub, in, inlen, NULL, 0);
> +	struct intel_scu_ipc_dev *scu = mid->scu;
> +
> +	return intel_scu_ipc_dev_command_with_size(scu, IPC_WATCHDOG, sub, in,
> +						   inlen, size, NULL, 0);
>  }
>  
>  static int wdt_start(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret, in_size;
>  	int timeout = wd->timeout;
>  	struct ipc_wd_start {
> @@ -49,38 +59,41 @@ static int wdt_start(struct watchdog_device *wd)
>  	} ipc_wd_start = { timeout - MID_WDT_PRETIMEOUT, timeout };
>  
>  	/*
> -	 * SCU expects the input size for watchdog IPC to
> -	 * be based on 4 bytes
> +	 * SCU expects the input size for watchdog IPC to be 2 which is the
> +	 * size of the structure in dwords. SCU IPC normally takes bytes
> +	 * but this is a special case where we specify size to be different
> +	 * than inlen.
>  	 */
>  	in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
>  
> -	ret = wdt_command(SCU_WATCHDOG_START, (u32 *)&ipc_wd_start, in_size);
> +	ret = wdt_command(mid, SCU_WATCHDOG_START, &ipc_wd_start,
> +			  sizeof(ipc_wd_start), in_size);
>  	if (ret)
> -		dev_crit(dev, "error starting watchdog: %d\n", ret);
> +		dev_crit(mid->dev, "error starting watchdog: %d\n", ret);
>  
>  	return ret;
>  }
>  
>  static int wdt_ping(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret;
>  
> -	ret = wdt_command(SCU_WATCHDOG_KEEPALIVE, NULL, 0);
> +	ret = wdt_command(mid, SCU_WATCHDOG_KEEPALIVE, NULL, 0, 0);
>  	if (ret)
> -		dev_crit(dev, "Error executing keepalive: %d\n", ret);
> +		dev_crit(mid->dev, "Error executing keepalive: %d\n", ret);
>  
>  	return ret;
>  }
>  
>  static int wdt_stop(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret;
>  
> -	ret = wdt_command(SCU_WATCHDOG_STOP, NULL, 0);
> +	ret = wdt_command(mid, SCU_WATCHDOG_STOP, NULL, 0, 0);
>  	if (ret)
> -		dev_crit(dev, "Error stopping watchdog: %d\n", ret);
> +		dev_crit(mid->dev, "Error stopping watchdog: %d\n", ret);
>  
>  	return ret;
>  }
> @@ -110,6 +123,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct watchdog_device *wdt_dev;
>  	struct intel_mid_wdt_pdata *pdata = dev->platform_data;
> +	struct mid_wdt *mid;
>  	int ret;
>  
>  	if (!pdata) {
> @@ -123,10 +137,13 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  			return ret;
>  	}
>  
> -	wdt_dev = devm_kzalloc(dev, sizeof(*wdt_dev), GFP_KERNEL);
> -	if (!wdt_dev)
> +	mid = devm_kzalloc(dev, sizeof(*mid), GFP_KERNEL);
> +	if (!mid)
>  		return -ENOMEM;
>  
> +	mid->dev = dev;
> +	wdt_dev = &mid->wd;
> +
>  	wdt_dev->info = &mid_wdt_info;
>  	wdt_dev->ops = &mid_wdt_ops;
>  	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
> @@ -135,7 +152,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  	wdt_dev->parent = dev;
>  
>  	watchdog_set_nowayout(wdt_dev, WATCHDOG_NOWAYOUT);
> -	watchdog_set_drvdata(wdt_dev, dev);
> +	watchdog_set_drvdata(wdt_dev, mid);
>  
>  	ret = devm_request_irq(dev, pdata->irq, mid_wdt_irq,
>  			       IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog",
> @@ -145,6 +162,10 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	mid->scu = devm_intel_scu_ipc_dev_get(dev);
> +	if (!mid->scu)
> +		return -EPROBE_DEFER;
> +
>  	/*
>  	 * The firmware followed by U-Boot leaves the watchdog running
>  	 * with the default threshold which may vary. When we get here
> -- 
> 2.24.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata
  2020-01-08 11:41 ` [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata Mika Westerberg
@ 2020-01-08 16:37   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:37 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:26PM +0300, Mika Westerberg wrote:
> The driver gets driver_data from memory that is marked as const (which
> is probably put to read-only memory) and it then modifies it. This
> likely causes some sort of fault to happen.
> 
> Fix this by taking a copy of the structure.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Fixes: c94a8ff14de3 ("platform/x86: intel_mid_powerbtn: make mid_pb_ddata const")
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_mid_powerbtn.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
> index 292bace83f1e..6f436836fe50 100644
> --- a/drivers/platform/x86/intel_mid_powerbtn.c
> +++ b/drivers/platform/x86/intel_mid_powerbtn.c
> @@ -146,9 +146,10 @@ static int mid_pb_probe(struct platform_device *pdev)
>  
>  	input_set_capability(input, EV_KEY, KEY_POWER);
>  
> -	ddata = (struct mid_pb_ddata *)id->driver_data;
> +	ddata = devm_kmemdup(&pdev->dev, (void *)id->driver_data,
> +			     sizeof(*ddata), GFP_KERNEL);
>  	if (!ddata)
> -		return -ENODATA;
> +		return -ENOMEM;
>  
>  	ddata->dev = &pdev->dev;
>  	ddata->irq = irq;
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig
  2020-01-08 11:41 ` [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig Mika Westerberg
@ 2020-01-08 16:38   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:27PM +0300, Mika Westerberg wrote:
> This driver is by no means essential for system to boot up so remove
> default y from it.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 27d5b40fb717..dd4326736d11 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -997,7 +997,6 @@ config INTEL_SCU_IPC
>  config INTEL_SCU_IPC_UTIL
>  	tristate "Intel SCU IPC utility driver"
>  	depends on INTEL_SCU_IPC
> -	default y
>  	---help---
>  	  The IPC Util driver provides an interface with the SCU enabling
>  	  low level access for debug work and updating the firmware. Say
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets
  2020-01-08 11:41 ` [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets Mika Westerberg
@ 2020-01-08 16:39   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:39 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:28PM +0300, Mika Westerberg wrote:
> This makes the code more readable. These are taken from intel_pmc_ipc.c
> which implements the same thing.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 22 +++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index cdab916fbf92..a8be5bcb9832 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -99,11 +99,15 @@ struct intel_scu_ipc_dev {
>  
>  static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
>  
> +#define IPC_STATUS		0x04
> +#define IPC_STATUS_ERR		BIT(1)
> +#define IPC_STATUS_BUSY		BIT(0)
> +
>  /*
> - * IPC Read Buffer (Read Only):
> - * 16 byte buffer for receiving data from SCU, if IPC command
> - * processing results in response data
> + * IPC Write/Read Buffers:
> + * 16 byte buffer for sending and receiving data to and from SCU.
>   */
> +#define IPC_WRITE_BUFFER	0x80
>  #define IPC_READ_BUFFER		0x90
>  
>  #define IPC_I2C_CNTRL_ADDR	0
> @@ -135,7 +139,7 @@ static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
>   */
>  static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32 offset)
>  {
> -	writel(data, scu->ipc_base + 0x80 + offset);
> +	writel(data, scu->ipc_base + IPC_WRITE_BUFFER + offset);
>  }
>  
>  /*
> @@ -147,7 +151,7 @@ static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32
>   */
>  static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu)
>  {
> -	return __raw_readl(scu->ipc_base + 0x04);
> +	return __raw_readl(scu->ipc_base + IPC_STATUS);
>  }
>  
>  /* Read ipc byte data */
> @@ -169,17 +173,17 @@ static inline int busy_loop(struct intel_scu_ipc_dev *scu)
>  	u32 loop_count = 100000;
>  
>  	/* break if scu doesn't reset busy bit after huge retry */
> -	while ((status & BIT(0)) && --loop_count) {
> +	while ((status & IPC_STATUS_BUSY) && --loop_count) {
>  		udelay(1); /* scu processing time is in few u secods */
>  		status = ipc_read_status(scu);
>  	}
>  
> -	if (status & BIT(0)) {
> +	if (status & IPC_STATUS_BUSY) {
>  		dev_err(scu->dev, "IPC timed out");
>  		return -ETIMEDOUT;
>  	}
>  
> -	if (status & BIT(1))
> +	if (status & IPC_STATUS_ERR)
>  		return -EIO;
>  
>  	return 0;
> @@ -196,7 +200,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
>  	}
>  
>  	status = ipc_read_status(scu);
> -	if (status & BIT(1))
> +	if (status & IPC_STATUS_ERR)
>  		return -EIO;
>  
>  	return 0;
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support
  2020-01-08 11:41 ` [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support Mika Westerberg
@ 2020-01-08 16:39   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:39 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:29PM +0300, Mika Westerberg wrote:
> Moorestown support was removed years ago with by the commit 1a8359e411eb
> ("x86/mid: Remove Intel Moorestown"). Lincroft is the CPU side chip of
> Moorestown and not supported anymore so remove the code from the driver.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index a8be5bcb9832..6c44fe5e55b5 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -58,7 +58,6 @@
>  #define IPC_RWBUF_SIZE    20		/* IPC Read buffer Size */
>  #define IPC_IOC	          0x100		/* IPC command register IOC bit */
>  
> -#define PCI_DEVICE_ID_LINCROFT		0x082a
>  #define PCI_DEVICE_ID_PENWELL		0x080e
>  #define PCI_DEVICE_ID_CLOVERVIEW	0x08ea
>  #define PCI_DEVICE_ID_TANGIER		0x11a0
> @@ -70,12 +69,6 @@ struct intel_scu_ipc_pdata_t {
>  	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,
> @@ -677,7 +670,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  #define SCU_DEVICE(id, pdata)	{PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&pdata}
>  
>  static const struct pci_device_id pci_ids[] = {
> -	SCU_DEVICE(PCI_DEVICE_ID_LINCROFT,	intel_scu_ipc_lincroft_pdata),
>  	SCU_DEVICE(PCI_DEVICE_ID_PENWELL,	intel_scu_ipc_penwell_pdata),
>  	SCU_DEVICE(PCI_DEVICE_ID_CLOVERVIEW,	intel_scu_ipc_penwell_pdata),
>  	SCU_DEVICE(PCI_DEVICE_ID_TANGIER,	intel_scu_ipc_tangier_pdata),
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl()
  2020-01-08 11:41 ` [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl() Mika Westerberg
@ 2020-01-08 16:39   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:39 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:30PM +0300, Mika Westerberg wrote:
> There are no existing users for this functionality so drop it from the
> driver completely.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h |  3 --
>  drivers/platform/x86/intel_scu_ipc.c | 62 ----------------------------
>  2 files changed, 65 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index 4a8c6e817398..d7bbebf4b729 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -53,9 +53,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
>  int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
>  			      u32 *out, int outlen, u32 dptr, u32 sptr);
>  
> -/* I2C control api */
> -int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data);
> -
>  /* Update FW version */
>  int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
>  
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 6c44fe5e55b5..b39680b53387 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -64,28 +64,21 @@
>  
>  /* intel scu ipc driver data */
>  struct intel_scu_ipc_pdata_t {
> -	u32 i2c_base;
> -	u32 i2c_len;
>  	u8 irq_mode;
>  };
>  
>  /* 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 {
>  	struct device *dev;
>  	void __iomem *ipc_base;
> -	void __iomem *i2c_base;
>  	struct completion cmd_complete;
>  	u8 irq_mode;
>  };
> @@ -103,9 +96,6 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
>  #define IPC_WRITE_BUFFER	0x80
>  #define IPC_READ_BUFFER		0x90
>  
> -#define IPC_I2C_CNTRL_ADDR	0
> -#define I2C_DATA_ADDR		0x04
> -
>  static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
>  
>  /*
> @@ -549,54 +539,6 @@ int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
>  }
>  EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
>  
> -/* I2C commands */
> -#define IPC_I2C_WRITE 1 /* I2C Write command */
> -#define IPC_I2C_READ  2 /* I2C Read command */
> -
> -/**
> - *	intel_scu_ipc_i2c_cntrl		-	I2C read/write operations
> - *	@addr: I2C address + command bits
> - *	@data: data to read/write
> - *
> - *	Perform an an I2C read/write operation via the SCU. All locking is
> - *	handled for the caller. This function may sleep.
> - *
> - *	Returns an error code or 0 on success.
> - *
> - *	This has to be in the IPC driver for the locking.
> - */
> -int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
> -{
> -	struct intel_scu_ipc_dev *scu = &ipcdev;
> -	u32 cmd = 0;
> -
> -	mutex_lock(&ipclock);
> -	if (scu->dev == NULL) {
> -		mutex_unlock(&ipclock);
> -		return -ENODEV;
> -	}
> -	cmd = (addr >> 24) & 0xFF;
> -	if (cmd == IPC_I2C_READ) {
> -		writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
> -		/* Write not getting updated without delay */
> -		usleep_range(1000, 2000);
> -		*data = readl(scu->i2c_base + I2C_DATA_ADDR);
> -	} else if (cmd == IPC_I2C_WRITE) {
> -		writel(*data, scu->i2c_base + I2C_DATA_ADDR);
> -		usleep_range(1000, 2000);
> -		writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
> -	} else {
> -		dev_err(scu->dev,
> -			"intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
> -
> -		mutex_unlock(&ipclock);
> -		return -EIO;
> -	}
> -	mutex_unlock(&ipclock);
> -	return 0;
> -}
> -EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
> -
>  /*
>   * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
>   * When ioc bit is set to 1, caller api must wait for interrupt handler called
> @@ -649,10 +591,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  
>  	scu->ipc_base = pcim_iomap_table(pdev)[0];
>  
> -	scu->i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
> -	if (!scu->i2c_base)
> -		return -ENOMEM;
> -
>  	err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
>  			       scu);
>  	if (err)
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support
  2020-01-08 11:41 ` [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support Mika Westerberg
@ 2020-01-08 16:40   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:40 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:31PM +0300, Mika Westerberg wrote:
> 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.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 48 ++++++----------------------
>  1 file changed, 10 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index b39680b53387..43eaf9400c67 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -58,24 +58,6 @@
>  #define IPC_RWBUF_SIZE    20		/* IPC Read buffer Size */
>  #define IPC_IOC	          0x100		/* IPC command register IOC bit */
>  
> -#define PCI_DEVICE_ID_PENWELL		0x080e
> -#define PCI_DEVICE_ID_CLOVERVIEW	0x08ea
> -#define PCI_DEVICE_ID_TANGIER		0x11a0
> -
> -/* intel scu ipc driver data */
> -struct intel_scu_ipc_pdata_t {
> -	u8 irq_mode;
> -};
> -
> -/* Penwell and Cloverview */
> -static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
> -	.irq_mode = 1,
> -};
> -
> -static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
> -	.irq_mode = 0,
> -};
> -
>  struct intel_scu_ipc_dev {
>  	struct device *dev;
>  	void __iomem *ipc_base;
> @@ -86,6 +68,7 @@ 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)
>  #define IPC_STATUS_ERR		BIT(1)
>  #define IPC_STATUS_BUSY		BIT(0)
>  
> @@ -107,11 +90,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);
>  }
>  
>  /*
> @@ -549,9 +529,10 @@ EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
>  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;
>  }
> @@ -568,17 +549,10 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
>  	int err;
>  	struct intel_scu_ipc_dev *scu = &ipcdev;
> -	struct intel_scu_ipc_pdata_t *pdata;
>  
>  	if (scu->dev)		/* We support only one SCU */
>  		return -EBUSY;
>  
> -	pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data;
> -	if (!pdata)
> -		return -ENODEV;
> -
> -	scu->irq_mode = pdata->irq_mode;
> -
>  	err = pcim_enable_device(pdev);
>  	if (err)
>  		return err;
> @@ -605,13 +579,11 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	return 0;
>  }
>  
> -#define SCU_DEVICE(id, pdata)	{PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&pdata}
> -
>  static const struct pci_device_id pci_ids[] = {
> -	SCU_DEVICE(PCI_DEVICE_ID_PENWELL,	intel_scu_ipc_penwell_pdata),
> -	SCU_DEVICE(PCI_DEVICE_ID_CLOVERVIEW,	intel_scu_ipc_penwell_pdata),
> -	SCU_DEVICE(PCI_DEVICE_ID_TANGIER,	intel_scu_ipc_tangier_pdata),
> -	{}
> +	{ PCI_VDEVICE(INTEL, 0x080e) },
> +	{ PCI_VDEVICE(INTEL, 0x08ea) },
> +	{ PCI_VDEVICE(INTEL, 0x11a0) },
> +	{ }
>  };
>  
>  static struct pci_driver ipc_driver = {
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update()
  2020-01-08 11:41 ` [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update() Mika Westerberg
@ 2020-01-08 16:41   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:41 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:33PM +0300, Mika Westerberg wrote:
> There is no implementation for that anymore so drop the prototype.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index d7bbebf4b729..b2dde96e0611 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -53,9 +53,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
>  int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
>  			      u32 *out, int outlen, u32 dptr, u32 sptr);
>  
> -/* Update FW version */
> -int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
> -
>  extern struct blocking_notifier_head intel_scu_notifier;
>  
>  static inline void intel_scu_notifier_add(struct notifier_block *nb)
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros
  2020-01-08 11:41 ` [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros Mika Westerberg
@ 2020-01-08 16:41   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:41 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:34PM +0300, Mika Westerberg wrote:
> These macros are not used anywhere in the driver so drop them.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 8db0644900a3..997fdac920c6 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -26,11 +26,7 @@
>  #include <asm/intel_scu_ipc.h>
>  
>  /* IPC defines the following message types */
> -#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */
> -#define IPCMSG_BATTERY        0xEF /* Coulomb Counter Accumulator */
> -#define IPCMSG_FW_UPDATE      0xFE /* Firmware update */
> -#define IPCMSG_PCNTRL         0xFF /* Power controller unit read/write */
> -#define IPCMSG_FW_REVISION    0xF4 /* Get firmware revision */
> +#define IPCMSG_PCNTRL         0xff /* Power controller unit read/write */
>  
>  /* Command id associated with message IPCMSG_PCNTRL */
>  #define IPC_CMD_PCNTRL_W      0 /* Register write */
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]()
  2020-01-08 11:41 ` [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]() Mika Westerberg
@ 2020-01-08 16:41   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:41 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:35PM +0300, Mika Westerberg wrote:
> There are no users for these so we can remove them.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h | 12 -----
>  drivers/platform/x86/intel_scu_ipc.c | 68 ----------------------------
>  2 files changed, 80 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index b2dde96e0611..b59afa59a4cb 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -22,24 +22,12 @@
>  /* Read single register */
>  int intel_scu_ipc_ioread8(u16 addr, u8 *data);
>  
> -/* Read two sequential registers */
> -int intel_scu_ipc_ioread16(u16 addr, u16 *data);
> -
> -/* Read four sequential registers */
> -int intel_scu_ipc_ioread32(u16 addr, u32 *data);
> -
>  /* Read a vector */
>  int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
>  
>  /* Write single register */
>  int intel_scu_ipc_iowrite8(u16 addr, u8 data);
>  
> -/* Write two sequential registers */
> -int intel_scu_ipc_iowrite16(u16 addr, u16 data);
> -
> -/* Write four sequential registers */
> -int intel_scu_ipc_iowrite32(u16 addr, u32 data);
> -
>  /* Write a vector */
>  int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
>  
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 997fdac920c6..ba857e54800b 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -237,40 +237,6 @@ int intel_scu_ipc_ioread8(u16 addr, u8 *data)
>  }
>  EXPORT_SYMBOL(intel_scu_ipc_ioread8);
>  
> -/**
> - *	intel_scu_ipc_ioread16		-	read a word via the SCU
> - *	@addr: register on SCU
> - *	@data: return pointer for read word
> - *
> - *	Read a register pair. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> - *
> - *	This function may sleep.
> - */
> -int intel_scu_ipc_ioread16(u16 addr, u16 *data)
> -{
> -	u16 x[2] = {addr, addr + 1};
> -	return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> -}
> -EXPORT_SYMBOL(intel_scu_ipc_ioread16);
> -
> -/**
> - *	intel_scu_ipc_ioread32		-	read a dword via the SCU
> - *	@addr: register on SCU
> - *	@data: return pointer for read dword
> - *
> - *	Read four registers. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> - *
> - *	This function may sleep.
> - */
> -int intel_scu_ipc_ioread32(u16 addr, u32 *data)
> -{
> -	u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
> -	return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> -}
> -EXPORT_SYMBOL(intel_scu_ipc_ioread32);
> -
>  /**
>   *	intel_scu_ipc_iowrite8		-	write a byte via the SCU
>   *	@addr: register on SCU
> @@ -287,40 +253,6 @@ int intel_scu_ipc_iowrite8(u16 addr, u8 data)
>  }
>  EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
>  
> -/**
> - *	intel_scu_ipc_iowrite16		-	write a word via the SCU
> - *	@addr: register on SCU
> - *	@data: word to write
> - *
> - *	Write two registers. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> - *
> - *	This function may sleep.
> - */
> -int intel_scu_ipc_iowrite16(u16 addr, u16 data)
> -{
> -	u16 x[2] = {addr, addr + 1};
> -	return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> -}
> -EXPORT_SYMBOL(intel_scu_ipc_iowrite16);
> -
> -/**
> - *	intel_scu_ipc_iowrite32		-	write a dword via the SCU
> - *	@addr: register on SCU
> - *	@data: dword to write
> - *
> - *	Write four registers. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> - *
> - *	This function may sleep.
> - */
> -int intel_scu_ipc_iowrite32(u16 addr, u32 data)
> -{
> -	u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
> -	return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> -}
> -EXPORT_SYMBOL(intel_scu_ipc_iowrite32);
> -
>  /**
>   *	intel_scu_ipc_readvv		-	read a set of registers
>   *	@addr: register list
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command()
  2020-01-08 11:41 ` [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command() Mika Westerberg
@ 2020-01-08 16:42   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:42 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:36PM +0300, Mika Westerberg wrote:
> There is no user for this function so we can drop it from the driver.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h |  2 -
>  drivers/platform/x86/intel_scu_ipc.c | 63 ----------------------------
>  2 files changed, 65 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index b59afa59a4cb..2a1442ba6e78 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -38,8 +38,6 @@ int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
>  int intel_scu_ipc_simple_command(int cmd, int sub);
>  int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
>  			  u32 *out, int outlen);
> -int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
> -			      u32 *out, int outlen, u32 dptr, u32 sptr);
>  
>  extern struct blocking_notifier_head intel_scu_notifier;
>  
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index ba857e54800b..93a810fa6c8a 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -383,69 +383,6 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
>  }
>  EXPORT_SYMBOL(intel_scu_ipc_command);
>  
> -#define IPC_SPTR		0x08
> -#define IPC_DPTR		0x0C
> -
> -/**
> - * intel_scu_ipc_raw_command() - IPC command with data and pointers
> - * @cmd:	IPC command code.
> - * @sub:	IPC command sub type.
> - * @in:		input data of this IPC command.
> - * @inlen:	input data length in dwords.
> - * @out:	output data of this IPC command.
> - * @outlen:	output data length in dwords.
> - * @sptr:	data writing to SPTR register.
> - * @dptr:	data writing to DPTR register.
> - *
> - * Send an IPC command to SCU with input/output data and source/dest pointers.
> - *
> - * Return:	an IPC error code or 0 on success.
> - */
> -int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
> -			      u32 *out, int outlen, u32 dptr, u32 sptr)
> -{
> -	struct intel_scu_ipc_dev *scu = &ipcdev;
> -	int inbuflen = DIV_ROUND_UP(inlen, 4);
> -	u32 inbuf[4];
> -	int i, err;
> -
> -	/* Up to 16 bytes */
> -	if (inbuflen > 4)
> -		return -EINVAL;
> -
> -	mutex_lock(&ipclock);
> -	if (scu->dev == NULL) {
> -		mutex_unlock(&ipclock);
> -		return -ENODEV;
> -	}
> -
> -	writel(dptr, scu->ipc_base + IPC_DPTR);
> -	writel(sptr, scu->ipc_base + IPC_SPTR);
> -
> -	/*
> -	 * SRAM controller doesn't support 8-bit writes, it only
> -	 * supports 32-bit writes, so we have to copy input data into
> -	 * the temporary buffer, and SCU FW will use the inlen to
> -	 * determine the actual input data length in the temporary
> -	 * buffer.
> -	 */
> -	memcpy(inbuf, in, inlen);
> -
> -	for (i = 0; i < inbuflen; i++)
> -		ipc_data_writel(scu, inbuf[i], 4 * i);
> -
> -	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(scu, 4 * i);
> -	}
> -
> -	mutex_unlock(&ipclock);
> -	return err;
> -}
> -EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
> -
>  /*
>   * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
>   * When ioc bit is set to 1, caller api must wait for interrupt handler called
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions
  2020-01-08 11:41 ` [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions Mika Westerberg
@ 2020-01-08 16:42   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:42 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:38PM +0300, Mika Westerberg wrote:
> Format kernel-doc comments of the exported functions to follow the
> typical format that does not have tab indentation. Also capitalize
> parameter descriptions and add a missing period.
> 
> No functional changes intended.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 112 +++++++++++++--------------
>  1 file changed, 55 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index e3f658f1b40a..b1ac381bb7dd 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -219,14 +219,14 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
>  }
>  
>  /**
> - *	intel_scu_ipc_ioread8		-	read a word via the SCU
> - *	@addr: register on SCU
> - *	@data: return pointer for read byte
> + * intel_scu_ipc_ioread8		-	read a word via the SCU
> + * @addr: Register on SCU
> + * @data: Return pointer for read byte
>   *
> - *	Read a single register. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> + * Read a single register. Returns %0 on success or an error code. All
> + * locking between SCU accesses is handled for the caller.
>   *
> - *	This function may sleep.
> + * This function may sleep.
>   */
>  int intel_scu_ipc_ioread8(u16 addr, u8 *data)
>  {
> @@ -235,14 +235,14 @@ int intel_scu_ipc_ioread8(u16 addr, u8 *data)
>  EXPORT_SYMBOL(intel_scu_ipc_ioread8);
>  
>  /**
> - *	intel_scu_ipc_iowrite8		-	write a byte via the SCU
> - *	@addr: register on SCU
> - *	@data: byte to write
> + * intel_scu_ipc_iowrite8		-	write a byte via the SCU
> + * @addr: Register on SCU
> + * @data: Byte to write
>   *
> - *	Write a single register. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> + * Write a single register. Returns %0 on success or an error code. All
> + * locking between SCU accesses is handled for the caller.
>   *
> - *	This function may sleep.
> + * This function may sleep.
>   */
>  int intel_scu_ipc_iowrite8(u16 addr, u8 data)
>  {
> @@ -251,17 +251,17 @@ int intel_scu_ipc_iowrite8(u16 addr, u8 data)
>  EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
>  
>  /**
> - *	intel_scu_ipc_readvv		-	read a set of registers
> - *	@addr: register list
> - *	@data: bytes to return
> - *	@len: length of array
> + * intel_scu_ipc_readvv		-	read a set of registers
> + * @addr: Register list
> + * @data: Bytes to return
> + * @len: Length of array
>   *
> - *	Read registers. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> + * Read registers. Returns %0 on success or an error code. All locking
> + * between SCU accesses is handled for the caller.
>   *
> - *	The largest array length permitted by the hardware is 5 items.
> + * The largest array length permitted by the hardware is 5 items.
>   *
> - *	This function may sleep.
> + * This function may sleep.
>   */
>  int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
>  {
> @@ -270,18 +270,17 @@ int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
>  EXPORT_SYMBOL(intel_scu_ipc_readv);
>  
>  /**
> - *	intel_scu_ipc_writev		-	write a set of registers
> - *	@addr: register list
> - *	@data: bytes to write
> - *	@len: length of array
> + * intel_scu_ipc_writev		-	write a set of registers
> + * @addr: Register list
> + * @data: Bytes to write
> + * @len: Length of array
>   *
> - *	Write registers. Returns 0 on success or an error code. All
> - *	locking between SCU accesses is handled for the caller.
> + * Write registers. Returns %0 on success or an error code. All locking
> + * between SCU accesses is handled for the caller.
>   *
> - *	The largest array length permitted by the hardware is 5 items.
> - *
> - *	This function may sleep.
> + * The largest array length permitted by the hardware is 5 items.
>   *
> + * This function may sleep.
>   */
>  int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
>  {
> @@ -290,19 +289,18 @@ int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
>  EXPORT_SYMBOL(intel_scu_ipc_writev);
>  
>  /**
> - *	intel_scu_ipc_update_register	-	r/m/w a register
> - *	@addr: register address
> - *	@bits: bits to update
> - *	@mask: mask of bits to update
> + * intel_scu_ipc_update_register	-	r/m/w a register
> + * @addr: Register address
> + * @bits: Bits to update
> + * @mask: Mask of bits to update
>   *
> - *	Read-modify-write power control unit register. The first data argument
> - *	must be register value and second is mask value
> - *	mask is a bitmap that indicates which bits to update.
> - *	0 = masked. Don't modify this bit, 1 = modify this bit.
> - *	returns 0 on success or an error code.
> + * Read-modify-write power control unit register. The first data argument
> + * must be register value and second is mask value mask is a bitmap that
> + * indicates which bits to update. %0 = masked. Don't modify this bit, %1 =
> + * modify this bit. returns %0 on success or an error code.
>   *
> - *	This function may sleep. Locking between SCU accesses is handled
> - *	for the caller.
> + * This function may sleep. Locking between SCU accesses is handled
> + * for the caller.
>   */
>  int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
>  {
> @@ -312,16 +310,16 @@ int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
>  EXPORT_SYMBOL(intel_scu_ipc_update_register);
>  
>  /**
> - *	intel_scu_ipc_simple_command	-	send a simple command
> - *	@cmd: command
> - *	@sub: sub type
> + * intel_scu_ipc_simple_command	-	send a simple command
> + * @cmd: Command
> + * @sub: Sub type
>   *
> - *	Issue a simple command to the SCU. Do not use this interface if
> - *	you must then access data as any data values may be overwritten
> - *	by another SCU access by the time this function returns.
> + * Issue a simple command to the SCU. Do not use this interface if you must
> + * then access data as any data values may be overwritten by another SCU
> + * access by the time this function returns.
>   *
> - *	This function may sleep. Locking for SCU accesses is handled for
> - *	the caller.
> + * This function may sleep. Locking for SCU accesses is handled for the
> + * caller.
>   */
>  int intel_scu_ipc_simple_command(int cmd, int sub)
>  {
> @@ -341,16 +339,16 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
>  EXPORT_SYMBOL(intel_scu_ipc_simple_command);
>  
>  /**
> - *	intel_scu_ipc_command	-	command with data
> - *	@cmd: command
> - *	@sub: sub type
> - *	@in: input data
> - *	@inlen: input length in dwords
> - *	@out: output data
> - *	@outlein: output length in dwords
> + * intel_scu_ipc_command	-	command with data
> + * @cmd: Command
> + * @sub: Sub type
> + * @in: Input data
> + * @inlen: Input length in dwords
> + * @out: Output data
> + * @outlen: Output length in dwords
>   *
> - *	Issue a command to the SCU which involves data transfers. Do the
> - *	data copies under the lock but leave it for the caller to interpret
> + * Issue a command to the SCU which involves data transfers. Do the
> + * data copies under the lock but leave it for the caller to interpret.
>   */
>  int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
>  			  u32 *out, int outlen)
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use " Mika Westerberg
@ 2020-01-08 16:43   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:43 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:40PM +0300, Mika Westerberg wrote:
> This converts the power button driver to use the new SCU IPC API where
> the SCU IPC instance is passed to the functions.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_mid_powerbtn.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
> index 6f436836fe50..1fdcdef1d89f 100644
> --- a/drivers/platform/x86/intel_mid_powerbtn.c
> +++ b/drivers/platform/x86/intel_mid_powerbtn.c
> @@ -46,6 +46,7 @@ struct mid_pb_ddata {
>  	unsigned short mirqlvl1_addr;
>  	unsigned short pbstat_addr;
>  	u8 pbstat_mask;
> +	struct intel_scu_ipc_dev *scu;
>  	int (*setup)(struct mid_pb_ddata *ddata);
>  };
>  
> @@ -55,7 +56,8 @@ static int mid_pbstat(struct mid_pb_ddata *ddata, int *value)
>  	int ret;
>  	u8 pbstat;
>  
> -	ret = intel_scu_ipc_ioread8(ddata->pbstat_addr, &pbstat);
> +	ret = intel_scu_ipc_dev_ioread8(ddata->scu, ddata->pbstat_addr,
> +					&pbstat);
>  	if (ret)
>  		return ret;
>  
> @@ -67,14 +69,15 @@ static int mid_pbstat(struct mid_pb_ddata *ddata, int *value)
>  
>  static int mid_irq_ack(struct mid_pb_ddata *ddata)
>  {
> -	return intel_scu_ipc_update_register(ddata->mirqlvl1_addr, 0, MSIC_PWRBTNM);
> +	return intel_scu_ipc_dev_update(ddata->scu, ddata->mirqlvl1_addr, 0,
> +					MSIC_PWRBTNM);
>  }
>  
>  static int mrfld_setup(struct mid_pb_ddata *ddata)
>  {
>  	/* Unmask the PBIRQ and MPBIRQ on Tangier */
> -	intel_scu_ipc_update_register(BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
> -	intel_scu_ipc_update_register(BCOVE_PBIRQMASK, 0, MSIC_PWRBTNM);
> +	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQ, 0, MSIC_PWRBTNM);
> +	intel_scu_ipc_dev_update(ddata->scu, BCOVE_PBIRQMASK, 0, MSIC_PWRBTNM);
>  
>  	return 0;
>  }
> @@ -161,6 +164,10 @@ static int mid_pb_probe(struct platform_device *pdev)
>  			return error;
>  	}
>  
> +	ddata->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
> +	if (!ddata->scu)
> +		return -EPROBE_DEFER;
> +
>  	error = devm_request_threaded_irq(&pdev->dev, irq, NULL, mid_pb_isr,
>  					  IRQF_ONESHOT, DRIVER_NAME, ddata);
>  	if (error) {
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: " Mika Westerberg
@ 2020-01-08 16:45   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:45 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:42PM +0300, Mika Westerberg wrote:
> Convert the IPC util to use the new SCU IPC API where the SCU IPC
> instance is passed to the functions.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipcutil.c | 43 +++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
> index 8afe6fa06d7b..b7c10c15a3d6 100644
> --- a/drivers/platform/x86/intel_scu_ipcutil.c
> +++ b/drivers/platform/x86/intel_scu_ipcutil.c
> @@ -22,6 +22,9 @@
>  
>  static int major;
>  
> +struct intel_scu_ipc_dev *scu;
> +static DEFINE_MUTEX(scu_lock);
> +
>  /* IOCTL commands */
>  #define	INTE_SCU_IPC_REGISTER_READ	0
>  #define INTE_SCU_IPC_REGISTER_WRITE	1
> @@ -52,12 +55,12 @@ static int scu_reg_access(u32 cmd, struct scu_ipc_data  *data)
>  
>  	switch (cmd) {
>  	case INTE_SCU_IPC_REGISTER_READ:
> -		return intel_scu_ipc_readv(data->addr, data->data, count);
> +		return intel_scu_ipc_dev_readv(scu, data->addr, data->data, count);
>  	case INTE_SCU_IPC_REGISTER_WRITE:
> -		return intel_scu_ipc_writev(data->addr, data->data, count);
> +		return intel_scu_ipc_dev_writev(scu, data->addr, data->data, count);
>  	case INTE_SCU_IPC_REGISTER_UPDATE:
> -		return intel_scu_ipc_update_register(data->addr[0],
> -						    data->data[0], data->mask);
> +		return intel_scu_ipc_dev_update(scu, data->addr[0], data->data[0],
> +						data->mask);
>  	default:
>  		return -ENOTTY;
>  	}
> @@ -91,8 +94,40 @@ static long scu_ipc_ioctl(struct file *fp, unsigned int cmd,
>  	return 0;
>  }
>  
> +static int scu_ipc_open(struct inode *inode, struct file *file)
> +{
> +	int ret = 0;
> +
> +	/* Only single open at the time */
> +	mutex_lock(&scu_lock);
> +	if (scu) {
> +		ret = -EBUSY;
> +		goto unlock;
> +	}
> +
> +	scu = intel_scu_ipc_dev_get();
> +	if (!scu)
> +		ret = -ENODEV;
> +
> +unlock:
> +	mutex_unlock(&scu_lock);
> +	return ret;
> +}
> +
> +static int scu_ipc_release(struct inode *inode, struct file *file)
> +{
> +	mutex_lock(&scu_lock);
> +	intel_scu_ipc_dev_put(scu);
> +	scu = NULL;
> +	mutex_unlock(&scu_lock);
> +
> +	return 0;
> +}
> +
>  static const struct file_operations scu_ipc_fops = {
>  	.unlocked_ioctl = scu_ipc_ioctl,
> +	.open = scu_ipc_open,
> +	.release = scu_ipc_release,
>  };
>  
>  static int __init ipc_module_init(void)
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static
  2020-01-08 11:41 ` [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static Mika Westerberg
@ 2020-01-08 16:46   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:46 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:43PM +0300, Mika Westerberg wrote:
> This function is not called outside of intel_pmc_ipc.c so we can make it
> static instead.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h | 6 ------
>  drivers/platform/x86/intel_pmc_ipc.c | 3 +--
>  2 files changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index 9e7adcdbe031..3b2e8b461520 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -40,7 +40,6 @@ int intel_pmc_s0ix_counter_read(u64 *data);
>  int intel_pmc_gcr_read(u32 offset, u32 *data);
>  int intel_pmc_gcr_read64(u32 offset, u64 *data);
>  int intel_pmc_gcr_write(u32 offset, u32 data);
> -int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val);
>  
>  #else
>  
> @@ -81,11 +80,6 @@ static inline int intel_pmc_gcr_write(u32 offset, u32 data)
>  	return -EINVAL;
>  }
>  
> -static inline int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
> -{
> -	return -EINVAL;
> -}
> -
>  #endif /*CONFIG_INTEL_PMC_IPC*/
>  
>  #endif
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 5c1da2bb1435..9229c7a16536 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -309,7 +309,7 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
>   *
>   * Return:	negative value on error or 0 on success.
>   */
> -int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
> +static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
>  {
>  	u32 new_val;
>  	int ret = 0;
> @@ -339,7 +339,6 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
>  	spin_unlock(&ipcdev.gcr_lock);
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
>  
>  static int update_no_reboot_bit(void *priv, bool set)
>  {
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static
  2020-01-08 11:41 ` [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static Mika Westerberg
@ 2020-01-08 16:46   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:46 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:44PM +0300, Mika Westerberg wrote:
> This function is not called outside of intel_pmc_ipc.c so we can make it
> static instead.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h | 6 ------
>  drivers/platform/x86/intel_pmc_ipc.c | 3 +--
>  2 files changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index 3b2e8b461520..b4f804877651 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -31,7 +31,6 @@
>  
>  #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
>  
> -int intel_pmc_ipc_simple_command(int cmd, int sub);
>  int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  		u32 *out, u32 outlen, u32 dptr, u32 sptr);
>  int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
> @@ -43,11 +42,6 @@ int intel_pmc_gcr_write(u32 offset, u32 data);
>  
>  #else
>  
> -static inline int intel_pmc_ipc_simple_command(int cmd, int sub)
> -{
> -	return -EINVAL;
> -}
> -
>  static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  		u32 *out, u32 outlen, u32 dptr, u32 sptr)
>  {
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 9229c7a16536..53551f5474a7 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -404,7 +404,7 @@ static int intel_pmc_ipc_check_status(void)
>   *
>   * Return:	an IPC error code or 0 on success.
>   */
> -int intel_pmc_ipc_simple_command(int cmd, int sub)
> +static int intel_pmc_ipc_simple_command(int cmd, int sub)
>  {
>  	int ret;
>  
> @@ -419,7 +419,6 @@ int intel_pmc_ipc_simple_command(int cmd, int sub)
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);
>  
>  /**
>   * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static
  2020-01-08 11:41 ` [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static Mika Westerberg
@ 2020-01-08 16:46   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:46 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:45PM +0300, Mika Westerberg wrote:
> This function is not called outside of intel_pmc_ipc.c so we can make it
> static instead.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h | 8 --------
>  drivers/platform/x86/intel_pmc_ipc.c | 5 ++---
>  2 files changed, 2 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index b4f804877651..966ff2171ff9 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -31,8 +31,6 @@
>  
>  #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
>  
> -int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
> -		u32 *out, u32 outlen, u32 dptr, u32 sptr);
>  int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  		u32 *out, u32 outlen);
>  int intel_pmc_s0ix_counter_read(u64 *data);
> @@ -42,12 +40,6 @@ int intel_pmc_gcr_write(u32 offset, u32 data);
>  
>  #else
>  
> -static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
> -		u32 *out, u32 outlen, u32 dptr, u32 sptr)
> -{
> -	return -EINVAL;
> -}
> -
>  static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  		u32 *out, u32 outlen)
>  {
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 53551f5474a7..83f47df1c4a5 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -435,8 +435,8 @@ static int intel_pmc_ipc_simple_command(int cmd, int sub)
>   *
>   * Return:	an IPC error code or 0 on success.
>   */
> -int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
> -			  u32 outlen, u32 dptr, u32 sptr)
> +static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
> +				 u32 outlen, u32 dptr, u32 sptr)
>  {
>  	u32 wbuf[4] = { 0 };
>  	int ret;
> @@ -468,7 +468,6 @@ int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd);
>  
>  /**
>   * intel_pmc_ipc_command() -  IPC command with input/output data
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write()
  2020-01-08 11:41 ` [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write() Mika Westerberg
@ 2020-01-08 16:47   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:47 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:46PM +0300, Mika Westerberg wrote:
> These functions are not used anywhere so drop them completely.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h | 12 ------
>  drivers/platform/x86/intel_pmc_ipc.c | 59 ----------------------------
>  2 files changed, 71 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index 966ff2171ff9..e6da1ce26256 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -34,9 +34,7 @@
>  int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  		u32 *out, u32 outlen);
>  int intel_pmc_s0ix_counter_read(u64 *data);
> -int intel_pmc_gcr_read(u32 offset, u32 *data);
>  int intel_pmc_gcr_read64(u32 offset, u64 *data);
> -int intel_pmc_gcr_write(u32 offset, u32 data);
>  
>  #else
>  
> @@ -51,21 +49,11 @@ static inline int intel_pmc_s0ix_counter_read(u64 *data)
>  	return -EINVAL;
>  }
>  
> -static inline int intel_pmc_gcr_read(u32 offset, u32 *data)
> -{
> -	return -EINVAL;
> -}
> -
>  static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
>  {
>  	return -EINVAL;
>  }
>  
> -static inline int intel_pmc_gcr_write(u32 offset, u32 data)
> -{
> -	return -EINVAL;
> -}
> -
>  #endif /*CONFIG_INTEL_PMC_IPC*/
>  
>  #endif
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 83f47df1c4a5..677ed470e14e 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -210,35 +210,6 @@ static inline int is_gcr_valid(u32 offset)
>  	return 0;
>  }
>  
> -/**
> - * intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
> - * @offset:	offset of GCR register from GCR address base
> - * @data:	data pointer for storing the register output
> - *
> - * Reads the 32-bit PMC GCR register at given offset.
> - *
> - * Return:	negative value on error or 0 on success.
> - */
> -int intel_pmc_gcr_read(u32 offset, u32 *data)
> -{
> -	int ret;
> -
> -	spin_lock(&ipcdev.gcr_lock);
> -
> -	ret = is_gcr_valid(offset);
> -	if (ret < 0) {
> -		spin_unlock(&ipcdev.gcr_lock);
> -		return ret;
> -	}
> -
> -	*data = readl(ipcdev.gcr_mem_base + offset);
> -
> -	spin_unlock(&ipcdev.gcr_lock);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
> -
>  /**
>   * intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
>   * @offset:	offset of GCR register from GCR address base
> @@ -268,36 +239,6 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data)
>  }
>  EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
>  
> -/**
> - * intel_pmc_gcr_write() - Write PMC GCR register
> - * @offset:	offset of GCR register from GCR address base
> - * @data:	register update value
> - *
> - * Writes the PMC GCR register of given offset with given
> - * value.
> - *
> - * Return:	negative value on error or 0 on success.
> - */
> -int intel_pmc_gcr_write(u32 offset, u32 data)
> -{
> -	int ret;
> -
> -	spin_lock(&ipcdev.gcr_lock);
> -
> -	ret = is_gcr_valid(offset);
> -	if (ret < 0) {
> -		spin_unlock(&ipcdev.gcr_lock);
> -		return ret;
> -	}
> -
> -	writel(data, ipcdev.gcr_mem_base + offset);
> -
> -	spin_unlock(&ipcdev.gcr_lock);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
> -
>  /**
>   * intel_pmc_gcr_update() - Update PMC GCR register bits
>   * @offset:	offset of GCR register from GCR address base
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb()
  2020-01-08 11:41 ` [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb() Mika Westerberg
@ 2020-01-08 16:47   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:47 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:47PM +0300, Mika Westerberg wrote:
> This function is not used anywhere so drop it completely.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_pmc_ipc.c | 5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 677ed470e14e..83b106f66fa6 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -184,11 +184,6 @@ static inline void ipc_data_writel(u32 data, u32 offset)
>  	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
>  }
>  
> -static inline u8 __maybe_unused ipc_data_readb(u32 offset)
> -{
> -	return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
> -}
> -
>  static inline u32 ipc_data_readl(u32 offset)
>  {
>  	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes
  2020-01-08 11:41 ` [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes Mika Westerberg
@ 2020-01-08 16:47   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:47 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:48PM +0300, Mika Westerberg wrote:
> There is no point including headers that are not needed in the driver so
> drop them.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_pmc_ipc.c | 10 ----------
>  1 file changed, 10 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 83b106f66fa6..8527327d88c7 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -12,23 +12,13 @@
>   */
>  
>  #include <linux/acpi.h>
> -#include <linux/atomic.h>
> -#include <linux/bitops.h>
>  #include <linux/delay.h>
> -#include <linux/device.h>
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
>  #include <linux/io-64-nonatomic-lo-hi.h>
> -#include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/notifier.h>
>  #include <linux/pci.h>
>  #include <linux/platform_device.h>
> -#include <linux/pm.h>
> -#include <linux/pm_qos.h>
> -#include <linux/sched.h>
> -#include <linux/spinlock.h>
> -#include <linux/suspend.h>
>  
>  #include <asm/intel_pmc_ipc.h>
>  
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using SCU IPC
  2020-01-08 11:41 ` [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using " Mika Westerberg
@ 2020-01-08 16:52   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:52 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:50PM +0300, Mika Westerberg wrote:
> SCU IPC is pretty much the same IPC implemented in the intel_pmc_ipc
> driver so drop the duplicate implementation and call directly the SCU
> IPC.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Couple of nits below.

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/Kconfig         |   1 +
>  drivers/platform/x86/intel_pmc_ipc.c | 299 +++++----------------------
>  2 files changed, 48 insertions(+), 252 deletions(-)
> 
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index e9ba81fc1770..797683c5d005 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1193,6 +1193,7 @@ config INTEL_SMARTCONNECT
>  config INTEL_PMC_IPC
>  	tristate "Intel PMC IPC Driver"
>  	depends on ACPI && PCI
> +	select INTEL_SCU_IPC
>  	---help---
>  	This driver provides support for PMC control on some Intel platforms.
>  	The PMC is an ARC processor which defines IPC commands for communication
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 8527327d88c7..10505fbd01b5 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -21,28 +21,10 @@
>  #include <linux/platform_device.h>
>  
>  #include <asm/intel_pmc_ipc.h>
> +#include <asm/intel_scu_ipc.h>
>  
>  #include <linux/platform_data/itco_wdt.h>
>  
> -/*
> - * IPC registers
> - * The IA write to IPC_CMD command register triggers an interrupt to the ARC,
> - * The ARC handles the interrupt and services it, writing optional data to
> - * the IPC1 registers, updates the IPC_STS response register with the status.
> - */
> -#define IPC_CMD			0x00
> -#define		IPC_CMD_MSI		BIT(8)
> -#define		IPC_CMD_SIZE		16
> -#define		IPC_CMD_SUBCMD		12
> -#define IPC_STATUS		0x04
> -#define		IPC_STATUS_IRQ		BIT(2)
> -#define		IPC_STATUS_ERR		BIT(1)
> -#define		IPC_STATUS_BUSY		BIT(0)
> -#define IPC_SPTR		0x08
> -#define IPC_DPTR		0x0C
> -#define IPC_WRITE_BUFFER	0x80
> -#define IPC_READ_BUFFER		0x90
> -
>  /* Residency with clock rate at 19.2MHz to usecs */
>  #define S0IX_RESIDENCY_IN_USECS(d, s)		\
>  ({						\
> @@ -51,16 +33,6 @@
>  	result;					\
>  })
>  
> -/*
> - * 16-byte buffer for sending data associated with IPC command.
> - */
> -#define IPC_DATA_BUFFER_SIZE	16
> -
> -#define IPC_LOOP_CNT		3000000
> -#define IPC_MAX_SEC		3
> -
> -#define IPC_TRIGGER_MODE_IRQ		true
> -
>  /* exported resources from IFWI */
>  #define PLAT_RESOURCE_IPC_INDEX		0
>  #define PLAT_RESOURCE_IPC_SIZE		0x1000
> @@ -103,11 +75,6 @@
>  
>  static struct intel_pmc_ipc_dev {
>  	struct device *dev;
> -	void __iomem *ipc_base;
> -	bool irq_mode;
> -	int irq;
> -	int cmd;
> -	struct completion cmd_complete;
>  
>  	/* The following PMC BARs share the same ACPI device with the IPC */
>  	resource_size_t acpi_io_base;
> @@ -132,53 +99,6 @@ static struct intel_pmc_ipc_dev {
>  	struct platform_device *telemetry_dev;
>  } ipcdev;
>  
> -static char *ipc_err_sources[] = {
> -	[IPC_ERR_NONE] =
> -		"no error",
> -	[IPC_ERR_CMD_NOT_SUPPORTED] =
> -		"command not supported",
> -	[IPC_ERR_CMD_NOT_SERVICED] =
> -		"command not serviced",
> -	[IPC_ERR_UNABLE_TO_SERVICE] =
> -		"unable to service",
> -	[IPC_ERR_CMD_INVALID] =
> -		"command invalid",
> -	[IPC_ERR_CMD_FAILED] =
> -		"command failed",
> -	[IPC_ERR_EMSECURITY] =
> -		"Invalid Battery",
> -	[IPC_ERR_UNSIGNEDKERNEL] =
> -		"Unsigned kernel",
> -};
> -
> -/* Prevent concurrent calls to the PMC */
> -static DEFINE_MUTEX(ipclock);
> -
> -static inline void ipc_send_command(u32 cmd)
> -{
> -	ipcdev.cmd = cmd;
> -	if (ipcdev.irq_mode) {
> -		reinit_completion(&ipcdev.cmd_complete);
> -		cmd |= IPC_CMD_MSI;
> -	}
> -	writel(cmd, ipcdev.ipc_base + IPC_CMD);
> -}
> -
> -static inline u32 ipc_read_status(void)
> -{
> -	return readl(ipcdev.ipc_base + IPC_STATUS);
> -}
> -
> -static inline void ipc_data_writel(u32 data, u32 offset)
> -{
> -	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
> -}
> -
> -static inline u32 ipc_data_readl(u32 offset)
> -{
> -	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
> -}
> -
>  static inline u64 gcr_data_readq(u32 offset)
>  {
>  	return readq(ipcdev.gcr_mem_base + offset);
> @@ -274,127 +194,6 @@ static int update_no_reboot_bit(void *priv, bool set)
>  				    PMC_CFG_NO_REBOOT_MASK, value);
>  }
>  
> -static int intel_pmc_ipc_check_status(void)
> -{
> -	int status;
> -	int ret = 0;
> -
> -	if (ipcdev.irq_mode) {
> -		if (0 == wait_for_completion_timeout(
> -				&ipcdev.cmd_complete, IPC_MAX_SEC * HZ))
> -			ret = -ETIMEDOUT;
> -	} else {
> -		int loop_count = IPC_LOOP_CNT;
> -
> -		while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count)
> -			udelay(1);
> -		if (loop_count == 0)
> -			ret = -ETIMEDOUT;
> -	}
> -
> -	status = ipc_read_status();
> -	if (ret == -ETIMEDOUT) {
> -		dev_err(ipcdev.dev,
> -			"IPC timed out, TS=0x%x, CMD=0x%x\n",
> -			status, ipcdev.cmd);
> -		return ret;
> -	}
> -
> -	if (status & IPC_STATUS_ERR) {
> -		int i;
> -
> -		ret = -EIO;
> -		i = (status >> IPC_CMD_SIZE) & 0xFF;
> -		if (i < ARRAY_SIZE(ipc_err_sources))
> -			dev_err(ipcdev.dev,
> -				"IPC failed: %s, STS=0x%x, CMD=0x%x\n",
> -				ipc_err_sources[i], status, ipcdev.cmd);
> -		else
> -			dev_err(ipcdev.dev,
> -				"IPC failed: unknown, STS=0x%x, CMD=0x%x\n",
> -				status, ipcdev.cmd);
> -		if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY))
> -			ret = -EACCES;
> -	}
> -
> -	return ret;
> -}
> -
> -/**
> - * intel_pmc_ipc_simple_command() - Simple IPC command
> - * @cmd:	IPC command code.
> - * @sub:	IPC command sub type.
> - *
> - * Send a simple IPC command to PMC when don't need to specify
> - * input/output data and source/dest pointers.
> - *
> - * Return:	an IPC error code or 0 on success.
> - */
> -static int intel_pmc_ipc_simple_command(int cmd, int sub)
> -{
> -	int ret;
> -
> -	mutex_lock(&ipclock);
> -	if (ipcdev.dev == NULL) {
> -		mutex_unlock(&ipclock);
> -		return -ENODEV;
> -	}
> -	ipc_send_command(sub << IPC_CMD_SUBCMD | cmd);
> -	ret = intel_pmc_ipc_check_status();
> -	mutex_unlock(&ipclock);
> -
> -	return ret;
> -}
> -
> -/**
> - * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
> - * @cmd:	IPC command code.
> - * @sub:	IPC command sub type.
> - * @in:		input data of this IPC command.
> - * @inlen:	input data length in bytes.
> - * @out:	output data of this IPC command.
> - * @outlen:	output data length in dwords.
> - * @sptr:	data writing to SPTR register.
> - * @dptr:	data writing to DPTR register.
> - *
> - * Send an IPC command to PMC with input/output data and source/dest pointers.
> - *
> - * Return:	an IPC error code or 0 on success.
> - */
> -static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
> -				 u32 outlen, u32 dptr, u32 sptr)
> -{
> -	u32 wbuf[4] = { 0 };
> -	int ret;
> -	int i;
> -
> -	if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4)
> -		return -EINVAL;
> -
> -	mutex_lock(&ipclock);
> -	if (ipcdev.dev == NULL) {
> -		mutex_unlock(&ipclock);
> -		return -ENODEV;
> -	}
> -	memcpy(wbuf, in, inlen);
> -	writel(dptr, ipcdev.ipc_base + IPC_DPTR);
> -	writel(sptr, ipcdev.ipc_base + IPC_SPTR);
> -	/* The input data register is 32bit register and inlen is in Byte */
> -	for (i = 0; i < ((inlen + 3) / 4); i++)
> -		ipc_data_writel(wbuf[i], 4 * i);
> -	ipc_send_command((inlen << IPC_CMD_SIZE) |
> -			(sub << IPC_CMD_SUBCMD) | cmd);
> -	ret = intel_pmc_ipc_check_status();
> -	if (!ret) {
> -		/* out is read from 32bit register and outlen is in 32bit */
> -		for (i = 0; i < outlen; i++)
> -			*out++ = ipc_data_readl(4 * i);
> -	}
> -	mutex_unlock(&ipclock);
> -
> -	return ret;
> -}
> -
>  /**
>   * intel_pmc_ipc_command() -  IPC command with input/output data
>   * @cmd:	IPC command code.
> @@ -411,34 +210,23 @@ static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
>  int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
>  			  u32 *out, u32 outlen)
>  {
> -	return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0);

> +	return intel_scu_ipc_dev_command(NULL, cmd, sub, in, inlen, out,
> +					 outlen);

I would leave it on one line.

>  }
>  EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);
>  
> -static irqreturn_t ioc(int irq, void *dev_id)
> -{
> -	int status;
> -
> -	if (ipcdev.irq_mode) {
> -		status = ipc_read_status();
> -		writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS);
> -	}
> -	complete(&ipcdev.cmd_complete);
> -
> -	return IRQ_HANDLED;
> -}
> -
>  static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
>  	struct intel_pmc_ipc_dev *pmc = &ipcdev;
> +	struct intel_scu_ipc_pdata pdata;
> +	struct intel_scu_ipc_dev *scu;
>  	int ret;
>  
>  	/* Only one PMC is supported */
>  	if (pmc->dev)
>  		return -EBUSY;
>  
> -	pmc->irq_mode = IPC_TRIGGER_MODE_IRQ;
> -
> +	memset(&pdata, 0, sizeof(pdata));
>  	spin_lock_init(&ipcdev.gcr_lock);
>  
>  	ret = pcim_enable_device(pdev);
> @@ -449,24 +237,25 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	if (ret)
>  		return ret;
>  
> -	init_completion(&pmc->cmd_complete);
> -
> -	pmc->ipc_base = pcim_iomap_table(pdev)[0];
> +	pdata.ipc_regs = pcim_iomap_table(pdev)[0];
>  
> -	ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc",
> -				pmc);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to request irq\n");
> -		return ret;
> -	}
> +	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
> +	if (IS_ERR(scu))
> +		return PTR_ERR(scu);
>  
>  	pmc->dev = &pdev->dev;
>  
> -	pci_set_drvdata(pdev, pmc);
> +	pci_set_drvdata(pdev, scu);
>  
>  	return 0;
>  }
>  
> +static void ipc_pci_remove(struct pci_dev *pdev)
> +{
> +	intel_scu_ipc_remove(pci_get_drvdata(pdev));
> +	ipcdev.dev = NULL;
> +}
> +
>  static const struct pci_device_id ipc_pci_ids[] = {
>  	{PCI_VDEVICE(INTEL, 0x0a94), 0},
>  	{PCI_VDEVICE(INTEL, 0x1a94), 0},
> @@ -479,12 +268,14 @@ static struct pci_driver ipc_pci_driver = {
>  	.name = "intel_pmc_ipc",
>  	.id_table = ipc_pci_ids,
>  	.probe = ipc_pci_probe,
> +	.remove = ipc_pci_remove,
>  };
>  
>  static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
>  					      struct device_attribute *attr,
>  					      const char *buf, size_t count)
>  {
> +	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
>  	int subcmd;
>  	int cmd;
>  	int ret;
> @@ -495,7 +286,7 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
>  		return -EINVAL;
>  	}
>  
> -	ret = intel_pmc_ipc_simple_command(cmd, subcmd);
> +	ret = intel_scu_ipc_dev_simple_command(scu, cmd, subcmd);
>  	if (ret) {
>  		dev_err(dev, "command %d error with %d\n", cmd, ret);
>  		return ret;
> @@ -507,6 +298,7 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
>  					     struct device_attribute *attr,
>  					     const char *buf, size_t count)
>  {
> +	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
>  	unsigned long val;
>  	int subcmd;
>  	int ret;
> @@ -518,7 +310,8 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
>  		subcmd = 1;
>  	else
>  		subcmd = 0;
> -	ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd);

> +	ret = intel_scu_ipc_dev_simple_command(scu, PMC_IPC_NORTHPEAK_CTRL,
> +					       subcmd);

I would leave it on one line.

>  	if (ret) {
>  		dev_err(dev, "command north %d error with %d\n", subcmd, ret);
>  		return ret;
> @@ -711,7 +504,8 @@ static int ipc_create_pmc_devices(void)
>  	return ret;
>  }
>  
> -static int ipc_plat_get_res(struct platform_device *pdev)
> +static int ipc_plat_get_res(struct platform_device *pdev,
> +			    struct intel_scu_ipc_pdata *pdata)
>  {
>  	struct resource *res, *punit_res = punit_res_array;
>  	void __iomem *addr;
> @@ -795,7 +589,7 @@ static int ipc_plat_get_res(struct platform_device *pdev)
>  	if (IS_ERR(addr))
>  		return PTR_ERR(addr);
>  
> -	ipcdev.ipc_base = addr;
> +	pdata->ipc_regs = addr;
>  
>  	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
>  	dev_info(&pdev->dev, "ipc res: %pR\n", res);
> @@ -851,49 +645,50 @@ MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
>  
>  static int ipc_plat_probe(struct platform_device *pdev)
>  {
> +	struct intel_scu_ipc_pdata pdata;
> +	struct intel_scu_ipc_dev *scu;
>  	int ret;
>  
> +	memset(&pdata, 0, sizeof(pdata));
> +	pdata.irq = platform_get_irq(pdev, 0);
> +	if (pdata.irq < 0)
> +		return -EINVAL;
> +
>  	ipcdev.dev = &pdev->dev;
> -	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
> -	init_completion(&ipcdev.cmd_complete);
>  	spin_lock_init(&ipcdev.gcr_lock);
>  
> -	ipcdev.irq = platform_get_irq(pdev, 0);
> -	if (ipcdev.irq < 0)
> -		return -EINVAL;
> -
> -	ret = ipc_plat_get_res(pdev);
> +	ret = ipc_plat_get_res(pdev, &pdata);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to request resource\n");
>  		return ret;
>  	}
>  
> +	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
> +	if (IS_ERR(scu))
> +		return PTR_ERR(scu);
> +
> +	platform_set_drvdata(pdev, scu);
> +
>  	ret = ipc_create_pmc_devices();
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to create pmc devices\n");
> -		return ret;
> -	}
> -
> -	if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
> -			     "intel_pmc_ipc", &ipcdev)) {
> -		dev_err(&pdev->dev, "Failed to request irq\n");
> -		ret = -EBUSY;
> -		goto err_irq;
> +		goto err_ipc;
>  	}
>  
>  	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
>  			ret);
> -		goto err_sys;
> +		goto err_devs;
>  	}
>  
>  	ipcdev.has_gcr_regs = true;
>  
>  	return 0;
> -err_sys:
> -	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
> -err_irq:
> +
> +err_ipc:
> +	intel_scu_ipc_remove(scu);
> +err_devs:
>  	platform_device_unregister(ipcdev.tco_dev);
>  	platform_device_unregister(ipcdev.punit_dev);
>  	platform_device_unregister(ipcdev.telemetry_dev);
> @@ -904,10 +699,10 @@ static int ipc_plat_probe(struct platform_device *pdev)
>  static int ipc_plat_remove(struct platform_device *pdev)
>  {
>  	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
> -	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
>  	platform_device_unregister(ipcdev.tco_dev);
>  	platform_device_unregister(ipcdev.punit_dev);
>  	platform_device_unregister(ipcdev.telemetry_dev);
> +	intel_scu_ipc_remove(platform_get_drvdata(pdev));
>  	ipcdev.dev = NULL;
>  	return 0;
>  }
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 29/36] platform/x86: intel_telemetry: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 29/36] platform/x86: intel_telemetry: " Mika Westerberg
@ 2020-01-08 16:54   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:54PM +0300, Mika Westerberg wrote:
> Convert the Intel Apollo Lake telemetry driver to use the new SCU IPC
> API. This allows us to get rid of the duplicate PMC IPC implementation
> which is now covered in SCU IPC driver.
> 
> Also move telemetry specific IPC message constant to the telementry
> driver where it belongs.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h          |   1 -
>  arch/x86/include/asm/intel_telemetry.h        |   3 +
>  drivers/platform/x86/intel_telemetry_pltdrv.c | 101 +++++++++---------
>  3 files changed, 55 insertions(+), 50 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index b438a488f613..ddc964b9c78c 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -8,7 +8,6 @@
>  #define PMC_IPC_PHY_CONFIG		0xEE
>  #define PMC_IPC_NORTHPEAK_CTRL		0xED
>  #define PMC_IPC_PM_DEBUG		0xEC
> -#define PMC_IPC_PMC_TELEMTRY		0xEB
>  #define PMC_IPC_PMC_FW_MSG_CTRL		0xEA
>  
>  /* IPC return code */
> diff --git a/arch/x86/include/asm/intel_telemetry.h b/arch/x86/include/asm/intel_telemetry.h
> index 214394860632..e19deb776003 100644
> --- a/arch/x86/include/asm/intel_telemetry.h
> +++ b/arch/x86/include/asm/intel_telemetry.h
> @@ -10,6 +10,8 @@
>  #define TELEM_MAX_EVENTS_SRAM		28
>  #define TELEM_MAX_OS_ALLOCATED_EVENTS	20
>  
> +#include <asm/intel_scu_ipc.h>
> +
>  enum telemetry_unit {
>  	TELEM_PSS = 0,
>  	TELEM_IOSS,
> @@ -54,6 +56,7 @@ struct telemetry_plt_config {
>  	struct telemetry_unit_config ioss_config;
>  	struct mutex telem_trace_lock;
>  	struct mutex telem_lock;
> +	struct intel_scu_ipc_dev *scu;
>  	bool telem_in_use;
>  };
>  
> diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c
> index df8565bad595..d39dde634866 100644
> --- a/drivers/platform/x86/intel_telemetry_pltdrv.c
> +++ b/drivers/platform/x86/intel_telemetry_pltdrv.c
> @@ -15,7 +15,6 @@
>  
>  #include <asm/cpu_device_id.h>
>  #include <asm/intel-family.h>
> -#include <asm/intel_pmc_ipc.h>
>  #include <asm/intel_punit_ipc.h>
>  #include <asm/intel_telemetry.h>
>  
> @@ -35,6 +34,7 @@
>  #define TELEM_SSRAM_STARTTIME_OFFSET	8
>  #define TELEM_SSRAM_EVTLOG_OFFSET	16
>  
> +#define IOSS_TELEM			0xeb
>  #define IOSS_TELEM_EVENT_READ		0x0
>  #define IOSS_TELEM_EVENT_WRITE		0x1
>  #define IOSS_TELEM_INFO_READ		0x2
> @@ -42,9 +42,6 @@
>  #define IOSS_TELEM_TRACE_CTL_WRITE	0x6
>  #define IOSS_TELEM_EVENT_CTL_READ	0x7
>  #define IOSS_TELEM_EVENT_CTL_WRITE	0x8
> -#define IOSS_TELEM_EVT_CTRL_WRITE_SIZE	0x4
> -#define IOSS_TELEM_READ_WORD		0x1
> -#define IOSS_TELEM_WRITE_FOURBYTES	0x4
>  #define IOSS_TELEM_EVT_WRITE_SIZE	0x3
>  
>  #define TELEM_INFO_SRAMEVTS_MASK	0xFF00
> @@ -253,17 +250,14 @@ static int telemetry_check_evtid(enum telemetry_unit telem_unit,
>  static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
>  {
>  	u32 write_buf;
> -	int ret;
>  
>  	write_buf = evt_id | TELEM_EVENT_ENABLE;
>  	write_buf <<= BITS_PER_BYTE;
>  	write_buf |= index;
>  
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -				    IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf,
> -				    IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
> -
> -	return ret;
> +	return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
> +					 IOSS_TELEM_EVENT_WRITE, &write_buf,
> +					 IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
>  }
>  
>  static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
> @@ -281,6 +275,7 @@ static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
>  static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  					 enum telemetry_action action)
>  {
> +	struct intel_scu_ipc_dev *scu = telm_conf->scu;
>  	u8 num_ioss_evts, ioss_period;
>  	int ret, index, idx;
>  	u32 *ioss_evtmap;
> @@ -291,9 +286,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  	ioss_evtmap = evtconfig.evtmap;
>  
>  	/* Get telemetry EVENT CTL */
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> +	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
>  				    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
> -				    &telem_ctrl, IOSS_TELEM_READ_WORD);
> +				    &telem_ctrl, sizeof(telem_ctrl));
>  	if (ret) {
>  		pr_err("IOSS TELEM_CTRL Read Failed\n");
>  		return ret;
> @@ -302,11 +297,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  	/* Disable Telemetry */
>  	TELEM_DISABLE(telem_ctrl);
>  
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -				    IOSS_TELEM_EVENT_CTL_WRITE,
> -				    (u8 *)&telem_ctrl,
> -				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
> -				    NULL, 0);
> +	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
> +				    IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
> +				    sizeof(telem_ctrl), NULL, 0);
>  	if (ret) {
>  		pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
>  		return ret;
> @@ -318,10 +311,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  		/* Clear All Events */
>  		TELEM_CLEAR_EVENTS(telem_ctrl);
>  
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> +		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
>  					    IOSS_TELEM_EVENT_CTL_WRITE,
> -					    (u8 *)&telem_ctrl,
> -					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
> +					    &telem_ctrl, sizeof(telem_ctrl),
>  					    NULL, 0);
>  		if (ret) {
>  			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
> @@ -347,10 +339,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  		/* Clear All Events */
>  		TELEM_CLEAR_EVENTS(telem_ctrl);
>  
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> +		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
>  					    IOSS_TELEM_EVENT_CTL_WRITE,
> -					    (u8 *)&telem_ctrl,
> -					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
> +					    &telem_ctrl, sizeof(telem_ctrl),
>  					    NULL, 0);
>  		if (ret) {
>  			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
> @@ -399,10 +390,9 @@ static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
>  	TELEM_ENABLE_PERIODIC(telem_ctrl);
>  	telem_ctrl |= ioss_period;
>  
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> +	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
>  				    IOSS_TELEM_EVENT_CTL_WRITE,
> -				    (u8 *)&telem_ctrl,
> -				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0);
> +				    &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
>  	if (ret) {
>  		pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
>  		return ret;
> @@ -589,8 +579,9 @@ static int telemetry_setup(struct platform_device *pdev)
>  	u32 read_buf, events, event_regs;
>  	int ret;
>  
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ,
> -				    NULL, 0, &read_buf, IOSS_TELEM_READ_WORD);
> +	ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
> +					IOSS_TELEM_INFO_READ, NULL, 0,
> +					&read_buf, sizeof(read_buf));
>  	if (ret) {
>  		dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
>  		return ret;
> @@ -684,6 +675,8 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
>  
>  	mutex_lock(&(telm_conf->telem_lock));
>  	if (ioss_period) {
> +		struct intel_scu_ipc_dev *scu = telm_conf->scu;
> +
>  		if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
>  			pr_err("IOSS Sampling Period Out of Range\n");
>  			ret = -EINVAL;
> @@ -691,9 +684,9 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
>  		}
>  
>  		/* Get telemetry EVENT CTL */
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> +		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
>  					    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
> -					    &telem_ctrl, IOSS_TELEM_READ_WORD);
> +					    &telem_ctrl, sizeof(telem_ctrl));
>  		if (ret) {
>  			pr_err("IOSS TELEM_CTRL Read Failed\n");
>  			goto out;
> @@ -702,11 +695,10 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
>  		/* Disable Telemetry */
>  		TELEM_DISABLE(telem_ctrl);
>  
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -					    IOSS_TELEM_EVENT_CTL_WRITE,
> -					    (u8 *)&telem_ctrl,
> -					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
> -					    NULL, 0);
> +		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
> +						IOSS_TELEM_EVENT_CTL_WRITE,
> +						&telem_ctrl, sizeof(telem_ctrl),
> +						NULL, 0);
>  		if (ret) {
>  			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
>  			goto out;
> @@ -718,11 +710,10 @@ static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
>  		TELEM_ENABLE_PERIODIC(telem_ctrl);
>  		telem_ctrl |= ioss_period;
>  
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -					    IOSS_TELEM_EVENT_CTL_WRITE,
> -					    (u8 *)&telem_ctrl,
> -					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
> -					    NULL, 0);
> +		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
> +						IOSS_TELEM_EVENT_CTL_WRITE,
> +						&telem_ctrl, sizeof(telem_ctrl),
> +						NULL, 0);
>  		if (ret) {
>  			pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
>  			goto out;
> @@ -1017,9 +1008,9 @@ static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
>  		break;
>  
>  	case TELEM_IOSS:
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
> -				IOSS_TELEM_READ_WORD);
> +		ret = intel_scu_ipc_dev_command(telm_conf->scu,
> +				IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
> +				NULL, 0, &temp, sizeof(temp));
>  		if (ret) {
>  			pr_err("IOSS TRACE_CTL Read Failed\n");
>  			goto out;
> @@ -1071,9 +1062,9 @@ static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
>  		break;
>  
>  	case TELEM_IOSS:
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
> -				IOSS_TELEM_READ_WORD);
> +		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
> +						IOSS_TELEM_TRACE_CTL_READ,
> +						NULL, 0, &temp, sizeof(temp));
>  		if (ret) {
>  			pr_err("IOSS TRACE_CTL Read Failed\n");
>  			goto out;
> @@ -1082,9 +1073,9 @@ static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
>  		TELEM_CLEAR_VERBOSITY_BITS(temp);
>  		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
>  
> -		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
> -				IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp,
> -				IOSS_TELEM_WRITE_FOURBYTES, NULL, 0);
> +		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
> +						IOSS_TELEM_TRACE_CTL_WRITE,
> +						&temp, sizeof(temp), NULL, 0);
>  		if (ret) {
>  			pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
>  			goto out;
> @@ -1172,6 +1163,12 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
>  		goto out;
>  	}
>  
> +	telm_conf->scu = intel_scu_ipc_dev_get();
> +	if (!telm_conf->scu) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
>  	mutex_init(&telm_conf->telem_lock);
>  	mutex_init(&telm_conf->telem_trace_lock);
>  
> @@ -1196,6 +1193,10 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
>  		iounmap(telm_conf->pss_config.regmap);
>  	if (telm_conf->ioss_config.regmap)
>  		iounmap(telm_conf->ioss_config.regmap);
> +	if (telm_conf->scu) {
> +		intel_scu_ipc_dev_put(telm_conf->scu);
> +		telm_conf->scu = NULL;
> +	}
>  	dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
>  
>  	return ret;
> @@ -1204,6 +1205,8 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
>  static int telemetry_pltdrv_remove(struct platform_device *pdev)
>  {
>  	telemetry_clear_pltdata();
> +	intel_scu_ipc_dev_put(telm_conf->scu);
> +	telm_conf->scu = NULL;
>  	iounmap(telm_conf->pss_config.regmap);
>  	iounmap(telm_conf->ioss_config.regmap);
>  
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command()
  2020-01-08 11:41 ` [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command() Mika Westerberg
@ 2020-01-08 16:57   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:57 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:55PM +0300, Mika Westerberg wrote:
> Now that all callers have been converted over to the SCU IPC API we can
> drop intel_pmc_ipc_command().

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h |  8 --------
>  drivers/platform/x86/intel_pmc_ipc.c | 21 ---------------------
>  2 files changed, 29 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index ddc964b9c78c..22848df5faaf 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -27,19 +27,11 @@
>  
>  #if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
>  
> -int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
> -		u32 *out, u32 outlen);
>  int intel_pmc_s0ix_counter_read(u64 *data);
>  int intel_pmc_gcr_read64(u32 offset, u64 *data);
>  
>  #else
>  
> -static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
> -		u32 *out, u32 outlen)
> -{
> -	return -EINVAL;
> -}
> -
>  static inline int intel_pmc_s0ix_counter_read(u64 *data)
>  {
>  	return -EINVAL;
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 10505fbd01b5..241bce603183 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -194,27 +194,6 @@ static int update_no_reboot_bit(void *priv, bool set)
>  				    PMC_CFG_NO_REBOOT_MASK, value);
>  }
>  
> -/**
> - * intel_pmc_ipc_command() -  IPC command with input/output data
> - * @cmd:	IPC command code.
> - * @sub:	IPC command sub type.
> - * @in:		input data of this IPC command.
> - * @inlen:	input data length in bytes.
> - * @out:	output data of this IPC command.
> - * @outlen:	output data length in dwords.
> - *
> - * Send an IPC command to PMC with input/output data.
> - *
> - * Return:	an IPC error code or 0 on success.
> - */
> -int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
> -			  u32 *out, u32 outlen)
> -{
> -	return intel_scu_ipc_dev_command(NULL, cmd, sub, in, inlen, out,
> -					 outlen);
> -}
> -EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);
> -
>  static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
>  	struct intel_pmc_ipc_dev *pmc = &ipcdev;
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes
  2020-01-08 11:41 ` [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes Mika Westerberg
@ 2020-01-08 16:58   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 16:58 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:58PM +0300, Mika Westerberg wrote:
> This is the current preferred way so replace the S_IWUSR with the
> corresponding octal value. While there move the attributes to follow
> directly their store functions.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_pmc_ipc.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index acec1c6d2069..20a4bb72aeac 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -215,6 +215,7 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
>  	}
>  	return (ssize_t)count;
>  }
> +static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store);
>  
>  static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
>  					     struct device_attribute *attr,
> @@ -240,11 +241,7 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
>  	}
>  	return (ssize_t)count;
>  }
> -
> -static DEVICE_ATTR(simplecmd, S_IWUSR,
> -		   NULL, intel_pmc_ipc_simple_cmd_store);
> -static DEVICE_ATTR(northpeak, S_IWUSR,
> -		   NULL, intel_pmc_ipc_northpeak_store);
> +static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store);
>  
>  static struct attribute *intel_ipc_attrs[] = {
>  	&dev_attr_northpeak.attr,
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c
  2020-01-08 11:41 ` [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c Mika Westerberg
@ 2020-01-08 17:03   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:03 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:57PM +0300, Mika Westerberg wrote:
> The PCI probe driver in intel_pmc_ipc.c is a duplicate of what we
> already have in intel_scu_pcidrv.c with the exception that the later also
> creates SCU specific devices. Move the PCI IDs from the intel_pmc_ipc.c
> to intel_scu.c and use driver_data to detect whether SCU devices need to
> be created or not.
> 
> Also update Kconfig entry to mention all platforms supported by the
> Intel SCU PCI driver.

One comment below. After addressing,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/Kconfig            | 13 +++--
>  drivers/platform/x86/intel_pmc_ipc.c    | 73 +------------------------
>  drivers/platform/x86/intel_scu_pcidrv.c | 21 +++++--
>  3 files changed, 27 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 797683c5d005..1c5afb9e4965 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -994,13 +994,18 @@ config INTEL_SCU
>  
>  config INTEL_SCU_PCI
>  	bool "Intel SCU PCI driver"
> -	depends on X86_INTEL_MID
> +	depends on X86_INTEL_MID || PCI

Dependency on PCI is much more generic than Intel MID one. I think we may drop
X86_INTEL_MID here completely -- less users of it better.

>  	select INTEL_SCU
>  	help
>  	  SCU is used to bridge the communications between kernel and
>  	  SCU on some embedded Intel x86 platforms. It also creates
> -	  devices that are connected to the SoC through the SCU. This is
> -	  not needed for PC-type machines.
> +	  devices that are connected to the SoC through the SCU.
> +	  Platforms supported:
> +	    Medfield
> +	    Clovertrail
> +	    Merrifield
> +	    Broxton
> +	    Apollo Lake
>  
>  config INTEL_SCU_IPC_UTIL
>  	tristate "Intel SCU IPC utility driver"
> @@ -1192,7 +1197,7 @@ config INTEL_SMARTCONNECT
>  
>  config INTEL_PMC_IPC
>  	tristate "Intel PMC IPC Driver"
> -	depends on ACPI && PCI
> +	depends on ACPI
>  	select INTEL_SCU_IPC
>  	---help---
>  	This driver provides support for PMC control on some Intel platforms.
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
> index 241bce603183..acec1c6d2069 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -17,7 +17,6 @@
>  #include <linux/interrupt.h>
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/module.h>
> -#include <linux/pci.h>
>  #include <linux/platform_device.h>
>  
>  #include <asm/intel_pmc_ipc.h>
> @@ -194,62 +193,6 @@ static int update_no_reboot_bit(void *priv, bool set)
>  				    PMC_CFG_NO_REBOOT_MASK, value);
>  }
>  
> -static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> -{
> -	struct intel_pmc_ipc_dev *pmc = &ipcdev;
> -	struct intel_scu_ipc_pdata pdata;
> -	struct intel_scu_ipc_dev *scu;
> -	int ret;
> -
> -	/* Only one PMC is supported */
> -	if (pmc->dev)
> -		return -EBUSY;
> -
> -	memset(&pdata, 0, sizeof(pdata));
> -	spin_lock_init(&ipcdev.gcr_lock);
> -
> -	ret = pcim_enable_device(pdev);
> -	if (ret)
> -		return ret;
> -
> -	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
> -	if (ret)
> -		return ret;
> -
> -	pdata.ipc_regs = pcim_iomap_table(pdev)[0];
> -
> -	scu = intel_scu_ipc_probe(&pdev->dev, &pdata);
> -	if (IS_ERR(scu))
> -		return PTR_ERR(scu);
> -
> -	pmc->dev = &pdev->dev;
> -
> -	pci_set_drvdata(pdev, scu);
> -
> -	return 0;
> -}
> -
> -static void ipc_pci_remove(struct pci_dev *pdev)
> -{
> -	intel_scu_ipc_remove(pci_get_drvdata(pdev));
> -	ipcdev.dev = NULL;
> -}
> -
> -static const struct pci_device_id ipc_pci_ids[] = {
> -	{PCI_VDEVICE(INTEL, 0x0a94), 0},
> -	{PCI_VDEVICE(INTEL, 0x1a94), 0},
> -	{PCI_VDEVICE(INTEL, 0x5a94), 0},
> -	{ 0,}
> -};
> -MODULE_DEVICE_TABLE(pci, ipc_pci_ids);
> -
> -static struct pci_driver ipc_pci_driver = {
> -	.name = "intel_pmc_ipc",
> -	.id_table = ipc_pci_ids,
> -	.probe = ipc_pci_probe,
> -	.remove = ipc_pci_remove,
> -};
> -
>  static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
>  					      struct device_attribute *attr,
>  					      const char *buf, size_t count)
> @@ -697,25 +640,11 @@ static struct platform_driver ipc_plat_driver = {
>  
>  static int __init intel_pmc_ipc_init(void)
>  {
> -	int ret;
> -
> -	ret = platform_driver_register(&ipc_plat_driver);
> -	if (ret) {
> -		pr_err("Failed to register PMC ipc platform driver\n");
> -		return ret;
> -	}
> -	ret = pci_register_driver(&ipc_pci_driver);
> -	if (ret) {
> -		pr_err("Failed to register PMC ipc pci driver\n");
> -		platform_driver_unregister(&ipc_plat_driver);
> -		return ret;
> -	}
> -	return ret;
> +	return platform_driver_register(&ipc_plat_driver);
>  }
>  
>  static void __exit intel_pmc_ipc_exit(void)
>  {
> -	pci_unregister_driver(&ipc_pci_driver);
>  	platform_driver_unregister(&ipc_plat_driver);
>  }
>  
> diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
> index 42030bdb3e08..4f2a7ca5c5f7 100644
> --- a/drivers/platform/x86/intel_scu_pcidrv.c
> +++ b/drivers/platform/x86/intel_scu_pcidrv.c
> @@ -17,6 +17,7 @@
>  static int intel_scu_pci_probe(struct pci_dev *pdev,
>  			       const struct pci_device_id *id)
>  {
> +	void (*setup_fn)(void) = (void (*)(void))id->driver_data;
>  	struct intel_scu_ipc_pdata *pdata;
>  	struct intel_scu_ipc_dev *scu;
>  	int ret;
> @@ -40,14 +41,26 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
>  	if (IS_ERR(scu))
>  		return PTR_ERR(scu);
>  
> -	intel_scu_devices_create();
> +	if (setup_fn)
> +		setup_fn();
>  	return 0;
>  }
>  
> +static void intel_mid_scu_setup(void)
> +{
> +	intel_scu_devices_create();
> +}
> +
>  static const struct pci_device_id pci_ids[] = {
> -	{ PCI_VDEVICE(INTEL, 0x080e) },
> -	{ PCI_VDEVICE(INTEL, 0x08ea) },
> -	{ PCI_VDEVICE(INTEL, 0x11a0) },
> +	{ PCI_VDEVICE(INTEL, 0x080e),
> +	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
> +	{ PCI_VDEVICE(INTEL, 0x08ea),
> +	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
> +	{ PCI_VDEVICE(INTEL, 0x0a94) },
> +	{ PCI_VDEVICE(INTEL, 0x11a0),
> +	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
> +	{ PCI_VDEVICE(INTEL, 0x1a94) },
> +	{ PCI_VDEVICE(INTEL, 0x5a94) },
>  	{}
>  };
>  
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver
  2020-01-08 11:42 ` [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver Mika Westerberg
@ 2020-01-08 17:06   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:06 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:42:01PM +0300, Mika Westerberg wrote:
> The driver lives now under MFD so split the current entry into two parts
> and add me as co-maintainer of the Intel Broxton PMC driver. While there
> correct formatting of Zha Qipeng's email address.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  MAINTAINERS | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8982c6e013b3..11b8bb4e2867 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8280,6 +8280,13 @@ L:	platform-driver-x86@vger.kernel.org
>  S:	Maintained
>  F:	drivers/platform/x86/intel_atomisp2_pm.c
>  
> +INTEL BROXTON PMC DRIVER
> +M:	Mika Westerberg <mika.westerberg@linux.intel.com>
> +M:	Zha Qipeng <qipeng.zha@intel.com>
> +S:	Maintained
> +F:	drivers/mfd/intel_pmc_bxt.c
> +F:	include/linux/mfd/intel_pmc_bxt.h
> +
>  INTEL C600 SERIES SAS CONTROLLER DRIVER
>  M:	Intel SCU Linux support <intel-linux-scu@intel.com>
>  M:	Artur Paszkiewicz <artur.paszkiewicz@intel.com>
> @@ -8488,13 +8495,11 @@ L:	platform-driver-x86@vger.kernel.org
>  S:	Maintained
>  F:	drivers/platform/x86/intel_pmc_core*
>  
> -INTEL PMC/P-Unit IPC DRIVER
> -M:	Zha Qipeng<qipeng.zha@intel.com>
> +INTEL P-Unit IPC DRIVER
> +M:	Zha Qipeng <qipeng.zha@intel.com>
>  L:	platform-driver-x86@vger.kernel.org
>  S:	Maintained
> -F:	drivers/platform/x86/intel_pmc_ipc.c
>  F:	drivers/platform/x86/intel_punit_ipc.c
> -F:	arch/x86/include/asm/intel_pmc_ipc.h
>  F:	arch/x86/include/asm/intel_punit_ipc.h
>  
>  INTEL PMIC GPIO DRIVERS
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling
  2020-01-08 11:41 ` [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling Mika Westerberg
@ 2020-01-08 17:12   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:12 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:32PM +0300, Mika Westerberg wrote:
> There is no reason why the driver would need to block other threads from
> running the CPU while it is waiting for the SCU IPC to complete its
> work. For this reason switch the driver to use usleep_range() instead
> with a bit more relaxed polling loop.

I agree on this and if somebody finds a race condition that had been hidden by
the original code it will mean that somewhere else something is completely
broken.

> 
> Also add constant for the timeout and use the same value for both
> polling and interrupt modes.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 29 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 43eaf9400c67..8db0644900a3 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
>  #define IPC_WRITE_BUFFER	0x80
>  #define IPC_READ_BUFFER		0x90
>  
> +/* Timeout in jiffies */
> +#define IPC_TIMEOUT		(3 * HZ)
> +
>  static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
>  
>  /*
> @@ -132,24 +135,20 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
>  /* Wait till scu status is busy */
>  static inline int busy_loop(struct intel_scu_ipc_dev *scu)
>  {
> -	u32 status = ipc_read_status(scu);
> -	u32 loop_count = 100000;
> +	unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT);
>  
> -	/* break if scu doesn't reset busy bit after huge retry */
> -	while ((status & IPC_STATUS_BUSY) && --loop_count) {
> -		udelay(1); /* scu processing time is in few u secods */
> -		status = ipc_read_status(scu);
> -	}
> +	do {
> +		u32 status;
>  
> -	if (status & IPC_STATUS_BUSY) {
> -		dev_err(scu->dev, "IPC timed out");
> -		return -ETIMEDOUT;
> -	}
> +		status = ipc_read_status(scu);
> +		if (!(status & IPC_STATUS_BUSY))
> +			return (status & IPC_STATUS_ERR) ? -EIO : 0;
>  
> -	if (status & IPC_STATUS_ERR)
> -		return -EIO;
> +		usleep_range(50, 100);
> +	} while (time_before(jiffies, end));
>  
> -	return 0;
> +	dev_err(scu->dev, "IPC timed out");
> +	return -ETIMEDOUT;
>  }
>  
>  /* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
> @@ -157,7 +156,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
>  {
>  	int status;
>  
> -	if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) {
> +	if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) {
>  		dev_err(scu->dev, "IPC timed out\n");
>  		return -ETIMEDOUT;
>  	}
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver
  2020-01-08 11:41 ` [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver Mika Westerberg
@ 2020-01-08 17:22   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:22 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:37PM +0300, Mika Westerberg wrote:
> The SCU IPC functionality is usable outside of Intel MID devices. For
> example modern Intel CPUs include the same thing but now it is called
> PMC (Power Management Controller) instead of SCU. To make the IPC
> available for those split the driver into library part (intel_scu_ipc.c)
> and the SCU PCI driver part (intel_scu_pcidrv.c) which then calls the
> former before it goes and creates rest of the SCU devices.
> 
> We also split the Kconfig symbols so that INTEL_SCU_IPC enables the SCU
> IPC library and INTEL_SCU_PCI the SCU driver and convert the users
> accordingly. While there remove default y from the INTEL_SCU_PCI symbol
> as it is already selected by X86_INTEL_MID.

After addressing at least Kconfig related comment (the rest is up to you)
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/Kconfig                        |  2 +-
>  arch/x86/include/asm/intel_scu_ipc.h    | 15 +++++
>  drivers/mfd/Kconfig                     |  4 +-
>  drivers/platform/x86/Kconfig            | 26 ++++++---
>  drivers/platform/x86/Makefile           |  1 +
>  drivers/platform/x86/intel_scu_ipc.c    | 77 +++++++++----------------
>  drivers/platform/x86/intel_scu_pcidrv.c | 61 ++++++++++++++++++++
>  7 files changed, 125 insertions(+), 61 deletions(-)
>  create mode 100644 drivers/platform/x86/intel_scu_pcidrv.c
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 5e8949953660..aca17d1583c4 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -594,7 +594,7 @@ config X86_INTEL_MID
>  	select I2C
>  	select DW_APB_TIMER
>  	select APB_TIMER
> -	select INTEL_SCU_IPC
> +	select INTEL_SCU_PCI
>  	select MFD_INTEL_MSIC
>  	---help---
>  	  Select to build a kernel capable of supporting Intel MID (Mobile
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index 2a1442ba6e78..405c47bf0965 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -19,6 +19,21 @@
>  	#define IPC_CMD_VRTC_SETTIME      1 /* Set time */
>  	#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
>  
> +struct device;
> +
> +/**
> + * struct intel_scu_ipc_pdata - Platform data for SCU IPC
> + * @ipc_regs: IPC regs MMIO address
> + * @irq: The IRQ number used for SCU (optional)
> + */
> +struct intel_scu_ipc_pdata {
> +	void __iomem *ipc_regs;
> +	int irq;
> +};
> +

> +int intel_scu_ipc_probe(struct device *dev,
> +			const struct intel_scu_ipc_pdata *pdata);

Perhaps one line?

> +
>  /* Read single register */
>  int intel_scu_ipc_ioread8(u16 addr, u8 *data);
>  
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 420900852166..59515142438e 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -593,7 +593,7 @@ config INTEL_SOC_PMIC_MRFLD
>  	tristate "Support for Intel Merrifield Basin Cove PMIC"
>  	depends on GPIOLIB
>  	depends on ACPI
> -	depends on INTEL_SCU_IPC
> +	depends on INTEL_SCU
>  	select MFD_CORE
>  	select REGMAP_IRQ
>  	help
> @@ -625,7 +625,7 @@ config MFD_INTEL_LPSS_PCI
>  
>  config MFD_INTEL_MSIC
>  	bool "Intel MSIC"
> -	depends on INTEL_SCU_IPC
> +	depends on INTEL_SCU
>  	select MFD_CORE
>  	help
>  	  Select this option to enable access to Intel MSIC (Avatele
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index dd4326736d11..e9ba81fc1770 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -986,25 +986,33 @@ config INTEL_VBTN
>  	  be called intel_vbtn.
>  
>  config INTEL_SCU_IPC
> -	bool "Intel SCU IPC Support"
> +	bool
> +
> +config INTEL_SCU
> +	bool
> +	select INTEL_SCU_IPC
> +
> +config INTEL_SCU_PCI
> +	bool "Intel SCU PCI driver"
>  	depends on X86_INTEL_MID
> -	default y
> -	---help---
> -	  IPC is used to bridge the communications between kernel and SCU on
> -	  some embedded Intel x86 platforms. This is not needed for PC-type
> -	  machines.
> +	select INTEL_SCU
> +	help

> +	  SCU is used to bridge the communications between kernel and

I guess you meant
	SCU -> This driver
here or alike, otherwise it sounds awkward.

> +	  SCU on some embedded Intel x86 platforms. It also creates
> +	  devices that are connected to the SoC through the SCU. This is
> +	  not needed for PC-type machines.
>  
>  config INTEL_SCU_IPC_UTIL
>  	tristate "Intel SCU IPC utility driver"
> -	depends on INTEL_SCU_IPC
> -	---help---
> +	depends on INTEL_SCU
> +	help
>  	  The IPC Util driver provides an interface with the SCU enabling
>  	  low level access for debug work and updating the firmware. Say
>  	  N unless you will be doing this on an Intel MID platform.
>  
>  config INTEL_MID_POWER_BUTTON
>  	tristate "power button driver for Intel MID platforms"
> -	depends on INTEL_SCU_IPC && INPUT
> +	depends on INTEL_SCU && INPUT
>  	help
>  	  This driver handles the power button on the Intel MID platforms.
>  
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index 42d85a00be4e..c7a42feaa521 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -68,6 +68,7 @@ intel_cht_int33fe-objs		:= intel_cht_int33fe_common.o \
>  obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
>  obj-$(CONFIG_INTEL_HID_EVENT)	+= intel-hid.o
>  obj-$(CONFIG_INTEL_VBTN)	+= intel-vbtn.o
> +obj-$(CONFIG_INTEL_SCU_PCI)	+= intel_scu_pcidrv.o
>  obj-$(CONFIG_INTEL_SCU_IPC)	+= intel_scu_ipc.o
>  obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
>  obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 93a810fa6c8a..e3f658f1b40a 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -18,11 +18,8 @@
>  #include <linux/errno.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
> -#include <linux/pci.h>
> -#include <linux/pm.h>
> -#include <linux/sfi.h>
> +#include <linux/io.h>
>  
> -#include <asm/intel-mid.h>
>  #include <asm/intel_scu_ipc.h>
>  
>  /* IPC defines the following message types */
> @@ -58,7 +55,7 @@ struct intel_scu_ipc_dev {
>  	struct device *dev;
>  	void __iomem *ipc_base;
>  	struct completion cmd_complete;
> -	u8 irq_mode;
> +	int irq;
>  };
>  
>  static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
> @@ -166,7 +163,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
>  
>  static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
>  {
> -	return scu->irq_mode ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
> +	return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
>  }
>  
>  /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
> @@ -402,60 +399,42 @@ static irqreturn_t ioc(int irq, void *dev_id)
>  }
>  
>  /**
> - *	ipc_probe	-	probe an Intel SCU IPC
> - *	@pdev: the PCI device matching
> - *	@id: entry in the match table
> + * intel_scu_ipc_probe() - Initializes SCU IPC mechanism
> + * @dev: SCU device
> + * @pdata: Platform specific data
>   *
> - *	Enable and install an intel SCU IPC. This appears in the PCI space
> - *	but uses some hard coded addresses as well.
> + * Call this function to initialize SCU IPC mechanism. It is removed
> + * automatically when the calling driver is unbound from @dev.
>   */
> -static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)

> +int intel_scu_ipc_probe(struct device *dev,
> +			const struct intel_scu_ipc_pdata *pdata)

Perhaps one line?

>  {
>  	int err;
>  	struct intel_scu_ipc_dev *scu = &ipcdev;
>  
> -	if (scu->dev)		/* We support only one SCU */
> +	mutex_lock(&ipclock);
> +	/* We support only one IPC */
> +	if (scu->dev) {
> +		mutex_unlock(&ipclock);
>  		return -EBUSY;
> +	}
>  
> -	err = pcim_enable_device(pdev);
> -	if (err)
> -		return err;
> -
> -	err = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
> -	if (err)
> -		return err;
> -
> +	scu->ipc_base = pdata->ipc_regs;
> +	scu->irq = pdata->irq;
>  	init_completion(&scu->cmd_complete);
>  
> -	scu->ipc_base = pcim_iomap_table(pdev)[0];
> -
> -	err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
> -			       scu);
> -	if (err)
> -		return err;
> +	if (scu->irq > 0) {

> +		err = devm_request_irq(dev, scu->irq, ioc, 0, "intel_scu_ipc",
> +				       scu);

One line?

> +		if (err)
> +			goto unlock;
> +	}
>  
>  	/* Assign device at last */
> -	scu->dev = &pdev->dev;
> -
> -	intel_scu_devices_create();
> +	scu->dev = dev;
>  
> -	pci_set_drvdata(pdev, scu);
> -	return 0;
> +unlock:
> +	mutex_unlock(&ipclock);
> +	return err;
>  }
> -
> -static const struct pci_device_id pci_ids[] = {
> -	{ PCI_VDEVICE(INTEL, 0x080e) },
> -	{ PCI_VDEVICE(INTEL, 0x08ea) },
> -	{ PCI_VDEVICE(INTEL, 0x11a0) },
> -	{ }
> -};
> -
> -static struct pci_driver ipc_driver = {
> -	.driver = {
> -		.suppress_bind_attrs = true,
> -	},
> -	.name = "intel_scu_ipc",
> -	.id_table = pci_ids,
> -	.probe = ipc_probe,
> -};
> -builtin_pci_driver(ipc_driver);
> +EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
> diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
> new file mode 100644
> index 000000000000..47dd4d85bf2a
> --- /dev/null
> +++ b/drivers/platform/x86/intel_scu_pcidrv.c
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCI driver for the Intel SCU.
> + *
> + * Copyright (C) 2008-2010, 2015, 2020 Intel Corporation
> + * Authors: Sreedhara DS (sreedhara.ds@intel.com)
> + *	    Mika Westerberg <mika.westerberg@linux.intel.com>
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/pci.h>
> +
> +#include <asm/intel-mid.h>
> +#include <asm/intel_scu_ipc.h>
> +
> +static int intel_scu_pci_probe(struct pci_dev *pdev,
> +			       const struct pci_device_id *id)
> +{
> +	struct intel_scu_ipc_pdata *pdata;
> +	int ret;
> +
> +	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		return -ENOMEM;
> +
> +	ret = pcim_enable_device(pdev);
> +	if (ret)
> +		return ret;
> +
> +	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
> +	if (ret)
> +		return ret;
> +
> +	pdata->ipc_regs = pcim_iomap_table(pdev)[0];
> +	pdata->irq = pdev->irq;
> +
> +	ret = intel_scu_ipc_probe(&pdev->dev, pdata);
> +	if (ret)
> +		return ret;
> +
> +	intel_scu_devices_create();
> +	return 0;
> +}
> +
> +static const struct pci_device_id pci_ids[] = {
> +	{ PCI_VDEVICE(INTEL, 0x080e) },
> +	{ PCI_VDEVICE(INTEL, 0x08ea) },
> +	{ PCI_VDEVICE(INTEL, 0x11a0) },
> +	{}
> +};
> +
> +static struct pci_driver intel_scu_pci_driver = {
> +	.driver = {
> +		.suppress_bind_attrs = true,
> +	},
> +	.name = "intel_scu",
> +	.id_table = pci_ids,
> +	.probe = intel_scu_pci_probe,
> +};
> +builtin_pci_driver(intel_scu_pci_driver);
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC
  2020-01-08 11:41 ` [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC Mika Westerberg
@ 2020-01-08 17:28   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:28 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:49PM +0300, Mika Westerberg wrote:
> Drivers such as intel_pmc_ipc.c can be unloaded as well so in order to
> support those in this driver add a new function that can be called to
> remove the SCU IPC if the driver is unloaded.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h |  1 +
>  drivers/platform/x86/intel_scu_ipc.c | 18 ++++++++++++++++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index 9895b60386c5..250127eb1e38 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -32,6 +32,7 @@ struct intel_scu_ipc_pdata {
>  
>  struct intel_scu_ipc_dev *
>  intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata);
> +void intel_scu_ipc_remove(struct intel_scu_ipc_dev *scu);
>  
>  struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void);
>  void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu);
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index cc29f504adcf..9fa0ea95198b 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -566,3 +566,21 @@ intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata)
>  	return scu;
>  }
>  EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
> +
> +/**
> + * intel_scu_ipc_remove() - Remove SCU IPC
> + * @scu: SCU IPC handle
> + *
> + * This unregisters the SCU IPC device and releases the interrupt.
> + */
> +void intel_scu_ipc_remove(struct intel_scu_ipc_dev *scu)
> +{
> +	mutex_lock(&ipclock);
> +	if (!WARN_ON(!scu->dev)) {
> +		if (scu->irq > 0)
> +			devm_free_irq(scu->dev, scu->irq, scu);
> +		scu->dev = NULL;
> +	}
> +	mutex_unlock(&ipclock);
> +}
> +EXPORT_SYMBOL_GPL(intel_scu_ipc_remove);
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups
  2020-01-08 11:42 ` [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups Mika Westerberg
@ 2020-01-08 17:30   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:30 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:42:00PM +0300, Mika Westerberg wrote:
> The driver core provides support for adding additional attributes for
> devices via new ->dev_groups member of struct device_driver.

I'm wondering if we can also do this before converting to MFD.

> Convert the
> driver to use that instead of adding the attributes manually.
> 

After addressing above and below comments,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/mfd/intel_pmc_bxt.c | 21 +++++++--------------
>  1 file changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mfd/intel_pmc_bxt.c b/drivers/mfd/intel_pmc_bxt.c
> index 76f166c1455b..9f2eb75bdf78 100644
> --- a/drivers/mfd/intel_pmc_bxt.c
> +++ b/drivers/mfd/intel_pmc_bxt.c
> @@ -244,6 +244,11 @@ static const struct attribute_group intel_pmc_group = {
>  	.attrs = intel_pmc_attrs,
>  };
>  
> +static const struct attribute_group *intel_pmc_groups[] = {
> +	&intel_pmc_group,

> +	NULL,

Comma is not needed for terminator lines.

> +};
> +
>  static int pmc_create_punit_device(void)
>  {
>  	struct mfd_cell punit = {
> @@ -492,27 +497,14 @@ static int intel_pmc_probe(struct platform_device *pdev)
>  	ret = pmc_create_devices();
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to create pmc devices\n");
> -		goto err_ipc;
> -	}
> -
> -	ret = sysfs_create_group(&pdev->dev.kobj, &intel_pmc_group);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
> -			ret);
> -		goto err_ipc;
> +		intel_scu_ipc_remove(scu);
>  	}
>  
> -	return 0;
> -
> -err_ipc:
> -	intel_scu_ipc_remove(scu);
> -
>  	return ret;
>  }
>  
>  static int intel_pmc_remove(struct platform_device *pdev)
>  {
> -	sysfs_remove_group(&pdev->dev.kobj, &intel_pmc_group);
>  	intel_scu_ipc_remove(platform_get_drvdata(pdev));
>  	pmcdev.dev = NULL;
>  	return 0;
> @@ -524,6 +516,7 @@ static struct platform_driver intel_pmc_driver = {
>  	.driver = {
>  		.name = "intel_pmc_bxt",
>  		.acpi_match_table = ACPI_PTR(intel_pmc_acpi_ids),
> +		.dev_groups = intel_pmc_groups,
>  	},
>  };
>  
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic
  2020-01-08 11:41 ` [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic Mika Westerberg
@ 2020-01-08 17:31   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:31 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:51PM +0300, Mika Westerberg wrote:
> Both PMIC drivers (intel_soc_pmic_mrfld and intel_soc_pmic_bxtwc) will
> be using this field going forward to access the SCU IPC instance.
> 
> While there add kernel-doc for the intel_soc_pmic structure.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  include/linux/mfd/intel_soc_pmic.h | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h
> index bfecd6bd4990..bda22d750be6 100644
> --- a/include/linux/mfd/intel_soc_pmic.h
> +++ b/include/linux/mfd/intel_soc_pmic.h
> @@ -13,6 +13,20 @@
>  
>  #include <linux/regmap.h>
>  
> +/**
> + * struct intel_soc_pmic - Intel SoC PMIC data
> + * @irq: Interrupt number
> + * @regmap: Pointer to the regmap structure
> + * @irq_chip_data: IRQ chip data for the PMIC itself
> + * @irq_chip_data_pwrbtn: Chained IRQ chip data for the power button
> + * @irq_chip_data_tmu: Chained IRQ chip data for the TMU
> + * @irq_chip_data_bcu: Chained IRQ chip data for the BCU
> + * @irq_chip_data_adc: Chained IRQ chip data for the ADC
> + * @irq_chip_data_chgr: Chained IRQ chip data for the CHGR
> + * @irq_chip_data_crit: Chained IRQ chip data for the CRIT
> + * @dev: Pointer to the PMIC device
> + * @scu: SCU IPC pointer used for IPC operations
> + */
>  struct intel_soc_pmic {
>  	int irq;
>  	struct regmap *regmap;
> @@ -24,6 +38,7 @@ struct intel_soc_pmic {
>  	struct regmap_irq_chip_data *irq_chip_data_chgr;
>  	struct regmap_irq_chip_data *irq_chip_data_crit;
>  	struct device *dev;
> +	struct intel_scu_ipc_dev *scu;
>  };
>  
>  int intel_soc_pmic_exec_mipi_pmic_seq_element(u16 i2c_address, u32 reg_address,
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API Mika Westerberg
@ 2020-01-08 17:32   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:32 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:52PM +0300, Mika Westerberg wrote:
> Convert the Intel Broxton Whiskey Cover PMIC driver to use the new SCU
> IPC API. This allows us to get rid of the PMC IPC implementation which
> is now covered in SCU IPC driver.
> 
> Also move PMIC specific IPC message constants to the PMIC driver from
> the intel_pmc_ipc.h header.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_pmc_ipc.h |  3 ---
>  drivers/mfd/intel_soc_pmic_bxtwc.c   | 22 +++++++++++++++-------
>  2 files changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
> index e6da1ce26256..b438a488f613 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/arch/x86/include/asm/intel_pmc_ipc.h
> @@ -3,9 +3,6 @@
>  #define  _ASM_X86_INTEL_PMC_IPC_H_
>  
>  /* Commands */
> -#define PMC_IPC_PMIC_ACCESS		0xFF
> -#define		PMC_IPC_PMIC_ACCESS_READ	0x0
> -#define		PMC_IPC_PMIC_ACCESS_WRITE	0x1
>  #define PMC_IPC_USB_PWR_CTRL		0xF0
>  #define PMC_IPC_PMIC_BLACKLIST_SEL	0xEF
>  #define PMC_IPC_PHY_CONFIG		0xEE
> diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
> index 739cfb5b69fe..60aba2a1561c 100644
> --- a/drivers/mfd/intel_soc_pmic_bxtwc.c
> +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
> @@ -15,7 +15,7 @@
>  #include <linux/mfd/intel_soc_pmic_bxtwc.h>
>  #include <linux/module.h>
>  
> -#include <asm/intel_pmc_ipc.h>
> +#include <asm/intel_scu_ipc.h>
>  
>  /* PMIC device registers */
>  #define REG_ADDR_MASK		0xFF00
> @@ -58,6 +58,10 @@
>  /* Whiskey Cove PMIC share same ACPI ID between different platforms */
>  #define BROXTON_PMIC_WC_HRV	4
>  
> +#define PMC_PMIC_ACCESS		0xFF
> +#define PMC_PMIC_READ		0x0
> +#define PMC_PMIC_WRITE		0x1
> +
>  enum bxtwc_irqs {
>  	BXTWC_PWRBTN_LVL1_IRQ = 0,
>  	BXTWC_TMU_LVL1_IRQ,
> @@ -288,9 +292,9 @@ static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
>  
>  	ipc_in[0] = reg;
>  	ipc_in[1] = i2c_addr;
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
> -			PMC_IPC_PMIC_ACCESS_READ,
> -			ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
> +	ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
> +					PMC_PMIC_READ, ipc_in, sizeof(ipc_in),
> +					ipc_out, sizeof(ipc_out));
>  	if (ret) {
>  		dev_err(pmic->dev, "Failed to read from PMIC\n");
>  		return ret;
> @@ -321,9 +325,9 @@ static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
>  	ipc_in[0] = reg;
>  	ipc_in[1] = i2c_addr;
>  	ipc_in[2] = val;
> -	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
> -			PMC_IPC_PMIC_ACCESS_WRITE,
> -			ipc_in, sizeof(ipc_in), NULL, 0);
> +	ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
> +					PMC_PMIC_WRITE, ipc_in, sizeof(ipc_in),
> +					NULL, 0);
>  	if (ret) {
>  		dev_err(pmic->dev, "Failed to write to PMIC\n");
>  		return ret;
> @@ -457,6 +461,10 @@ static int bxtwc_probe(struct platform_device *pdev)
>  	dev_set_drvdata(&pdev->dev, pmic);
>  	pmic->dev = &pdev->dev;
>  
> +	pmic->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
> +	if (!pmic->scu)
> +		return -EPROBE_DEFER;
> +
>  	pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
>  					&bxtwc_regmap_config);
>  	if (IS_ERR(pmic->regmap)) {
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (35 preceding siblings ...)
  2020-01-08 11:42 ` [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver Mika Westerberg
@ 2020-01-08 17:34 ` Andy Shevchenko
  2020-01-09  6:13   ` Mika Westerberg
  2020-01-13 10:38 ` Lee Jones
  37 siblings, 1 reply; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:34 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:25PM +0300, Mika Westerberg wrote:
> Hi,
> 
> Currently both intel_scu_ipc.c and intel_pmc_ipc.c implement the same SCU
> IPC communications with minor differences. This duplication does not make
> much sense so this series reworks the two drivers so that there is only a
> single implementation of the SCU IPC. In addition to that the API will be
> updated to take SCU instance pointer as an argument, and most of the
> callers will be converted to this new API. The old API is left there but
> the plan is to get rid the callers and then the old API as well (this is
> something we are working with Andy Shevchenko).
> 
> The intel_pmc_ipc.c is then moved under MFD which suits better for this
> kind of a driver that pretty much sets up the SCU IPC and then creates a
> bunch of platform devices for the things sitting behind the PMC. The driver
> is renamed to intel_pmc_bxt.c which should follow the existing conventions
> under drivers/mfd (and it is only meant for Intel Broxton derivatives).
> 
> Previous version of the series:
> 
>   https://www.spinics.net/lists/platform-driver-x86/msg20359.html
> 
> Changes from the previous version:
> 
>   * Update changelog of patch 16 according to what the patch actually does.
>   * Add kernel-doc for struct intel_soc_pmic.
>   * Move octal permission patch to be before MFD conversion.
>   * Convert the intel_pmc_bxt.c to MFD APIs whilst it is being moved under
>     drivers/mfd.

Hmm... I didn't see you appended Lee's ACKs.

> 
> I'm including all x86 maintainers just to be sure they are aware of this as
> I'm not sure if x86@kernel.org reaches them all. Let me know if you have
> issues with this series.
> 
> I would prefer this to be merged through platform/x86 or MFD trees assuming
> there are no objections.

I'm almost reviewed it (few patches left which I plan to do soon), I'm fine if
it goes via other tree.

> 
> I have tested this on Intel Edison (Merrifield) and Joule (Broxton-M).
> 
> Mika Westerberg (36):
>   platform/x86: intel_mid_powerbtn: Take a copy of ddata
>   platform/x86: intel_scu_ipcutil: Remove default y from Kconfig
>   platform/x86: intel_scu_ipc: Add constants for register offsets
>   platform/x86: intel_scu_ipc: Remove Lincroft support
>   platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl()
>   platform/x86: intel_scu_ipc: Fix interrupt support
>   platform/x86: intel_scu_ipc: Sleeping is fine when polling
>   platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update()
>   platform/x86: intel_scu_ipc: Drop unused macros
>   platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]()
>   platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command()
>   platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver
>   platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions
>   platform/x86: intel_scu_ipc: Introduce new SCU IPC API
>   platform/x86: intel_mid_powerbtn: Convert to use new SCU IPC API
>   watchdog: intel-mid_wdt: Convert to use new SCU IPC API
>   platform/x86: intel_scu_ipcutil: Convert to use new SCU IPC API
>   platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static
>   platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static
>   platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static
>   platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write()
>   platform/x86: intel_pmc_ipc: Drop ipc_data_readb()
>   platform/x86: intel_pmc_ipc: Get rid of unnecessary includes
>   platform/x86: intel_scu_ipc: Add function to remove SCU IPC
>   platform/x86: intel_pmc_ipc: Start using SCU IPC
>   mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic
>   mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API
>   mfd: intel_soc_pmic_mrfld: Convert to use new SCU IPC API
>   platform/x86: intel_telemetry: Convert to use new SCU IPC API
>   platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command()
>   x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]()
>   platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c
>   platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes
>   platform/x86: intel_pmc_ipc: Convert to MFD
>   mfd: intel_pmc_bxt: Switch to use driver->dev_groups
>   MAINTAINERS: Update entry for Intel Broxton PMC driver
> 
>  MAINTAINERS                                   |   13 +-
>  arch/x86/Kconfig                              |    2 +-
>  arch/x86/include/asm/intel-mid.h              |    9 +-
>  arch/x86/include/asm/intel_pmc_ipc.h          |   91 --
>  arch/x86/include/asm/intel_scu_ipc.h          |  104 +-
>  arch/x86/include/asm/intel_scu_ipc_legacy.h   |   76 ++
>  arch/x86/include/asm/intel_telemetry.h        |    3 +
>  drivers/mfd/Kconfig                           |   18 +-
>  drivers/mfd/Makefile                          |    1 +
>  drivers/mfd/intel_pmc_bxt.c                   |  539 +++++++++
>  drivers/mfd/intel_soc_pmic_bxtwc.c            |   22 +-
>  drivers/mfd/intel_soc_pmic_mrfld.c            |   10 +-
>  drivers/platform/x86/Kconfig                  |   49 +-
>  drivers/platform/x86/Makefile                 |    2 +-
>  drivers/platform/x86/intel_mid_powerbtn.c     |   20 +-
>  drivers/platform/x86/intel_pmc_ipc.c          | 1031 -----------------
>  drivers/platform/x86/intel_scu_ipc.c          |  681 +++++------
>  drivers/platform/x86/intel_scu_ipcutil.c      |   43 +-
>  drivers/platform/x86/intel_scu_pcidrv.c       |   75 ++
>  .../platform/x86/intel_telemetry_debugfs.c    |    2 +-
>  drivers/platform/x86/intel_telemetry_pltdrv.c |  101 +-
>  drivers/usb/typec/tcpm/Kconfig                |    2 +-
>  drivers/watchdog/intel-mid_wdt.c              |   53 +-
>  include/linux/mfd/intel_pmc_bxt.h             |   50 +
>  include/linux/mfd/intel_soc_pmic.h            |   15 +
>  25 files changed, 1319 insertions(+), 1693 deletions(-)
>  delete mode 100644 arch/x86/include/asm/intel_pmc_ipc.h
>  create mode 100644 arch/x86/include/asm/intel_scu_ipc_legacy.h
>  create mode 100644 drivers/mfd/intel_pmc_bxt.c
>  delete mode 100644 drivers/platform/x86/intel_pmc_ipc.c
>  create mode 100644 drivers/platform/x86/intel_scu_pcidrv.c
>  create mode 100644 include/linux/mfd/intel_pmc_bxt.h
> 
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: " Mika Westerberg
@ 2020-01-08 17:35   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:35 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:53PM +0300, Mika Westerberg wrote:
> This converts the Intel Merrifield PMIC driver over the new SCU IPC API
> where the SCU IPC instance is passed to the functions.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/mfd/intel_soc_pmic_mrfld.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mfd/intel_soc_pmic_mrfld.c b/drivers/mfd/intel_soc_pmic_mrfld.c
> index 26a1551c5faf..bd94c989d232 100644
> --- a/drivers/mfd/intel_soc_pmic_mrfld.c
> +++ b/drivers/mfd/intel_soc_pmic_mrfld.c
> @@ -74,10 +74,11 @@ static const struct mfd_cell bcove_dev[] = {
>  static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
>  				    unsigned int *val)
>  {
> +	struct intel_soc_pmic *pmic = context;
>  	u8 ipc_out;
>  	int ret;
>  
> -	ret = intel_scu_ipc_ioread8(reg, &ipc_out);
> +	ret = intel_scu_ipc_dev_ioread8(pmic->scu, reg, &ipc_out);
>  	if (ret)
>  		return ret;
>  
> @@ -88,10 +89,11 @@ static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
>  static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
>  				     unsigned int val)
>  {
> +	struct intel_soc_pmic *pmic = context;
>  	u8 ipc_in = val;
>  	int ret;
>  
> -	ret = intel_scu_ipc_iowrite8(reg, ipc_in);
> +	ret = intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
>  	if (ret)
>  		return ret;
>  
> @@ -117,6 +119,10 @@ static int bcove_probe(struct platform_device *pdev)
>  	if (!pmic)
>  		return -ENOMEM;
>  
> +	pmic->scu = devm_intel_scu_ipc_dev_get(dev);
> +	if (!pmic->scu)
> +		return -ENOMEM;
> +
>  	platform_set_drvdata(pdev, pmic);
>  	pmic->dev = &pdev->dev;
>  
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]()
  2020-01-08 11:41 ` [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]() Mika Westerberg
@ 2020-01-08 17:36   ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:36 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:56PM +0300, Mika Westerberg wrote:
> This allows to call the functions even when CONFIG_X86_INTEL_MID is not
> enabled.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel-mid.h | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h
> index 8e5af119dc2d..de58391bdee0 100644
> --- a/arch/x86/include/asm/intel-mid.h
> +++ b/arch/x86/include/asm/intel-mid.h
> @@ -88,11 +88,17 @@ static inline bool intel_mid_has_msic(void)
>  	return (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL);
>  }
>  
> +extern void intel_scu_devices_create(void);
> +extern void intel_scu_devices_destroy(void);
> +
>  #else /* !CONFIG_X86_INTEL_MID */
>  
>  #define intel_mid_identify_cpu()	0
>  #define intel_mid_has_msic()		0
>  
> +static inline void intel_scu_devices_create(void) { }
> +static inline void intel_scu_devices_destroy(void) { }
> +
>  #endif /* !CONFIG_X86_INTEL_MID */
>  
>  enum intel_mid_timer_options {
> @@ -115,9 +121,6 @@ extern enum intel_mid_timer_options intel_mid_timer_options;
>  #define SFI_MTMR_MAX_NUM		8
>  #define SFI_MRTC_MAX			8
>  
> -extern void intel_scu_devices_create(void);
> -extern void intel_scu_devices_destroy(void);
> -
>  /* VRTC timer */
>  #define MRST_VRTC_MAP_SZ		1024
>  /* #define MRST_VRTC_PGOFFSET		0xc00 */
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 16/36] watchdog: intel-mid_wdt: Convert to use new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 16/36] watchdog: intel-mid_wdt: " Mika Westerberg
  2020-01-08 15:37   ` Guenter Roeck
@ 2020-01-08 17:38   ` Andy Shevchenko
  1 sibling, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-08 17:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:41PM +0300, Mika Westerberg wrote:
> This converts the Intel MID watchdog driver over the new SCU IPC API
> where the SCU IPC instance is passed to the functions.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/watchdog/intel-mid_wdt.c | 53 ++++++++++++++++++++++----------
>  1 file changed, 37 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
> index 470213abfd3d..1ae03b64ef8b 100644
> --- a/drivers/watchdog/intel-mid_wdt.c
> +++ b/drivers/watchdog/intel-mid_wdt.c
> @@ -33,14 +33,24 @@ enum {
>  	SCU_WATCHDOG_KEEPALIVE,
>  };
>  
> -static inline int wdt_command(int sub, u32 *in, int inlen)
> +struct mid_wdt {
> +	struct watchdog_device wd;
> +	struct device *dev;
> +	struct intel_scu_ipc_dev *scu;
> +};
> +
> +static inline int
> +wdt_command(struct mid_wdt *mid, int sub, const void *in, size_t inlen, size_t size)
>  {
> -	return intel_scu_ipc_command(IPC_WATCHDOG, sub, in, inlen, NULL, 0);
> +	struct intel_scu_ipc_dev *scu = mid->scu;
> +
> +	return intel_scu_ipc_dev_command_with_size(scu, IPC_WATCHDOG, sub, in,
> +						   inlen, size, NULL, 0);
>  }
>  
>  static int wdt_start(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret, in_size;
>  	int timeout = wd->timeout;
>  	struct ipc_wd_start {
> @@ -49,38 +59,41 @@ static int wdt_start(struct watchdog_device *wd)
>  	} ipc_wd_start = { timeout - MID_WDT_PRETIMEOUT, timeout };
>  
>  	/*
> -	 * SCU expects the input size for watchdog IPC to
> -	 * be based on 4 bytes
> +	 * SCU expects the input size for watchdog IPC to be 2 which is the
> +	 * size of the structure in dwords. SCU IPC normally takes bytes
> +	 * but this is a special case where we specify size to be different
> +	 * than inlen.
>  	 */
>  	in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
>  
> -	ret = wdt_command(SCU_WATCHDOG_START, (u32 *)&ipc_wd_start, in_size);
> +	ret = wdt_command(mid, SCU_WATCHDOG_START, &ipc_wd_start,
> +			  sizeof(ipc_wd_start), in_size);
>  	if (ret)
> -		dev_crit(dev, "error starting watchdog: %d\n", ret);
> +		dev_crit(mid->dev, "error starting watchdog: %d\n", ret);
>  
>  	return ret;
>  }
>  
>  static int wdt_ping(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret;
>  
> -	ret = wdt_command(SCU_WATCHDOG_KEEPALIVE, NULL, 0);
> +	ret = wdt_command(mid, SCU_WATCHDOG_KEEPALIVE, NULL, 0, 0);
>  	if (ret)
> -		dev_crit(dev, "Error executing keepalive: %d\n", ret);
> +		dev_crit(mid->dev, "Error executing keepalive: %d\n", ret);
>  
>  	return ret;
>  }
>  
>  static int wdt_stop(struct watchdog_device *wd)
>  {
> -	struct device *dev = watchdog_get_drvdata(wd);
> +	struct mid_wdt *mid = watchdog_get_drvdata(wd);
>  	int ret;
>  
> -	ret = wdt_command(SCU_WATCHDOG_STOP, NULL, 0);
> +	ret = wdt_command(mid, SCU_WATCHDOG_STOP, NULL, 0, 0);
>  	if (ret)
> -		dev_crit(dev, "Error stopping watchdog: %d\n", ret);
> +		dev_crit(mid->dev, "Error stopping watchdog: %d\n", ret);
>  
>  	return ret;
>  }
> @@ -110,6 +123,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct watchdog_device *wdt_dev;
>  	struct intel_mid_wdt_pdata *pdata = dev->platform_data;
> +	struct mid_wdt *mid;
>  	int ret;
>  
>  	if (!pdata) {
> @@ -123,10 +137,13 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  			return ret;
>  	}
>  
> -	wdt_dev = devm_kzalloc(dev, sizeof(*wdt_dev), GFP_KERNEL);
> -	if (!wdt_dev)
> +	mid = devm_kzalloc(dev, sizeof(*mid), GFP_KERNEL);
> +	if (!mid)
>  		return -ENOMEM;
>  
> +	mid->dev = dev;
> +	wdt_dev = &mid->wd;
> +
>  	wdt_dev->info = &mid_wdt_info;
>  	wdt_dev->ops = &mid_wdt_ops;
>  	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
> @@ -135,7 +152,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  	wdt_dev->parent = dev;
>  
>  	watchdog_set_nowayout(wdt_dev, WATCHDOG_NOWAYOUT);
> -	watchdog_set_drvdata(wdt_dev, dev);
> +	watchdog_set_drvdata(wdt_dev, mid);
>  
>  	ret = devm_request_irq(dev, pdata->irq, mid_wdt_irq,
>  			       IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog",
> @@ -145,6 +162,10 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	mid->scu = devm_intel_scu_ipc_dev_get(dev);
> +	if (!mid->scu)
> +		return -EPROBE_DEFER;
> +
>  	/*
>  	 * The firmware followed by U-Boot leaves the watchdog running
>  	 * with the default threshold which may vary. When we get here
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers
  2020-01-08 17:34 ` [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Andy Shevchenko
@ 2020-01-09  6:13   ` Mika Westerberg
  0 siblings, 0 replies; 81+ messages in thread
From: Mika Westerberg @ 2020-01-09  6:13 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 07:34:44PM +0200, Andy Shevchenko wrote:
> On Wed, Jan 08, 2020 at 02:41:25PM +0300, Mika Westerberg wrote:
> > Hi,
> > 
> > Currently both intel_scu_ipc.c and intel_pmc_ipc.c implement the same SCU
> > IPC communications with minor differences. This duplication does not make
> > much sense so this series reworks the two drivers so that there is only a
> > single implementation of the SCU IPC. In addition to that the API will be
> > updated to take SCU instance pointer as an argument, and most of the
> > callers will be converted to this new API. The old API is left there but
> > the plan is to get rid the callers and then the old API as well (this is
> > something we are working with Andy Shevchenko).
> > 
> > The intel_pmc_ipc.c is then moved under MFD which suits better for this
> > kind of a driver that pretty much sets up the SCU IPC and then creates a
> > bunch of platform devices for the things sitting behind the PMC. The driver
> > is renamed to intel_pmc_bxt.c which should follow the existing conventions
> > under drivers/mfd (and it is only meant for Intel Broxton derivatives).
> > 
> > Previous version of the series:
> > 
> >   https://www.spinics.net/lists/platform-driver-x86/msg20359.html
> > 
> > Changes from the previous version:
> > 
> >   * Update changelog of patch 16 according to what the patch actually does.
> >   * Add kernel-doc for struct intel_soc_pmic.
> >   * Move octal permission patch to be before MFD conversion.
> >   * Convert the intel_pmc_bxt.c to MFD APIs whilst it is being moved under
> >     drivers/mfd.
> 
> Hmm... I didn't see you appended Lee's ACKs.

I thought those were for his own reference:

  For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

I can add them if that's not the case.

> > I'm including all x86 maintainers just to be sure they are aware of this as
> > I'm not sure if x86@kernel.org reaches them all. Let me know if you have
> > issues with this series.
> > 
> > I would prefer this to be merged through platform/x86 or MFD trees assuming
> > there are no objections.
> 
> I'm almost reviewed it (few patches left which I plan to do soon), I'm fine if
> it goes via other tree.

Thanks a lot for the review!

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API
  2020-01-08 11:41 ` [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API Mika Westerberg
@ 2020-01-09 11:30   ` Andy Shevchenko
  2020-01-09 11:39     ` Mika Westerberg
  0 siblings, 1 reply; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-09 11:30 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:39PM +0300, Mika Westerberg wrote:
> The current SCU IPC API has been operating on a single instance and
> there has been no way to pin the providing module in place when the SCU
> IPC is in use.
> 
> This implements a new API that takes the SCU IPC instance as first
> parameter (NULL means the single instance is being used). The SCU IPC
> instance can be retrieved by calling new function
> intel_scu_ipc_dev_get() that take care of pinning the providing module
> in place as long as intel_scu_ipc_dev_put() is not called.
> 
> The old API is left there to support existing users which cannot be
> converted easily but it is put to a separate header that is subject to
> be removed eventually. Subsequent patches will convert most of the users
> to the new API.

Few minor comments below. After addressing them,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  arch/x86/include/asm/intel_scu_ipc.h        |  74 +++----
>  arch/x86/include/asm/intel_scu_ipc_legacy.h |  76 +++++++
>  drivers/platform/x86/intel_scu_ipc.c        | 228 +++++++++++++++-----
>  drivers/platform/x86/intel_scu_pcidrv.c     |   7 +-
>  4 files changed, 291 insertions(+), 94 deletions(-)
>  create mode 100644 arch/x86/include/asm/intel_scu_ipc_legacy.h
> 
> diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> index 405c47bf0965..9895b60386c5 100644
> --- a/arch/x86/include/asm/intel_scu_ipc.h
> +++ b/arch/x86/include/asm/intel_scu_ipc.h
> @@ -1,8 +1,6 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  #ifndef _ASM_X86_INTEL_SCU_IPC_H_
> -#define  _ASM_X86_INTEL_SCU_IPC_H_
> -
> -#include <linux/notifier.h>
> +#define _ASM_X86_INTEL_SCU_IPC_H_
>  
>  #define IPCMSG_INDIRECT_READ	0x02
>  #define IPCMSG_INDIRECT_WRITE	0x05
> @@ -20,6 +18,7 @@
>  	#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
>  
>  struct device;
> +struct intel_scu_ipc_dev;
>  
>  /**
>   * struct intel_scu_ipc_pdata - Platform data for SCU IPC
> @@ -31,47 +30,38 @@ struct intel_scu_ipc_pdata {
>  	int irq;
>  };
>  
> -int intel_scu_ipc_probe(struct device *dev,
> -			const struct intel_scu_ipc_pdata *pdata);
> -
> -/* Read single register */
> -int intel_scu_ipc_ioread8(u16 addr, u8 *data);
> -
> -/* Read a vector */
> -int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
> -
> -/* Write single register */
> -int intel_scu_ipc_iowrite8(u16 addr, u8 data);
> -
> -/* Write a vector */
> -int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
> -
> -/* Update single register based on the mask */
> -int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
> -
> -/* Issue commands to the SCU with or without data */
> -int intel_scu_ipc_simple_command(int cmd, int sub);
> -int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> -			  u32 *out, int outlen);
> -
> -extern struct blocking_notifier_head intel_scu_notifier;
> -
> -static inline void intel_scu_notifier_add(struct notifier_block *nb)
> -{
> -	blocking_notifier_chain_register(&intel_scu_notifier, nb);
> -}
> -
> -static inline void intel_scu_notifier_remove(struct notifier_block *nb)
> -{
> -	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
> -}
> -
> -static inline int intel_scu_notifier_post(unsigned long v, void *p)
> +struct intel_scu_ipc_dev *
> +intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata);
> +
> +struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void);
> +void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu);
> +struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev);
> +
> +int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr,
> +			      u8 *data);
> +int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr,
> +			       u8 data);
> +int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr,
> +			    u8 *data, size_t len);
> +int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr,
> +			     u8 *data, size_t len);

+ blank line?

> +int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 data,
> +			     u8 mask);

Perhaps move u8 data on the next line to be (slightly) consistent with above.

> +
> +int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
> +				     int sub);
> +int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
> +					int sub, const void *in, size_t inlen,
> +					size_t size, void *out, size_t outlen);
> +
> +static inline int intel_scu_ipc_dev_command(struct intel_scu_ipc_dev *scu, int cmd,
> +					    int sub, const void *in, size_t inlen,
> +					    void *out, size_t outlen)
>  {
> -	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
> +	return intel_scu_ipc_dev_command_with_size(scu, cmd, sub, in, inlen,
> +						   inlen, out, outlen);
>  }
>  
> -#define		SCU_AVAILABLE		1
> -#define		SCU_DOWN		2
> +#include <asm/intel_scu_ipc_legacy.h>
>  
>  #endif
> diff --git a/arch/x86/include/asm/intel_scu_ipc_legacy.h b/arch/x86/include/asm/intel_scu_ipc_legacy.h
> new file mode 100644
> index 000000000000..3399ea8eea48
> --- /dev/null
> +++ b/arch/x86/include/asm/intel_scu_ipc_legacy.h
> @@ -0,0 +1,76 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
> +#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
> +
> +#include <linux/notifier.h>
> +
> +/* Don't call these in new code - they will be removed eventually */
> +
> +/* Read single register */
> +static inline int intel_scu_ipc_ioread8(u16 addr, u8 *data)
> +{
> +	return intel_scu_ipc_dev_ioread8(NULL, addr, data);
> +}
> +
> +/* Read a vector */
> +static inline int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
> +{
> +	return intel_scu_ipc_dev_readv(NULL, addr, data, len);
> +}
> +
> +/* Write single register */
> +static inline int intel_scu_ipc_iowrite8(u16 addr, u8 data)
> +{
> +	return intel_scu_ipc_dev_iowrite8(NULL, addr, data);
> +}
> +
> +/* Write a vector */
> +static inline int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
> +{
> +	return intel_scu_ipc_dev_writev(NULL, addr, data, len);
> +}
> +
> +/* Update single register based on the mask */
> +static inline int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask)
> +{
> +	return intel_scu_ipc_dev_update(NULL, addr, data, mask);
> +}
> +
> +/* Issue commands to the SCU with or without data */
> +static inline int intel_scu_ipc_simple_command(int cmd, int sub)
> +{
> +	return intel_scu_ipc_dev_simple_command(NULL, cmd, sub);
> +}
> +
> +static inline int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> +					u32 *out, int outlen)
> +{
> +	/* New API takes both inlen and outlen as bytes so convert here */
> +	size_t inbytes = inlen * sizeof(u32);
> +	size_t outbytes = outlen * sizeof(u32);
> +
> +	return intel_scu_ipc_dev_command_with_size(NULL, cmd, sub, in, inbytes,
> +						   inlen, out, outbytes);
> +}
> +
> +extern struct blocking_notifier_head intel_scu_notifier;
> +
> +static inline void intel_scu_notifier_add(struct notifier_block *nb)
> +{
> +	blocking_notifier_chain_register(&intel_scu_notifier, nb);
> +}
> +
> +static inline void intel_scu_notifier_remove(struct notifier_block *nb)
> +{
> +	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
> +}
> +
> +static inline int intel_scu_notifier_post(unsigned long v, void *p)
> +{
> +	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
> +}
> +
> +#define		SCU_AVAILABLE		1
> +#define		SCU_DOWN		2
> +
> +#endif
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index b1ac381bb7dd..cc29f504adcf 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -19,6 +19,7 @@
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> +#include <linux/module.h>
>  
>  #include <asm/intel_scu_ipc.h>
>  
> @@ -77,6 +78,99 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
>  
>  static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
>  
> +/**
> + * intel_scu_ipc_dev_get() - Get SCU IPC instance
> + *
> + * The recommended new API takes SCU IPC instance as parameter and this
> + * function can be called by driver to get the instance. This also makes
> + * sure the driver providing the IPC functionality cannot be unloaded
> + * while the caller has the intance.
> + *
> + * Call intel_scu_ipc_dev_put() to release the instance.
> + *
> + * Returns %NULL if SCU IPC is not currently available.
> + */
> +struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void)
> +{
> +	struct intel_scu_ipc_dev *scu = &ipcdev;
> +
> +	mutex_lock(&ipclock);
> +	if (!scu->dev)
> +		goto err_unlock;
> +	if (!try_module_get(scu->dev->driver->owner))
> +		goto err_unlock;
> +	mutex_unlock(&ipclock);
> +	return scu;
> +
> +err_unlock:
> +	mutex_unlock(&ipclock);
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_get);
> +
> +/**
> + * intel_scu_ipc_dev_put() - Put SCU IPC instance
> + * @scu: SCU IPC instance
> + *
> + * This function releases the SCU IPC instance retrieved from
> + * intel_scu_ipc_dev_get() and allows the driver providing IPC to be
> + * unloaded.
> + */
> +void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu)
> +{
> +	mutex_lock(&ipclock);
> +	if (scu->dev)
> +		module_put(scu->dev->driver->owner);
> +	mutex_unlock(&ipclock);
> +}
> +EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_put);
> +
> +struct intel_scu_ipc_devres {
> +	struct intel_scu_ipc_dev *scu;
> +};
> +
> +static void devm_intel_scu_ipc_dev_release(struct device *dev, void *res)
> +{
> +	struct intel_scu_ipc_devres *devres = res;
> +	struct intel_scu_ipc_dev *scu = devres->scu;
> +
> +	intel_scu_ipc_dev_put(scu);
> +}
> +
> +/**
> + * devm_intel_scu_ipc_dev_get() - Allocate managed SCU IPC device
> + * @dev: Device requesting the SCU IPC device
> + *
> + * The recommended new API takes SCU IPC instance as parameter and this
> + * function can be called by driver to get the instance. This also makes
> + * sure the driver providing the IPC functionality cannot be unloaded
> + * while the caller has the intance.
> + *
> + * Returns %NULL if SCU IPC is not currently available.
> + */
> +struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev)
> +{
> +	struct intel_scu_ipc_devres *devres;
> +	struct intel_scu_ipc_dev *scu;
> +
> +	devres = devres_alloc(devm_intel_scu_ipc_dev_release, sizeof(*devres),
> +			      GFP_KERNEL);
> +	if (!devres)
> +		return NULL;
> +
> +	scu = intel_scu_ipc_dev_get();
> +	if (!scu) {
> +		devres_free(devres);
> +		return NULL;
> +	}
> +
> +	devres->scu = scu;
> +	devres_add(dev, devres);
> +
> +	return scu;
> +}
> +EXPORT_SYMBOL_GPL(devm_intel_scu_ipc_dev_get);
> +
>  /*
>   * Send ipc command
>   * Command Register (Write Only):
> @@ -167,15 +261,18 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *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)
> +static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> +			u32 count, u32 op, u32 id)
>  {
> -	struct intel_scu_ipc_dev *scu = &ipcdev;
>  	int nc;
>  	u32 offset = 0;
>  	int err;
>  	u8 cbuf[IPC_WWBUF_SIZE];
>  	u32 *wbuf = (u32 *)&cbuf;
>  
> +	if (!scu)
> +		scu = &ipcdev;
> +
>  	memset(cbuf, 0, sizeof(cbuf));
>  
>  	mutex_lock(&ipclock);
> @@ -219,7 +316,8 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
>  }
>  
>  /**
> - * intel_scu_ipc_ioread8		-	read a word via the SCU
> + * intel_scu_ipc_dev_ioread8() - Read a byte via the SCU
> + * @scu: Optional SCU IPC instance
>   * @addr: Register on SCU
>   * @data: Return pointer for read byte
>   *
> @@ -228,14 +326,15 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
>   *
>   * This function may sleep.
>   */
> -int intel_scu_ipc_ioread8(u16 addr, u8 *data)
> +int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr, u8 *data)
>  {
> -	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> +	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_ioread8);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_ioread8);
>  
>  /**
> - * intel_scu_ipc_iowrite8		-	write a byte via the SCU
> + * intel_scu_ipc_dev_iowrite8() - Write a byte via the SCU
> + * @scu: Optional SCU IPC instance
>   * @addr: Register on SCU
>   * @data: Byte to write
>   *
> @@ -244,14 +343,15 @@ EXPORT_SYMBOL(intel_scu_ipc_ioread8);
>   *
>   * This function may sleep.
>   */
> -int intel_scu_ipc_iowrite8(u16 addr, u8 data)
> +int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr, u8 data)
>  {
> -	return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> +	return pwr_reg_rdwr(scu, &addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_iowrite8);
>  
>  /**
> - * intel_scu_ipc_readvv		-	read a set of registers
> + * intel_scu_ipc_dev_readv() - Read a set of registers
> + * @scu: Optional SCU IPC instance
>   * @addr: Register list
>   * @data: Bytes to return
>   * @len: Length of array
> @@ -263,14 +363,16 @@ EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
>   *
>   * This function may sleep.
>   */
> -int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
> +int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> +			    size_t len)
>  {
> -	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> +	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_readv);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_readv);
>  
>  /**
> - * intel_scu_ipc_writev		-	write a set of registers
> + * intel_scu_ipc_dev_writev() - Write a set of registers
> + * @scu: Optional SCU IPC instance
>   * @addr: Register list
>   * @data: Bytes to write
>   * @len: Length of array
> @@ -282,14 +384,16 @@ EXPORT_SYMBOL(intel_scu_ipc_readv);
>   *
>   * This function may sleep.
>   */
> -int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
> +int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> +			     size_t len)
>  {
> -	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> +	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_writev);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_writev);
>  
>  /**
> - * intel_scu_ipc_update_register	-	r/m/w a register
> + * intel_scu_ipc_dev_update() - Update a register
> + * @scu: Optional SCU IPC instance
>   * @addr: Register address
>   * @bits: Bits to update
>   * @mask: Mask of bits to update
> @@ -302,15 +406,17 @@ EXPORT_SYMBOL(intel_scu_ipc_writev);
>   * This function may sleep. Locking between SCU accesses is handled
>   * for the caller.
>   */
> -int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)

> +int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 bits,
> +			     u8 mask)

In header you have 'u8 data'. Can we be consistent with a name?

>  {
>  	u8 data[2] = { bits, mask };
> -	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
> +	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_update_register);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_update);
>  
>  /**
> - * intel_scu_ipc_simple_command	-	send a simple command
> + * intel_scu_ipc_dev_simple_command() - Send a simple command
> + * @scu: Optional SCU IPC instance
>   * @cmd: Command
>   * @sub: Sub type
>   *
> @@ -321,11 +427,14 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register);
>   * This function may sleep. Locking for SCU accesses is handled for the
>   * caller.
>   */
> -int intel_scu_ipc_simple_command(int cmd, int sub)
> +int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
> +				     int sub)
>  {
> -	struct intel_scu_ipc_dev *scu = &ipcdev;
>  	int err;
>  
> +	if (!scu)
> +		scu = &ipcdev;
> +
>  	mutex_lock(&ipclock);
>  	if (scu->dev == NULL) {
>  		mutex_unlock(&ipclock);
> @@ -336,47 +445,65 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
>  	mutex_unlock(&ipclock);
>  	return err;
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_simple_command);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_simple_command);
>  
>  /**
> - * intel_scu_ipc_command	-	command with data
> + * intel_scu_ipc_command_with_size() - Command with data
> + * @scu: Optional SCU IPC instance
>   * @cmd: Command
>   * @sub: Sub type
>   * @in: Input data
> - * @inlen: Input length in dwords
> + * @inlen: Input length in bytes
> + * @size: Input size written to the IPC command register in whatever
> + *	  units (dword, byte) the particular firmware requires. Normally
> + *	  should be the same as @inlen.
>   * @out: Output data
> - * @outlen: Output length in dwords
> + * @outlen: Output length in bytes
>   *
>   * Issue a command to the SCU which involves data transfers. Do the
>   * data copies under the lock but leave it for the caller to interpret.
>   */
> -int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> -			  u32 *out, int outlen)
> +int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
> +					int sub, const void *in, size_t inlen,
> +					size_t size, void *out, size_t outlen)
>  {
> -	struct intel_scu_ipc_dev *scu = &ipcdev;
> +	size_t outbuflen = DIV_ROUND_UP(outlen, sizeof(u32));
> +	size_t inbuflen = DIV_ROUND_UP(inlen, sizeof(u32));
> +	u32 inbuf[4] = {};
>  	int i, err;
>  
> +	if (inbuflen > 4 || outbuflen > 4)
> +		return -EINVAL;
> +
> +	if (!scu)
> +		scu = &ipcdev;
> +
>  	mutex_lock(&ipclock);
>  	if (scu->dev == NULL) {
>  		mutex_unlock(&ipclock);
>  		return -ENODEV;
>  	}
>  
> -	for (i = 0; i < inlen; i++)
> -		ipc_data_writel(scu, *in++, 4 * i);
> +	memcpy(inbuf, in, inlen);
> +	for (i = 0; i < inbuflen; i++)
> +		ipc_data_writel(scu, inbuf[i], 4 * i);
>  
> -	ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
> +	ipc_command(scu, (size << 16) | (sub << 12) | cmd);
>  	err = intel_scu_ipc_check_status(scu);
>  
> -	if (!err) {
> -		for (i = 0; i < outlen; i++)
> -			*out++ = ipc_data_readl(scu, 4 * i);

> +	if (!err && outlen) {

Do we need the 'outlen' test here? In any case if it's zero the following
will be no-op.

> +		u32 outbuf[4] = {};
> +
> +		for (i = 0; i < outbuflen; i++)
> +			outbuf[i] = ipc_data_readl(scu, 4 * i);
> +
> +		memcpy(out, outbuf, outlen);
>  	}
>  
>  	mutex_unlock(&ipclock);
>  	return err;
>  }
> -EXPORT_SYMBOL(intel_scu_ipc_command);
> +EXPORT_SYMBOL(intel_scu_ipc_dev_command_with_size);
>  
>  /*
>   * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
> @@ -401,20 +528,20 @@ static irqreturn_t ioc(int irq, void *dev_id)
>   * @dev: SCU device
>   * @pdata: Platform specific data
>   *
> - * Call this function to initialize SCU IPC mechanism. It is removed
> - * automatically when the calling driver is unbound from @dev.
> + * Call this function to initialize SCU IPC mechanism. Returns SCU IPC
> + * instance or ERR_PTR() if there was an error. The caller may use the
> + * returned instance if it needs to do SCU IPC calls itself.
>   */
> -int intel_scu_ipc_probe(struct device *dev,
> -			const struct intel_scu_ipc_pdata *pdata)
> +struct intel_scu_ipc_dev *
> +intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata)
>  {
> -	int err;
>  	struct intel_scu_ipc_dev *scu = &ipcdev;
>  
>  	mutex_lock(&ipclock);
>  	/* We support only one IPC */
>  	if (scu->dev) {
>  		mutex_unlock(&ipclock);
> -		return -EBUSY;
> +		return ERR_PTR(-EBUSY);
>  	}
>  
>  	scu->ipc_base = pdata->ipc_regs;
> @@ -422,17 +549,20 @@ int intel_scu_ipc_probe(struct device *dev,
>  	init_completion(&scu->cmd_complete);
>  
>  	if (scu->irq > 0) {
> +		int err;
> +
>  		err = devm_request_irq(dev, scu->irq, ioc, 0, "intel_scu_ipc",
>  				       scu);
> -		if (err)
> -			goto unlock;
> +		if (err) {
> +			mutex_unlock(&ipclock);
> +			return ERR_PTR(err);
> +		}
>  	}
>  
>  	/* Assign device at last */
>  	scu->dev = dev;
>  
> -unlock:
>  	mutex_unlock(&ipclock);
> -	return err;
> +	return scu;
>  }
>  EXPORT_SYMBOL_GPL(intel_scu_ipc_probe);
> diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
> index 47dd4d85bf2a..42030bdb3e08 100644
> --- a/drivers/platform/x86/intel_scu_pcidrv.c
> +++ b/drivers/platform/x86/intel_scu_pcidrv.c
> @@ -18,6 +18,7 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
>  			       const struct pci_device_id *id)
>  {
>  	struct intel_scu_ipc_pdata *pdata;
> +	struct intel_scu_ipc_dev *scu;
>  	int ret;
>  
>  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> @@ -35,9 +36,9 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
>  	pdata->ipc_regs = pcim_iomap_table(pdev)[0];
>  	pdata->irq = pdev->irq;
>  
> -	ret = intel_scu_ipc_probe(&pdev->dev, pdata);
> -	if (ret)
> -		return ret;
> +	scu = intel_scu_ipc_probe(&pdev->dev, pdata);
> +	if (IS_ERR(scu))
> +		return PTR_ERR(scu);
>  
>  	intel_scu_devices_create();
>  	return 0;
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API
  2020-01-09 11:30   ` Andy Shevchenko
@ 2020-01-09 11:39     ` Mika Westerberg
  0 siblings, 0 replies; 81+ messages in thread
From: Mika Westerberg @ 2020-01-09 11:39 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Thu, Jan 09, 2020 at 01:30:15PM +0200, Andy Shevchenko wrote:
> On Wed, Jan 08, 2020 at 02:41:39PM +0300, Mika Westerberg wrote:
> > The current SCU IPC API has been operating on a single instance and
> > there has been no way to pin the providing module in place when the SCU
> > IPC is in use.
> > 
> > This implements a new API that takes the SCU IPC instance as first
> > parameter (NULL means the single instance is being used). The SCU IPC
> > instance can be retrieved by calling new function
> > intel_scu_ipc_dev_get() that take care of pinning the providing module
> > in place as long as intel_scu_ipc_dev_put() is not called.
> > 
> > The old API is left there to support existing users which cannot be
> > converted easily but it is put to a separate header that is subject to
> > be removed eventually. Subsequent patches will convert most of the users
> > to the new API.
> 
> Few minor comments below. After addressing them,
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Thanks!

> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  arch/x86/include/asm/intel_scu_ipc.h        |  74 +++----
> >  arch/x86/include/asm/intel_scu_ipc_legacy.h |  76 +++++++
> >  drivers/platform/x86/intel_scu_ipc.c        | 228 +++++++++++++++-----
> >  drivers/platform/x86/intel_scu_pcidrv.c     |   7 +-
> >  4 files changed, 291 insertions(+), 94 deletions(-)
> >  create mode 100644 arch/x86/include/asm/intel_scu_ipc_legacy.h
> > 
> > diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h
> > index 405c47bf0965..9895b60386c5 100644
> > --- a/arch/x86/include/asm/intel_scu_ipc.h
> > +++ b/arch/x86/include/asm/intel_scu_ipc.h
> > @@ -1,8 +1,6 @@
> >  /* SPDX-License-Identifier: GPL-2.0 */
> >  #ifndef _ASM_X86_INTEL_SCU_IPC_H_
> > -#define  _ASM_X86_INTEL_SCU_IPC_H_
> > -
> > -#include <linux/notifier.h>
> > +#define _ASM_X86_INTEL_SCU_IPC_H_
> >  
> >  #define IPCMSG_INDIRECT_READ	0x02
> >  #define IPCMSG_INDIRECT_WRITE	0x05
> > @@ -20,6 +18,7 @@
> >  	#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
> >  
> >  struct device;
> > +struct intel_scu_ipc_dev;
> >  
> >  /**
> >   * struct intel_scu_ipc_pdata - Platform data for SCU IPC
> > @@ -31,47 +30,38 @@ struct intel_scu_ipc_pdata {
> >  	int irq;
> >  };
> >  
> > -int intel_scu_ipc_probe(struct device *dev,
> > -			const struct intel_scu_ipc_pdata *pdata);
> > -
> > -/* Read single register */
> > -int intel_scu_ipc_ioread8(u16 addr, u8 *data);
> > -
> > -/* Read a vector */
> > -int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
> > -
> > -/* Write single register */
> > -int intel_scu_ipc_iowrite8(u16 addr, u8 data);
> > -
> > -/* Write a vector */
> > -int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
> > -
> > -/* Update single register based on the mask */
> > -int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
> > -
> > -/* Issue commands to the SCU with or without data */
> > -int intel_scu_ipc_simple_command(int cmd, int sub);
> > -int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> > -			  u32 *out, int outlen);
> > -
> > -extern struct blocking_notifier_head intel_scu_notifier;
> > -
> > -static inline void intel_scu_notifier_add(struct notifier_block *nb)
> > -{
> > -	blocking_notifier_chain_register(&intel_scu_notifier, nb);
> > -}
> > -
> > -static inline void intel_scu_notifier_remove(struct notifier_block *nb)
> > -{
> > -	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
> > -}
> > -
> > -static inline int intel_scu_notifier_post(unsigned long v, void *p)
> > +struct intel_scu_ipc_dev *
> > +intel_scu_ipc_probe(struct device *dev, const struct intel_scu_ipc_pdata *pdata);
> > +
> > +struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void);
> > +void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu);
> > +struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev);
> > +
> > +int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr,
> > +			      u8 *data);
> > +int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr,
> > +			       u8 data);
> > +int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr,
> > +			    u8 *data, size_t len);
> > +int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr,
> > +			     u8 *data, size_t len);
> 
> + blank line?

OK

> > +int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 data,
> > +			     u8 mask);
> 
> Perhaps move u8 data on the next line to be (slightly) consistent with above.

OK

> > +
> > +int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
> > +				     int sub);
> > +int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
> > +					int sub, const void *in, size_t inlen,
> > +					size_t size, void *out, size_t outlen);
> > +
> > +static inline int intel_scu_ipc_dev_command(struct intel_scu_ipc_dev *scu, int cmd,
> > +					    int sub, const void *in, size_t inlen,
> > +					    void *out, size_t outlen)
> >  {
> > -	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
> > +	return intel_scu_ipc_dev_command_with_size(scu, cmd, sub, in, inlen,
> > +						   inlen, out, outlen);
> >  }
> >  
> > -#define		SCU_AVAILABLE		1
> > -#define		SCU_DOWN		2
> > +#include <asm/intel_scu_ipc_legacy.h>
> >  
> >  #endif
> > diff --git a/arch/x86/include/asm/intel_scu_ipc_legacy.h b/arch/x86/include/asm/intel_scu_ipc_legacy.h
> > new file mode 100644
> > index 000000000000..3399ea8eea48
> > --- /dev/null
> > +++ b/arch/x86/include/asm/intel_scu_ipc_legacy.h
> > @@ -0,0 +1,76 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
> > +#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
> > +
> > +#include <linux/notifier.h>
> > +
> > +/* Don't call these in new code - they will be removed eventually */
> > +
> > +/* Read single register */
> > +static inline int intel_scu_ipc_ioread8(u16 addr, u8 *data)
> > +{
> > +	return intel_scu_ipc_dev_ioread8(NULL, addr, data);
> > +}
> > +
> > +/* Read a vector */
> > +static inline int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
> > +{
> > +	return intel_scu_ipc_dev_readv(NULL, addr, data, len);
> > +}
> > +
> > +/* Write single register */
> > +static inline int intel_scu_ipc_iowrite8(u16 addr, u8 data)
> > +{
> > +	return intel_scu_ipc_dev_iowrite8(NULL, addr, data);
> > +}
> > +
> > +/* Write a vector */
> > +static inline int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
> > +{
> > +	return intel_scu_ipc_dev_writev(NULL, addr, data, len);
> > +}
> > +
> > +/* Update single register based on the mask */
> > +static inline int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask)
> > +{
> > +	return intel_scu_ipc_dev_update(NULL, addr, data, mask);
> > +}
> > +
> > +/* Issue commands to the SCU with or without data */
> > +static inline int intel_scu_ipc_simple_command(int cmd, int sub)
> > +{
> > +	return intel_scu_ipc_dev_simple_command(NULL, cmd, sub);
> > +}
> > +
> > +static inline int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> > +					u32 *out, int outlen)
> > +{
> > +	/* New API takes both inlen and outlen as bytes so convert here */
> > +	size_t inbytes = inlen * sizeof(u32);
> > +	size_t outbytes = outlen * sizeof(u32);
> > +
> > +	return intel_scu_ipc_dev_command_with_size(NULL, cmd, sub, in, inbytes,
> > +						   inlen, out, outbytes);
> > +}
> > +
> > +extern struct blocking_notifier_head intel_scu_notifier;
> > +
> > +static inline void intel_scu_notifier_add(struct notifier_block *nb)
> > +{
> > +	blocking_notifier_chain_register(&intel_scu_notifier, nb);
> > +}
> > +
> > +static inline void intel_scu_notifier_remove(struct notifier_block *nb)
> > +{
> > +	blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
> > +}
> > +
> > +static inline int intel_scu_notifier_post(unsigned long v, void *p)
> > +{
> > +	return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
> > +}
> > +
> > +#define		SCU_AVAILABLE		1
> > +#define		SCU_DOWN		2
> > +
> > +#endif
> > diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> > index b1ac381bb7dd..cc29f504adcf 100644
> > --- a/drivers/platform/x86/intel_scu_ipc.c
> > +++ b/drivers/platform/x86/intel_scu_ipc.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/init.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/io.h>
> > +#include <linux/module.h>
> >  
> >  #include <asm/intel_scu_ipc.h>
> >  
> > @@ -77,6 +78,99 @@ static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
> >  
> >  static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
> >  
> > +/**
> > + * intel_scu_ipc_dev_get() - Get SCU IPC instance
> > + *
> > + * The recommended new API takes SCU IPC instance as parameter and this
> > + * function can be called by driver to get the instance. This also makes
> > + * sure the driver providing the IPC functionality cannot be unloaded
> > + * while the caller has the intance.
> > + *
> > + * Call intel_scu_ipc_dev_put() to release the instance.
> > + *
> > + * Returns %NULL if SCU IPC is not currently available.
> > + */
> > +struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void)
> > +{
> > +	struct intel_scu_ipc_dev *scu = &ipcdev;
> > +
> > +	mutex_lock(&ipclock);
> > +	if (!scu->dev)
> > +		goto err_unlock;
> > +	if (!try_module_get(scu->dev->driver->owner))
> > +		goto err_unlock;
> > +	mutex_unlock(&ipclock);
> > +	return scu;
> > +
> > +err_unlock:
> > +	mutex_unlock(&ipclock);
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_get);
> > +
> > +/**
> > + * intel_scu_ipc_dev_put() - Put SCU IPC instance
> > + * @scu: SCU IPC instance
> > + *
> > + * This function releases the SCU IPC instance retrieved from
> > + * intel_scu_ipc_dev_get() and allows the driver providing IPC to be
> > + * unloaded.
> > + */
> > +void intel_scu_ipc_dev_put(struct intel_scu_ipc_dev *scu)
> > +{
> > +	mutex_lock(&ipclock);
> > +	if (scu->dev)
> > +		module_put(scu->dev->driver->owner);
> > +	mutex_unlock(&ipclock);
> > +}
> > +EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_put);
> > +
> > +struct intel_scu_ipc_devres {
> > +	struct intel_scu_ipc_dev *scu;
> > +};
> > +
> > +static void devm_intel_scu_ipc_dev_release(struct device *dev, void *res)
> > +{
> > +	struct intel_scu_ipc_devres *devres = res;
> > +	struct intel_scu_ipc_dev *scu = devres->scu;
> > +
> > +	intel_scu_ipc_dev_put(scu);
> > +}
> > +
> > +/**
> > + * devm_intel_scu_ipc_dev_get() - Allocate managed SCU IPC device
> > + * @dev: Device requesting the SCU IPC device
> > + *
> > + * The recommended new API takes SCU IPC instance as parameter and this
> > + * function can be called by driver to get the instance. This also makes
> > + * sure the driver providing the IPC functionality cannot be unloaded
> > + * while the caller has the intance.
> > + *
> > + * Returns %NULL if SCU IPC is not currently available.
> > + */
> > +struct intel_scu_ipc_dev *devm_intel_scu_ipc_dev_get(struct device *dev)
> > +{
> > +	struct intel_scu_ipc_devres *devres;
> > +	struct intel_scu_ipc_dev *scu;
> > +
> > +	devres = devres_alloc(devm_intel_scu_ipc_dev_release, sizeof(*devres),
> > +			      GFP_KERNEL);
> > +	if (!devres)
> > +		return NULL;
> > +
> > +	scu = intel_scu_ipc_dev_get();
> > +	if (!scu) {
> > +		devres_free(devres);
> > +		return NULL;
> > +	}
> > +
> > +	devres->scu = scu;
> > +	devres_add(dev, devres);
> > +
> > +	return scu;
> > +}
> > +EXPORT_SYMBOL_GPL(devm_intel_scu_ipc_dev_get);
> > +
> >  /*
> >   * Send ipc command
> >   * Command Register (Write Only):
> > @@ -167,15 +261,18 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *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)
> > +static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> > +			u32 count, u32 op, u32 id)
> >  {
> > -	struct intel_scu_ipc_dev *scu = &ipcdev;
> >  	int nc;
> >  	u32 offset = 0;
> >  	int err;
> >  	u8 cbuf[IPC_WWBUF_SIZE];
> >  	u32 *wbuf = (u32 *)&cbuf;
> >  
> > +	if (!scu)
> > +		scu = &ipcdev;
> > +
> >  	memset(cbuf, 0, sizeof(cbuf));
> >  
> >  	mutex_lock(&ipclock);
> > @@ -219,7 +316,8 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
> >  }
> >  
> >  /**
> > - * intel_scu_ipc_ioread8		-	read a word via the SCU
> > + * intel_scu_ipc_dev_ioread8() - Read a byte via the SCU
> > + * @scu: Optional SCU IPC instance
> >   * @addr: Register on SCU
> >   * @data: Return pointer for read byte
> >   *
> > @@ -228,14 +326,15 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
> >   *
> >   * This function may sleep.
> >   */
> > -int intel_scu_ipc_ioread8(u16 addr, u8 *data)
> > +int intel_scu_ipc_dev_ioread8(struct intel_scu_ipc_dev *scu, u16 addr, u8 *data)
> >  {
> > -	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> > +	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_ioread8);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_ioread8);
> >  
> >  /**
> > - * intel_scu_ipc_iowrite8		-	write a byte via the SCU
> > + * intel_scu_ipc_dev_iowrite8() - Write a byte via the SCU
> > + * @scu: Optional SCU IPC instance
> >   * @addr: Register on SCU
> >   * @data: Byte to write
> >   *
> > @@ -244,14 +343,15 @@ EXPORT_SYMBOL(intel_scu_ipc_ioread8);
> >   *
> >   * This function may sleep.
> >   */
> > -int intel_scu_ipc_iowrite8(u16 addr, u8 data)
> > +int intel_scu_ipc_dev_iowrite8(struct intel_scu_ipc_dev *scu, u16 addr, u8 data)
> >  {
> > -	return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> > +	return pwr_reg_rdwr(scu, &addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_iowrite8);
> >  
> >  /**
> > - * intel_scu_ipc_readvv		-	read a set of registers
> > + * intel_scu_ipc_dev_readv() - Read a set of registers
> > + * @scu: Optional SCU IPC instance
> >   * @addr: Register list
> >   * @data: Bytes to return
> >   * @len: Length of array
> > @@ -263,14 +363,16 @@ EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
> >   *
> >   * This function may sleep.
> >   */
> > -int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
> > +int intel_scu_ipc_dev_readv(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> > +			    size_t len)
> >  {
> > -	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> > +	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_readv);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_readv);
> >  
> >  /**
> > - * intel_scu_ipc_writev		-	write a set of registers
> > + * intel_scu_ipc_dev_writev() - Write a set of registers
> > + * @scu: Optional SCU IPC instance
> >   * @addr: Register list
> >   * @data: Bytes to write
> >   * @len: Length of array
> > @@ -282,14 +384,16 @@ EXPORT_SYMBOL(intel_scu_ipc_readv);
> >   *
> >   * This function may sleep.
> >   */
> > -int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
> > +int intel_scu_ipc_dev_writev(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
> > +			     size_t len)
> >  {
> > -	return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> > +	return pwr_reg_rdwr(scu, addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_writev);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_writev);
> >  
> >  /**
> > - * intel_scu_ipc_update_register	-	r/m/w a register
> > + * intel_scu_ipc_dev_update() - Update a register
> > + * @scu: Optional SCU IPC instance
> >   * @addr: Register address
> >   * @bits: Bits to update
> >   * @mask: Mask of bits to update
> > @@ -302,15 +406,17 @@ EXPORT_SYMBOL(intel_scu_ipc_writev);
> >   * This function may sleep. Locking between SCU accesses is handled
> >   * for the caller.
> >   */
> > -int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
> 
> > +int intel_scu_ipc_dev_update(struct intel_scu_ipc_dev *scu, u16 addr, u8 bits,
> > +			     u8 mask)
> 
> In header you have 'u8 data'. Can we be consistent with a name?

Sure.

> >  {
> >  	u8 data[2] = { bits, mask };
> > -	return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
> > +	return pwr_reg_rdwr(scu, &addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_update_register);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_update);
> >  
> >  /**
> > - * intel_scu_ipc_simple_command	-	send a simple command
> > + * intel_scu_ipc_dev_simple_command() - Send a simple command
> > + * @scu: Optional SCU IPC instance
> >   * @cmd: Command
> >   * @sub: Sub type
> >   *
> > @@ -321,11 +427,14 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register);
> >   * This function may sleep. Locking for SCU accesses is handled for the
> >   * caller.
> >   */
> > -int intel_scu_ipc_simple_command(int cmd, int sub)
> > +int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
> > +				     int sub)
> >  {
> > -	struct intel_scu_ipc_dev *scu = &ipcdev;
> >  	int err;
> >  
> > +	if (!scu)
> > +		scu = &ipcdev;
> > +
> >  	mutex_lock(&ipclock);
> >  	if (scu->dev == NULL) {
> >  		mutex_unlock(&ipclock);
> > @@ -336,47 +445,65 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
> >  	mutex_unlock(&ipclock);
> >  	return err;
> >  }
> > -EXPORT_SYMBOL(intel_scu_ipc_simple_command);
> > +EXPORT_SYMBOL(intel_scu_ipc_dev_simple_command);
> >  
> >  /**
> > - * intel_scu_ipc_command	-	command with data
> > + * intel_scu_ipc_command_with_size() - Command with data
> > + * @scu: Optional SCU IPC instance
> >   * @cmd: Command
> >   * @sub: Sub type
> >   * @in: Input data
> > - * @inlen: Input length in dwords
> > + * @inlen: Input length in bytes
> > + * @size: Input size written to the IPC command register in whatever
> > + *	  units (dword, byte) the particular firmware requires. Normally
> > + *	  should be the same as @inlen.
> >   * @out: Output data
> > - * @outlen: Output length in dwords
> > + * @outlen: Output length in bytes
> >   *
> >   * Issue a command to the SCU which involves data transfers. Do the
> >   * data copies under the lock but leave it for the caller to interpret.
> >   */
> > -int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
> > -			  u32 *out, int outlen)
> > +int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
> > +					int sub, const void *in, size_t inlen,
> > +					size_t size, void *out, size_t outlen)
> >  {
> > -	struct intel_scu_ipc_dev *scu = &ipcdev;
> > +	size_t outbuflen = DIV_ROUND_UP(outlen, sizeof(u32));
> > +	size_t inbuflen = DIV_ROUND_UP(inlen, sizeof(u32));
> > +	u32 inbuf[4] = {};
> >  	int i, err;
> >  
> > +	if (inbuflen > 4 || outbuflen > 4)
> > +		return -EINVAL;
> > +
> > +	if (!scu)
> > +		scu = &ipcdev;
> > +
> >  	mutex_lock(&ipclock);
> >  	if (scu->dev == NULL) {
> >  		mutex_unlock(&ipclock);
> >  		return -ENODEV;
> >  	}
> >  
> > -	for (i = 0; i < inlen; i++)
> > -		ipc_data_writel(scu, *in++, 4 * i);
> > +	memcpy(inbuf, in, inlen);
> > +	for (i = 0; i < inbuflen; i++)
> > +		ipc_data_writel(scu, inbuf[i], 4 * i);
> >  
> > -	ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
> > +	ipc_command(scu, (size << 16) | (sub << 12) | cmd);
> >  	err = intel_scu_ipc_check_status(scu);
> >  
> > -	if (!err) {
> > -		for (i = 0; i < outlen; i++)
> > -			*out++ = ipc_data_readl(scu, 4 * i);
> 
> > +	if (!err && outlen) {
> 
> Do we need the 'outlen' test here? In any case if it's zero the following
> will be no-op.

Right, it is not needed. I'll remove the check.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD
  2020-01-08 11:41 ` [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD Mika Westerberg
@ 2020-01-09 11:43   ` Andy Shevchenko
  2020-01-09 11:47     ` Mika Westerberg
  0 siblings, 1 reply; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-09 11:43 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, Jan 08, 2020 at 02:41:59PM +0300, Mika Westerberg wrote:
> This driver only creates a bunch of platform devices sharing resources
> belonging to the PMC device. This is pretty much what MFD subsystem is
> for so move the driver there, renaming it to intel_pmc_bxt.c which
> should be more clear what it is.
> 
> MFD subsystem provides nice helper APIs for subdevice creation so
> convert the driver to use those. Unfortunately the ACPI device includes
> separate resources for most of the subdevices so we cannot simply call
> mfd_add_devices() to create all of them but instead we need to call it
> separately for each device.

Comments below, after addressing,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/mfd/Kconfig                           |  14 +-
>  drivers/mfd/Makefile                          |   1 +
>  .../intel_pmc_ipc.c => mfd/intel_pmc_bxt.c}   | 394 +++++++-----------
>  drivers/platform/x86/Kconfig                  |  16 +-
>  drivers/platform/x86/Makefile                 |   1 -
>  .../platform/x86/intel_telemetry_debugfs.c    |   2 +-
>  drivers/usb/typec/tcpm/Kconfig                |   2 +-
>  .../linux/mfd/intel_pmc_bxt.h                 |  11 +-
>  8 files changed, 171 insertions(+), 270 deletions(-)
>  rename drivers/{platform/x86/intel_pmc_ipc.c => mfd/intel_pmc_bxt.c} (50%)
>  rename arch/x86/include/asm/intel_pmc_ipc.h => include/linux/mfd/intel_pmc_bxt.h (83%)
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 59515142438e..04542feffe25 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -551,7 +551,7 @@ config INTEL_SOC_PMIC
>  
>  config INTEL_SOC_PMIC_BXTWC
>  	tristate "Support for Intel Broxton Whiskey Cove PMIC"
> -	depends on INTEL_PMC_IPC
> +	depends on MFD_INTEL_PMC_BXT
>  	select MFD_CORE
>  	select REGMAP_IRQ
>  	help
> @@ -632,6 +632,18 @@ config MFD_INTEL_MSIC
>  	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
>  	  devices used in Intel Medfield platforms.
>  
> +config MFD_INTEL_PMC_BXT
> +	tristate "Intel PMC Driver for Broxton"

> +	depends on X86 && X86_PLATFORM_DEVICES && ACPI

Is the X86_PLATFORM_DEVICES dependency compulsory?
Quick grep shows that none of drivers (except nouveau) relies on it.

For the rest two I think we might split one per line to be consistent with
existing example(s) in  drivers/mfd/Kconfig.

> +	select INTEL_SCU_IPC
> +	select MFD_CORE
> +	help
> +	  This driver provides support for PMC (Power Management
> +	  Controller) on Intel Broxton and Apollo Lake. PMC is a
> +	  multi-function device that exposes IPC, General Control
> +	  Register and P-unit access. In addition this creates devices
> +	  for iTCO watchdog and telemetry that are part of the PMC.
> +
>  config MFD_IPAQ_MICRO
>  	bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support"
>  	depends on SA1100_H3100 || SA1100_H3600
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index aed99f08739f..34563a6a047b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -211,6 +211,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS)	+= intel-lpss.o
>  obj-$(CONFIG_MFD_INTEL_LPSS_PCI)	+= intel-lpss-pci.o
>  obj-$(CONFIG_MFD_INTEL_LPSS_ACPI)	+= intel-lpss-acpi.o
>  obj-$(CONFIG_MFD_INTEL_MSIC)	+= intel_msic.o
> +obj-$(CONFIG_MFD_INTEL_PMC_BXT)	+= intel_pmc_bxt.o
>  obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
>  obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/mfd/intel_pmc_bxt.c
> similarity index 50%
> rename from drivers/platform/x86/intel_pmc_ipc.c
> rename to drivers/mfd/intel_pmc_bxt.c
> index 20a4bb72aeac..76f166c1455b 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/mfd/intel_pmc_bxt.c
> @@ -1,8 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - * Driver for the Intel PMC IPC mechanism
> + * Driver for the Intel Broxton PMC
>   *
> - * (C) Copyright 2014-2015 Intel Corporation
> + * (C) Copyright 2014-2015, 2020 Intel Corporation
>   *
>   * This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by
>   *     Sreedhara DS <sreedhara.ds@intel.com>
> @@ -16,10 +16,11 @@
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
>  #include <linux/io-64-nonatomic-lo-hi.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/intel_pmc_bxt.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  
> -#include <asm/intel_pmc_ipc.h>
>  #include <asm/intel_scu_ipc.h>
>  
>  #include <linux/platform_data/itco_wdt.h>
> @@ -62,8 +63,6 @@
>  #define TELEM_SSRAM_SIZE		240
>  #define TELEM_PMC_SSRAM_OFFSET		0x1B00
>  #define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
> -#define TCO_PMC_OFFSET			0x08
> -#define TCO_PMC_SIZE			0x04
>  
>  /* PMC register bit definitions */
>  
> @@ -72,40 +71,32 @@
>  #define PMC_CFG_NO_REBOOT_EN		(1 << 4)
>  #define PMC_CFG_NO_REBOOT_DIS		(0 << 4)
>  
> -static struct intel_pmc_ipc_dev {
> +static struct intel_pmc_dev {
>  	struct device *dev;
>  
> -	/* The following PMC BARs share the same ACPI device with the IPC */
> -	resource_size_t acpi_io_base;
> -	int acpi_io_size;
> -	struct platform_device *tco_dev;
> +	/* iTCO */
> +	struct resource tco_res[2];
>  
>  	/* gcr */
>  	void __iomem *gcr_mem_base;
> -	bool has_gcr_regs;
>  	spinlock_t gcr_lock;
>  
>  	/* punit */
> -	struct platform_device *punit_dev;
> +	struct resource punit_res[6];
>  	unsigned int punit_res_count;
>  
>  	/* Telemetry */
> -	resource_size_t telem_pmc_ssram_base;
> -	resource_size_t telem_punit_ssram_base;
> -	int telem_pmc_ssram_size;
> -	int telem_punit_ssram_size;
> -	u8 telem_res_inval;
> -	struct platform_device *telemetry_dev;
> -} ipcdev;
> +	struct resource *telem_base;
> +} pmcdev;
>  
>  static inline u64 gcr_data_readq(u32 offset)
>  {
> -	return readq(ipcdev.gcr_mem_base + offset);
> +	return readq(pmcdev.gcr_mem_base + offset);
>  }
>  
>  static inline int is_gcr_valid(u32 offset)
>  {
> -	if (!ipcdev.has_gcr_regs)
> +	if (!pmcdev.gcr_mem_base)
>  		return -EACCES;
>  
>  	if (offset > PLAT_RESOURCE_GCR_SIZE)
> @@ -127,17 +118,17 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data)
>  {
>  	int ret;
>  
> -	spin_lock(&ipcdev.gcr_lock);
> +	spin_lock(&pmcdev.gcr_lock);
>  
>  	ret = is_gcr_valid(offset);
>  	if (ret < 0) {
> -		spin_unlock(&ipcdev.gcr_lock);
> +		spin_unlock(&pmcdev.gcr_lock);
>  		return ret;
>  	}
>  
> -	*data = readq(ipcdev.gcr_mem_base + offset);
> +	*data = readq(pmcdev.gcr_mem_base + offset);
>  
> -	spin_unlock(&ipcdev.gcr_lock);
> +	spin_unlock(&pmcdev.gcr_lock);
>  
>  	return 0;
>  }
> @@ -159,29 +150,29 @@ static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
>  	u32 new_val;
>  	int ret = 0;
>  
> -	spin_lock(&ipcdev.gcr_lock);
> +	spin_lock(&pmcdev.gcr_lock);
>  
>  	ret = is_gcr_valid(offset);
>  	if (ret < 0)
> -		goto gcr_ipc_unlock;
> +		goto gcr_unlock;
>  
> -	new_val = readl(ipcdev.gcr_mem_base + offset);
> +	new_val = readl(pmcdev.gcr_mem_base + offset);
>  
>  	new_val &= ~mask;
>  	new_val |= val & mask;
>  
> -	writel(new_val, ipcdev.gcr_mem_base + offset);
> +	writel(new_val, pmcdev.gcr_mem_base + offset);
>  
> -	new_val = readl(ipcdev.gcr_mem_base + offset);
> +	new_val = readl(pmcdev.gcr_mem_base + offset);
>  
>  	/* check whether the bit update is successful */
>  	if ((new_val & mask) != (val & mask)) {
>  		ret = -EIO;
> -		goto gcr_ipc_unlock;
> +		goto gcr_unlock;
>  	}
>  
> -gcr_ipc_unlock:
> -	spin_unlock(&ipcdev.gcr_lock);
> +gcr_unlock:
> +	spin_unlock(&pmcdev.gcr_lock);
>  	return ret;
>  }
>  
> @@ -193,9 +184,9 @@ static int update_no_reboot_bit(void *priv, bool set)
>  				    PMC_CFG_NO_REBOOT_MASK, value);
>  }
>  
> -static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
> -					      struct device_attribute *attr,
> -					      const char *buf, size_t count)
> +static ssize_t intel_pmc_simple_cmd_store(struct device *dev,
> +					  struct device_attribute *attr,
> +					  const char *buf, size_t count)
>  {
>  	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
>  	int subcmd;
> @@ -215,11 +206,11 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
>  	}
>  	return (ssize_t)count;
>  }
> -static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store);
> +static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_simple_cmd_store);
>  
> -static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
> -					     struct device_attribute *attr,
> -					     const char *buf, size_t count)
> +static ssize_t intel_pmc_northpeak_store(struct device *dev,
> +					 struct device_attribute *attr,
> +					 const char *buf, size_t count)
>  {
>  	struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev);
>  	unsigned long val;
> @@ -241,264 +232,183 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
>  	}
>  	return (ssize_t)count;
>  }
> -static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store);
> +static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_northpeak_store);
>  
> -static struct attribute *intel_ipc_attrs[] = {
> +static struct attribute *intel_pmc_attrs[] = {
>  	&dev_attr_northpeak.attr,
>  	&dev_attr_simplecmd.attr,
>  	NULL
>  };
>  
> -static const struct attribute_group intel_ipc_group = {
> -	.attrs = intel_ipc_attrs,
> +static const struct attribute_group intel_pmc_group = {
> +	.attrs = intel_pmc_attrs,
>  };
>  
> -static struct resource punit_res_array[] = {
> -	/* Punit BIOS */
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	/* Punit ISP */
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	/* Punit GTD */
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -};
> -
> -#define TCO_RESOURCE_ACPI_IO		0
> -#define TCO_RESOURCE_SMI_EN_IO		1
> -#define TCO_RESOURCE_GCR_MEM		2
> -static struct resource tco_res[] = {
> -	/* ACPI - TCO */
> -	{
> -		.flags = IORESOURCE_IO,
> -	},
> -	/* ACPI - SMI */
> -	{
> -		.flags = IORESOURCE_IO,
> -	},
> -};
> -
> -static struct itco_wdt_platform_data tco_info = {
> -	.name = "Apollo Lake SoC",
> -	.version = 5,
> -	.no_reboot_priv = &ipcdev,
> -	.update_no_reboot_bit = update_no_reboot_bit,
> -};
> -
> -#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
> -#define TELEMETRY_RESOURCE_PMC_SSRAM	1
> -static struct resource telemetry_res[] = {
> -	/*Telemetry*/
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -	{
> -		.flags = IORESOURCE_MEM,
> -	},
> -};
> -
> -static int ipc_create_punit_device(void)
> +static int pmc_create_punit_device(void)
>  {
> -	struct platform_device *pdev;
> -	const struct platform_device_info pdevinfo = {
> -		.parent = ipcdev.dev,
> +	struct mfd_cell punit = {
>  		.name = PUNIT_DEVICE_NAME,
> -		.id = -1,
> -		.res = punit_res_array,
> -		.num_res = ipcdev.punit_res_count,
> -		};
> +		.resources = pmcdev.punit_res,
> +		.num_resources = pmcdev.punit_res_count,
> +	};
>  
> -	pdev = platform_device_register_full(&pdevinfo);
> -	if (IS_ERR(pdev))
> -		return PTR_ERR(pdev);
> +	if (!pmcdev.punit_res_count)
> +		return 0;
>  
> -	ipcdev.punit_dev = pdev;
> -
> -	return 0;
> +	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &punit, 1,
> +				    NULL, 0, NULL);
>  }
>  
> -static int ipc_create_tco_device(void)
> +static int pmc_create_tco_device(void)
>  {
> -	struct platform_device *pdev;
> -	struct resource *res;
> -	const struct platform_device_info pdevinfo = {
> -		.parent = ipcdev.dev,
> +	struct itco_wdt_platform_data tco_info = {
> +		.name = "Apollo Lake SoC",
> +		.version = 5,
> +		.no_reboot_priv = &pmcdev,
> +		.update_no_reboot_bit = update_no_reboot_bit,
> +	};
> +	struct mfd_cell tco = {
>  		.name = TCO_DEVICE_NAME,
> -		.id = -1,
> -		.res = tco_res,
> -		.num_res = ARRAY_SIZE(tco_res),
> -		.data = &tco_info,
> -		.size_data = sizeof(tco_info),
> -		};
> -
> -	res = tco_res + TCO_RESOURCE_ACPI_IO;
> -	res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET;
> -	res->end = res->start + TCO_REGS_SIZE - 1;
> -
> -	res = tco_res + TCO_RESOURCE_SMI_EN_IO;
> -	res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
> -	res->end = res->start + SMI_EN_SIZE - 1;
> -
> -	pdev = platform_device_register_full(&pdevinfo);
> -	if (IS_ERR(pdev))
> -		return PTR_ERR(pdev);
> -
> -	ipcdev.tco_dev = pdev;
> -
> -	return 0;
> +		.ignore_resource_conflicts = true,
> +		.platform_data = &tco_info,
> +		.pdata_size = sizeof(tco_info),
> +		.resources = pmcdev.tco_res,
> +		.num_resources = ARRAY_SIZE(pmcdev.tco_res),
> +	};
> +
> +	if (!pmcdev.tco_res[0].start)
> +		return 0;
> +
> +	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &tco, 1,
> +				    NULL, 0, NULL);
>  }
>  
> -static int ipc_create_telemetry_device(void)
> +static int pmc_create_telemetry_device(void)
>  {
> -	struct platform_device *pdev;
> -	struct resource *res;
> -	const struct platform_device_info pdevinfo = {
> -		.parent = ipcdev.dev,
> +	struct resource telem_res[] = {
> +		DEFINE_RES_MEM(TELEM_PUNIT_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
> +		DEFINE_RES_MEM(TELEM_PMC_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
> +	};
> +	struct mfd_cell telem  = {
>  		.name = TELEMETRY_DEVICE_NAME,
> -		.id = -1,
> -		.res = telemetry_res,
> -		.num_res = ARRAY_SIZE(telemetry_res),
> -		};
> -
> -	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
> -	res->start = ipcdev.telem_punit_ssram_base;
> -	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
> +		.resources = telem_res,
> +		.num_resources = ARRAY_SIZE(telem_res),
> +	};
>  
> -	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
> -	res->start = ipcdev.telem_pmc_ssram_base;
> -	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
> +	if (!pmcdev.telem_base)
> +		return 0;
>  
> -	pdev = platform_device_register_full(&pdevinfo);
> -	if (IS_ERR(pdev))
> -		return PTR_ERR(pdev);
> -
> -	ipcdev.telemetry_dev = pdev;
> -
> -	return 0;
> +	return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &telem, 1,
> +				    pmcdev.telem_base, 0, NULL);
>  }
>  
> -static int ipc_create_pmc_devices(void)
> +static int pmc_create_devices(void)
>  {
>  	int ret;
>  
>  	/* If we have ACPI based watchdog use that instead */
>  	if (!acpi_has_watchdog()) {
> -		ret = ipc_create_tco_device();
> +		ret = pmc_create_tco_device();
>  		if (ret) {
> -			dev_err(ipcdev.dev, "Failed to add tco platform device\n");
> +			dev_err(pmcdev.dev, "Failed to add tco platform device\n");
>  			return ret;
>  		}
>  	}
>  
> -	ret = ipc_create_punit_device();
> +	ret = pmc_create_punit_device();
>  	if (ret) {
> -		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
> -		platform_device_unregister(ipcdev.tco_dev);
> +		dev_err(pmcdev.dev, "Failed to add punit platform device\n");
>  		return ret;
>  	}
>  
> -	if (!ipcdev.telem_res_inval) {
> -		ret = ipc_create_telemetry_device();
> -		if (ret) {
> -			dev_warn(ipcdev.dev,
> -				"Failed to add telemetry platform device\n");
> -			platform_device_unregister(ipcdev.punit_dev);
> -			platform_device_unregister(ipcdev.tco_dev);
> -		}
> -	}
> +	ret = pmc_create_telemetry_device();
> +	if (ret)
> +		dev_warn(pmcdev.dev, "Failed to add telemetry platform device\n");
>  
>  	return ret;
>  }
>  
> -static int ipc_plat_get_res(struct platform_device *pdev,
> +static int pmc_plat_get_res(struct platform_device *pdev,
>  			    struct intel_scu_ipc_pdata *pdata)
>  {
> -	struct resource *res, *punit_res = punit_res_array;
> +	struct resource *res, *punit_res = pmcdev.punit_res;
> +	struct resource *tco_res = pmcdev.tco_res;
>  	void __iomem *addr;
>  	int size;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_IO,
>  				    PLAT_RESOURCE_ACPI_IO_INDEX);
>  	if (!res) {
> -		dev_err(&pdev->dev, "Failed to get io resource\n");
> +		dev_err(&pdev->dev, "Failed to get IO resource\n");
>  		return -ENXIO;
> +
>  	}
> -	size = resource_size(res);
> -	ipcdev.acpi_io_base = res->start;
> -	ipcdev.acpi_io_size = size;
> -	dev_info(&pdev->dev, "io res: %pR\n", res);
> +	tco_res[0].flags = IORESOURCE_IO;
> +	tco_res[0].start = res->start + TCO_BASE_OFFSET;
> +	tco_res[0].end = tco_res[0].start + TCO_REGS_SIZE - 1;
> +	tco_res[1].flags = IORESOURCE_IO;
> +	tco_res[1].start = res->start + SMI_EN_OFFSET;
> +	tco_res[1].end = tco_res[1].start + SMI_EN_SIZE - 1;
> +	dev_dbg(&pdev->dev, "IO: %pR\n", res);
>  
> -	ipcdev.punit_res_count = 0;
> +	pmcdev.punit_res_count = 0;
>  
>  	/* This is index 0 to cover BIOS data register */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_BIOS_DATA_INDEX);
>  	if (!res) {
> -		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
> +		dev_err(&pdev->dev, "Failed to get res of P-unit BIOS data\n");
>  		return -ENXIO;
>  	}
> -	punit_res[ipcdev.punit_res_count++] = *res;
> -	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
> +	punit_res[pmcdev.punit_res_count++] = *res;
> +	dev_dbg(&pdev->dev, "P-unit BIOS data: %pR\n", res);
>  
>  	/* This is index 1 to cover BIOS interface register */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
>  	if (!res) {
> -		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
> +		dev_err(&pdev->dev, "Failed to get res of P-unit BIOS iface\n");
>  		return -ENXIO;
>  	}
> -	punit_res[ipcdev.punit_res_count++] = *res;
> -	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
> +	punit_res[pmcdev.punit_res_count++] = *res;
> +	dev_dbg(&pdev->dev, "P-unit BIOS interface: %pR\n", res);
>  
>  	/* This is index 2 to cover ISP data register, optional */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_ISP_DATA_INDEX);
>  	if (res) {
> -		punit_res[ipcdev.punit_res_count++] = *res;
> -		dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
> +		punit_res[pmcdev.punit_res_count++] = *res;
> +		dev_dbg(&pdev->dev, "P-unit ISP data: %pR\n", res);
>  	}
>  
>  	/* This is index 3 to cover ISP interface register, optional */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_ISP_IFACE_INDEX);
>  	if (res) {
> -		punit_res[ipcdev.punit_res_count++] = *res;
> -		dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
> +		punit_res[pmcdev.punit_res_count++] = *res;
> +		dev_dbg(&pdev->dev, "P-unit ISP interface: %pR\n", res);
>  	}
>  
>  	/* This is index 4 to cover GTD data register, optional */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_GTD_DATA_INDEX);
>  	if (res) {
> -		punit_res[ipcdev.punit_res_count++] = *res;
> -		dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
> +		punit_res[pmcdev.punit_res_count++] = *res;
> +		dev_dbg(&pdev->dev, "P-unit GTD data: %pR\n", res);
>  	}
>  
>  	/* This is index 5 to cover GTD interface register, optional */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_GTD_IFACE_INDEX);
>  	if (res) {
> -		punit_res[ipcdev.punit_res_count++] = *res;
> -		dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
> +		punit_res[pmcdev.punit_res_count++] = *res;
> +		dev_dbg(&pdev->dev, "P-unit GTD interface: %pR\n", res);
>  	}
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_IPC_INDEX);
>  	if (!res) {
> -		dev_err(&pdev->dev, "Failed to get ipc resource\n");
> +		dev_err(&pdev->dev, "Failed to get IPC resource\n");
>  		return -ENXIO;
>  	}
>  	size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE;
> @@ -510,23 +420,16 @@ static int ipc_plat_get_res(struct platform_device *pdev,
>  
>  	pdata->ipc_regs = addr;
>  
> -	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
> -	dev_info(&pdev->dev, "ipc res: %pR\n", res);
> +	pmcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
> +	dev_dbg(&pdev->dev, "IPC: %pR\n", res);
>  
> -	ipcdev.telem_res_inval = 0;
>  	res = platform_get_resource(pdev, IORESOURCE_MEM,
>  				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
>  	if (!res) {
> -		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
> -		ipcdev.telem_res_inval = 1;
> +		dev_err(&pdev->dev, "Failed to get telemetry SSRAM resource\n");
>  	} else {
> -		ipcdev.telem_punit_ssram_base = res->start +
> -						TELEM_PUNIT_SSRAM_OFFSET;
> -		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
> -		ipcdev.telem_pmc_ssram_base = res->start +
> -						TELEM_PMC_SSRAM_OFFSET;
> -		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
> -		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
> +		dev_dbg(&pdev->dev, "Telemetry SSRAM: %pR\n", res);
> +		pmcdev.telem_base = res;
>  	}
>  
>  	return 0;
> @@ -542,7 +445,7 @@ int intel_pmc_s0ix_counter_read(u64 *data)
>  {
>  	u64 deep, shlw;
>  
> -	if (!ipcdev.has_gcr_regs)
> +	if (!pmcdev.gcr_mem_base)
>  		return -EACCES;
>  
>  	deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG);
> @@ -554,15 +457,13 @@ int intel_pmc_s0ix_counter_read(u64 *data)
>  }
>  EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read);
>  
> -#ifdef CONFIG_ACPI
> -static const struct acpi_device_id ipc_acpi_ids[] = {
> +static const struct acpi_device_id intel_pmc_acpi_ids[] = {
>  	{ "INT34D2", 0},
>  	{ }
>  };
> -MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
> -#endif
> +MODULE_DEVICE_TABLE(acpi, intel_pmc_acpi_ids);
>  
> -static int ipc_plat_probe(struct platform_device *pdev)
> +static int intel_pmc_probe(struct platform_device *pdev)
>  {
>  	struct intel_scu_ipc_pdata pdata;
>  	struct intel_scu_ipc_dev *scu;
> @@ -573,10 +474,10 @@ static int ipc_plat_probe(struct platform_device *pdev)
>  	if (pdata.irq < 0)
>  		return -EINVAL;
>  
> -	ipcdev.dev = &pdev->dev;
> -	spin_lock_init(&ipcdev.gcr_lock);
> +	pmcdev.dev = &pdev->dev;
> +	spin_lock_init(&pmcdev.gcr_lock);
>  
> -	ret = ipc_plat_get_res(pdev, &pdata);
> +	ret = pmc_plat_get_res(pdev, &pdata);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to request resource\n");
>  		return ret;
> @@ -588,67 +489,58 @@ static int ipc_plat_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, scu);
>  
> -	ret = ipc_create_pmc_devices();
> +	ret = pmc_create_devices();
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to create pmc devices\n");
>  		goto err_ipc;
>  	}
>  
> -	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
> +	ret = sysfs_create_group(&pdev->dev.kobj, &intel_pmc_group);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
>  			ret);
> -		goto err_devs;
> +		goto err_ipc;
>  	}
>  
> -	ipcdev.has_gcr_regs = true;
> -
>  	return 0;
>  
>  err_ipc:
>  	intel_scu_ipc_remove(scu);
> -err_devs:
> -	platform_device_unregister(ipcdev.tco_dev);
> -	platform_device_unregister(ipcdev.punit_dev);
> -	platform_device_unregister(ipcdev.telemetry_dev);
>  
>  	return ret;
>  }
>  
> -static int ipc_plat_remove(struct platform_device *pdev)
> +static int intel_pmc_remove(struct platform_device *pdev)
>  {
> -	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
> -	platform_device_unregister(ipcdev.tco_dev);
> -	platform_device_unregister(ipcdev.punit_dev);
> -	platform_device_unregister(ipcdev.telemetry_dev);
> +	sysfs_remove_group(&pdev->dev.kobj, &intel_pmc_group);
>  	intel_scu_ipc_remove(platform_get_drvdata(pdev));
> -	ipcdev.dev = NULL;
> +	pmcdev.dev = NULL;
>  	return 0;
>  }
>  
> -static struct platform_driver ipc_plat_driver = {
> -	.remove = ipc_plat_remove,
> -	.probe = ipc_plat_probe,
> +static struct platform_driver intel_pmc_driver = {
> +	.remove = intel_pmc_remove,
> +	.probe = intel_pmc_probe,
>  	.driver = {
> -		.name = "pmc-ipc-plat",
> -		.acpi_match_table = ACPI_PTR(ipc_acpi_ids),
> +		.name = "intel_pmc_bxt",
> +		.acpi_match_table = ACPI_PTR(intel_pmc_acpi_ids),
>  	},
>  };
>  
> -static int __init intel_pmc_ipc_init(void)
> +static int __init intel_pmc_init(void)
>  {
> -	return platform_driver_register(&ipc_plat_driver);
> +	return platform_driver_register(&intel_pmc_driver);
>  }
>  
> -static void __exit intel_pmc_ipc_exit(void)
> +static void __exit intel_pmc_exit(void)
>  {
> -	platform_driver_unregister(&ipc_plat_driver);
> +	platform_driver_unregister(&intel_pmc_driver);
>  }
>  
>  MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
> -MODULE_DESCRIPTION("Intel PMC IPC driver");
> +MODULE_DESCRIPTION("Intel Broxton PMC driver");
>  MODULE_LICENSE("GPL v2");
>  
>  /* Some modules are dependent on this, so init earlier */
> -fs_initcall(intel_pmc_ipc_init);
> -module_exit(intel_pmc_ipc_exit);
> +fs_initcall(intel_pmc_init);
> +module_exit(intel_pmc_exit);
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 1c5afb9e4965..e01aba797656 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1195,19 +1195,11 @@ config INTEL_SMARTCONNECT
>  	  This driver checks to determine whether the device has Intel Smart
>  	  Connect enabled, and if so disables it.
>  
> -config INTEL_PMC_IPC
> -	tristate "Intel PMC IPC Driver"
> -	depends on ACPI
> -	select INTEL_SCU_IPC
> -	---help---
> -	This driver provides support for PMC control on some Intel platforms.
> -	The PMC is an ARC processor which defines IPC commands for communication
> -	with other entities in the CPU.
> -
>  config INTEL_BXTWC_PMIC_TMU
>  	tristate "Intel BXT Whiskey Cove TMU Driver"
>  	depends on REGMAP
> -	depends on INTEL_SOC_PMIC_BXTWC && INTEL_PMC_IPC
> +	depends on MFD_INTEL_PMC_BXT
> +	depends on INTEL_SOC_PMIC_BXTWC
>  	---help---
>  	  Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
>  	  This driver enables the alarm wakeup functionality in the TMU unit
> @@ -1233,7 +1225,9 @@ config INTEL_PUNIT_IPC
>  
>  config INTEL_TELEMETRY
>  	tristate "Intel SoC Telemetry Driver"
> -	depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
> +	depends on X86_64
> +	depends on MFD_INTEL_PMC_BXT
> +	depends on INTEL_PUNIT_IPC
>  	---help---
>  	  This driver provides interfaces to configure and use
>  	  telemetry for INTEL SoC from APL onwards. It is also
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index c7a42feaa521..f1abce3e1720 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -86,7 +86,6 @@ obj-$(CONFIG_INTEL_RST)		+= intel-rst.o
>  obj-$(CONFIG_INTEL_SMARTCONNECT)	+= intel-smartconnect.o
>  
>  obj-$(CONFIG_ALIENWARE_WMI)	+= alienware-wmi.o
> -obj-$(CONFIG_INTEL_PMC_IPC)	+= intel_pmc_ipc.o
>  obj-$(CONFIG_TOUCHSCREEN_DMI)	+= touchscreen_dmi.o
>  obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
>  obj-$(CONFIG_SURFACE_3_BUTTON)	+= surface3_button.o
> diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c
> index e84d3e983e0c..7b7a766a6cb8 100644
> --- a/drivers/platform/x86/intel_telemetry_debugfs.c
> +++ b/drivers/platform/x86/intel_telemetry_debugfs.c
> @@ -16,13 +16,13 @@
>  #include <linux/debugfs.h>
>  #include <linux/device.h>
>  #include <linux/module.h>
> +#include <linux/mfd/intel_pmc_bxt.h>
>  #include <linux/pci.h>
>  #include <linux/seq_file.h>
>  #include <linux/suspend.h>
>  
>  #include <asm/cpu_device_id.h>
>  #include <asm/intel-family.h>
> -#include <asm/intel_pmc_ipc.h>
>  #include <asm/intel_telemetry.h>
>  
>  #define DRIVER_NAME			"telemetry_soc_debugfs"
> diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
> index 5b986d6c801d..fa3f39336246 100644
> --- a/drivers/usb/typec/tcpm/Kconfig
> +++ b/drivers/usb/typec/tcpm/Kconfig
> @@ -41,8 +41,8 @@ config TYPEC_FUSB302
>  config TYPEC_WCOVE
>  	tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
>  	depends on ACPI
> +	depends on MFD_INTEL_PMC_BXT
>  	depends on INTEL_SOC_PMIC
> -	depends on INTEL_PMC_IPC
>  	depends on BXT_WC_PMIC_OPREGION
>  	help
>  	  This driver adds support for USB Type-C on Intel Broxton platforms
> diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/include/linux/mfd/intel_pmc_bxt.h
> similarity index 83%
> rename from arch/x86/include/asm/intel_pmc_ipc.h
> rename to include/linux/mfd/intel_pmc_bxt.h
> index 22848df5faaf..f03a80df0728 100644
> --- a/arch/x86/include/asm/intel_pmc_ipc.h
> +++ b/include/linux/mfd/intel_pmc_bxt.h
> @@ -1,6 +1,9 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _ASM_X86_INTEL_PMC_IPC_H_
> -#define  _ASM_X86_INTEL_PMC_IPC_H_
> +#ifndef MFD_INTEL_PMC_BXT_H
> +#define MFD_INTEL_PMC_BXT_H
> +
> +#include <linux/errno.h>
> +#include <linux/types.h>
>  
>  /* Commands */
>  #define PMC_IPC_USB_PWR_CTRL		0xF0
> @@ -25,7 +28,7 @@
>  #define PMC_GCR_TELEM_DEEP_S0IX_REG	0x78
>  #define PMC_GCR_TELEM_SHLW_S0IX_REG	0x80
>  
> -#if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
> +#if IS_ENABLED(CONFIG_MFD_INTEL_PMC_BXT)
>  
>  int intel_pmc_s0ix_counter_read(u64 *data);
>  int intel_pmc_gcr_read64(u32 offset, u64 *data);
> @@ -42,6 +45,6 @@ static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
>  	return -EINVAL;
>  }
>  
> -#endif /*CONFIG_INTEL_PMC_IPC*/
> +#endif /* CONFIG_MFD_INTEL_PMC_BXT */
>  
>  #endif
> -- 
> 2.24.1
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD
  2020-01-09 11:43   ` Andy Shevchenko
@ 2020-01-09 11:47     ` Mika Westerberg
  2020-01-09 12:57       ` Mika Westerberg
  0 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-09 11:47 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Thu, Jan 09, 2020 at 01:43:54PM +0200, Andy Shevchenko wrote:
> On Wed, Jan 08, 2020 at 02:41:59PM +0300, Mika Westerberg wrote:
> > This driver only creates a bunch of platform devices sharing resources
> > belonging to the PMC device. This is pretty much what MFD subsystem is
> > for so move the driver there, renaming it to intel_pmc_bxt.c which
> > should be more clear what it is.
> > 
> > MFD subsystem provides nice helper APIs for subdevice creation so
> > convert the driver to use those. Unfortunately the ACPI device includes
> > separate resources for most of the subdevices so we cannot simply call
> > mfd_add_devices() to create all of them but instead we need to call it
> > separately for each device.
> 
> Comments below, after addressing,
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Thanks!

> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  drivers/mfd/Kconfig                           |  14 +-
> >  drivers/mfd/Makefile                          |   1 +
> >  .../intel_pmc_ipc.c => mfd/intel_pmc_bxt.c}   | 394 +++++++-----------
> >  drivers/platform/x86/Kconfig                  |  16 +-
> >  drivers/platform/x86/Makefile                 |   1 -
> >  .../platform/x86/intel_telemetry_debugfs.c    |   2 +-
> >  drivers/usb/typec/tcpm/Kconfig                |   2 +-
> >  .../linux/mfd/intel_pmc_bxt.h                 |  11 +-
> >  8 files changed, 171 insertions(+), 270 deletions(-)
> >  rename drivers/{platform/x86/intel_pmc_ipc.c => mfd/intel_pmc_bxt.c} (50%)
> >  rename arch/x86/include/asm/intel_pmc_ipc.h => include/linux/mfd/intel_pmc_bxt.h (83%)
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 59515142438e..04542feffe25 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -551,7 +551,7 @@ config INTEL_SOC_PMIC
> >  
> >  config INTEL_SOC_PMIC_BXTWC
> >  	tristate "Support for Intel Broxton Whiskey Cove PMIC"
> > -	depends on INTEL_PMC_IPC
> > +	depends on MFD_INTEL_PMC_BXT
> >  	select MFD_CORE
> >  	select REGMAP_IRQ
> >  	help
> > @@ -632,6 +632,18 @@ config MFD_INTEL_MSIC
> >  	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
> >  	  devices used in Intel Medfield platforms.
> >  
> > +config MFD_INTEL_PMC_BXT
> > +	tristate "Intel PMC Driver for Broxton"
> 
> > +	depends on X86 && X86_PLATFORM_DEVICES && ACPI
> 
> Is the X86_PLATFORM_DEVICES dependency compulsory?
> Quick grep shows that none of drivers (except nouveau) relies on it.

Well, we need that to be able to do the "select INTEL_SCU_IPC" below.
I'm happy to change it if you have a better alternative ;-)

> For the rest two I think we might split one per line to be consistent with
> existing example(s) in  drivers/mfd/Kconfig.

OK

> 
> > +	select INTEL_SCU_IPC
> > +	select MFD_CORE
> > +	help
> > +	  This driver provides support for PMC (Power Management
> > +	  Controller) on Intel Broxton and Apollo Lake. PMC is a
> > +	  multi-function device that exposes IPC, General Control
> > +	  Register and P-unit access. In addition this creates devices
> > +	  for iTCO watchdog and telemetry that are part of the PMC.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD
  2020-01-09 11:47     ` Mika Westerberg
@ 2020-01-09 12:57       ` Mika Westerberg
  2020-01-09 14:25         ` Andy Shevchenko
  0 siblings, 1 reply; 81+ messages in thread
From: Mika Westerberg @ 2020-01-09 12:57 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Thu, Jan 09, 2020 at 01:47:59PM +0200, Mika Westerberg wrote:
> > >  config INTEL_SOC_PMIC_BXTWC
> > >  	tristate "Support for Intel Broxton Whiskey Cove PMIC"
> > > -	depends on INTEL_PMC_IPC
> > > +	depends on MFD_INTEL_PMC_BXT
> > >  	select MFD_CORE
> > >  	select REGMAP_IRQ
> > >  	help
> > > @@ -632,6 +632,18 @@ config MFD_INTEL_MSIC
> > >  	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
> > >  	  devices used in Intel Medfield platforms.
> > >  
> > > +config MFD_INTEL_PMC_BXT
> > > +	tristate "Intel PMC Driver for Broxton"
> > 
> > > +	depends on X86 && X86_PLATFORM_DEVICES && ACPI
> > 
> > Is the X86_PLATFORM_DEVICES dependency compulsory?
> > Quick grep shows that none of drivers (except nouveau) relies on it.
> 
> Well, we need that to be able to do the "select INTEL_SCU_IPC" below.
> I'm happy to change it if you have a better alternative ;-)

Just to provide more information. If I don't have that dependency I get
warnings like this:

WARNING: unmet direct dependencies detected for INTEL_SCU_IPC
  Depends on [n]: X86 [=y] && X86_PLATFORM_DEVICES [=n]
    Selected by [y]:
      - MFD_INTEL_PMC_BXT [=y] && HAS_IOMEM [=y] && X86 [=y] && ACPI [=y]

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD
  2020-01-09 12:57       ` Mika Westerberg
@ 2020-01-09 14:25         ` Andy Shevchenko
  0 siblings, 0 replies; 81+ messages in thread
From: Andy Shevchenko @ 2020-01-09 14:25 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Darren Hart, Lee Jones, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Thu, Jan 09, 2020 at 02:57:27PM +0200, Mika Westerberg wrote:
> On Thu, Jan 09, 2020 at 01:47:59PM +0200, Mika Westerberg wrote:
> > > >  config INTEL_SOC_PMIC_BXTWC
> > > >  	tristate "Support for Intel Broxton Whiskey Cove PMIC"
> > > > -	depends on INTEL_PMC_IPC
> > > > +	depends on MFD_INTEL_PMC_BXT
> > > >  	select MFD_CORE
> > > >  	select REGMAP_IRQ
> > > >  	help
> > > > @@ -632,6 +632,18 @@ config MFD_INTEL_MSIC
> > > >  	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
> > > >  	  devices used in Intel Medfield platforms.
> > > >  
> > > > +config MFD_INTEL_PMC_BXT
> > > > +	tristate "Intel PMC Driver for Broxton"
> > > 
> > > > +	depends on X86 && X86_PLATFORM_DEVICES && ACPI
> > > 
> > > Is the X86_PLATFORM_DEVICES dependency compulsory?
> > > Quick grep shows that none of drivers (except nouveau) relies on it.
> > 
> > Well, we need that to be able to do the "select INTEL_SCU_IPC" below.
> > I'm happy to change it if you have a better alternative ;-)
> 
> Just to provide more information. If I don't have that dependency I get
> warnings like this:
> 
> WARNING: unmet direct dependencies detected for INTEL_SCU_IPC
>   Depends on [n]: X86 [=y] && X86_PLATFORM_DEVICES [=n]
>     Selected by [y]:
>       - MFD_INTEL_PMC_BXT [=y] && HAS_IOMEM [=y] && X86 [=y] && ACPI [=y]

I see, thanks for elaboration.
Please, just split them one per line.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers
  2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
                   ` (36 preceding siblings ...)
  2020-01-08 17:34 ` [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Andy Shevchenko
@ 2020-01-13 10:38 ` Lee Jones
  37 siblings, 0 replies; 81+ messages in thread
From: Lee Jones @ 2020-01-13 10:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Shevchenko, Darren Hart, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, x86, Zha Qipeng,
	Rajneesh Bhardwaj, David E . Box, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman, Wim Van Sebroeck, platform-driver-x86,
	linux-kernel

On Wed, 08 Jan 2020, Mika Westerberg wrote:

> Hi,
> 
> Currently both intel_scu_ipc.c and intel_pmc_ipc.c implement the same SCU
> IPC communications with minor differences. This duplication does not make
> much sense so this series reworks the two drivers so that there is only a
> single implementation of the SCU IPC. In addition to that the API will be
> updated to take SCU instance pointer as an argument, and most of the
> callers will be converted to this new API. The old API is left there but
> the plan is to get rid the callers and then the old API as well (this is
> something we are working with Andy Shevchenko).
> 
> The intel_pmc_ipc.c is then moved under MFD which suits better for this
> kind of a driver that pretty much sets up the SCU IPC and then creates a
> bunch of platform devices for the things sitting behind the PMC. The driver
> is renamed to intel_pmc_bxt.c which should follow the existing conventions
> under drivers/mfd (and it is only meant for Intel Broxton derivatives).
> 
> Previous version of the series:
> 
>   https://www.spinics.net/lists/platform-driver-x86/msg20359.html
> 
> Changes from the previous version:
> 
>   * Update changelog of patch 16 according to what the patch actually does.
>   * Add kernel-doc for struct intel_soc_pmic.
>   * Move octal permission patch to be before MFD conversion.
>   * Convert the intel_pmc_bxt.c to MFD APIs whilst it is being moved under
>     drivers/mfd.
> 
> I'm including all x86 maintainers just to be sure they are aware of this as
> I'm not sure if x86@kernel.org reaches them all. Let me know if you have
> issues with this series.
> 
> I would prefer this to be merged through platform/x86 or MFD trees assuming
> there are no objections.
> 
> I have tested this on Intel Edison (Merrifield) and Joule (Broxton-M).

FYI, I'm waiting until v3 before I conduct my review.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 81+ messages in thread

end of thread, other threads:[~2020-01-13 10:37 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-08 11:41 [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
2020-01-08 11:41 ` [PATCH v2 01/36] platform/x86: intel_mid_powerbtn: Take a copy of ddata Mika Westerberg
2020-01-08 16:37   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 02/36] platform/x86: intel_scu_ipcutil: Remove default y from Kconfig Mika Westerberg
2020-01-08 16:38   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 03/36] platform/x86: intel_scu_ipc: Add constants for register offsets Mika Westerberg
2020-01-08 16:39   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 04/36] platform/x86: intel_scu_ipc: Remove Lincroft support Mika Westerberg
2020-01-08 16:39   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 05/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl() Mika Westerberg
2020-01-08 16:39   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 06/36] platform/x86: intel_scu_ipc: Fix interrupt support Mika Westerberg
2020-01-08 16:40   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 07/36] platform/x86: intel_scu_ipc: Sleeping is fine when polling Mika Westerberg
2020-01-08 17:12   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 08/36] platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update() Mika Westerberg
2020-01-08 16:41   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 09/36] platform/x86: intel_scu_ipc: Drop unused macros Mika Westerberg
2020-01-08 16:41   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 10/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]() Mika Westerberg
2020-01-08 16:41   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 11/36] platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command() Mika Westerberg
2020-01-08 16:42   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 12/36] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver Mika Westerberg
2020-01-08 17:22   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 13/36] platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions Mika Westerberg
2020-01-08 16:42   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 14/36] platform/x86: intel_scu_ipc: Introduce new SCU IPC API Mika Westerberg
2020-01-09 11:30   ` Andy Shevchenko
2020-01-09 11:39     ` Mika Westerberg
2020-01-08 11:41 ` [PATCH v2 15/36] platform/x86: intel_mid_powerbtn: Convert to use " Mika Westerberg
2020-01-08 16:43   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 16/36] watchdog: intel-mid_wdt: " Mika Westerberg
2020-01-08 15:37   ` Guenter Roeck
2020-01-08 17:38   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 17/36] platform/x86: intel_scu_ipcutil: " Mika Westerberg
2020-01-08 16:45   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 18/36] platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static Mika Westerberg
2020-01-08 16:46   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 19/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static Mika Westerberg
2020-01-08 16:46   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 20/36] platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static Mika Westerberg
2020-01-08 16:46   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 21/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write() Mika Westerberg
2020-01-08 16:47   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 22/36] platform/x86: intel_pmc_ipc: Drop ipc_data_readb() Mika Westerberg
2020-01-08 16:47   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 23/36] platform/x86: intel_pmc_ipc: Get rid of unnecessary includes Mika Westerberg
2020-01-08 16:47   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 24/36] platform/x86: intel_scu_ipc: Add function to remove SCU IPC Mika Westerberg
2020-01-08 17:28   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 25/36] platform/x86: intel_pmc_ipc: Start using " Mika Westerberg
2020-01-08 16:52   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 26/36] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic Mika Westerberg
2020-01-08 17:31   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 27/36] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API Mika Westerberg
2020-01-08 17:32   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 28/36] mfd: intel_soc_pmic_mrfld: " Mika Westerberg
2020-01-08 17:35   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 29/36] platform/x86: intel_telemetry: " Mika Westerberg
2020-01-08 16:54   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 30/36] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command() Mika Westerberg
2020-01-08 16:57   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 31/36] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]() Mika Westerberg
2020-01-08 17:36   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 32/36] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c Mika Westerberg
2020-01-08 17:03   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 33/36] platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes Mika Westerberg
2020-01-08 16:58   ` Andy Shevchenko
2020-01-08 11:41 ` [PATCH v2 34/36] platform/x86: intel_pmc_ipc: Convert to MFD Mika Westerberg
2020-01-09 11:43   ` Andy Shevchenko
2020-01-09 11:47     ` Mika Westerberg
2020-01-09 12:57       ` Mika Westerberg
2020-01-09 14:25         ` Andy Shevchenko
2020-01-08 11:42 ` [PATCH v2 35/36] mfd: intel_pmc_bxt: Switch to use driver->dev_groups Mika Westerberg
2020-01-08 17:30   ` Andy Shevchenko
2020-01-08 11:42 ` [PATCH v2 36/36] MAINTAINERS: Update entry for Intel Broxton PMC driver Mika Westerberg
2020-01-08 17:06   ` Andy Shevchenko
2020-01-08 17:34 ` [PATCH v2 00/36] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Andy Shevchenko
2020-01-09  6:13   ` Mika Westerberg
2020-01-13 10:38 ` Lee Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.