diff mbox series

[2/4] i2c: mux: add basic support for calling i2c_register_spd on muxed bus segments

Message ID 53e5c71a-d954-4211-91a1-de067451d532@gmail.com
State New
Headers show
Series i2c: Support i2c_register_spd() on multiplexed bus segments | expand

Commit Message

Heiner Kallweit Jan. 10, 2024, 8:14 p.m. UTC
This extension allows mux drivers to instruct i2c_mux_add_adapter to
call i2c_register_spd. First user of this feature will be gpio mux.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/i2c/i2c-mux.c   | 4 ++++
 include/linux/i2c-mux.h | 1 +
 2 files changed, 5 insertions(+)

Comments

kernel test robot Jan. 11, 2024, 3:53 p.m. UTC | #1
Hi Heiner,

kernel test robot noticed the following build errors:

[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on next-20240111]
[cannot apply to linus/master v6.7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Heiner-Kallweit/i2c-smbus-Prepare-i2c_register_spd-for-usage-on-muxed-segments/20240111-042152
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
patch link:    https://lore.kernel.org/r/53e5c71a-d954-4211-91a1-de067451d532%40gmail.com
patch subject: [PATCH 2/4] i2c: mux: add basic support for calling i2c_register_spd on muxed bus segments
config: i386-randconfig-053-20240111 (https://download.01.org/0day-ci/archive/20240111/202401112333.GUpSFOuc-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240111/202401112333.GUpSFOuc-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401112333.GUpSFOuc-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: drivers/i2c/i2c-mux.o: in function `i2c_mux_add_adapter':
>> drivers/i2c/i2c-mux.c:434: undefined reference to `i2c_register_spd'


vim +434 drivers/i2c/i2c-mux.c

   283	
   284	int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
   285				u32 force_nr, u32 chan_id,
   286				unsigned int class)
   287	{
   288		struct i2c_adapter *parent = muxc->parent;
   289		struct i2c_mux_priv *priv;
   290		char symlink_name[20];
   291		int ret;
   292	
   293		if (muxc->num_adapters >= muxc->max_adapters) {
   294			dev_err(muxc->dev, "No room for more i2c-mux adapters\n");
   295			return -EINVAL;
   296		}
   297	
   298		priv = kzalloc(sizeof(*priv), GFP_KERNEL);
   299		if (!priv)
   300			return -ENOMEM;
   301	
   302		/* Set up private adapter data */
   303		priv->muxc = muxc;
   304		priv->chan_id = chan_id;
   305	
   306		/* Need to do algo dynamically because we don't know ahead
   307		 * of time what sort of physical adapter we'll be dealing with.
   308		 */
   309		if (parent->algo->master_xfer) {
   310			if (muxc->mux_locked)
   311				priv->algo.master_xfer = i2c_mux_master_xfer;
   312			else
   313				priv->algo.master_xfer = __i2c_mux_master_xfer;
   314		}
   315		if (parent->algo->master_xfer_atomic)
   316			priv->algo.master_xfer_atomic = priv->algo.master_xfer;
   317	
   318		if (parent->algo->smbus_xfer) {
   319			if (muxc->mux_locked)
   320				priv->algo.smbus_xfer = i2c_mux_smbus_xfer;
   321			else
   322				priv->algo.smbus_xfer = __i2c_mux_smbus_xfer;
   323		}
   324		if (parent->algo->smbus_xfer_atomic)
   325			priv->algo.smbus_xfer_atomic = priv->algo.smbus_xfer;
   326	
   327		priv->algo.functionality = i2c_mux_functionality;
   328	
   329		/* Now fill out new adapter structure */
   330		snprintf(priv->adap.name, sizeof(priv->adap.name),
   331			 "i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id);
   332		priv->adap.owner = THIS_MODULE;
   333		priv->adap.algo = &priv->algo;
   334		priv->adap.algo_data = priv;
   335		priv->adap.dev.parent = &parent->dev;
   336		priv->adap.retries = parent->retries;
   337		priv->adap.timeout = parent->timeout;
   338		priv->adap.quirks = parent->quirks;
   339		if (muxc->mux_locked)
   340			priv->adap.lock_ops = &i2c_mux_lock_ops;
   341		else
   342			priv->adap.lock_ops = &i2c_parent_lock_ops;
   343	
   344		/* Sanity check on class */
   345		if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED)
   346			dev_err(&parent->dev,
   347				"Segment %d behind mux can't share classes with ancestors\n",
   348				chan_id);
   349		else
   350			priv->adap.class = class;
   351	
   352		/*
   353		 * Try to populate the mux adapter's of_node, expands to
   354		 * nothing if !CONFIG_OF.
   355		 */
   356		if (muxc->dev->of_node) {
   357			struct device_node *dev_node = muxc->dev->of_node;
   358			struct device_node *mux_node, *child = NULL;
   359			u32 reg;
   360	
   361			if (muxc->arbitrator)
   362				mux_node = of_get_child_by_name(dev_node, "i2c-arb");
   363			else if (muxc->gate)
   364				mux_node = of_get_child_by_name(dev_node, "i2c-gate");
   365			else
   366				mux_node = of_get_child_by_name(dev_node, "i2c-mux");
   367	
   368			if (mux_node) {
   369				/* A "reg" property indicates an old-style DT entry */
   370				if (!of_property_read_u32(mux_node, "reg", &reg)) {
   371					of_node_put(mux_node);
   372					mux_node = NULL;
   373				}
   374			}
   375	
   376			if (!mux_node)
   377				mux_node = of_node_get(dev_node);
   378			else if (muxc->arbitrator || muxc->gate)
   379				child = of_node_get(mux_node);
   380	
   381			if (!child) {
   382				for_each_child_of_node(mux_node, child) {
   383					ret = of_property_read_u32(child, "reg", &reg);
   384					if (ret)
   385						continue;
   386					if (chan_id == reg)
   387						break;
   388				}
   389			}
   390	
   391			priv->adap.dev.of_node = child;
   392			of_node_put(mux_node);
   393		}
   394	
   395		/*
   396		 * Associate the mux channel with an ACPI node.
   397		 */
   398		if (has_acpi_companion(muxc->dev))
   399			acpi_preset_companion(&priv->adap.dev,
   400					      ACPI_COMPANION(muxc->dev),
   401					      chan_id);
   402	
   403		if (force_nr) {
   404			priv->adap.nr = force_nr;
   405			ret = i2c_add_numbered_adapter(&priv->adap);
   406			if (ret < 0) {
   407				dev_err(&parent->dev,
   408					"failed to add mux-adapter %u as bus %u (error=%d)\n",
   409					chan_id, force_nr, ret);
   410				goto err_free_priv;
   411			}
   412		} else {
   413			ret = i2c_add_adapter(&priv->adap);
   414			if (ret < 0) {
   415				dev_err(&parent->dev,
   416					"failed to add mux-adapter %u (error=%d)\n",
   417					chan_id, ret);
   418				goto err_free_priv;
   419			}
   420		}
   421	
   422		WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
   423				       "mux_device"),
   424		     "can't create symlink to mux device\n");
   425	
   426		snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id);
   427		WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
   428				       symlink_name),
   429		     "can't create symlink to channel %u\n", chan_id);
   430		dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
   431			 i2c_adapter_id(&priv->adap));
   432	
   433		if (muxc->register_spd)
 > 434			i2c_register_spd(&priv->adap);
   435	
   436		muxc->adapter[muxc->num_adapters++] = &priv->adap;
   437		return 0;
   438	
   439	err_free_priv:
   440		kfree(priv);
   441		return ret;
   442	}
   443	EXPORT_SYMBOL_GPL(i2c_mux_add_adapter);
   444
kernel test robot Jan. 13, 2024, 8:38 a.m. UTC | #2
Hi Heiner,

kernel test robot noticed the following build errors:

[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on next-20240112]
[cannot apply to linus/master v6.7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Heiner-Kallweit/i2c-smbus-Prepare-i2c_register_spd-for-usage-on-muxed-segments/20240111-042152
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
patch link:    https://lore.kernel.org/r/53e5c71a-d954-4211-91a1-de067451d532%40gmail.com
patch subject: [PATCH 2/4] i2c: mux: add basic support for calling i2c_register_spd on muxed bus segments
config: loongarch-randconfig-001-20240111 (https://download.01.org/0day-ci/archive/20240113/202401131601.Qe16pupf-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240113/202401131601.Qe16pupf-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401131601.Qe16pupf-lkp@intel.com/

All errors (new ones prefixed by >>):

   loongarch64-linux-ld: drivers/i2c/i2c-mux.o: in function `.L155':
>> i2c-mux.c:(.text+0xc84): undefined reference to `i2c_register_spd'
diff mbox series

Patch

diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 57ff09f18..ada9c764f 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -22,6 +22,7 @@ 
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
+#include <linux/i2c-smbus.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -429,6 +430,9 @@  int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 	dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
 		 i2c_adapter_id(&priv->adap));
 
+	if (muxc->register_spd)
+		i2c_register_spd(&priv->adap);
+
 	muxc->adapter[muxc->num_adapters++] = &priv->adap;
 	return 0;
 
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index 98ef73b7c..ec51d9bc4 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -21,6 +21,7 @@  struct i2c_mux_core {
 	unsigned int mux_locked:1;
 	unsigned int arbitrator:1;
 	unsigned int gate:1;
+	unsigned int register_spd:1;
 
 	void *priv;