2024-01-27 14:08:15

by Nico Coesel

[permalink] [raw]
Subject: Patch to allow hot-plugging Atmel AT24 eeproms

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