From 4f8715bdbf4cad3aef63d0189e48f675dbee1f73 Mon Sep 17 00:00:00 2001 From: Martin Kennedy Date: Tue, 16 Feb 2021 02:05:16 +0000 Subject: [PATCH] Add further patches --- ...ee_node_to_memory_accessor_functions.patch | 310 ++++++++++++++++++ ...or_functions_with_of_memory_accessor.patch | 43 +++ 2 files changed, 353 insertions(+) create mode 100644 target/linux/octeon/patches-5.4/0002-Add_of_memory_accessor_to_map_device_tree_node_to_memory_accessor_functions.patch create mode 100644 target/linux/octeon/patches-5.4/0003-register_memory_accessor_functions_with_of_memory_accessor.patch diff --git a/target/linux/octeon/patches-5.4/0002-Add_of_memory_accessor_to_map_device_tree_node_to_memory_accessor_functions.patch b/target/linux/octeon/patches-5.4/0002-Add_of_memory_accessor_to_map_device_tree_node_to_memory_accessor_functions.patch new file mode 100644 index 0000000000..6f9e48fbfb --- /dev/null +++ b/target/linux/octeon/patches-5.4/0002-Add_of_memory_accessor_to_map_device_tree_node_to_memory_accessor_functions.patch @@ -0,0 +1,310 @@ +From: Abhishek Paliwal +Date: Fri, 13 Feb 2015 12:47:36 +0530 +Subject: of: Add of_memory_accessor to map device tree node to memory accessor + functions. + +From: Aaron Williams + +Currently there is no easy way to map a device tree node to a memory +accessor function for devices like I2C EEPROMs. For example, the Vitesse +vsc848x 10G PHY driver needs to be able to use the I2C at24 serial EEPROM +memory accessor function in order to read the SFP+ eeprom. + +This provides a way where the vsc848x module can parse its device tree and +easily gain the accessor functions for the eeprom through a phandle. + +This may be useful for any module which provides memory accessor functions. + +Signed-off-by: Aaron Williams +Signed-off-by: Leonid Rosenboim +Signed-off-by: Abhishek Paliwal +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -75,4 +75,11 @@ config OF_MTD + depends on MTD + def_bool y + ++config OF_MEMORY_ACCESSOR ++ def_bool y ++ depends on OF_I2C || OF_SPI ++ help ++ OpenFirmware memory accessor support for accessing devices like ++ i2c and SPI eeproms. ++ + endmenu # OF +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o + obj-$(CONFIG_OF_PCI) += of_pci.o + obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o + obj-$(CONFIG_OF_MTD) += of_mtd.o ++obj-$(CONFIG_OF_MEMORY_ACCESSOR) += of_memory_accessor.o +--- /dev/null ++++ b/drivers/of/of_memory_accessor.c +@@ -0,0 +1,192 @@ ++/* ++ * Memory accessor OF helpers ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Cavium Inc. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct of_macc_entry { ++ struct list_head list; ++ struct device *dev; ++ struct memory_accessor *macc; ++ int ref; ++}; ++ ++static DEFINE_MUTEX(lock); ++static LIST_HEAD(macc_list); ++ ++/** ++ * Adds a mapping of a device node to a memory accessor ++ * ++ * @param[in] dev - device ++ * @param[in] macc - memory accessor ++ * ++ * @returns 0 for success or -ENOMEM ++ */ ++int of_memory_accessor_register(struct device *dev, ++ struct memory_accessor *macc) ++{ ++ struct of_macc_entry *mentry; ++ ++ mentry = kmalloc(sizeof(*mentry), GFP_KERNEL); ++ if (mentry == NULL) ++ return -ENOMEM; ++ ++ mentry->dev = dev; ++ mentry->macc = macc; ++ mentry->ref = 0; ++ ++ mutex_lock(&lock); ++ ++ list_add(&(mentry->list), &macc_list); ++ ++ mutex_unlock(&lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL(of_memory_accessor_register); ++ ++/** ++ * removes the mapping of a device node to a memory accessor ++ * ++ * @param[in] devnode - device node to remove ++ * ++ * @returns 0 for success or -ENODEV if device node not found, -EBUSY if still ++ * in use ++ */ ++ ++int of_memory_accessor_remove(struct device *dev) ++{ ++ struct of_macc_entry *mentry; ++ struct list_head *pos, *q; ++ int ret = -ENODEV; ++ ++ mutex_lock(&lock); ++ ++ list_for_each_safe(pos, q, &macc_list) { ++ mentry = list_entry(pos, struct of_macc_entry, list); ++ if (mentry->dev == dev) { ++ if (mentry->ref > 0) { ++ ret = -EBUSY; ++ goto done; ++ } ++ list_del(pos); ++ kfree(mentry); ++ ret = 0; ++ goto done; ++ } ++ } ++ ++ /* Not found */ ++done: ++ mutex_unlock(&lock); ++ return ret; ++} ++EXPORT_SYMBOL(of_memory_accessor_remove); ++ ++/** ++ * Returns the memory accessor for a device node and increments a reference ++ * count ++ * ++ * @param[in] devnode - device node to look up ++ * ++ * @returns memory accessor for device node or NULL if none found. ++ */ ++struct memory_accessor * ++of_memory_accessor_get(const struct device_node *devnode) ++{ ++ struct of_macc_entry *mentry; ++ struct list_head *pos; ++ struct memory_accessor *macc = NULL; ++ ++ mutex_lock(&lock); ++ ++ list_for_each(pos, &macc_list) { ++ mentry = list_entry(pos, struct of_macc_entry, list); ++ if (mentry->dev->of_node == devnode) { ++ macc = mentry->macc; ++ if (!mentry->ref) { ++ if (!try_module_get(mentry->dev->driver->owner)) { ++ macc = NULL; ++ pr_info("Warning: module for %s not found!", ++ mentry->dev->of_node->full_name); ++ } ++ } ++ mentry->ref++; ++ goto done; ++ } ++ } ++done: ++ mutex_unlock(&lock); ++ return macc; ++} ++EXPORT_SYMBOL(of_memory_accessor_get); ++ ++/** ++ * Decrements the reference count for the memory accessor attached to the ++ * device node. ++ * ++ * @param[in] devnode - device node to look up ++ * ++ * @returns 0 for success or -ENODEV if the device node was not found. ++ */ ++int of_memory_accessor_put(const struct device_node *devnode) ++{ ++ struct of_macc_entry *mentry; ++ struct list_head *pos; ++ int ret = -ENODEV; ++ ++ mutex_lock(&lock); ++ list_for_each(pos, &macc_list) { ++ mentry = list_entry(pos, struct of_macc_entry, list); ++ if (mentry->dev->of_node == devnode) { ++ if (mentry->ref > 0) ++ mentry->ref--; ++ if (!mentry->ref) ++ module_put(mentry->dev->driver->owner); ++ ++ module_put(THIS_MODULE); ++ ret = 0; ++ goto done; ++ } ++ } ++done: ++ mutex_unlock(&lock); ++ return ret; ++} ++EXPORT_SYMBOL(of_memory_accessor_put); ++ ++static void __exit of_memory_accessor_exit(void) ++{ ++ struct of_macc_entry *mentry; ++ struct list_head *pos, *q; ++ ++ list_for_each_safe(pos, q, &macc_list) { ++ mentry = list_entry(pos, struct of_macc_entry, list); ++ if (mentry->ref) ++ module_put(mentry->dev->driver->owner); ++ list_del(pos); ++ kfree(mentry); ++ } ++ ++ /* Not found */ ++ mutex_destroy(&lock); ++ list_del(&macc_list); ++} ++module_exit(of_memory_accessor_exit); ++ ++MODULE_DESCRIPTION("Driver for mapping device nodes to memory accessors"); ++MODULE_AUTHOR("Aaron Williams"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/include/linux/of_memory_accessor.h +@@ -0,0 +1,71 @@ ++#ifndef _LINUX_OF_MEMORY_ACCESSOR_H ++#define _LINUX_OF_MEMORY_ACCESSOR_H ++/* ++ * Memory accessor OF helpers ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Cavium Inc. ++ */ ++ ++#include ++#include ++ ++/** ++ * Adds a mapping of a device node to a memory accessor ++ * ++ * @param[in] dev - device ++ * @param[in] macc - memory accessor ++ * ++ * @returns 0 for success or -ENOMEM ++ */ ++#ifdef CONFIG_OF_MEMORY_ACCESSOR ++int of_memory_accessor_register(struct device *dev, ++ struct memory_accessor *macc); ++#else ++static inline int of_memory_accessor_register(struct device *dev, ++ struct memory_accessor *macc) ++{ ++ return 0; ++} ++#endif ++ ++/** ++ * removes the mapping of a device node to a memory accessor ++ * ++ * @param[in] devnode - device node to remove ++ * ++ * @returns 0 for success or 1 if device node not found ++ */ ++#ifdef CONFIG_OF_MEMORY_ACCESSOR ++int of_memory_accessor_remove(struct device *dev); ++#else ++static inline int of_memory_accessor_remove(struct device *dev) ++{ ++ return 0; ++} ++#endif ++ ++/** ++ * Returns the memory accessor for a device node ++ * ++ * @param[in] devnode - device node to look up ++ * ++ * @returns memory accessor for device node or NULL if none found. ++ */ ++struct memory_accessor * ++of_memory_accessor_get(const struct device_node *devnode); ++ ++/** ++ * Decrements the reference count for the memory accessor attached to the ++ * device node. ++ * ++ * @param[in] devnode - device node to look up ++ * ++ * @returns 0 for success or -1 if the device node was not found. ++ */ ++int of_memory_accessor_put(const struct device_node *devnode); ++ ++#endif /* _LINUX_OF_MEMORY_ACCESSOR_H */ diff --git a/target/linux/octeon/patches-5.4/0003-register_memory_accessor_functions_with_of_memory_accessor.patch b/target/linux/octeon/patches-5.4/0003-register_memory_accessor_functions_with_of_memory_accessor.patch new file mode 100644 index 0000000000..7a484210b8 --- /dev/null +++ b/target/linux/octeon/patches-5.4/0003-register_memory_accessor_functions_with_of_memory_accessor.patch @@ -0,0 +1,43 @@ +From: Abhishek Paliwal +Date: Fri, 13 Feb 2015 12:48:16 +0530 +Subject: misc/at24: Register memory accessor functions with of_memory_accessor + +From: Aaron Williams + +The at24 module will now register its memory accessor functions with its +device tree entry so that other modules may call these functions based on +the device tree node. + +Signed-off-by: Aaron Williams +Signed-off-by: Leonid Rosenboim +Signed-off-by: Abhishek Paliwal +--- a/drivers/misc/eeprom/at24.c ++++ b/drivers/misc/eeprom/at24.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + /* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. +@@ -637,6 +638,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) + if (chip.setup) + chip.setup(&at24->macc, chip.context); + ++ if (client->dev.of_node) ++ of_memory_accessor_register(&client->dev, &at24->macc); ++ + return 0; + + err_clients: +@@ -655,6 +659,9 @@ static int at24_remove(struct i2c_client *client) + at24 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &at24->bin); + ++ if (client->dev.of_node) ++ of_memory_accessor_remove(&client->dev); ++ + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); +