summaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 19:13:58 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 19:13:58 -0800
commit01539ba2a706ab7d35fc0667dff919ade7f87d63 (patch)
tree5a4bd0cf78007d06690fe4ac06bbd49a5a70bc47 /arch/arm/plat-omap
parent9e9bc9736756f25d6c47b4eba0ebf25b20a6f153 (diff)
parentdc69d1af9e8d9cbbabff88bb35a6782187a22229 (diff)
downloadlinux-01539ba2a706ab7d35fc0667dff919ade7f87d63.tar.bz2
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (243 commits) omap2: Make OMAP2PLUS select OMAP_DM_TIMER OMAP4: hwmod data: Fix alignment and end of line in structurefields OMAP4: hwmod data: Move the DMA structures OMAP4: hwmod data: Move the smartreflex structures OMAP4: hwmod data: Fix missing SIDLE_SMART_WKUP in smartreflexsysc arm: omap: tusb6010: add name for MUSB IRQ arm: omap: craneboard: Add USB EHCI support omap2+: Initialize serial port for dynamic remuxing for n8x0 omap2+: Add struct omap_board_data and use it for platform level serial init omap2+: Allow hwmod state changes to mux pads based on the state changes omap2+: Add support for hwmod specific muxing of devices omap2+: Add omap_mux_get_by_name OMAP2: PM: fix compile error when !CONFIG_SUSPEND MAINTAINERS: OMAP: hwmod: update hwmod code, data maintainership OMAP4: Smartreflex framework extensions OMAP4: hwmod: Add inital data for smartreflex modules. OMAP4: PM: Program correct init voltages for scalable VDDs OMAP4: Adding voltage driver support OMAP4: Register voltage PMIC parameters with the voltage layer OMAP3: PM: Program correct init voltages for VDD1 and VDD2 ... Fix up trivial conflict in arch/arm/plat-omap/Kconfig
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig35
-rw-r--r--arch/arm/plat-omap/devices.c40
-rw-r--r--arch/arm/plat-omap/dma.c695
-rw-r--r--arch/arm/plat-omap/gpio.c670
-rw-r--r--arch/arm/plat-omap/i2c.c128
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h20
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h16
-rw-r--r--arch/arm/plat-omap/include/plat/clockdomain.h141
-rw-r--r--arch/arm/plat-omap/include/plat/common.h2
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h232
-rw-r--r--arch/arm/plat-omap/include/plat/fpga.h4
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h48
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc.h9
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h13
-rw-r--r--arch/arm/plat-omap/include/plat/io.h5
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h5
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-omap/include/plat/keypad.h35
-rw-r--r--arch/arm/plat-omap/include/plat/l4_3xxx.h24
-rw-r--r--arch/arm/plat-omap/include/plat/mailbox.h8
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h39
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h14
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h73
-rw-r--r--arch/arm/plat-omap/include/plat/powerdomain.h167
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h20
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h5
-rw-r--r--arch/arm/plat-omap/include/plat/smartreflex.h245
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h11
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h3
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h146
-rw-r--r--arch/arm/plat-omap/io.c58
-rw-r--r--arch/arm/plat-omap/iommu.c24
-rw-r--r--arch/arm/plat-omap/iovmm.c81
-rw-r--r--arch/arm/plat-omap/mailbox.c130
-rw-r--r--arch/arm/plat-omap/mcbsp.c26
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c78
-rw-r--r--arch/arm/plat-omap/omap_device.c28
-rw-r--r--arch/arm/plat-omap/sram.c14
39 files changed, 1567 insertions, 1728 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index c9408434a855..18fe3cb195dc 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -18,6 +18,7 @@ config ARCH_OMAP1
config ARCH_OMAP2PLUS
bool "TI OMAP2/3/4"
select CLKDEV_LOOKUP
+ select OMAP_DM_TIMER
help
"Systems based on OMAP2, OMAP3 or OMAP4"
@@ -35,6 +36,37 @@ config OMAP_DEBUG_LEDS
depends on OMAP_DEBUG_DEVICES
default y if LEDS_CLASS
+config OMAP_SMARTREFLEX
+ bool "SmartReflex support"
+ depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ help
+ Say Y if you want to enable SmartReflex.
+
+ SmartReflex can perform continuous dynamic voltage
+ scaling around the nominal operating point voltage
+ according to silicon characteristics and operating
+ conditions. Enabling SmartReflex reduces power
+ consumption.
+
+ Please note, that by default SmartReflex is only
+ initialized. To enable the automatic voltage
+ compensation for vdd mpu and vdd core from user space,
+ user must write 1 to
+ /debug/voltage/vdd_<X>/smartreflex/autocomp,
+ where X is mpu or core for OMAP3.
+ Optionallly autocompensation can be enabled in the kernel
+ by default during system init via the enable_on_init flag
+ which an be passed as platform data to the smartreflex driver.
+
+config OMAP_SMARTREFLEX_CLASS3
+ bool "Class 3 mode of Smartreflex Implementation"
+ depends on OMAP_SMARTREFLEX && TWL4030_CORE
+ help
+ Say Y to enable Class 3 implementation of Smartreflex
+
+ Class 3 implementation of Smartreflex employs continuous hardware
+ voltage calibration.
+
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_OMAP
@@ -109,6 +141,9 @@ config OMAP_IOMMU_DEBUG
Say N unless you know you need this.
+config OMAP_IOMMU_IVA2
+ bool
+
choice
prompt "System timer"
default OMAP_32K_TIMER if !ARCH_OMAP15XX
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index fc819120978d..10245b837c10 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -232,46 +232,6 @@ static void omap_init_uwire(void)
static inline void omap_init_uwire(void) {}
#endif
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
-
-static struct resource wdt_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device omap_wdt_device = {
- .name = "omap_wdt",
- .id = -1,
- .num_resources = ARRAY_SIZE(wdt_resources),
- .resource = wdt_resources,
-};
-
-static void omap_init_wdt(void)
-{
- if (cpu_is_omap16xx())
- wdt_resources[0].start = 0xfffeb000;
- else if (cpu_is_omap2420())
- wdt_resources[0].start = 0x48022000; /* WDT2 */
- else if (cpu_is_omap2430())
- wdt_resources[0].start = 0x49016000; /* WDT2 */
- else if (cpu_is_omap343x())
- wdt_resources[0].start = 0x48314000; /* WDT2 */
- else if (cpu_is_omap44xx())
- wdt_resources[0].start = 0x4a314000;
- else
- return;
-
- wdt_resources[0].end = wdt_resources[0].start + 0x4f;
-
- (void) platform_device_register(&omap_wdt_device);
-}
-#else
-static inline void omap_init_wdt(void) {}
-#endif
-
#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
static phys_addr_t omap_dsp_phys_mempool_base;
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 2c2826571d45..c4b2b478b1a5 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -15,6 +15,10 @@
*
* Support functions for the OMAP internal DMA channels.
*
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into DMA platform driver.
+ * - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -53,7 +57,11 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+static struct omap_system_dma_plat_info *p;
+static struct omap_dma_dev_attr *d;
+
static int enable_1510_mode;
+static u32 errata;
static struct omap_dma_global_context_registers {
u32 dma_irqenable_l0;
@@ -61,27 +69,6 @@ static struct omap_dma_global_context_registers {
u32 dma_gcr;
} omap_dma_global_context;
-struct omap_dma_lch {
- int next_lch;
- int dev_id;
- u16 saved_csr;
- u16 enabled_irqs;
- const char *dev_name;
- void (*callback)(int lch, u16 ch_status, void *data);
- void *data;
-
-#ifndef CONFIG_ARCH_OMAP1
- /* required for Dynamic chaining */
- int prev_linked_ch;
- int next_linked_ch;
- int state;
- int chain_id;
-
- int status;
-#endif
- long flags;
-};
-
struct dma_link_info {
int *linked_dmach_q;
int no_of_lchs_linked;
@@ -137,15 +124,6 @@ static int omap_dma_reserve_channels;
static spinlock_t dma_chan_lock;
static struct omap_dma_lch *dma_chan;
-static void __iomem *omap_dma_base;
-
-static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
- INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
- INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
- INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
- INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
- INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
-};
static inline void disable_lnk(int lch);
static void omap_disable_channel_irq(int lch);
@@ -154,24 +132,6 @@ static inline void omap_enable_channel_irq(int lch);
#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
__func__);
-#define dma_read(reg) \
-({ \
- u32 __val; \
- if (cpu_class_is_omap1()) \
- __val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \
- else \
- __val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \
- __val; \
-})
-
-#define dma_write(val, reg) \
-({ \
- if (cpu_class_is_omap1()) \
- __raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \
- else \
- __raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \
-})
-
#ifdef CONFIG_ARCH_OMAP15XX
/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
int omap_dma_in_1510_mode(void)
@@ -206,16 +166,6 @@ static inline void set_gdma_dev(int req, int dev)
#define set_gdma_dev(req, dev) do {} while (0)
#endif
-/* Omap1 only */
-static void clear_lch_regs(int lch)
-{
- int i;
- void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch);
-
- for (i = 0; i < 0x2c; i += 2)
- __raw_writew(0, lch_base + i);
-}
-
void omap_set_dma_priority(int lch, int dst_port, int priority)
{
unsigned long reg;
@@ -248,12 +198,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
if (cpu_class_is_omap2()) {
u32 ccr;
- ccr = dma_read(CCR(lch));
+ ccr = p->dma_read(CCR, lch);
if (priority)
ccr |= (1 << 6);
else
ccr &= ~(1 << 6);
- dma_write(ccr, CCR(lch));
+ p->dma_write(ccr, CCR, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_priority);
@@ -264,31 +214,31 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~0x03;
l |= data_type;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
if (cpu_class_is_omap1()) {
u16 ccr;
- ccr = dma_read(CCR(lch));
+ ccr = p->dma_read(CCR, lch);
ccr &= ~(1 << 5);
if (sync_mode == OMAP_DMA_SYNC_FRAME)
ccr |= 1 << 5;
- dma_write(ccr, CCR(lch));
+ p->dma_write(ccr, CCR, lch);
- ccr = dma_read(CCR2(lch));
+ ccr = p->dma_read(CCR2, lch);
ccr &= ~(1 << 2);
if (sync_mode == OMAP_DMA_SYNC_BLOCK)
ccr |= 1 << 2;
- dma_write(ccr, CCR2(lch));
+ p->dma_write(ccr, CCR2, lch);
}
if (cpu_class_is_omap2() && dma_trigger) {
u32 val;
- val = dma_read(CCR(lch));
+ val = p->dma_read(CCR, lch);
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
val &= ~((1 << 23) | (3 << 19) | 0x1f);
@@ -313,11 +263,11 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
} else {
val &= ~(1 << 24); /* dest synch */
}
- dma_write(val, CCR(lch));
+ p->dma_write(val, CCR, lch);
}
- dma_write(elem_count, CEN(lch));
- dma_write(frame_count, CFN(lch));
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
}
EXPORT_SYMBOL(omap_set_dma_transfer_params);
@@ -328,7 +278,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CCR2(lch));
+ w = p->dma_read(CCR2, lch);
w &= ~0x03;
switch (mode) {
@@ -343,23 +293,22 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(w, CCR2(lch));
+ p->dma_write(w, CCR2, lch);
- w = dma_read(LCH_CTRL(lch));
+ w = p->dma_read(LCH_CTRL, lch);
w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
- dma_write((u16)color, COLOR_L(lch));
- dma_write((u16)(color >> 16), COLOR_U(lch));
+ p->dma_write(color, COLOR, lch);
w |= 1; /* Channel type G */
}
- dma_write(w, LCH_CTRL(lch));
+ p->dma_write(w, LCH_CTRL, lch);
}
if (cpu_class_is_omap2()) {
u32 val;
- val = dma_read(CCR(lch));
+ val = p->dma_read(CCR, lch);
val &= ~((1 << 17) | (1 << 16));
switch (mode) {
@@ -374,10 +323,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(val, CCR(lch));
+ p->dma_write(val, CCR, lch);
color &= 0xffffff;
- dma_write(color, COLOR(lch));
+ p->dma_write(color, COLOR, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_color_mode);
@@ -387,10 +336,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
if (cpu_class_is_omap2()) {
u32 csdp;
- csdp = dma_read(CSDP(lch));
+ csdp = p->dma_read(CSDP, lch);
csdp &= ~(0x3 << 16);
csdp |= (mode << 16);
- dma_write(csdp, CSDP(lch));
+ p->dma_write(csdp, CSDP, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_write_mode);
@@ -400,10 +349,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
u32 l;
- l = dma_read(LCH_CTRL(lch));
+ l = p->dma_read(LCH_CTRL, lch);
l &= ~0x7;
l |= mode;
- dma_write(l, LCH_CTRL(lch));
+ p->dma_write(l, LCH_CTRL, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_channel_mode);
@@ -418,27 +367,21 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CSDP(lch));
+ w = p->dma_read(CSDP, lch);
w &= ~(0x1f << 2);
w |= src_port << 2;
- dma_write(w, CSDP(lch));
+ p->dma_write(w, CSDP, lch);
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~(0x03 << 12);
l |= src_amode << 12;
- dma_write(l, CCR(lch));
-
- if (cpu_class_is_omap1()) {
- dma_write(src_start >> 16, CSSA_U(lch));
- dma_write((u16)src_start, CSSA_L(lch));
- }
+ p->dma_write(l, CCR, lch);
- if (cpu_class_is_omap2())
- dma_write(src_start, CSSA(lch));
+ p->dma_write(src_start, CSSA, lch);
- dma_write(src_ei, CSEI(lch));
- dma_write(src_fi, CSFI(lch));
+ p->dma_write(src_ei, CSEI, lch);
+ p->dma_write(src_fi, CSFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_params);
@@ -466,8 +409,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CSEI(lch));
- dma_write(fidx, CSFI(lch));
+ p->dma_write(eidx, CSEI, lch);
+ p->dma_write(fidx, CSFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_index);
@@ -475,11 +418,11 @@ void omap_set_dma_src_data_pack(int lch, int enable)
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(1 << 6);
if (enable)
l |= (1 << 6);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_data_pack);
@@ -488,7 +431,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned int burst = 0;
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x03 << 7);
switch (burst_mode) {
@@ -524,7 +467,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
}
l |= (burst << 7);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
@@ -536,27 +479,21 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
u32 l;
if (cpu_class_is_omap1()) {
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x1f << 9);
l |= dest_port << 9;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~(0x03 << 14);
l |= dest_amode << 14;
- dma_write(l, CCR(lch));
-
- if (cpu_class_is_omap1()) {
- dma_write(dest_start >> 16, CDSA_U(lch));
- dma_write(dest_start, CDSA_L(lch));
- }
+ p->dma_write(l, CCR, lch);
- if (cpu_class_is_omap2())
- dma_write(dest_start, CDSA(lch));
+ p->dma_write(dest_start, CDSA, lch);
- dma_write(dst_ei, CDEI(lch));
- dma_write(dst_fi, CDFI(lch));
+ p->dma_write(dst_ei, CDEI, lch);
+ p->dma_write(dst_fi, CDFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_params);
@@ -565,8 +502,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CDEI(lch));
- dma_write(fidx, CDFI(lch));
+ p->dma_write(eidx, CDEI, lch);
+ p->dma_write(fidx, CDFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_index);
@@ -574,11 +511,11 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(1 << 13);
if (enable)
l |= 1 << 13;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
@@ -587,7 +524,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned int burst = 0;
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x03 << 14);
switch (burst_mode) {
@@ -620,7 +557,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
return;
}
l |= (burst << 14);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
@@ -630,18 +567,18 @@ static inline void omap_enable_channel_irq(int lch)
/* Clear CSR */
if (cpu_class_is_omap1())
- status = dma_read(CSR(lch));
+ status = p->dma_read(CSR, lch);
else if (cpu_class_is_omap2())
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
/* Enable some nice interrupts. */
- dma_write(dma_chan[lch].enabled_irqs, CICR(lch));
+ p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
}
static void omap_disable_channel_irq(int lch)
{
if (cpu_class_is_omap2())
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
}
void omap_enable_dma_irq(int lch, u16 bits)
@@ -660,7 +597,7 @@ static inline void enable_lnk(int lch)
{
u32 l;
- l = dma_read(CLNK_CTRL(lch));
+ l = p->dma_read(CLNK_CTRL, lch);
if (cpu_class_is_omap1())
l &= ~(1 << 14);
@@ -675,18 +612,18 @@ static inline void enable_lnk(int lch)
l = dma_chan[lch].next_linked_ch | (1 << 15);
#endif
- dma_write(l, CLNK_CTRL(lch));
+ p->dma_write(l, CLNK_CTRL, lch);
}
static inline void disable_lnk(int lch)
{
u32 l;
- l = dma_read(CLNK_CTRL(lch));
+ l = p->dma_read(CLNK_CTRL, lch);
/* Disable interrupts */
if (cpu_class_is_omap1()) {
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Set the STOP_LNK bit */
l |= 1 << 14;
}
@@ -697,7 +634,7 @@ static inline void disable_lnk(int lch)
l &= ~(1 << 15);
}
- dma_write(l, CLNK_CTRL(lch));
+ p->dma_write(l, CLNK_CTRL, lch);
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
@@ -710,9 +647,9 @@ static inline void omap2_enable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0);
+ val = p->dma_read(IRQENABLE_L0, lch);
val |= 1 << lch;
- dma_write(val, IRQENABLE_L0);
+ p->dma_write(val, IRQENABLE_L0, lch);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -725,9 +662,9 @@ static inline void omap2_disable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0);
+ val = p->dma_read(IRQENABLE_L0, lch);
val &= ~(1 << lch);
- dma_write(val, IRQENABLE_L0);
+ p->dma_write(val, IRQENABLE_L0, lch);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -754,8 +691,8 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan = dma_chan + free_ch;
chan->dev_id = dev_id;
- if (cpu_class_is_omap1())
- clear_lch_regs(free_ch);
+ if (p->clear_lch_regs)
+ p->clear_lch_regs(free_ch);
if (cpu_class_is_omap2())
omap_clear_dma(free_ch);
@@ -792,17 +729,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
* Disable the 1510 compatibility mode and set the sync device
* id.
*/
- dma_write(dev_id | (1 << 10), CCR(free_ch));
+ p->dma_write(dev_id | (1 << 10), CCR, free_ch);
} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
- dma_write(dev_id, CCR(free_ch));
+ p->dma_write(dev_id, CCR, free_ch);
}
if (cpu_class_is_omap2()) {
omap2_enable_irq_lch(free_ch);
omap_enable_channel_irq(free_ch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch));
- dma_write(1 << free_ch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, free_ch);
+ p->dma_write(1 << free_ch, IRQSTATUS_L0, 0);
}
*dma_ch_out = free_ch;
@@ -823,23 +760,23 @@ void omap_free_dma(int lch)
if (cpu_class_is_omap1()) {
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR(lch));
+ p->dma_write(0, CCR, lch);
}
if (cpu_class_is_omap2()) {
omap2_disable_irq_lch(lch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
- dma_write(1 << lch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
+ p->dma_write(1 << lch, IRQSTATUS_L0, lch);
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR(lch));
+ p->dma_write(0, CCR, lch);
omap_clear_dma(lch);
}
@@ -880,7 +817,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
reg |= (0x3 & tparams) << 12;
reg |= (arb_rate & 0xff) << 16;
- dma_write(reg, GCR);
+ p->dma_write(reg, GCR, 0);
}
EXPORT_SYMBOL(omap_dma_set_global_params);
@@ -903,14 +840,14 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
printk(KERN_ERR "Invalid channel id\n");
return -EINVAL;
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~((1 << 6) | (1 << 26));
if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
else
l |= ((read_prio & 0x1) << 6);
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
return 0;
}
@@ -925,25 +862,7 @@ void omap_clear_dma(int lch)
unsigned long flags;
local_irq_save(flags);
-
- if (cpu_class_is_omap1()) {
- u32 l;
-
- l = dma_read(CCR(lch));
- l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
-
- /* Clear pending interrupts */
- l = dma_read(CSR(lch));
- }
-
- if (cpu_class_is_omap2()) {
- int i;
- void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch);
- for (i = 0; i < 0x44; i += 4)
- __raw_writel(0, lch_base + i);
- }
-
+ p->clear_dma(lch);
local_irq_restore(flags);
}
EXPORT_SYMBOL(omap_clear_dma);
@@ -957,13 +876,13 @@ void omap_start_dma(int lch)
* before starting dma transfer.
*/
if (cpu_is_omap15xx())
- dma_write(0, CPC(lch));
+ p->dma_write(0, CPC, lch);
else
- dma_write(0, CDAC(lch));
+ p->dma_write(0, CDAC, lch);
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch;
- char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[dma_lch_count];
dma_chan_link_map[lch] = 1;
/* Set the link register of the first channel */
@@ -985,32 +904,18 @@ void omap_start_dma(int lch)
cur_lch = next_lch;
} while (next_lch != -1);
- } else if (cpu_is_omap242x() ||
- (cpu_is_omap243x() && omap_type() <= OMAP2430_REV_ES1_0)) {
-
- /* Errata: Need to write lch even if not using chaining */
- dma_write(lch, CLNK_CTRL(lch));
- }
+ } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
+ p->dma_write(lch, CLNK_CTRL, lch);
omap_enable_channel_irq(lch);
- l = dma_read(CCR(lch));
-
- /*
- * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
- * OMAP2430ES1.0): DMA will wrongly buffer elements if packing and
- * bursting is enabled. This might result in data gets stalled in
- * FIFO at the end of the block.
- * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
- * guarantee no data will stay in the DMA FIFO in case inter frame
- * buffering occurs.
- */
- if (cpu_is_omap2420() ||
- (cpu_is_omap2430() && (omap_type() == OMAP2430_REV_ES1_0)))
- l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
+ l = p->dma_read(CCR, lch);
+ if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
+ l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
l |= OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+
+ p->dma_write(l, CCR, lch);
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1022,46 +927,46 @@ void omap_stop_dma(int lch)
/* Disable all interrupts on the channel */
if (cpu_class_is_omap1())
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
- l = dma_read(CCR(lch));
- /* OMAP3 Errata i541: sDMA FIFO draining does not finish */
- if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
+ l = p->dma_read(CCR, lch);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
+ (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
int i = 0;
u32 sys_cf;
/* Configure No-Standby */
- l = dma_read(OCP_SYSCONFIG);
+ l = p->dma_read(OCP_SYSCONFIG, lch);
sys_cf = l;
l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
- dma_write(l , OCP_SYSCONFIG);
+ p->dma_write(l , OCP_SYSCONFIG, 0);
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
/* Wait for sDMA FIFO drain */
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
OMAP_DMA_CCR_WR_ACTIVE))) {
udelay(5);
i++;
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
}
if (i >= 100)
printk(KERN_ERR "DMA drain did not complete on "
"lch %d\n", lch);
/* Restore OCP_SYSCONFIG */
- dma_write(sys_cf, OCP_SYSCONFIG);
+ p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
} else {
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
}
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
- char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[dma_lch_count];
memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
do {
@@ -1122,19 +1027,15 @@ dma_addr_t omap_get_dma_src_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC(lch));
+ offset = p->dma_read(CPC, lch);
else
- offset = dma_read(CSAC(lch));
+ offset = p->dma_read(CSAC, lch);
- /*
- * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- if (!cpu_is_omap15xx() && offset == 0)
- offset = dma_read(CSAC(lch));
+ if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
+ offset = p->dma_read(CSAC, lch);
if (cpu_class_is_omap1())
- offset |= (dma_read(CSSA_U(lch)) << 16);
+ offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
return offset;
}
@@ -1153,19 +1054,19 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC(lch));
+ offset = p->dma_read(CPC, lch);
else
- offset = dma_read(CDAC(lch));
+ offset = p->dma_read(CDAC, lch);
/*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if (!cpu_is_omap15xx() && offset == 0)
- offset = dma_read(CDAC(lch));
+ offset = p->dma_read(CDAC, lch);
if (cpu_class_is_omap1())
- offset |= (dma_read(CDSA_U(lch)) << 16);
+ offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
return offset;
}
@@ -1173,7 +1074,7 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
int omap_get_dma_active_status(int lch)
{
- return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0;
+ return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
}
EXPORT_SYMBOL(omap_get_dma_active_status);
@@ -1186,7 +1087,7 @@ int omap_dma_running(void)
return 1;
for (lch = 0; lch < dma_chan_count; lch++)
- if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN)
+ if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
return 1;
return 0;
@@ -1201,8 +1102,8 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR(lch_head)) | (3 << 8),
- CCR(lch_head));
+ p->dma_write(p->dma_read(CCR, lch_head) | (3 << 8),
+ CCR, lch_head);
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1228,8 +1129,8 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
- CCR(lch_head));
+ p->dma_write(p->dma_read(CCR, lch_head) & ~(3 << 8),
+ CCR, lch_head);
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1255,8 +1156,6 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
}
EXPORT_SYMBOL(omap_dma_unlink_lch);
-/*----------------------------------------------------------------------------*/
-
#ifndef CONFIG_ARCH_OMAP1
/* Create chain of DMA channesls */
static void create_dma_lch_chain(int lch_head, int lch_queue)
@@ -1281,15 +1180,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
lch_queue;
}
- l = dma_read(CLNK_CTRL(lch_head));
+ l = p->dma_read(CLNK_CTRL, lch_head);
l &= ~(0x1f);
l |= lch_queue;
- dma_write(l, CLNK_CTRL(lch_head));
+ p->dma_write(l, CLNK_CTRL, lch_head);
- l = dma_read(CLNK_CTRL(lch_queue));
+ l = p->dma_read(CLNK_CTRL, lch_queue);
l &= ~(0x1f);
l |= (dma_chan[lch_queue].next_linked_ch);
- dma_write(l, CLNK_CTRL(lch_queue));
+ p->dma_write(l, CLNK_CTRL, lch_queue);
}
/**
@@ -1565,13 +1464,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Set the params to the free channel */
if (src_start != 0)
- dma_write(src_start, CSSA(lch));
+ p->dma_write(src_start, CSSA, lch);
if (dest_start != 0)
- dma_write(dest_start, CDSA(lch));
+ p->dma_write(dest_start, CDSA, lch);
/* Write the buffer size */
- dma_write(elem_count, CEN(lch));
- dma_write(frame_count, CFN(lch));
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
/*
* If the chain is dynamically linked,
@@ -1604,8 +1503,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
enable_lnk(dma_chan[lch].prev_linked_ch);
dma_chan[lch].state = DMA_CH_QUEUED;
start_dma = 0;
- if (0 == ((1 << 7) & dma_read(
- CCR(dma_chan[lch].prev_linked_ch)))) {
+ if (0 == ((1 << 7) & p->dma_read(
+ CCR, dma_chan[lch].prev_linked_ch))) {
disable_lnk(dma_chan[lch].
prev_linked_ch);
pr_debug("\n prev ch is stopped\n");
@@ -1621,7 +1520,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
}
omap_enable_channel_irq(lch);
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
if ((0 == (l & (1 << 24))))
l &= ~(1 << 25);
@@ -1632,12 +1531,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
l |= (1 << 7);
dma_chan[lch].state = DMA_CH_STARTED;
pr_debug("starting %d\n", lch);
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
} else
start_dma = 0;
} else {
if (0 == (l & (1 << 7)))
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
}
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1682,7 +1581,7 @@ int omap_start_dma_chain_transfers(int chain_id)
omap_enable_channel_irq(channels[0]);
}
- l = dma_read(CCR(channels[0]));
+ l = p->dma_read(CCR, channels[0]);
l |= (1 << 7);
dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
dma_chan[channels[0]].state = DMA_CH_STARTED;
@@ -1691,7 +1590,7 @@ int omap_start_dma_chain_transfers(int chain_id)
l &= ~(1 << 25);
else
l |= (1 << 25);
- dma_write(l, CCR(channels[0]));
+ p->dma_write(l, CCR, channels[0]);
dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
@@ -1711,7 +1610,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
{
int *channels;
u32 l, i;
- u32 sys_cf;
+ u32 sys_cf = 0;
/* Check for input params */
if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1726,22 +1625,20 @@ int omap_stop_dma_chain_transfers(int chain_id)
}
channels = dma_linked_lch[chain_id].linked_dmach_q;
- /*
- * DMA Errata:
- * Special programming model needed to disable DMA before end of block
- */
- sys_cf = dma_read(OCP_SYSCONFIG);
- l = sys_cf;
- /* Middle mode reg set no Standby */
- l &= ~((1 << 12)|(1 << 13));
- dma_write(l, OCP_SYSCONFIG);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
+ sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
+ l = sys_cf;
+ /* Middle mode reg set no Standby */
+ l &= ~((1 << 12)|(1 << 13));
+ p->dma_write(l, OCP_SYSCONFIG, 0);
+ }
for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
/* Stop the Channel transmission */
- l = dma_read(CCR(channels[i]));
+ l = p->dma_read(CCR, channels[i]);
l &= ~(1 << 7);
- dma_write(l, CCR(channels[i]));
+ p->dma_write(l, CCR, channels[i]);
/* Disable the link in all the channels */
disable_lnk(channels[i]);
@@ -1753,8 +1650,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
/* Reset the Queue pointers */
OMAP_DMA_CHAIN_QINIT(chain_id);
- /* Errata - put in the old value */
- dma_write(sys_cf, OCP_SYSCONFIG);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88))
+ p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
return 0;
}
@@ -1796,8 +1693,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- *ei = dma_read(CCEN(lch));
- *fi = dma_read(CCFN(lch));
+ *ei = p->dma_read(CCEN, lch);
+ *fi = p->dma_read(CCFN, lch);
return 0;
}
@@ -1834,7 +1731,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CDAC(lch));
+ return p->dma_read(CDAC, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
@@ -1868,7 +1765,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CSAC(lch));
+ return p->dma_read(CSAC, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
#endif /* ifndef CONFIG_ARCH_OMAP1 */
@@ -1885,7 +1782,7 @@ static int omap1_dma_handle_ch(int ch)
csr = dma_chan[ch].saved_csr;
dma_chan[ch].saved_csr = 0;
} else
- csr = dma_read(CSR(ch));
+ csr = p->dma_read(CSR, ch);
if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
dma_chan[ch + 6].saved_csr = csr >> 7;
csr &= 0x7f;
@@ -1938,13 +1835,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
static int omap2_dma_handle_ch(int ch)
{
- u32 status = dma_read(CSR(ch));
+ u32 status = p->dma_read(CSR, ch);
if (!status) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
ch);
- dma_write(1 << ch, IRQSTATUS_L0);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
return 0;
}
if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -1960,17 +1857,12 @@ static int omap2_dma_handle_ch(int ch)
if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
printk(KERN_INFO "DMA transaction error with device %d\n",
dma_chan[ch].dev_id);
- if (cpu_class_is_omap2()) {
- /*
- * Errata: sDMA Channel is not disabled
- * after a transaction error. So we explicitely
- * disable the channel
- */
+ if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
u32 ccr;
- ccr = dma_read(CCR(ch));
+ ccr = p->dma_read(CCR, ch);
ccr &= ~OMAP_DMA_CCR_EN;
- dma_write(ccr, CCR(ch));
+ p->dma_write(ccr, CCR, ch);
dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
}
}
@@ -1981,16 +1873,16 @@ static int omap2_dma_handle_ch(int ch)
printk(KERN_INFO "DMA misaligned error with device %d\n",
dma_chan[ch].dev_id);
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
- dma_write(1 << ch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
/* read back the register to flush the write */
- dma_read(IRQSTATUS_L0);
+ p->dma_read(IRQSTATUS_L0, ch);
/* If the ch is not chained then chain_id will be -1 */
if (dma_chan[ch].chain_id != -1) {
int chain_id = dma_chan[ch].chain_id;
dma_chan[ch].state = DMA_CH_NOTSTARTED;
- if (dma_read(CLNK_CTRL(ch)) & (1 << 15))
+ if (p->dma_read(CLNK_CTRL, ch) & (1 << 15))
dma_chan[dma_chan[ch].next_linked_ch].state =
DMA_CH_STARTED;
if (dma_linked_lch[chain_id].chain_mode ==
@@ -2000,10 +1892,10 @@ static int omap2_dma_handle_ch(int ch)
if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
OMAP_DMA_CHAIN_INCQHEAD(chain_id);
- status = dma_read(CSR(ch));
+ status = p->dma_read(CSR, ch);
}
- dma_write(status, CSR(ch));
+ p->dma_write(status, CSR, ch);
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, status, dma_chan[ch].data);
@@ -2017,13 +1909,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
u32 val, enable_reg;
int i;
- val = dma_read(IRQSTATUS_L0);
+ val = p->dma_read(IRQSTATUS_L0, 0);
if (val == 0) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ\n");
return IRQ_HANDLED;
}
- enable_reg = dma_read(IRQENABLE_L0);
+ enable_reg = p->dma_read(IRQENABLE_L0, 0);
val &= enable_reg; /* Dispatch only relevant interrupts */
for (i = 0; i < dma_lch_count && val != 0; i++) {
if (val & 1)
@@ -2049,119 +1941,66 @@ static struct irqaction omap24xx_dma_irq;
void omap_dma_global_context_save(void)
{
omap_dma_global_context.dma_irqenable_l0 =
- dma_read(IRQENABLE_L0);
+ p->dma_read(IRQENABLE_L0, 0);
omap_dma_global_context.dma_ocp_sysconfig =
- dma_read(OCP_SYSCONFIG);
- omap_dma_global_context.dma_gcr = dma_read(GCR);
+ p->dma_read(OCP_SYSCONFIG, 0);
+ omap_dma_global_context.dma_gcr = p->dma_read(GCR, 0);
}
void omap_dma_global_context_restore(void)
{
int ch;
- dma_write(omap_dma_global_context.dma_gcr, GCR);
- dma_write(omap_dma_global_context.dma_ocp_sysconfig,
- OCP_SYSCONFIG);
- dma_write(omap_dma_global_context.dma_irqenable_l0,
- IRQENABLE_L0);
+ p->dma_write(omap_dma_global_context.dma_gcr, GCR, 0);
+ p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+ OCP_SYSCONFIG, 0);
+ p->dma_write(omap_dma_global_context.dma_irqenable_l0,
+ IRQENABLE_L0, 0);
- /*
- * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
- * after secure sram context save and restore. Hence we need to
- * manually clear those IRQs to avoid spurious interrupts. This
- * affects only secure devices.
- */
- if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
- dma_write(0x3 , IRQSTATUS_L0);
+ if (IS_DMA_ERRATA(DMA_ROMCODE_BUG))
+ p->dma_write(0x3 , IRQSTATUS_L0, 0);
for (ch = 0; ch < dma_chan_count; ch++)
if (dma_chan[ch].dev_id != -1)
omap_clear_dma(ch);
}
-/*----------------------------------------------------------------------------*/
-
-static int __init omap_init_dma(void)
+static int __devinit omap_system_dma_probe(struct platform_device *pdev)
{
- unsigned long base;
- int ch, r;
-
- if (cpu_class_is_omap1()) {
- base = OMAP1_DMA_BASE;
- dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap24xx()) {
- base = OMAP24XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap34xx()) {
- base = OMAP34XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap44xx()) {
- base = OMAP44XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else {
- pr_err("DMA init failed for unsupported omap\n");
- return -ENODEV;
+ int ch, ret = 0;
+ int dma_irq;
+ char irq_name[4];
+ int irq_rel;
+
+ p = pdev->dev.platform_data;
+ if (!p) {
+ dev_err(&pdev->dev, "%s: System DMA initialized without"
+ "platform data\n", __func__);
+ return -EINVAL;
}
- omap_dma_base = ioremap(base, SZ_4K);
- BUG_ON(!omap_dma_base);
+ d = p->dma_attr;
+ errata = p->errata;
- if (cpu_class_is_omap2() && omap_dma_reserve_channels
+ if ((d->dev_caps & RESERVE_CHANNEL) && omap_dma_reserve_channels
&& (omap_dma_reserve_channels <= dma_lch_count))
- dma_lch_count = omap_dma_reserve_channels;
+ d->lch_count = omap_dma_reserve_channels;
- dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
- GFP_KERNEL);
- if (!dma_chan) {
- r = -ENOMEM;
- goto out_unmap;
- }
+ dma_lch_count = d->lch_count;
+ dma_chan_count = dma_lch_count;
+ dma_chan = d->chan;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
if (cpu_class_is_omap2()) {
dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
dma_lch_count, GFP_KERNEL);
if (!dma_linked_lch) {
- r = -ENOMEM;
- goto out_free;
+ ret = -ENOMEM;
+ goto exit_dma_lch_fail;
}
}
- if (cpu_is_omap15xx()) {
- printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
- dma_chan_count = 9;
- enable_1510_mode = 1;
- } else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
- printk(KERN_INFO "OMAP DMA hardware version %d\n",
- dma_read(HW_ID));
- printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (dma_read(CAPS_0_U) << 16) |
- dma_read(CAPS_0_L),
- (dma_read(CAPS_1_U) << 16) |
- dma_read(CAPS_1_L),
- dma_read(CAPS_2), dma_read(CAPS_3),
- dma_read(CAPS_4));
- if (!enable_1510_mode) {
- u16 w;
-
- /* Disable OMAP 3.0/3.1 compatibility mode. */
- w = dma_read(GSCR);
- w |= 1 << 3;
- dma_write(w, GSCR);
- dma_chan_count = 16;
- } else
- dma_chan_count = 9;
- } else if (cpu_class_is_omap2()) {
- u8 revision = dma_read(REVISION) & 0xff;
- printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
- revision >> 4, revision & 0xf);
- dma_chan_count = dma_lch_count;
- } else {
- dma_chan_count = 0;
- return 0;
- }
-
spin_lock_init(&dma_chan_lock);
-
for (ch = 0; ch < dma_chan_count; ch++) {
omap_clear_dma(ch);
if (cpu_class_is_omap2())
@@ -2178,20 +2017,23 @@ static int __init omap_init_dma(void)
* request_irq() doesn't like dev_id (ie. ch) being
* zero, so we have to kludge around this.
*/
- r = request_irq(omap1_dma_irq[ch],
+ sprintf(&irq_name[0], "%d", ch);
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+
+ if (dma_irq < 0) {
+ ret = dma_irq;
+ goto exit_dma_irq_fail;
+ }
+
+ /* INT_DMA_LCD is handled in lcd_dma.c */
+ if (dma_irq == INT_DMA_LCD)
+ continue;
+
+ ret = request_irq(dma_irq,
omap1_dma_irq_handler, 0, "DMA",
(void *) (ch + 1));
- if (r != 0) {
- int i;
-
- printk(KERN_ERR "unable to request IRQ %d "
- "for DMA (error %d)\n",
- omap1_dma_irq[ch], r);
- for (i = 0; i < ch; i++)
- free_irq(omap1_dma_irq[i],
- (void *) (i + 1));
- goto out_free;
- }
+ if (ret != 0)
+ goto exit_dma_irq_fail;
}
}
@@ -2200,46 +2042,91 @@ static int __init omap_init_dma(void)
DMA_DEFAULT_FIFO_DEPTH, 0);
if (cpu_class_is_omap2()) {
- int irq;
- if (cpu_is_omap44xx())
- irq = OMAP44XX_IRQ_SDMA_0;
- else
- irq = INT_24XX_SDMA_IRQ0;
- setup_irq(irq, &omap24xx_dma_irq);
- }
-
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- /* Enable smartidle idlemodes and autoidle */
- u32 v = dma_read(OCP_SYSCONFIG);
- v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
- DMA_SYSCONFIG_SIDLEMODE_MASK |
- DMA_SYSCONFIG_AUTOIDLE);
- v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_AUTOIDLE);
- dma_write(v , OCP_SYSCONFIG);
- /* reserve dma channels 0 and 1 in high security devices */
- if (cpu_is_omap34xx() &&
- (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
- printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
- "HS ROM code\n");
- dma_chan[0].dev_id = 0;
- dma_chan[1].dev_id = 1;
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ if (dma_irq < 0) {
+ dev_err(&pdev->dev, "failed: request IRQ %d", dma_irq);
+ goto exit_dma_lch_fail;
+ }
+ ret = setup_irq(dma_irq, &omap24xx_dma_irq);
+ if (ret) {
+ dev_err(&pdev->dev, "set_up failed for IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ goto exit_dma_lch_fail;
}
}
+ /* reserve dma channels 0 and 1 in high security devices */
+ if (cpu_is_omap34xx() &&
+ (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+ "HS ROM code\n");
+ dma_chan[0].dev_id = 0;
+ dma_chan[1].dev_id = 1;
+ }
+ p->show_dma_caps();
return 0;
-out_free:
+exit_dma_irq_fail:
+ dev_err(&pdev->dev, "unable to request IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ for (irq_rel = 0; irq_rel < ch; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+
+exit_dma_lch_fail:
+ kfree(p);
+ kfree(d);
kfree(dma_chan);
+ return ret;
+}
-out_unmap:
- iounmap(omap_dma_base);
+static int __devexit omap_system_dma_remove(struct platform_device *pdev)
+{
+ int dma_irq;
- return r;
+ if (cpu_class_is_omap2()) {
+ char irq_name[4];
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ remove_irq(dma_irq, &omap24xx_dma_irq);
+ } else {
+ int irq_rel = 0;
+ for ( ; irq_rel < dma_chan_count; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+ }
+ kfree(p);
+ kfree(d);
+ kfree(dma_chan);
+ return 0;
+}
+
+static struct platform_driver omap_system_dma_driver = {
+ .probe = omap_system_dma_probe,
+ .remove = omap_system_dma_remove,
+ .driver = {
+ .name = "omap_dma_system"
+ },
+};
+
+static int __init omap_system_dma_init(void)
+{
+ return platform_driver_register(&omap_system_dma_driver);
+}
+arch_initcall(omap_system_dma_init);
+
+static void __exit omap_system_dma_exit(void)
+{
+ platform_driver_unregister(&omap_system_dma_driver);
}
-arch_initcall(omap_init_dma);
+MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
/*
* Reserve the omap SDMA channels using cmdline bootarg
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index c05c653d1674..1f98e0b94847 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -21,18 +21,18 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/irqs.h>
#include <mach/gpio.h>
#include <asm/mach/irq.h>
-#include <plat/powerdomain.h>
/*
* OMAP1510 GPIO registers
*/
-#define OMAP1510_GPIO_BASE 0xfffce000
#define OMAP1510_GPIO_DATA_INPUT 0x00
#define OMAP1510_GPIO_DATA_OUTPUT 0x04
#define OMAP1510_GPIO_DIR_CONTROL 0x08
@@ -46,10 +46,6 @@
/*
* OMAP1610 specific GPIO registers
*/
-#define OMAP1610_GPIO1_BASE 0xfffbe400
-#define OMAP1610_GPIO2_BASE 0xfffbec00
-#define OMAP1610_GPIO3_BASE 0xfffbb400
-#define OMAP1610_GPIO4_BASE 0xfffbbc00
#define OMAP1610_GPIO_REVISION 0x0000
#define OMAP1610_GPIO_SYSCONFIG 0x0010
#define OMAP1610_GPIO_SYSSTATUS 0x0014
@@ -71,12 +67,6 @@
/*
* OMAP7XX specific GPIO registers
*/
-#define OMAP7XX_GPIO1_BASE 0xfffbc000
-#define OMAP7XX_GPIO2_BASE 0xfffbc800
-#define OMAP7XX_GPIO3_BASE 0xfffbd000
-#define OMAP7XX_GPIO4_BASE 0xfffbd800
-#define OMAP7XX_GPIO5_BASE 0xfffbe000
-#define OMAP7XX_GPIO6_BASE 0xfffbe800
#define OMAP7XX_GPIO_DATA_INPUT 0x00
#define OMAP7XX_GPIO_DATA_OUTPUT 0x04
#define OMAP7XX_GPIO_DIR_CONTROL 0x08
@@ -84,25 +74,10 @@
#define OMAP7XX_GPIO_INT_MASK 0x10
#define OMAP7XX_GPIO_INT_STATUS 0x14
-#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
-
/*
- * omap24xx specific GPIO registers
+ * omap2+ specific GPIO registers
*/
-#define OMAP242X_GPIO1_BASE 0x48018000
-#define OMAP242X_GPIO2_BASE 0x4801a000
-#define OMAP242X_GPIO3_BASE 0x4801c000
-#define OMAP242X_GPIO4_BASE 0x4801e000
-
-#define OMAP243X_GPIO1_BASE 0x4900C000
-#define OMAP243X_GPIO2_BASE 0x4900E000
-#define OMAP243X_GPIO3_BASE 0x49010000
-#define OMAP243X_GPIO4_BASE 0x49012000
-#define OMAP243X_GPIO5_BASE 0x480B6000
-
#define OMAP24XX_GPIO_REVISION 0x0000
-#define OMAP24XX_GPIO_SYSCONFIG 0x0010
-#define OMAP24XX_GPIO_SYSSTATUS 0x0014
#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
#define OMAP24XX_GPIO_IRQENABLE2 0x002c
@@ -126,7 +101,6 @@
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
#define OMAP4_GPIO_REVISION 0x0000
-#define OMAP4_GPIO_SYSCONFIG 0x0010
#define OMAP4_GPIO_EOI 0x0020
#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
@@ -138,7 +112,6 @@
#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
#define OMAP4_GPIO_IRQWAKEN0 0x0044
#define OMAP4_GPIO_IRQWAKEN1 0x0048
-#define OMAP4_GPIO_SYSSTATUS 0x0114
#define OMAP4_GPIO_IRQENABLE1 0x011c
#define OMAP4_GPIO_WAKE_EN 0x0120
#define OMAP4_GPIO_IRQSTATUS2 0x0128
@@ -159,26 +132,6 @@
#define OMAP4_GPIO_SETWKUENA 0x0184
#define OMAP4_GPIO_CLEARDATAOUT 0x0190
#define OMAP4_GPIO_SETDATAOUT 0x0194
-/*
- * omap34xx specific GPIO registers
- */
-
-#define OMAP34XX_GPIO1_BASE 0x48310000
-#define OMAP34XX_GPIO2_BASE 0x49050000
-#define OMAP34XX_GPIO3_BASE 0x49052000
-#define OMAP34XX_GPIO4_BASE 0x49054000
-#define OMAP34XX_GPIO5_BASE 0x49056000
-#define OMAP34XX_GPIO6_BASE 0x49058000
-
-/*
- * OMAP44XX specific GPIO registers
- */
-#define OMAP44XX_GPIO1_BASE 0x4a310000
-#define OMAP44XX_GPIO2_BASE 0x48055000
-#define OMAP44XX_GPIO3_BASE 0x48057000
-#define OMAP44XX_GPIO4_BASE 0x48059000
-#define OMAP44XX_GPIO5_BASE 0x4805B000
-#define OMAP44XX_GPIO6_BASE 0x4805D000
struct gpio_bank {
unsigned long pbase;
@@ -190,14 +143,12 @@ struct gpio_bank {
u32 suspend_wakeup;
u32 saved_wakeup;
#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
u32 non_wakeup_gpios;
u32 enabled_non_wakeup_gpios;
u32 saved_datain;
u32 saved_fallingdetect;
u32 saved_risingdetect;
-#endif
u32 level_mask;
u32 toggle_mask;
spinlock_t lock;
@@ -205,104 +156,13 @@ struct gpio_bank {
struct clk *dbck;
u32 mod_usage;
u32 dbck_enable_mask;
+ struct device *dev;
+ bool dbck_flag;
+ int stride;
};
-#define METHOD_MPUIO 0
-#define METHOD_GPIO_1510 1
-#define METHOD_GPIO_1610 2
-#define METHOD_GPIO_7XX 3
-#define METHOD_GPIO_24XX 5
-#define METHOD_GPIO_44XX 6
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static struct gpio_bank gpio_bank_1610[5] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48,
- METHOD_GPIO_1610 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP15XX
-static struct gpio_bank gpio_bank_1510[2] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_1510 }
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-static struct gpio_bank gpio_bank_7xx[7] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6, IH_GPIO_BASE + 160,
- METHOD_GPIO_7XX },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
-
-static struct gpio_bank gpio_bank_242x[4] = {
- { OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
-};
-
-static struct gpio_bank gpio_bank_243x[5] = {
- { OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_24XX },
-};
-
-#endif
-
#ifdef CONFIG_ARCH_OMAP3
-static struct gpio_bank gpio_bank_34xx[6] = {
- { OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO2_BASE, NULL, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO3_BASE, NULL, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO4_BASE, NULL, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO5_BASE, NULL, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO6_BASE, NULL, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160,
- METHOD_GPIO_24XX },
-};
-
struct omap3_gpio_regs {
- u32 sysconfig;
u32 irqenable1;
u32 irqenable2;
u32 wake_en;
@@ -318,26 +178,16 @@ struct omap3_gpio_regs {
static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
#endif
-#ifdef CONFIG_ARCH_OMAP4
-static struct gpio_bank gpio_bank_44xx[6] = {
- { OMAP44XX_GPIO1_BASE, NULL, OMAP44XX_IRQ_GPIO1, IH_GPIO_BASE,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO2_BASE, NULL, OMAP44XX_IRQ_GPIO2, IH_GPIO_BASE + 32,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO3_BASE, NULL, OMAP44XX_IRQ_GPIO3, IH_GPIO_BASE + 64,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO4_BASE, NULL, OMAP44XX_IRQ_GPIO4, IH_GPIO_BASE + 96,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO5_BASE, NULL, OMAP44XX_IRQ_GPIO5, IH_GPIO_BASE + 128,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO6_BASE, NULL, OMAP44XX_IRQ_GPIO6, IH_GPIO_BASE + 160,
- METHOD_GPIO_44XX },
-};
+/*
+ * TODO: Cleanup gpio_bank usage as it is having information
+ * related to all instances of the device
+ */
+static struct gpio_bank *gpio_bank;
-#endif
+static int bank_width;
-static struct gpio_bank *gpio_bank;
-static int gpio_bank_count;
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+int gpio_bank_count;
static inline struct gpio_bank *get_gpio_bank(int gpio)
{
@@ -417,7 +267,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_IO_CNTL;
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -465,7 +315,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_OUTPUT;
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
l = __raw_readl(reg);
if (enable)
l |= 1 << gpio;
@@ -537,7 +387,7 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_INPUT_LATCH;
+ reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -583,7 +433,7 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_OUTPUT;
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -642,6 +492,9 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
u32 val;
u32 l;
+ if (!bank->dbck_flag)
+ return;
+
if (debounce < 32)
debounce = 0x01;
else if (debounce > 7936)
@@ -651,7 +504,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
l = 1 << get_gpio_index(gpio);
- if (cpu_is_omap44xx())
+ if (bank->method == METHOD_GPIO_44XX)
reg += OMAP4_GPIO_DEBOUNCINGTIME;
else
reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
@@ -659,7 +512,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
__raw_writel(debounce, reg);
reg = bank->base;
- if (cpu_is_omap44xx())
+ if (bank->method == METHOD_GPIO_44XX)
reg += OMAP4_GPIO_DEBOUNCENABLE;
else
reg += OMAP24XX_GPIO_DEBOUNCE_EN;
@@ -668,12 +521,10 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
if (debounce) {
val |= l;
- if (cpu_is_omap34xx() || cpu_is_omap44xx())
- clk_enable(bank->dbck);
+ clk_enable(bank->dbck);
} else {
val &= ~l;
- if (cpu_is_omap34xx() || cpu_is_omap44xx())
- clk_disable(bank->dbck);
+ clk_disable(bank->dbck);
}
bank->dbck_enable_mask = val;
@@ -769,7 +620,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_INT_EDGE;
+ reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
break;
#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
@@ -803,7 +654,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_INT_EDGE;
+ reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
l = __raw_readl(reg);
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
@@ -989,7 +840,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_MASKIT;
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
mask = 0xffff;
inv = 1;
break;
@@ -1046,7 +897,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_MASKIT;
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
l = __raw_readl(reg);
if (enable)
l &= ~(gpio_mask);
@@ -1296,7 +1147,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
bank = get_irq_data(irq);
#ifdef CONFIG_ARCH_OMAP1
if (bank->method == METHOD_MPUIO)
- isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
+ isr_reg = bank->base +
+ OMAP_MPUIO_GPIO_INT / bank->stride;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510)
@@ -1318,6 +1170,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (bank->method == METHOD_GPIO_44XX)
isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
#endif
+
+ if (WARN_ON(!isr_reg))
+ goto exit;
+
while(1) {
u32 isr_saved, level_mask = 0;
u32 enabled;
@@ -1377,6 +1233,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
configured, we must unmask the bank interrupt only after
handler(s) are executed in order to avoid spurious bank
interrupt */
+exit:
if (!unmasked)
desc->chip->unmask(irq);
@@ -1489,7 +1346,8 @@ static int omap_mpuio_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_bank *bank = platform_get_drvdata(pdev);
- void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+ void __iomem *mask_reg = bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride;
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
@@ -1504,7 +1362,8 @@ static int omap_mpuio_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_bank *bank = platform_get_drvdata(pdev);
- void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+ void __iomem *mask_reg = bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride;
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
@@ -1540,7 +1399,8 @@ static struct platform_device omap_mpuio_device = {
static inline void mpuio_init(void)
{
- platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]);
+ struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+ platform_set_drvdata(&omap_mpuio_device, bank);
if (platform_driver_register(&omap_mpuio_driver) == 0)
(void) platform_device_register(&omap_mpuio_device);
@@ -1583,7 +1443,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_IO_CNTL;
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DIR_CONTROL;
@@ -1645,6 +1505,13 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
unsigned long flags;
bank = container_of(chip, struct gpio_bank, chip);
+
+ if (!bank->dbck) {
+ bank->dbck = clk_get(bank->dev, "dbclk");
+ if (IS_ERR(bank->dbck))
+ dev_err(bank->dev, "Could not get gpio dbck\n");
+ }
+
spin_lock_irqsave(&bank->lock, flags);
_set_gpio_debounce(bank, offset, debounce);
spin_unlock_irqrestore(&bank->lock, flags);
@@ -1673,34 +1540,16 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
/*---------------------------------------------------------------------*/
-static int initialized;
-#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_ick;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2430)
-static struct clk * gpio5_ick;
-static struct clk * gpio5_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
-#endif
-
-static void __init omap_gpio_show_rev(void)
+static void __init omap_gpio_show_rev(struct gpio_bank *bank)
{
u32 rev;
- if (cpu_is_omap16xx())
- rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+ if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
+ rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
else if (cpu_is_omap24xx() || cpu_is_omap34xx())
- rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
else if (cpu_is_omap44xx())
- rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
+ rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
else
return;
@@ -1713,250 +1562,190 @@ static void __init omap_gpio_show_rev(void)
*/
static struct lock_class_key gpio_lock_class;
-static int __init _omap_gpio_init(void)
+static inline int init_gpio_info(struct platform_device *pdev)
{
- int i;
- int gpio = 0;
- struct gpio_bank *bank;
- int bank_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
- char clk_name[11];
-
- initialized = 1;
-
-#if defined(CONFIG_ARCH_OMAP1)
- if (cpu_is_omap15xx()) {
- gpio_ick = clk_get(NULL, "arm_gpio_ck");
- if (IS_ERR(gpio_ick))
- printk("Could not get arm_gpio_ck\n");
- else
- clk_enable(gpio_ick);
+ /* TODO: Analyze removing gpio_bank_count usage from driver code */
+ gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
+ GFP_KERNEL);
+ if (!gpio_bank) {
+ dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+ return -ENOMEM;
}
-#endif
-#if defined(CONFIG_ARCH_OMAP2)
- if (cpu_class_is_omap2()) {
- gpio_ick = clk_get(NULL, "gpios_ick");
- if (IS_ERR(gpio_ick))
- printk("Could not get gpios_ick\n");
- else
- clk_enable(gpio_ick);
- gpio_fck = clk_get(NULL, "gpios_fck");
- if (IS_ERR(gpio_fck))
- printk("Could not get gpios_fck\n");
- else
- clk_enable(gpio_fck);
+ return 0;
+}
- /*
- * On 2430 & 3430 GPIO 5 uses CORE L4 ICLK
- */
-#if defined(CONFIG_ARCH_OMAP2430)
- if (cpu_is_omap2430()) {
- gpio5_ick = clk_get(NULL, "gpio5_ick");
- if (IS_ERR(gpio5_ick))
- printk("Could not get gpio5_ick\n");
- else
- clk_enable(gpio5_ick);
- gpio5_fck = clk_get(NULL, "gpio5_fck");
- if (IS_ERR(gpio5_fck))
- printk("Could not get gpio5_fck\n");
- else
- clk_enable(gpio5_fck);
+/* TODO: Cleanup cpu_is_* checks */
+static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
+{
+ if (cpu_class_is_omap2()) {
+ if (cpu_is_omap44xx()) {
+ __raw_writel(0xffffffff, bank->base +
+ OMAP4_GPIO_IRQSTATUSCLR0);
+ __raw_writel(0x00000000, bank->base +
+ OMAP4_GPIO_DEBOUNCENABLE);
+ /* Initialize interface clk ungated, module enabled */
+ __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
+ } else if (cpu_is_omap34xx()) {
+ __raw_writel(0x00000000, bank->base +
+ OMAP24XX_GPIO_IRQENABLE1);
+ __raw_writel(0xffffffff, bank->base +
+ OMAP24XX_GPIO_IRQSTATUS1);
+ __raw_writel(0x00000000, bank->base +
+ OMAP24XX_GPIO_DEBOUNCE_EN);
+
+ /* Initialize interface clk ungated, module enabled */
+ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+ } else if (cpu_is_omap24xx()) {
+ static const u32 non_wakeup_gpios[] = {
+ 0xe203ffc0, 0x08700040
+ };
+ if (id < ARRAY_SIZE(non_wakeup_gpios))
+ bank->non_wakeup_gpios = non_wakeup_gpios[id];
}
-#endif
- }
-#endif
+ } else if (cpu_class_is_omap1()) {
+ if (bank_is_mpuio(bank))
+ __raw_writew(0xffff, bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride);
+ if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
+ __raw_writew(0xffff, bank->base
+ + OMAP1510_GPIO_INT_MASK);
+ __raw_writew(0x0000, bank->base
+ + OMAP1510_GPIO_INT_STATUS);
+ }
+ if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
+ __raw_writew(0x0000, bank->base
+ + OMAP1610_GPIO_IRQENABLE1);
+ __raw_writew(0xffff, bank->base
+ + OMAP1610_GPIO_IRQSTATUS1);
+ __raw_writew(0x0014, bank->base
+ + OMAP1610_GPIO_SYSCONFIG);
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- for (i = 0; i < OMAP34XX_NR_GPIOS; i++) {
- sprintf(clk_name, "gpio%d_ick", i + 1);
- gpio_iclks[i] = clk_get(NULL, clk_name);
- if (IS_ERR(gpio_iclks[i]))
- printk(KERN_ERR "Could not get %s\n", clk_name);
- else
- clk_enable(gpio_iclks[i]);
+ /*
+ * Enable system clock for GPIO module.
+ * The CAM_CLK_CTRL *is* really the right place.
+ */
+ omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+ ULPD_CAM_CLK_CTRL);
+ }
+ if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
+ __raw_writel(0xffffffff, bank->base
+ + OMAP7XX_GPIO_INT_MASK);
+ __raw_writel(0x00000000, bank->base
+ + OMAP7XX_GPIO_INT_STATUS);
}
}
-#endif
+}
+static void __init omap_gpio_chip_init(struct gpio_bank *bank)
+{
+ int j;
+ static int gpio;
-#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx()) {
- gpio_bank_count = 2;
- gpio_bank = gpio_bank_1510;
- bank_size = SZ_2K;
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
- if (cpu_is_omap16xx()) {
- gpio_bank_count = 5;
- gpio_bank = gpio_bank_1610;
- bank_size = SZ_2K;
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
- if (cpu_is_omap7xx()) {
- gpio_bank_count = 7;
- gpio_bank = gpio_bank_7xx;
- bank_size = SZ_2K;
- }
-#endif
-#ifdef CONFIG_ARCH_OMAP2
- if (cpu_is_omap242x()) {
- gpio_bank_count = 4;
- gpio_bank = gpio_bank_242x;
- }
- if (cpu_is_omap243x()) {
- gpio_bank_count = 5;
- gpio_bank = gpio_bank_243x;
- }
+ bank->mod_usage = 0;
+ /*
+ * REVISIT eventually switch from OMAP-specific gpio structs
+ * over to the generic ones
+ */
+ bank->chip.request = omap_gpio_request;
+ bank->chip.free = omap_gpio_free;
+ bank->chip.direction_input = gpio_input;
+ bank->chip.get = gpio_get;
+ bank->chip.direction_output = gpio_output;
+ bank->chip.set_debounce = gpio_debounce;
+ bank->chip.set = gpio_set;
+ bank->chip.to_irq = gpio_2irq;
+ if (bank_is_mpuio(bank)) {
+ bank->chip.label = "mpuio";
+#ifdef CONFIG_ARCH_OMAP16XX
+ bank->chip.dev = &omap_mpuio_device.dev;
#endif
-#ifdef CONFIG_ARCH_OMAP3
- if (cpu_is_omap34xx()) {
- gpio_bank_count = OMAP34XX_NR_GPIOS;
- gpio_bank = gpio_bank_34xx;
+ bank->chip.base = OMAP_MPUIO(0);
+ } else {
+ bank->chip.label = "gpio";
+ bank->chip.base = gpio;
+ gpio += bank_width;
}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
- if (cpu_is_omap44xx()) {
- gpio_bank_count = OMAP34XX_NR_GPIOS;
- gpio_bank = gpio_bank_44xx;
+ bank->chip.ngpio = bank_width;
+
+ gpiochip_add(&bank->chip);
+
+ for (j = bank->virtual_irq_start;
+ j < bank->virtual_irq_start + bank_width; j++) {
+ lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
+ set_irq_chip_data(j, bank);
+ if (bank_is_mpuio(bank))
+ set_irq_chip(j, &mpuio_irq_chip);
+ else
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_simple_irq);
+ set_irq_flags(j, IRQF_VALID);
}
-#endif
- for (i = 0; i < gpio_bank_count; i++) {
- int j, gpio_count = 16;
+ set_irq_chained_handler(bank->irq, gpio_irq_handler);
+ set_irq_data(bank->irq, bank);
+}
+
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
+{
+ static int gpio_init_done;
+ struct omap_gpio_platform_data *pdata;
+ struct resource *res;
+ int id;
+ struct gpio_bank *bank;
- bank = &gpio_bank[i];
- spin_lock_init(&bank->lock);
+ if (!pdev->dev.platform_data)
+ return -EINVAL;
- /* Static mapping, never released */
- bank->base = ioremap(bank->pbase, bank_size);
- if (!bank->base) {
- printk(KERN_ERR "Could not ioremap gpio bank%i\n", i);
- continue;
- }
+ pdata = pdev->dev.platform_data;
- if (bank_is_mpuio(bank))
- __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
- if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
- __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
- __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
- }
- if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
- __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
- __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
- __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
- }
- if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
- __raw_writel(0xffffffff, bank->base + OMAP7XX_GPIO_INT_MASK);
- __raw_writel(0x00000000, bank->base + OMAP7XX_GPIO_INT_STATUS);
+ if (!gpio_init_done) {
+ int ret;
- gpio_count = 32; /* 7xx has 32-bit GPIOs */
- }
+ ret = init_gpio_info(pdev);
+ if (ret)
+ return ret;
+ }
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if ((bank->method == METHOD_GPIO_24XX) ||
- (bank->method == METHOD_GPIO_44XX)) {
- static const u32 non_wakeup_gpios[] = {
- 0xe203ffc0, 0x08700040
- };
+ id = pdev->id;
+ bank = &gpio_bank[id];
- if (cpu_is_omap44xx()) {
- __raw_writel(0xffffffff, bank->base +
- OMAP4_GPIO_IRQSTATUSCLR0);
- __raw_writew(0x0015, bank->base +
- OMAP4_GPIO_SYSCONFIG);
- __raw_writel(0x00000000, bank->base +
- OMAP4_GPIO_DEBOUNCENABLE);
- /*
- * Initialize interface clock ungated,
- * module enabled
- */
- __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
- } else {
- __raw_writel(0x00000000, bank->base +
- OMAP24XX_GPIO_IRQENABLE1);
- __raw_writel(0xffffffff, bank->base +
- OMAP24XX_GPIO_IRQSTATUS1);
- __raw_writew(0x0015, bank->base +
- OMAP24XX_GPIO_SYSCONFIG);
- __raw_writel(0x00000000, bank->base +
- OMAP24XX_GPIO_DEBOUNCE_EN);
-
- /*
- * Initialize interface clock ungated,
- * module enabled
- */
- __raw_writel(0, bank->base +
- OMAP24XX_GPIO_CTRL);
- }
- if (cpu_is_omap24xx() &&
- i < ARRAY_SIZE(non_wakeup_gpios))
- bank->non_wakeup_gpios = non_wakeup_gpios[i];
- gpio_count = 32;
- }
-#endif
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
+ return -ENODEV;
+ }
- bank->mod_usage = 0;
- /* REVISIT eventually switch from OMAP-specific gpio structs
- * over to the generic ones
- */
- bank->chip.request = omap_gpio_request;
- bank->chip.free = omap_gpio_free;
- bank->chip.direction_input = gpio_input;
- bank->chip.get = gpio_get;
- bank->chip.direction_output = gpio_output;
- bank->chip.set_debounce = gpio_debounce;
- bank->chip.set = gpio_set;
- bank->chip.to_irq = gpio_2irq;
- if (bank_is_mpuio(bank)) {
- bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
- bank->chip.dev = &omap_mpuio_device.dev;
-#endif
- bank->chip.base = OMAP_MPUIO(0);
- } else {
- bank->chip.label = "gpio";
- bank->chip.base = gpio;
- gpio += gpio_count;
- }
- bank->chip.ngpio = gpio_count;
+ bank->irq = res->start;
+ bank->virtual_irq_start = pdata->virtual_irq_start;
+ bank->method = pdata->bank_type;
+ bank->dev = &pdev->dev;
+ bank->dbck_flag = pdata->dbck_flag;
+ bank->stride = pdata->bank_stride;
+ bank_width = pdata->bank_width;
- gpiochip_add(&bank->chip);
+ spin_lock_init(&bank->lock);
- for (j = bank->virtual_irq_start;
- j < bank->virtual_irq_start + gpio_count; j++) {
- lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
- set_irq_chip_data(j, bank);
- if (bank_is_mpuio(bank))
- set_irq_chip(j, &mpuio_irq_chip);
- else
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_simple_irq);
- set_irq_flags(j, IRQF_VALID);
- }
- set_irq_chained_handler(bank->irq, gpio_irq_handler);
- set_irq_data(bank->irq, bank);
-
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- sprintf(clk_name, "gpio%d_dbck", i + 1);
- bank->dbck = clk_get(NULL, clk_name);
- if (IS_ERR(bank->dbck))
- printk(KERN_ERR "Could not get %s\n", clk_name);
- }
+ /* Static mapping, never released */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
+ return -ENODEV;
}
- /* Enable system clock for GPIO module.
- * The CAM_CLK_CTRL *is* really the right place. */
- if (cpu_is_omap16xx())
- omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
+ bank->base = ioremap(res->start, resource_size(res));
+ if (!bank->base) {
+ dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
+ return -ENOMEM;
+ }
- /* Enable autoidle for the OCP interface */
- if (cpu_is_omap24xx())
- omap_writel(1 << 0, 0x48019010);
- if (cpu_is_omap34xx())
- omap_writel(1 << 0, 0x48306814);
+ pm_runtime_enable(bank->dev);
+ pm_runtime_get_sync(bank->dev);
+
+ omap_gpio_mod_init(bank, id);
+ omap_gpio_chip_init(bank);
+ omap_gpio_show_rev(bank);
- omap_gpio_show_rev();
+ if (!gpio_init_done)
+ gpio_init_done = 1;
return 0;
}
@@ -2074,7 +1863,7 @@ static struct sys_device omap_gpio_device = {
static int workaround_enabled;
-void omap2_gpio_prepare_for_idle(int power_state)
+void omap2_gpio_prepare_for_idle(int off_mode)
{
int i, c = 0;
int min = 0;
@@ -2090,7 +1879,7 @@ void omap2_gpio_prepare_for_idle(int power_state)
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_disable(bank->dbck);
- if (power_state > PWRDM_POWER_OFF)
+ if (!off_mode)
continue;
/* If going to OFF, remove triggering for all
@@ -2251,8 +2040,6 @@ void omap_gpio_save_context(void)
/* saving banks from 2-6 only since GPIO1 is in WKUP */
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- gpio_context[i].sysconfig =
- __raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);
gpio_context[i].irqenable1 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
gpio_context[i].irqenable2 =
@@ -2283,8 +2070,6 @@ void omap_gpio_restore_context(void)
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- __raw_writel(gpio_context[i].sysconfig,
- bank->base + OMAP24XX_GPIO_SYSCONFIG);
__raw_writel(gpio_context[i].irqenable1,
bank->base + OMAP24XX_GPIO_IRQENABLE1);
__raw_writel(gpio_context[i].irqenable2,
@@ -2309,25 +2094,28 @@ void omap_gpio_restore_context(void)
}
#endif
+static struct platform_driver omap_gpio_driver = {
+ .probe = omap_gpio_probe,
+ .driver = {
+ .name = "omap_gpio",
+ },
+};
+
/*
- * This may get called early from board specific init
- * for boards that have interrupts routed via FPGA.
+ * gpio driver register needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap_gpio_drv_reg() is a postcore_initcall.
*/
-int __init omap_gpio_init(void)
+static int __init omap_gpio_drv_reg(void)
{
- if (!initialized)
- return _omap_gpio_init();
- else
- return 0;
+ return platform_driver_register(&omap_gpio_driver);
}
+postcore_initcall(omap_gpio_drv_reg);
static int __init omap_gpio_sysinit(void)
{
int ret = 0;
- if (!initialized)
- ret = _omap_gpio_init();
-
mpuio_init();
#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5ce4f0aad35..a4f8003de664 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -27,20 +27,20 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-omap.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/mux.h>
#include <plat/i2c.h>
#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
#define OMAP1_I2C_BASE 0xfffb3800
-#define OMAP2_I2C_BASE1 0x48070000
-#define OMAP2_I2C_BASE2 0x48072000
-#define OMAP2_I2C_BASE3 0x48060000
-#define OMAP4_I2C_BASE4 0x48350000
-static const char name[] = "i2c_omap";
+static const char name[] = "omap_i2c";
#define I2C_RESOURCE_BUILDER(base, irq) \
{ \
@@ -55,15 +55,6 @@ static const char name[] = "i2c_omap";
static struct resource i2c_resources[][2] = {
{ I2C_RESOURCE_BUILDER(0, 0) },
-#if defined(CONFIG_ARCH_OMAP2PLUS)
- { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) },
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) },
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
- { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) },
-#endif
};
#define I2C_DEV_BUILDER(bus_id, res, data) \
@@ -77,18 +68,11 @@ static struct resource i2c_resources[][2] = {
}, \
}
-static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)];
+#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
+#define OMAP_I2C_MAX_CONTROLLERS 4
+static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
-#if defined(CONFIG_ARCH_OMAP2PLUS)
- I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
- I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]),
-#endif
};
#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
@@ -109,35 +93,25 @@ static int __init omap_i2c_nr_ports(void)
return ports;
}
-/* Shared between omap2 and 3 */
-static resource_size_t omap2_i2c_irq[3] __initdata = {
- INT_24XX_I2C1_IRQ,
- INT_24XX_I2C2_IRQ,
- INT_34XX_I2C3_IRQ,
-};
-
-static resource_size_t omap4_i2c_irq[4] __initdata = {
- OMAP44XX_IRQ_I2C1,
- OMAP44XX_IRQ_I2C2,
- OMAP44XX_IRQ_I2C3,
- OMAP44XX_IRQ_I2C4,
-};
-
-static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
+static inline int omap1_i2c_add_bus(int bus_id)
{
- struct omap_i2c_bus_platform_data *pd;
+ struct platform_device *pdev;
+ struct omap_i2c_bus_platform_data *pdata;
struct resource *res;
- pd = pdev->dev.platform_data;
+ omap1_i2c_mux_pins(bus_id);
+
+ pdev = &omap_i2c_devices[bus_id - 1];
res = pdev->resource;
res[0].start = OMAP1_I2C_BASE;
res[0].end = res[0].start + OMAP_I2C_SIZE;
res[1].start = INT_I2C;
- omap1_i2c_mux_pins(bus_id);
+ pdata = &i2c_pdata[bus_id - 1];
return platform_device_register(pdev);
}
+
/*
* XXX This function is a temporary compatibility wrapper - only
* needed until the I2C driver can be converted to call
@@ -148,52 +122,64 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
omap_pm_set_max_mpu_wakeup_lat(dev, t);
}
-static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
-{
- struct resource *res;
- resource_size_t *irq;
+static struct omap_device_pm_latency omap_i2c_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
- res = pdev->resource;
+#ifdef CONFIG_ARCH_OMAP2PLUS
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ int l;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
+ struct omap_i2c_bus_platform_data *pdata;
- if (!cpu_is_omap44xx())
- irq = omap2_i2c_irq;
- else
- irq = omap4_i2c_irq;
+ omap2_i2c_mux_pins(bus_id);
- if (bus_id == 1) {
- res[0].start = OMAP2_I2C_BASE1;
- res[0].end = res[0].start + OMAP_I2C_SIZE;
+ l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
+ WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
+ "String buffer overflow in I2C%d device setup\n", bus_id);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -EEXIST;
}
- res[1].start = irq[bus_id - 1];
- omap2_i2c_mux_pins(bus_id);
-
+ pdata = &i2c_pdata[bus_id - 1];
/*
* When waiting for completion of a i2c transfer, we need to
* set a wake up latency constraint for the MPU. This is to
* ensure quick enough wakeup from idle, when transfer
* completes.
+ * Only omap3 has support for constraints
*/
- if (cpu_is_omap34xx()) {
- struct omap_i2c_bus_platform_data *pd;
-
- pd = pdev->dev.platform_data;
- pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
- }
-
- return platform_device_register(pdev);
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+ od = omap_device_build(name, bus_id, oh, pdata,
+ sizeof(struct omap_i2c_bus_platform_data),
+ omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
+ WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
+
+ return PTR_ERR(od);
}
+#else
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ return 0;
+}
+#endif
static int __init omap_i2c_add_bus(int bus_id)
{
- struct platform_device *pdev;
-
- pdev = &omap_i2c_devices[bus_id - 1];
-
if (cpu_class_is_omap1())
- return omap1_i2c_add_bus(pdev, bus_id);
+ return omap1_i2c_add_bus(bus_id);
else
- return omap2_i2c_add_bus(pdev, bus_id);
+ return omap2_i2c_add_bus(bus_id);
}
/**
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index 4b2028ab4d2b..256ab3f1ec8f 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -31,18 +31,18 @@ struct omap_clk {
#define CK_1510 (1 << 2)
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
#define CK_242X (1 << 4)
-#define CK_243X (1 << 5)
-#define CK_3XXX (1 << 6) /* OMAP3 + AM3 common clocks*/
-#define CK_343X (1 << 7) /* OMAP34xx common clocks */
-#define CK_3430ES1 (1 << 8) /* 34xxES1 only */
-#define CK_3430ES2 (1 << 9) /* 34xxES2, ES3, non-Sitara 35xx only */
-#define CK_3505 (1 << 10)
-#define CK_3517 (1 << 11)
-#define CK_36XX (1 << 12) /* OMAP36xx/37xx-specific clocks */
-#define CK_443X (1 << 13)
+#define CK_243X (1 << 5) /* 243x, 253x */
+#define CK_3430ES1 (1 << 6) /* 34xxES1 only */
+#define CK_3430ES2PLUS (1 << 7) /* 34xxES2, ES3, non-Sitara 35xx only */
+#define CK_3505 (1 << 8)
+#define CK_3517 (1 << 9)
+#define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */
+#define CK_443X (1 << 11)
-#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
+#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
+#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
+#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
#endif
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index fef4696dcf67..8eb0adab19ea 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -49,13 +49,18 @@ struct clkops {
/* struct clksel_rate.flags possibilities */
#define RATE_IN_242X (1 << 0)
#define RATE_IN_243X (1 << 1)
-#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
-#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
+#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */
+#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */
#define RATE_IN_36XX (1 << 4)
#define RATE_IN_4430 (1 << 5)
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
-#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
+#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
+#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX)
+
+/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
+#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
+
/**
* struct clksel_rate - register bitfield values corresponding to clk divisors
@@ -119,8 +124,7 @@ struct clksel {
*
* Possible values for @flags:
* DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
- * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs)
-
+ *
* @freqsel_mask is only used on the OMAP34xx family and AM35xx.
*
* XXX Some DPLLs have multiple bypass inputs, so it's not technically
@@ -156,6 +160,8 @@ struct dpll_data {
u32 autoidle_mask;
u32 freqsel_mask;
u32 idlest_mask;
+ u32 dco_mask;
+ u32 sddiv_mask;
u8 auto_recal_bit;
u8 recal_en_bit;
u8 recal_st_bit;
diff --git a/arch/arm/plat-omap/include/plat/clockdomain.h b/arch/arm/plat-omap/include/plat/clockdomain.h
deleted file mode 100644
index ba0a6c07c0fe..000000000000
--- a/arch/arm/plat-omap/include/plat/clockdomain.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
- * OMAP2/3 clockdomain framework functions
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
-#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
-
-#include <plat/powerdomain.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* Clockdomain capability flags */
-#define CLKDM_CAN_FORCE_SLEEP (1 << 0)
-#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)
-#define CLKDM_CAN_ENABLE_AUTO (1 << 2)
-#define CLKDM_CAN_DISABLE_AUTO (1 << 3)
-
-#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
-#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
-#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
-
-/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
-#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
-#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
-
-/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
-#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0
-#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1
-#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
-#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
-
-/**
- * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
- * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
- * @omap_chip: OMAP chip types that this autodep is valid on
- *
- * A clockdomain that should have wkdeps and sleepdeps added when a
- * clockdomain should stay active in hwsup mode; and conversely,
- * removed when the clockdomain should be allowed to go inactive in
- * hwsup mode.
- *
- * Autodeps are deprecated and should be removed after
- * omap_hwmod-based fine-grained module idle control is added.
- */
-struct clkdm_autodep {
- union {
- const char *name;
- struct clockdomain *ptr;
- } clkdm;
- const struct omap_chip_id omap_chip;
-};
-
-/**
- * struct clkdm_dep - encode dependencies between clockdomains
- * @clkdm_name: clockdomain name
- * @clkdm: pointer to the struct clockdomain of @clkdm_name
- * @omap_chip: OMAP chip types that this dependency is valid on
- * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake
- * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle
- *
- * Statically defined. @clkdm is resolved from @clkdm_name at runtime and
- * should not be pre-initialized.
- *
- * XXX Should also include hardware (fixed) dependencies.
- */
-struct clkdm_dep {
- const char *clkdm_name;
- struct clockdomain *clkdm;
- atomic_t wkdep_usecount;
- atomic_t sleepdep_usecount;
- const struct omap_chip_id omap_chip;
-};
-
-/**
- * struct clockdomain - OMAP clockdomain
- * @name: clockdomain name
- * @pwrdm: powerdomain containing this clockdomain
- * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain
- * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
- * @flags: Clockdomain capability flags
- * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
- * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
- * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
- * @omap_chip: OMAP chip types that this clockdomain is valid on
- * @usecount: Usecount tracking
- * @node: list_head to link all clockdomains together
- */
-struct clockdomain {
- const char *name;
- union {
- const char *name;
- struct powerdomain *ptr;
- } pwrdm;
- void __iomem *clkstctrl_reg;
- const u16 clktrctrl_mask;
- const u8 flags;
- const u8 dep_bit;
- struct clkdm_dep *wkdep_srcs;
- struct clkdm_dep *sleepdep_srcs;
- const struct omap_chip_id omap_chip;
- atomic_t usecount;
- struct list_head node;
-};
-
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps);
-struct clockdomain *clkdm_lookup(const char *name);
-
-int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
- void *user);
-struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
-
-int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
-int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
-int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
-
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
-
-int omap2_clkdm_wakeup(struct clockdomain *clkdm);
-int omap2_clkdm_sleep(struct clockdomain *clkdm);
-
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
-
-#endif
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index a9d69a09920d..6b8088ec74af 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -27,6 +27,8 @@
#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
#define __ARCH_ARM_MACH_OMAP_COMMON_H
+#include <linux/delay.h>
+
#include <plat/i2c.h>
struct sys_timer;
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 0cce4ca83aa0..d1c916fcf770 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -21,141 +21,15 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
-/* Move omap4 specific defines to dma-44xx.h */
-#include "dma-44xx.h"
+#include <linux/platform_device.h>
-/* Hardware registers for omap1 */
-#define OMAP1_DMA_BASE (0xfffed800)
-
-#define OMAP1_DMA_GCR 0x400
-#define OMAP1_DMA_GSCR 0x404
-#define OMAP1_DMA_GRST 0x408
-#define OMAP1_DMA_HW_ID 0x442
-#define OMAP1_DMA_PCH2_ID 0x444
-#define OMAP1_DMA_PCH0_ID 0x446
-#define OMAP1_DMA_PCH1_ID 0x448
-#define OMAP1_DMA_PCHG_ID 0x44a
-#define OMAP1_DMA_PCHD_ID 0x44c
-#define OMAP1_DMA_CAPS_0_U 0x44e
-#define OMAP1_DMA_CAPS_0_L 0x450
-#define OMAP1_DMA_CAPS_1_U 0x452
-#define OMAP1_DMA_CAPS_1_L 0x454
-#define OMAP1_DMA_CAPS_2 0x456
-#define OMAP1_DMA_CAPS_3 0x458
-#define OMAP1_DMA_CAPS_4 0x45a
-#define OMAP1_DMA_PCH2_SR 0x460
-#define OMAP1_DMA_PCH0_SR 0x480
-#define OMAP1_DMA_PCH1_SR 0x482
-#define OMAP1_DMA_PCHD_SR 0x4c0
-
-/* Hardware registers for omap2 and omap3 */
-#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
-#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
-#define OMAP44XX_DMA4_BASE (L4_44XX_BASE + 0x56000)
-
-#define OMAP_DMA4_REVISION 0x00
-#define OMAP_DMA4_GCR 0x78
-#define OMAP_DMA4_IRQSTATUS_L0 0x08
-#define OMAP_DMA4_IRQSTATUS_L1 0x0c
-#define OMAP_DMA4_IRQSTATUS_L2 0x10
-#define OMAP_DMA4_IRQSTATUS_L3 0x14
-#define OMAP_DMA4_IRQENABLE_L0 0x18
-#define OMAP_DMA4_IRQENABLE_L1 0x1c
-#define OMAP_DMA4_IRQENABLE_L2 0x20
-#define OMAP_DMA4_IRQENABLE_L3 0x24
-#define OMAP_DMA4_SYSSTATUS 0x28
-#define OMAP_DMA4_OCP_SYSCONFIG 0x2c
-#define OMAP_DMA4_CAPS_0 0x64
-#define OMAP_DMA4_CAPS_2 0x6c
-#define OMAP_DMA4_CAPS_3 0x70
-#define OMAP_DMA4_CAPS_4 0x74
-
-#define OMAP1_LOGICAL_DMA_CH_COUNT 17
-#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
-
-/* Common channel specific registers for omap1 */
-#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00)
-#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00)
-#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02)
-#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04)
-#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06)
-#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10)
-#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12)
-#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14)
-#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16)
-#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18) /* 15xx only */
-#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18)
-#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a)
-#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c)
-#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e)
-#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28)
-
-/* Common channel specific registers for omap2 */
-#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80)
-#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80)
-#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84)
-#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88)
-#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c)
-#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90)
-#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94)
-#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98)
-#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4)
-#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8)
-#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac)
-#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0)
-#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4)
-#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8)
-
-/* Channel specific registers only on omap1 */
-#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08)
-#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a)
-#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c)
-#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e)
-#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20)
-#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22)
-#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24)
-#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a) /* not on 15xx */
-#define OMAP1_DMA_CCEN(n) 0
-#define OMAP1_DMA_CCFN(n) 0
-
-/* Channel specific registers only on omap2 */
-#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c)
-#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0)
-#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc)
-#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0)
-#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4)
-
-/* Additional registers available on OMAP4 */
-#define OMAP_DMA4_CDP(n) (0x60 * (n) + 0xd0)
-#define OMAP_DMA4_CNDP(n) (0x60 * (n) + 0xd4)
-#define OMAP_DMA4_CCDN(n) (0x60 * (n) + 0xd8)
-
-/* Dummy defines to keep multi-omap compiles happy */
-#define OMAP1_DMA_REVISION 0
-#define OMAP1_DMA_IRQSTATUS_L0 0
-#define OMAP1_DMA_IRQENABLE_L0 0
-#define OMAP1_DMA_OCP_SYSCONFIG 0
-#define OMAP_DMA4_HW_ID 0
-#define OMAP_DMA4_CAPS_0_L 0
-#define OMAP_DMA4_CAPS_0_U 0
-#define OMAP_DMA4_CAPS_1_L 0
-#define OMAP_DMA4_CAPS_1_U 0
-#define OMAP_DMA4_GSCR 0
-#define OMAP_DMA4_CPC(n) 0
-
-#define OMAP_DMA4_LCH_CTRL(n) 0
-#define OMAP_DMA4_COLOR_L(n) 0
-#define OMAP_DMA4_COLOR_U(n) 0
-#define OMAP_DMA4_CCR2(n) 0
-#define OMAP1_DMA_CSSA(n) 0
-#define OMAP1_DMA_CDSA(n) 0
-#define OMAP_DMA4_CSSA_L(n) 0
-#define OMAP_DMA4_CSSA_U(n) 0
-#define OMAP_DMA4_CDSA_L(n) 0
-#define OMAP_DMA4_CDSA_U(n) 0
-#define OMAP1_DMA_COLOR(n) 0
+/*
+ * TODO: These dma channel defines should go away once all
+ * the omap drivers hwmod adapted.
+ */
-/*----------------------------------------------------------------------------*/
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
/* DMA channels for omap1 */
#define OMAP_DMA_NO_DEVICE 0
@@ -405,6 +279,63 @@
#define DMA_CH_PRIO_HIGH 0x1
#define DMA_CH_PRIO_LOW 0x0 /* Def */
+/* Errata handling */
+#define IS_DMA_ERRATA(id) (errata & (id))
+#define SET_DMA_ERRATA(id) (errata |= (id))
+
+#define DMA_ERRATA_IFRAME_BUFFERING BIT(0x0)
+#define DMA_ERRATA_PARALLEL_CHANNELS BIT(0x1)
+#define DMA_ERRATA_i378 BIT(0x2)
+#define DMA_ERRATA_i541 BIT(0x3)
+#define DMA_ERRATA_i88 BIT(0x4)
+#define DMA_ERRATA_3_3 BIT(0x5)
+#define DMA_ROMCODE_BUG BIT(0x6)
+
+/* Attributes for OMAP DMA Contrller */
+#define DMA_LINKED_LCH BIT(0x0)
+#define GLOBAL_PRIORITY BIT(0x1)
+#define RESERVE_CHANNEL BIT(0x2)
+#define IS_CSSA_32 BIT(0x3)
+#define IS_CDSA_32 BIT(0x4)
+#define IS_RW_PRIORITY BIT(0x5)
+#define ENABLE_1510_MODE BIT(0x6)
+#define SRC_PORT BIT(0x7)
+#define DST_PORT BIT(0x8)
+#define SRC_INDEX BIT(0x9)
+#define DST_INDEX BIT(0xA)
+#define IS_BURST_ONLY4 BIT(0xB)
+#define CLEAR_CSR_ON_READ BIT(0xC)
+#define IS_WORD_16 BIT(0xD)
+
+enum omap_reg_offsets {
+
+GCR, GSCR, GRST1, HW_ID,
+PCH2_ID, PCH0_ID, PCH1_ID, PCHG_ID,
+PCHD_ID, CAPS_0, CAPS_1, CAPS_2,
+CAPS_3, CAPS_4, PCH2_SR, PCH0_SR,
+PCH1_SR, PCHD_SR, REVISION, IRQSTATUS_L0,
+IRQSTATUS_L1, IRQSTATUS_L2, IRQSTATUS_L3, IRQENABLE_L0,
+IRQENABLE_L1, IRQENABLE_L2, IRQENABLE_L3, SYSSTATUS,
+OCP_SYSCONFIG,
+
+/* omap1+ specific */
+CPC, CCR2, LCH_CTRL,
+
+/* Common registers for all omap's */
+CSDP, CCR, CICR, CSR,
+CEN, CFN, CSFI, CSEI,
+CSAC, CDAC, CDEI,
+CDFI, CLNK_CTRL,
+
+/* Channel specific registers */
+CSSA, CDSA, COLOR,
+CCEN, CCFN,
+
+/* omap3630 and omap4 specific */
+CDP, CNDP, CCDN,
+
+};
+
enum omap_dma_burst_mode {
OMAP_DMA_DATA_BURST_DIS = 0,
OMAP_DMA_DATA_BURST_4,
@@ -470,6 +401,41 @@ struct omap_dma_channel_params {
#endif
};
+struct omap_dma_lch {
+ int next_lch;
+ int dev_id;
+ u16 saved_csr;
+ u16 enabled_irqs;
+ const char *dev_name;
+ void (*callback)(int lch, u16 ch_status, void *data);
+ void *data;
+ long flags;
+ /* required for Dynamic chaining */
+ int prev_linked_ch;
+ int next_linked_ch;
+ int state;
+ int chain_id;
+ int status;
+};
+
+struct omap_dma_dev_attr {
+ u32 dev_caps;
+ u16 lch_count;
+ u16 chan_count;
+ struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+ struct omap_dma_dev_attr *dma_attr;
+ u32 errata;
+ void (*disable_irq_lch)(int lch);
+ void (*show_dma_caps)(void);
+ void (*clear_lch_regs)(int lch);
+ void (*clear_dma)(int lch);
+ void (*dma_write)(u32 val, int reg, int lch);
+ u32 (*dma_read)(int reg, int lch);
+};
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
diff --git a/arch/arm/plat-omap/include/plat/fpga.h b/arch/arm/plat-omap/include/plat/fpga.h
index f1864a652f7a..ae39bcb3f5ba 100644
--- a/arch/arm/plat-omap/include/plat/fpga.h
+++ b/arch/arm/plat-omap/include/plat/fpga.h
@@ -19,11 +19,7 @@
#ifndef __ASM_ARCH_OMAP_FPGA_H
#define __ASM_ARCH_OMAP_FPGA_H
-#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
extern void omap1510_fpga_init_irq(void);
-#else
-#define omap1510_fpga_init_irq() (0)
-#endif
#define fpga_read(reg) __raw_readb(reg)
#define fpga_write(val, reg) __raw_writeb(val, reg)
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index de1c604962eb..d6f9fa0f62af 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -27,26 +27,15 @@
#define __ASM_ARCH_OMAP_GPIO_H
#include <linux/io.h>
+#include <linux/platform_device.h>
#include <mach/irqs.h>
#define OMAP1_MPUIO_BASE 0xfffb5000
-#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
-
-#define OMAP_MPUIO_INPUT_LATCH 0x00
-#define OMAP_MPUIO_OUTPUT 0x02
-#define OMAP_MPUIO_IO_CNTL 0x04
-#define OMAP_MPUIO_KBR_LATCH 0x08
-#define OMAP_MPUIO_KBC 0x0a
-#define OMAP_MPUIO_GPIO_EVENT_MODE 0x0c
-#define OMAP_MPUIO_GPIO_INT_EDGE 0x0e
-#define OMAP_MPUIO_KBD_INT 0x10
-#define OMAP_MPUIO_GPIO_INT 0x12
-#define OMAP_MPUIO_KBD_MASKIT 0x14
-#define OMAP_MPUIO_GPIO_MASKIT 0x16
-#define OMAP_MPUIO_GPIO_DEBOUNCING 0x18
-#define OMAP_MPUIO_LATCH 0x1a
-#else
+/*
+ * These are the omap15xx/16xx offsets. The omap7xx offset are
+ * OMAP_MPUIO_ / 2 offsets below.
+ */
#define OMAP_MPUIO_INPUT_LATCH 0x00
#define OMAP_MPUIO_OUTPUT 0x04
#define OMAP_MPUIO_IO_CNTL 0x08
@@ -60,7 +49,6 @@
#define OMAP_MPUIO_GPIO_MASKIT 0x2c
#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
#define OMAP_MPUIO_LATCH 0x34
-#endif
#define OMAP34XX_NR_GPIOS 6
@@ -71,8 +59,30 @@
IH_MPUIO_BASE + ((nr) & 0x0f) : \
IH_GPIO_BASE + (nr))
-extern int omap_gpio_init(void); /* Call from board init only */
-extern void omap2_gpio_prepare_for_idle(int power_state);
+#define METHOD_MPUIO 0
+#define METHOD_GPIO_1510 1
+#define METHOD_GPIO_1610 2
+#define METHOD_GPIO_7XX 3
+#define METHOD_GPIO_24XX 5
+#define METHOD_GPIO_44XX 6
+
+struct omap_gpio_dev_attr {
+ int bank_width; /* GPIO bank width */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+struct omap_gpio_platform_data {
+ u16 virtual_irq_start;
+ int bank_type;
+ int bank_width; /* GPIO bank width */
+ int bank_stride; /* Only needed for omap1 MPUIO */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+extern int gpio_bank_count;
+
+extern void omap2_gpio_prepare_for_idle(int off_mode);
extern void omap2_gpio_resume_after_idle(void);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 9fd99b9e40ab..85ded598853e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -80,12 +80,12 @@
#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
/*
- * Note that all values in this struct are in nanoseconds, while
- * the register values are in gpmc_fck cycles.
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
*/
struct gpmc_timings {
- /* Minimum clock period for synchronous mode */
- u16 sync_clk;
+ /* Minimum clock period for synchronous mode (in picoseconds) */
+ u32 sync_clk;
/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
u16 cs_on; /* Assertion time */
@@ -117,6 +117,7 @@ struct gpmc_timings {
};
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
extern unsigned long gpmc_get_fclk_period(void);
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,
}
#endif
+/**
+ * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod
+ * @fifo_depth: total controller FIFO size (in bytes)
+ * @flags: differences in hardware support capability
+ *
+ * @fifo_depth represents what exists on the hardware, not what is
+ * actually configured at runtime by the device driver.
+ */
+struct omap_i2c_dev_attr {
+ u8 fifo_depth;
+ u8 flags;
+};
+
void __init omap1_i2c_mux_pins(int bus_id);
void __init omap2_i2c_mux_pins(int bus_id);
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
index 204865f91d93..ef4106c13183 100644
--- a/arch/arm/plat-omap/include/plat/io.h
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -291,8 +291,9 @@ static inline void omap44xx_map_common_io(void)
}
#endif
-extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
- struct omap_sdrc_params *sdrc_cs1);
+extern void omap2_init_common_infrastructure(void);
+extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1);
#define __arch_ioremap omap_ioremap
#define __arch_iounmap omap_iounmap
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 33c7d41cb6a5..69230d685538 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -50,6 +50,8 @@ struct iommu {
int (*isr)(struct iommu *obj);
void *ctx; /* iommu context: registres saved area */
+ u32 da_start;
+ u32 da_end;
};
struct cr_regs {
@@ -103,6 +105,8 @@ struct iommu_platform_data {
const char *name;
const char *clk_name;
const int nr_tlb_entries;
+ u32 da_start;
+ u32 da_end;
};
#if defined(CONFIG_ARCH_OMAP1)
@@ -152,6 +156,7 @@ extern void flush_iotlb_all(struct iommu *obj);
extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
+extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
extern struct iommu *iommu_get(const char *name);
extern void iommu_put(struct iommu *obj);
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 65e20a686713..2910de921c52 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -77,7 +77,7 @@
/*
* OMAP-1610 specific IRQ numbers for interrupt handler 1
*/
-#define INT_1610_IH2_IRQ 0
+#define INT_1610_IH2_IRQ INT_1510_IH2_IRQ
#define INT_1610_IH2_FIQ 2
#define INT_1610_McBSP2_TX 4
#define INT_1610_McBSP2_RX 5
diff --git a/arch/arm/plat-omap/include/plat/keypad.h b/arch/arm/plat-omap/include/plat/keypad.h
index 3ae52ccc793c..793ce9d53294 100644
--- a/arch/arm/plat-omap/include/plat/keypad.h
+++ b/arch/arm/plat-omap/include/plat/keypad.h
@@ -10,16 +10,18 @@
#ifndef ASMARM_ARCH_KEYPAD_H
#define ASMARM_ARCH_KEYPAD_H
-#warning: Please update the board to use matrix_keypad.h instead
+#ifndef CONFIG_ARCH_OMAP1
+#warning Please update the board to use matrix-keypad driver
+#endif
+#include <linux/input/matrix_keypad.h>
struct omap_kp_platform_data {
int rows;
int cols;
- int *keymap;
- unsigned int keymapsize;
- unsigned int rep:1;
+ const struct matrix_keymap_data *keymap_data;
+ bool rep;
unsigned long delay;
- unsigned int dbounce:1;
+ bool dbounce;
/* specific to OMAP242x*/
unsigned int *row_gpios;
unsigned int *col_gpios;
@@ -28,18 +30,21 @@ struct omap_kp_platform_data {
/* Group (0..3) -- when multiple keys are pressed, only the
* keys pressed in the same group are considered as pressed. This is
* in order to workaround certain crappy HW designs that produce ghost
- * keypresses. */
-#define GROUP_0 (0 << 16)
-#define GROUP_1 (1 << 16)
-#define GROUP_2 (2 << 16)
-#define GROUP_3 (3 << 16)
+ * keypresses. Two free bits, not used by neither row/col nor keynum,
+ * must be available for use as group bits. The below GROUP_SHIFT
+ * macro definition is based on some prior knowledge of the
+ * matrix_keypad defined KEY() macro internals.
+ */
+#define GROUP_SHIFT 14
+#define GROUP_0 (0 << GROUP_SHIFT)
+#define GROUP_1 (1 << GROUP_SHIFT)
+#define GROUP_2 (2 << GROUP_SHIFT)
+#define GROUP_3 (3 << GROUP_SHIFT)
#define GROUP_MASK GROUP_3
+#if KEY_MAX & GROUP_MASK
+#error Group bits in conflict with keynum bits
+#endif
-#define KEY_PERSISTENT 0x00800000
-#define KEYNUM_MASK 0x00EFFFFF
-#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
-#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
- KEY_PERSISTENT)
#endif
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 @@
+/*
+ * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+
+/* L4 CORE */
+#define OMAP3_L4_CORE_FW_I2C1_REGION 21
+#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22
+#define OMAP3_L4_CORE_FW_I2C2_REGION 23
+#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24
+#define OMAP3_L4_CORE_FW_I2C3_REGION 73
+#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h
index 997656552109..cc3921e9059c 100644
--- a/arch/arm/plat-omap/include/plat/mailbox.h
+++ b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -46,8 +46,8 @@ struct omap_mbox_queue {
struct kfifo fifo;
struct work_struct work;
struct tasklet_struct tasklet;
- int (*callback)(void *);
struct omap_mbox *mbox;
+ bool full;
};
struct omap_mbox {
@@ -57,13 +57,15 @@ struct omap_mbox {
struct omap_mbox_ops *ops;
struct device *dev;
void *priv;
+ int use_count;
+ struct blocking_notifier_head notifier;
};
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
void omap_mbox_init_seq(struct omap_mbox *);
-struct omap_mbox *omap_mbox_get(const char *);
-void omap_mbox_put(struct omap_mbox *);
+struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
int omap_mbox_register(struct device *parent, struct omap_mbox **);
int omap_mbox_unregister(void);
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 728fbb9dd549..c0a752053039 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -17,26 +17,7 @@
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
-
-#include "powerdomain.h"
-
-/**
- * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
- * @rate: target clock rate
- * @opp_id: OPP ID
- * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
- *
- * Operating performance point data. Can vary by OMAP chip and board.
- */
-struct omap_opp {
- unsigned long rate;
- u8 opp_id;
- u16 min_vdd;
-};
-
-extern struct omap_opp *mpu_opps;
-extern struct omap_opp *dsp_opps;
-extern struct omap_opp *l3_opps;
+#include <linux/opp.h>
/*
* agent_id values for use with omap_pm_set_min_bus_tput():
@@ -59,9 +40,11 @@ extern struct omap_opp *l3_opps;
* framework starts. The "_if_" is to avoid name collisions with the
* PM idle-loop code.
*/
-int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
- struct omap_opp *dsp_opp_table,
- struct omap_opp *l3_opp_table);
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_early_init() 0
+#else
+int __init omap_pm_if_early_init(void);
+#endif
/**
* omap_pm_if_init - OMAP PM init code called after clock fw init
@@ -69,7 +52,11 @@ int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
* The main initialization code. OPP tables are passed in here. The
* "_if_" is to avoid name collisions with the PM idle-loop code.
*/
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_init() 0
+#else
int __init omap_pm_if_init(void);
+#endif
/**
* omap_pm_if_exit - OMAP PM exit code
@@ -363,9 +350,11 @@ unsigned long omap_pm_cpu_get_freq(void);
* driver must restore device context. If the number of context losses
* exceeds the maximum positive integer, the function will wrap to 0 and
* continue counting. Returns the number of context losses for this device,
- * or -EINVAL upon error.
+ * or zero upon error.
*/
-int omap_pm_get_dev_context_loss_count(struct device *dev);
+u32 omap_pm_get_dev_context_loss_count(struct device *dev);
+void omap_pm_enable_off_mode(void);
+void omap_pm_disable_off_mode(void);
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index c8dae02f0704..2682043f5a5b 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -22,7 +22,7 @@
#include <plat/mux.h>
-#define DRIVER_NAME "omap-hsuart"
+#define DRIVER_NAME "omap_uart"
/*
* Use tty device name as ttyO, [O -> OMAP]
@@ -31,20 +31,8 @@
*/
#define OMAP_SERIAL_NAME "ttyO"
-#define OMAP_MDR1_DISABLE 0x07
-#define OMAP_MDR1_MODE13X 0x03
-#define OMAP_MDR1_MODE16X 0x00
#define OMAP_MODE13X_SPEED 230400
-/*
- * LCR = 0XBF: Switch to Configuration Mode B.
- * In configuration mode b allow access
- * to EFR,DLL,DLH.
- * Reference OMAP TRM Chapter 17
- * Section: 1.4.3 Mode Selection
- */
-#define OMAP_UART_LCR_CONF_MDB 0XBF
-
/* WER = 0x7F
* Enable module level wakeup in WER reg
*/
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 28e2d1a78433..e4c349ff9fd8 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -107,6 +107,7 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+u32 omap_device_get_context_loss_count(struct platform_device *pdev);
/* Other */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 7eaa8edf3b14..6864a997f2ca 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -23,7 +23,7 @@
* - add pinmuxing
* - init_conn_id_bit (CONNID_BIT_VECTOR)
* - implement default hwmod SMS/SDRC flags?
- * - remove unused fields
+ * - move Linux-specific data ("non-ROM data") out
*
*/
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
@@ -32,8 +32,9 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ioport.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
struct omap_device;
@@ -76,6 +77,20 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_FORCE (1 << 0)
#define HWMOD_IDLEMODE_NO (1 << 1)
#define HWMOD_IDLEMODE_SMART (1 << 2)
+/* Slave idle mode flag only */
+#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
+
+/**
+ * struct omap_hwmod_mux_info - hwmod specific mux configuration
+ * @pads: array of omap_device_pad entries
+ * @nr_pads: number of omap_device_pad entries
+ *
+ * Note that this is currently built during init as needed.
+ */
+struct omap_hwmod_mux_info {
+ int nr_pads;
+ struct omap_device_pad *pads;
+};
/**
* struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
@@ -159,7 +174,7 @@ struct omap_hwmod_omap2_firewall {
* ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
* ADDR_TYPE_RT: Address space contains module register target data.
*/
-#define ADDR_MAP_ON_INIT (1 << 0)
+#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */
#define ADDR_TYPE_RT (1 << 1)
/**
@@ -200,8 +215,6 @@ struct omap_hwmod_addr_space {
* @fw: interface firewall data
* @addr_cnt: ARRAY_SIZE(@addr)
* @width: OCP data width
- * @thread_cnt: number of threads
- * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
* @user: initiators using this interface (see OCP_USER_* macros above)
* @flags: OCP interface flags (see OCPIF_* macros above)
*
@@ -221,8 +234,6 @@ struct omap_hwmod_ocp_if {
} fw;
u8 addr_cnt;
u8 width;
- u8 thread_cnt;
- u8 max_burst_len;
u8 user;
u8 flags;
};
@@ -231,11 +242,12 @@ struct omap_hwmod_ocp_if {
/* Macros for use in struct omap_hwmod_sysconfig */
/* Flags for use in omap_hwmod_sysconfig.idlemodes */
-#define MASTER_STANDBY_SHIFT 2
+#define MASTER_STANDBY_SHIFT 4
#define SLAVE_IDLE_SHIFT 0
#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT)
#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
@@ -357,14 +369,14 @@ struct omap_hwmod_omap4_prcm {
* HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
* of standby, rather than relying on module smart-standby
* HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
- * SDRAM controller, etc.
+ * SDRAM controller, etc. XXX probably belongs outside the main hwmod file
* HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
- * controller, etc.
+ * controller, etc. XXX probably belongs outside the main hwmod file
* HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
* when module is enabled, rather than the default, which is to
* enable autoidle
* HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
- * HWMOD_NO_IDLEST : this module does not have idle status - this is the case
+ * HWMOD_NO_IDLEST: this module does not have idle status - this is the case
* only for few initiator modules on OMAP2 & 3.
* HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
* This is needed for devices like DSS that require optional clocks enabled
@@ -415,14 +427,31 @@ struct omap_hwmod_omap4_prcm {
* @name: name of the hwmod_class
* @sysc: device SYSCONFIG/SYSSTATUS register data
* @rev: revision of the IP class
+ * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
+ * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
*
* Represent the class of a OMAP hardware "modules" (e.g. timer,
* smartreflex, gpio, uart...)
+ *
+ * @pre_shutdown is a function that will be run immediately before
+ * hwmod clocks are disabled, etc. It is intended for use for hwmods
+ * like the MPU watchdog, which cannot be disabled with the standard
+ * omap_hwmod_shutdown(). The function should return 0 upon success,
+ * or some negative error upon failure. Returning an error will cause
+ * omap_hwmod_shutdown() to abort the device shutdown and return an
+ * error.
+ *
+ * If @reset is defined, then the function it points to will be
+ * executed in place of the standard hwmod _reset() code in
+ * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have
+ * unusual reset sequences - usually processor IP blocks like the IVA.
*/
struct omap_hwmod_class {
const char *name;
struct omap_hwmod_class_sysconfig *sysc;
u32 rev;
+ int (*pre_shutdown)(struct omap_hwmod *oh);
+ int (*reset)(struct omap_hwmod *oh);
};
/**
@@ -436,14 +465,14 @@ struct omap_hwmod_class {
* @main_clk: main clock: OMAP clock name
* @_clk: pointer to the main struct clk (filled in at runtime)
* @opt_clks: other device clocks that drivers can request (0..*)
+ * @vdd_name: voltage domain name
+ * @voltdm: pointer to voltage domain (filled in at runtime)
* @masters: ptr to array of OCP ifs that this hwmod can initiate on
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
* @dev_attr: arbitrary device attributes that can be passed to the driver
* @_sysc_cache: internal-use hwmod flags
* @_mpu_rt_va: cached register target start address (internal use)
* @_mpu_port_index: cached MPU register target slave ID (internal use)
- * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
- * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
* @mpu_irqs_cnt: number of @mpu_irqs
* @sdma_reqs_cnt: number of @sdma_reqs
* @opt_clks_cnt: number of @opt_clks
@@ -452,9 +481,10 @@ struct omap_hwmod_class {
* @response_lat: device OCP response latency (in interface clock cycles)
* @_int_flags: internal-use hwmod flags
* @_state: internal-use hwmod state
+ * @_postsetup_state: internal-use state to leave the hwmod in after _setup()
* @flags: hwmod flags (documented below)
* @omap_chip: OMAP chips this hwmod is present on
- * @_mutex: mutex serializing operations on this hwmod
+ * @_lock: spinlock serializing operations on this hwmod
* @node: list node for hwmod list (internal use)
*
* @main_clk refers to this module's "main clock," which for our
@@ -469,6 +499,7 @@ struct omap_hwmod {
const char *name;
struct omap_hwmod_class *class;
struct omap_device *od;
+ struct omap_hwmod_mux_info *mux;
struct omap_hwmod_irq_info *mpu_irqs;
struct omap_hwmod_dma_info *sdma_reqs;
struct omap_hwmod_rst_info *rst_lines;
@@ -479,17 +510,17 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
+ char *vdd_name;
+ struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
u32 _sysc_cache;
void __iomem *_mpu_rt_va;
- struct mutex _mutex;
+ spinlock_t _lock;
struct list_head node;
u16 flags;
u8 _mpu_port_index;
- u8 msuspendmux_reg_id;
- u8 msuspendmux_shift;
u8 response_lat;
u8 mpu_irqs_cnt;
u8 sdma_reqs_cnt;
@@ -500,16 +531,15 @@ struct omap_hwmod {
u8 hwmods_cnt;
u8 _int_flags;
u8 _state;
+ u8 _postsetup_state;
const struct omap_chip_id omap_chip;
};
int omap_hwmod_init(struct omap_hwmod **ohs);
-int omap_hwmod_register(struct omap_hwmod *oh);
-int omap_hwmod_unregister(struct omap_hwmod *oh);
struct omap_hwmod *omap_hwmod_lookup(const char *name);
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
void *data);
-int omap_hwmod_late_init(u8 skip_setup_idle);
+int omap_hwmod_late_init(void);
int omap_hwmod_enable(struct omap_hwmod *oh);
int _omap_hwmod_enable(struct omap_hwmod *oh);
@@ -556,6 +586,9 @@ int omap_hwmod_for_each_by_class(const char *classname,
void *user),
void *user);
+int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
+u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+
/*
* Chip variant-specific hwmod init routines - XXX should be converted
* to use initcalls once the initial boot ordering is straightened out
diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h
deleted file mode 100644
index 9ca420dcd2f8..000000000000
--- a/arch/arm/plat-omap/include/plat/powerdomain.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * OMAP2/3 powerdomain control
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
- *
- * Written by Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN
-#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
-
-#include <linux/types.h>
-#include <linux/list.h>
-
-#include <asm/atomic.h>
-
-#include <plat/cpu.h>
-
-
-/* Powerdomain basic power states */
-#define PWRDM_POWER_OFF 0x0
-#define PWRDM_POWER_RET 0x1
-#define PWRDM_POWER_INACTIVE 0x2
-#define PWRDM_POWER_ON 0x3
-
-#define PWRDM_MAX_PWRSTS 4
-
-/* Powerdomain allowable state bitfields */
-#define PWRSTS_ON (1 << PWRDM_POWER_ON)
-#define PWRSTS_OFF (1 << PWRDM_POWER_OFF)
-#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \
- (1 << PWRDM_POWER_ON))
-
-#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \
- (1 << PWRDM_POWER_RET))
-
-#define PWRSTS_RET_ON ((1 << PWRDM_POWER_RET) | \
- (1 << PWRDM_POWER_ON))
-
-#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
-
-
-/* Powerdomain flags */
-#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
-#define PWRDM_HAS_MPU_QUIRK (1 << 1) /* MPU pwr domain has MEM bank 0 bits
- * in MEM bank 1 position. This is
- * true for OMAP3430
- */
-#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /*
- * support to transition from a
- * sleep state to a lower sleep
- * state without waking up the
- * powerdomain
- */
-
-/*
- * Number of memory banks that are power-controllable. On OMAP4430, the
- * maximum is 5.
- */
-#define PWRDM_MAX_MEM_BANKS 5
-
-/*
- * Maximum number of clockdomains that can be associated with a powerdomain.
- * CORE powerdomain on OMAP4 is the worst case
- */
-#define PWRDM_MAX_CLKDMS 9
-
-/* XXX A completely arbitrary number. What is reasonable here? */
-#define PWRDM_TRANSITION_BAILOUT 100000
-
-struct clockdomain;
-struct powerdomain;
-
-/**
- * struct powerdomain - OMAP powerdomain
- * @name: Powerdomain name
- * @omap_chip: represents the OMAP chip types containing this pwrdm
- * @prcm_offs: the address offset from CM_BASE/PRM_BASE
- * @pwrsts: Possible powerdomain power states
- * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
- * @flags: Powerdomain flags
- * @banks: Number of software-controllable memory banks in this powerdomain
- * @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION
- * @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
- * @pwrdm_clkdms: Clockdomains in this powerdomain
- * @node: list_head linking all powerdomains
- * @state:
- * @state_counter:
- * @timer:
- * @state_timer:
- */
-struct powerdomain {
- const char *name;
- const struct omap_chip_id omap_chip;
- const s16 prcm_offs;
- const u8 pwrsts;
- const u8 pwrsts_logic_ret;
- const u8 flags;
- const u8 banks;
- const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
- const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
- struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
- struct list_head node;
- int state;
- unsigned state_counter[PWRDM_MAX_PWRSTS];
- unsigned ret_logic_off_counter;
- unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
-
-#ifdef CONFIG_PM_DEBUG
- s64 timer;
- s64 state_timer[PWRDM_MAX_PWRSTS];
-#endif
-};
-
-
-void pwrdm_init(struct powerdomain **pwrdm_list);
-
-struct powerdomain *pwrdm_lookup(const char *name);
-
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
- void *user);
-int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
- void *user);
-
-int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
- int (*fn)(struct powerdomain *pwrdm,
- struct clockdomain *clkdm));
-
-int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
-
-int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
-int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
-
-int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-
-int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
-int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
-
-int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
-int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
-bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
-
-int pwrdm_wait_transition(struct powerdomain *pwrdm);
-
-int pwrdm_state_switch(struct powerdomain *pwrdm);
-int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
-int pwrdm_pre_transition(void);
-int pwrdm_post_transition(void);
-int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
-
-#endif
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index ab77442e42ab..2fdf8c80d390 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -18,6 +18,10 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * XXX This file is deprecated. The PRCM is an OMAP2+-only subsystem,
+ * so this file doesn't belong in plat-omap/include/plat. Please
+ * do not add anything new to this file.
*/
#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
@@ -28,22 +32,6 @@ void omap_prcm_arch_reset(char mode, const char *cmd);
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
const char *name);
-#define START_PADCONF_SAVE 0x2
-#define PADCONF_SAVE_DONE 0x1
-
-void omap3_prcm_save_context(void);
-void omap3_prcm_restore_context(void);
-
-u32 prm_read_mod_reg(s16 module, u16 idx);
-void prm_write_mod_reg(u32 val, s16 module, u16 idx);
-u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
-u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
-u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
-u32 cm_read_mod_reg(s16 module, u16 idx);
-void cm_write_mod_reg(u32 val, s16 module, u16 idx);
-u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-
#endif
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 19145f5c32ba..cec5d56db2eb 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -93,9 +93,12 @@
})
#ifndef __ASSEMBLER__
+
+struct omap_board_data;
+
extern void __init omap_serial_early_init(void);
extern void omap_serial_init(void);
-extern void omap_serial_init_port(int port);
+extern void omap_serial_init_port(struct omap_board_data *bdata);
extern int omap_uart_can_sleep(void);
extern void omap_uart_check_wakeup(void);
extern void omap_uart_prepare_suspend(void);
diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h
new file mode 100644
index 000000000000..6568c885f37a
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/smartreflex.h
@@ -0,0 +1,245 @@
+/*
+ * OMAP Smartreflex Defines and Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
+#define __ASM_ARM_OMAP_SMARTREFLEX_H
+
+#include <linux/platform_device.h>
+#include <plat/voltage.h>
+
+/*
+ * Different Smartreflex IPs version. The v1 is the 65nm version used in
+ * OMAP3430. The v2 is the update for the 45nm version of the IP
+ * used in OMAP3630 and OMAP4430
+ */
+#define SR_TYPE_V1 1
+#define SR_TYPE_V2 2
+
+/* SMART REFLEX REG ADDRESS OFFSET */
+#define SRCONFIG 0x00
+#define SRSTATUS 0x04
+#define SENVAL 0x08
+#define SENMIN 0x0C
+#define SENMAX 0x10
+#define SENAVG 0x14
+#define AVGWEIGHT 0x18
+#define NVALUERECIPROCAL 0x1c
+#define SENERROR_V1 0x20
+#define ERRCONFIG_V1 0x24
+#define IRQ_EOI 0x20
+#define IRQSTATUS_RAW 0x24
+#define IRQSTATUS 0x28
+#define IRQENABLE_SET 0x2C
+#define IRQENABLE_CLR 0x30
+#define SENERROR_V2 0x34
+#define ERRCONFIG_V2 0x38
+
+/* Bit/Shift Positions */
+
+/* SRCONFIG */
+#define SRCONFIG_ACCUMDATA_SHIFT 22
+#define SRCONFIG_SRCLKLENGTH_SHIFT 12
+#define SRCONFIG_SENNENABLE_V1_SHIFT 5
+#define SRCONFIG_SENPENABLE_V1_SHIFT 3
+#define SRCONFIG_SENNENABLE_V2_SHIFT 1
+#define SRCONFIG_SENPENABLE_V2_SHIFT 0
+#define SRCONFIG_CLKCTRL_SHIFT 0
+
+#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
+
+#define SRCONFIG_SRENABLE BIT(11)
+#define SRCONFIG_SENENABLE BIT(10)
+#define SRCONFIG_ERRGEN_EN BIT(9)
+#define SRCONFIG_MINMAXAVG_EN BIT(8)
+#define SRCONFIG_DELAYCTRL BIT(2)
+
+/* AVGWEIGHT */
+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
+
+/* NVALUERECIPROCAL */
+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
+
+/* ERRCONFIG */
+#define ERRCONFIG_ERRWEIGHT_SHIFT 16
+#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
+#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
+
+#define SR_ERRWEIGHT_MASK (0x07 << 16)
+#define SR_ERRMAXLIMIT_MASK (0xff << 8)
+#define SR_ERRMINLIMIT_MASK (0xff << 0)
+
+#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
+#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
+#define ERRCONFIG_MCUACCUMINTEN BIT(29)
+#define ERRCONFIG_MCUACCUMINTST BIT(28)
+#define ERRCONFIG_MCUVALIDINTEN BIT(27)
+#define ERRCONFIG_MCUVALIDINTST BIT(26)
+#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
+#define ERRCONFIG_MCUBOUNDINTST BIT(24)
+#define ERRCONFIG_MCUDISACKINTEN BIT(23)
+#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
+#define ERRCONFIG_MCUDISACKINTST BIT(22)
+#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
+
+#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
+ ERRCONFIG_MCUACCUMINTST | \
+ ERRCONFIG_MCUVALIDINTST | \
+ ERRCONFIG_MCUBOUNDINTST | \
+ ERRCONFIG_MCUDISACKINTST)
+/* IRQSTATUS */
+#define IRQSTATUS_MCUACCUMINT BIT(3)
+#define IRQSTATUS_MCVALIDINT BIT(2)
+#define IRQSTATUS_MCBOUNDSINT BIT(1)
+#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
+
+/* IRQENABLE_SET and IRQENABLE_CLEAR */
+#define IRQENABLE_MCUACCUMINT BIT(3)
+#define IRQENABLE_MCUVALIDINT BIT(2)
+#define IRQENABLE_MCUBOUNDSINT BIT(1)
+#define IRQENABLE_MCUDISABLEACKINT BIT(0)
+
+/* Common Bit values */
+
+#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
+#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
+#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
+#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
+#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
+
+/*
+ * 3430 specific values. Maybe these should be passed from board file or
+ * pmic structures.
+ */
+#define OMAP3430_SR_ACCUMDATA 0x1f4
+
+#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
+#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
+
+#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
+#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
+
+#define OMAP3430_SR_ERRWEIGHT 0x04
+#define OMAP3430_SR_ERRMAXLIMIT 0x02
+
+/**
+ * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
+ * pmic specific info to smartreflex driver
+ *
+ * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
+ */
+struct omap_sr_pmic_data {
+ void (*sr_pmic_init) (void);
+};
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+/*
+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
+ * The smartreflex class driver should pass the class type.
+ * Should be used to populate the class_type field of the
+ * omap_smartreflex_class_data structure.
+ */
+#define SR_CLASS1 0x1
+#define SR_CLASS2 0x2
+#define SR_CLASS3 0x3
+
+/**
+ * struct omap_sr_class_data - Smartreflex class driver info
+ *
+ * @enable: API to enable a particular class smaartreflex.
+ * @disable: API to disable a particular class smartreflex.
+ * @configure: API to configure a particular class smartreflex.
+ * @notify: API to notify the class driver about an event in SR.
+ * Not needed for class3.
+ * @notify_flags: specify the events to be notified to the class driver
+ * @class_type: specify which smartreflex class.
+ * Can be used by the SR driver to take any class
+ * based decisions.
+ */
+struct omap_sr_class_data {
+ int (*enable)(struct voltagedomain *voltdm);
+ int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
+ int (*configure)(struct voltagedomain *voltdm);
+ int (*notify)(struct voltagedomain *voltdm, u32 status);
+ u8 notify_flags;
+ u8 class_type;
+};
+
+/**
+ * struct omap_sr_nvalue_table - Smartreflex n-target value info
+ *
+ * @efuse_offs: The offset of the efuse where n-target values are stored.
+ * @nvalue: The n-target value.
+ */
+struct omap_sr_nvalue_table {
+ u32 efuse_offs;
+ u32 nvalue;
+};
+
+/**
+ * struct omap_sr_data - Smartreflex platform data.
+ *
+ * @ip_type: Smartreflex IP type.
+ * @senp_mod: SENPENABLE value for the sr
+ * @senn_mod: SENNENABLE value for sr
+ * @nvalue_count: Number of distinct nvalues in the nvalue table
+ * @enable_on_init: whether this sr module needs to enabled at
+ * boot up or not.
+ * @nvalue_table: table containing the efuse offsets and nvalues
+ * corresponding to them.
+ * @voltdm: Pointer to the voltage domain associated with the SR
+ */
+struct omap_sr_data {
+ int ip_type;
+ u32 senp_mod;
+ u32 senn_mod;
+ int nvalue_count;
+ bool enable_on_init;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+};
+
+/* Smartreflex module enable/disable interface */
+void omap_sr_enable(struct voltagedomain *voltdm);
+void omap_sr_disable(struct voltagedomain *voltdm);
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
+
+/* API to register the pmic specific data with the smartreflex driver. */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
+
+/* Smartreflex driver hooks to be called from Smartreflex class driver */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
+void sr_disable(struct voltagedomain *voltdm);
+int sr_configure_errgen(struct voltagedomain *voltdm);
+int sr_configure_minmax(struct voltagedomain *voltdm);
+
+/* API to register the smartreflex class driver with the smartreflex driver */
+int sr_register_class(struct omap_sr_class_data *class_data);
+#else
+static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable_reset_volt(
+ struct voltagedomain *voltdm) {}
+static inline void omap_sr_register_pmic(
+ struct omap_sr_pmic_data *pmic_data) {}
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 5905100b29a1..9967d5e855c7 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -11,6 +11,7 @@
#ifndef __ARCH_ARM_OMAP_SRAM_H
#define __ARCH_ARM_OMAP_SRAM_H
+#ifndef __ASSEMBLY__
extern void * omap_sram_push(void * start, unsigned long size);
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
@@ -74,4 +75,14 @@ extern void omap_push_sram_idle(void);
static inline void omap_push_sram_idle(void) {}
#endif /* CONFIG_PM */
+#endif /* __ASSEMBLY__ */
+
+/*
+ * OMAP2+: define the SRAM PA addresses.
+ * Used by the SRAM management code and the idle sleep code.
+ */
+#define OMAP2_SRAM_PA 0x40200000
+#define OMAP3_SRAM_PA 0x40200000
+#define OMAP4_SRAM_PA 0x40300000
+
#endif
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index 9036e374e0ac..ad98b85cae21 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -145,8 +145,11 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
/* omap3 based boards using UART3 */
DEBUG_LL_OMAP3(3, cm_t35);
DEBUG_LL_OMAP3(3, cm_t3517);
+ DEBUG_LL_OMAP3(3, craneboard);
+ DEBUG_LL_OMAP3(3, devkit8000);
DEBUG_LL_OMAP3(3, igep0020);
DEBUG_LL_OMAP3(3, igep0030);
+ DEBUG_LL_OMAP3(3, nokia_rm680);
DEBUG_LL_OMAP3(3, nokia_rx51);
DEBUG_LL_OMAP3(3, omap3517evm);
DEBUG_LL_OMAP3(3, omap3_beagle);
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
new file mode 100644
index 000000000000..0ff123399f3b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -0,0 +1,146 @@
+/*
+ * OMAP Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+
+#define VOLTSCALE_VPFORCEUPDATE 1
+#define VOLTSCALE_VCBYPASS 2
+
+/*
+ * OMAP3 GENERIC setup times. Revisit to see if these needs to be
+ * passed from board or PMIC file
+ */
+#define OMAP3_CLKSETUP 0xff
+#define OMAP3_VOLTOFFSET 0xff
+#define OMAP3_VOLTSETUP2 0xff
+
+/* Voltage value defines */
+#define OMAP3430_VDD_MPU_OPP1_UV 975000
+#define OMAP3430_VDD_MPU_OPP2_UV 1075000
+#define OMAP3430_VDD_MPU_OPP3_UV 1200000
+#define OMAP3430_VDD_MPU_OPP4_UV 1270000
+#define OMAP3430_VDD_MPU_OPP5_UV 1350000
+
+#define OMAP3430_VDD_CORE_OPP1_UV 975000
+#define OMAP3430_VDD_CORE_OPP2_UV 1050000
+#define OMAP3430_VDD_CORE_OPP3_UV 1150000
+
+#define OMAP3630_VDD_MPU_OPP50_UV 1012500
+#define OMAP3630_VDD_MPU_OPP100_UV 1200000
+#define OMAP3630_VDD_MPU_OPP120_UV 1325000
+#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
+
+#define OMAP3630_VDD_CORE_OPP50_UV 1000000
+#define OMAP3630_VDD_CORE_OPP100_UV 1200000
+
+#define OMAP4430_VDD_MPU_OPP50_UV 930000
+#define OMAP4430_VDD_MPU_OPP100_UV 1100000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
+
+#define OMAP4430_VDD_IVA_OPP50_UV 930000
+#define OMAP4430_VDD_IVA_OPP100_UV 1100000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
+
+#define OMAP4430_VDD_CORE_OPP50_UV 930000
+#define OMAP4430_VDD_CORE_OPP100_UV 1100000
+
+/**
+ * struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as a unique
+ * identifier.
+ */
+struct voltagedomain {
+ char *name;
+};
+
+/* API to get the voltagedomain pointer */
+struct voltagedomain *omap_voltage_domain_lookup(char *name);
+
+/**
+ * struct omap_volt_data - Omap voltage specific data.
+ * @voltage_nominal: The possible voltage value in uV
+ * @sr_efuse_offs: The offset of the efuse register(from system
+ * control module base address) from where to read
+ * the n-target value for the smartreflex module.
+ * @sr_errminlimit: Error min limit value for smartreflex. This value
+ * differs at differnet opp and thus is linked
+ * with voltage.
+ * @vp_errorgain: Error gain value for the voltage processor. This
+ * field also differs according to the voltage/opp.
+ */
+struct omap_volt_data {
+ u32 volt_nominal;
+ u32 sr_efuse_offs;
+ u8 sr_errminlimit;
+ u8 vp_errgain;
+};
+
+/**
+ * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * @slew_rate: PMIC slew rate (in uv/us)
+ * @step_size: PMIC voltage step size (in uv)
+ * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
+ * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
+ */
+struct omap_volt_pmic_info {
+ int slew_rate;
+ int step_size;
+ u32 on_volt;
+ u32 onlp_volt;
+ u32 ret_volt;
+ u32 off_volt;
+ u16 volt_setup_time;
+ u8 vp_erroroffset;
+ u8 vp_vstepmin;
+ u8 vp_vstepmax;
+ u8 vp_vddmin;
+ u8 vp_vddmax;
+ u8 vp_timeout_us;
+ u8 i2c_slave_addr;
+ u8 pmic_reg;
+ unsigned long (*vsel_to_uv) (const u8 vsel);
+ u8 (*uv_to_vsel) (unsigned long uV);
+};
+
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+void omap_voltage_reset(struct voltagedomain *voltdm);
+void omap_voltage_get_volttable(struct voltagedomain *voltdm,
+ struct omap_volt_data **volt_data);
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt);
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+#ifdef CONFIG_PM
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info);
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method);
+int omap_voltage_late_init(void);
+#else
+static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info) {}
+static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method) {}
+static inline int omap_voltage_late_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
index b0078cf96281..f1295fafcd31 100644
--- a/arch/arm/plat-omap/io.c
+++ b/arch/arm/plat-omap/io.c
@@ -136,61 +136,3 @@ void omap_iounmap(volatile void __iomem *addr)
__iounmap(addr);
}
EXPORT_SYMBOL(omap_iounmap);
-
-/*
- * NOTE: Please use ioremap + __raw_read/write where possible instead of these
- */
-
-u8 omap_readb(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readb(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readb);
-
-u16 omap_readw(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readw(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readw);
-
-u32 omap_readl(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readl(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readl);
-
-void omap_writeb(u8 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writeb(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writeb);
-
-void omap_writew(u16 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writew(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writew);
-
-void omap_writel(u32 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writel(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 6cd151b31bc5..b1107c08da56 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -830,6 +830,28 @@ static int device_match_by_alias(struct device *dev, void *data)
}
/**
+ * iommu_set_da_range - Set a valid device address range
+ * @obj: target iommu
+ * @start Start of valid range
+ * @end End of valid range
+ **/
+int iommu_set_da_range(struct iommu *obj, u32 start, u32 end)
+{
+
+ if (!obj)
+ return -EFAULT;
+
+ if (end < start || !PAGE_ALIGN(start | end))
+ return -EINVAL;
+
+ obj->da_start = start;
+ obj->da_end = end;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_set_da_range);
+
+/**
* iommu_get - Get iommu handler
* @name: target iommu name
**/
@@ -922,6 +944,8 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
obj->name = pdata->name;
obj->dev = &pdev->dev;
obj->ctx = (void *)obj + sizeof(*obj);
+ obj->da_start = pdata->da_start;
+ obj->da_end = pdata->da_end;
mutex_init(&obj->iommu_lock);
mutex_init(&obj->mmap_lock);
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 8ce0de247c71..6dc1296c8c77 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt)
}
#define sgtable_ok(x) (!!sgtable_len(x))
+static unsigned max_alignment(u32 addr)
+{
+ int i;
+ unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
+ for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++)
+ ;
+ return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0;
+}
+
/*
* calculate the optimal number sg elements from total bytes based on
* iommu superpages
*/
-static unsigned int sgtable_nents(size_t bytes)
+static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa)
{
- int i;
- unsigned int nr_entries;
- const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
+ unsigned nr_entries = 0, ent_sz;
if (!IS_ALIGNED(bytes, PAGE_SIZE)) {
pr_err("%s: wrong size %08x\n", __func__, bytes);
return 0;
}
- nr_entries = 0;
- for (i = 0; i < ARRAY_SIZE(pagesize); i++) {
- if (bytes >= pagesize[i]) {
- nr_entries += (bytes / pagesize[i]);
- bytes %= pagesize[i];
- }
+ while (bytes) {
+ ent_sz = max_alignment(da | pa);
+ ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes));
+ nr_entries++;
+ da += ent_sz;
+ pa += ent_sz;
+ bytes -= ent_sz;
}
- BUG_ON(bytes);
return nr_entries;
}
/* allocate and initialize sg_table header(a kind of 'superblock') */
-static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
+static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags,
+ u32 da, u32 pa)
{
unsigned int nr_entries;
int err;
@@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
if (!IS_ALIGNED(bytes, PAGE_SIZE))
return ERR_PTR(-EINVAL);
- /* FIXME: IOVMF_DA_FIXED should support 'superpages' */
- if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) {
- nr_entries = sgtable_nents(bytes);
+ if (flags & IOVMF_LINEAR) {
+ nr_entries = sgtable_nents(bytes, da, pa);
if (!nr_entries)
return ERR_PTR(-EINVAL);
} else
@@ -273,13 +280,14 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
alignement = PAGE_SIZE;
if (flags & IOVMF_DA_ANON) {
- /*
- * Reserve the first page for NULL
- */
- start = PAGE_SIZE;
+ start = obj->da_start;
+
if (flags & IOVMF_LINEAR)
alignement = iopgsz_max(bytes);
start = roundup(start, alignement);
+ } else if (start < obj->da_start || start > obj->da_end ||
+ obj->da_end - start < bytes) {
+ return ERR_PTR(-EINVAL);
}
tmp = NULL;
@@ -289,19 +297,19 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
prev_end = 0;
list_for_each_entry(tmp, &obj->mmap, list) {
- if (prev_end >= start)
+ if (prev_end > start)
break;
- if (start + bytes < tmp->da_start)
+ if (tmp->da_start > start && (tmp->da_start - start) >= bytes)
goto found;
- if (flags & IOVMF_DA_ANON)
+ if (tmp->da_end >= start && flags & IOVMF_DA_ANON)
start = roundup(tmp->da_end + 1, alignement);
prev_end = tmp->da_end;
}
- if ((start > prev_end) && (ULONG_MAX - start >= bytes))
+ if ((start >= prev_end) && (obj->da_end - start >= bytes))
goto found;
dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n",
@@ -409,7 +417,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
BUG_ON(!sgt);
}
-static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
+static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da,
+ size_t len)
{
unsigned int i;
struct scatterlist *sg;
@@ -418,9 +427,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
va = phys_to_virt(pa);
for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes;
+ unsigned bytes;
- bytes = iopgsz_max(len);
+ bytes = max_alignment(da | pa);
+ bytes = min_t(unsigned, bytes, iopgsz_max(len));
BUG_ON(!iopgsz_ok(bytes));
@@ -429,6 +439,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
* 'pa' is cotinuous(linear).
*/
pa += bytes;
+ da += bytes;
len -= bytes;
}
BUG_ON(len);
@@ -695,18 +706,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
if (!va)
return -ENOMEM;
- sgt = sgtable_alloc(bytes, flags);
+ flags &= IOVMF_HW_MASK;
+ flags |= IOVMF_DISCONT;
+ flags |= IOVMF_ALLOC;
+ flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
+
+ sgt = sgtable_alloc(bytes, flags, da, 0);
if (IS_ERR(sgt)) {
da = PTR_ERR(sgt);
goto err_sgt_alloc;
}
sgtable_fill_vmalloc(sgt, va);
- flags &= IOVMF_HW_MASK;
- flags |= IOVMF_DISCONT;
- flags |= IOVMF_ALLOC;
- flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
-
da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
if (IS_ERR_VALUE(da))
goto err_iommu_vmap;
@@ -746,11 +757,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va,
{
struct sg_table *sgt;
- sgt = sgtable_alloc(bytes, flags);
+ sgt = sgtable_alloc(bytes, flags, da, pa);
if (IS_ERR(sgt))
return PTR_ERR(sgt);
- sgtable_fill_kmalloc(sgt, pa, bytes);
+ sgtable_fill_kmalloc(sgt, pa, da, bytes);
da = map_iommu_region(obj, da, sgt, va, bytes, flags);
if (IS_ERR_VALUE(da)) {
@@ -811,7 +822,7 @@ void iommu_kunmap(struct iommu *obj, u32 da)
struct sg_table *sgt;
typedef void (*func_t)(const void *);
- sgt = unmap_vm_area(obj, da, (func_t)__iounmap,
+ sgt = unmap_vm_area(obj, da, (func_t)iounmap,
IOVMF_LINEAR | IOVMF_MMIO);
if (!sgt)
dev_dbg(obj->dev, "%s: No sgt\n", __func__);
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index d2fafb892f7f..459b319a9fad 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -28,12 +28,12 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <linux/err.h>
+#include <linux/notifier.h>
#include <plat/mailbox.h>
static struct workqueue_struct *mboxd;
static struct omap_mbox **mboxes;
-static bool rq_full;
static int mbox_configured;
static DEFINE_MUTEX(mbox_configured_lock);
@@ -93,20 +93,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
struct omap_mbox_queue *mq = mbox->txq;
int ret = 0, len;
- spin_lock(&mq->lock);
+ spin_lock_bh(&mq->lock);
if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
ret = -ENOMEM;
goto out;
}
+ if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
+ mbox_fifo_write(mbox, msg);
+ goto out;
+ }
+
len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));
tasklet_schedule(&mbox->txq->tasklet);
out:
- spin_unlock(&mq->lock);
+ spin_unlock_bh(&mq->lock);
return ret;
}
EXPORT_SYMBOL(omap_mbox_msg_send);
@@ -146,8 +151,14 @@ static void mbox_rx_work(struct work_struct *work)
len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));
- if (mq->callback)
- mq->callback((void *)msg);
+ blocking_notifier_call_chain(&mq->mbox->notifier, len,
+ (void *)msg);
+ spin_lock_irq(&mq->lock);
+ if (mq->full) {
+ mq->full = false;
+ omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+ }
+ spin_unlock_irq(&mq->lock);
}
}
@@ -170,7 +181,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
while (!mbox_fifo_empty(mbox)) {
if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
omap_mbox_disable_irq(mbox, IRQ_RX);
- rq_full = true;
+ mq->full = true;
goto nomem;
}
@@ -239,73 +250,77 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
int ret = 0;
struct omap_mbox_queue *mq;
- if (mbox->ops->startup) {
- mutex_lock(&mbox_configured_lock);
- if (!mbox_configured)
+ mutex_lock(&mbox_configured_lock);
+ if (!mbox_configured++) {
+ if (likely(mbox->ops->startup)) {
ret = mbox->ops->startup(mbox);
-
- if (ret) {
- mutex_unlock(&mbox_configured_lock);
- return ret;
- }
- mbox_configured++;
- mutex_unlock(&mbox_configured_lock);
- }
-
- ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
- mbox->name, mbox);
- if (ret) {
- printk(KERN_ERR
- "failed to register mailbox interrupt:%d\n", ret);
- goto fail_request_irq;
+ if (unlikely(ret))
+ goto fail_startup;
+ } else
+ goto fail_startup;
}
- mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
- if (!mq) {
- ret = -ENOMEM;
- goto fail_alloc_txq;
- }
- mbox->txq = mq;
+ if (!mbox->use_count++) {
+ ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+ mbox->name, mbox);
+ if (unlikely(ret)) {
+ pr_err("failed to register mailbox interrupt:%d\n",
+ ret);
+ goto fail_request_irq;
+ }
+ mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_txq;
+ }
+ mbox->txq = mq;
- mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
- if (!mq) {
- ret = -ENOMEM;
- goto fail_alloc_rxq;
+ mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_rxq;
+ }
+ mbox->rxq = mq;
+ mq->mbox = mbox;
}
- mbox->rxq = mq;
-
+ mutex_unlock(&mbox_configured_lock);
return 0;
- fail_alloc_rxq:
+fail_alloc_rxq:
mbox_queue_free(mbox->txq);
- fail_alloc_txq:
+fail_alloc_txq:
free_irq(mbox->irq, mbox);
- fail_request_irq:
+fail_request_irq:
if (mbox->ops->shutdown)
mbox->ops->shutdown(mbox);
-
+ mbox->use_count--;
+fail_startup:
+ mbox_configured--;
+ mutex_unlock(&mbox_configured_lock);
return ret;
}
static void omap_mbox_fini(struct omap_mbox *mbox)
{
- free_irq(mbox->irq, mbox);
- tasklet_kill(&mbox->txq->tasklet);
- flush_work(&mbox->rxq->work);
- mbox_queue_free(mbox->txq);
- mbox_queue_free(mbox->rxq);
+ mutex_lock(&mbox_configured_lock);
+
+ if (!--mbox->use_count) {
+ free_irq(mbox->irq, mbox);
+ tasklet_kill(&mbox->txq->tasklet);
+ flush_work(&mbox->rxq->work);
+ mbox_queue_free(mbox->txq);
+ mbox_queue_free(mbox->rxq);
+ }
- if (mbox->ops->shutdown) {
- mutex_lock(&mbox_configured_lock);
- if (mbox_configured > 0)
- mbox_configured--;
- if (!mbox_configured)
+ if (likely(mbox->ops->shutdown)) {
+ if (!--mbox_configured)
mbox->ops->shutdown(mbox);
- mutex_unlock(&mbox_configured_lock);
}
+
+ mutex_unlock(&mbox_configured_lock);
}
-struct omap_mbox *omap_mbox_get(const char *name)
+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
{
struct omap_mbox *mbox;
int ret;
@@ -324,12 +339,16 @@ struct omap_mbox *omap_mbox_get(const char *name)
if (ret)
return ERR_PTR(-ENODEV);
+ if (nb)
+ blocking_notifier_chain_register(&mbox->notifier, nb);
+
return mbox;
}
EXPORT_SYMBOL(omap_mbox_get);
-void omap_mbox_put(struct omap_mbox *mbox)
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
{
+ blocking_notifier_chain_unregister(&mbox->notifier, nb);
omap_mbox_fini(mbox);
}
EXPORT_SYMBOL(omap_mbox_put);
@@ -353,6 +372,8 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list)
ret = PTR_ERR(mbox->dev);
goto err_out;
}
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
}
return 0;
@@ -391,7 +412,8 @@ static int __init omap_mbox_init(void)
/* kfifo size sanity check: alignment and minimal size */
mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
- mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t));
+ mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
+ sizeof(mbox_msg_t));
return 0;
}
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index eac4b978e9fd..b5a6e178a7f9 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -28,6 +28,8 @@
#include <plat/dma.h>
#include <plat/mcbsp.h>
+/* XXX These "sideways" includes are a sign that something is wrong */
+#include "../mach-omap2/cm2xxx_3xxx.h"
#include "../mach-omap2/cm-regbits-34xx.h"
struct omap_mcbsp **mcbsp_ptr;
@@ -234,9 +236,9 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
* Sidetone uses McBSP ICLK - which must not idle when sidetones
* are enabled or sidetones start sounding ugly.
*/
- w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
w &= ~(1 << (mcbsp->id - 2));
- cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
/* Enable McBSP Sidetone */
w = MCBSP_READ(mcbsp, SSELCR);
@@ -263,9 +265,9 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
w = MCBSP_READ(mcbsp, SSELCR);
MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
- w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
w |= 1 << (mcbsp->id - 2);
- cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
}
static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
@@ -755,7 +757,7 @@ int omap_mcbsp_request(unsigned int id)
goto err_kfree;
}
- mcbsp->free = 0;
+ mcbsp->free = false;
mcbsp->reg_cache = reg_cache;
spin_unlock(&mcbsp->lock);
@@ -815,7 +817,7 @@ err_clk_disable:
clk_disable(mcbsp->iclk);
spin_lock(&mcbsp->lock);
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->reg_cache = NULL;
err_kfree:
spin_unlock(&mcbsp->lock);
@@ -858,7 +860,7 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->free)
dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
else
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->reg_cache = NULL;
spin_unlock(&mcbsp->lock);
@@ -1771,7 +1773,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
spin_lock_init(&mcbsp->lock);
mcbsp->id = id + 1;
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->dma_tx_lch = -1;
mcbsp->dma_rx_lch = -1;
@@ -1836,17 +1838,11 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
omap34xx_device_exit(mcbsp);
- clk_disable(mcbsp->fclk);
- clk_disable(mcbsp->iclk);
clk_put(mcbsp->fclk);
clk_put(mcbsp->iclk);
iounmap(mcbsp->io_base);
-
- mcbsp->fclk = NULL;
- mcbsp->iclk = NULL;
- mcbsp->free = 0;
- mcbsp->dev = NULL;
+ kfree(mcbsp);
}
return 0;
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index e129ce80c53b..b0471bb2d47d 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -20,15 +20,14 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
/* Interface documentation is in mach/omap-pm.h */
#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
-#include <plat/powerdomain.h>
-
-struct omap_opp *dsp_opps;
-struct omap_opp *mpu_opps;
-struct omap_opp *l3_opps;
+static bool off_mode_enabled;
+static u32 dummy_context_loss_counter;
/*
* Device-driver-originated constraints (via board-*.c files)
@@ -284,37 +283,70 @@ unsigned long omap_pm_cpu_get_freq(void)
return 0;
}
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+ off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+ off_mode_enabled = false;
+}
+
/*
* Device context loss tracking
*/
-int omap_pm_get_dev_context_loss_count(struct device *dev)
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
{
- if (!dev) {
- WARN_ON(1);
- return -EINVAL;
- };
+ struct platform_device *pdev = to_platform_device(dev);
+ u32 count;
+
+ if (WARN_ON(!dev))
+ return 0;
+
+ if (dev->parent == &omap_device_parent) {
+ count = omap_device_get_context_loss_count(pdev);
+ } else {
+ WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
+ dev_name(dev));
+ if (off_mode_enabled)
+ dummy_context_loss_counter++;
+ count = dummy_context_loss_counter;
+ }
- pr_debug("OMAP PM: returning context loss count for dev %s\n",
- dev_name(dev));
+ pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+ dev_name(dev), count);
- /*
- * Map the device to the powerdomain. Return the powerdomain
- * off counter.
- */
+ return count;
+}
- return 0;
+#else
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ return dummy_context_loss_counter;
}
+#endif
/* Should be called before clk framework init */
-int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
- struct omap_opp *dsp_opp_table,
- struct omap_opp *l3_opp_table)
+int __init omap_pm_if_early_init(void)
{
- mpu_opps = mpu_opp_table;
- dsp_opps = dsp_opp_table;
- l3_opps = l3_opp_table;
return 0;
}
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index abe933cd8f09..57adb270767b 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -280,6 +280,34 @@ static void _add_optional_clock_alias(struct omap_device *od,
/* Public functions for use by core code */
/**
+ * omap_device_get_context_loss_count - get lost context count
+ * @od: struct omap_device *
+ *
+ * Using the primary hwmod, query the context loss count for this
+ * device.
+ *
+ * Callers should consider context for this device lost any time this
+ * function returns a value different than the value the caller got
+ * the last time it called this function.
+ *
+ * If any hwmods exist for the omap_device assoiated with @pdev,
+ * return the context loss counter for that hwmod, otherwise return
+ * zero.
+ */
+u32 omap_device_get_context_loss_count(struct platform_device *pdev)
+{
+ struct omap_device *od;
+ u32 ret = 0;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->hwmods_cnt)
+ ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
+
+ return ret;
+}
+
+/**
* omap_device_count_resources - count number of struct resource entries needed
* @od: struct omap_device *
*
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 74dac419d328..e26e50487d60 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -33,23 +33,21 @@
#include "sram.h"
#include "fb.h"
+
+/* XXX These "sideways" includes are a sign that something is wrong */
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-# include "../mach-omap2/prm.h"
-# include "../mach-omap2/cm.h"
+# include "../mach-omap2/prm2xxx_3xxx.h"
# include "../mach-omap2/sdrc.h"
#endif
#define OMAP1_SRAM_PA 0x20000000
#define OMAP1_SRAM_VA VMALLOC_END
-#define OMAP2_SRAM_PA 0x40200000
-#define OMAP2_SRAM_PUB_PA 0x4020f800
+#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
#define OMAP2_SRAM_VA 0xfe400000
#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
-#define OMAP3_SRAM_PA 0x40200000
#define OMAP3_SRAM_VA 0xfe400000
-#define OMAP3_SRAM_PUB_PA 0x40208000
+#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
#define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000)
-#define OMAP4_SRAM_PA 0x40300000
#define OMAP4_SRAM_VA 0xfe400000
#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000)
@@ -270,7 +268,7 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
_omap_sram_reprogram_clock(dpllctl, ckctl);
}
-int __init omap1_sram_init(void)
+static int __init omap1_sram_init(void)
{
_omap_sram_reprogram_clock =
omap_sram_push(omap1_sram_reprogram_clock,