kernel: Patch in i2c, sbefifo, and occ drivers

Change-Id: I845752ca9f64f42f1fc46e14cac90a48f7195ca3
Signed-off-by: Edward A. James <eajames@us.ibm.com>
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/0001-fsi-Match-fsi-slaves-engines-to-available-device-tre.patch b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/0001-fsi-Match-fsi-slaves-engines-to-available-device-tre.patch
new file mode 100644
index 0000000..6fdfe93
--- /dev/null
+++ b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/0001-fsi-Match-fsi-slaves-engines-to-available-device-tre.patch
@@ -0,0 +1,236 @@
+From 8f10daa0cc99ce286b9a2f249f1fa0a245d4fc03 Mon Sep 17 00:00:00 2001
+From: "Edward A. James" <eajames@us.ibm.com>
+Date: Wed, 17 May 2017 09:46:19 -0500
+Subject: [PATCH] fsi: Match fsi slaves & engines to available device tree
+ nodes
+
+This change populates device tree nodes for scanned FSI slaves and
+engines. If the master populates ->of_node of the FSI master device,
+we'll look for matching slaves, and under those slaves we'll look for
+matching engines.
+
+This means that FSI drivers will have their ->of_node pointer populated
+if there's a corresponding DT node, which they can use for further
+device discover.
+
+Presence of device tree nodes is optional, and only required for
+fsi device drivers that need extra properties, or subordinate devices,
+to be enumerated.
+
+Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
+Signed-off-by: Edward A. James <eajames@us.ibm.com>
+---
+ drivers/fsi/fsi-core.c        | 99 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/fsi/fsi-master-gpio.c |  4 ++
+ drivers/fsi/fsi-master-hub.c  |  4 ++
+ 3 files changed, 107 insertions(+)
+
+diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
+index 7ca5b74..71e3af9 100644
+--- a/drivers/fsi/fsi-core.c
++++ b/drivers/fsi/fsi-core.c
+@@ -17,6 +17,7 @@
+ #include <linux/fsi.h>
+ #include <linux/idr.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/slab.h>
+ 
+ #include "fsi-master.h"
+@@ -125,6 +126,7 @@ static void fsi_device_release(struct device *_device)
+ {
+ 	struct fsi_device *device = to_fsi_dev(_device);
+ 
++	of_node_put(device->dev.of_node);
+ 	kfree(device);
+ }
+ 
+@@ -337,6 +339,57 @@ extern void fsi_slave_release_range(struct fsi_slave *slave,
+ {
+ }
+ 
++static bool fsi_device_node_matches(struct device *dev, struct device_node *np,
++		uint32_t addr, uint32_t size)
++{
++	unsigned int len, na, ns;
++	const __be32 *prop;
++	uint32_t psize;
++
++	na = of_n_addr_cells(np);
++	ns = of_n_size_cells(np);
++
++	if (na != 1 || ns != 1)
++		return false;
++
++	prop = of_get_property(np, "reg", &len);
++	if (!prop || len != 8)
++		return false;
++
++	if (of_read_number(prop, 1) != addr)
++		return false;
++
++	psize = of_read_number(prop + 1, 1);
++	if (psize != size) {
++		dev_warn(dev,
++			"node %s matches probed address, but not size (got 0x%x, expected 0x%x)",
++			of_node_full_name(np), psize, size);
++	}
++
++	return true;
++}
++
++/* Find a matching node for the slave engine at @address, using @size bytes
++ * of space. Returns NULL if not found, or a matching node with refcount
++ * already incremented.
++ */
++static struct device_node *fsi_device_find_of_node(struct fsi_device *dev)
++{
++	struct device_node *parent, *np;
++
++	parent = dev_of_node(&dev->slave->dev);
++	if (!parent)
++		return NULL;
++
++	for_each_child_of_node(parent, np) {
++		if (fsi_device_node_matches(&dev->dev, np,
++					dev->addr, dev->size))
++			return np;
++	}
++
++	return NULL;
++}
++
+ static int fsi_slave_scan(struct fsi_slave *slave)
+ {
+ 	uint32_t engine_addr;
+@@ -405,6 +458,7 @@ static int fsi_slave_scan(struct fsi_slave *slave)
+ 			dev_set_name(&dev->dev, "%02x:%02x:%02x:%02x",
+ 					slave->master->idx, slave->link,
+ 					slave->id, i - 2);
++			dev->dev.of_node = fsi_device_find_of_node(dev);
+ 
+ 			rc = device_register(&dev->dev);
+ 			if (rc) {
+@@ -561,9 +615,53 @@ static void fsi_slave_release(struct device *dev)
+ {
+ 	struct fsi_slave *slave = to_fsi_slave(dev);
+ 
++	of_node_put(dev->of_node);
+ 	kfree(slave);
+ }
+ 
++static bool fsi_slave_node_matches(struct device_node *np,
++		int link, uint8_t id)
++{
++	unsigned int len, na, ns;
++	const __be32 *prop;
++
++	na = of_n_addr_cells(np);
++	ns = of_n_size_cells(np);
++
++	/* Ensure we have the correct format for addresses and sizes in
++	 * reg properties
++	 */
++	if (na != 2 || ns != 0)
++		return false;
++
++	prop = of_get_property(np, "reg", &len);
++	if (!prop || len != 8)
++		return false;
++
++	return (of_read_number(prop, 1) == link) &&
++		(of_read_number(prop + 1, 1) == id);
++}
++
++/* Find a matching node for the slave at (link, id). Returns NULL if none
++ * found, or a matching node with refcount already incremented.
++ */
++static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
++		int link, uint8_t id)
++{
++	struct device_node *parent, *np;
++
++	parent = dev_of_node(&master->dev);
++	if (!parent)
++		return NULL;
++
++	for_each_child_of_node(parent, np) {
++		if (fsi_slave_node_matches(np, link, id))
++			return np;
++	}
++
++	return NULL;
++}
++
+ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
+ {
+ 	uint32_t chip_id, llmode;
+@@ -626,6 +724,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
+ 
+ 	slave->master = master;
+ 	slave->dev.parent = &master->dev;
++	slave->dev.of_node = fsi_slave_find_of_node(master, link, id);
+ 	slave->dev.release = fsi_slave_release;
+ 	slave->link = link;
+ 	slave->id = id;
+diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
+index ef209ef..2a6a812 100644
+--- a/drivers/fsi/fsi-master-gpio.c
++++ b/drivers/fsi/fsi-master-gpio.c
+@@ -5,6 +5,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/delay.h>
+ #include <linux/fsi.h>
+ #include <linux/device.h>
+@@ -529,6 +530,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
+ 
+ 	master->dev = &pdev->dev;
+ 	master->master.dev.parent = master->dev;
++	master->master.dev.of_node = of_node_get(dev_of_node(master->dev));
+ 	master->master.dev.release = fsi_master_gpio_release;
+ 
+ 	gpio = devm_gpiod_get(&pdev->dev, "clock", 0);
+@@ -598,6 +600,8 @@ static int fsi_master_gpio_remove(struct platform_device *pdev)
+ 		devm_gpiod_put(&pdev->dev, master->gpio_mux);
+ 	fsi_master_unregister(&master->master);
+ 
++	of_node_put(master->master.dev.of_node);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c
+index 133b9bf..3223a67 100644
+--- a/drivers/fsi/fsi-master-hub.c
++++ b/drivers/fsi/fsi-master-hub.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/fsi.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/slab.h>
+ 
+ #include "fsi-master.h"
+@@ -274,6 +275,7 @@ static int hub_master_probe(struct device *dev)
+ 
+ 	hub->master.dev.parent = dev;
+ 	hub->master.dev.release = hub_master_release;
++	hub->master.dev.of_node = of_node_get(dev_of_node(dev));
+ 
+ 	hub->master.n_links = links;
+ 	hub->master.read = hub_master_read;
+@@ -302,6 +304,8 @@ static int hub_master_remove(struct device *dev)
+ 
+ 	fsi_master_unregister(&hub->master);
+ 	fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size);
++	of_node_put(hub->master.dev.of_node);
++
+ 	return 0;
+ }
+ 
+-- 
+1.8.3.1
+