diff --git a/README.md b/README.md
index 3c7b9e12ce58e12a267d2d805a813a83ee1b7cb7..c5ff6cc9c416ceab9b45aa216b17daa2eec0c96f 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,3 @@ errors during installation) in the following distributions:
 However, there is no guarantee that things will properly work on these distributions, once
 installed. In particular, there is a known issue with DMA transfers causing a kernel crash, which
 prohibits for example the retrieval of ADC samples from the FMC-ADC-100M.
-
-There is also another known issue with Linux kernels > v5.0. Due to a significant change in the at24
-driver, it is no longer possible to access the SPEC/SVEC/FMC EEPROMs. The drivers have been modified
-to bypass this issue and continue working when used with such a kernel, but the EEPROM will still
-not be accessible.
diff --git a/patches/fmc-sw.diff b/patches/fmc-sw.diff
index f5cc6f76ea70f7e13a7651fed63d30b54d604f84..4272729abb20debda32975a48e6899fe4fcbaff5 100644
--- a/patches/fmc-sw.diff
+++ b/patches/fmc-sw.diff
@@ -1,8 +1,12 @@
 diff --git a/drivers/fmc/fmc-eeprom.c b/drivers/fmc/fmc-eeprom.c
-index a000a0d..e5f96b2 100644
+index a000a0d..2bd2a6f 100644
 --- a/drivers/fmc/fmc-eeprom.c
 +++ b/drivers/fmc/fmc-eeprom.c
-@@ -10,6 +10,10 @@
+@@ -7,9 +7,14 @@
+ #include <linux/module.h>
+ #include <linux/memory.h>
+ #include <linux/fmc.h>
++#include <linux/slab.h>
  #include "fmc-internal.h"
  #include "fmc-compat.h"
  
@@ -13,49 +17,31 @@ index a000a0d..e5f96b2 100644
  #define FRU_EEPROM_NAME "fru_eeprom"
  
  /**
-@@ -17,12 +21,37 @@
+@@ -17,11 +22,14 @@
   */
  #define FMC_EEPROM_TYPE_DEFAULT "24c02"
  
-+#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
-+/* static int fmc_slot_eeprom_setup(struct notifier_block *nb, */
-+/* 				 unsigned long event, void *data) */
-+/* { */
-+/* 	struct nvmem_device *nvmem = data; */
-+
-+/* 	//dev_err(&nvmem->dev, "friendly notifier, action %ld\n", event); */
-+/* 	if (strcmp(nvmem_dev_name(nvmem), "1-00500") != 0) */
-+/* 		return NOTIFY_DONE; */
-+
-+/* 	return NOTIFY_OK; */
-+/* }; */
-+
-+/* static struct notifier_block fmc_eeprom_nvmem_notifier = { */
-+/* 	.notifier_call = fmc_slot_eeprom_setup, */
-+/* }; */
-+struct property_entry at24_properties[] = {
+-/**
+- * Setup function for the AT24C02 EEPROM. What we need to do here is to
+- * quickly validate the EEPROM content. The EEPROM should contain a valid
+- * FRU.
+- */
++#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
++const struct property_entry at24_24c02[AT24_NUM_PROPERTIES] = {
++	PROPERTY_ENTRY_U32("size", 256),
 +	PROPERTY_ENTRY_U32("pagesize", 8),
++	PROPERTY_ENTRY_U32("address-width", 16),
 +	{ }
 +};
-+#else
- /**
-  * Setup function for the AT24C02 EEPROM. What we need to do here is to
-  * quickly validate the EEPROM content. The EEPROM should contain a valid
-  * FRU.
-  */
-+#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
-+static void fmc_slot_eeprom_setup(struct nvmem_device *macc, void *context)
 +#else
  static void fmc_slot_eeprom_setup(struct memory_accessor *macc, void *context)
-+#endif
  {
  	struct fmc_slot *slot = context;
- 
-@@ -38,17 +67,26 @@ static const struct at24_platform_data at24_24c02 = {
+@@ -38,9 +46,10 @@ static const struct at24_platform_data at24_24c02 = {
  	.flags = 0,
  	.setup = fmc_slot_eeprom_setup,
  };
-+#endif /* KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE */
++#endif /* KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE */
  
  /**
 - * Initialize I2C EEPROM info with standad values
@@ -63,68 +49,92 @@ index a000a0d..e5f96b2 100644
   */
  static void fmc_slot_eeprom_init(struct fmc_slot *slot,
  				 struct i2c_board_info *info,
- 				 const char *name)
+@@ -48,7 +57,11 @@ static void fmc_slot_eeprom_init(struct fmc_slot *slot,
  {
-+#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
-+        struct property_entry **p_entry;
-+#endif
  	strncpy(info->type, name, I2C_NAME_SIZE);
  	info->addr = FMC_EEPROM_ADDR_SPACE;
-+#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
-+	p_entry = (struct property_entry **)&info->properties;
-+	*p_entry = at24_properties;
++#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
++	info->properties = slot->at24_data;
 +#else
  	info->platform_data = &slot->at24_data;
 +#endif
  }
  
  static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
-@@ -56,8 +94,12 @@ static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
+@@ -56,8 +69,12 @@ static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
  {
  	memset(info, 0, sizeof(*info));
  	fmc_slot_eeprom_init(slot, info, FMC_EEPROM_TYPE_DEFAULT);
-+#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
++#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
  	memcpy(&slot->at24_data, &at24_24c02, sizeof(slot->at24_data));
  	slot->at24_data.context = slot;
-+/* #else */
-+/* 	nvmem_register_notifier(&fmc_eeprom_nvmem_notifier); */
++#else
++	memcpy(slot->at24_data, &at24_24c02, sizeof(slot->at24_data));
 +#endif
  }
  
  /**
-@@ -70,9 +112,15 @@ ssize_t fmc_slot_eeprom_read(struct fmc_slot *slot,
+@@ -66,13 +83,41 @@ static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
+ ssize_t fmc_slot_eeprom_read(struct fmc_slot *slot,
+ 			     void *buf, off_t offset, size_t count)
+ {
++	int err = 0;
++#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
++	int idx;
++	size_t len;
++	struct nvmem_device *nvmem;
++	char *nvmem_name;
++	/* 
++	 * TODO Check if index can be anything else than zero and,
++	 * if yes, how to get the proper value.
++	 */
++	idx = 0;
++	len = strlen(dev_name(&slot->eeprom->dev)) + 2;
++	nvmem_name = kzalloc(len, GFP_KERNEL);
++	if (nvmem_name) {
++		snprintf(nvmem_name, len, "%s%d",
++			 dev_name(&slot->eeprom->dev), idx);
++		nvmem = nvmem_device_get(&slot->dev, nvmem_name);
++		if (nvmem) {
++			err = nvmem_device_read(nvmem, offset, count, buf);
++#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
++			nvmem_device_put(nvmem);
++#endif
++		}
++		kfree(nvmem_name);
++	}
++#else
+ 	/*
  	 * TODO if we export this function, do we have to lock it when we
  	 * use it? Think about it
  	 */
--	if (!slot->macc || !slot->macc->read)
-+	if (!slot->macc)
-+		return -ENODEV;
-+#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
-+	return nvmem_device_read(slot->macc, offset, count, buf);
-+#else
-+	if (!slot->macc->read)
+ 	if (!slot->macc || !slot->macc->read)
  		return -ENODEV;
- 	return slot->macc->read(slot->macc, buf, offset, count);
+-	return slot->macc->read(slot->macc, buf, offset, count);
++	err = slot->macc->read(slot->macc, buf, offset, count);
 +#endif
++	return err;
  }
  EXPORT_SYMBOL(fmc_slot_eeprom_read);
  
-@@ -176,6 +224,9 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
- 	struct i2c_board_info i2c_info;
- 	unsigned int len;
- 	int ret;
-+#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
-+	struct property_entry *p_entry;
+@@ -152,7 +197,9 @@ void fmc_slot_eeprom_del(struct fmc_slot *slot)
+ 	sysfs_remove_link(&slot->dev.kobj, FRU_EEPROM_NAME);
+ 	i2c_unregister_device(slot->eeprom);
+ 	slot->eeprom = NULL;
++#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
+ 	slot->macc = NULL;
 +#endif
+ }
  
- 	if (strncmp(type, "24c", 3)) {
- 		if (strncmp(type, "at24c", 5)) {
-@@ -197,19 +248,24 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
+ /**
+@@ -197,19 +244,25 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
  
  
  	memset(&i2c_info, 0, sizeof(i2c_info));
-+#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
++#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
  	memset(&slot->at24_data, 0, sizeof(slot->at24_data));
++#else
++	memset(slot->at24_data, 0, sizeof(slot->at24_data));
 +#endif
  
  	len = (len * 1024) / 8;
@@ -137,26 +147,27 @@ index a000a0d..e5f96b2 100644
 -	else if (len > 131072) /* 1024K 128KiB */
 +	if (len > 131072) /* 1024K 128KiB */
  		return -EINVAL;
-+#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
-+	else if (len > 4096) /* 32K 4KiB */
-+		slot->at24_data.flags = AT24_FLAG_ADDR16;
-+#endif
  
  	fmc_slot_eeprom_init(slot, &i2c_info, type);
-+#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
++
++#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
++	if (len > 4096) /* 32K 4KiB */
++		slot->at24_data.flags = AT24_FLAG_ADDR16;
  	slot->at24_data.byte_len = len;
  	slot->at24_data.page_size = 1; /* 1Byte page to play safe */
  	slot->at24_data.setup = fmc_slot_eeprom_setup;
-@@ -219,7 +275,12 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
+@@ -219,7 +272,15 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
  		i2c_info.type, i2c_info.addr,
  		slot->at24_data.byte_len, slot->at24_data.page_size,
  		slot->at24_data.flags);
--
 +#else
-+        p_entry = (struct property_entry *)i2c_info.properties;
-+        p_entry[0] = PROPERTY_ENTRY_U32("pagesize", 1);
-+	dev_dbg(&slot->dev, "%s 0x%x\n",
-+		i2c_info.type, i2c_info.addr);
++	slot->at24_data[0] = PROPERTY_ENTRY_U32("size", len);
++	slot->at24_data[1] = PROPERTY_ENTRY_U32("pagesize", 1);
++	if (len > 4096) /* 32K 4KiB */
++		slot->at24_data[2] = PROPERTY_ENTRY_U32("address-width", 16);
+ 
++	dev_dbg(&slot->dev, "%s 0x%x %d\n",
++		i2c_info.type, i2c_info.addr, len);
 +#endif
  	return fmc_slot_eeprom_replace(slot, &i2c_info);
  }
@@ -185,7 +196,7 @@ index 35a1380..2fd95eb 100644
 -
 -#endif
 diff --git a/include/linux/fmc.h b/include/linux/fmc.h
-index 3bc5c12..f99886c 100644
+index 3bc5c12..7fd835f 100644
 --- a/include/linux/fmc.h
 +++ b/include/linux/fmc.h
 @@ -11,13 +11,13 @@
@@ -204,16 +215,15 @@ index 3bc5c12..f99886c 100644
  
  #ifndef _LINUX_FMC_H
  #define _LINUX_FMC_H
-@@ -84,8 +84,14 @@ struct fmc_slot {
+@@ -84,8 +84,13 @@ struct fmc_slot {
  
  	struct i2c_client *eeprom;
  
 +#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
-+	struct nvmem_device *macc;
++#define AT24_NUM_PROPERTIES 4
++	struct property_entry at24_data[AT24_NUM_PROPERTIES];
 +#else
  	struct memory_accessor *macc;
-+#endif
-+#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
  	struct at24_platform_data at24_data;
 +#endif
  };