All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFT] i2c: i801: Call i2c_register_spd for muxed child segments
@ 2024-03-05 20:28 Heiner Kallweit
  0 siblings, 0 replies; only message in thread
From: Heiner Kallweit @ 2024-03-05 20:28 UTC (permalink / raw)
  To: linux-i2c, Linux Kernel Mailing List; +Cc: Wolfram Sang

So far i2c_register_spd() is supported only on systems with up to
8 memory slots. Reason is that on a single SMBus only 8 SPD EEPROMS
can be addressed. The following patch adds support for calling
i2c_register_spd() on multiplexed SMBUS segments.

Out-of-the-box only certain ASUS Z8 systems are supported.
See mux_dmi_table[] in the i801 driver.
These systems seem to be quite rare nowadays, so I'd appreciate
if the owner of such a system could test the patch.

For each DIMM module a message like the following should appear in dmesg.
i2c i2c-11: Successfully instantiated SPD at 0x50
A response including the full dmesg log would be perfect.

For other systems with >8 memory slots, where the SMBUS is GPIO-muxed,
it should be possible to add an appropriate entry to mux_dmi_table[].
Then the patch should work as expected on such a system too.

Note: This patch is applicable only after 8821c8376993 ("i2c: smbus:
Prepare i2c_register_spd for usage on muxed segments").
This patch showed up in linux-next from March 5th 2024.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/i2c/busses/i2c-i801.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 8f225cd7b..4b9d04f20 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -105,6 +105,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/i2c-mux.h>
 #include <linux/i2c-smbus.h>
 #include <linux/acpi.h>
 #include <linux/io.h>
@@ -291,6 +292,7 @@ struct i801_priv {
 #if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
 	struct platform_device *mux_pdev;
 	struct gpiod_lookup_table *lookup;
+	struct notifier_block mux_notifier_block;
 #endif
 	struct platform_device *tco_pdev;
 
@@ -1388,6 +1390,23 @@ static const struct dmi_system_id mux_dmi_table[] = {
 	{ }
 };
 
+static int i801_notifier_call(struct notifier_block *nb, unsigned long action,
+			      void *data)
+{
+	struct i801_priv *priv = container_of(nb, struct i801_priv, mux_notifier_block);
+	struct device *dev = data;
+
+	if (action != BUS_NOTIFY_ADD_DEVICE ||
+	    dev->type != &i2c_adapter_type ||
+	    i2c_root_adapter(dev) != &priv->adapter)
+		return NOTIFY_DONE;
+
+	/* Call i2c_register_spd for muxed child segments */
+	i2c_register_spd(to_i2c_adapter(dev));
+
+	return NOTIFY_OK;
+}
+
 /* Setup multiplexing if needed */
 static void i801_add_mux(struct i801_priv *priv)
 {
@@ -1425,6 +1444,9 @@ static void i801_add_mux(struct i801_priv *priv)
 	gpiod_add_lookup_table(lookup);
 	priv->lookup = lookup;
 
+	priv->mux_notifier_block.notifier_call = i801_notifier_call;
+	if (bus_register_notifier(&i2c_bus_type, &priv->mux_notifier_block))
+		return;
 	/*
 	 * Register the mux device, we use PLATFORM_DEVID_NONE here
 	 * because since we are referring to the GPIO chip by name we are
@@ -1443,6 +1465,7 @@ static void i801_add_mux(struct i801_priv *priv)
 
 static void i801_del_mux(struct i801_priv *priv)
 {
+	bus_unregister_notifier(&i2c_bus_type, &priv->mux_notifier_block);
 	platform_device_unregister(priv->mux_pdev);
 	gpiod_remove_lookup_table(priv->lookup);
 }
-- 
2.44.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-05 20:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-05 20:28 [PATCH RFT] i2c: i801: Call i2c_register_spd for muxed child segments Heiner Kallweit

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.