aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:38:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:38:42 -0400
commitae4c42e4e4d76d003f8ca551fe1aef93ff9a4b21 (patch)
tree2bff2e4f4456077e7d7c589c8c28824f12dfa21c /arch/arm/plat-omap
parentdd58ecba48edf14be1a5f70120fcd3002277a74a (diff)
parentab2a0e0d135490729e384c1826d118f92e88cae8 (diff)
Merge branch 'next/cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc
* 'next/cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc: (133 commits) ARM: EXYNOS4: Change devname for FIMD clkdev ARM: S3C64XX: Cleanup mach/regs-fb.h from mach-s3c64xx ARM: S5PV210: Cleanup mach/regs-fb.h from mach-s5pv210 ARM: S5PC100: Cleanup mach/regs-fb.h from mach-s5pc100 ARM: S3C24XX: Use generic s3c_set_platdata for devices ARM: S3C64XX: Use generic s3c_set_platdata for OneNAND ARM: SAMSUNG: Use generic s3c_set_platdata for NAND ARM: SAMSUNG: Use generic s3c_set_platdata for USB OHCI ARM: SAMSUNG: Use generic s3c_set_platdata for HWMON ARM: SAMSUNG: Use generic s3c_set_platdata for FB ARM: SAMSUNG: Use generic s3c_set_platdata for TS ARM: S3C64XX: Add PWM backlight support on SMDK6410 ARM: S5P64X0: Add PWM backlight support on SMDK6450 ARM: S5P64X0: Add PWM backlight support on SMDK6440 ARM: S5PC100: Add PWM backlight support on SMDKC100 ARM: S5PV210: Add PWM backlight support on SMDKV210 ARM: EXYNOS4: Add PWM backlight support on SMDKC210 ARM: EXYNOS4: Add PWM backlight support on SMDKV310 ARM: SAMSUNG: Create a common infrastructure for PWM backlight support clocksource: convert 32-bit down counting clocksource on S5PV210/S5P64X0 ... Fix up trivial conflict in arch/arm/mach-imx/mach-scb9328.c
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig3
-rw-r--r--arch/arm/plat-omap/counter_32k.c123
-rw-r--r--arch/arm/plat-omap/dmtimer.c209
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h2
-rw-r--r--arch/arm/plat-omap/include/plat/common.h6
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h251
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h6
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h74
-rw-r--r--arch/arm/plat-omap/include/plat/nand.h6
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h8
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h20
-rw-r--r--arch/arm/plat-omap/mcbsp.c599
-rw-r--r--arch/arm/plat-omap/omap_device.c15
13 files changed, 352 insertions, 970 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 49a4c75243fc..6e6735f04ee3 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -211,9 +211,6 @@ choice
211 depends on ARCH_OMAP 211 depends on ARCH_OMAP
212 default OMAP_PM_NOOP 212 default OMAP_PM_NOOP
213 213
214config OMAP_PM_NONE
215 bool "No PM layer"
216
217config OMAP_PM_NOOP 214config OMAP_PM_NOOP
218 bool "No-op/debug PM layer" 215 bool "No-op/debug PM layer"
219 216
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index f7fed6080190..a6cbb712da51 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -18,6 +18,7 @@
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/clocksource.h>
21 22
22#include <asm/sched_clock.h> 23#include <asm/sched_clock.h>
23 24
@@ -26,87 +27,16 @@
26 27
27#include <plat/clock.h> 28#include <plat/clock.h>
28 29
29
30/* 30/*
31 * 32KHz clocksource ... always available, on pretty most chips except 31 * 32KHz clocksource ... always available, on pretty most chips except
32 * OMAP 730 and 1510. Other timers could be used as clocksources, with 32 * OMAP 730 and 1510. Other timers could be used as clocksources, with
33 * higher resolution in free-running counter modes (e.g. 12 MHz xtal), 33 * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
34 * but systems won't necessarily want to spend resources that way. 34 * but systems won't necessarily want to spend resources that way.
35 */ 35 */
36static void __iomem *timer_32k_base;
36 37
37#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410 38#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
38 39
39#include <linux/clocksource.h>
40
41/*
42 * offset_32k holds the init time counter value. It is then subtracted
43 * from every counter read to achieve a counter that counts time from the
44 * kernel boot (needed for sched_clock()).
45 */
46static u32 offset_32k __read_mostly;
47
48#ifdef CONFIG_ARCH_OMAP16XX
49static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
50{
51 return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
52}
53#else
54#define omap16xx_32k_read NULL
55#endif
56
57#ifdef CONFIG_SOC_OMAP2420
58static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
59{
60 return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
61}
62#else
63#define omap2420_32k_read NULL
64#endif
65
66#ifdef CONFIG_SOC_OMAP2430
67static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
68{
69 return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
70}
71#else
72#define omap2430_32k_read NULL
73#endif
74
75#ifdef CONFIG_ARCH_OMAP3
76static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
77{
78 return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
79}
80#else
81#define omap34xx_32k_read NULL
82#endif
83
84#ifdef CONFIG_ARCH_OMAP4
85static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
86{
87 return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
88}
89#else
90#define omap44xx_32k_read NULL
91#endif
92
93/*
94 * Kernel assumes that sched_clock can be called early but may not have
95 * things ready yet.
96 */
97static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
98{
99 return 0;
100}
101
102static struct clocksource clocksource_32k = {
103 .name = "32k_counter",
104 .rating = 250,
105 .read = omap_32k_read_dummy,
106 .mask = CLOCKSOURCE_MASK(32),
107 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
108};
109
110/* 40/*
111 * Returns current time from boot in nsecs. It's OK for this to wrap 41 * Returns current time from boot in nsecs. It's OK for this to wrap
112 * around for now, as it's just a relative time stamp. 42 * around for now, as it's just a relative time stamp.
@@ -122,11 +52,11 @@ static DEFINE_CLOCK_DATA(cd);
122 52
123static inline unsigned long long notrace _omap_32k_sched_clock(void) 53static inline unsigned long long notrace _omap_32k_sched_clock(void)
124{ 54{
125 u32 cyc = clocksource_32k.read(&clocksource_32k); 55 u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
126 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); 56 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
127} 57}
128 58
129#ifndef CONFIG_OMAP_MPU_TIMER 59#if defined(CONFIG_OMAP_32K_TIMER) && !defined(CONFIG_OMAP_MPU_TIMER)
130unsigned long long notrace sched_clock(void) 60unsigned long long notrace sched_clock(void)
131{ 61{
132 return _omap_32k_sched_clock(); 62 return _omap_32k_sched_clock();
@@ -140,7 +70,7 @@ unsigned long long notrace omap_32k_sched_clock(void)
140 70
141static void notrace omap_update_sched_clock(void) 71static void notrace omap_update_sched_clock(void)
142{ 72{
143 u32 cyc = clocksource_32k.read(&clocksource_32k); 73 u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
144 update_sched_clock(&cd, cyc, (u32)~0); 74 update_sched_clock(&cd, cyc, (u32)~0);
145} 75}
146 76
@@ -153,6 +83,7 @@ static void notrace omap_update_sched_clock(void)
153 */ 83 */
154static struct timespec persistent_ts; 84static struct timespec persistent_ts;
155static cycles_t cycles, last_cycles; 85static cycles_t cycles, last_cycles;
86static unsigned int persistent_mult, persistent_shift;
156void read_persistent_clock(struct timespec *ts) 87void read_persistent_clock(struct timespec *ts)
157{ 88{
158 unsigned long long nsecs; 89 unsigned long long nsecs;
@@ -160,11 +91,10 @@ void read_persistent_clock(struct timespec *ts)
160 struct timespec *tsp = &persistent_ts; 91 struct timespec *tsp = &persistent_ts;
161 92
162 last_cycles = cycles; 93 last_cycles = cycles;
163 cycles = clocksource_32k.read(&clocksource_32k); 94 cycles = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
164 delta = cycles - last_cycles; 95 delta = cycles - last_cycles;
165 96
166 nsecs = clocksource_cyc2ns(delta, 97 nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
167 clocksource_32k.mult, clocksource_32k.shift);
168 98
169 timespec_add_ns(tsp, nsecs); 99 timespec_add_ns(tsp, nsecs);
170 *ts = *tsp; 100 *ts = *tsp;
@@ -176,29 +106,46 @@ int __init omap_init_clocksource_32k(void)
176 "%s: can't register clocksource!\n"; 106 "%s: can't register clocksource!\n";
177 107
178 if (cpu_is_omap16xx() || cpu_class_is_omap2()) { 108 if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
109 u32 pbase;
110 unsigned long size = SZ_4K;
111 void __iomem *base;
179 struct clk *sync_32k_ick; 112 struct clk *sync_32k_ick;
180 113
181 if (cpu_is_omap16xx()) 114 if (cpu_is_omap16xx()) {
182 clocksource_32k.read = omap16xx_32k_read; 115 pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED;
183 else if (cpu_is_omap2420()) 116 size = SZ_1K;
184 clocksource_32k.read = omap2420_32k_read; 117 } else if (cpu_is_omap2420())
118 pbase = OMAP2420_32KSYNCT_BASE + 0x10;
185 else if (cpu_is_omap2430()) 119 else if (cpu_is_omap2430())
186 clocksource_32k.read = omap2430_32k_read; 120 pbase = OMAP2430_32KSYNCT_BASE + 0x10;
187 else if (cpu_is_omap34xx()) 121 else if (cpu_is_omap34xx())
188 clocksource_32k.read = omap34xx_32k_read; 122 pbase = OMAP3430_32KSYNCT_BASE + 0x10;
189 else if (cpu_is_omap44xx()) 123 else if (cpu_is_omap44xx())
190 clocksource_32k.read = omap44xx_32k_read; 124 pbase = OMAP4430_32KSYNCT_BASE + 0x10;
191 else 125 else
192 return -ENODEV; 126 return -ENODEV;
193 127
128 /* For this to work we must have a static mapping in io.c for this area */
129 base = ioremap(pbase, size);
130 if (!base)
131 return -ENODEV;
132
194 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); 133 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
195 if (!IS_ERR(sync_32k_ick)) 134 if (!IS_ERR(sync_32k_ick))
196 clk_enable(sync_32k_ick); 135 clk_enable(sync_32k_ick);
197 136
198 offset_32k = clocksource_32k.read(&clocksource_32k); 137 timer_32k_base = base;
138
139 /*
140 * 120000 rough estimate from the calculations in
141 * __clocksource_updatefreq_scale.
142 */
143 clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
144 32768, NSEC_PER_SEC, 120000);
199 145
200 if (clocksource_register_hz(&clocksource_32k, 32768)) 146 if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
201 printk(err, clocksource_32k.name); 147 clocksource_mmio_readl_up))
148 printk(err, "32k_counter");
202 149
203 init_fixed_sched_clock(&cd, omap_update_sched_clock, 32, 150 init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
204 32768, SC_MULT, SC_SHIFT); 151 32768, SC_MULT, SC_SHIFT);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index ee9f6ebba29b..8dfb8186b2c2 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -41,127 +41,6 @@
41#include <plat/dmtimer.h> 41#include <plat/dmtimer.h>
42#include <mach/irqs.h> 42#include <mach/irqs.h>
43 43
44/* register offsets */
45#define _OMAP_TIMER_ID_OFFSET 0x00
46#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10
47#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14
48#define _OMAP_TIMER_STAT_OFFSET 0x18
49#define _OMAP_TIMER_INT_EN_OFFSET 0x1c
50#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20
51#define _OMAP_TIMER_CTRL_OFFSET 0x24
52#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
53#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
54#define OMAP_TIMER_CTRL_PT (1 << 12)
55#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
56#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
57#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
58#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
59#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
60#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
61#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */
62#define OMAP_TIMER_CTRL_POSTED (1 << 2)
63#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
64#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
65#define _OMAP_TIMER_COUNTER_OFFSET 0x28
66#define _OMAP_TIMER_LOAD_OFFSET 0x2c
67#define _OMAP_TIMER_TRIGGER_OFFSET 0x30
68#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34
69#define WP_NONE 0 /* no write pending bit */
70#define WP_TCLR (1 << 0)
71#define WP_TCRR (1 << 1)
72#define WP_TLDR (1 << 2)
73#define WP_TTGR (1 << 3)
74#define WP_TMAR (1 << 4)
75#define WP_TPIR (1 << 5)
76#define WP_TNIR (1 << 6)
77#define WP_TCVR (1 << 7)
78#define WP_TOCR (1 << 8)
79#define WP_TOWR (1 << 9)
80#define _OMAP_TIMER_MATCH_OFFSET 0x38
81#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c
82#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40
83#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44 /* TCAR2, 34xx only */
84#define _OMAP_TIMER_TICK_POS_OFFSET 0x48 /* TPIR, 34xx only */
85#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c /* TNIR, 34xx only */
86#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50 /* TCVR, 34xx only */
87#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54 /* TOCR, 34xx only */
88#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58 /* TOWR, 34xx only */
89
90/* register offsets with the write pending bit encoded */
91#define WPSHIFT 16
92
93#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \
94 | (WP_NONE << WPSHIFT))
95
96#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \
97 | (WP_NONE << WPSHIFT))
98
99#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \
100 | (WP_NONE << WPSHIFT))
101
102#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \
103 | (WP_NONE << WPSHIFT))
104
105#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \
106 | (WP_NONE << WPSHIFT))
107
108#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \
109 | (WP_NONE << WPSHIFT))
110
111#define OMAP_TIMER_CTRL_REG (_OMAP_TIMER_CTRL_OFFSET \
112 | (WP_TCLR << WPSHIFT))
113
114#define OMAP_TIMER_COUNTER_REG (_OMAP_TIMER_COUNTER_OFFSET \
115 | (WP_TCRR << WPSHIFT))
116
117#define OMAP_TIMER_LOAD_REG (_OMAP_TIMER_LOAD_OFFSET \
118 | (WP_TLDR << WPSHIFT))
119
120#define OMAP_TIMER_TRIGGER_REG (_OMAP_TIMER_TRIGGER_OFFSET \
121 | (WP_TTGR << WPSHIFT))
122
123#define OMAP_TIMER_WRITE_PEND_REG (_OMAP_TIMER_WRITE_PEND_OFFSET \
124 | (WP_NONE << WPSHIFT))
125
126#define OMAP_TIMER_MATCH_REG (_OMAP_TIMER_MATCH_OFFSET \
127 | (WP_TMAR << WPSHIFT))
128
129#define OMAP_TIMER_CAPTURE_REG (_OMAP_TIMER_CAPTURE_OFFSET \
130 | (WP_NONE << WPSHIFT))
131
132#define OMAP_TIMER_IF_CTRL_REG (_OMAP_TIMER_IF_CTRL_OFFSET \
133 | (WP_NONE << WPSHIFT))
134
135#define OMAP_TIMER_CAPTURE2_REG (_OMAP_TIMER_CAPTURE2_OFFSET \
136 | (WP_NONE << WPSHIFT))
137
138#define OMAP_TIMER_TICK_POS_REG (_OMAP_TIMER_TICK_POS_OFFSET \
139 | (WP_TPIR << WPSHIFT))
140
141#define OMAP_TIMER_TICK_NEG_REG (_OMAP_TIMER_TICK_NEG_OFFSET \
142 | (WP_TNIR << WPSHIFT))
143
144#define OMAP_TIMER_TICK_COUNT_REG (_OMAP_TIMER_TICK_COUNT_OFFSET \
145 | (WP_TCVR << WPSHIFT))
146
147#define OMAP_TIMER_TICK_INT_MASK_SET_REG \
148 (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
149
150#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
151 (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
152
153struct omap_dm_timer {
154 unsigned long phys_base;
155 int irq;
156#ifdef CONFIG_ARCH_OMAP2PLUS
157 struct clk *iclk, *fclk;
158#endif
159 void __iomem *io_base;
160 unsigned reserved:1;
161 unsigned enabled:1;
162 unsigned posted:1;
163};
164
165static int dm_timer_count; 44static int dm_timer_count;
166 45
167#ifdef CONFIG_ARCH_OMAP1 46#ifdef CONFIG_ARCH_OMAP1
@@ -291,11 +170,7 @@ static spinlock_t dm_timer_lock;
291 */ 170 */
292static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) 171static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
293{ 172{
294 if (timer->posted) 173 return __omap_dm_timer_read(timer->io_base, reg, timer->posted);
295 while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
296 & (reg >> WPSHIFT))
297 cpu_relax();
298 return readl(timer->io_base + (reg & 0xff));
299} 174}
300 175
301/* 176/*
@@ -307,11 +182,7 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
307static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, 182static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
308 u32 value) 183 u32 value)
309{ 184{
310 if (timer->posted) 185 __omap_dm_timer_write(timer->io_base, reg, value, timer->posted);
311 while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
312 & (reg >> WPSHIFT))
313 cpu_relax();
314 writel(value, timer->io_base + (reg & 0xff));
315} 186}
316 187
317static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) 188static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
@@ -330,7 +201,7 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
330 201
331static void omap_dm_timer_reset(struct omap_dm_timer *timer) 202static void omap_dm_timer_reset(struct omap_dm_timer *timer)
332{ 203{
333 u32 l; 204 int autoidle = 0, wakeup = 0;
334 205
335 if (!cpu_class_is_omap2() || timer != &dm_timers[0]) { 206 if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
336 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 207 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
@@ -338,28 +209,21 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
338 } 209 }
339 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); 210 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
340 211
341 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
342 l |= 0x02 << 3; /* Set to smart-idle mode */
343 l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
344
345 /* Enable autoidle on OMAP2 / OMAP3 */ 212 /* Enable autoidle on OMAP2 / OMAP3 */
346 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 213 if (cpu_is_omap24xx() || cpu_is_omap34xx())
347 l |= 0x1 << 0; 214 autoidle = 1;
348 215
349 /* 216 /*
350 * Enable wake-up on OMAP2 CPUs. 217 * Enable wake-up on OMAP2 CPUs.
351 */ 218 */
352 if (cpu_class_is_omap2()) 219 if (cpu_class_is_omap2())
353 l |= 1 << 2; 220 wakeup = 1;
354 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
355 221
356 /* Match hardware reset default of posted mode */ 222 __omap_dm_timer_reset(timer->io_base, autoidle, wakeup);
357 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
358 OMAP_TIMER_CTRL_POSTED);
359 timer->posted = 1; 223 timer->posted = 1;
360} 224}
361 225
362static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 226void omap_dm_timer_prepare(struct omap_dm_timer *timer)
363{ 227{
364 omap_dm_timer_enable(timer); 228 omap_dm_timer_enable(timer);
365 omap_dm_timer_reset(timer); 229 omap_dm_timer_reset(timer);
@@ -531,25 +395,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
531 395
532void omap_dm_timer_stop(struct omap_dm_timer *timer) 396void omap_dm_timer_stop(struct omap_dm_timer *timer)
533{ 397{
534 u32 l; 398 unsigned long rate = 0;
535 399
536 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
537 if (l & OMAP_TIMER_CTRL_ST) {
538 l &= ~0x1;
539 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
540#ifdef CONFIG_ARCH_OMAP2PLUS 400#ifdef CONFIG_ARCH_OMAP2PLUS
541 /* Readback to make sure write has completed */ 401 rate = clk_get_rate(timer->fclk);
542 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
543 /*
544 * Wait for functional clock period x 3.5 to make sure that
545 * timer is stopped
546 */
547 udelay(3500000 / clk_get_rate(timer->fclk) + 1);
548#endif 402#endif
549 } 403
550 /* Ack possibly pending interrupt */ 404 __omap_dm_timer_stop(timer->io_base, timer->posted, rate);
551 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
552 OMAP_TIMER_INT_OVERFLOW);
553} 405}
554EXPORT_SYMBOL_GPL(omap_dm_timer_stop); 406EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
555 407
@@ -572,22 +424,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
572 424
573int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 425int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
574{ 426{
575 int ret = -EINVAL;
576
577 if (source < 0 || source >= 3) 427 if (source < 0 || source >= 3)
578 return -EINVAL; 428 return -EINVAL;
579 429
580 clk_disable(timer->fclk); 430 return __omap_dm_timer_set_source(timer->fclk,
581 ret = clk_set_parent(timer->fclk, dm_source_clocks[source]); 431 dm_source_clocks[source]);
582 clk_enable(timer->fclk);
583
584 /*
585 * When the functional clock disappears, too quick writes seem
586 * to cause an abort. XXX Is this still necessary?
587 */
588 __delay(300000);
589
590 return ret;
591} 432}
592EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); 433EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
593 434
@@ -625,8 +466,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
625 } 466 }
626 l |= OMAP_TIMER_CTRL_ST; 467 l |= OMAP_TIMER_CTRL_ST;
627 468
628 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load); 469 __omap_dm_timer_load_start(timer->io_base, l, load, timer->posted);
629 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
630} 470}
631EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start); 471EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
632 472
@@ -679,8 +519,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
679void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, 519void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
680 unsigned int value) 520 unsigned int value)
681{ 521{
682 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); 522 __omap_dm_timer_int_enable(timer->io_base, value);
683 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
684} 523}
685EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); 524EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
686 525
@@ -696,17 +535,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
696 535
697void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 536void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
698{ 537{
699 omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value); 538 __omap_dm_timer_write_status(timer->io_base, value);
700} 539}
701EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); 540EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
702 541
703unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 542unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
704{ 543{
705 unsigned int l; 544 return __omap_dm_timer_read_counter(timer->io_base, timer->posted);
706
707 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
708
709 return l;
710} 545}
711EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter); 546EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
712 547
@@ -737,7 +572,7 @@ int omap_dm_timers_active(void)
737} 572}
738EXPORT_SYMBOL_GPL(omap_dm_timers_active); 573EXPORT_SYMBOL_GPL(omap_dm_timers_active);
739 574
740int __init omap_dm_timer_init(void) 575static int __init omap_dm_timer_init(void)
741{ 576{
742 struct omap_dm_timer *timer; 577 struct omap_dm_timer *timer;
743 int i, map_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */ 578 int i, map_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
@@ -790,8 +625,16 @@ int __init omap_dm_timer_init(void)
790 sprintf(clk_name, "gpt%d_fck", i + 1); 625 sprintf(clk_name, "gpt%d_fck", i + 1);
791 timer->fclk = clk_get(NULL, clk_name); 626 timer->fclk = clk_get(NULL, clk_name);
792 } 627 }
628
629 /* One or two timers may be set up early for sys_timer */
630 if (sys_timer_reserved & (1 << i)) {
631 timer->reserved = 1;
632 timer->posted = 1;
633 }
793#endif 634#endif
794 } 635 }
795 636
796 return 0; 637 return 0;
797} 638}
639
640arch_initcall(omap_dm_timer_init);
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 006e599c6613..f57e0649ab30 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -152,7 +152,7 @@ struct dpll_data {
152 u16 max_multiplier; 152 u16 max_multiplier;
153 u8 last_rounded_n; 153 u8 last_rounded_n;
154 u8 min_divider; 154 u8 min_divider;
155 u8 max_divider; 155 u16 max_divider;
156 u8 modes; 156 u8 modes;
157#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) 157#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
158 void __iomem *autoidle_reg; 158 void __iomem *autoidle_reg;
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 5288130be96e..4564cc697d7f 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -34,7 +34,11 @@
34struct sys_timer; 34struct sys_timer;
35 35
36extern void omap_map_common_io(void); 36extern void omap_map_common_io(void);
37extern struct sys_timer omap_timer; 37extern struct sys_timer omap1_timer;
38extern struct sys_timer omap2_timer;
39extern struct sys_timer omap3_timer;
40extern struct sys_timer omap3_secure_timer;
41extern struct sys_timer omap4_timer;
38extern bool omap_32k_timer_init(void); 42extern bool omap_32k_timer_init(void);
39extern int __init omap_init_clocksource_32k(void); 43extern int __init omap_init_clocksource_32k(void);
40extern unsigned long long notrace omap_32k_sched_clock(void); 44extern unsigned long long notrace omap_32k_sched_clock(void);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index d6c70d2f4030..eb5d16c60cd9 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -32,6 +32,10 @@
32 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */ 33 */
34 34
35#include <linux/clk.h>
36#include <linux/delay.h>
37#include <linux/io.h>
38
35#ifndef __ASM_ARCH_DMTIMER_H 39#ifndef __ASM_ARCH_DMTIMER_H
36#define __ASM_ARCH_DMTIMER_H 40#define __ASM_ARCH_DMTIMER_H
37 41
@@ -56,12 +60,8 @@
56 */ 60 */
57#define OMAP_TIMER_IP_VERSION_1 0x1 61#define OMAP_TIMER_IP_VERSION_1 0x1
58struct omap_dm_timer; 62struct omap_dm_timer;
59extern struct omap_dm_timer *gptimer_wakeup;
60extern struct sys_timer omap_timer;
61struct clk; 63struct clk;
62 64
63int omap_dm_timer_init(void);
64
65struct omap_dm_timer *omap_dm_timer_request(void); 65struct omap_dm_timer *omap_dm_timer_request(void);
66struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); 66struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
67void omap_dm_timer_free(struct omap_dm_timer *timer); 67void omap_dm_timer_free(struct omap_dm_timer *timer);
@@ -93,5 +93,248 @@ void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value
93 93
94int omap_dm_timers_active(void); 94int omap_dm_timers_active(void);
95 95
96/*
97 * Do not use the defines below, they are not needed. They should be only
98 * used by dmtimer.c and sys_timer related code.
99 */
100
101/* register offsets */
102#define _OMAP_TIMER_ID_OFFSET 0x00
103#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10
104#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14
105#define _OMAP_TIMER_STAT_OFFSET 0x18
106#define _OMAP_TIMER_INT_EN_OFFSET 0x1c
107#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20
108#define _OMAP_TIMER_CTRL_OFFSET 0x24
109#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
110#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
111#define OMAP_TIMER_CTRL_PT (1 << 12)
112#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
113#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
114#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
115#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
116#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
117#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
118#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */
119#define OMAP_TIMER_CTRL_POSTED (1 << 2)
120#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
121#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
122#define _OMAP_TIMER_COUNTER_OFFSET 0x28
123#define _OMAP_TIMER_LOAD_OFFSET 0x2c
124#define _OMAP_TIMER_TRIGGER_OFFSET 0x30
125#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34
126#define WP_NONE 0 /* no write pending bit */
127#define WP_TCLR (1 << 0)
128#define WP_TCRR (1 << 1)
129#define WP_TLDR (1 << 2)
130#define WP_TTGR (1 << 3)
131#define WP_TMAR (1 << 4)
132#define WP_TPIR (1 << 5)
133#define WP_TNIR (1 << 6)
134#define WP_TCVR (1 << 7)
135#define WP_TOCR (1 << 8)
136#define WP_TOWR (1 << 9)
137#define _OMAP_TIMER_MATCH_OFFSET 0x38
138#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c
139#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40
140#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44 /* TCAR2, 34xx only */
141#define _OMAP_TIMER_TICK_POS_OFFSET 0x48 /* TPIR, 34xx only */
142#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c /* TNIR, 34xx only */
143#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50 /* TCVR, 34xx only */
144#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54 /* TOCR, 34xx only */
145#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58 /* TOWR, 34xx only */
146
147/* register offsets with the write pending bit encoded */
148#define WPSHIFT 16
149
150#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \
151 | (WP_NONE << WPSHIFT))
152
153#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \
154 | (WP_NONE << WPSHIFT))
155
156#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \
157 | (WP_NONE << WPSHIFT))
158
159#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \
160 | (WP_NONE << WPSHIFT))
161
162#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \
163 | (WP_NONE << WPSHIFT))
164
165#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \
166 | (WP_NONE << WPSHIFT))
167
168#define OMAP_TIMER_CTRL_REG (_OMAP_TIMER_CTRL_OFFSET \
169 | (WP_TCLR << WPSHIFT))
170
171#define OMAP_TIMER_COUNTER_REG (_OMAP_TIMER_COUNTER_OFFSET \
172 | (WP_TCRR << WPSHIFT))
173
174#define OMAP_TIMER_LOAD_REG (_OMAP_TIMER_LOAD_OFFSET \
175 | (WP_TLDR << WPSHIFT))
176
177#define OMAP_TIMER_TRIGGER_REG (_OMAP_TIMER_TRIGGER_OFFSET \
178 | (WP_TTGR << WPSHIFT))
179
180#define OMAP_TIMER_WRITE_PEND_REG (_OMAP_TIMER_WRITE_PEND_OFFSET \
181 | (WP_NONE << WPSHIFT))
182
183#define OMAP_TIMER_MATCH_REG (_OMAP_TIMER_MATCH_OFFSET \
184 | (WP_TMAR << WPSHIFT))
185
186#define OMAP_TIMER_CAPTURE_REG (_OMAP_TIMER_CAPTURE_OFFSET \
187 | (WP_NONE << WPSHIFT))
188
189#define OMAP_TIMER_IF_CTRL_REG (_OMAP_TIMER_IF_CTRL_OFFSET \
190 | (WP_NONE << WPSHIFT))
191
192#define OMAP_TIMER_CAPTURE2_REG (_OMAP_TIMER_CAPTURE2_OFFSET \
193 | (WP_NONE << WPSHIFT))
194
195#define OMAP_TIMER_TICK_POS_REG (_OMAP_TIMER_TICK_POS_OFFSET \
196 | (WP_TPIR << WPSHIFT))
197
198#define OMAP_TIMER_TICK_NEG_REG (_OMAP_TIMER_TICK_NEG_OFFSET \
199 | (WP_TNIR << WPSHIFT))
200
201#define OMAP_TIMER_TICK_COUNT_REG (_OMAP_TIMER_TICK_COUNT_OFFSET \
202 | (WP_TCVR << WPSHIFT))
203
204#define OMAP_TIMER_TICK_INT_MASK_SET_REG \
205 (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
206
207#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
208 (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
209
210struct omap_dm_timer {
211 unsigned long phys_base;
212 int irq;
213#ifdef CONFIG_ARCH_OMAP2PLUS
214 struct clk *iclk, *fclk;
215#endif
216 void __iomem *io_base;
217 unsigned long rate;
218 unsigned reserved:1;
219 unsigned enabled:1;
220 unsigned posted:1;
221};
222
223extern u32 sys_timer_reserved;
224void omap_dm_timer_prepare(struct omap_dm_timer *timer);
225
226static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg,
227 int posted)
228{
229 if (posted)
230 while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
231 & (reg >> WPSHIFT))
232 cpu_relax();
233
234 return __raw_readl(base + (reg & 0xff));
235}
236
237static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val,
238 int posted)
239{
240 if (posted)
241 while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
242 & (reg >> WPSHIFT))
243 cpu_relax();
244
245 __raw_writel(val, base + (reg & 0xff));
246}
247
248/* Assumes the source clock has been set by caller */
249static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,
250 int wakeup)
251{
252 u32 l;
253
254 l = __omap_dm_timer_read(base, OMAP_TIMER_OCP_CFG_REG, 0);
255 l |= 0x02 << 3; /* Set to smart-idle mode */
256 l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
257
258 if (autoidle)
259 l |= 0x1 << 0;
260
261 if (wakeup)
262 l |= 1 << 2;
263
264 __omap_dm_timer_write(base, OMAP_TIMER_OCP_CFG_REG, l, 0);
265
266 /* Match hardware reset default of posted mode */
267 __omap_dm_timer_write(base, OMAP_TIMER_IF_CTRL_REG,
268 OMAP_TIMER_CTRL_POSTED, 0);
269}
270
271static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
272 struct clk *parent)
273{
274 int ret;
275
276 clk_disable(timer_fck);
277 ret = clk_set_parent(timer_fck, parent);
278 clk_enable(timer_fck);
279
280 /*
281 * When the functional clock disappears, too quick writes seem
282 * to cause an abort. XXX Is this still necessary?
283 */
284 __delay(300000);
285
286 return ret;
287}
288
289static inline void __omap_dm_timer_stop(void __iomem *base, int posted,
290 unsigned long rate)
291{
292 u32 l;
293
294 l = __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
295 if (l & OMAP_TIMER_CTRL_ST) {
296 l &= ~0x1;
297 __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, l, posted);
298#ifdef CONFIG_ARCH_OMAP2PLUS
299 /* Readback to make sure write has completed */
300 __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
301 /*
302 * Wait for functional clock period x 3.5 to make sure that
303 * timer is stopped
304 */
305 udelay(3500000 / rate + 1);
306#endif
307 }
308
309 /* Ack possibly pending interrupt */
310 __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG,
311 OMAP_TIMER_INT_OVERFLOW, 0);
312}
313
314static inline void __omap_dm_timer_load_start(void __iomem *base, u32 ctrl,
315 unsigned int load, int posted)
316{
317 __omap_dm_timer_write(base, OMAP_TIMER_COUNTER_REG, load, posted);
318 __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, ctrl, posted);
319}
320
321static inline void __omap_dm_timer_int_enable(void __iomem *base,
322 unsigned int value)
323{
324 __omap_dm_timer_write(base, OMAP_TIMER_INT_EN_REG, value, 0);
325 __omap_dm_timer_write(base, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
326}
327
328static inline unsigned int __omap_dm_timer_read_counter(void __iomem *base,
329 int posted)
330{
331 return __omap_dm_timer_read(base, OMAP_TIMER_COUNTER_REG, posted);
332}
333
334static inline void __omap_dm_timer_write_status(void __iomem *base,
335 unsigned int value)
336{
337 __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, value, 0);
338}
96 339
97#endif /* __ASM_ARCH_DMTIMER_H */ 340#endif /* __ASM_ARCH_DMTIMER_H */
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 5a25098ea7ea..c88432005665 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -428,7 +428,11 @@
428#define INTCPS_NR_IRQS 96 428#define INTCPS_NR_IRQS 96
429 429
430#ifndef __ASSEMBLY__ 430#ifndef __ASSEMBLY__
431extern void omap_init_irq(void); 431extern void __iomem *omap_irq_base;
432void omap1_init_irq(void);
433void omap2_init_irq(void);
434void omap3_init_irq(void);
435void ti816x_init_irq(void);
432extern int omap_irq_pending(void); 436extern int omap_irq_pending(void);
433void omap_intc_save_context(void); 437void omap_intc_save_context(void);
434void omap_intc_restore_context(void); 438void omap_intc_restore_context(void);
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index f8f690ab2997..9882c657b2d4 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -24,7 +24,6 @@
24#ifndef __ASM_ARCH_OMAP_MCBSP_H 24#ifndef __ASM_ARCH_OMAP_MCBSP_H
25#define __ASM_ARCH_OMAP_MCBSP_H 25#define __ASM_ARCH_OMAP_MCBSP_H
26 26
27#include <linux/completion.h>
28#include <linux/spinlock.h> 27#include <linux/spinlock.h>
29 28
30#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -34,7 +33,7 @@
34#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \ 33#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
35static struct platform_device omap_mcbsp##port_nr = { \ 34static struct platform_device omap_mcbsp##port_nr = { \
36 .name = "omap-mcbsp-dai", \ 35 .name = "omap-mcbsp-dai", \
37 .id = OMAP_MCBSP##port_nr, \ 36 .id = port_nr - 1, \
38} 37}
39 38
40#define MCBSP_CONFIG_TYPE2 0x2 39#define MCBSP_CONFIG_TYPE2 0x2
@@ -333,18 +332,6 @@ struct omap_mcbsp_reg_cfg {
333}; 332};
334 333
335typedef enum { 334typedef enum {
336 OMAP_MCBSP1 = 0,
337 OMAP_MCBSP2,
338 OMAP_MCBSP3,
339 OMAP_MCBSP4,
340 OMAP_MCBSP5
341} omap_mcbsp_id;
342
343typedef int __bitwise omap_mcbsp_io_type_t;
344#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
345#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
346
347typedef enum {
348 OMAP_MCBSP_WORD_8 = 0, 335 OMAP_MCBSP_WORD_8 = 0,
349 OMAP_MCBSP_WORD_12, 336 OMAP_MCBSP_WORD_12,
350 OMAP_MCBSP_WORD_16, 337 OMAP_MCBSP_WORD_16,
@@ -353,38 +340,6 @@ typedef enum {
353 OMAP_MCBSP_WORD_32, 340 OMAP_MCBSP_WORD_32,
354} omap_mcbsp_word_length; 341} omap_mcbsp_word_length;
355 342
356typedef enum {
357 OMAP_MCBSP_CLK_RISING = 0,
358 OMAP_MCBSP_CLK_FALLING,
359} omap_mcbsp_clk_polarity;
360
361typedef enum {
362 OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
363 OMAP_MCBSP_FS_ACTIVE_LOW,
364} omap_mcbsp_fs_polarity;
365
366typedef enum {
367 OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
368 OMAP_MCBSP_CLK_STP_MODE_DELAY,
369} omap_mcbsp_clk_stp_mode;
370
371
372/******* SPI specific mode **********/
373typedef enum {
374 OMAP_MCBSP_SPI_MASTER = 0,
375 OMAP_MCBSP_SPI_SLAVE,
376} omap_mcbsp_spi_mode;
377
378struct omap_mcbsp_spi_cfg {
379 omap_mcbsp_spi_mode spi_mode;
380 omap_mcbsp_clk_polarity rx_clock_polarity;
381 omap_mcbsp_clk_polarity tx_clock_polarity;
382 omap_mcbsp_fs_polarity fsx_polarity;
383 u8 clk_div;
384 omap_mcbsp_clk_stp_mode clk_stp_mode;
385 omap_mcbsp_word_length word_length;
386};
387
388/* Platform specific configuration */ 343/* Platform specific configuration */
389struct omap_mcbsp_ops { 344struct omap_mcbsp_ops {
390 void (*request)(unsigned int); 345 void (*request)(unsigned int);
@@ -422,25 +377,13 @@ struct omap_mcbsp {
422 void __iomem *io_base; 377 void __iomem *io_base;
423 u8 id; 378 u8 id;
424 u8 free; 379 u8 free;
425 omap_mcbsp_word_length rx_word_length;
426 omap_mcbsp_word_length tx_word_length;
427 380
428 omap_mcbsp_io_type_t io_type; /* IRQ or poll */
429 /* IRQ based TX/RX */
430 int rx_irq; 381 int rx_irq;
431 int tx_irq; 382 int tx_irq;
432 383
433 /* DMA stuff */ 384 /* DMA stuff */
434 u8 dma_rx_sync; 385 u8 dma_rx_sync;
435 short dma_rx_lch;
436 u8 dma_tx_sync; 386 u8 dma_tx_sync;
437 short dma_tx_lch;
438
439 /* Completion queues */
440 struct completion tx_irq_completion;
441 struct completion rx_irq_completion;
442 struct completion tx_dma_completion;
443 struct completion rx_dma_completion;
444 387
445 /* Protect the field .free, while checking if the mcbsp is in use */ 388 /* Protect the field .free, while checking if the mcbsp is in use */
446 spinlock_t lock; 389 spinlock_t lock;
@@ -499,24 +442,9 @@ int omap_mcbsp_request(unsigned int id);
499void omap_mcbsp_free(unsigned int id); 442void omap_mcbsp_free(unsigned int id);
500void omap_mcbsp_start(unsigned int id, int tx, int rx); 443void omap_mcbsp_start(unsigned int id, int tx, int rx);
501void omap_mcbsp_stop(unsigned int id, int tx, int rx); 444void omap_mcbsp_stop(unsigned int id, int tx, int rx);
502void omap_mcbsp_xmit_word(unsigned int id, u32 word);
503u32 omap_mcbsp_recv_word(unsigned int id);
504
505int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
506int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
507int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
508int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
509
510 445
511/* McBSP functional clock source changing function */ 446/* McBSP functional clock source changing function */
512extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id); 447extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
513/* SPI specific API */
514void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
515
516/* Polled read/write functions */
517int omap_mcbsp_pollread(unsigned int id, u16 * buf);
518int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
519int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
520 448
521/* McBSP signal muxing API */ 449/* McBSP signal muxing API */
522void omap2_mcbsp1_mux_clkr_src(u8 mux); 450void omap2_mcbsp1_mux_clkr_src(u8 mux);
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index d86d1ecf0068..67fc5060183e 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -19,15 +19,11 @@ enum nand_io {
19}; 19};
20 20
21struct omap_nand_platform_data { 21struct omap_nand_platform_data {
22 unsigned int options;
23 int cs; 22 int cs;
24 int gpio_irq;
25 struct mtd_partition *parts; 23 struct mtd_partition *parts;
26 struct gpmc_timings *gpmc_t; 24 struct gpmc_timings *gpmc_t;
27 int nr_parts; 25 int nr_parts;
28 int (*nand_setup)(void); 26 bool dev_ready;
29 int (*dev_ready)(struct omap_nand_platform_data *);
30 int dma_channel;
31 int gpmc_irq; 27 int gpmc_irq;
32 enum nand_io xfer_type; 28 enum nand_io xfer_type;
33 unsigned long phys_base; 29 unsigned long phys_base;
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index c0a752053039..0840df813f4f 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -40,11 +40,7 @@
40 * framework starts. The "_if_" is to avoid name collisions with the 40 * framework starts. The "_if_" is to avoid name collisions with the
41 * PM idle-loop code. 41 * PM idle-loop code.
42 */ 42 */
43#ifdef CONFIG_OMAP_PM_NONE
44#define omap_pm_if_early_init() 0
45#else
46int __init omap_pm_if_early_init(void); 43int __init omap_pm_if_early_init(void);
47#endif
48 44
49/** 45/**
50 * omap_pm_if_init - OMAP PM init code called after clock fw init 46 * omap_pm_if_init - OMAP PM init code called after clock fw init
@@ -52,11 +48,7 @@ int __init omap_pm_if_early_init(void);
52 * The main initialization code. OPP tables are passed in here. The 48 * The main initialization code. OPP tables are passed in here. The
53 * "_if_" is to avoid name collisions with the PM idle-loop code. 49 * "_if_" is to avoid name collisions with the PM idle-loop code.
54 */ 50 */
55#ifdef CONFIG_OMAP_PM_NONE
56#define omap_pm_if_init() 0
57#else
58int __init omap_pm_if_init(void); 51int __init omap_pm_if_init(void);
59#endif
60 52
61/** 53/**
62 * omap_pm_if_exit - OMAP PM exit code 54 * omap_pm_if_exit - OMAP PM exit code
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c62984..ce06ac6a9709 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -77,7 +77,6 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
77#define HWMOD_IDLEMODE_FORCE (1 << 0) 77#define HWMOD_IDLEMODE_FORCE (1 << 0)
78#define HWMOD_IDLEMODE_NO (1 << 1) 78#define HWMOD_IDLEMODE_NO (1 << 1)
79#define HWMOD_IDLEMODE_SMART (1 << 2) 79#define HWMOD_IDLEMODE_SMART (1 << 2)
80/* Slave idle mode flag only */
81#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) 80#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
82 81
83/** 82/**
@@ -98,7 +97,7 @@ struct omap_hwmod_mux_info {
98/** 97/**
99 * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod 98 * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
100 * @name: name of the IRQ channel (module local name) 99 * @name: name of the IRQ channel (module local name)
101 * @irq_ch: IRQ channel ID 100 * @irq: IRQ channel ID (should be non-negative except -1 = terminator)
102 * 101 *
103 * @name should be something short, e.g., "tx" or "rx". It is for use 102 * @name should be something short, e.g., "tx" or "rx". It is for use
104 * by platform_get_resource_byname(). It is defined locally to the 103 * by platform_get_resource_byname(). It is defined locally to the
@@ -106,13 +105,13 @@ struct omap_hwmod_mux_info {
106 */ 105 */
107struct omap_hwmod_irq_info { 106struct omap_hwmod_irq_info {
108 const char *name; 107 const char *name;
109 u16 irq; 108 s16 irq;
110}; 109};
111 110
112/** 111/**
113 * struct omap_hwmod_dma_info - DMA channels used by the hwmod 112 * struct omap_hwmod_dma_info - DMA channels used by the hwmod
114 * @name: name of the DMA channel (module local name) 113 * @name: name of the DMA channel (module local name)
115 * @dma_req: DMA request ID 114 * @dma_req: DMA request ID (should be non-negative except -1 = terminator)
116 * 115 *
117 * @name should be something short, e.g., "tx" or "rx". It is for use 116 * @name should be something short, e.g., "tx" or "rx". It is for use
118 * by platform_get_resource_byname(). It is defined locally to the 117 * by platform_get_resource_byname(). It is defined locally to the
@@ -120,7 +119,7 @@ struct omap_hwmod_irq_info {
120 */ 119 */
121struct omap_hwmod_dma_info { 120struct omap_hwmod_dma_info {
122 const char *name; 121 const char *name;
123 u16 dma_req; 122 s16 dma_req;
124}; 123};
125 124
126/** 125/**
@@ -220,7 +219,6 @@ struct omap_hwmod_addr_space {
220 * @clk: interface clock: OMAP clock name 219 * @clk: interface clock: OMAP clock name
221 * @_clk: pointer to the interface struct clk (filled in at runtime) 220 * @_clk: pointer to the interface struct clk (filled in at runtime)
222 * @fw: interface firewall data 221 * @fw: interface firewall data
223 * @addr_cnt: ARRAY_SIZE(@addr)
224 * @width: OCP data width 222 * @width: OCP data width
225 * @user: initiators using this interface (see OCP_USER_* macros above) 223 * @user: initiators using this interface (see OCP_USER_* macros above)
226 * @flags: OCP interface flags (see OCPIF_* macros above) 224 * @flags: OCP interface flags (see OCPIF_* macros above)
@@ -239,7 +237,6 @@ struct omap_hwmod_ocp_if {
239 union { 237 union {
240 struct omap_hwmod_omap2_firewall omap2; 238 struct omap_hwmod_omap2_firewall omap2;
241 } fw; 239 } fw;
242 u8 addr_cnt;
243 u8 width; 240 u8 width;
244 u8 user; 241 u8 user;
245 u8 flags; 242 u8 flags;
@@ -258,6 +255,7 @@ struct omap_hwmod_ocp_if {
258#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT) 255#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
259#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT) 256#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
260#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT) 257#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
258#define MSTANDBY_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << MASTER_STANDBY_SHIFT)
261 259
262/* omap_hwmod_sysconfig.sysc_flags capability flags */ 260/* omap_hwmod_sysconfig.sysc_flags capability flags */
263#define SYSC_HAS_AUTOIDLE (1 << 0) 261#define SYSC_HAS_AUTOIDLE (1 << 0)
@@ -468,8 +466,8 @@ struct omap_hwmod_class {
468 * @name: name of the hwmod 466 * @name: name of the hwmod
469 * @class: struct omap_hwmod_class * to the class of this hwmod 467 * @class: struct omap_hwmod_class * to the class of this hwmod
470 * @od: struct omap_device currently associated with this hwmod (internal use) 468 * @od: struct omap_device currently associated with this hwmod (internal use)
471 * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt) 469 * @mpu_irqs: ptr to an array of MPU IRQs
472 * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt) 470 * @sdma_reqs: ptr to an array of System DMA request IDs
473 * @prcm: PRCM data pertaining to this hwmod 471 * @prcm: PRCM data pertaining to this hwmod
474 * @main_clk: main clock: OMAP clock name 472 * @main_clk: main clock: OMAP clock name
475 * @_clk: pointer to the main struct clk (filled in at runtime) 473 * @_clk: pointer to the main struct clk (filled in at runtime)
@@ -482,8 +480,6 @@ struct omap_hwmod_class {
482 * @_sysc_cache: internal-use hwmod flags 480 * @_sysc_cache: internal-use hwmod flags
483 * @_mpu_rt_va: cached register target start address (internal use) 481 * @_mpu_rt_va: cached register target start address (internal use)
484 * @_mpu_port_index: cached MPU register target slave ID (internal use) 482 * @_mpu_port_index: cached MPU register target slave ID (internal use)
485 * @mpu_irqs_cnt: number of @mpu_irqs
486 * @sdma_reqs_cnt: number of @sdma_reqs
487 * @opt_clks_cnt: number of @opt_clks 483 * @opt_clks_cnt: number of @opt_clks
488 * @master_cnt: number of @master entries 484 * @master_cnt: number of @master entries
489 * @slaves_cnt: number of @slave entries 485 * @slaves_cnt: number of @slave entries
@@ -531,8 +527,6 @@ struct omap_hwmod {
531 u16 flags; 527 u16 flags;
532 u8 _mpu_port_index; 528 u8 _mpu_port_index;
533 u8 response_lat; 529 u8 response_lat;
534 u8 mpu_irqs_cnt;
535 u8 sdma_reqs_cnt;
536 u8 rst_lines_cnt; 530 u8 rst_lines_cnt;
537 u8 opt_clks_cnt; 531 u8 opt_clks_cnt;
538 u8 masters_cnt; 532 u8 masters_cnt;
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 5587acf0eb2c..3c1fbdc92468 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -16,8 +16,6 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/wait.h>
20#include <linux/completion.h>
21#include <linux/interrupt.h> 19#include <linux/interrupt.h>
22#include <linux/err.h> 20#include <linux/err.h>
23#include <linux/clk.h> 21#include <linux/clk.h>
@@ -25,7 +23,6 @@
25#include <linux/io.h> 23#include <linux/io.h>
26#include <linux/slab.h> 24#include <linux/slab.h>
27 25
28#include <plat/dma.h>
29#include <plat/mcbsp.h> 26#include <plat/mcbsp.h>
30#include <plat/omap_device.h> 27#include <plat/omap_device.h>
31#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
@@ -136,8 +133,6 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
136 irqst_spcr2); 133 irqst_spcr2);
137 /* Writing zero to XSYNC_ERR clears the IRQ */ 134 /* Writing zero to XSYNC_ERR clears the IRQ */
138 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2)); 135 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
139 } else {
140 complete(&mcbsp_tx->tx_irq_completion);
141 } 136 }
142 137
143 return IRQ_HANDLED; 138 return IRQ_HANDLED;
@@ -156,41 +151,11 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
156 irqst_spcr1); 151 irqst_spcr1);
157 /* Writing zero to RSYNC_ERR clears the IRQ */ 152 /* Writing zero to RSYNC_ERR clears the IRQ */
158 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); 153 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
159 } else {
160 complete(&mcbsp_rx->rx_irq_completion);
161 } 154 }
162 155
163 return IRQ_HANDLED; 156 return IRQ_HANDLED;
164} 157}
165 158
166static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
167{
168 struct omap_mcbsp *mcbsp_dma_tx = data;
169
170 dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
171 MCBSP_READ(mcbsp_dma_tx, SPCR2));
172
173 /* We can free the channels */
174 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
175 mcbsp_dma_tx->dma_tx_lch = -1;
176
177 complete(&mcbsp_dma_tx->tx_dma_completion);
178}
179
180static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
181{
182 struct omap_mcbsp *mcbsp_dma_rx = data;
183
184 dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
185 MCBSP_READ(mcbsp_dma_rx, SPCR2));
186
187 /* We can free the channels */
188 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
189 mcbsp_dma_rx->dma_rx_lch = -1;
190
191 complete(&mcbsp_dma_rx->rx_dma_completion);
192}
193
194/* 159/*
195 * omap_mcbsp_config simply write a config to the 160 * omap_mcbsp_config simply write a config to the
196 * appropriate McBSP. 161 * appropriate McBSP.
@@ -758,37 +723,6 @@ static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
758static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {} 723static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
759#endif 724#endif
760 725
761/*
762 * We can choose between IRQ based or polled IO.
763 * This needs to be called before omap_mcbsp_request().
764 */
765int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
766{
767 struct omap_mcbsp *mcbsp;
768
769 if (!omap_mcbsp_check_valid_id(id)) {
770 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
771 return -ENODEV;
772 }
773 mcbsp = id_to_mcbsp_ptr(id);
774
775 spin_lock(&mcbsp->lock);
776
777 if (!mcbsp->free) {
778 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
779 mcbsp->id);
780 spin_unlock(&mcbsp->lock);
781 return -EINVAL;
782 }
783
784 mcbsp->io_type = io_type;
785
786 spin_unlock(&mcbsp->lock);
787
788 return 0;
789}
790EXPORT_SYMBOL(omap_mcbsp_set_io_type);
791
792int omap_mcbsp_request(unsigned int id) 726int omap_mcbsp_request(unsigned int id)
793{ 727{
794 struct omap_mcbsp *mcbsp; 728 struct omap_mcbsp *mcbsp;
@@ -833,29 +767,24 @@ int omap_mcbsp_request(unsigned int id)
833 MCBSP_WRITE(mcbsp, SPCR1, 0); 767 MCBSP_WRITE(mcbsp, SPCR1, 0);
834 MCBSP_WRITE(mcbsp, SPCR2, 0); 768 MCBSP_WRITE(mcbsp, SPCR2, 0);
835 769
836 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { 770 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
837 /* We need to get IRQs here */ 771 0, "McBSP", (void *)mcbsp);
838 init_completion(&mcbsp->tx_irq_completion); 772 if (err != 0) {
839 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, 773 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
840 0, "McBSP", (void *)mcbsp); 774 "for McBSP%d\n", mcbsp->tx_irq,
775 mcbsp->id);
776 goto err_clk_disable;
777 }
778
779 if (mcbsp->rx_irq) {
780 err = request_irq(mcbsp->rx_irq,
781 omap_mcbsp_rx_irq_handler,
782 0, "McBSP", (void *)mcbsp);
841 if (err != 0) { 783 if (err != 0) {
842 dev_err(mcbsp->dev, "Unable to request TX IRQ %d " 784 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
843 "for McBSP%d\n", mcbsp->tx_irq, 785 "for McBSP%d\n", mcbsp->rx_irq,
844 mcbsp->id); 786 mcbsp->id);
845 goto err_clk_disable; 787 goto err_free_irq;
846 }
847
848 if (mcbsp->rx_irq) {
849 init_completion(&mcbsp->rx_irq_completion);
850 err = request_irq(mcbsp->rx_irq,
851 omap_mcbsp_rx_irq_handler,
852 0, "McBSP", (void *)mcbsp);
853 if (err != 0) {
854 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
855 "for McBSP%d\n", mcbsp->rx_irq,
856 mcbsp->id);
857 goto err_free_irq;
858 }
859 } 788 }
860 } 789 }
861 790
@@ -901,12 +830,9 @@ void omap_mcbsp_free(unsigned int id)
901 830
902 pm_runtime_put_sync(mcbsp->dev); 831 pm_runtime_put_sync(mcbsp->dev);
903 832
904 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { 833 if (mcbsp->rx_irq)
905 /* Free IRQs */ 834 free_irq(mcbsp->rx_irq, (void *)mcbsp);
906 if (mcbsp->rx_irq) 835 free_irq(mcbsp->tx_irq, (void *)mcbsp);
907 free_irq(mcbsp->rx_irq, (void *)mcbsp);
908 free_irq(mcbsp->tx_irq, (void *)mcbsp);
909 }
910 836
911 reg_cache = mcbsp->reg_cache; 837 reg_cache = mcbsp->reg_cache;
912 838
@@ -943,9 +869,6 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
943 if (cpu_is_omap34xx()) 869 if (cpu_is_omap34xx())
944 omap_st_start(mcbsp); 870 omap_st_start(mcbsp);
945 871
946 mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
947 mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
948
949 /* Only enable SRG, if McBSP is master */ 872 /* Only enable SRG, if McBSP is master */
950 w = MCBSP_READ_CACHE(mcbsp, PCR0); 873 w = MCBSP_READ_CACHE(mcbsp, PCR0);
951 if (w & (FSXM | FSRM | CLKXM | CLKRM)) 874 if (w & (FSXM | FSRM | CLKXM | CLKRM))
@@ -1043,485 +966,6 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
1043} 966}
1044EXPORT_SYMBOL(omap_mcbsp_stop); 967EXPORT_SYMBOL(omap_mcbsp_stop);
1045 968
1046/* polled mcbsp i/o operations */
1047int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
1048{
1049 struct omap_mcbsp *mcbsp;
1050
1051 if (!omap_mcbsp_check_valid_id(id)) {
1052 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1053 return -ENODEV;
1054 }
1055
1056 mcbsp = id_to_mcbsp_ptr(id);
1057
1058 MCBSP_WRITE(mcbsp, DXR1, buf);
1059 /* if frame sync error - clear the error */
1060 if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
1061 /* clear error */
1062 MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
1063 /* resend */
1064 return -1;
1065 } else {
1066 /* wait for transmit confirmation */
1067 int attemps = 0;
1068 while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
1069 if (attemps++ > 1000) {
1070 MCBSP_WRITE(mcbsp, SPCR2,
1071 MCBSP_READ_CACHE(mcbsp, SPCR2) &
1072 (~XRST));
1073 udelay(10);
1074 MCBSP_WRITE(mcbsp, SPCR2,
1075 MCBSP_READ_CACHE(mcbsp, SPCR2) |
1076 (XRST));
1077 udelay(10);
1078 dev_err(mcbsp->dev, "Could not write to"
1079 " McBSP%d Register\n", mcbsp->id);
1080 return -2;
1081 }
1082 }
1083 }
1084
1085 return 0;
1086}
1087EXPORT_SYMBOL(omap_mcbsp_pollwrite);
1088
1089int omap_mcbsp_pollread(unsigned int id, u16 *buf)
1090{
1091 struct omap_mcbsp *mcbsp;
1092
1093 if (!omap_mcbsp_check_valid_id(id)) {
1094 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1095 return -ENODEV;
1096 }
1097 mcbsp = id_to_mcbsp_ptr(id);
1098
1099 /* if frame sync error - clear the error */
1100 if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
1101 /* clear error */
1102 MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
1103 /* resend */
1104 return -1;
1105 } else {
1106 /* wait for receive confirmation */
1107 int attemps = 0;
1108 while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
1109 if (attemps++ > 1000) {
1110 MCBSP_WRITE(mcbsp, SPCR1,
1111 MCBSP_READ_CACHE(mcbsp, SPCR1) &
1112 (~RRST));
1113 udelay(10);
1114 MCBSP_WRITE(mcbsp, SPCR1,
1115 MCBSP_READ_CACHE(mcbsp, SPCR1) |
1116 (RRST));
1117 udelay(10);
1118 dev_err(mcbsp->dev, "Could not read from"
1119 " McBSP%d Register\n", mcbsp->id);
1120 return -2;
1121 }
1122 }
1123 }
1124 *buf = MCBSP_READ(mcbsp, DRR1);
1125
1126 return 0;
1127}
1128EXPORT_SYMBOL(omap_mcbsp_pollread);
1129
1130/*
1131 * IRQ based word transmission.
1132 */
1133void omap_mcbsp_xmit_word(unsigned int id, u32 word)
1134{
1135 struct omap_mcbsp *mcbsp;
1136 omap_mcbsp_word_length word_length;
1137
1138 if (!omap_mcbsp_check_valid_id(id)) {
1139 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1140 return;
1141 }
1142
1143 mcbsp = id_to_mcbsp_ptr(id);
1144 word_length = mcbsp->tx_word_length;
1145
1146 wait_for_completion(&mcbsp->tx_irq_completion);
1147
1148 if (word_length > OMAP_MCBSP_WORD_16)
1149 MCBSP_WRITE(mcbsp, DXR2, word >> 16);
1150 MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
1151}
1152EXPORT_SYMBOL(omap_mcbsp_xmit_word);
1153
1154u32 omap_mcbsp_recv_word(unsigned int id)
1155{
1156 struct omap_mcbsp *mcbsp;
1157 u16 word_lsb, word_msb = 0;
1158 omap_mcbsp_word_length word_length;
1159
1160 if (!omap_mcbsp_check_valid_id(id)) {
1161 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1162 return -ENODEV;
1163 }
1164 mcbsp = id_to_mcbsp_ptr(id);
1165
1166 word_length = mcbsp->rx_word_length;
1167
1168 wait_for_completion(&mcbsp->rx_irq_completion);
1169
1170 if (word_length > OMAP_MCBSP_WORD_16)
1171 word_msb = MCBSP_READ(mcbsp, DRR2);
1172 word_lsb = MCBSP_READ(mcbsp, DRR1);
1173
1174 return (word_lsb | (word_msb << 16));
1175}
1176EXPORT_SYMBOL(omap_mcbsp_recv_word);
1177
1178int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
1179{
1180 struct omap_mcbsp *mcbsp;
1181 omap_mcbsp_word_length tx_word_length;
1182 omap_mcbsp_word_length rx_word_length;
1183 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
1184
1185 if (!omap_mcbsp_check_valid_id(id)) {
1186 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1187 return -ENODEV;
1188 }
1189 mcbsp = id_to_mcbsp_ptr(id);
1190 tx_word_length = mcbsp->tx_word_length;
1191 rx_word_length = mcbsp->rx_word_length;
1192
1193 if (tx_word_length != rx_word_length)
1194 return -EINVAL;
1195
1196 /* First we wait for the transmitter to be ready */
1197 spcr2 = MCBSP_READ(mcbsp, SPCR2);
1198 while (!(spcr2 & XRDY)) {
1199 spcr2 = MCBSP_READ(mcbsp, SPCR2);
1200 if (attempts++ > 1000) {
1201 /* We must reset the transmitter */
1202 MCBSP_WRITE(mcbsp, SPCR2,
1203 MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
1204 udelay(10);
1205 MCBSP_WRITE(mcbsp, SPCR2,
1206 MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
1207 udelay(10);
1208 dev_err(mcbsp->dev, "McBSP%d transmitter not "
1209 "ready\n", mcbsp->id);
1210 return -EAGAIN;
1211 }
1212 }
1213
1214 /* Now we can push the data */
1215 if (tx_word_length > OMAP_MCBSP_WORD_16)
1216 MCBSP_WRITE(mcbsp, DXR2, word >> 16);
1217 MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
1218
1219 /* We wait for the receiver to be ready */
1220 spcr1 = MCBSP_READ(mcbsp, SPCR1);
1221 while (!(spcr1 & RRDY)) {
1222 spcr1 = MCBSP_READ(mcbsp, SPCR1);
1223 if (attempts++ > 1000) {
1224 /* We must reset the receiver */
1225 MCBSP_WRITE(mcbsp, SPCR1,
1226 MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
1227 udelay(10);
1228 MCBSP_WRITE(mcbsp, SPCR1,
1229 MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
1230 udelay(10);
1231 dev_err(mcbsp->dev, "McBSP%d receiver not "
1232 "ready\n", mcbsp->id);
1233 return -EAGAIN;
1234 }
1235 }
1236
1237 /* Receiver is ready, let's read the dummy data */
1238 if (rx_word_length > OMAP_MCBSP_WORD_16)
1239 word_msb = MCBSP_READ(mcbsp, DRR2);
1240 word_lsb = MCBSP_READ(mcbsp, DRR1);
1241
1242 return 0;
1243}
1244EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
1245
1246int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
1247{
1248 struct omap_mcbsp *mcbsp;
1249 u32 clock_word = 0;
1250 omap_mcbsp_word_length tx_word_length;
1251 omap_mcbsp_word_length rx_word_length;
1252 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
1253
1254 if (!omap_mcbsp_check_valid_id(id)) {
1255 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1256 return -ENODEV;
1257 }
1258
1259 mcbsp = id_to_mcbsp_ptr(id);
1260
1261 tx_word_length = mcbsp->tx_word_length;
1262 rx_word_length = mcbsp->rx_word_length;
1263
1264 if (tx_word_length != rx_word_length)
1265 return -EINVAL;
1266
1267 /* First we wait for the transmitter to be ready */
1268 spcr2 = MCBSP_READ(mcbsp, SPCR2);
1269 while (!(spcr2 & XRDY)) {
1270 spcr2 = MCBSP_READ(mcbsp, SPCR2);
1271 if (attempts++ > 1000) {
1272 /* We must reset the transmitter */
1273 MCBSP_WRITE(mcbsp, SPCR2,
1274 MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
1275 udelay(10);
1276 MCBSP_WRITE(mcbsp, SPCR2,
1277 MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
1278 udelay(10);
1279 dev_err(mcbsp->dev, "McBSP%d transmitter not "
1280 "ready\n", mcbsp->id);
1281 return -EAGAIN;
1282 }
1283 }
1284
1285 /* We first need to enable the bus clock */
1286 if (tx_word_length > OMAP_MCBSP_WORD_16)
1287 MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
1288 MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
1289
1290 /* We wait for the receiver to be ready */
1291 spcr1 = MCBSP_READ(mcbsp, SPCR1);
1292 while (!(spcr1 & RRDY)) {
1293 spcr1 = MCBSP_READ(mcbsp, SPCR1);
1294 if (attempts++ > 1000) {
1295 /* We must reset the receiver */
1296 MCBSP_WRITE(mcbsp, SPCR1,
1297 MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
1298 udelay(10);
1299 MCBSP_WRITE(mcbsp, SPCR1,
1300 MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
1301 udelay(10);
1302 dev_err(mcbsp->dev, "McBSP%d receiver not "
1303 "ready\n", mcbsp->id);
1304 return -EAGAIN;
1305 }
1306 }
1307
1308 /* Receiver is ready, there is something for us */
1309 if (rx_word_length > OMAP_MCBSP_WORD_16)
1310 word_msb = MCBSP_READ(mcbsp, DRR2);
1311 word_lsb = MCBSP_READ(mcbsp, DRR1);
1312
1313 word[0] = (word_lsb | (word_msb << 16));
1314
1315 return 0;
1316}
1317EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
1318
1319/*
1320 * Simple DMA based buffer rx/tx routines.
1321 * Nothing fancy, just a single buffer tx/rx through DMA.
1322 * The DMA resources are released once the transfer is done.
1323 * For anything fancier, you should use your own customized DMA
1324 * routines and callbacks.
1325 */
1326int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
1327 unsigned int length)
1328{
1329 struct omap_mcbsp *mcbsp;
1330 int dma_tx_ch;
1331 int src_port = 0;
1332 int dest_port = 0;
1333 int sync_dev = 0;
1334
1335 if (!omap_mcbsp_check_valid_id(id)) {
1336 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1337 return -ENODEV;
1338 }
1339 mcbsp = id_to_mcbsp_ptr(id);
1340
1341 if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
1342 omap_mcbsp_tx_dma_callback,
1343 mcbsp,
1344 &dma_tx_ch)) {
1345 dev_err(mcbsp->dev, " Unable to request DMA channel for "
1346 "McBSP%d TX. Trying IRQ based TX\n",
1347 mcbsp->id);
1348 return -EAGAIN;
1349 }
1350 mcbsp->dma_tx_lch = dma_tx_ch;
1351
1352 dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
1353 dma_tx_ch);
1354
1355 init_completion(&mcbsp->tx_dma_completion);
1356
1357 if (cpu_class_is_omap1()) {
1358 src_port = OMAP_DMA_PORT_TIPB;
1359 dest_port = OMAP_DMA_PORT_EMIFF;
1360 }
1361 if (cpu_class_is_omap2())
1362 sync_dev = mcbsp->dma_tx_sync;
1363
1364 omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
1365 OMAP_DMA_DATA_TYPE_S16,
1366 length >> 1, 1,
1367 OMAP_DMA_SYNC_ELEMENT,
1368 sync_dev, 0);
1369
1370 omap_set_dma_dest_params(mcbsp->dma_tx_lch,
1371 src_port,
1372 OMAP_DMA_AMODE_CONSTANT,
1373 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
1374 0, 0);
1375
1376 omap_set_dma_src_params(mcbsp->dma_tx_lch,
1377 dest_port,
1378 OMAP_DMA_AMODE_POST_INC,
1379 buffer,
1380 0, 0);
1381
1382 omap_start_dma(mcbsp->dma_tx_lch);
1383 wait_for_completion(&mcbsp->tx_dma_completion);
1384
1385 return 0;
1386}
1387EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
1388
1389int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
1390 unsigned int length)
1391{
1392 struct omap_mcbsp *mcbsp;
1393 int dma_rx_ch;
1394 int src_port = 0;
1395 int dest_port = 0;
1396 int sync_dev = 0;
1397
1398 if (!omap_mcbsp_check_valid_id(id)) {
1399 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1400 return -ENODEV;
1401 }
1402 mcbsp = id_to_mcbsp_ptr(id);
1403
1404 if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
1405 omap_mcbsp_rx_dma_callback,
1406 mcbsp,
1407 &dma_rx_ch)) {
1408 dev_err(mcbsp->dev, "Unable to request DMA channel for "
1409 "McBSP%d RX. Trying IRQ based RX\n",
1410 mcbsp->id);
1411 return -EAGAIN;
1412 }
1413 mcbsp->dma_rx_lch = dma_rx_ch;
1414
1415 dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
1416 dma_rx_ch);
1417
1418 init_completion(&mcbsp->rx_dma_completion);
1419
1420 if (cpu_class_is_omap1()) {
1421 src_port = OMAP_DMA_PORT_TIPB;
1422 dest_port = OMAP_DMA_PORT_EMIFF;
1423 }
1424 if (cpu_class_is_omap2())
1425 sync_dev = mcbsp->dma_rx_sync;
1426
1427 omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
1428 OMAP_DMA_DATA_TYPE_S16,
1429 length >> 1, 1,
1430 OMAP_DMA_SYNC_ELEMENT,
1431 sync_dev, 0);
1432
1433 omap_set_dma_src_params(mcbsp->dma_rx_lch,
1434 src_port,
1435 OMAP_DMA_AMODE_CONSTANT,
1436 mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
1437 0, 0);
1438
1439 omap_set_dma_dest_params(mcbsp->dma_rx_lch,
1440 dest_port,
1441 OMAP_DMA_AMODE_POST_INC,
1442 buffer,
1443 0, 0);
1444
1445 omap_start_dma(mcbsp->dma_rx_lch);
1446 wait_for_completion(&mcbsp->rx_dma_completion);
1447
1448 return 0;
1449}
1450EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
1451
1452/*
1453 * SPI wrapper.
1454 * Since SPI setup is much simpler than the generic McBSP one,
1455 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
1456 * Once this is done, you can call omap_mcbsp_start().
1457 */
1458void omap_mcbsp_set_spi_mode(unsigned int id,
1459 const struct omap_mcbsp_spi_cfg *spi_cfg)
1460{
1461 struct omap_mcbsp *mcbsp;
1462 struct omap_mcbsp_reg_cfg mcbsp_cfg;
1463
1464 if (!omap_mcbsp_check_valid_id(id)) {
1465 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1466 return;
1467 }
1468 mcbsp = id_to_mcbsp_ptr(id);
1469
1470 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
1471
1472 /* SPI has only one frame */
1473 mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
1474 mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
1475
1476 /* Clock stop mode */
1477 if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
1478 mcbsp_cfg.spcr1 |= (1 << 12);
1479 else
1480 mcbsp_cfg.spcr1 |= (3 << 11);
1481
1482 /* Set clock parities */
1483 if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
1484 mcbsp_cfg.pcr0 |= CLKRP;
1485 else
1486 mcbsp_cfg.pcr0 &= ~CLKRP;
1487
1488 if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
1489 mcbsp_cfg.pcr0 &= ~CLKXP;
1490 else
1491 mcbsp_cfg.pcr0 |= CLKXP;
1492
1493 /* Set SCLKME to 0 and CLKSM to 1 */
1494 mcbsp_cfg.pcr0 &= ~SCLKME;
1495 mcbsp_cfg.srgr2 |= CLKSM;
1496
1497 /* Set FSXP */
1498 if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
1499 mcbsp_cfg.pcr0 &= ~FSXP;
1500 else
1501 mcbsp_cfg.pcr0 |= FSXP;
1502
1503 if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
1504 mcbsp_cfg.pcr0 |= CLKXM;
1505 mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
1506 mcbsp_cfg.pcr0 |= FSXM;
1507 mcbsp_cfg.srgr2 &= ~FSGM;
1508 mcbsp_cfg.xcr2 |= XDATDLY(1);
1509 mcbsp_cfg.rcr2 |= RDATDLY(1);
1510 } else {
1511 mcbsp_cfg.pcr0 &= ~CLKXM;
1512 mcbsp_cfg.srgr1 |= CLKGDV(1);
1513 mcbsp_cfg.pcr0 &= ~FSXM;
1514 mcbsp_cfg.xcr2 &= ~XDATDLY(3);
1515 mcbsp_cfg.rcr2 &= ~RDATDLY(3);
1516 }
1517
1518 mcbsp_cfg.xcr2 &= ~XPHASE;
1519 mcbsp_cfg.rcr2 &= ~RPHASE;
1520
1521 omap_mcbsp_config(id, &mcbsp_cfg);
1522}
1523EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
1524
1525#ifdef CONFIG_ARCH_OMAP3 969#ifdef CONFIG_ARCH_OMAP3
1526#define max_thres(m) (mcbsp->pdata->buffer_size) 970#define max_thres(m) (mcbsp->pdata->buffer_size)
1527#define valid_threshold(m, val) ((val) <= max_thres(m)) 971#define valid_threshold(m, val) ((val) <= max_thres(m))
@@ -1833,8 +1277,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1833 spin_lock_init(&mcbsp->lock); 1277 spin_lock_init(&mcbsp->lock);
1834 mcbsp->id = id + 1; 1278 mcbsp->id = id + 1;
1835 mcbsp->free = true; 1279 mcbsp->free = true;
1836 mcbsp->dma_tx_lch = -1;
1837 mcbsp->dma_rx_lch = -1;
1838 1280
1839 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 1281 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
1840 if (!res) { 1282 if (!res) {
@@ -1860,9 +1302,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1860 else 1302 else
1861 mcbsp->phys_dma_base = res->start; 1303 mcbsp->phys_dma_base = res->start;
1862 1304
1863 /* Default I/O is IRQ based */
1864 mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
1865
1866 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx"); 1305 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
1867 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx"); 1306 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
1868 1307
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 2526fa312b8a..3471c650743b 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -236,11 +236,6 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
236 return 0; 236 return 0;
237} 237}
238 238
239static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
240{
241 return container_of(pdev, struct omap_device, pdev);
242}
243
244/** 239/**
245 * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks 240 * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks
246 * @od: struct omap_device *od 241 * @od: struct omap_device *od
@@ -316,7 +311,7 @@ u32 omap_device_get_context_loss_count(struct platform_device *pdev)
316 struct omap_device *od; 311 struct omap_device *od;
317 u32 ret = 0; 312 u32 ret = 0;
318 313
319 od = _find_by_pdev(pdev); 314 od = to_omap_device(pdev);
320 315
321 if (od->hwmods_cnt) 316 if (od->hwmods_cnt)
322 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); 317 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
@@ -654,7 +649,7 @@ int omap_device_enable(struct platform_device *pdev)
654 int ret; 649 int ret;
655 struct omap_device *od; 650 struct omap_device *od;
656 651
657 od = _find_by_pdev(pdev); 652 od = to_omap_device(pdev);
658 653
659 if (od->_state == OMAP_DEVICE_STATE_ENABLED) { 654 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
660 WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", 655 WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
@@ -693,7 +688,7 @@ int omap_device_idle(struct platform_device *pdev)
693 int ret; 688 int ret;
694 struct omap_device *od; 689 struct omap_device *od;
695 690
696 od = _find_by_pdev(pdev); 691 od = to_omap_device(pdev);
697 692
698 if (od->_state != OMAP_DEVICE_STATE_ENABLED) { 693 if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
699 WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", 694 WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
@@ -724,7 +719,7 @@ int omap_device_shutdown(struct platform_device *pdev)
724 int ret, i; 719 int ret, i;
725 struct omap_device *od; 720 struct omap_device *od;
726 721
727 od = _find_by_pdev(pdev); 722 od = to_omap_device(pdev);
728 723
729 if (od->_state != OMAP_DEVICE_STATE_ENABLED && 724 if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
730 od->_state != OMAP_DEVICE_STATE_IDLE) { 725 od->_state != OMAP_DEVICE_STATE_IDLE) {
@@ -765,7 +760,7 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
765 int ret = -EINVAL; 760 int ret = -EINVAL;
766 struct omap_device *od; 761 struct omap_device *od;
767 762
768 od = _find_by_pdev(pdev); 763 od = to_omap_device(pdev);
769 764
770 if (new_wakeup_lat_limit == od->dev_wakeup_lat) 765 if (new_wakeup_lat_limit == od->dev_wakeup_lat)
771 return 0; 766 return 0;