[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