aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap1/mailbox.c3
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/devices.c34
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c70
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h4
-rw-r--r--arch/arm/mach-omap2/mailbox.c3
-rw-r--r--arch/arm/mach-omap2/mux.c49
-rw-r--r--arch/arm/mach-omap2/mux.h20
-rw-r--r--arch/arm/mach-omap2/pm24xx.c2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c2
-rw-r--r--arch/arm/mach-omap2/pm44xx.c23
-rw-r--r--arch/arm/mach-omap2/prcm-debug.c11
-rw-r--r--arch/arm/plat-omap/Makefile3
-rw-r--r--arch/arm/plat-omap/devices.c38
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h6
-rw-r--r--arch/arm/plat-omap/iovmm.c4
-rw-r--r--drivers/gpio/gpio-omap.c192
-rw-r--r--drivers/gpu/ion/ion.c13
-rw-r--r--drivers/gpu/ion/omap/omap_ion.c2
-rw-r--r--drivers/gpu/pvr/deviceclass.c29
-rw-r--r--drivers/gpu/pvr/kerneldisplay.h12
-rw-r--r--drivers/gpu/pvr/module.c1
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c44
-rw-r--r--drivers/gpu/pvr/pvrversion.h6
-rw-r--r--drivers/gpu/pvr/sgx/sgxinfokm.h3
-rw-r--r--drivers/gpu/pvr/sgx/sgxinit.c5
-rw-r--r--drivers/gpu/pvr/sgx/sgxpower.c1
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c2
-rw-r--r--drivers/i2c/busses/i2c-omap.c4
-rw-r--r--drivers/mfd/twl6030-madc.c44
-rw-r--r--drivers/mfd/twl6030-power.c111
-rw-r--r--drivers/misc/omap_temp_sensor.c4
-rw-r--r--drivers/mmc/host/omap_hsmmc.c8
-rw-r--r--drivers/net/wireless/bcm4329/dhd_linux.c3
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_linux.c7
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c51
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h8
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c3
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c45
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c15
-rw-r--r--drivers/usb/musb/omap2430.c3
-rw-r--r--drivers/video/omap2/dss/fifothreshold.c25
-rw-r--r--drivers/video/omap2/dsscomp/queue.c2
-rw-r--r--include/linux/i2c/twl.h8
-rw-r--r--net/ipv4/tcp.c19
-rw-r--r--sound/soc/omap/omap-mcasp.c159
46 files changed, 813 insertions, 289 deletions
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
index c0e1f48aa11..99971bf73b2 100644
--- a/arch/arm/mach-omap1/mailbox.c
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -151,6 +151,9 @@ static int __devinit omap1_mbox_probe(struct platform_device *pdev)
list[0]->irq = platform_get_irq_byname(pdev, "dsp");
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -ENODEV;
+
mbox_base = ioremap(mem->start, resource_size(mem));
if (!mbox_base)
return -ENOMEM;
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index da332d2b4af..450aabf4609 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -41,6 +41,7 @@
/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
#define DPLL_LOW_POWER_STOP 0x1
+#define DPLL_MN_BYPASS 0x4
#define DPLL_LOW_POWER_BYPASS 0x5
#define DPLL_LOCKED 0x7
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 4979efd5396..ef7c65e5f4d 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -491,6 +491,39 @@ static void omap_init_audio(void)
static inline void omap_init_audio(void) {}
#endif
+#if defined(CONFIG_SND_OMAP_SOC_MCASP) || \
+ defined(CONFIG_SND_OMAP_SOC_MCASP_MODULE)
+static struct omap_device_pm_latency omap_mcasp_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void omap_init_mcasp(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ char *oh_name = "omap-mcasp-dai";
+ char *dev_name = "omap-mcasp-dai";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("%s: could not look up %s\n", __func__, oh_name);
+ return;
+ }
+
+ od = omap_device_build(dev_name, -1, oh, NULL, 0,
+ omap_mcasp_latency,
+ ARRAY_SIZE(omap_mcasp_latency), 0);
+ WARN(IS_ERR(od), "could not build omap_device for %s:%s\n",
+ oh_name, dev_name);
+}
+#else
+static inline void omap_init_mcasp(void) {}
+#endif
+
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
#include <plat/mcspi.h>
@@ -911,6 +944,7 @@ static int __init omap2_init_devices(void)
omap_init_audio();
omap_init_camera();
omap_init_mbox();
+ omap_init_mcasp();
omap_init_mcspi();
omap_init_pmu();
omap_hdq_init();
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 73a1595c5f2..7fb0d21b6b1 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -32,8 +32,10 @@
#include <plat/clock.h>
#include "clock.h"
+#include "cm2_44xx.h"
#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
#define DPLL_AUTOIDLE_DISABLE 0x0
@@ -61,22 +63,76 @@ static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
{
const struct dpll_data *dd;
- int i = 0;
+ int i;
int ret = -EINVAL;
+ bool first_time = true;
+ u32 reg;
+ u32 orig_cm_div_m2_dpll_usb;
+ u32 orig_cm_clkdcoldo_dpll_usb;
+retry:
dd = clk->dpll_data;
state <<= __ffs(dd->idlest_mask);
+ i = 0;
while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
i < MAX_DPLL_WAIT_TRIES) {
i++;
udelay(1);
}
+ /* restore back old values if hit work-around */
+ if (!first_time) {
+ __raw_writel(orig_cm_div_m2_dpll_usb,
+ OMAP4430_CM_DIV_M2_DPLL_USB);
+ __raw_writel(orig_cm_clkdcoldo_dpll_usb,
+ OMAP4430_CM_CLKDCOLDO_DPLL_USB);
+ }
+
if (i == MAX_DPLL_WAIT_TRIES) {
printk(KERN_ERR "clock: %s failed transition to '%s'\n",
clk->name, (state) ? "locked" : "bypassed");
+
+ /* Try Error Recovery: for failing usbdpll locking */
+ if (!strcmp(clk->name, "dpll_usb_ck")) {
+
+ reg = __raw_readl(dd->mult_div1_reg);
+
+ /* Put in MN bypass */
+ _omap3_dpll_write_clken(clk, DPLL_MN_BYPASS);
+ i = 0;
+ while (!(__raw_readl(dd->idlest_reg) & (1 << OMAP4430_ST_MN_BYPASS_SHIFT)) &&
+ i < MAX_DPLL_WAIT_TRIES) {
+ i++;
+ udelay(1);
+ }
+
+ /* MN bypass looses contents of CM_CLKSEL_DPLL_USB */
+ __raw_writel(reg, dd->mult_div1_reg);
+
+ /* Force generate request to PRCM: put in Force mode */
+
+ /* a) CM_DIV_M2_DPLL_USB.DPLL_CLKOUT_GATE_CTRL = 1 */
+ orig_cm_div_m2_dpll_usb = __raw_readl(OMAP4430_CM_DIV_M2_DPLL_USB);
+ __raw_writel(orig_cm_div_m2_dpll_usb |
+ (1 << OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT),
+ OMAP4430_CM_DIV_M2_DPLL_USB);
+
+ /* b) CM_CLKDCOLDO_DPLL_USB.DPLL_CLKDCOLDO_GATE_CTRL = 1 */
+ orig_cm_clkdcoldo_dpll_usb = __raw_readl(OMAP4430_CM_CLKDCOLDO_DPLL_USB);
+ __raw_writel(orig_cm_clkdcoldo_dpll_usb |
+ (1 << OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT),
+ OMAP4430_CM_CLKDCOLDO_DPLL_USB);
+
+ /* Put back to locked mode */
+ _omap3_dpll_write_clken(clk, DPLL_LOCKED);
+
+ if (first_time) {
+ first_time = false;
+ goto retry;
+ }
+ }
} else {
pr_debug("clock: %s transition to '%s' in %d loops\n",
clk->name, (state) ? "locked" : "bypassed", i);
@@ -135,11 +191,20 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
*/
static int _omap3_noncore_dpll_lock(struct clk *clk)
{
+ const struct dpll_data *dd;
u8 ai;
- int r;
+ u8 state = 1;
+ int r = 0;
pr_debug("clock: locking DPLL %s\n", clk->name);
+ dd = clk->dpll_data;
+ state <<= __ffs(dd->idlest_mask);
+
+ /* Check if already locked */
+ if ((__raw_readl(dd->idlest_reg) & dd->idlest_mask) == state)
+ goto done;
+
ai = omap3_dpll_autoidle_read(clk);
omap3_dpll_deny_idle(clk);
@@ -151,6 +216,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
if (ai)
omap3_dpll_allow_idle(clk);
+done:
return r;
}
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
index 2f9b0551d03..6cdb5d494c9 100644
--- a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
@@ -1189,6 +1189,10 @@
#define OMAP4_LPDDR21_VREF_EN_CA_MASK (1 << 3)
#define OMAP4_LPDDR21_VREF_EN_DQ_SHIFT 2
#define OMAP4_LPDDR21_VREF_EN_DQ_MASK (1 << 2)
+#define OMAP4_LPDDR21_VREF_AUTO_EN_CA_SHIFT 1
+#define OMAP4_LPDDR21_VREF_AUTO_EN_CA_MASK (1 << 1)
+#define OMAP4_LPDDR21_VREF_AUTO_EN_DQ_SHIFT 0
+#define OMAP4_LPDDR21_VREF_AUTO_EN_DQ_MASK (1 << 0)
/* CONTROL_LPDDR2IO2_0 */
#define OMAP4_LPDDR2IO2_GR4_SR_SHIFT 30
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index d94205d819e..74750bfd9ed 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -397,6 +397,9 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -ENODEV;
+
mbox_base = ioremap(mem->start, resource_size(mem));
if (!mbox_base)
return -ENOMEM;
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 637ce2def14..d2ef973e86b 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -971,7 +971,7 @@ static struct omap_mux *omap_mux_get_by_gpio(
}
/* Needed for dynamic muxing of GPIO pins for off-idle */
-u16 omap_mux_get_gpio(int gpio)
+struct omap_mux *omap_mux_get_gpio(int gpio)
{
struct omap_mux_partition *partition;
struct omap_mux *m = NULL;
@@ -979,13 +979,10 @@ u16 omap_mux_get_gpio(int gpio)
list_for_each_entry(partition, &mux_partitions, node) {
m = omap_mux_get_by_gpio(partition, gpio);
if (m)
- return omap_mux_read(partition, m->reg_offset);
+ return m;
}
- if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
- pr_err("%s: Could not get gpio%i\n", __func__, gpio);
-
- return OMAP_MUX_TERMINATOR;
+ return NULL;
}
/* Needed for dynamic muxing of GPIO pins for off-idle */
@@ -1006,6 +1003,45 @@ void omap_mux_set_gpio(u16 val, int gpio)
pr_err("%s: Could not set gpio%i\n", __func__, gpio);
}
+/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */
+bool omap_mux_get_wakeupenable(struct omap_mux *m)
+{
+ u16 val;
+ if (IS_ERR_OR_NULL(m))
+ return false;
+
+ val = omap_mux_read(m->partition, m->reg_offset);
+ return val & OMAP_PIN_OFF_WAKEUPENABLE;
+}
+
+/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */
+int omap_mux_set_wakeupenable(struct omap_mux *m)
+{
+ u16 val;
+ if (IS_ERR_OR_NULL(m))
+ return -EINVAL;
+
+ val = omap_mux_read(m->partition, m->reg_offset);
+ val |= OMAP_PIN_OFF_WAKEUPENABLE;
+ omap_mux_write(m->partition, val, m->reg_offset);
+
+ return 0;
+}
+
+/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */
+int omap_mux_clear_wakeupenable(struct omap_mux *m)
+{
+ u16 val;
+ if (IS_ERR_OR_NULL(m))
+ return -EINVAL;
+
+ val = omap_mux_read(m->partition, m->reg_offset);
+ val &= ~OMAP_PIN_OFF_WAKEUPENABLE;
+ omap_mux_write(m->partition, val, m->reg_offset);
+
+ return 0;
+}
+
static struct omap_mux * __init omap_mux_list_add(
struct omap_mux_partition *partition,
struct omap_mux *src)
@@ -1019,6 +1055,7 @@ static struct omap_mux * __init omap_mux_list_add(
m = &entry->mux;
entry->mux = *src;
+ m->partition = partition;
#ifdef CONFIG_OMAP_MUX
if (omap_mux_copy_names(src, m)) {
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 3447c374de6..063b158a588 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -131,6 +131,7 @@ struct omap_mux_partition {
struct omap_mux {
u16 reg_offset;
u16 gpio;
+ struct omap_mux_partition *partition;
#ifdef CONFIG_OMAP_MUX
char *muxnames[OMAP_MUX_NR_MODES];
#ifdef CONFIG_DEBUG_FS
@@ -281,11 +282,26 @@ static struct omap_board_mux *board_mux __initdata __maybe_unused;
#endif
/**
- * omap_mux_get_gpio() - get mux register value based on GPIO number
+ * omap_mux_get_gpio() - get mux struct based on GPIO number
* @gpio: GPIO number
*
*/
-u16 omap_mux_get_gpio(int gpio);
+struct omap_mux *omap_mux_get_gpio(int gpio);
+
+/** omap_mux_set_wakeupenable() - set the wakeupenable bit on a mux struct
+ * @m: mux struct
+ */
+int omap_mux_set_wakeupenable(struct omap_mux *m);
+
+/** omap_mux_clear_wakeupenable() - clear the wakeupenable bit on a mux struct
+ * @m: mux struct
+ */
+int omap_mux_clear_wakeupenable(struct omap_mux *m);
+
+/** omap_mux_get_wakeupenable() - get the wakeupenable bit from a mux struct
+ * @m: mux struct
+ */
+bool omap_mux_get_wakeupenable(struct omap_mux *m);
/**
* omap_mux_set_gpio() - set mux register value based on GPIO number
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index fb999bc0eea..faa84634402 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -148,7 +148,7 @@ no_sleep:
tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
omap2_pm_dump(0, 1, tmp);
}
- omap2_gpio_resume_after_idle();
+ omap2_gpio_resume_after_idle(0);
clk_enable(osc_ck);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 321a7e69d7b..535480f5527 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -449,7 +449,7 @@ void omap_sram_idle(void)
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
- omap2_gpio_resume_after_idle();
+ omap2_gpio_resume_after_idle(per_going_off);
}
/* Disable IO-PAD and IO-CHAIN wakeup */
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index aaaebd8194f..42582a8f12c 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -126,6 +126,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
int per_next_state = PWRDM_POWER_ON;
int core_next_state = PWRDM_POWER_ON;
int mpu_next_state = PWRDM_POWER_ON;
+ int ret;
pwrdm_clear_all_prev_pwrst(cpu0_pwrdm);
pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
@@ -138,6 +139,10 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+ ret = omap2_gpio_prepare_for_idle(omap4_device_next_state_off());
+ if (ret)
+ goto abort_gpio;
+
if (mpu_next_state < PWRDM_POWER_INACTIVE) {
if (omap_dvfs_is_scaling(mpu_voltdm)) {
mpu_next_state = PWRDM_POWER_INACTIVE;
@@ -174,10 +179,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
}
}
- omap2_gpio_set_edge_wakeup();
-
if (omap4_device_next_state_off()) {
- omap2_gpio_prepare_for_idle(true);
omap_gpmc_save_context();
omap_dma_global_context_save();
}
@@ -232,26 +234,21 @@ abort_device_off:
}
if (omap4_device_next_state_off()) {
- /*
- * GPIO: since we have put_synced clks, we need to resume
- * even if OFF was not really achieved
- */
- omap2_gpio_resume_after_idle();
-
/* Disable the extension of Non-EMIF I/O isolation */
omap4_prminst_rmw_inst_reg_bits(OMAP4430_ISOOVR_EXTEND_MASK,
0, OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
}
- omap2_gpio_restore_edge_wakeup();
-
if (mpu_next_state < PWRDM_POWER_INACTIVE) {
omap_vc_set_auto_trans(mpu_voltdm,
OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE);
omap_sr_enable(mpu_voltdm);
}
+ omap2_gpio_resume_after_idle(omap4_device_next_state_off());
+
+abort_gpio:
return;
}
@@ -752,13 +749,15 @@ static void __init syscontrol_setup_regs(void)
{
u32 v;
- /* Disable LPDDR VREF manual control */
+ /* Disable LPDDR VREF manual control and enable Auto control */
v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_3);
v &= ~(OMAP4_LPDDR21_VREF_EN_CA_MASK | OMAP4_LPDDR21_VREF_EN_DQ_MASK);
+ v |= OMAP4_LPDDR21_VREF_AUTO_EN_CA_MASK | OMAP4_LPDDR21_VREF_AUTO_EN_DQ_MASK;
omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_3);
v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_3);
v &= ~(OMAP4_LPDDR21_VREF_EN_CA_MASK | OMAP4_LPDDR21_VREF_EN_DQ_MASK);
+ v |= OMAP4_LPDDR21_VREF_AUTO_EN_CA_MASK | OMAP4_LPDDR21_VREF_AUTO_EN_DQ_MASK;
omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_3);
/*
diff --git a/arch/arm/mach-omap2/prcm-debug.c b/arch/arm/mach-omap2/prcm-debug.c
index 12e3e555003..ab638c2e973 100644
--- a/arch/arm/mach-omap2/prcm-debug.c
+++ b/arch/arm/mach-omap2/prcm-debug.c
@@ -1480,6 +1480,8 @@ static void prcmdebug_dump_real_cd(struct seq_file *sf, struct d_clkd_info *cd,
u32 clktrctrl =
omap4_cminst_read_inst_reg(cd->prcm_partition, cd->cm_inst,
cd->clkdm_offs + OMAP4_CM_CLKSTCTRL);
+ u32 mode = (clktrctrl & OMAP4430_CLKTRCTRL_MASK) >>
+ OMAP4430_CLKTRCTRL_SHIFT;
u32 activity = clktrctrl & cd->activity;
#if 0
u32 staticdep =
@@ -1492,9 +1494,10 @@ static void prcmdebug_dump_real_cd(struct seq_file *sf, struct d_clkd_info *cd,
int i;
#endif
- d_pr(sf, " %s mode=%s", cd->name,
- cmtrctrl_s[(clktrctrl & OMAP4430_CLKTRCTRL_MASK) >>
- OMAP4430_CLKTRCTRL_SHIFT]);
+ if (flags & PRCMDEBUG_LASTSLEEP && mode == 3 /* HW_AUTO */)
+ return;
+
+ d_pr(sf, " %s mode=%s", cd->name, cmtrctrl_s[mode]);
d_pr_ctd(sf, " activity=0x%x", activity);
@@ -1525,7 +1528,7 @@ static void prcmdebug_dump_cd(struct seq_file *sf, struct d_clkd_info *cd,
if (cd->cm_inst != -1) {
prcmdebug_dump_real_cd(sf, cd, flags);
- } else {
+ } else if (!(flags & PRCMDEBUG_LASTSLEEP)) {
d_pr(sf, " %s\n", cd->name);
}
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index c3fa01564fe..476d817d1d7 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -15,7 +15,8 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
# omap_device support (OMAP2+ only at the moment)
obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
-obj-$(CONFIG_ARCH_OMAP4) += omap_device.o rproc_user.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
+obj-$(CONFIG_REMOTE_PROC) += rproc_user.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_RPMSG) += omap_rpmsg.o
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 2bf146fbcac..70d8f8d3bc1 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -29,7 +29,6 @@
#include <plat/mmc.h>
#include <mach/gpio.h>
#include <plat/menelaus.h>
-#include <plat/mcasp.h>
#include <plat/mcbsp.h>
#include <plat/remoteproc.h>
#include <plat/omap44xx.h>
@@ -77,43 +76,6 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
{ }
#endif
-
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_SND_OMAP_SOC_MCASP) || \
- defined(CONFIG_SND_OMAP_SOC_MCASP_MODULE)
-
-static struct omap_device_pm_latency omap_mcasp_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
-void omap_init_mcasp(struct omap_mcasp_platform_data *pdata)
-{
- struct omap_hwmod *oh;
- struct omap_device *od;
-
- oh = omap_hwmod_lookup("omap-mcasp-dai");
- if (!oh) {
- printk(KERN_ERR "Could not look up mcasp hw_mod\n");
- return;
- }
-
- od = omap_device_build("omap-mcasp-dai", -1, oh, pdata,
- sizeof(struct omap_mcasp_platform_data),
- omap_mcasp_latency,
- ARRAY_SIZE(omap_mcasp_latency), 0);
-
- if (od <= 0)
- printk(KERN_ERR "Could not build omap_device for omap-mcasp-dai\n");
-}
-#else
-inline void omap_init_mcasp(struct omap_mcasp_platform_data *pdata) {}
-#endif
-
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 89af4ad8a37..0b1f7c539d1 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -213,12 +213,10 @@ struct omap_gpio_platform_data {
struct omap_gpio_reg_offs *regs;
};
-extern void omap2_gpio_prepare_for_idle(int off_mode);
-extern void omap2_gpio_resume_after_idle(void);
+extern int omap2_gpio_prepare_for_idle(int off_mode);
+extern void omap2_gpio_resume_after_idle(int off_mode);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
-extern void omap2_gpio_set_edge_wakeup(void);
-extern void omap2_gpio_restore_edge_wakeup(void);
/*-------------------------------------------------------------------------*/
/* Wrappers for "new style" GPIO calls, using the new infrastructure
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 83a37c54342..6e711b94026 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -163,10 +163,10 @@ static void sgtable_free(struct sg_table *sgt)
if (!sgt)
return;
+ pr_debug("%s: sgt:%p\n", __func__, sgt);
+
sg_free_table(sgt);
kfree(sgt);
-
- pr_debug("%s: sgt:%p\n", __func__, sgt);
}
/* map 'sglist' to a contiguous mpu virtual area and return 'va' */
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index d91a5aa5cc8..5b45bc1d9af 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
+#include <linux/bitops.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -29,6 +30,8 @@
#include <asm/mach/irq.h>
#include <plat/omap-pm.h>
+#include "../mux.h"
+
static LIST_HEAD(omap_gpio_list);
struct gpio_regs {
@@ -46,6 +49,7 @@ struct gpio_regs {
u32 debounce_en;
u32 edge_falling;
u32 edge_rising;
+ u32 pad_set_wakeupenable;
};
struct gpio_bank {
@@ -81,6 +85,8 @@ struct gpio_bank {
void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
struct omap_gpio_reg_offs *regs;
+
+ struct omap_mux *mux[32];
};
static void omap_gpio_mod_init(struct gpio_bank *bank);
@@ -761,6 +767,7 @@ static struct irq_chip gpio_irq_chip = {
.irq_unmask = gpio_unmask_irq,
.irq_set_type = gpio_irq_type,
.irq_set_wake = gpio_wake_enable,
+ .flags = IRQCHIP_MASK_ON_SUSPEND,
};
/*---------------------------------------------------------------------*/
@@ -941,6 +948,8 @@ static struct lock_class_key gpio_lock_class;
static void omap_gpio_mod_init(struct gpio_bank *bank)
{
+ int i;
+
if (bank->width == 32) {
u32 clr_all = 0; /* clear all the bits */
u32 set_all = 0xFFFFFFFF; /* set all the bits */
@@ -1036,6 +1045,11 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
ULPD_CAM_CLK_CTRL);
}
}
+
+ for (i = 0; i < bank->width; i++) {
+ int gpio = irq_to_gpio(bank->virtual_irq_start + i);
+ bank->mux[i] = omap_mux_get_gpio(gpio);
+ }
}
static __init void
@@ -1271,6 +1285,35 @@ static int omap_gpio_resume(struct device *dev)
#ifdef CONFIG_ARCH_OMAP2PLUS
static void omap_gpio_save_context(struct gpio_bank *bank);
static void omap_gpio_restore_context(struct gpio_bank *bank);
+
+static void omap2_gpio_set_wakeupenables(struct gpio_bank *bank)
+{
+ unsigned long pad_wakeup;
+ int i;
+
+ bank->context.pad_set_wakeupenable = 0;
+
+ pad_wakeup = __raw_readl(bank->base + bank->regs->irqenable);
+
+ for_each_set_bit(i, &pad_wakeup, bank->width) {
+ if (!omap_mux_get_wakeupenable(bank->mux[i])) {
+ bank->context.pad_set_wakeupenable |= BIT(i);
+ omap_mux_set_wakeupenable(bank->mux[i]);
+ }
+ }
+}
+
+static void omap2_gpio_clear_wakeupenables(struct gpio_bank *bank)
+{
+ unsigned long pad_wakeup;
+ int i;
+
+ pad_wakeup = bank->context.pad_set_wakeupenable;
+
+ for_each_set_bit(i, &pad_wakeup, bank->width)
+ omap_mux_clear_wakeupenable(bank->mux[i]);
+}
+
#endif
static int omap_gpio_pm_runtime_suspend(struct device *dev)
@@ -1385,100 +1428,125 @@ static int omap_gpio_pm_runtime_resume(struct device *dev)
}
#ifdef CONFIG_ARCH_OMAP2PLUS
-void omap2_gpio_set_edge_wakeup(void)
+static int omap2_gpio_set_edge_wakeup(struct gpio_bank *bank)
{
- struct gpio_bank *bank;
+ int ret = 0;
+ u32 wkup_status = 0;
+ u32 datain;
- list_for_each_entry(bank, &omap_gpio_list, node) {
- u32 level_low = 0;
- u32 level_high = 0;
- u32 wkup_status = 0;
+ if (pm_runtime_get_sync(bank->dev) < 0) {
+ dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync "
+ "failed\n", __func__, bank->id);
+ return -EINVAL;
+ }
- if (pm_runtime_get_sync(bank->dev) < 0) {
- dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync "
- "failed\n", __func__, bank->id);
- return;
- }
+ bank->context.leveldetect0 = __raw_readl(bank->base +
+ bank->regs->leveldetect0);
+ bank->context.leveldetect1 = __raw_readl(bank->base +
+ bank->regs->leveldetect1);
+ wkup_status = __raw_readl(bank->base +
+ bank->regs->wkup_status);
+ bank->context.edge_falling = __raw_readl(bank->base +
+ bank->regs->fallingdetect);
+ bank->context.edge_rising = __raw_readl(bank->base +
+ bank->regs->risingdetect);
- level_low = __raw_readl(bank->base +
- bank->regs->leveldetect0);
- level_high = __raw_readl(bank->base +
- bank->regs->leveldetect1);
- wkup_status = __raw_readl(bank->base +
- bank->regs->wkup_status);
- bank->context.edge_falling = __raw_readl(bank->base +
- bank->regs->fallingdetect);
- bank->context.edge_rising = __raw_readl(bank->base +
- bank->regs->risingdetect);
+ /*
+ * Set edge trigger for all gpio's that are
+ * expected to produce wakeup from low power.
+ * even if they are set for level detection only.
+ */
+ __raw_writel(bank->context.edge_falling |
+ (bank->context.leveldetect0 & wkup_status),
+ (bank->base + bank->regs->fallingdetect));
+ __raw_writel(bank->context.edge_rising |
+ (bank->context.leveldetect1 & wkup_status),
+ (bank->base + bank->regs->risingdetect));
+ __raw_writel(0, bank->base + bank->regs->leveldetect0);
+ __raw_writel(0, bank->base + bank->regs->leveldetect1);
- /*
- * Set edge trigger for all gpio's that are
- * expected to produce wakeup from low power.
- * even if they are set for level detection only.
- */
- __raw_writel(bank->context.edge_falling | (level_low & wkup_status),
- (bank->base + bank->regs->fallingdetect));
- __raw_writel(bank->context.edge_rising | (level_high & wkup_status),
- (bank->base + bank->regs->risingdetect));
-
- if (pm_runtime_put_sync_suspend(bank->dev) < 0) {
- dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync "
- "failed\n", __func__, bank->id);
- return;
- }
+ /*
+ * If a level interrupt is pending it will be lost since
+ * we just cleared it's enable bit. Detect and abort,
+ * the interrupt will be delivered when
+ * omap2_gpio_restore_edge_wakeup restores the level
+ * interrupt mask.
+ */
+ datain = __raw_readl(bank->base + bank->regs->datain);
+ if ((datain & bank->context.leveldetect1) ||
+ (~datain & bank->context.leveldetect0))
+ ret = -EBUSY;
+
+ if (pm_runtime_put_sync_suspend(bank->dev) < 0) {
+ dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync "
+ "failed\n", __func__, bank->id);
+ return -EINVAL;
}
+
+ return ret;
}
-void omap2_gpio_restore_edge_wakeup(void)
+static void omap2_gpio_restore_edge_wakeup(struct gpio_bank *bank)
{
- struct gpio_bank *bank;
-
- list_for_each_entry(bank, &omap_gpio_list, node) {
- /* restore edge setting */
- if (pm_runtime_get_sync(bank->dev) < 0) {
- dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync "
- "failed\n", __func__, bank->id);
- return;
- }
+ if (pm_runtime_get_sync(bank->dev) < 0) {
+ dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync "
+ "failed\n", __func__, bank->id);
+ return;
+ }
- __raw_writel(bank->context.edge_falling,
- (bank->base + bank->regs->fallingdetect));
- __raw_writel(bank->context.edge_rising,
- (bank->base + bank->regs->risingdetect));
+ __raw_writel(bank->context.edge_falling,
+ (bank->base + bank->regs->fallingdetect));
+ __raw_writel(bank->context.edge_rising,
+ (bank->base + bank->regs->risingdetect));
+ __raw_writel(bank->context.leveldetect0,
+ (bank->base + bank->regs->leveldetect0));
+ __raw_writel(bank->context.leveldetect1,
+ (bank->base + bank->regs->leveldetect1));
- if (pm_runtime_put_sync_suspend(bank->dev) < 0) {
- dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync "
- "failed\n", __func__, bank->id);
- return;
- }
+ if (pm_runtime_put_sync_suspend(bank->dev) < 0) {
+ dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync "
+ "failed\n", __func__, bank->id);
+ return;
}
}
-void omap2_gpio_prepare_for_idle(int off_mode)
+int omap2_gpio_prepare_for_idle(int off_mode)
{
+ int ret = 0;
struct gpio_bank *bank;
- if (!off_mode)
- return;
-
list_for_each_entry(bank, &omap_gpio_list, node) {
- if (!bank->mod_usage || !bank->loses_context)
+ omap2_gpio_set_wakeupenables(bank);
+
+ if (!bank->mod_usage || !bank->loses_context || !off_mode) {
+ if (omap2_gpio_set_edge_wakeup(bank))
+ ret = -EBUSY;
continue;
+ }
if (pm_runtime_put_sync_suspend(bank->dev) < 0)
dev_err(bank->dev, "%s: GPIO bank %d "
"pm_runtime_put_sync failed\n",
__func__, bank->id);
}
+
+ if (ret)
+ omap2_gpio_resume_after_idle(off_mode);
+
+ return ret;
}
-void omap2_gpio_resume_after_idle(void)
+void omap2_gpio_resume_after_idle(int off_mode)
{
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
- if (!bank->mod_usage || !bank->loses_context)
+ omap2_gpio_clear_wakeupenables(bank);
+
+ if (!bank->mod_usage || !bank->loses_context || !off_mode) {
+ omap2_gpio_restore_edge_wakeup(bank);
continue;
+ }
if (pm_runtime_get_sync(bank->dev) < 0)
dev_err(bank->dev, "%s: GPIO bank %d "
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 37b23af0550..688e7ed46dc 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -332,6 +332,7 @@ end:
ion_buffer_put(buffer);
return handle;
}
+EXPORT_SYMBOL(ion_alloc);
void ion_free(struct ion_client *client, struct ion_handle *handle)
{
@@ -349,6 +350,7 @@ void ion_free(struct ion_client *client, struct ion_handle *handle)
}
ion_handle_put(handle);
}
+EXPORT_SYMBOL(ion_free);
static void ion_client_get(struct ion_client *client);
static int ion_client_put(struct ion_client *client);
@@ -406,6 +408,7 @@ int ion_phys(struct ion_client *client, struct ion_handle *handle,
ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len);
return ret;
}
+EXPORT_SYMBOL(ion_phys);
void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle)
{
@@ -443,6 +446,7 @@ void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle)
mutex_unlock(&client->lock);
return vaddr;
}
+EXPORT_SYMBOL(ion_map_kernel);
struct scatterlist *ion_map_dma(struct ion_client *client,
struct ion_handle *handle)
@@ -479,6 +483,7 @@ struct scatterlist *ion_map_dma(struct ion_client *client,
mutex_unlock(&client->lock);
return sglist;
}
+EXPORT_SYMBOL(ion_map_dma);
void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle)
{
@@ -494,6 +499,7 @@ void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle)
mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock);
}
+EXPORT_SYMBOL(ion_unmap_kernel);
void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle)
{
@@ -509,7 +515,7 @@ void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle)
mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock);
}
-
+EXPORT_SYMBOL(ion_unmap_dma);
struct ion_buffer *ion_share(struct ion_client *client,
struct ion_handle *handle)
@@ -531,6 +537,7 @@ struct ion_buffer *ion_share(struct ion_client *client,
*/
return handle->buffer;
}
+EXPORT_SYMBOL(ion_share);
struct ion_handle *ion_import(struct ion_client *client,
struct ion_buffer *buffer)
@@ -552,6 +559,7 @@ end:
mutex_unlock(&client->lock);
return handle;
}
+EXPORT_SYMBOL(ion_import);
static const struct file_operations ion_share_fops;
@@ -575,6 +583,7 @@ end:
fput(file);
return handle;
}
+EXPORT_SYMBOL(ion_import_fd);
static int ion_debug_client_show(struct seq_file *s, void *unused)
{
@@ -728,6 +737,7 @@ struct ion_client *ion_client_create(struct ion_device *dev,
return client;
}
+EXPORT_SYMBOL(ion_client_create);
static void _ion_client_destroy(struct kref *kref)
{
@@ -768,6 +778,7 @@ void ion_client_destroy(struct ion_client *client)
{
ion_client_put(client);
}
+EXPORT_SYMBOL(ion_client_destroy);
static int ion_share_release(struct inode *inode, struct file* file)
{
diff --git a/drivers/gpu/ion/omap/omap_ion.c b/drivers/gpu/ion/omap/omap_ion.c
index 00c93de9095..1ae3e536397 100644
--- a/drivers/gpu/ion/omap/omap_ion.c
+++ b/drivers/gpu/ion/omap/omap_ion.c
@@ -24,6 +24,8 @@
#include "omap_ion_priv.h"
struct ion_device *omap_ion_device;
+EXPORT_SYMBOL(omap_ion_device);
+
int num_heaps;
struct ion_heap **heaps;
struct ion_heap *tiler_heap;
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c
index d011bacdd31..f8c83f66073 100644
--- a/drivers/gpu/pvr/deviceclass.c
+++ b/drivers/gpu/pvr/deviceclass.c
@@ -1700,7 +1700,7 @@ PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
psFlipCmd->pvPrivData = pvPrivData;
psFlipCmd->ui32PrivDataLength = ui32PrivDataLength;
- psFlipCmd->ppvMemInfos = ppvMemInfos;
+ psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos;
psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos;
SysAcquireData(&psSysData);
@@ -1988,6 +1988,29 @@ IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
ui32State);
}
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuVAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_CPU_VIRTADDR *pVAddr)
+{
+ *pVAddr = psKernelMemInfo->pvLinAddrKM;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuPAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr)
+{
+ *pPAddr = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uByteOffset);
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetByteSize(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T *uByteSize)
+{
+ *uByteSize = psKernelMemInfo->uAllocSize;
+ return PVRSRV_OK;
+}
IMG_EXPORT
IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
@@ -2008,7 +2031,9 @@ IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
#endif
-
+ psJTable->pfnPVRSRVDCMemInfoGetCpuVAddr = &PVRSRVDCMemInfoGetCpuVAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetCpuPAddr = &PVRSRVDCMemInfoGetCpuPAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetByteSize = &PVRSRVDCMemInfoGetByteSize;
return IMG_TRUE;
}
diff --git a/drivers/gpu/pvr/kerneldisplay.h b/drivers/gpu/pvr/kerneldisplay.h
index 76ee4b8947c..7e9ba51d6df 100644
--- a/drivers/gpu/pvr/kerneldisplay.h
+++ b/drivers/gpu/pvr/kerneldisplay.h
@@ -106,6 +106,12 @@ typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POS
PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
+typedef struct _PVRSRV_KERNEL_MEM_INFO_* PDC_MEM_INFO;
+
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_VADDR)(PDC_MEM_INFO, IMG_CPU_VIRTADDR *pVAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_PADDR)(PDC_MEM_INFO, IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_BYTE_SIZE)(PDC_MEM_INFO, IMG_SIZE_T *uByteSize);
+
typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
{
IMG_UINT32 ui32TableSize;
@@ -118,6 +124,10 @@ typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler;
PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice;
PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket;
+ PFN_DC_MEMINFO_GET_CPU_VADDR pfnPVRSRVDCMemInfoGetCpuVAddr;
+ PFN_DC_MEMINFO_GET_CPU_PADDR pfnPVRSRVDCMemInfoGetCpuPAddr;
+ PFN_DC_MEMINFO_GET_BYTE_SIZE pfnPVRSRVDCMemInfoGetByteSize;
+
} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
@@ -168,7 +178,7 @@ typedef struct DISPLAYCLASS_FLIP_COMMAND2_TAG
IMG_UINT32 ui32PrivDataLength;
- IMG_VOID **ppvMemInfos;
+ PDC_MEM_INFO *ppsMemInfos;
IMG_UINT32 ui32NumMemInfos;
diff --git a/drivers/gpu/pvr/module.c b/drivers/gpu/pvr/module.c
index 0abff8414f0..91d61f2a747 100644
--- a/drivers/gpu/pvr/module.c
+++ b/drivers/gpu/pvr/module.c
@@ -148,6 +148,7 @@ module_param(sgx_apm_latency, uint, 0644);
#include <linux/omap_ion.h>
extern struct ion_device *omap_ion_device;
struct ion_client *gpsIONClient;
+EXPORT_SYMBOL(gpsIONClient);
#endif
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
index 3d0eb29ebca..d16ebbde472 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
@@ -44,6 +44,9 @@ extern struct ion_client *gpsIONClient;
#endif
#if defined(CONFIG_TI_TILER)
#include <mach/tiler.h>
+#include <video/dsscomp.h>
+#include <plat/dsscomp.h>
+
#endif
#define OMAPLFB_COMMAND_COUNT 1
@@ -868,13 +871,11 @@ static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
OMAPLFB_DEVINFO *psDevInfo,
- IMG_VOID **ppvMemInfos,
+ PDC_MEM_INFO *ppsMemInfos,
IMG_UINT32 ui32NumMemInfos,
struct dsscomp_setup_dispc_data *psDssData,
IMG_UINT32 uiDssDataLength)
{
- PVRSRV_KERNEL_MEM_INFO **ppsMemInfos =
- (PVRSRV_KERNEL_MEM_INFO **)ppvMemInfos;
struct tiler_pa_info *apsTilerPAs[5];
IMG_UINT32 i, k;
@@ -894,34 +895,36 @@ static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(apsTilerPAs); i++, k++)
{
struct tiler_pa_info *psTilerInfo;
- LinuxMemArea *psLinuxMemArea;
+ IMG_CPU_VIRTADDR virtAddr;
+ IMG_CPU_PHYADDR phyAddr;
IMG_UINT32 ui32NumPages;
- IMG_UINT32 uiAddr;
+ IMG_SIZE_T uByteSize;
int j;
- psLinuxMemArea = ppsMemInfos[i]->sMemBlk.hOSMemHandle;
- ui32NumPages = (psLinuxMemArea->ui32ByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize);
+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
apsTilerPAs[k] = NULL;
- uiAddr = (IMG_UINT32) LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr;
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr);
+
/* NV12 buffers do not need meminfos */
if(psDssData->ovls[k].cfg.color_mode == OMAP_DSS_COLOR_NV12)
{
/* must have still 2 meminfos in array */
BUG_ON(i + 1 >= ui32NumMemInfos);
- psDssData->ovls[k].ba = uiAddr;
+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr;
i++;
- psLinuxMemArea = ppsMemInfos[i]->sMemBlk.hOSMemHandle;
- psDssData->ovls[k].uv = (u32)LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr;
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr);
+ psDssData->ovls[k].uv = (u32)phyAddr.uiAddr;
continue;
}
/* check if it is a TILER buffer */
- else if(is_tiler_addr(uiAddr))
+ else if(is_tiler_addr((u32)phyAddr.uiAddr))
{
- psDssData->ovls[k].ba = uiAddr;
+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr;
continue;
}
@@ -943,12 +946,13 @@ static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
for(j = 0; j < ui32NumPages; j++)
{
- psTilerInfo->mem[j] =
- (u32)LinuxMemAreaToCpuPAddr(psLinuxMemArea, j << PAGE_SHIFT).uiAddr;
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr);
+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr;
}
/* need base address for in-page offset */
- psDssData->ovls[k].ba = (u32)ppsMemInfos[i]->pvLinAddrKM;
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr);
+ psDssData->ovls[k].ba = (u32)virtAddr;
apsTilerPAs[k] = psTilerInfo;
}
@@ -956,6 +960,12 @@ static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
for(i = k; i < psDssData->num_ovls && i < ARRAY_SIZE(apsTilerPAs); i++)
{
unsigned int ix = psDssData->ovls[i].ba;
+ if(ix >= ARRAY_SIZE(apsTilerPAs))
+ {
+ WARN(1, "Invalid clone layer (%u); skipping all cloned layers", ix);
+ psDssData->num_ovls = k;
+ break;
+ }
apsTilerPAs[i] = apsTilerPAs[ix];
psDssData->ovls[i].ba = psDssData->ovls[ix].ba;
psDssData->ovls[i].uv = psDssData->ovls[ix].uv;
@@ -1011,7 +1021,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData;
return ProcessFlipV2(hCmdCookie,
psDevInfo,
- psFlipCmd2->ppvMemInfos,
+ psFlipCmd2->ppsMemInfos,
psFlipCmd2->ui32NumMemInfos,
psFlipCmd2->pvPrivData,
psFlipCmd2->ui32PrivDataLength);
diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h
index 8f987efa132..c887f583d7d 100644
--- a/drivers/gpu/pvr/pvrversion.h
+++ b/drivers/gpu/pvr/pvrversion.h
@@ -36,7 +36,7 @@
#define PVRVERSION_FAMILY "sgxddk"
#define PVRVERSION_BRANCHNAME "1.8"
-#define PVRVERSION_BUILD 300406
+#define PVRVERSION_BUILD 550175
#define PVRVERSION_BSCONTROL "CustomerGoogle_Android_ogles1_ogles2_GPL"
#define PVRVERSION_STRING "CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@" PVR_STR2(PVRVERSION_BUILD)
@@ -44,8 +44,8 @@
#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
-#define PVRVERSION_BUILD_HI 30
-#define PVRVERSION_BUILD_LO 406
+#define PVRVERSION_BUILD_HI 55
+#define PVRVERSION_BUILD_LO 175
#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
#endif /* _PVRVERSION_H_ */
diff --git a/drivers/gpu/pvr/sgx/sgxinfokm.h b/drivers/gpu/pvr/sgx/sgxinfokm.h
index 2f25a87e67f..7e2b3f9e71a 100644
--- a/drivers/gpu/pvr/sgx/sgxinfokm.h
+++ b/drivers/gpu/pvr/sgx/sgxinfokm.h
@@ -545,6 +545,9 @@ PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle,
IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo);
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs);
+
PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
#if defined(SGX_DYNAMIC_TIMING_INFO)
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c
index b48269b64e3..934f88f3354 100644
--- a/drivers/gpu/pvr/sgx/sgxinit.c
+++ b/drivers/gpu/pvr/sgx/sgxinit.c
@@ -519,6 +519,7 @@ PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
{
PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
#if !defined(FIX_HW_BRN_23281)
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
PVR_DBG_BREAK;
#endif
return PVRSRV_ERROR_RETRY;
@@ -1013,8 +1014,8 @@ static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
}
void dsscomp_kdump(void);
-static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
- IMG_BOOL bDumpSGXRegs)
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs)
{
IMG_UINT32 ui32CoreNum;
diff --git a/drivers/gpu/pvr/sgx/sgxpower.c b/drivers/gpu/pvr/sgx/sgxpower.c
index 3947cddea8b..696941f7a79 100644
--- a/drivers/gpu/pvr/sgx/sgxpower.c
+++ b/drivers/gpu/pvr/sgx/sgxpower.c
@@ -202,6 +202,7 @@ static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo,
IMG_FALSE) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
PVR_DBG_BREAK;
}
#endif
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
index 84cf702f9c6..f362e064820 100644
--- a/drivers/gpu/pvr/sgx/sgxutils.c
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -664,6 +664,7 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
PVR_DBG_BREAK;
return eError;
}
@@ -679,6 +680,7 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
{
PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType));
eError = PVRSRV_ERROR_TIMEOUT;
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
PVR_DBG_BREAK;
}
#endif
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0679c2a218f..6b325c4dafe 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -314,7 +314,7 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
}
dev->idle = 0;
- if (dev->rev >= OMAP_I2C_REV_ON_4430) {
+ if (cpu_is_omap44xx() && dev->rev >= OMAP_I2C_REV_ON_4430) {
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR,0x6FFF);
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_SET, dev->iestate);
} else {
@@ -333,7 +333,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
pdev = to_platform_device(dev->dev);
pdata = pdev->dev.platform_data;
- if (dev->rev >= OMAP_I2C_REV_ON_4430)
+ if (cpu_is_omap44xx() && dev->rev >= OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 0x6FFF);
else
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
diff --git a/drivers/mfd/twl6030-madc.c b/drivers/mfd/twl6030-madc.c
index c7a9e55ad85..f537ba5cbc8 100644
--- a/drivers/mfd/twl6030-madc.c
+++ b/drivers/mfd/twl6030-madc.c
@@ -68,6 +68,7 @@ struct twl6030_madc_data {
};
static struct twl6030_madc_data *twl6030_madc;
+static u8 gpadc_ctrl_reg;
static inline int twl6030_madc_start_conversion(struct twl6030_madc_data *madc)
{
@@ -281,12 +282,55 @@ static int __devexit twl6030_madc_remove(struct platform_device *pdev)
return 0;
}
+static int twl6030_madc_suspend(struct device *pdev)
+{
+ int ret;
+ u8 reg_val;
+
+ ret = twl_i2c_read_u8(TWL_MODULE_MADC, &reg_val, TWL6030_MADC_CTRL);
+ if (!ret) {
+ reg_val &= ~(TWL6030_MADC_TEMP1_EN);
+ ret = twl_i2c_write_u8(TWL_MODULE_MADC, reg_val,
+ TWL6030_MADC_CTRL);
+ }
+
+ if (ret) {
+ dev_err(twl6030_madc->dev, "unable to disable madc temp1!\n");
+ gpadc_ctrl_reg = TWL6030_MADC_TEMP1_EN;
+ } else
+ gpadc_ctrl_reg = reg_val;
+
+ return 0;
+};
+
+static int twl6030_madc_resume(struct device *pdev)
+{
+ int ret;
+
+ if (!(gpadc_ctrl_reg & TWL6030_MADC_TEMP1_EN)) {
+ gpadc_ctrl_reg |= TWL6030_MADC_TEMP1_EN;
+ ret = twl_i2c_write_u8(TWL_MODULE_MADC, gpadc_ctrl_reg,
+ TWL6030_MADC_CTRL);
+ if (ret)
+ dev_err(twl6030_madc->dev,
+ "unable to enable madc temp1!\n");
+ }
+
+ return 0;
+};
+
+static const struct dev_pm_ops twl6030_madc_pm_ops = {
+ .suspend = twl6030_madc_suspend,
+ .resume = twl6030_madc_resume,
+};
+
static struct platform_driver twl6030_madc_driver = {
.probe = twl6030_madc_probe,
.remove = __exit_p(twl6030_madc_remove),
.driver = {
.name = "twl6030_madc",
.owner = THIS_MODULE,
+ .pm = &twl6030_madc_pm_ops,
},
};
diff --git a/drivers/mfd/twl6030-power.c b/drivers/mfd/twl6030-power.c
index 84a8a225f31..2bbea1a37d5 100644
--- a/drivers/mfd/twl6030-power.c
+++ b/drivers/mfd/twl6030-power.c
@@ -18,11 +18,14 @@
#include <linux/pm.h>
#include <linux/i2c/twl.h>
#include <linux/platform_device.h>
+#include <linux/suspend.h>
#include <asm/mach-types.h>
#define VREG_GRP 0
+static u8 dev_on_group;
+
/**
* struct twl6030_resource_map - describe the resource mapping for TWL6030
* @name: name of the resource
@@ -70,11 +73,60 @@ static __initdata struct twl6030_resource_map twl6030_res_map[] = {
/* TEMP cannot be modified */
};
+static struct twl4030_system_config twl6030_sys_config[] = {
+ {.name = "DEV_ON", .group = DEV_GRP_P1,},
+};
+
/* Actual power groups that TWL understands */
#define P3_GRP_6030 BIT(2) /* secondary processor, modem, etc */
#define P2_GRP_6030 BIT(1) /* "peripherals" */
#define P1_GRP_6030 BIT(0) /* CPU/Linux */
+static __init void twl6030_process_system_config(void)
+{
+ u8 grp;
+ int r;
+ bool i = false;
+
+ struct twl4030_system_config *sys_config;
+ sys_config = twl6030_sys_config;
+
+ while (sys_config && sys_config->name) {
+ if (!strcmp(sys_config->name, "DEV_ON")) {
+ dev_on_group = sys_config->group;
+ i = true;
+ break;
+ }
+ sys_config++;
+ }
+ if (!i)
+ pr_err("%s: Couldn't find DEV_ON resource configuration!"
+ " MOD & CON group would be kept active.\n", __func__);
+
+ if (dev_on_group) {
+ r = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &grp,
+ TWL6030_PHOENIX_DEV_ON);
+ if (r) {
+ pr_err("%s: Error(%d) reading {addr=0x%02x}",
+ __func__, r, TWL6030_PHOENIX_DEV_ON);
+ /*
+ * On error resetting to 0, so that all the process
+ * groups are kept active.
+ */
+ dev_on_group = 0;
+ } else {
+ /*
+ * Unmapped processor groups are disabled by writing
+ * 1 to corresponding group in DEV_ON.
+ */
+ grp |= (dev_on_group & DEV_GRP_P1) ? 0 : P1_GRP_6030;
+ grp |= (dev_on_group & DEV_GRP_P2) ? 0 : P2_GRP_6030;
+ grp |= (dev_on_group & DEV_GRP_P3) ? 0 : P3_GRP_6030;
+ dev_on_group = grp;
+ }
+ }
+}
+
static __init void twl6030_program_map(void)
{
struct twl6030_resource_map *res = twl6030_res_map;
@@ -98,6 +150,24 @@ static __init void twl6030_program_map(void)
}
}
+static __init void twl6030_update_system_map
+ (struct twl4030_system_config *sys_list)
+{
+ int i;
+ struct twl4030_system_config *sys_res;
+
+ while (sys_list && sys_list->name) {
+ sys_res = twl6030_sys_config;
+ for (i = 0; i < ARRAY_SIZE(twl6030_sys_config); i++) {
+ if (!strcmp(sys_res->name, sys_list->name))
+ sys_res->group = sys_list->group &
+ (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3);
+ sys_res++;
+ }
+ sys_list++;
+ }
+}
+
static __init void twl6030_update_map(struct twl4030_resconfig *res_list)
{
int i, res_idx = 0;
@@ -124,6 +194,29 @@ static __init void twl6030_update_map(struct twl4030_resconfig *res_list)
}
}
+
+static int twl6030_power_notifier_cb(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ int r = 0;
+
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ r = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, dev_on_group,
+ TWL6030_PHOENIX_DEV_ON);
+ if (r)
+ pr_err("%s: Error(%d) programming {addr=0x%02x}",
+ __func__, r, TWL6030_PHOENIX_DEV_ON);
+ break;
+ }
+
+ return notifier_from_errno(r);
+}
+
+static struct notifier_block twl6030_power_pm_notifier = {
+ .notifier_call = twl6030_power_notifier_cb,
+};
+
/**
* twl6030_power_init() - Update the power map to reflect connectivity of board
* @power_data: power resource map to update (OPTIONAL) - use this if a resource
@@ -131,16 +224,28 @@ static __init void twl6030_update_map(struct twl4030_resconfig *res_list)
*/
void __init twl6030_power_init(struct twl4030_power_data *power_data)
{
- if (power_data && !power_data->resource_config) {
- pr_err("%s: power data from platform without resources!\n",
+ int r;
+
+ if (power_data && (!power_data->resource_config &&
+ !power_data->sys_config)) {
+ pr_err("%s: power data from platform without configuration!\n",
__func__);
return;
}
- if (power_data)
+ if (power_data && power_data->resource_config)
twl6030_update_map(power_data->resource_config);
+ if (power_data && power_data->sys_config)
+ twl6030_update_system_map(power_data->sys_config);
+
+ twl6030_process_system_config();
+
twl6030_program_map();
+ r = register_pm_notifier(&twl6030_power_pm_notifier);
+ if (r)
+ pr_err("%s: twl6030 power registration failed!\n", __func__);
+
return;
}
diff --git a/drivers/misc/omap_temp_sensor.c b/drivers/misc/omap_temp_sensor.c
index 68ac804af4e..6fc4d5522b5 100644
--- a/drivers/misc/omap_temp_sensor.c
+++ b/drivers/misc/omap_temp_sensor.c
@@ -60,8 +60,8 @@ static void throttle_delayed_work_fn(struct work_struct *work);
#define TSHUT_THRESHOLD_TSHUT_HOT 110000 /* 110 deg C */
#define TSHUT_THRESHOLD_TSHUT_COLD 100000 /* 100 deg C */
-#define BGAP_THRESHOLD_T_HOT 83000 /* 83 deg C */
-#define BGAP_THRESHOLD_T_COLD 76000 /* 76 deg C */
+#define BGAP_THRESHOLD_T_HOT 64000 /* 64 deg C */
+#define BGAP_THRESHOLD_T_COLD 61000 /* 61 deg C */
#define OMAP_ADC_START_VALUE 530
#define OMAP_ADC_END_VALUE 923
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8014565e138..e892ec9d40c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2352,8 +2352,9 @@ static int omap_hsmmc_suspend(struct device *dev)
}
}
cancel_work_sync(&host->mmc_carddetect_work);
- if (host->mmc->card && (host->mmc->card->type != MMC_TYPE_SDIO))
- ret = mmc_suspend_host(host->mmc);
+ if (mmc_slot(host).mmc_data.built_in)
+ host->mmc->pm_flags |= MMC_PM_KEEP_POWER;
+ ret = mmc_suspend_host(host->mmc);
mmc_host_enable(host->mmc);
if (ret == 0) {
omap_hsmmc_disable_irq(host);
@@ -2415,8 +2416,7 @@ static int omap_hsmmc_resume(struct device *dev)
omap_hsmmc_protect_card(host);
/* Notify the core to resume the host */
- if (host->mmc->card && (host->mmc->card->type != MMC_TYPE_SDIO))
- ret = mmc_resume_host(host->mmc);
+ ret = mmc_resume_host(host->mmc);
if (ret == 0)
host->suspended = 0;
diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c
index 3ec1f3f108d..5f5b418abc2 100644
--- a/drivers/net/wireless/bcm4329/dhd_linux.c
+++ b/drivers/net/wireless/bcm4329/dhd_linux.c
@@ -1519,7 +1519,8 @@ dhd_dpc_thread(void *data)
dhd_os_wake_unlock(&dhd->pub);
}
} else {
- dhd_bus_stop(dhd->pub.bus, TRUE);
+ if (dhd->pub.up)
+ dhd_bus_stop(dhd->pub.bus, TRUE);
dhd_os_wake_unlock(&dhd->pub);
}
}
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
index a4dc6ff4042..04c43a3225c 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -611,6 +611,13 @@ static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+void *bcmsdh_get_drvdata(void)
+{
+ if (!sdhcinfo)
+ return NULL;
+ return dev_get_drvdata(sdhcinfo->dev);
+}
+
int bcmsdh_register_oob_intr(void * dhdp)
{
int error = 0;
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 8baa60bf24f..726b6391353 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -66,6 +66,9 @@ extern void wl_cfg80211_set_sdio_func(void *func);
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern int dhd_os_check_wakelock(void *dhdp);
+extern int dhd_os_check_if_up(void *dhdp);
+extern void *bcmsdh_get_drvdata(void);
int sdio_function_init(void);
void sdio_function_cleanup(void);
@@ -87,6 +90,8 @@ PBCMSDH_SDMMC_INSTANCE gInstance;
extern int bcmsdh_probe(struct device *dev);
extern int bcmsdh_remove(struct device *dev);
+extern volatile bool dhd_mmc_suspend;
+
static int bcmsdh_sdmmc_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -154,12 +159,56 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
+static int bcmsdh_sdmmc_suspend(struct device *pdev)
+{
+ struct sdio_func *func = dev_to_sdio_func(pdev);
+
+ if (func->num != 2)
+ return 0;
+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
+ return -EBUSY;
+#if defined(OOB_INTR_ONLY)
+ bcmsdh_oob_intr_set(0);
+#endif
+ dhd_mmc_suspend = TRUE;
+ smp_mb();
+
+ return 0;
+}
+
+static int bcmsdh_sdmmc_resume(struct device *pdev)
+{
+ struct sdio_func *func = dev_to_sdio_func(pdev);
+
+ if (func->num != 2)
+ return 0;
+ dhd_mmc_suspend = FALSE;
+#if defined(OOB_INTR_ONLY)
+ if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ bcmsdh_oob_intr_set(1);
+#endif
+ smp_mb();
+ return 0;
+}
+
+static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = {
+ .suspend = bcmsdh_sdmmc_suspend,
+ .resume = bcmsdh_sdmmc_resume,
+};
+#endif
+
static struct sdio_driver bcmsdh_sdmmc_driver = {
.probe = bcmsdh_sdmmc_probe,
.remove = bcmsdh_sdmmc_remove,
.name = "bcmsdh_sdmmc",
.id_table = bcmsdh_sdmmc_ids,
- };
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
+ .drv = {
+ .pm = &bcmsdh_sdmmc_pm_ops,
+ },
+#endif
+};
struct sdos_info {
sdioh_info_t *sd;
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 0ea5d4a9961..c87f6cf37d9 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -235,11 +235,12 @@ typedef struct dhd_cmn {
#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
#define _DHD_PM_RESUME_WAIT(a, b) do {\
int retry = 0; \
- smp_mb(); \
+ SMP_RD_BARRIER_DEPENDS(); \
while (dhd_mmc_suspend && retry++ != b) { \
- wait_event_interruptible_timeout(a, FALSE, HZ/100); \
+ SMP_RD_BARRIER_DEPENDS(); \
+ wait_event_interruptible_timeout(a, !dhd_mmc_suspend, HZ/100); \
} \
- } while (0)
+ } while (0)
#define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200)
#define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0)
#define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0)
@@ -422,6 +423,7 @@ extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
extern int dhd_dev_get_pno_status(struct net_device *dev);
extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd);
+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
#define DHD_UNICAST_FILTER_NUM 0
#define DHD_BROADCAST_FILTER_NUM 1
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index 2222b029f51..a29c2fab28c 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -300,7 +300,8 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le
dhd_os_proto_block(dhd_pub);
ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len);
-
+ if (!ret)
+ dhd_os_check_hang(dhd_pub, ifindex, ret);
dhd_os_proto_unblock(dhd_pub);
return ret;
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 014a40dc6c8..92cdc9b1a4b 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -478,19 +478,21 @@ static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long actio
{
int ret = NOTIFY_DONE;
- switch (action) {
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39))
+ switch (action) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
dhd_mmc_suspend = TRUE;
- ret = NOTIFY_OK;
+ ret = NOTIFY_OK;
break;
case PM_POST_HIBERNATION:
case PM_POST_SUSPEND:
dhd_mmc_suspend = FALSE;
- ret = NOTIFY_OK;
+ ret = NOTIFY_OK;
break;
}
smp_mb();
+#endif
return ret;
}
@@ -1742,7 +1744,8 @@ dhd_dpc_thread(void *data)
DHD_OS_WAKE_UNLOCK(&dhd->pub);
}
} else {
- dhd_bus_stop(dhd->pub.bus, TRUE);
+ if (dhd->pub.up)
+ dhd_bus_stop(dhd->pub.bus, TRUE);
DHD_OS_WAKE_UNLOCK(&dhd->pub);
}
}
@@ -2312,6 +2315,7 @@ dhd_open(struct net_device *net)
#endif
int ifidx;
int32 ret = 0;
+
DHD_OS_WAKE_LOCK(&dhd->pub);
/* Update FW path if it was changed */
if ((firmware_path != NULL) && (firmware_path[0] != '\0')) {
@@ -4510,6 +4514,31 @@ int dhd_os_wake_unlock(dhd_pub_t *pub)
return ret;
}
+int dhd_os_check_wakelock(void *dhdp)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+ dhd_info_t *dhd;
+
+ if (!pub)
+ return 0;
+ dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd && wake_lock_active(&dhd->wl_wifi))
+ return 1;
+#endif
+ return 0;
+}
+
+int dhd_os_check_if_up(void *dhdp)
+{
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+
+ if (!pub)
+ return 0;
+ return pub->up;
+}
+
int net_os_wake_unlock(struct net_device *dev)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
@@ -4546,6 +4575,14 @@ int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd)
return ret;
}
+bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret)
+{
+ struct net_device *net;
+
+ net = dhd_idx2net(dhdp, ifidx);
+ return dhd_check_hang(net, dhdp, ret);
+}
+
#ifdef PROP_TXSTATUS
extern int dhd_wlfc_interface_entry_update(void* state, ewlfc_mac_entry_action_t action, uint8 ifid,
uint8 iftype, uint8* ea);
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 76df647b677..7c6ab2fb282 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -126,6 +126,8 @@ int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
{ return 0; }
#endif
+extern int dhd_os_check_if_up(void *dhdp);
+extern void *bcmsdh_get_drvdata(void);
extern bool ap_fw_loaded;
#ifdef CUSTOMER_HW2
@@ -708,7 +710,7 @@ int wifi_set_power(int on, unsigned long msec)
wifi_control_data->set_power(on);
}
if (msec)
- mdelay(msec);
+ msleep(msec);
return 0;
}
@@ -784,18 +786,19 @@ static int wifi_remove(struct platform_device *pdev)
static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
{
DHD_TRACE(("##> %s\n", __FUNCTION__));
-#if defined(OOB_INTR_ONLY)
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
bcmsdh_oob_intr_set(0);
-#endif /* (OOB_INTR_ONLY) */
+#endif
return 0;
}
static int wifi_resume(struct platform_device *pdev)
{
DHD_TRACE(("##> %s\n", __FUNCTION__));
-#if defined(OOB_INTR_ONLY)
- bcmsdh_oob_intr_set(1);
-#endif /* (OOB_INTR_ONLY) */
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
+ if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ bcmsdh_oob_intr_set(1);
+#endif
return 0;
}
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 5749b72b80c..c82086dc5d7 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -361,7 +361,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
static int omap2430_musb_init(struct musb *musb)
{
- u32 l, status = 0;
+ u32 l;
+ int status = 0;
struct device *dev = musb->controller;
/* We require some kind of external transceiver, hooked
diff --git a/drivers/video/omap2/dss/fifothreshold.c b/drivers/video/omap2/dss/fifothreshold.c
index e82e0e019a2..74359561d5a 100644
--- a/drivers/video/omap2/dss/fifothreshold.c
+++ b/drivers/video/omap2/dss/fifothreshold.c
@@ -358,7 +358,6 @@ static void sa_calc(struct dispc_config *dispc_reg_config, u32 channel_no,
* buffers allocated.
*/
i = Tot_mem / pict_16word_ceil;
- Tot_mem -= pict_16word_ceil * i;
if (i == 0) {
/* LineSize > MemoryLineBufferSize (Valid only for 1D) */
@@ -368,22 +367,26 @@ static void sa_calc(struct dispc_config *dispc_reg_config, u32 channel_no,
* When MemoryLineBufferSize > LineSize >
* (MemoryLineBufferSize/2)
*/
-
- /* HACK: we multiplied pict_16word by 2 as we hit underflow */
- sa_info->min_sa = 2 * pict_16word + C2 * (Tot_mem - 8);
+ sa_info->min_sa = pict_16word + C2 * (Tot_mem -
+ pict_16word_ceil - 8);
} else {
/* All other cases */
- sa_info->min_sa = (4 * (i - 2) + C1) * pict_16word +
- C2 * (Tot_mem - 8);
+ sa_info->min_sa = 4 * pict_16word_ceil;
}
/* C2=0:: no partialy filed lines:: Then minLT = 0 */
- if (C2 == 0)
+ if (C2 == 0) {
sa_info->min_lt = 0;
- else if (bh_config.antifckr == 1 && (C1 == 3 || C1 == 4))
- sa_info->min_lt = (6 - C1) * pict_16word_ceil + C2 * Tot_mem;
- else
- sa_info->min_lt = (C2 - 1) * Tot_mem;
+ } else if (bh_config.antifckr == 1) {
+ if (C1 == 3)
+ sa_info->min_lt = 3 * pict_16word_ceil + C2 * (Tot_mem -
+ (pict_16word_ceil*i));
+ else if (C1 == 4)
+ sa_info->min_lt = 2 * pict_16word_ceil + C2 * (Tot_mem -
+ (pict_16word_ceil*i));
+ } else {
+ sa_info->min_lt = (C2 - 1) * (Tot_mem - (pict_16word_ceil*i));
+ }
sa_info->max_lt = max(sa_info->min_sa - 8, sa_info->min_lt + 1);
}
diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c
index ef778bb2bc8..c25d65596c5 100644
--- a/drivers/video/omap2/dsscomp/queue.c
+++ b/drivers/video/omap2/dsscomp/queue.c
@@ -547,8 +547,6 @@ skip_ovl_set:
if (r && !comp->must_apply) {
dev_err(DEV(cdev), "[%p] set failed %d\n", comp, r);
- /* extra callbacks in case of delayed apply */
- dsscomp_mgr_callback(comp, mgr->id, DSS_COMPLETION_ECLIPSED_SET);
goto done;
} else {
if (r)
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 623c6e0a1c6..1172847d6bb 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -468,6 +468,8 @@ int twl6030_unregister_notifier(struct notifier_block *nb,
#define TWL4030_PM_MASTER_GLOBAL_TST 0xb6
+#define TWL6030_PHOENIX_DEV_ON 0x06
+
/*
* TWL6030 PM Master module register offsets (use TWL_MODULE_PM_MASTER)
*/
@@ -709,10 +711,16 @@ struct twl4030_resconfig {
u8 remap_sleep; /* sleep state remapping */
};
+struct twl4030_system_config {
+ char *name;
+ u8 group;
+};
+
struct twl4030_power_data {
struct twl4030_script **scripts; /* used in TWL4030 only */
unsigned num; /* used in TWL4030 only */
struct twl4030_resconfig *resource_config;
+ struct twl4030_system_config *sys_config; /*system resources*/
#define TWL4030_RESCONFIG_UNDEF ((u8)-1)
};
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5eb7af23461..09ced58e6a5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -273,6 +273,8 @@
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/ip6_route.h>
+#include <net/ipv6.h>
+#include <net/transp_v6.h>
#include <net/netdma.h>
#include <net/sock.h>
@@ -3374,8 +3376,16 @@ restart:
sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) {
struct inet_sock *inet = inet_sk(sk);
+ if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT)
+ continue;
+ if (sock_flag(sk, SOCK_DEAD))
+ continue;
+
if (family == AF_INET) {
__be32 s4 = inet->inet_rcv_saddr;
+ if (s4 == LOOPBACK4_IPV6)
+ continue;
+
if (in->s_addr != s4 &&
!(in->s_addr == INADDR_ANY &&
!tcp_is_local(net, s4)))
@@ -3387,7 +3397,11 @@ restart:
struct in6_addr *s6;
if (!inet->pinet6)
continue;
+
s6 = &inet->pinet6->rcv_saddr;
+ if (ipv6_addr_type(s6) == IPV6_ADDR_MAPPED)
+ continue;
+
if (!ipv6_addr_equal(in6, s6) &&
!(ipv6_addr_equal(in6, &in6addr_any) &&
!tcp_is_local6(net, s6)))
@@ -3395,11 +3409,6 @@ restart:
}
#endif
- if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT)
- continue;
- if (sock_flag(sk, SOCK_DEAD))
- continue;
-
sock_hold(sk);
spin_unlock_bh(lock);
diff --git a/sound/soc/omap/omap-mcasp.c b/sound/soc/omap/omap-mcasp.c
index 2f680c2b162..bf8e1fb0fa4 100644
--- a/sound/soc/omap/omap-mcasp.c
+++ b/sound/soc/omap/omap-mcasp.c
@@ -199,6 +199,21 @@
*/
#define TXDATADMADIS BIT(0)
+#define MCASP_ALLOWED_PPM 100
+
+/*
+ * OMAP_MCASP_DITCSRA_REG/OMAP_MCASP_DITCSRB_REG
+ */
+#define OMAP_MCASP_DITCSR_44100HZ (0x0 << 24)
+#define OMAP_MCASP_DITCSR_48000HZ (0x2 << 24)
+#define OMAP_MCASP_DITCSR_32000HZ (0x3 << 24)
+#define OMAP_MCASP_DITCSR_22050HZ (0x4 << 24)
+#define OMAP_MCASP_DITCSR_24000HZ (0x6 << 24)
+#define OMAP_MCASP_DITCSR_88200HZ (0x8 << 24)
+#define OMAP_MCASP_DITCSR_96000HZ (0xA << 24)
+#define OMAP_MCASP_DITCSR_176400HZ (0xC << 24)
+#define OMAP_MCASP_DITCSR_192000HZ (0xE << 24)
+
/*
* Stream DMA parameters
*/
@@ -279,7 +294,8 @@ static int mcasp_compute_clock_dividers(long fclk_rate, int tgt_sample_rate,
* the transmit clock.
*/
long divisor;
- int i;
+ unsigned long ppm;
+ int sample_rate, i;
BUG_ON(!out_div_lo);
BUG_ON(!out_div_hi);
@@ -291,11 +307,19 @@ static int mcasp_compute_clock_dividers(long fclk_rate, int tgt_sample_rate,
fclk_rate >>= 7;
- /* Next, make sure that our target Fs divides fClk/128 */
- if (fclk_rate % tgt_sample_rate)
+ /* rounded division: fclk_rate / tgt_sample_rate + 0.5 */
+ divisor = (2 * fclk_rate + tgt_sample_rate) / (2 * tgt_sample_rate);
+ if (!divisor)
return -EINVAL;
- divisor = fclk_rate / tgt_sample_rate;
+ sample_rate = fclk_rate / divisor;
+
+ /* ppm calculation in two steps to avoid overflow */
+ ppm = abs(tgt_sample_rate - sample_rate);
+ ppm = (1000000 * ppm) / tgt_sample_rate;
+
+ if (ppm > MCASP_ALLOWED_PPM)
+ return -EINVAL;
/* At this point, divisor holds the product of the two divider values we
* need to use for ACLKXCTL and AHCLKXCTL. ACLKXCTL holds a 5 bit
@@ -319,43 +343,7 @@ static int mcasp_compute_clock_dividers(long fclk_rate, int tgt_sample_rate,
return (*out_div_hi <= 4096) ? 0 : -EINVAL;
}
-static int mcasp_compute_playback_rates(long fclk_rate)
-{
- static const int rate_table[][2] = {
- { 5512, SNDRV_PCM_RATE_5512 },
- { 8000, SNDRV_PCM_RATE_8000 },
- { 11025, SNDRV_PCM_RATE_11025 },
- { 16000, SNDRV_PCM_RATE_16000 },
- { 22050, SNDRV_PCM_RATE_22050 },
- { 32000, SNDRV_PCM_RATE_32000 },
- { 44100, SNDRV_PCM_RATE_44100 },
- { 48000, SNDRV_PCM_RATE_48000 },
- { 64000, SNDRV_PCM_RATE_64000 },
- { 88200, SNDRV_PCM_RATE_88200 },
- { 96000, SNDRV_PCM_RATE_96000 },
- { 176400, SNDRV_PCM_RATE_176400 },
- { 192000, SNDRV_PCM_RATE_192000 },
- };
- int i, res;
-
- if (!fclk_rate)
- return 0;
-
- res = 0;
- for (i = 0; i < ARRAY_SIZE(rate_table); ++i) {
- int lo, hi;
-
- if (!mcasp_compute_clock_dividers(fclk_rate,
- rate_table[i][0],
- &lo,
- &hi))
- res |= rate_table[i][1];
- }
-
- return res;
-}
-
-static int mcasp_start_tx(struct omap_mcasp *mcasp)
+static int omap_mcasp_start(struct omap_mcasp *mcasp)
{
int i;
mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXHCLKRST);
@@ -386,39 +374,22 @@ static int mcasp_start_tx(struct omap_mcasp *mcasp)
return 0;
}
-static int omap_mcasp_start(struct omap_mcasp *mcasp, int stream)
-{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- return mcasp_start_tx(mcasp);
-
- return -EINVAL;
-}
-
-static void mcasp_stop_tx(struct omap_mcasp *mcasp)
+static void omap_mcasp_stop(struct omap_mcasp *mcasp)
{
mcasp_set_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, 0);
mcasp_set_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG,
OMAP_MCASP_TXSTAT_MASK);
}
-static void omap_mcasp_stop(struct omap_mcasp *mcasp, int stream)
-{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- mcasp_stop_tx(mcasp);
-}
-
static int omap_mcasp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct platform_device *pdev;
struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
mcasp_clk_on(mcasp);
- pdev = to_platform_device(mcasp->dev);
-
if (!mcasp->active++)
- pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_get_sync(mcasp->dev);
mcasp_set_reg(mcasp->base + OMAP_MCASP_SYSCONFIG_REG, 0x1);
@@ -428,15 +399,12 @@ static int omap_mcasp_startup(struct snd_pcm_substream *substream,
static void omap_mcasp_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct platform_device *pdev;
struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
- pdev = to_platform_device(mcasp->dev);
-
mcasp_set_reg(mcasp->base + OMAP_MCASP_SYSCONFIG_REG, 0x2);
if (!--mcasp->active)
- pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_put_sync(mcasp->dev);
mcasp_clk_off(mcasp);
}
@@ -444,7 +412,7 @@ static void omap_mcasp_shutdown(struct snd_pcm_substream *substream,
/* S/PDIF */
static int omap_hw_dit_param(struct omap_mcasp *mcasp, unsigned int rate)
{
- u32 aclkxdiv, ahclkxdiv;
+ u32 aclkxdiv, ahclkxdiv, ditcsr;
int res;
/* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
@@ -478,6 +446,41 @@ static int omap_hw_dit_param(struct omap_mcasp *mcasp, unsigned int rate)
return res;
}
+ switch (rate) {
+ case 22050:
+ ditcsr = OMAP_MCASP_DITCSR_22050HZ;
+ break;
+ case 24000:
+ ditcsr = OMAP_MCASP_DITCSR_24000HZ;
+ break;
+ case 32000:
+ ditcsr = OMAP_MCASP_DITCSR_32000HZ;
+ break;
+ case 44100:
+ ditcsr = OMAP_MCASP_DITCSR_44100HZ;
+ break;
+ case 48000:
+ ditcsr = OMAP_MCASP_DITCSR_48000HZ;
+ break;
+ case 88200:
+ ditcsr = OMAP_MCASP_DITCSR_88200HZ;
+ break;
+ case 96000:
+ ditcsr = OMAP_MCASP_DITCSR_96000HZ;
+ break;
+ case 176400:
+ ditcsr = OMAP_MCASP_DITCSR_176400HZ;
+ break;
+ case 192000:
+ ditcsr = OMAP_MCASP_DITCSR_192000HZ;
+ break;
+ default:
+ dev_err(mcasp->dev, "%s: Invalid sampling rate: %d\n",
+ __func__, rate);
+ return -EINVAL;
+ }
+ mcasp_set_reg(mcasp->base + OMAP_MCASP_DITCSRA_REG, ditcsr);
+ mcasp_set_reg(mcasp->base + OMAP_MCASP_DITCSRB_REG, ditcsr);
mcasp_set_bits(mcasp->base + OMAP_MCASP_AHCLKXCTL_REG,
AHCLKXDIV(ahclkxdiv));
mcasp_set_bits(mcasp->base + OMAP_MCASP_ACLKXCTL_REG,
@@ -516,12 +519,7 @@ static int omap_mcasp_hw_params(struct snd_pcm_substream *substream,
struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
int stream = substream->stream;
- mcasp_stop_tx(mcasp);
-
- if ((params_format(params)) != SNDRV_PCM_FORMAT_S16_LE) {
- printk(KERN_WARNING "omap-mcasp: unsupported PCM format");
- return -EINVAL;
- }
+ omap_mcasp_stop(mcasp);
if (omap_hw_dit_param(mcasp, params_rate(params)) < 0)
return -EPERM;
@@ -542,13 +540,13 @@ static int omap_mcasp_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ret = omap_mcasp_start(mcasp, substream->stream);
+ ret = omap_mcasp_start(mcasp);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- omap_mcasp_stop(mcasp, substream->stream);
+ omap_mcasp_stop(mcasp);
break;
default:
@@ -566,6 +564,11 @@ static struct snd_soc_dai_ops omap_mcasp_dai_ops = {
};
+#define MCASP_RATES (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | \
+ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
+
static struct snd_soc_dai_driver omap_mcasp_dai[] = {
{
.name = "omap-mcasp-dai",
@@ -573,6 +576,7 @@ static struct snd_soc_dai_driver omap_mcasp_dai[] = {
.channels_min = 1,
.channels_max = 384,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = MCASP_RATES,
},
.ops = &omap_mcasp_dai_ops,
},
@@ -613,15 +617,6 @@ static __devinit int omap_mcasp_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mcasp);
mcasp->dev = &pdev->dev;
- omap_mcasp_dai[0].playback.rates =
- mcasp_compute_playback_rates(fclk_rate);
- if (!omap_mcasp_dai[0].playback.rates) {
- dev_err(&pdev->dev, "no valid sample rates can be produce from"
- " a %ld Hz fClk\n", fclk_rate);
- ret = -ENODEV;
- goto err;
- }
-
ret = snd_soc_register_dai(&pdev->dev, omap_mcasp_dai);
if (ret < 0)