All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Jean Delvare <jdelvare@suse.com>, Andi Shyti <andi.shyti@kernel.org>
Subject: [PATCH v1 05/12] i2c: isch: Use custom private data structure
Date: Wed, 11 Sep 2024 18:39:18 +0300	[thread overview]
Message-ID: <20240911154820.2846187-6-andriy.shevchenko@linux.intel.com> (raw)
In-Reply-To: <20240911154820.2846187-1-andriy.shevchenko@linux.intel.com>

Use custom private data structure instead of global variables.
With that, remove not anymore true comment.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/i2c/busses/i2c-isch.c | 145 ++++++++++++++++++----------------
 1 file changed, 75 insertions(+), 70 deletions(-)

diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 8d34d4398f9b..4ec6c0a66a96 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -9,16 +9,14 @@
 
 */
 
-/*
-   Supports:
-	Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L)
-   Note: we assume there can only be one device, with one SMBus interface.
-*/
+/* Supports: Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L) */
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
+#include <linux/container_of.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
@@ -46,31 +44,33 @@
 #define SCH_WORD_DATA		0x03
 #define SCH_BLOCK_DATA		0x05
 
-static struct i2c_adapter sch_adapter;
-static void __iomem *sch_smba;
+struct sch_i2c {
+	struct i2c_adapter adapter;
+	void __iomem *smba;
+};
 
 static int backbone_speed = 33000; /* backbone speed in kHz */
 module_param(backbone_speed, int, S_IRUSR | S_IWUSR);
 MODULE_PARM_DESC(backbone_speed, "Backbone speed in kHz, (default = 33000)");
 
-static inline u8 sch_io_rd8(void __iomem *smba, unsigned int offset)
+static inline u8 sch_io_rd8(struct sch_i2c *priv, unsigned int offset)
 {
-	return ioread8(smba + offset);
+	return ioread8(priv->smba + offset);
 }
 
-static inline void sch_io_wr8(void __iomem *smba, unsigned int offset, u8 value)
+static inline void sch_io_wr8(struct sch_i2c *priv, unsigned int offset, u8 value)
 {
-	iowrite8(value, smba + offset);
+	iowrite8(value, priv->smba + offset);
 }
 
-static inline u16 sch_io_rd16(void __iomem *smba, unsigned int offset)
+static inline u16 sch_io_rd16(struct sch_i2c *priv, unsigned int offset)
 {
-	return ioread16(smba + offset);
+	return ioread16(priv->smba + offset);
 }
 
-static inline void sch_io_wr16(void __iomem *smba, unsigned int offset, u16 value)
+static inline void sch_io_wr16(struct sch_i2c *priv, unsigned int offset, u16 value)
 {
-	iowrite16(value, smba + offset);
+	iowrite16(value, priv->smba + offset);
 }
 
 /*
@@ -80,26 +80,27 @@ static inline void sch_io_wr16(void __iomem *smba, unsigned int offset, u16 valu
  */
 static int sch_transaction(struct i2c_adapter *adap)
 {
+	struct sch_i2c *priv = container_of(adap, struct sch_i2c, adapter);
 	int temp;
 	int result = 0;
 	int retries = 0;
 
 	dev_dbg(&adap->dev,
 		"Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
-		sch_io_rd8(sch_smba, SMBHSTCNT), sch_io_rd8(sch_smba, SMBHSTCMD),
-		sch_io_rd8(sch_smba, SMBHSTADD),
-		sch_io_rd8(sch_smba, SMBHSTDAT0), sch_io_rd8(sch_smba, SMBHSTDAT1));
+		sch_io_rd8(priv, SMBHSTCNT), sch_io_rd8(priv, SMBHSTCMD),
+		sch_io_rd8(priv, SMBHSTADD),
+		sch_io_rd8(priv, SMBHSTDAT0), sch_io_rd8(priv, SMBHSTDAT1));
 
 	/* Make sure the SMBus host is ready to start transmitting */
-	temp = sch_io_rd8(sch_smba, SMBHSTSTS) & 0x0f;
+	temp = sch_io_rd8(priv, SMBHSTSTS) & 0x0f;
 	if (temp) {
 		/* Can not be busy since we checked it in sch_access */
 		if (temp & 0x01)
 			dev_dbg(&adap->dev, "Completion (%02x). Clear...\n", temp);
 		if (temp & 0x06)
 			dev_dbg(&adap->dev, "SMBus error (%02x). Resetting...\n", temp);
-		sch_io_wr8(sch_smba, SMBHSTSTS, temp);
-		temp = sch_io_rd8(sch_smba, SMBHSTSTS) & 0x0f;
+		sch_io_wr8(priv, SMBHSTSTS, temp);
+		temp = sch_io_rd8(priv, SMBHSTSTS) & 0x0f;
 		if (temp) {
 			dev_err(&adap->dev, "SMBus is not ready: (%02x)\n", temp);
 			return -EAGAIN;
@@ -107,13 +108,13 @@ static int sch_transaction(struct i2c_adapter *adap)
 	}
 
 	/* start the transaction by setting bit 4 */
-	temp = sch_io_rd8(sch_smba, SMBHSTCNT);
+	temp = sch_io_rd8(priv, SMBHSTCNT);
 	temp |= 0x10;
-	sch_io_wr8(sch_smba, SMBHSTCNT, temp);
+	sch_io_wr8(priv, SMBHSTCNT, temp);
 
 	do {
 		usleep_range(100, 200);
-		temp = sch_io_rd8(sch_smba, SMBHSTSTS) & 0x0f;
+		temp = sch_io_rd8(priv, SMBHSTSTS) & 0x0f;
 	} while ((temp & 0x08) && (retries++ < MAX_RETRIES));
 
 	/* If the SMBus is still busy, we give up */
@@ -129,8 +130,8 @@ static int sch_transaction(struct i2c_adapter *adap)
 		dev_err(&adap->dev, "Error: no response!\n");
 	} else if (temp & 0x01) {
 		dev_dbg(&adap->dev, "Post complete!\n");
-		sch_io_wr8(sch_smba, SMBHSTSTS, temp);
-		temp = sch_io_rd8(sch_smba, SMBHSTSTS) & 0x07;
+		sch_io_wr8(priv, SMBHSTSTS, temp);
+		temp = sch_io_rd8(priv, SMBHSTSTS) & 0x07;
 		if (temp & 0x06) {
 			/* Completion clear failed */
 			dev_dbg(&adap->dev,
@@ -141,9 +142,9 @@ static int sch_transaction(struct i2c_adapter *adap)
 		dev_dbg(&adap->dev, "No such address.\n");
 	}
 	dev_dbg(&adap->dev, "Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
-		sch_io_rd8(sch_smba, SMBHSTCNT), sch_io_rd8(sch_smba, SMBHSTCMD),
-		sch_io_rd8(sch_smba, SMBHSTADD),
-		sch_io_rd8(sch_smba, SMBHSTDAT0), sch_io_rd8(sch_smba, SMBHSTDAT1));
+		sch_io_rd8(priv, SMBHSTCNT), sch_io_rd8(priv, SMBHSTCMD),
+		sch_io_rd8(priv, SMBHSTADD),
+		sch_io_rd8(priv, SMBHSTDAT0), sch_io_rd8(priv, SMBHSTDAT1));
 	return result;
 }
 
@@ -158,15 +159,16 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr,
 		 unsigned short flags, char read_write,
 		 u8 command, int size, union i2c_smbus_data *data)
 {
+	struct sch_i2c *priv = container_of(adap, struct sch_i2c, adapter);
 	int i, len, temp, rc;
 
 	/* Make sure the SMBus host is not busy */
-	temp = sch_io_rd8(sch_smba, SMBHSTSTS) & 0x0f;
+	temp = sch_io_rd8(priv, SMBHSTSTS) & 0x0f;
 	if (temp & 0x08) {
 		dev_dbg(&adap->dev, "SMBus busy (%02x)\n", temp);
 		return -EAGAIN;
 	}
-	temp = sch_io_rd16(sch_smba, SMBHSTCLK);
+	temp = sch_io_rd16(priv, SMBHSTCLK);
 	if (!temp) {
 		/*
 		 * We can't determine if we have 33 or 25 MHz clock for
@@ -175,47 +177,47 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr,
 		 * run ~75 kHz instead which should do no harm.
 		 */
 		dev_notice(&adap->dev, "Clock divider uninitialized. Setting defaults\n");
-		sch_io_wr16(sch_smba, SMBHSTCLK, backbone_speed / (4 * 100));
+		sch_io_wr16(priv, SMBHSTCLK, backbone_speed / (4 * 100));
 	}
 
 	dev_dbg(&adap->dev, "access size: %d %s\n", size, str_read_write(read_write));
 	switch (size) {
 	case I2C_SMBUS_QUICK:
-		sch_io_wr8(sch_smba, SMBHSTADD, (addr << 1) | read_write);
+		sch_io_wr8(priv, SMBHSTADD, (addr << 1) | read_write);
 		size = SCH_QUICK;
 		break;
 	case I2C_SMBUS_BYTE:
-		sch_io_wr8(sch_smba, SMBHSTADD, (addr << 1) | read_write);
+		sch_io_wr8(priv, SMBHSTADD, (addr << 1) | read_write);
 		if (read_write == I2C_SMBUS_WRITE)
-			sch_io_wr8(sch_smba, SMBHSTCMD, command);
+			sch_io_wr8(priv, SMBHSTCMD, command);
 		size = SCH_BYTE;
 		break;
 	case I2C_SMBUS_BYTE_DATA:
-		sch_io_wr8(sch_smba, SMBHSTADD, (addr << 1) | read_write);
-		sch_io_wr8(sch_smba, SMBHSTCMD, command);
+		sch_io_wr8(priv, SMBHSTADD, (addr << 1) | read_write);
+		sch_io_wr8(priv, SMBHSTCMD, command);
 		if (read_write == I2C_SMBUS_WRITE)
-			sch_io_wr8(sch_smba, SMBHSTDAT0, data->byte);
+			sch_io_wr8(priv, SMBHSTDAT0, data->byte);
 		size = SCH_BYTE_DATA;
 		break;
 	case I2C_SMBUS_WORD_DATA:
-		sch_io_wr8(sch_smba, SMBHSTADD, (addr << 1) | read_write);
-		sch_io_wr8(sch_smba, SMBHSTCMD, command);
+		sch_io_wr8(priv, SMBHSTADD, (addr << 1) | read_write);
+		sch_io_wr8(priv, SMBHSTCMD, command);
 		if (read_write == I2C_SMBUS_WRITE) {
-			sch_io_wr8(sch_smba, SMBHSTDAT0, data->word >> 0);
-			sch_io_wr8(sch_smba, SMBHSTDAT1, data->word >> 8);
+			sch_io_wr8(priv, SMBHSTDAT0, data->word >> 0);
+			sch_io_wr8(priv, SMBHSTDAT1, data->word >> 8);
 		}
 		size = SCH_WORD_DATA;
 		break;
 	case I2C_SMBUS_BLOCK_DATA:
-		sch_io_wr8(sch_smba, SMBHSTADD, (addr << 1) | read_write);
-		sch_io_wr8(sch_smba, SMBHSTCMD, command);
+		sch_io_wr8(priv, SMBHSTADD, (addr << 1) | read_write);
+		sch_io_wr8(priv, SMBHSTCMD, command);
 		if (read_write == I2C_SMBUS_WRITE) {
 			len = data->block[0];
 			if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
 				return -EINVAL;
-			sch_io_wr8(sch_smba, SMBHSTDAT0, len);
+			sch_io_wr8(priv, SMBHSTDAT0, len);
 			for (i = 1; i <= len; i++)
-				sch_io_wr8(sch_smba, SMBBLKDAT + i - 1, data->block[i]);
+				sch_io_wr8(priv, SMBBLKDAT + i - 1, data->block[i]);
 		}
 		size = SCH_BLOCK_DATA;
 		break;
@@ -225,9 +227,9 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr,
 	}
 	dev_dbg(&adap->dev, "write size %d to 0x%04x\n", size, SMBHSTCNT);
 
-	temp = sch_io_rd8(sch_smba, SMBHSTCNT);
+	temp = sch_io_rd8(priv, SMBHSTCNT);
 	temp = (temp & 0xb0) | (size & 0x7);
-	sch_io_wr8(sch_smba, SMBHSTCNT, temp);
+	sch_io_wr8(priv, SMBHSTCNT, temp);
 
 	rc = sch_transaction(adap);
 	if (rc)	/* Error in transaction */
@@ -239,18 +241,18 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr,
 	switch (size) {
 	case SCH_BYTE:
 	case SCH_BYTE_DATA:
-		data->byte = sch_io_rd8(sch_smba, SMBHSTDAT0);
+		data->byte = sch_io_rd8(priv, SMBHSTDAT0);
 		break;
 	case SCH_WORD_DATA:
-		data->word = (sch_io_rd8(sch_smba, SMBHSTDAT0) << 0) +
-			     (sch_io_rd8(sch_smba, SMBHSTDAT1) << 8);
+		data->word = (sch_io_rd8(priv, SMBHSTDAT0) << 0) +
+			     (sch_io_rd8(priv, SMBHSTDAT1) << 8);
 		break;
 	case SCH_BLOCK_DATA:
-		data->block[0] = sch_io_rd8(sch_smba, SMBHSTDAT0);
+		data->block[0] = sch_io_rd8(priv, SMBHSTDAT0);
 		if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
 			return -EPROTO;
 		for (i = 1; i <= data->block[0]; i++)
-			data->block[i] = sch_io_rd8(sch_smba, SMBBLKDAT + i - 1);
+			data->block[i] = sch_io_rd8(priv, SMBBLKDAT + i - 1);
 		break;
 	}
 	return 0;
@@ -268,46 +270,49 @@ static const struct i2c_algorithm smbus_algorithm = {
 	.functionality	= sch_func,
 };
 
-static struct i2c_adapter sch_adapter = {
-	.owner		= THIS_MODULE,
-	.class		= I2C_CLASS_HWMON,
-	.algo		= &smbus_algorithm,
-};
-
 static int smbus_sch_probe(struct platform_device *dev)
 {
+	struct sch_i2c *priv;
 	struct resource *res;
 	int retval;
 
+	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	res = platform_get_resource(dev, IORESOURCE_IO, 0);
 	if (!res)
 		return -EBUSY;
 
-	sch_smba = devm_ioport_map(&dev->dev, res->start, resource_size(res));
-	if (!sch_smba) {
+	priv->smba = devm_ioport_map(&dev->dev, res->start, resource_size(res));
+	if (!priv->smba) {
 		dev_err(&dev->dev, "SMBus region %pR already in use!\n", res);
 		return -EBUSY;
 	}
 
 	/* set up the sysfs linkage to our parent device */
-	sch_adapter.dev.parent = &dev->dev;
+	priv->adapter.dev.parent = &dev->dev;
+	priv->adapter.owner = THIS_MODULE,
+	priv->adapter.class = I2C_CLASS_HWMON,
+	priv->adapter.algo = &smbus_algorithm,
 
-	snprintf(sch_adapter.name, sizeof(sch_adapter.name),
+	snprintf(priv->adapter.name, sizeof(priv->adapter.name),
 		"SMBus SCH adapter at %04x", res->start);
 
-	retval = i2c_add_adapter(&sch_adapter);
+	retval = i2c_add_adapter(&priv->adapter);
 	if (retval)
-		sch_smba = NULL;
+		return retval;
 
-	return retval;
+	platform_set_drvdata(dev, priv);
+
+	return 0;
 }
 
 static void smbus_sch_remove(struct platform_device *pdev)
 {
-	if (sch_smba) {
-		i2c_del_adapter(&sch_adapter);
-		sch_smba = NULL;
-	}
+	struct sch_i2c *priv = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&priv->adapter);
 }
 
 static struct platform_driver smbus_sch_driver = {
-- 
2.43.0.rc1.1336.g36b5255a03ac


  parent reply	other threads:[~2024-09-11 15:48 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-11 15:39 [PATCH v1 00/12] i2c: isch: Put the driver into shape Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 01/12] i2c: isch: Add missed 'else' Andy Shevchenko
2024-09-11 21:35   ` Andi Shyti
2024-09-11 21:36     ` Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 02/12] i2c: isch: Pass pointer to struct i2c_adapter down Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 03/12] i2c: isch: Use string_choices API instead of ternary operator Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 04/12] i2c: isch: Switch to memory mapped IO accessors Andy Shevchenko
2024-09-14  0:10   ` kernel test robot
2024-09-14  6:56   ` kernel test robot
2024-09-16  9:07     ` Andy Shevchenko
2024-09-16 10:10       ` Andi Shyti
2024-09-16 10:30         ` Andy Shevchenko
2024-09-16 11:58           ` Andi Shyti
2024-09-16 12:03             ` Andy Shevchenko
2024-09-11 15:39 ` Andy Shevchenko [this message]
2024-09-11 15:39 ` [PATCH v1 06/12] i2c: isch: switch i2c registration to devm functions Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 07/12] i2c: isch: Utilize temporary variable to hold device pointer Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 08/12] i2c: isch: Use read_poll_timeout() Andy Shevchenko
2024-09-12  7:29   ` Andi Shyti
2024-09-12 15:35     ` Andy Shevchenko
2024-09-12 15:55       ` Andi Shyti
2024-09-12 16:06         ` Andy Shevchenko
2024-09-12 16:43           ` Andi Shyti
2024-09-11 15:39 ` [PATCH v1 09/12] i2c: isch: Unify the name of the variable to hold an error code Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 10/12] i2c: isch: Don't use "proxy" headers Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 11/12] i2c: isch: Prefer to use octal permission Andy Shevchenko
2024-09-11 15:53   ` Jesper Juhl
2024-09-11 16:06     ` Andy Shevchenko
2024-09-11 15:39 ` [PATCH v1 12/12] i2c: isch: Convert to kernel-doc Andy Shevchenko
2024-09-12  7:33 ` [PATCH v1 00/12] i2c: isch: Put the driver into shape Andi Shyti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240911154820.2846187-6-andriy.shevchenko@linux.intel.com \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=andi.shyti@kernel.org \
    --cc=jdelvare@suse.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.