Add further patches
This commit is contained in:
parent
d803c68954
commit
4f8715bdbf
@ -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 */
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user