fiq_buffer[i] = 0;
/*
- * FIQ mode r9 always points to the fiq_buffer, becauses the FIQ isr
+ * FIQ mode r9 always points to the fiq_buffer, because the FIQ isr
* will run in an unpredictable context. The fiq_buffer is the FIQ isr's
* only means of communication with the IRQ level and other kernel
* context code.
#define xip_currtime() (~xip_omap_mpu_timer_read(0))
/*
- * It's permitted to do approxmation for xip_elapsed_since macro
+ * It's permitted to do approximation for xip_elapsed_since macro
* (see linux/mtd/xip.h)
*/
endif
+config OMAP5_ERRATA_801819
+ bool "Errata 801819: An eviction from L1 data cache might stall indefinitely"
+ depends on SOC_OMAP5 || SOC_DRA7XX
+ help
+ A livelock can occur in the L2 cache arbitration that might prevent
+ a snoop from completing. Under certain conditions this can cause the
+ system to deadlock.
+
endmenu
# Common support
obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o timer.o pm.o \
common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
- omap_device.o sram.o drm.o
+ omap_device.o omap-headsmp.o sram.o drm.o
hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
omap_hwmod_common_data.o
# SMP support ONLY available for OMAP4
-smp-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
+smp-$(CONFIG_SMP) += omap-smp.o
smp-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
omap-4-5-common = omap4-common.o omap-wakeupgen.o
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) $(smp-y) sleep44xx.o
#include "gpmc.h"
#include "gpmc-smsc911x.h"
-#include <video/omapdss.h>
+#include <linux/platform_data/omapdss.h>
#include <video/omap-panel-data.h>
#include "board-flash.h"
#include "hsmmc.h"
#include "control.h"
#include "common-board-devices.h"
+#include "display.h"
#define LDP_SMSC911X_CS 1
#define LDP_SMSC911X_GPIO 152
#include <linux/spi/spi.h>
#include <linux/mm.h>
#include <asm/mach-types.h>
-#include <video/omapdss.h>
+#include <linux/platform_data/omapdss.h>
#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include "soc.h"
#include "board-rx51.h"
+#include "display.h"
#include "mux.h"
static struct connector_atv_platform_data rx51_tv_pdata = {
.name = "tv",
.source = "venc.0",
- .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE,
.invert_polarity = false,
};
/*
* As per erratum i671, ROM code does not respect the PER DPLL
* programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
- * Then, in anycase, clear these bits to avoid extra latencies.
+ * Then, in any case, clear these bits to avoid extra latencies.
*/
*ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
~OMAP3430_AUTO_PERIPH_DPLL_MASK;
extern bool gic_dist_disabled(void);
extern void gic_timer_retrigger(void);
extern void omap_smc1(u32 fn, u32 arg);
+extern void omap4_sar_ram_init(void);
extern void __iomem *omap4_get_sar_ram_base(void);
+extern void omap4_mpuss_early_init(void);
extern void omap_do_wfi(void);
-#ifdef CONFIG_SMP
-/* Needed for secondary core boot */
extern void omap4_secondary_startup(void);
extern void omap4460_secondary_startup(void);
+
+#ifdef CONFIG_SMP
+/* Needed for secondary core boot */
extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
extern void omap_auxcoreboot_addr(u32 cpu_addr);
extern u32 omap_read_auxcoreboot0(void);
extern void omap4_cpu_die(unsigned int cpu);
+extern int omap4_cpu_kill(unsigned int cpu);
extern const struct smp_operations omap4_smp_ops;
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
-#include <video/omapdss.h>
+#include <linux/platform_data/omapdss.h>
#include "omap_hwmod.h"
#include "omap_device.h"
#include "omap-pm.h"
struct device_node * __init omapdss_find_dss_of_node(void);
+struct omap_dss_board_info;
+
+/* Init with the board info */
+int omap_display_init(struct omap_dss_board_info *board_data);
+
#endif
#include <linux/gpio.h>
#include <linux/platform_device.h>
-#include <video/omapdss.h>
+#include <linux/platform_data/omapdss.h>
#include <video/omap-panel-data.h>
#include "soc.h"
omap4xxx_check_revision();
omap4xxx_check_features();
omap2_prcm_base_init();
+ omap4_sar_ram_init();
+ omap4_mpuss_early_init();
omap4_pm_init_early();
omap44xx_voltagedomains_init();
omap44xx_powerdomains_init();
omap4_pm_init_early();
omap2_prcm_base_init();
omap5xxx_check_revision();
+ omap4_sar_ram_init();
omap54xx_voltagedomains_init();
omap54xx_powerdomains_init();
omap54xx_clockdomains_init();
#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
-static struct clk *mcbsp_iclks[5];
-
-static int omap3_enable_st_clock(unsigned int id, bool enable)
+static int omap3_mcbsp_force_ick_on(struct clk *clk, bool force_on)
{
- /*
- * Sidetone uses McBSP ICLK - which must not idle when sidetones
- * are enabled or sidetones start sounding ugly.
- */
- if (enable)
- return omap2_clk_deny_idle(mcbsp_iclks[id]);
+ if (!clk)
+ return 0;
+
+ if (force_on)
+ return omap2_clk_deny_idle(clk);
else
- return omap2_clk_allow_idle(mcbsp_iclks[id]);
+ return omap2_clk_allow_idle(clk);
+}
+
+void __init omap3_mcbsp_init_pdata_callback(
+ struct omap_mcbsp_platform_data *pdata)
+{
+ if (!pdata)
+ return;
+
+ pdata->force_ick_on = omap3_mcbsp_force_ick_on;
}
static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
struct omap_hwmod *oh_device[2];
struct omap_mcbsp_platform_data *pdata = NULL;
struct platform_device *pdev;
- char clk_name[11];
sscanf(oh->name, "mcbsp%d", &id);
if (oh->dev_attr) {
oh_device[1] = omap_hwmod_lookup((
(struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
- pdata->enable_st_clock = omap3_enable_st_clock;
- sprintf(clk_name, "mcbsp%d_ick", id);
- mcbsp_iclks[id] = clk_get(NULL, clk_name);
+ pdata->force_ick_on = omap3_mcbsp_force_ick_on;
count++;
}
pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
#endif
/*
- * Signals different on CBB package comapared to superset
+ * Signals different on CBB package compared to superset
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB)
static struct omap_mux __initdata omap3_cbb_subset[] = {
#endif
/*
- * Signals different on 36XX CBP package comapared to 34XX CBC package
+ * Signals different on 36XX CBP package compared to 34XX CBC package
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP)
static struct omap_mux __initdata omap36xx_cbp_subset[] = {
#define AUX_CORE_BOOT0_PA 0x48281800
#define API_HYP_ENTRY 0x102
+ENTRY(omap_secondary_startup)
+#ifdef CONFIG_SMP
+ b secondary_startup
+#else
+/* Should never get here */
+again: wfi
+ b again
+#endif
+#ENDPROC(omap_secondary_startup)
+
/*
* OMAP5 specific entry point for secondary CPU to jump from ROM
* code. This routine also provides a holding flag into which
and r4, r4, #0x0f
cmp r0, r4
bne wait
- b secondary_startup
+ b omap_secondary_startup
ENDPROC(omap5_secondary_startup)
/*
* Same as omap5_secondary_startup except we call into the ROM to
adr r0, hyp_boot
smc #0
hyp_boot:
- b secondary_startup
+ b omap_secondary_startup
ENDPROC(omap5_secondary_hyp_startup)
/*
* OMAP4 specific entry point for secondary CPU to jump from ROM
* we've been released from the wait loop,secondary_stack
* should now contain the SVC stack for this core
*/
- b secondary_startup
+ b omap_secondary_startup
ENDPROC(omap4_secondary_startup)
ENTRY(omap4460_secondary_startup)
* we've been released from the wait loop,secondary_stack
* should now contain the SVC stack for this core
*/
- b secondary_startup
+ b omap_secondary_startup
ENDPROC(omap4460_secondary_startup)
pr_debug("CPU%u: spurious wakeup call\n", cpu);
}
}
+
+/* Needed by kexec and platform_can_cpu_hotplug() */
+int omap4_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
#include "prm44xx.h"
#include "prm-regbits-44xx.h"
+static void __iomem *sar_base;
+
#ifdef CONFIG_SMP
struct omap4_cpu_pm_info {
static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
static struct powerdomain *mpuss_pd;
-static void __iomem *sar_base;
static u32 cpu_context_offset;
static int default_finish_suspend(unsigned long cpu_state)
return -ENODEV;
}
- if (cpu_is_omap44xx())
- sar_base = omap4_get_sar_ram_base();
-
/* Initilaise per CPU PM information */
pm_info = &per_cpu(omap4_pm_info, 0x0);
if (sar_base) {
}
#endif
+
+/*
+ * For kexec, we must set CPU1_WAKEUP_NS_PA_ADDR to point to
+ * current kernel's secondary_startup() early before
+ * clockdomains_init(). Otherwise clockdomain_init() can
+ * wake CPU1 and cause a hang.
+ */
+void __init omap4_mpuss_early_init(void)
+{
+ unsigned long startup_pa;
+
+ if (!cpu_is_omap44xx())
+ return;
+
+ sar_base = omap4_get_sar_ram_base();
+
+ if (cpu_is_omap443x())
+ startup_pa = virt_to_phys(omap4_secondary_startup);
+ else
+ startup_pa = virt_to_phys(omap4460_secondary_startup);
+
+ writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+}
#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109
#define OMAP5_MON_AMBA_IF_INDEX 0x108
+#define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107
/* Secure PPA(Primary Protected Application) APIs */
#define OMAP4_PPA_L2_POR_INDEX 0x23
#define OMAP5_CORE_COUNT 0x2
-/* SCU base address */
-static void __iomem *scu_base;
+struct omap_smp_config {
+ unsigned long cpu1_rstctrl_pa;
+ void __iomem *cpu1_rstctrl_va;
+ void __iomem *scu_base;
+ void *startup_addr;
+};
+
+static struct omap_smp_config cfg;
+
+static const struct omap_smp_config omap443x_cfg __initconst = {
+ .cpu1_rstctrl_pa = 0x4824380c,
+ .startup_addr = omap4_secondary_startup,
+};
+
+static const struct omap_smp_config omap446x_cfg __initconst = {
+ .cpu1_rstctrl_pa = 0x4824380c,
+ .startup_addr = omap4460_secondary_startup,
+};
+
+static const struct omap_smp_config omap5_cfg __initconst = {
+ .cpu1_rstctrl_pa = 0x48243810,
+ .startup_addr = omap5_secondary_startup,
+};
static DEFINE_SPINLOCK(boot_lock);
void __iomem *omap4_get_scu_base(void)
{
- return scu_base;
+ return cfg.scu_base;
}
+#ifdef CONFIG_OMAP5_ERRATA_801819
+void omap5_erratum_workaround_801819(void)
+{
+ u32 acr, revidr;
+ u32 acr_mask;
+
+ /* REVIDR[3] indicates erratum fix available on silicon */
+ asm volatile ("mrc p15, 0, %0, c0, c0, 6" : "=r" (revidr));
+ if (revidr & (0x1 << 3))
+ return;
+
+ asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+ /*
+ * BIT(27) - Disables streaming. All write-allocate lines allocate in
+ * the L1 or L2 cache.
+ * BIT(25) - Disables streaming. All write-allocate lines allocate in
+ * the L1 cache.
+ */
+ acr_mask = (0x3 << 25) | (0x3 << 27);
+ /* do we already have it done.. if yes, skip expensive smc */
+ if ((acr & acr_mask) == acr_mask)
+ return;
+
+ acr |= acr_mask;
+ omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
+
+ pr_debug("%s: ARM erratum workaround 801819 applied on CPU%d\n",
+ __func__, smp_processor_id());
+}
+#else
+static inline void omap5_erratum_workaround_801819(void) { }
+#endif
+
static void omap4_secondary_init(unsigned int cpu)
{
/*
* OMAP443X GP devices- SMP bit isn't accessible.
* OMAP446X GP devices - SMP bit access is enabled on both CPUs.
*/
- if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ if (soc_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
4, 0, 0, 0, 0, 0);
- /*
- * Configure the CNTFRQ register for the secondary cpu's which
- * indicates the frequency of the cpu local timers.
- */
- if (soc_is_omap54xx() || soc_is_dra7xx())
+ if (soc_is_omap54xx() || soc_is_dra7xx()) {
+ /*
+ * Configure the CNTFRQ register for the secondary cpu's which
+ * indicates the frequency of the cpu local timers.
+ */
set_cntfreq();
+ /* Configure ACR to disable streaming WA for 801819 */
+ omap5_erratum_workaround_801819();
+ }
/*
* Synchronise with the boot thread.
* Currently we can't call ioremap here because
* SoC detection won't work until after init_early.
*/
- scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
- BUG_ON(!scu_base);
- ncores = scu_get_core_count(scu_base);
+ cfg.scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
+ BUG_ON(!cfg.scu_base);
+ ncores = scu_get_core_count(cfg.scu_base);
} else if (cpu_id == CPU_CORTEX_A15) {
ncores = OMAP5_CORE_COUNT;
}
static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
{
- void *startup_addr = omap4_secondary_startup;
void __iomem *base = omap_get_wakeupgen_base();
+ const struct omap_smp_config *c = NULL;
+
+ if (soc_is_omap443x())
+ c = &omap443x_cfg;
+ else if (soc_is_omap446x())
+ c = &omap446x_cfg;
+ else if (soc_is_dra74x() || soc_is_omap54xx())
+ c = &omap5_cfg;
+
+ if (!c) {
+ pr_err("%s Unknown SMP SoC?\n", __func__);
+ return;
+ }
+
+ /* Must preserve cfg.scu_base set earlier */
+ cfg.cpu1_rstctrl_pa = c->cpu1_rstctrl_pa;
+ cfg.startup_addr = c->startup_addr;
+
+ if (soc_is_dra74x() || soc_is_omap54xx()) {
+ if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
+ cfg.startup_addr = omap5_secondary_hyp_startup;
+ omap5_erratum_workaround_801819();
+ }
+
+ cfg.cpu1_rstctrl_va = ioremap(cfg.cpu1_rstctrl_pa, 4);
+ if (!cfg.cpu1_rstctrl_va)
+ return;
/*
* Initialise the SCU and wake up the secondary core using
* wakeup_secondary().
*/
- if (scu_base)
- scu_enable(scu_base);
+ if (cfg.scu_base)
+ scu_enable(cfg.scu_base);
- if (cpu_is_omap446x())
- startup_addr = omap4460_secondary_startup;
+ /*
+ * Reset CPU1 before configuring, otherwise kexec will
+ * end up trying to use old kernel startup address.
+ */
+ if (cfg.cpu1_rstctrl_va) {
+ writel_relaxed(1, cfg.cpu1_rstctrl_va);
+ readl_relaxed(cfg.cpu1_rstctrl_va);
+ writel_relaxed(0, cfg.cpu1_rstctrl_va);
+ }
/*
* Write the address of secondary startup routine into the
* A barrier is added to ensure that write buffer is drained
*/
if (omap_secure_apis_support())
- omap_auxcoreboot_addr(virt_to_phys(startup_addr));
+ omap_auxcoreboot_addr(virt_to_phys(cfg.startup_addr));
else
- /*
- * If the boot CPU is in HYP mode then start secondary
- * CPU in HYP mode as well.
- */
- if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
- writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
- base + OMAP_AUX_CORE_BOOT_1);
- else
- writel_relaxed(virt_to_phys(omap5_secondary_startup),
- base + OMAP_AUX_CORE_BOOT_1);
-
+ writel_relaxed(virt_to_phys(cfg.startup_addr),
+ base + OMAP_AUX_CORE_BOOT_1);
}
const struct smp_operations omap4_smp_ops __initconst = {
.smp_boot_secondary = omap4_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = omap4_cpu_die,
+ .cpu_kill = omap4_cpu_kill,
#endif
};
static u32 dram_sync_size;
/*
- * The OMAP4 bus structure contains asynchrnous bridges which can buffer
+ * The OMAP4 bus structure contains asynchronous bridges which can buffer
* data writes from the MPU. These asynchronous bridges can be found on
* paths between the MPU to EMIF, and the MPU to L3 interconnects.
*
}
/*
- * SAR RAM used to save and restore the HW
- * context in low power modes
+ * SAR RAM used to save and restore the HW context in low power modes.
+ * Note that we need to initialize this very early for kexec. See
+ * omap4_mpuss_early_init().
*/
-static int __init omap4_sar_ram_init(void)
+void __init omap4_sar_ram_init(void)
{
unsigned long sar_base;
else if (soc_is_omap54xx())
sar_base = OMAP54XX_SAR_RAM_BASE;
else
- return -ENOMEM;
+ return;
/* Static mapping, never released */
sar_ram_base = ioremap(sar_base, SZ_16K);
if (WARN_ON(!sar_ram_base))
- return -ENOMEM;
-
- return 0;
+ return;
}
-omap_early_initcall(omap4_sar_ram_init);
static const struct of_device_id intc_match[] = {
{ .compatible = "ti,omap4-wugen-mpu", },
* 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,
+ * If any hwmods exist for the omap_device associated with @pdev,
* return the context loss counter for that hwmod, otherwise return
* zero.
*/
extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio;
extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm;
extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0;
-extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0;
-extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0;
-extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0;
extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1;
-extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1;
-extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1;
-extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1;
extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2;
-extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2;
-extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2;
-extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2;
extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc;
extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2;
extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3;
extern struct omap_hwmod am33xx_dcan1_hwmod;
extern struct omap_hwmod am33xx_elm_hwmod;
extern struct omap_hwmod am33xx_epwmss0_hwmod;
-extern struct omap_hwmod am33xx_ecap0_hwmod;
-extern struct omap_hwmod am33xx_eqep0_hwmod;
-extern struct omap_hwmod am33xx_ehrpwm0_hwmod;
extern struct omap_hwmod am33xx_epwmss1_hwmod;
-extern struct omap_hwmod am33xx_ecap1_hwmod;
-extern struct omap_hwmod am33xx_eqep1_hwmod;
-extern struct omap_hwmod am33xx_ehrpwm1_hwmod;
extern struct omap_hwmod am33xx_epwmss2_hwmod;
-extern struct omap_hwmod am33xx_ecap2_hwmod;
-extern struct omap_hwmod am33xx_eqep2_hwmod;
-extern struct omap_hwmod am33xx_ehrpwm2_hwmod;
extern struct omap_hwmod am33xx_gpio1_hwmod;
extern struct omap_hwmod am33xx_gpio2_hwmod;
extern struct omap_hwmod am33xx_gpio3_hwmod;
.user = OCP_USER_MPU,
};
-struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
- .master = &am33xx_epwmss0_hwmod,
- .slave = &am33xx_ecap0_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
- .master = &am33xx_epwmss0_hwmod,
- .slave = &am33xx_eqep0_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
- .master = &am33xx_epwmss0_hwmod,
- .slave = &am33xx_ehrpwm0_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-
static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
{
.pa_start = 0x48302000,
.user = OCP_USER_MPU,
};
-struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
- .master = &am33xx_epwmss1_hwmod,
- .slave = &am33xx_ecap1_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
- .master = &am33xx_epwmss1_hwmod,
- .slave = &am33xx_eqep1_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
- .master = &am33xx_epwmss1_hwmod,
- .slave = &am33xx_ehrpwm1_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
{
.pa_start = 0x48304000,
.user = OCP_USER_MPU,
};
-struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
- .master = &am33xx_epwmss2_hwmod,
- .slave = &am33xx_ecap2_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
- .master = &am33xx_epwmss2_hwmod,
- .slave = &am33xx_eqep2_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
- .master = &am33xx_epwmss2_hwmod,
- .slave = &am33xx_ehrpwm2_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
/* l3s cfg -> gpmc */
struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
.master = &am33xx_l3_s_hwmod,
.sysc = &am33xx_epwmss_sysc,
};
-static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
- .name = "ecap",
-};
-
-static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
- .name = "eqep",
-};
-
-struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
- .name = "ehrpwm",
-};
-
/* epwmss0 */
struct omap_hwmod am33xx_epwmss0_hwmod = {
.name = "epwmss0",
},
};
-/* ecap0 */
-struct omap_hwmod am33xx_ecap0_hwmod = {
- .name = "ecap0",
- .class = &am33xx_ecap_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* eqep0 */
-struct omap_hwmod am33xx_eqep0_hwmod = {
- .name = "eqep0",
- .class = &am33xx_eqep_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* ehrpwm0 */
-struct omap_hwmod am33xx_ehrpwm0_hwmod = {
- .name = "ehrpwm0",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
/* epwmss1 */
struct omap_hwmod am33xx_epwmss1_hwmod = {
.name = "epwmss1",
},
};
-/* ecap1 */
-struct omap_hwmod am33xx_ecap1_hwmod = {
- .name = "ecap1",
- .class = &am33xx_ecap_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* eqep1 */
-struct omap_hwmod am33xx_eqep1_hwmod = {
- .name = "eqep1",
- .class = &am33xx_eqep_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* ehrpwm1 */
-struct omap_hwmod am33xx_ehrpwm1_hwmod = {
- .name = "ehrpwm1",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
/* epwmss2 */
struct omap_hwmod am33xx_epwmss2_hwmod = {
.name = "epwmss2",
},
};
-/* ecap2 */
-struct omap_hwmod am33xx_ecap2_hwmod = {
- .name = "ecap2",
- .class = &am33xx_ecap_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* eqep2 */
-struct omap_hwmod am33xx_eqep2_hwmod = {
- .name = "eqep2",
- .class = &am33xx_eqep_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
-/* ehrpwm2 */
-struct omap_hwmod am33xx_ehrpwm2_hwmod = {
- .name = "ehrpwm2",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
/*
* 'gpio' class: for gpio 0,1,2,3
*/
{
RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET);
RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET);
+ RSTST(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTST_OFFSET);
RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET);
}
&am33xx_l4_ls__spinlock,
&am33xx_l4_ls__elm,
&am33xx_l4_ls__epwmss0,
- &am33xx_epwmss0__ecap0,
- &am33xx_epwmss0__eqep0,
- &am33xx_epwmss0__ehrpwm0,
&am33xx_l4_ls__epwmss1,
- &am33xx_epwmss1__ecap1,
- &am33xx_epwmss1__eqep1,
- &am33xx_epwmss1__ehrpwm1,
&am33xx_l4_ls__epwmss2,
- &am33xx_epwmss2__ecap2,
- &am33xx_epwmss2__eqep2,
- &am33xx_epwmss2__ehrpwm2,
&am33xx_l3_s__gpmc,
&am33xx_l3_main__lcdc,
&am33xx_l4_ls__mcspi0,
.name = "mcbsp2_sidetone",
.class = &omap3xxx_mcbsp_sidetone_hwmod_class,
.mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs,
- .main_clk = "mcbsp2_fck",
- .prcm = {
- .omap2 = {
- .prcm_reg_id = 1,
- .module_bit = OMAP3430_EN_MCBSP2_SHIFT,
- .module_offs = OMAP3430_PER_MOD,
- .idlest_reg_id = 1,
- .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT,
- },
- },
+ .main_clk = "mcbsp2_ick",
+ .flags = HWMOD_NO_IDLEST,
};
/* mcbsp3_sidetone */
.name = "mcbsp3_sidetone",
.class = &omap3xxx_mcbsp_sidetone_hwmod_class,
.mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs,
- .main_clk = "mcbsp3_fck",
- .prcm = {
- .omap2 = {
- .prcm_reg_id = 1,
- .module_bit = OMAP3430_EN_MCBSP3_SHIFT,
- .module_offs = OMAP3430_PER_MOD,
- .idlest_reg_id = 1,
- .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT,
- },
- },
+ .main_clk = "mcbsp3_ick",
+ .flags = HWMOD_NO_IDLEST,
};
/* SR common */
},
};
-static struct omap_hwmod am43xx_ehrpwm3_hwmod = {
- .name = "ehrpwm3",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
static struct omap_hwmod am43xx_epwmss4_hwmod = {
.name = "epwmss4",
.class = &am33xx_epwmss_hwmod_class,
},
};
-static struct omap_hwmod am43xx_ehrpwm4_hwmod = {
- .name = "ehrpwm4",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
static struct omap_hwmod am43xx_epwmss5_hwmod = {
.name = "epwmss5",
.class = &am33xx_epwmss_hwmod_class,
},
};
-static struct omap_hwmod am43xx_ehrpwm5_hwmod = {
- .name = "ehrpwm5",
- .class = &am33xx_ehrpwm_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .main_clk = "l4ls_gclk",
-};
-
static struct omap_hwmod am43xx_spi2_hwmod = {
.name = "spi2",
.class = &am33xx_spi_hwmod_class,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = {
- .master = &am43xx_epwmss3_hwmod,
- .slave = &am43xx_ehrpwm3_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = {
.master = &am33xx_l4_ls_hwmod,
.slave = &am43xx_epwmss4_hwmod,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = {
- .master = &am43xx_epwmss4_hwmod,
- .slave = &am43xx_ehrpwm4_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = {
.master = &am33xx_l4_ls_hwmod,
.slave = &am43xx_epwmss5_hwmod,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = {
- .master = &am43xx_epwmss5_hwmod,
- .slave = &am43xx_ehrpwm5_hwmod,
- .clk = "l4ls_gclk",
- .user = OCP_USER_MPU,
-};
-
static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = {
.master = &am33xx_l4_ls_hwmod,
.slave = &am43xx_spi2_hwmod,
&am43xx_l4_ls__timer10,
&am43xx_l4_ls__timer11,
&am43xx_l4_ls__epwmss3,
- &am43xx_epwmss3__ehrpwm3,
&am43xx_l4_ls__epwmss4,
- &am43xx_epwmss4__ehrpwm4,
&am43xx_l4_ls__epwmss5,
- &am43xx_epwmss5__ehrpwm5,
&am43xx_l4_ls__mcspi2,
&am43xx_l4_ls__mcspi3,
&am43xx_l4_ls__mcspi4,
&am33xx_l4_ls__spinlock,
&am33xx_l4_ls__elm,
&am33xx_l4_ls__epwmss0,
- &am33xx_epwmss0__ecap0,
- &am33xx_epwmss0__eqep0,
- &am33xx_epwmss0__ehrpwm0,
&am33xx_l4_ls__epwmss1,
- &am33xx_epwmss1__ecap1,
- &am33xx_epwmss1__eqep1,
- &am33xx_epwmss1__ehrpwm1,
&am33xx_l4_ls__epwmss2,
- &am33xx_epwmss2__ecap2,
- &am33xx_epwmss2__eqep2,
- &am33xx_epwmss2__ehrpwm2,
&am33xx_l3_s__gpmc,
&am33xx_l4_ls__mcspi0,
&am33xx_l4_ls__mcspi1,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = {
- {
- .name = "family",
- .pa_start = 0x58000000,
- .pa_end = 0x5800007f,
- .flags = ADDR_TYPE_RT
- },
-};
-
/* l3_main_1 -> dss */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dss = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_dss_hwmod,
.clk = "l3_iclk_div",
- .addr = dra7xx_dss_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space dra7xx_dss_dispc_addrs[] = {
- {
- .name = "dispc",
- .pa_start = 0x58001000,
- .pa_end = 0x58001fff,
- .flags = ADDR_TYPE_RT
- },
-};
-
/* l3_main_1 -> dispc */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dispc = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_dss_dispc_hwmod,
.clk = "l3_iclk_div",
- .addr = dra7xx_dss_dispc_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space dra7xx_dss_hdmi_addrs[] = {
- {
- .name = "hdmi_wp",
- .pa_start = 0x58040000,
- .pa_end = 0x580400ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
/* l3_main_1 -> dispc */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_dss_hdmi_hwmod,
.clk = "l3_iclk_div",
- .addr = dra7xx_dss_hdmi_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space dra7xx_qspi_addrs[] = {
- {
- .pa_start = 0x4b300000,
- .pa_end = 0x4b30007f,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
/* l3_main_1 -> qspi */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__qspi = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_qspi_hwmod,
.clk = "l3_iclk_div",
- .addr = dra7xx_qspi_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
.sysc = &ti81xx_rtc_sysc,
};
-struct omap_hwmod ti81xx_rtc_hwmod = {
+static struct omap_hwmod ti81xx_rtc_hwmod = {
.name = "rtc",
.class = &ti81xx_rtc_hwmod_class,
.clkdm_name = "alwon_l3s_clkdm",
#include <linux/platform_data/wkup_m3.h>
#include <linux/platform_data/pwm_omap_dmtimer.h>
#include <linux/platform_data/media/ir-rx51.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
#include <plat/dmtimer.h>
#include "common.h"
},
};
+#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP)
+static struct omap_mcbsp_platform_data mcbsp_pdata;
+static void __init omap3_mcbsp_init(void)
+{
+ omap3_mcbsp_init_pdata_callback(&mcbsp_pdata);
+}
+#else
+static void __init omap3_mcbsp_init(void) {}
+#endif
+
/*
* Few boards still need auxdata populated before we populate
* the dev entries in of_platform_populate().
OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
&am35xx_emac_pdata),
+ /* McBSP modules with sidetone core */
+#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP)
+ OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49022000, "49022000.mcbsp", &mcbsp_pdata),
+ OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49024000, "49024000.mcbsp", &mcbsp_pdata),
+#endif
#endif
#ifdef CONFIG_SOC_AM33XX
OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
of_machine_is_compatible("ti,omap3"))
omap_sdrc_init(NULL, NULL);
+ if (of_machine_is_compatible("ti,omap3"))
+ omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks);
of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL);
/* RM RSTST offsets */
#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014
+#define AM43XX_RM_PER_RSTST_OFFSET 0x0014
#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014
/* CM instances */
/* PRM.PER_PRM register offsets */
#define AM33XX_RM_PER_RSTCTRL_OFFSET 0x0000
#define AM33XX_RM_PER_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0000)
-#define AM33XX_RM_PER_RSTST_OFFSET 0x0004
-#define AM33XX_RM_PER_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0004)
#define AM33XX_PM_PER_PWRSTST_OFFSET 0x0008
#define AM33XX_PM_PER_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0008)
#define AM33XX_PM_PER_PWRSTCTRL_OFFSET 0x000c
* don't adjust it down as your clock period increases the refresh interval
* will not be met. Setting all parameters for complete worst case may work,
* but may cut memory performance by 2x. Due to errata the DLLs need to be
- * unlocked and their value needs run time calibration. A dynamic call is
- * need for that as no single right value exists acorss production samples.
+ * unlocked and their value needs run time calibration. A dynamic call is
+ * need for that as no single right value exists across production samples.
*
* Only the FULL speed values are given. Current code is such that rate
* changes must be made at DPLLoutx2. The actual value adjustment for low
DT_CLK("48300200.ehrpwm", "tbclk", "ehrpwm0_tbclk"),
DT_CLK("48302200.ehrpwm", "tbclk", "ehrpwm1_tbclk"),
DT_CLK("48304200.ehrpwm", "tbclk", "ehrpwm2_tbclk"),
+ DT_CLK("48300200.pwm", "tbclk", "ehrpwm0_tbclk"),
+ DT_CLK("48302200.pwm", "tbclk", "ehrpwm1_tbclk"),
+ DT_CLK("48304200.pwm", "tbclk", "ehrpwm2_tbclk"),
{ .node_name = NULL },
};
DT_CLK("48306200.ehrpwm", "tbclk", "ehrpwm3_tbclk"),
DT_CLK("48308200.ehrpwm", "tbclk", "ehrpwm4_tbclk"),
DT_CLK("4830a200.ehrpwm", "tbclk", "ehrpwm5_tbclk"),
+ DT_CLK("48300200.pwm", "tbclk", "ehrpwm0_tbclk"),
+ DT_CLK("48302200.pwm", "tbclk", "ehrpwm1_tbclk"),
+ DT_CLK("48304200.pwm", "tbclk", "ehrpwm2_tbclk"),
+ DT_CLK("48306200.pwm", "tbclk", "ehrpwm3_tbclk"),
+ DT_CLK("48308200.pwm", "tbclk", "ehrpwm4_tbclk"),
+ DT_CLK("4830a200.pwm", "tbclk", "ehrpwm5_tbclk"),
{ .node_name = NULL },
};
/* McBSP platform and instance specific features */
bool has_wakeup; /* Wakeup capability */
bool has_ccr; /* Transceiver has configuration control registers */
- int (*enable_st_clock)(unsigned int, bool);
+ int (*force_ick_on)(struct clk *clk, bool force_on);
};
/**
const char *sidetone;
};
+void omap3_mcbsp_init_pdata_callback(struct omap_mcbsp_platform_data *pdata);
+
#endif
--- /dev/null
+/*
+ * Copyright (C) 2016 Texas Instruments, Inc.
+ *
+ * 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 __OMAPDSS_PDATA_H
+#define __OMAPDSS_PDATA_H
+
+enum omapdss_version {
+ OMAPDSS_VER_UNKNOWN = 0,
+ OMAPDSS_VER_OMAP24xx,
+ OMAPDSS_VER_OMAP34xx_ES1, /* OMAP3430 ES1.0, 2.0 */
+ OMAPDSS_VER_OMAP34xx_ES3, /* OMAP3430 ES3.0+ */
+ OMAPDSS_VER_OMAP3630,
+ OMAPDSS_VER_AM35xx,
+ OMAPDSS_VER_OMAP4430_ES1, /* OMAP4430 ES1.0 */
+ OMAPDSS_VER_OMAP4430_ES2, /* OMAP4430 ES2.0, 2.1, 2.2 */
+ OMAPDSS_VER_OMAP4, /* All other OMAP4s */
+ OMAPDSS_VER_OMAP5,
+ OMAPDSS_VER_AM43xx,
+ OMAPDSS_VER_DRA7xx,
+};
+
+struct omap_dss_device;
+
+/* Board specific data */
+struct omap_dss_board_info {
+ int num_devices;
+ struct omap_dss_device **devices;
+ struct omap_dss_device *default_device;
+ const char *default_display_name;
+ int (*dsi_enable_pads)(int dsi_id, unsigned int lane_mask);
+ void (*dsi_disable_pads)(int dsi_id, unsigned int lane_mask);
+ int (*set_min_bus_tput)(struct device *dev, unsigned long r);
+ enum omapdss_version version;
+};
+
+#endif /* __OMAPDSS_PDATA_H */
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/platform_data/omapdss.h>
#include <video/videomode.h>
enum omap_dss_dsi_trans_mode trans_mode;
};
-enum omapdss_version {
- OMAPDSS_VER_UNKNOWN = 0,
- OMAPDSS_VER_OMAP24xx,
- OMAPDSS_VER_OMAP34xx_ES1, /* OMAP3430 ES1.0, 2.0 */
- OMAPDSS_VER_OMAP34xx_ES3, /* OMAP3430 ES3.0+ */
- OMAPDSS_VER_OMAP3630,
- OMAPDSS_VER_AM35xx,
- OMAPDSS_VER_OMAP4430_ES1, /* OMAP4430 ES1.0 */
- OMAPDSS_VER_OMAP4430_ES2, /* OMAP4430 ES2.0, 2.1, 2.2 */
- OMAPDSS_VER_OMAP4, /* All other OMAP4s */
- OMAPDSS_VER_OMAP5,
- OMAPDSS_VER_AM43xx,
- OMAPDSS_VER_DRA7xx,
-};
-
-/* Board specific data */
-struct omap_dss_board_info {
- int num_devices;
- struct omap_dss_device **devices;
- struct omap_dss_device *default_device;
- const char *default_display_name;
- int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask);
- void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
- int (*set_min_bus_tput)(struct device *dev, unsigned long r);
- enum omapdss_version version;
-};
-
-/* Init with the board info */
-extern int omap_display_init(struct omap_dss_board_info *board_data);
-
struct omap_video_timings {
/* Unit: pixels */
u16 x_res;
{
unsigned int w;
- if (mcbsp->pdata->enable_st_clock)
- mcbsp->pdata->enable_st_clock(mcbsp->id, 1);
+ if (mcbsp->pdata->force_ick_on)
+ mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, true);
/* Disable Sidetone clock auto-gating for normal operation */
w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
- if (mcbsp->pdata->enable_st_clock)
- mcbsp->pdata->enable_st_clock(mcbsp->id, 0);
+ if (mcbsp->pdata->force_ick_on)
+ mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, false);
}
static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
if (!st_data)
return -ENOMEM;
+ st_data->mcbsp_iclk = clk_get(mcbsp->dev, "ick");
+ if (IS_ERR(st_data->mcbsp_iclk)) {
+ dev_warn(mcbsp->dev,
+ "Failed to get ick, sidetone might be broken\n");
+ st_data->mcbsp_iclk = NULL;
+ }
+
st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start,
resource_size(res));
if (!st_data->io_base_st)
return ret;
}
-void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp)
+void omap_mcbsp_cleanup(struct omap_mcbsp *mcbsp)
{
if (mcbsp->pdata->buffer_size)
sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
- if (mcbsp->st_data)
+ if (mcbsp->st_data) {
sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+ clk_put(mcbsp->st_data->mcbsp_iclk);
+ }
}
struct omap_mcbsp_st_data {
void __iomem *io_base_st;
+ struct clk *mcbsp_iclk;
bool running;
bool enabled;
s16 taps[128]; /* Sidetone filter coefficients */
int omap_st_is_enabled(struct omap_mcbsp *mcbsp);
int omap_mcbsp_init(struct platform_device *pdev);
-void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp);
+void omap_mcbsp_cleanup(struct omap_mcbsp *mcbsp);
#endif /* __ASOC_MCBSP_H */
match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
if (match) {
struct device_node *node = pdev->dev.of_node;
+ struct omap_mcbsp_platform_data *pdata_quirk = pdata;
int buffer_size;
pdata = devm_kzalloc(&pdev->dev,
memcpy(pdata, match->data, sizeof(*pdata));
if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
pdata->buffer_size = buffer_size;
+ if (pdata_quirk)
+ pdata->force_ick_on = pdata_quirk->force_ick_on;
} else if (!pdata) {
dev_err(&pdev->dev, "missing platform data.\n");
return -EINVAL;
if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id);
- omap_mcbsp_sysfs_remove(mcbsp);
+ omap_mcbsp_cleanup(mcbsp);
clk_put(mcbsp->fclk);