[linux-yocto] [PATCH 35/87] mach-axxia/i2c: fix editing typo.
Paul Butler
butler.paul at gmail.com
Mon May 27 09:56:06 PDT 2013
From: Michael Bringmann <michael.bringmann at lsi.com>
Signed-off-by: Michael Bringmann <michael.bringmann at lsi.com>
---
arch/arm/mach-axxia/i2c.c | 213 +++++++++++++++++++++++++++++++++-------------
1 file changed, 156 insertions(+), 57 deletions(-)
diff --git a/arch/arm/mach-axxia/i2c.c b/arch/arm/mach-axxia/i2c.c
index ef90a5a..5f9eff3 100644
--- a/arch/arm/mach-axxia/i2c.c
+++ b/arch/arm/mach-axxia/i2c.c
@@ -23,11 +23,15 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/of_address.h>
#include <linux/i2c.h>
#include <linux/i2c-axxia.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/interrupt.h>
#include <mach/irqs.h>
@@ -39,62 +43,110 @@
static const char name[] = "axxia_ai2c";
-#define I2C_RESOURCE_BUILDER(base, irq) \
- { \
- .start = (base), \
- .end = (base) + AXXIA_I2C_SIZE, \
- .flags = IORESOURCE_MEM, \
- }, \
- { \
- .start = (irq), \
- .flags = IORESOURCE_IRQ, \
- },
-
- /* Filler values for now; real values will be filled in
- * based on chip type / chip version / etc. */
-static struct resource i2c_resources[][2] = {
- { I2C_RESOURCE_BUILDER(0, 0) },
-};
-
-#define I2C_DEV_BUILDER(bus_id, res, data) \
- { \
- .id = (bus_id), \
- .name = name, \
- .num_resources = ARRAY_SIZE(res), \
- .resource = (res), \
- .dev = { \
- .platform_data = (data), \
- }, \
- }
-static struct axxia_i2c_bus_platform_data i2c_pdata[ARCH_AXXIA_MAX_I2C_BUSSES];
-static struct platform_device axxia_i2c_devices[ARCH_AXXIA_MAX_I2C_BUSSES] =
-{
- I2C_DEV_BUILDER(ARCH_AXXIA_MAX_I2C_BUS_NR, i2c_resources[0], &i2c_pdata[0]),
-};
+static struct axxia_i2c_bus_platform_data *axxia_i2cx_ports;
+static unsigned int axxia_i2cx_port_count;
+static struct platform_device *axxia_i2cx_devices;
+static struct platform_device **axxia_i2cx_device_ptrs;
static inline
int
axxia_add_i2c_bus(
- int ndx,
- int bus_id)
+ struct device_node *np,
+ struct platform_device *pdev,
+ int ndx,
+ int bus_id)
{
- struct platform_device *pdev;
- struct axxia_i2c_bus_platform_data *pdata;
- struct resource *res;
+ struct axxia_i2c_bus_platform_data *pdata;
+ const u32 pval;
+ const char *val;
+ int portno;
+
+ /* Get the port number from the device-tree */
+ if (!of_property_read_u32(np, "port", (u32 *)&pval)) {
+ portno = pval;
+ } else {
+ printk(KERN_ERR "I2C: Can't find port number for %s\n",
+ np->full_name);
+ return -ENXIO;
+ }
+ if (portno > axxia_i2cx_port_count) {
+ printk(KERN_ERR "I2C: port number out of range for %s\n",
+ np->full_name);
+ return -ENXIO;
+ }
+
+ pdata = &axxia_i2cx_ports[ndx];
+ pdata->node = of_node_get(np);
+
+ pdata->index = portno;
+
+ /* Verify device type */
+ val = of_get_property(np, "device_type", NULL);
+ if (strcmp(val, "i2c")) {
+ printk(KERN_ERR "I2C%d: missing or incorrect device_type for %s\n",
+ portno, np->full_name);
+ return -ENXIO;
+ }
+
+ /* Get or insert bus name */
+ val = of_get_property(np, "bus_name", NULL);
+ if (val)
+ strncpy(pdata->name, val, MAX_AXXIA_I2C_HWMOD_NAME_LEN);
+ else
+ sprintf(pdata->name, "i2c%d", portno);
- pdev = &axxia_i2c_devices[ndx];
- res = pdev->resource;
- res[0].start = AXXIA1_I2C_BASE;
- res[0].end = res[0].start + AXXIA_I2C_SIZE;
- res[1].start = 0; /* I2C interrup handle? */
- pdata = &i2c_pdata[ndx];
+ pdata->rev = AXXIA_I2C_IP_VERSION_2; /* AXM55xx */
- pdata->rev = AXXIA_I2C_IP_VERSION_2;
- pdata->flags = 0;
+ pdata->flags = AXXIA_I2C_FLAGS_NONE;
- return platform_device_register(pdev);
+ /* Get the bus number from the device-tree */
+ if (!of_property_read_u32(np, "bus", (u32 *)&pval))
+ pdata->bus_nr = pval;
+ else
+ pdata->bus_nr = ~0;
+
+ /* Fetch config space registers address */
+ if (of_address_to_resource(np, 0, &pdata->dev_space)) {
+ printk(KERN_ERR "%s: Can't get I2C device space !",
+ np->full_name);
+ return -ENXIO;
+ }
+ pdata->dev_space.flags = IORESOURCE_MEM;
+
+ /* Hookup an interrupt handler -- TBD, maybe later */
+ pdata->int_space.start = irq_of_parse_and_map(np, 0);
+ pdata->int_space.flags = IORESOURCE_IRQ;
+
+ if (pdata->bus_nr == ~0) {
+ printk(KERN_INFO
+ "I2C Port %d found; bus#=<auto> '%s'\n",
+ portno, pdata->name);
+ } else {
+ printk(KERN_INFO
+ "I2C Port %d found; bus#=i%d '%s'\n",
+ portno, pdata->bus_nr, pdata->name);
+ }
+ printk(KERN_INFO
+ " dev_space start = 0x%012llx, end = 0x%012llx\n",
+ pdata->dev_space.start, pdata->dev_space.end);
+ printk(KERN_INFO
+ " mappedIrq#=%x\n", (unsigned int)pdata->int_space.start);
+
+ /* Fill in the device */
+ pdev->id = ndx;
+ pdev->name = name;
+ pdev->num_resources = 2;
+ pdev->resource = &pdata->dev_space;
+ pdev->dev.platform_data = pdata;
+
+ /* printk(KERN_INFO
+ "pdev: id=%d name='%s' n_r=%d res=%p d.p_d=%p\n",
+ pdev->id, pdev->name, pdev->num_resources,
+ pdev->resource, pdev->dev.platform_data); */
+
+ return 0;
}
@@ -105,17 +157,64 @@ axxia_add_i2c_bus(
*/
int __init
axxia_register_i2c_busses(
- void)
+ void)
{
- int i;
- int err;
-
- for (i=0; i < ARCH_AXXIA_MAX_I2C_BUSSES; i++)
- {
- err = axxia_add_i2c_bus(i, i+ARCH_AXXIA_MAX_I2C_BUS_NR);
- if (err)
- return err;
- }
+ int i;
+ int err;
+ struct device_node *np;
+
+ /* How many of these devices will be needed? */
+ axxia_i2cx_port_count = 0;
+ for_each_compatible_node(np, NULL, "lsi,api2c")
+ axxia_i2cx_port_count++;
+
+ if (axxia_i2cx_port_count == 0)
+ return -ENXIO;
+
+ /* Allocate memory */
+ axxia_i2cx_ports = kzalloc(axxia_i2cx_port_count*
+ sizeof(struct axxia_i2c_bus_platform_data),
+ GFP_KERNEL);
+ if (!axxia_i2cx_ports) {
+ printk(KERN_WARNING "I2C: failed to allocate ports array\n");
+ return -ENOMEM;
+ }
+ memset(axxia_i2cx_ports, 0,
+ axxia_i2cx_port_count*
+ sizeof(struct axxia_i2c_bus_platform_data));
+
+ axxia_i2cx_devices = kzalloc(axxia_i2cx_port_count*
+ sizeof(struct platform_device),
+ GFP_KERNEL);
+ if (!axxia_i2cx_devices) {
+ printk(KERN_WARNING "I2C: failed to allocate devices array\n");
+ return -ENOMEM;
+ }
+ memset(axxia_i2cx_devices, 0,
+ axxia_i2cx_port_count*sizeof(struct platform_device));
+
+ axxia_i2cx_device_ptrs = kzalloc(axxia_i2cx_port_count*
+ sizeof(struct platform_device *),
+ GFP_KERNEL);
+ if (!axxia_i2cx_device_ptrs) {
+ printk(KERN_WARNING
+ "I2C: failed to allocate device ptrs array\n");
+ return -ENOMEM;
+ }
+ memset(axxia_i2cx_device_ptrs, 0,
+ axxia_i2cx_port_count*sizeof(struct platform_device *));
+
+ /* Now parse and fill in the device entries */
+ i = 0;
+ for_each_compatible_node(np, NULL, "lsi,api2c")
+ {
+ axxia_i2cx_device_ptrs[i] = &axxia_i2cx_devices[i];
+
+ err = axxia_add_i2c_bus(np, axxia_i2cx_device_ptrs[i],
+ i, i+ARCH_AXXIA_MAX_I2C_BUS_NR);
+ if (err == 0)
+ i++;
+ }
- return 0;
+ return platform_add_devices(axxia_i2cx_device_ptrs, i);
}
--
1.8.3
More information about the linux-yocto
mailing list