Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: rt2x00: add nvmem eeprom support

Some embedded platforms have eeproms located in flash. Add nvmem support
to handle this. Support is added for PCI and SOC backends.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20251027180639.3797-1-rosenp@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Rosen Penev and committed by
Johannes Berg
ec81b33b db82ddea

+41 -1
+31
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
··· 24 24 #include <linux/crc-ccitt.h> 25 25 #include <linux/kernel.h> 26 26 #include <linux/module.h> 27 + #include <linux/nvmem-consumer.h> 27 28 #include <linux/slab.h> 28 29 29 30 #include "rt2x00.h" ··· 10962 10961 return 0; 10963 10962 } 10964 10963 EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); 10964 + 10965 + int rt2800_read_eeprom_nvmem(struct rt2x00_dev *rt2x00dev) 10966 + { 10967 + struct device_node *np = rt2x00dev->dev->of_node; 10968 + unsigned int len = rt2x00dev->ops->eeprom_size; 10969 + struct nvmem_cell *cell; 10970 + const void *data; 10971 + size_t retlen; 10972 + 10973 + cell = of_nvmem_cell_get(np, "eeprom"); 10974 + if (IS_ERR(cell)) 10975 + return PTR_ERR(cell); 10976 + 10977 + data = nvmem_cell_read(cell, &retlen); 10978 + nvmem_cell_put(cell); 10979 + 10980 + if (IS_ERR(data)) 10981 + return PTR_ERR(data); 10982 + 10983 + if (retlen != len) { 10984 + dev_err(rt2x00dev->dev, "invalid eeprom size, required: 0x%04x\n", len); 10985 + kfree(data); 10986 + return -EINVAL; 10987 + } 10988 + 10989 + memcpy(rt2x00dev->eeprom, data, len); 10990 + kfree(data); 10991 + return 0; 10992 + } 10993 + EXPORT_SYMBOL_GPL(rt2800_read_eeprom_nvmem); 10965 10994 10966 10995 static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev) 10967 10996 {
+2
drivers/net/wireless/ralink/rt2x00/rt2800lib.h
··· 248 248 int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); 249 249 int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); 250 250 251 + int rt2800_read_eeprom_nvmem(struct rt2x00_dev *rt2x00dev); 252 + 251 253 int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); 252 254 253 255 void rt2800_get_key_seq(struct ieee80211_hw *hw,
+3
drivers/net/wireless/ralink/rt2x00/rt2800pci.c
··· 278 278 { 279 279 int retval; 280 280 281 + if (!rt2800_read_eeprom_nvmem(rt2x00dev)) 282 + return 0; 283 + 281 284 if (rt2800pci_efuse_detect(rt2x00dev)) 282 285 retval = rt2800pci_read_eeprom_efuse(rt2x00dev); 283 286 else
+5 -1
drivers/net/wireless/ralink/rt2x00/rt2800soc.c
··· 92 92 93 93 static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) 94 94 { 95 - void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); 95 + void __iomem *base_addr; 96 96 97 + if (!rt2800_read_eeprom_nvmem(rt2x00dev)) 98 + return 0; 99 + 100 + base_addr = ioremap(0x1F040000, EEPROM_SIZE); 97 101 if (!base_addr) 98 102 return -ENOMEM; 99 103