Patch to allow hot-plugging Atmel AT24 eeproms

From: Nico Coesel
Date: Sat Jan 27 2024 - 09:08:13 EST


Hello,
I'm working on an embedded project which uses SFPs (hot-pluggable optical network interface modules) which have two Atmel 'AT24' compatible eeproms inside. I wanted to be able to read the contents of the eeproms through the nvme subsystem as a file so the higher level software doesn't need to mess with I2C and all.

I tried to use the at24 driver but it tests if the device is present or not. Since the device may not be present, this behaviour is not suitable for the project I'm working on. The patch below (against kernel version 5.4.142) adds a hotplug flag so the 'device present' test is skipped and the device is added nevertheless. The behaviour is controlled by an extra device property called 'hotplug'.


diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 2cccd82..c4e9cf3 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -24,6 +24,9 @@
 #include <linux/pm_runtime.h>
 #include <linux/gpio/consumer.h>

+//NC: Added flag to support devices not being preseny
+#define AT24_FLAG_HOTPLUG    BIT(8)
+
 /* Address pointer is 16 bit. */
 #define AT24_FLAG_ADDR16    BIT(7)
 /* sysfs-entry will be read-only. */
@@ -592,6 +595,10 @@
     if (device_property_present(dev, "no-read-rollover"))
         flags |= AT24_FLAG_NO_RDROL;

+    //NC: Add hotplug flag. This skips device detection
+    if (device_property_present(dev, "hotplug"))
+        flags |= AT24_FLAG_HOTPLUG;
+
     err = device_property_read_u32(dev, "address-width", &addrw);
     if (!err) {
         switch (addrw) {
@@ -709,11 +716,14 @@
      * Perform a one-byte test read to verify that the
      * chip is functional.
      */
-    err = at24_read(at24, 0, &test_byte, 1);
-    pm_runtime_idle(dev);
-    if (err) {
-        pm_runtime_disable(dev);
-        return -ENODEV;
+    if ((flags & AT24_FLAG_HOTPLUG) ==0)
+        {
+        err = at24_read(at24, 0, &test_byte, 1);
+        pm_runtime_idle(dev);
+        if (err) {
+            pm_runtime_disable(dev);
+            return -ENODEV;
+        }
     }

     dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n",

I used the device tree snippet from below:

    sfp1_info: eeprom@50 {
        compatible = "atmel,24c02";
        reg = <0x50>;
        read-only;
        pagesize = <1>;
        hotplug;
    };

I hope this can be of use to somebody.

Regards,
Nico Coesel

--
o---------------------------------------------------------------o
| N C T Developments |
|Innovative embedded solutions |
o---------------------------------------------------------------o