Add further patches

This commit is contained in:
Martin Kennedy 2021-02-16 02:05:16 +00:00
parent d803c68954
commit 4f8715bdbf
2 changed files with 353 additions and 0 deletions

View File

@ -0,0 +1,310 @@
From: Abhishek Paliwal <abhishek.paliwal@aricent.com>
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 <aaron.williams@cavium.com>
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 <aaron.williams@cavium.com>
Signed-off-by: Leonid Rosenboim <lrosenboim@caviumnetworks.com>
Signed-off-by: Abhishek Paliwal <abhishek.paliwal@aricent.com>
--- 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 <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_memory_accessor.h>
+#include <linux/list.h>
+#include <linux/memory.h>
+
+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 <linux/of.h>
+#include <linux/memory.h>
+
+/**
+ * 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 */

View File

@ -0,0 +1,43 @@
From: Abhishek Paliwal <abhishek.paliwal@aricent.com>
Date: Fri, 13 Feb 2015 12:48:16 +0530
Subject: misc/at24: Register memory accessor functions with of_memory_accessor
From: Aaron Williams <aaron.williams@cavium.com>
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 <aaron.williams@cavium.com>
Signed-off-by: Leonid Rosenboim <lrosenboim@caviumnetworks.com>
Signed-off-by: Abhishek Paliwal <abhishek.paliwal@aricent.com>
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -23,6 +23,7 @@
#include <linux/of.h>
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
+#include <linux/of_memory_accessor.h>
/*
* 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]);