public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups
@ 2024-10-16 11:48 Andy Shevchenko
  2024-10-16 11:48 ` [PATCH v1 1/3] platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO Andy Shevchenko
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Andy Shevchenko @ 2024-10-16 11:48 UTC (permalink / raw)
  To: Andy Shevchenko, linux-kernel, platform-driver-x86
  Cc: Mika Westerberg, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

The first patch avoids using a workaround for IO (which seems unneeded).
The rest is a batch of cleanups. Cc'ed to Ferry in hope of testing on
Intel Merrifield (the main platform that uses these APIs).

Andy Shevchenko (3):
  platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO
  platform/x86: intel_scu_ipc: Simplify code with cleanup helpers
  platform/x86: intel_scu_ipc: Save a copy of the entire struct
    intel_scu_ipc_data

 drivers/platform/x86/intel_scu_ipc.c | 142 ++++++++++++---------------
 1 file changed, 61 insertions(+), 81 deletions(-)

-- 
2.43.0.rc1.1336.g36b5255a03ac


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

* [PATCH v1 1/3] platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO
  2024-10-16 11:48 [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Andy Shevchenko
@ 2024-10-16 11:48 ` Andy Shevchenko
  2024-10-16 11:48 ` [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers Andy Shevchenko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2024-10-16 11:48 UTC (permalink / raw)
  To: Andy Shevchenko, linux-kernel, platform-driver-x86
  Cc: Mika Westerberg, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

The theory is that the so called workaround in pwr_reg_rdwr() is
the actual reader of the data in 32-bit chunks. For some reason
the 8-bit IO won't fail after that. Replace the workaround by using
32-bit IO explicitly and then memcpy() as much data as was requested
by the user. The same approach is already in use in
intel_scu_ipc_dev_command_with_size().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 5b16d29c93d7..290b38627542 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -217,12 +217,6 @@ static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu)
 	return __raw_readl(scu->ipc_base + IPC_STATUS);
 }
 
-/* Read ipc byte data */
-static inline u8 ipc_data_readb(struct intel_scu_ipc_dev *scu, u32 offset)
-{
-	return readb(scu->ipc_base + IPC_READ_BUFFER + offset);
-}
-
 /* Read ipc u32 data */
 static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
 {
@@ -325,11 +319,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
 	}
 
 	err = intel_scu_ipc_check_status(scu);
-	if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
-		/* Workaround: values are read as 0 without memcpy_fromio */
-		memcpy_fromio(cbuf, scu->ipc_base + 0x90, 16);
-		for (nc = 0; nc < count; nc++)
-			data[nc] = ipc_data_readb(scu, nc);
+	if (!err) { /* Read rbuf */
+		for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
+			wbuf[nc] = ipc_data_readl(scu, offset);
+		memcpy(data, wbuf, count);
 	}
 	mutex_unlock(&ipclock);
 	return err;
-- 
2.43.0.rc1.1336.g36b5255a03ac


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

* [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers
  2024-10-16 11:48 [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Andy Shevchenko
  2024-10-16 11:48 ` [PATCH v1 1/3] platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO Andy Shevchenko
@ 2024-10-16 11:48 ` Andy Shevchenko
  2024-10-21  7:00   ` Mika Westerberg
  2024-10-16 11:48 ` [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data Andy Shevchenko
  2024-10-17 21:10 ` [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Ferry Toth
  3 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2024-10-16 11:48 UTC (permalink / raw)
  To: Andy Shevchenko, linux-kernel, platform-driver-x86
  Cc: Mika Westerberg, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

Use macros defined in linux/cleanup.h to automate resource lifetime
control in the driver.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 102 ++++++++++++---------------
 1 file changed, 44 insertions(+), 58 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 290b38627542..ffb0a2524388 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -13,6 +13,7 @@
  * along with other APIs.
  */
 
+#include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -99,23 +100,22 @@ static struct class intel_scu_ipc_class = {
  */
 struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void)
 {
-	struct intel_scu_ipc_dev *scu = NULL;
+	guard(mutex)(&ipclock);
 
-	mutex_lock(&ipclock);
 	if (ipcdev) {
 		get_device(&ipcdev->dev);
+
 		/*
 		 * Prevent the IPC provider from being unloaded while it
 		 * is being used.
 		 */
-		if (!try_module_get(ipcdev->owner))
-			put_device(&ipcdev->dev);
-		else
-			scu = ipcdev;
+		if (try_module_get(ipcdev->owner))
+			return ipcdev;
+
+		put_device(&ipcdev->dev);
 	}
 
-	mutex_unlock(&ipclock);
-	return scu;
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_get);
 
@@ -289,12 +289,11 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
 
 	memset(cbuf, 0, sizeof(cbuf));
 
-	mutex_lock(&ipclock);
+	guard(mutex)(&ipclock);
+
 	scu = intel_scu_ipc_get(scu);
-	if (IS_ERR(scu)) {
-		mutex_unlock(&ipclock);
+	if (IS_ERR(scu))
 		return PTR_ERR(scu);
-	}
 
 	for (nc = 0; nc < count; nc++, offset += 2) {
 		cbuf[offset] = addr[nc];
@@ -319,13 +318,14 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
 	}
 
 	err = intel_scu_ipc_check_status(scu);
-	if (!err) { /* Read rbuf */
-		for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
-			wbuf[nc] = ipc_data_readl(scu, offset);
-		memcpy(data, wbuf, count);
-	}
-	mutex_unlock(&ipclock);
-	return err;
+	if (err)
+		return err;
+
+	for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
+		wbuf[nc] = ipc_data_readl(scu, offset);
+	memcpy(data, wbuf, count);
+
+	return 0;
 }
 
 /**
@@ -446,17 +446,15 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
 	u32 cmdval;
 	int err;
 
-	mutex_lock(&ipclock);
+	guard(mutex)(&ipclock);
+
 	scu = intel_scu_ipc_get(scu);
-	if (IS_ERR(scu)) {
-		mutex_unlock(&ipclock);
+	if (IS_ERR(scu))
 		return PTR_ERR(scu);
-	}
 
 	cmdval = sub << 12 | cmd;
 	ipc_command(scu, cmdval);
 	err = intel_scu_ipc_check_status(scu);
-	mutex_unlock(&ipclock);
 	if (err)
 		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
 	return err;
@@ -485,18 +483,17 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
 {
 	size_t outbuflen = DIV_ROUND_UP(outlen, sizeof(u32));
 	size_t inbuflen = DIV_ROUND_UP(inlen, sizeof(u32));
-	u32 cmdval, inbuf[4] = {};
+	u32 cmdval, inbuf[4] = {}, outbuf[4] = {};
 	int i, err;
 
 	if (inbuflen > 4 || outbuflen > 4)
 		return -EINVAL;
 
-	mutex_lock(&ipclock);
+	guard(mutex)(&ipclock);
+
 	scu = intel_scu_ipc_get(scu);
-	if (IS_ERR(scu)) {
-		mutex_unlock(&ipclock);
+	if (IS_ERR(scu))
 		return PTR_ERR(scu);
-	}
 
 	memcpy(inbuf, in, inlen);
 	for (i = 0; i < inbuflen; i++)
@@ -505,20 +502,17 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
 	cmdval = (size << 16) | (sub << 12) | cmd;
 	ipc_command(scu, cmdval);
 	err = intel_scu_ipc_check_status(scu);
-
-	if (!err) {
-		u32 outbuf[4] = {};
-
-		for (i = 0; i < outbuflen; i++)
-			outbuf[i] = ipc_data_readl(scu, 4 * i);
-
-		memcpy(out, outbuf, outlen);
+	if (err) {
+		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
+		return err;
 	}
 
-	mutex_unlock(&ipclock);
-	if (err)
-		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
-	return err;
+	for (i = 0; i < outbuflen; i++)
+		outbuf[i] = ipc_data_readl(scu, 4 * i);
+
+	memcpy(out, outbuf, outlen);
+
+	return 0;
 }
 EXPORT_SYMBOL(intel_scu_ipc_dev_command_with_size);
 
@@ -572,18 +566,15 @@ __intel_scu_ipc_register(struct device *parent,
 	struct intel_scu_ipc_dev *scu;
 	void __iomem *ipc_base;
 
-	mutex_lock(&ipclock);
+	guard(mutex)(&ipclock);
+
 	/* We support only one IPC */
-	if (ipcdev) {
-		err = -EBUSY;
-		goto err_unlock;
-	}
+	if (ipcdev)
+		return ERR_PTR(-EBUSY);
 
 	scu = kzalloc(sizeof(*scu), GFP_KERNEL);
-	if (!scu) {
-		err = -ENOMEM;
-		goto err_unlock;
-	}
+	if (!scu)
+		return ERR_PTR(-ENOMEM);
 
 	scu->owner = owner;
 	scu->dev.parent = parent;
@@ -621,13 +612,11 @@ __intel_scu_ipc_register(struct device *parent,
 	err = device_register(&scu->dev);
 	if (err) {
 		put_device(&scu->dev);
-		goto err_unlock;
+		return ERR_PTR(err);
 	}
 
 	/* Assign device at last */
 	ipcdev = scu;
-	mutex_unlock(&ipclock);
-
 	return scu;
 
 err_unmap:
@@ -636,9 +625,6 @@ __intel_scu_ipc_register(struct device *parent,
 	release_mem_region(scu_data->mem.start, resource_size(&scu_data->mem));
 err_free:
 	kfree(scu);
-err_unlock:
-	mutex_unlock(&ipclock);
-
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(__intel_scu_ipc_register);
@@ -652,12 +638,12 @@ EXPORT_SYMBOL_GPL(__intel_scu_ipc_register);
  */
 void intel_scu_ipc_unregister(struct intel_scu_ipc_dev *scu)
 {
-	mutex_lock(&ipclock);
+	guard(mutex)(&ipclock);
+
 	if (!WARN_ON(!ipcdev)) {
 		ipcdev = NULL;
 		device_unregister(&scu->dev);
 	}
-	mutex_unlock(&ipclock);
 }
 EXPORT_SYMBOL_GPL(intel_scu_ipc_unregister);
 
-- 
2.43.0.rc1.1336.g36b5255a03ac


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

* [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data
  2024-10-16 11:48 [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Andy Shevchenko
  2024-10-16 11:48 ` [PATCH v1 1/3] platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO Andy Shevchenko
  2024-10-16 11:48 ` [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers Andy Shevchenko
@ 2024-10-16 11:48 ` Andy Shevchenko
  2024-10-21  7:00   ` Mika Westerberg
  2024-10-17 21:10 ` [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Ferry Toth
  3 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2024-10-16 11:48 UTC (permalink / raw)
  To: Andy Shevchenko, linux-kernel, platform-driver-x86
  Cc: Mika Westerberg, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

Save a copy of the entire struct intel_scu_ipc_data for easier
maintenance in case of expanding (adding new members become simpler).

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/platform/x86/intel_scu_ipc.c | 33 ++++++++++++++--------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index ffb0a2524388..e86a255f70ba 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -57,11 +57,11 @@
 
 struct intel_scu_ipc_dev {
 	struct device dev;
-	struct resource mem;
 	struct module *owner;
-	int irq;
 	void __iomem *ipc_base;
 	struct completion cmd_complete;
+
+	struct intel_scu_ipc_data data;
 };
 
 #define IPC_STATUS		0x04
@@ -256,7 +256,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 > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
+	return scu->data.irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
 }
 
 static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu)
@@ -536,13 +536,13 @@ static irqreturn_t ioc(int irq, void *dev_id)
 
 static void intel_scu_ipc_release(struct device *dev)
 {
-	struct intel_scu_ipc_dev *scu;
+	struct intel_scu_ipc_dev *scu = container_of(dev, struct intel_scu_ipc_dev, dev);
+	struct intel_scu_ipc_data *data = &scu->data;
 
-	scu = container_of(dev, struct intel_scu_ipc_dev, dev);
-	if (scu->irq > 0)
-		free_irq(scu->irq, scu);
+	if (data->irq > 0)
+		free_irq(data->irq, scu);
 	iounmap(scu->ipc_base);
-	release_mem_region(scu->mem.start, resource_size(&scu->mem));
+	release_mem_region(data->mem.start, resource_size(&data->mem));
 	kfree(scu);
 }
 
@@ -563,6 +563,7 @@ __intel_scu_ipc_register(struct device *parent,
 			 struct module *owner)
 {
 	int err;
+	struct intel_scu_ipc_data *data;
 	struct intel_scu_ipc_dev *scu;
 	void __iomem *ipc_base;
 
@@ -581,25 +582,25 @@ __intel_scu_ipc_register(struct device *parent,
 	scu->dev.class = &intel_scu_ipc_class;
 	scu->dev.release = intel_scu_ipc_release;
 
-	if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem),
-				"intel_scu_ipc")) {
+	memcpy(&scu->data, scu_data, sizeof(scu->data));
+	data = &scu->data;
+
+	if (!request_mem_region(data->mem.start, resource_size(&data->mem), "intel_scu_ipc")) {
 		err = -EBUSY;
 		goto err_free;
 	}
 
-	ipc_base = ioremap(scu_data->mem.start, resource_size(&scu_data->mem));
+	ipc_base = ioremap(data->mem.start, resource_size(&data->mem));
 	if (!ipc_base) {
 		err = -ENOMEM;
 		goto err_release;
 	}
 
 	scu->ipc_base = ipc_base;
-	scu->mem = scu_data->mem;
-	scu->irq = scu_data->irq;
 	init_completion(&scu->cmd_complete);
 
-	if (scu->irq > 0) {
-		err = request_irq(scu->irq, ioc, 0, "intel_scu_ipc", scu);
+	if (data->irq > 0) {
+		err = request_irq(data->irq, ioc, 0, "intel_scu_ipc", scu);
 		if (err)
 			goto err_unmap;
 	}
@@ -622,7 +623,7 @@ __intel_scu_ipc_register(struct device *parent,
 err_unmap:
 	iounmap(ipc_base);
 err_release:
-	release_mem_region(scu_data->mem.start, resource_size(&scu_data->mem));
+	release_mem_region(data->mem.start, resource_size(&data->mem));
 err_free:
 	kfree(scu);
 	return ERR_PTR(err);
-- 
2.43.0.rc1.1336.g36b5255a03ac


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

* Re: [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups
  2024-10-16 11:48 [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Andy Shevchenko
                   ` (2 preceding siblings ...)
  2024-10-16 11:48 ` [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data Andy Shevchenko
@ 2024-10-17 21:10 ` Ferry Toth
  3 siblings, 0 replies; 8+ messages in thread
From: Ferry Toth @ 2024-10-17 21:10 UTC (permalink / raw)
  To: Andy Shevchenko, linux-kernel, platform-driver-x86
  Cc: Mika Westerberg, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

Hi

Op 16-10-2024 om 13:48 schreef Andy Shevchenko:
> The first patch avoids using a workaround for IO (which seems unneeded).
> The rest is a batch of cleanups. Cc'ed to Ferry in hope of testing on
> Intel Merrifield (the main platform that uses these APIs).
>
> Andy Shevchenko (3):
>    platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO
>    platform/x86: intel_scu_ipc: Simplify code with cleanup helpers
>    platform/x86: intel_scu_ipc: Save a copy of the entire struct
>      intel_scu_ipc_data
>
>   drivers/platform/x86/intel_scu_ipc.c | 142 ++++++++++++---------------
>   1 file changed, 61 insertions(+), 81 deletions(-)
>
Tested iio_info (mrfld_bcove_adc), host/gadget switch, power button.

Tested-by: Ferry Toth <fntoth@gmail.com> (Intel Edison-Arduino)


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

* Re: [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers
  2024-10-16 11:48 ` [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers Andy Shevchenko
@ 2024-10-21  7:00   ` Mika Westerberg
  2024-10-21  8:34     ` Andy Shevchenko
  0 siblings, 1 reply; 8+ messages in thread
From: Mika Westerberg @ 2024-10-21  7:00 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-kernel, platform-driver-x86, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

On Wed, Oct 16, 2024 at 02:48:25PM +0300, Andy Shevchenko wrote:
> Use macros defined in linux/cleanup.h to automate resource lifetime
> control in the driver.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/platform/x86/intel_scu_ipc.c | 102 ++++++++++++---------------
>  1 file changed, 44 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
> index 290b38627542..ffb0a2524388 100644
> --- a/drivers/platform/x86/intel_scu_ipc.c
> +++ b/drivers/platform/x86/intel_scu_ipc.c
> @@ -13,6 +13,7 @@
>   * along with other APIs.
>   */
>  
> +#include <linux/cleanup.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/errno.h>
> @@ -99,23 +100,22 @@ static struct class intel_scu_ipc_class = {
>   */
>  struct intel_scu_ipc_dev *intel_scu_ipc_dev_get(void)
>  {
> -	struct intel_scu_ipc_dev *scu = NULL;
> +	guard(mutex)(&ipclock);
>  
> -	mutex_lock(&ipclock);
>  	if (ipcdev) {
>  		get_device(&ipcdev->dev);
> +

unintended whitespace change?

>  		/*
>  		 * Prevent the IPC provider from being unloaded while it
>  		 * is being used.
>  		 */
> -		if (!try_module_get(ipcdev->owner))
> -			put_device(&ipcdev->dev);
> -		else
> -			scu = ipcdev;
> +		if (try_module_get(ipcdev->owner))
> +			return ipcdev;
> +
> +		put_device(&ipcdev->dev);
>  	}
>  
> -	mutex_unlock(&ipclock);
> -	return scu;
> +	return NULL;
>  }
>  EXPORT_SYMBOL_GPL(intel_scu_ipc_dev_get);
>  
> @@ -289,12 +289,11 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
>  
>  	memset(cbuf, 0, sizeof(cbuf));
>  
> -	mutex_lock(&ipclock);
> +	guard(mutex)(&ipclock);
> +
>  	scu = intel_scu_ipc_get(scu);
> -	if (IS_ERR(scu)) {
> -		mutex_unlock(&ipclock);
> +	if (IS_ERR(scu))
>  		return PTR_ERR(scu);
> -	}
>  
>  	for (nc = 0; nc < count; nc++, offset += 2) {
>  		cbuf[offset] = addr[nc];
> @@ -319,13 +318,14 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
>  	}
>  
>  	err = intel_scu_ipc_check_status(scu);
> -	if (!err) { /* Read rbuf */
> -		for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
> -			wbuf[nc] = ipc_data_readl(scu, offset);
> -		memcpy(data, wbuf, count);
> -	}

Here you changed also the check to be for if (err) instead of (!err) so
at least mention why you did these at the same time you did the cleanup
change. It is fine by me but good to mention in the commit message.

> -	mutex_unlock(&ipclock);
> -	return err;
> +	if (err)
> +		return err;
> +
> +	for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
> +		wbuf[nc] = ipc_data_readl(scu, offset);
> +	memcpy(data, wbuf, count);
> +
> +	return 0;
>  }
>  
>  /**
> @@ -446,17 +446,15 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
>  	u32 cmdval;
>  	int err;
>  
> -	mutex_lock(&ipclock);
> +	guard(mutex)(&ipclock);
> +
>  	scu = intel_scu_ipc_get(scu);
> -	if (IS_ERR(scu)) {
> -		mutex_unlock(&ipclock);
> +	if (IS_ERR(scu))
>  		return PTR_ERR(scu);
> -	}
>  
>  	cmdval = sub << 12 | cmd;
>  	ipc_command(scu, cmdval);
>  	err = intel_scu_ipc_check_status(scu);
> -	mutex_unlock(&ipclock);
>  	if (err)
>  		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
>  	return err;
> @@ -485,18 +483,17 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
>  {
>  	size_t outbuflen = DIV_ROUND_UP(outlen, sizeof(u32));
>  	size_t inbuflen = DIV_ROUND_UP(inlen, sizeof(u32));
> -	u32 cmdval, inbuf[4] = {};
> +	u32 cmdval, inbuf[4] = {}, outbuf[4] = {};
>  	int i, err;
>  
>  	if (inbuflen > 4 || outbuflen > 4)
>  		return -EINVAL;
>  
> -	mutex_lock(&ipclock);
> +	guard(mutex)(&ipclock);
> +
>  	scu = intel_scu_ipc_get(scu);
> -	if (IS_ERR(scu)) {
> -		mutex_unlock(&ipclock);
> +	if (IS_ERR(scu))
>  		return PTR_ERR(scu);
> -	}
>  
>  	memcpy(inbuf, in, inlen);
>  	for (i = 0; i < inbuflen; i++)
> @@ -505,20 +502,17 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
>  	cmdval = (size << 16) | (sub << 12) | cmd;
>  	ipc_command(scu, cmdval);
>  	err = intel_scu_ipc_check_status(scu);
> -
> -	if (!err) {
> -		u32 outbuf[4] = {};
> -
> -		for (i = 0; i < outbuflen; i++)
> -			outbuf[i] = ipc_data_readl(scu, 4 * i);
> -
> -		memcpy(out, outbuf, outlen);

Same here.

> +	if (err) {
> +		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
> +		return err;
>  	}
>  
> -	mutex_unlock(&ipclock);
> -	if (err)
> -		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
> -	return err;
> +	for (i = 0; i < outbuflen; i++)
> +		outbuf[i] = ipc_data_readl(scu, 4 * i);
> +
> +	memcpy(out, outbuf, outlen);
> +
> +	return 0;
>  }
>  EXPORT_SYMBOL(intel_scu_ipc_dev_command_with_size);
>  
> @@ -572,18 +566,15 @@ __intel_scu_ipc_register(struct device *parent,
>  	struct intel_scu_ipc_dev *scu;
>  	void __iomem *ipc_base;
>  
> -	mutex_lock(&ipclock);
> +	guard(mutex)(&ipclock);
> +
>  	/* We support only one IPC */
> -	if (ipcdev) {
> -		err = -EBUSY;
> -		goto err_unlock;
> -	}
> +	if (ipcdev)
> +		return ERR_PTR(-EBUSY);
>  
>  	scu = kzalloc(sizeof(*scu), GFP_KERNEL);
> -	if (!scu) {
> -		err = -ENOMEM;
> -		goto err_unlock;
> -	}
> +	if (!scu)
> +		return ERR_PTR(-ENOMEM);
>  
>  	scu->owner = owner;
>  	scu->dev.parent = parent;
> @@ -621,13 +612,11 @@ __intel_scu_ipc_register(struct device *parent,
>  	err = device_register(&scu->dev);
>  	if (err) {
>  		put_device(&scu->dev);
> -		goto err_unlock;
> +		return ERR_PTR(err);
>  	}
>  
>  	/* Assign device at last */
>  	ipcdev = scu;
> -	mutex_unlock(&ipclock);
> -
>  	return scu;
>  
>  err_unmap:
> @@ -636,9 +625,6 @@ __intel_scu_ipc_register(struct device *parent,
>  	release_mem_region(scu_data->mem.start, resource_size(&scu_data->mem));
>  err_free:
>  	kfree(scu);
> -err_unlock:
> -	mutex_unlock(&ipclock);
> -
>  	return ERR_PTR(err);
>  }
>  EXPORT_SYMBOL_GPL(__intel_scu_ipc_register);
> @@ -652,12 +638,12 @@ EXPORT_SYMBOL_GPL(__intel_scu_ipc_register);
>   */
>  void intel_scu_ipc_unregister(struct intel_scu_ipc_dev *scu)
>  {
> -	mutex_lock(&ipclock);
> +	guard(mutex)(&ipclock);
> +
>  	if (!WARN_ON(!ipcdev)) {
>  		ipcdev = NULL;
>  		device_unregister(&scu->dev);
>  	}
> -	mutex_unlock(&ipclock);
>  }
>  EXPORT_SYMBOL_GPL(intel_scu_ipc_unregister);
>  
> -- 
> 2.43.0.rc1.1336.g36b5255a03ac

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

* Re: [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data
  2024-10-16 11:48 ` [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data Andy Shevchenko
@ 2024-10-21  7:00   ` Mika Westerberg
  0 siblings, 0 replies; 8+ messages in thread
From: Mika Westerberg @ 2024-10-21  7:00 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-kernel, platform-driver-x86, Andy Shevchenko, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

On Wed, Oct 16, 2024 at 02:48:26PM +0300, Andy Shevchenko wrote:
> Save a copy of the entire struct intel_scu_ipc_data for easier
> maintenance in case of expanding (adding new members become simpler).
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>

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

* Re: [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers
  2024-10-21  7:00   ` Mika Westerberg
@ 2024-10-21  8:34     ` Andy Shevchenko
  0 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2024-10-21  8:34 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, platform-driver-x86, Hans de Goede,
	Ilpo Järvinen, Ferry Toth

On Mon, Oct 21, 2024 at 10:00:05AM +0300, Mika Westerberg wrote:
> On Wed, Oct 16, 2024 at 02:48:25PM +0300, Andy Shevchenko wrote:
> > Use macros defined in linux/cleanup.h to automate resource lifetime
> > control in the driver.

...

> >  		get_device(&ipcdev->dev);
> > +
> 
> unintended whitespace change?

Hmm... I don't remember, probably.
I will remove this part in v2.

...

> >  	err = intel_scu_ipc_check_status(scu);
> > -	if (!err) { /* Read rbuf */
> > -		for (nc = 0, offset = 0; nc < 4; nc++, offset += 4)
> > -			wbuf[nc] = ipc_data_readl(scu, offset);
> > -		memcpy(data, wbuf, count);
> > -	}
> 
> Here you changed also the check to be for if (err) instead of (!err) so
> at least mention why you did these at the same time you did the cleanup
> change. It is fine by me but good to mention in the commit message.

Yes, this is the part of the cleanup change. It's a byproduct of it.
I will try to mention this in the commit message, however I consider
the text redundant.

...

> > -	if (!err) {
> > -		u32 outbuf[4] = {};
> > -
> > -		for (i = 0; i < outbuflen; i++)
> > -			outbuf[i] = ipc_data_readl(scu, 4 * i);
> > -
> > -		memcpy(out, outbuf, outlen);
> 
> Same here.

Same answer.

> > +	if (err) {
> > +		dev_err(&scu->dev, "IPC command %#x failed with %d\n", cmdval, err);
> > +		return err;
> >  	}

...

Thank you for the review!

-- 
With Best Regards,
Andy Shevchenko



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

end of thread, other threads:[~2024-10-21  8:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-16 11:48 [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Andy Shevchenko
2024-10-16 11:48 ` [PATCH v1 1/3] platform/x86: intel_scu_ipc: Replace workaround by 32-bit IO Andy Shevchenko
2024-10-16 11:48 ` [PATCH v1 2/3] platform/x86: intel_scu_ipc: Simplify code with cleanup helpers Andy Shevchenko
2024-10-21  7:00   ` Mika Westerberg
2024-10-21  8:34     ` Andy Shevchenko
2024-10-16 11:48 ` [PATCH v1 3/3] platform/x86: intel_scu_ipc: Save a copy of the entire struct intel_scu_ipc_data Andy Shevchenko
2024-10-21  7:00   ` Mika Westerberg
2024-10-17 21:10 ` [PATCH v1 0/3] platform/x86: intel_scu_ipc: Avoid working around IO and cleanups Ferry Toth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox