aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-11-30 17:45:49 -0500
committerTony Lindgren <tony@atomide.com>2010-11-30 17:45:49 -0500
commit55a4e78952286d498d89a399d845e7cfaa8ddd56 (patch)
treef5d67bdaa07b36009476d2e1bdcde8b7dc0c6e3d /arch/arm/plat-omap
parent9c7bc451e41abf78b0fd856a9f916f7d39e26297 (diff)
parent27b1fec2caa668c162cd1a862c69e087df277fae (diff)
Merge branch 'pm-hwmod-i2c' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/i2c.c124
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h13
-rw-r--r--arch/arm/plat-omap/include/plat/l4_3xxx.h24
3 files changed, 86 insertions, 75 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5ce4f0aad35..a5bff9ce7cbe 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -27,18 +27,18 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/i2c-omap.h> 29#include <linux/i2c-omap.h>
30#include <linux/slab.h>
31#include <linux/err.h>
32#include <linux/clk.h>
30 33
31#include <mach/irqs.h> 34#include <mach/irqs.h>
32#include <plat/mux.h> 35#include <plat/mux.h>
33#include <plat/i2c.h> 36#include <plat/i2c.h>
34#include <plat/omap-pm.h> 37#include <plat/omap-pm.h>
38#include <plat/omap_device.h>
35 39
36#define OMAP_I2C_SIZE 0x3f 40#define OMAP_I2C_SIZE 0x3f
37#define OMAP1_I2C_BASE 0xfffb3800 41#define OMAP1_I2C_BASE 0xfffb3800
38#define OMAP2_I2C_BASE1 0x48070000
39#define OMAP2_I2C_BASE2 0x48072000
40#define OMAP2_I2C_BASE3 0x48060000
41#define OMAP4_I2C_BASE4 0x48350000
42 42
43static const char name[] = "i2c_omap"; 43static const char name[] = "i2c_omap";
44 44
@@ -55,15 +55,6 @@ static const char name[] = "i2c_omap";
55 55
56static struct resource i2c_resources[][2] = { 56static struct resource i2c_resources[][2] = {
57 { I2C_RESOURCE_BUILDER(0, 0) }, 57 { I2C_RESOURCE_BUILDER(0, 0) },
58#if defined(CONFIG_ARCH_OMAP2PLUS)
59 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) },
60#endif
61#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
62 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) },
63#endif
64#if defined(CONFIG_ARCH_OMAP4)
65 { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) },
66#endif
67}; 58};
68 59
69#define I2C_DEV_BUILDER(bus_id, res, data) \ 60#define I2C_DEV_BUILDER(bus_id, res, data) \
@@ -77,18 +68,11 @@ static struct resource i2c_resources[][2] = {
77 }, \ 68 }, \
78 } 69 }
79 70
80static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)]; 71#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
72#define OMAP_I2C_MAX_CONTROLLERS 4
73static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
81static struct platform_device omap_i2c_devices[] = { 74static struct platform_device omap_i2c_devices[] = {
82 I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), 75 I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
83#if defined(CONFIG_ARCH_OMAP2PLUS)
84 I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
85#endif
86#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
87 I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
88#endif
89#if defined(CONFIG_ARCH_OMAP4)
90 I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]),
91#endif
92}; 76};
93 77
94#define OMAP_I2C_CMDLINE_SETUP (BIT(31)) 78#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
@@ -109,35 +93,20 @@ static int __init omap_i2c_nr_ports(void)
109 return ports; 93 return ports;
110} 94}
111 95
112/* Shared between omap2 and 3 */ 96static inline int omap1_i2c_add_bus(int bus_id)
113static resource_size_t omap2_i2c_irq[3] __initdata = {
114 INT_24XX_I2C1_IRQ,
115 INT_24XX_I2C2_IRQ,
116 INT_34XX_I2C3_IRQ,
117};
118
119static resource_size_t omap4_i2c_irq[4] __initdata = {
120 OMAP44XX_IRQ_I2C1,
121 OMAP44XX_IRQ_I2C2,
122 OMAP44XX_IRQ_I2C3,
123 OMAP44XX_IRQ_I2C4,
124};
125
126static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
127{ 97{
128 struct omap_i2c_bus_platform_data *pd; 98 struct platform_device *pdev;
129 struct resource *res; 99 struct omap_i2c_bus_platform_data *pdata;
130 100
131 pd = pdev->dev.platform_data;
132 res = pdev->resource;
133 res[0].start = OMAP1_I2C_BASE;
134 res[0].end = res[0].start + OMAP_I2C_SIZE;
135 res[1].start = INT_I2C;
136 omap1_i2c_mux_pins(bus_id); 101 omap1_i2c_mux_pins(bus_id);
137 102
103 pdev = &omap_i2c_devices[bus_id - 1];
104 pdata = &i2c_pdata[bus_id - 1];
105
138 return platform_device_register(pdev); 106 return platform_device_register(pdev);
139} 107}
140 108
109
141/* 110/*
142 * XXX This function is a temporary compatibility wrapper - only 111 * XXX This function is a temporary compatibility wrapper - only
143 * needed until the I2C driver can be converted to call 112 * needed until the I2C driver can be converted to call
@@ -148,52 +117,57 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
148 omap_pm_set_max_mpu_wakeup_lat(dev, t); 117 omap_pm_set_max_mpu_wakeup_lat(dev, t);
149} 118}
150 119
151static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) 120static struct omap_device_pm_latency omap_i2c_latency[] = {
152{ 121 [0] = {
153 struct resource *res; 122 .deactivate_func = omap_device_idle_hwmods,
154 resource_size_t *irq; 123 .activate_func = omap_device_enable_hwmods,
124 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
125 },
126};
155 127
156 res = pdev->resource; 128static inline int omap2_i2c_add_bus(int bus_id)
129{
130 int l;
131 struct omap_hwmod *oh;
132 struct omap_device *od;
133 char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
134 struct omap_i2c_bus_platform_data *pdata;
157 135
158 if (!cpu_is_omap44xx()) 136 omap2_i2c_mux_pins(bus_id);
159 irq = omap2_i2c_irq;
160 else
161 irq = omap4_i2c_irq;
162 137
163 if (bus_id == 1) { 138 l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
164 res[0].start = OMAP2_I2C_BASE1; 139 WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
165 res[0].end = res[0].start + OMAP_I2C_SIZE; 140 "String buffer overflow in I2C%d device setup\n", bus_id);
141 oh = omap_hwmod_lookup(oh_name);
142 if (!oh) {
143 pr_err("Could not look up %s\n", oh_name);
144 return -EEXIST;
166 } 145 }
167 146
168 res[1].start = irq[bus_id - 1]; 147 pdata = &i2c_pdata[bus_id - 1];
169 omap2_i2c_mux_pins(bus_id);
170
171 /* 148 /*
172 * When waiting for completion of a i2c transfer, we need to 149 * When waiting for completion of a i2c transfer, we need to
173 * set a wake up latency constraint for the MPU. This is to 150 * set a wake up latency constraint for the MPU. This is to
174 * ensure quick enough wakeup from idle, when transfer 151 * ensure quick enough wakeup from idle, when transfer
175 * completes. 152 * completes.
153 * Only omap3 has support for constraints
176 */ 154 */
177 if (cpu_is_omap34xx()) { 155 if (cpu_is_omap34xx())
178 struct omap_i2c_bus_platform_data *pd; 156 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
179 157 od = omap_device_build(name, bus_id, oh, pdata,
180 pd = pdev->dev.platform_data; 158 sizeof(struct omap_i2c_bus_platform_data),
181 pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; 159 omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
182 } 160 WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
183 161
184 return platform_device_register(pdev); 162 return PTR_ERR(od);
185} 163}
186 164
187static int __init omap_i2c_add_bus(int bus_id) 165static int __init omap_i2c_add_bus(int bus_id)
188{ 166{
189 struct platform_device *pdev;
190
191 pdev = &omap_i2c_devices[bus_id - 1];
192
193 if (cpu_class_is_omap1()) 167 if (cpu_class_is_omap1())
194 return omap1_i2c_add_bus(pdev, bus_id); 168 return omap1_i2c_add_bus(bus_id);
195 else 169 else
196 return omap2_i2c_add_bus(pdev, bus_id); 170 return omap2_i2c_add_bus(bus_id);
197} 171}
198 172
199/** 173/**
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h
index 36a0befd6168..878d632c4092 100644
--- a/arch/arm/plat-omap/include/plat/i2c.h
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -36,6 +36,19 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
36} 36}
37#endif 37#endif
38 38
39/**
40 * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod
41 * @fifo_depth: total controller FIFO size (in bytes)
42 * @flags: differences in hardware support capability
43 *
44 * @fifo_depth represents what exists on the hardware, not what is
45 * actually configured at runtime by the device driver.
46 */
47struct omap_i2c_dev_attr {
48 u8 fifo_depth;
49 u8 flags;
50};
51
39void __init omap1_i2c_mux_pins(int bus_id); 52void __init omap1_i2c_mux_pins(int bus_id);
40void __init omap2_i2c_mux_pins(int bus_id); 53void __init omap2_i2c_mux_pins(int bus_id);
41 54
diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h
new file mode 100644
index 000000000000..5e1949375422
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
14#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
15
16/* L4 CORE */
17#define OMAP3_L4_CORE_FW_I2C1_REGION 21
18#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22
19#define OMAP3_L4_CORE_FW_I2C2_REGION 23
20#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24
21#define OMAP3_L4_CORE_FW_I2C3_REGION 73
22#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74
23
24#endif