#include <linux/module.h>
 #include <linux/mtd/partitions.h>
 #include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
 #include <linux/pci.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #define CP500_NUM_MSIX_NO_AXI  3
 
 /* EEPROM */
-#define CP500_HW_CPU_EEPROM_NAME       "cp500_cpu_eeprom"
 #define CP500_EEPROM_DA_OFFSET         0x016F
 #define CP500_EEPROM_DA_ESC_TYPE_MASK  0x01
 #define CP500_EEPROM_ESC_LAN9252       0x00
 #define CP500_EEPROM_ESC_ET1100                0x01
+#define CP500_EEPROM_CPU_NAME          "cpu_eeprom"
+#define CP500_EEPROM_CPU_OFFSET                0
+#define CP500_EEPROM_CPU_SIZE          3072
+#define CP500_EEPROM_USER_NAME         "user_eeprom"
+#define CP500_EEPROM_USER_OFFSET       3072
+#define CP500_EEPROM_USER_SIZE         1024
 
 /* SPI flash running at full speed */
 #define CP500_FLASH_HZ         (33 * 1000 * 1000)
        .i2c     = { 0x5000, SZ_4K },
 };
 
+struct cp500_nvmem {
+       struct nvmem_device *nvmem;
+       unsigned int offset;
+};
+
 struct cp500 {
        struct pci_dev *pci_dev;
        struct cp500_devs *devs;
        /* ECM EtherCAT BAR */
        resource_size_t ecm_hwbase;
 
+       /* NVMEM devices */
+       struct cp500_nvmem nvmem_cpu;
+       struct cp500_nvmem nvmem_user;
+
        void __iomem *system_startup_addr;
 };
 
                 * CP520 family: carrier board
                 */
                I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR),
-               .dev_name = CP500_HW_CPU_EEPROM_NAME,
        },
        {       /* interface board EEPROM */
                I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 1),
        return 0;
 }
 
+static int cp500_nvmem_read(void *priv, unsigned int offset, void *val,
+                           size_t bytes)
+{
+       struct cp500_nvmem *nvmem = priv;
+       int ret;
+
+       ret = nvmem_device_read(nvmem->nvmem, nvmem->offset + offset, bytes,
+                               val);
+       if (ret != bytes)
+               return ret;
+
+       return 0;
+}
+
+static int cp500_nvmem_write(void *priv, unsigned int offset, void *val,
+                            size_t bytes)
+{
+       struct cp500_nvmem *nvmem = priv;
+       int ret;
+
+       ret = nvmem_device_write(nvmem->nvmem, nvmem->offset + offset, bytes,
+                                val);
+       if (ret != bytes)
+               return ret;
+
+       return 0;
+}
+
+static int cp500_nvmem_register(struct cp500 *cp500, struct nvmem_device *nvmem)
+{
+       struct device *dev = &cp500->pci_dev->dev;
+       struct nvmem_config nvmem_config = {};
+       struct nvmem_device *tmp;
+
+       /*
+        * The main EEPROM of CP500 devices is logically split into two EEPROMs.
+        * The first logical EEPROM with 3 kB contains the type label which is
+        * programmed during production of the device. The second logical EEPROM
+        * with 1 kB is not programmed during production and can be used for
+        * arbitrary user data.
+        */
+
+       nvmem_config.dev = dev;
+       nvmem_config.owner = THIS_MODULE;
+       nvmem_config.id = NVMEM_DEVID_NONE;
+       nvmem_config.type = NVMEM_TYPE_EEPROM;
+       nvmem_config.root_only = true;
+       nvmem_config.reg_read = cp500_nvmem_read;
+       nvmem_config.reg_write = cp500_nvmem_write;
+
+       cp500->nvmem_cpu.nvmem = nvmem;
+       cp500->nvmem_cpu.offset = CP500_EEPROM_CPU_OFFSET;
+       nvmem_config.name = CP500_EEPROM_CPU_NAME;
+       nvmem_config.size = CP500_EEPROM_CPU_SIZE;
+       nvmem_config.priv = &cp500->nvmem_cpu;
+       tmp = devm_nvmem_register(dev, &nvmem_config);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
+
+       cp500->nvmem_user.nvmem = nvmem;
+       cp500->nvmem_user.offset = CP500_EEPROM_USER_OFFSET;
+       nvmem_config.name = CP500_EEPROM_USER_NAME;
+       nvmem_config.size = CP500_EEPROM_USER_SIZE;
+       nvmem_config.priv = &cp500->nvmem_user;
+       tmp = devm_nvmem_register(dev, &nvmem_config);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
+
+       return 0;
+}
+
 static int cp500_nvmem_match(struct device *dev, const void *data)
 {
        const struct cp500 *cp500 = data;
        return 0;
 }
 
+static void cp500_devm_nvmem_put(void *data)
+{
+       struct nvmem_device *nvmem = data;
+
+       nvmem_device_put(nvmem);
+}
+
 static int cp500_nvmem(struct notifier_block *nb, unsigned long action,
                       void *data)
 {
                return NOTIFY_DONE;
        }
 
+       ret = devm_add_action_or_reset(dev, cp500_devm_nvmem_put, nvmem);
+       if (ret)
+               return ret;
+
+       ret = cp500_nvmem_register(cp500, nvmem);
+       if (ret)
+               return ret;
+
        ret = nvmem_device_read(nvmem, CP500_EEPROM_DA_OFFSET, sizeof(esc_type),
                                (void *)&esc_type);
-       nvmem_device_put(nvmem);
        if (ret != sizeof(esc_type)) {
                dev_warn(dev, "Failed to read device assembly!\n");