Commit b0189cd0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'next/devel2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc

* 'next/devel2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc: (47 commits)
  OMAP: Add debugfs node to show the summary of all clocks
  OMAP2+: hwmod: Follow the recommended PRCM module enable sequence
  OMAP2+: clock: allow per-SoC clock init code to prevent clockdomain calls from clock code
  OMAP2+: clockdomain: Add per clkdm lock to prevent concurrent state programming
  OMAP2+: PM: idle clkdms only if already in idle
  OMAP2+: clockdomain: add clkdm_in_hwsup()
  OMAP2+: clockdomain: Add 2 APIs to control clockdomain from hwmod framework
  OMAP: clockdomain: Remove redundant call to pwrdm_wait_transition()
  OMAP4: hwmod: Introduce the module control in hwmod control
  OMAP4: cm: Add two new APIs for modulemode control
  OMAP4: hwmod data: Add modulemode entry in omap_hwmod structure
  OMAP4: hwmod data: Add PRM context register offset
  OMAP4: prm: Remove deprecated functions
  OMAP4: prm: Replace warm reset API with the offset based version
  OMAP4: hwmod: Replace RSTCTRL absolute address with offset macros
  OMAP: hwmod: Wait the idle status to be disabled
  OMAP4: hwmod: Replace CLKCTRL absolute address with offset macros
  OMAP2+: hwmod: Init clkdm field at boot time
  OMAP4: hwmod data: Add clock domain attribute
  OMAP4: clock data: Add missing divider selection for auxclks
  ...
parents 69f1d1a6 bc574e19
...@@ -345,11 +345,40 @@ static struct platform_device sdp4430_lcd_device = { ...@@ -345,11 +345,40 @@ static struct platform_device sdp4430_lcd_device = {
.id = -1, .id = -1,
}; };
static struct regulator_consumer_supply sdp4430_vbat_supply[] = {
REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"),
REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"),
};
static struct regulator_init_data sdp4430_vbat_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(sdp4430_vbat_supply),
.consumer_supplies = sdp4430_vbat_supply,
};
static struct fixed_voltage_config sdp4430_vbat_pdata = {
.supply_name = "VBAT",
.microvolts = 3750000,
.init_data = &sdp4430_vbat_data,
.gpio = -EINVAL,
};
static struct platform_device sdp4430_vbat = {
.name = "reg-fixed-voltage",
.id = -1,
.dev = {
.platform_data = &sdp4430_vbat_pdata,
},
};
static struct platform_device *sdp4430_devices[] __initdata = { static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device, &sdp4430_lcd_device,
&sdp4430_gpio_keys_device, &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio, &sdp4430_leds_gpio,
&sdp4430_leds_pwm, &sdp4430_leds_pwm,
&sdp4430_vbat,
}; };
static struct omap_lcd_config sdp4430_lcd_config __initdata = { static struct omap_lcd_config sdp4430_lcd_config __initdata = {
...@@ -505,7 +534,33 @@ static struct regulator_init_data sdp4430_vusim = { ...@@ -505,7 +534,33 @@ static struct regulator_init_data sdp4430_vusim = {
}, },
}; };
static struct twl4030_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
.hf_left_step = 0x1d,
.hf_right_step = 0x1d,
};
static struct twl4030_vibra_data twl6040_vibra = {
.vibldrv_res = 8,
.vibrdrv_res = 3,
.viblmotor_res = 10,
.vibrmotor_res = 10,
.vddvibl_uV = 0, /* fixed volt supply - VBAT */
.vddvibr_uV = 0, /* fixed volt supply - VBAT */
};
static struct twl4030_audio_data twl6040_audio = {
.codec = &twl6040_codec,
.vibra = &twl6040_vibra,
.audpwron_gpio = 127,
.naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
static struct twl4030_platform_data sdp4430_twldata = { static struct twl4030_platform_data sdp4430_twldata = {
.audio = &twl6040_audio,
/* Regulators */ /* Regulators */
.vusim = &sdp4430_vusim, .vusim = &sdp4430_vusim,
.vaux1 = &sdp4430_vaux1, .vaux1 = &sdp4430_vaux1,
......
...@@ -864,11 +864,11 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = { ...@@ -864,11 +864,11 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = {
.resource_config = twl4030_rconfig, .resource_config = twl4030_rconfig,
}; };
struct twl4030_codec_vibra_data rx51_vibra_data __initdata = { struct twl4030_vibra_data rx51_vibra_data __initdata = {
.coexist = 0, .coexist = 0,
}; };
struct twl4030_codec_data rx51_codec_data __initdata = { struct twl4030_audio_data rx51_audio_data __initdata = {
.audio_mclk = 26000000, .audio_mclk = 26000000,
.vibra = &rx51_vibra_data, .vibra = &rx51_vibra_data,
}; };
...@@ -878,7 +878,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = { ...@@ -878,7 +878,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
.gpio = &rx51_gpio_data, .gpio = &rx51_gpio_data,
.keypad = &rx51_kp_data, .keypad = &rx51_kp_data,
.power = &rx51_t2scripts_data, .power = &rx51_t2scripts_data,
.codec = &rx51_codec_data, .audio = &rx51_audio_data,
.vaux1 = &rx51_vaux1, .vaux1 = &rx51_vaux1,
.vaux2 = &rx51_vaux2, .vaux2 = &rx51_vaux2,
......
...@@ -274,12 +274,12 @@ static int __init omap_i2c_init(void) ...@@ -274,12 +274,12 @@ static int __init omap_i2c_init(void)
TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
if (machine_is_omap_zoom2()) { if (machine_is_omap_zoom2()) {
struct twl4030_codec_audio_data *audio_data; struct twl4030_codec_data *codec_data;
audio_data = zoom_twldata.codec->audio; codec_data = zoom_twldata.audio->codec;
audio_data->ramp_delay_value = 3; /* 161 ms */ codec_data->ramp_delay_value = 3; /* 161 ms */
audio_data->hs_extmute = 1; codec_data->hs_extmute = 1;
audio_data->set_hs_extmute = zoom2_set_hs_extmute; codec_data->set_hs_extmute = zoom2_set_hs_extmute;
} }
omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata); omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata);
omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(2, 400, NULL, 0);
......
...@@ -37,6 +37,14 @@ ...@@ -37,6 +37,14 @@
u8 cpu_mask; u8 cpu_mask;
/*
* clkdm_control: if true, then when a clock is enabled in the
* hardware, its clockdomain will first be enabled; and when a clock
* is disabled in the hardware, its clockdomain will be disabled
* afterwards.
*/
static bool clkdm_control = true;
/* /*
* OMAP2+ specific clock functions * OMAP2+ specific clock functions
*/ */
...@@ -99,6 +107,19 @@ void omap2_init_clk_clkdm(struct clk *clk) ...@@ -99,6 +107,19 @@ void omap2_init_clk_clkdm(struct clk *clk)
} }
} }
/**
* omap2_clk_disable_clkdm_control - disable clkdm control on clk enable/disable
*
* Prevent the OMAP clock code from calling into the clockdomain code
* when a hardware clock in that clockdomain is enabled or disabled.
* Intended to be called at init time from omap*_clk_init(). No
* return value.
*/
void __init omap2_clk_disable_clkdm_control(void)
{
clkdm_control = false;
}
/** /**
* omap2_clk_dflt_find_companion - find companion clock to @clk * omap2_clk_dflt_find_companion - find companion clock to @clk
* @clk: struct clk * to find the companion clock of * @clk: struct clk * to find the companion clock of
...@@ -268,7 +289,7 @@ void omap2_clk_disable(struct clk *clk) ...@@ -268,7 +289,7 @@ void omap2_clk_disable(struct clk *clk)
clk->ops->disable(clk); clk->ops->disable(clk);
} }
if (clk->clkdm) if (clkdm_control && clk->clkdm)
clkdm_clk_disable(clk->clkdm, clk); clkdm_clk_disable(clk->clkdm, clk);
if (clk->parent) if (clk->parent)
...@@ -308,7 +329,7 @@ int omap2_clk_enable(struct clk *clk) ...@@ -308,7 +329,7 @@ int omap2_clk_enable(struct clk *clk)
} }
} }
if (clk->clkdm) { if (clkdm_control && clk->clkdm) {
ret = clkdm_clk_enable(clk->clkdm, clk); ret = clkdm_clk_enable(clk->clkdm, clk);
if (ret) { if (ret) {
WARN(1, "clock: %s: could not enable clockdomain %s: " WARN(1, "clock: %s: could not enable clockdomain %s: "
...@@ -330,7 +351,7 @@ int omap2_clk_enable(struct clk *clk) ...@@ -330,7 +351,7 @@ int omap2_clk_enable(struct clk *clk)
return 0; return 0;
oce_err3: oce_err3:
if (clk->clkdm) if (clkdm_control && clk->clkdm)
clkdm_clk_disable(clk->clkdm, clk); clkdm_clk_disable(clk->clkdm, clk);
oce_err2: oce_err2:
if (clk->parent) if (clk->parent)
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
#define __ARCH_ARM_MACH_OMAP2_CLOCK_H #define __ARCH_ARM_MACH_OMAP2_CLOCK_H
#include <linux/kernel.h>
#include <plat/clock.h> #include <plat/clock.h>
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
...@@ -72,6 +74,7 @@ void omap2_clk_disable_unused(struct clk *clk); ...@@ -72,6 +74,7 @@ void omap2_clk_disable_unused(struct clk *clk);
#endif #endif
void omap2_init_clk_clkdm(struct clk *clk); void omap2_init_clk_clkdm(struct clk *clk);
void __init omap2_clk_disable_clkdm_control(void);
/* clkt_clksel.c public functions */ /* clkt_clksel.c public functions */
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
......
...@@ -1805,9 +1805,9 @@ static struct omap_clk omap2420_clks[] = { ...@@ -1805,9 +1805,9 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
/* DSS domain clocks */ /* DSS domain clocks */
CLK("omapdss_dss", "ick", &dss_ick, CK_242X), CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
CLK("omapdss_dss", "fck", &dss1_fck, CK_242X), CLK(NULL, "dss1_fck", &dss1_fck, CK_242X),
CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X), CLK(NULL, "dss2_fck", &dss2_fck, CK_242X),
CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X), CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_242X),
/* L3 domain clocks */ /* L3 domain clocks */
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
...@@ -1844,13 +1844,13 @@ static struct omap_clk omap2420_clks[] = { ...@@ -1844,13 +1844,13 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_242X), CLK(NULL, "gpt12_ick", &gpt12_ick, CK_242X),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_242X), CLK(NULL, "gpt12_fck", &gpt12_fck, CK_242X),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X), CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X),
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_242X), CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_242X),
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_242X), CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_242X),
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_242X), CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_242X),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_242X), CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_242X),
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_242X), CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_242X),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_242X), CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_242X),
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_242X), CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_242X),
CLK(NULL, "uart1_ick", &uart1_ick, CK_242X), CLK(NULL, "uart1_ick", &uart1_ick, CK_242X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_242X), CLK(NULL, "uart1_fck", &uart1_fck, CK_242X),
CLK(NULL, "uart2_ick", &uart2_ick, CK_242X), CLK(NULL, "uart2_ick", &uart2_ick, CK_242X),
...@@ -1860,7 +1860,7 @@ static struct omap_clk omap2420_clks[] = { ...@@ -1860,7 +1860,7 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gpios_ick", &gpios_ick, CK_242X), CLK(NULL, "gpios_ick", &gpios_ick, CK_242X),
CLK(NULL, "gpios_fck", &gpios_fck, CK_242X), CLK(NULL, "gpios_fck", &gpios_fck, CK_242X),
CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_242X), CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_242X),
CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_242X), CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_242X),
CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_242X), CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_242X),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_242X), CLK(NULL, "wdt1_ick", &wdt1_ick, CK_242X),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_242X), CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_242X),
...@@ -1880,11 +1880,11 @@ static struct omap_clk omap2420_clks[] = { ...@@ -1880,11 +1880,11 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "eac_ick", &eac_ick, CK_242X), CLK(NULL, "eac_ick", &eac_ick, CK_242X),
CLK(NULL, "eac_fck", &eac_fck, CK_242X), CLK(NULL, "eac_fck", &eac_fck, CK_242X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X), CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_242X), CLK("omap_hdq.0", "fck", &hdq_fck, CK_242X),
CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X), CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X),
CLK("omap_i2c.1", "fck", &i2c1_fck, CK_242X), CLK(NULL, "i2c1_fck", &i2c1_fck, CK_242X),
CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X), CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X),
CLK("omap_i2c.2", "fck", &i2c2_fck, CK_242X), CLK(NULL, "i2c2_fck", &i2c2_fck, CK_242X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X), CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_242X), CLK(NULL, "sdma_fck", &sdma_fck, CK_242X),
CLK(NULL, "sdma_ick", &sdma_ick, CK_242X), CLK(NULL, "sdma_ick", &sdma_ick, CK_242X),
......
...@@ -1895,9 +1895,9 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1895,9 +1895,9 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
/* DSS domain clocks */ /* DSS domain clocks */
CLK("omapdss_dss", "ick", &dss_ick, CK_243X), CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
CLK("omapdss_dss", "fck", &dss1_fck, CK_243X), CLK(NULL, "dss1_fck", &dss1_fck, CK_243X),
CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X), CLK(NULL, "dss2_fck", &dss2_fck, CK_243X),
CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X), CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X),
/* L3 domain clocks */ /* L3 domain clocks */
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
...@@ -1934,21 +1934,21 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1934,21 +1934,21 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X), CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X), CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X), CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X),
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X), CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_243X),
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X), CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X),
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X), CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_243X),
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X), CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X),
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X), CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_243X),
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X), CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X),
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X), CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_243X),
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X), CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X),
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X), CLK(NULL, "mcbsp5_fck", &mcbsp5_fck, CK_243X),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X), CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X),
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X), CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_243X),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X), CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X),
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X), CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_243X),
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X), CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X),
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X), CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_243X),
CLK(NULL, "uart1_ick", &uart1_ick, CK_243X), CLK(NULL, "uart1_ick", &uart1_ick, CK_243X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_243X), CLK(NULL, "uart1_fck", &uart1_fck, CK_243X),
CLK(NULL, "uart2_ick", &uart2_ick, CK_243X), CLK(NULL, "uart2_ick", &uart2_ick, CK_243X),
...@@ -1958,7 +1958,7 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1958,7 +1958,7 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "gpios_ick", &gpios_ick, CK_243X), CLK(NULL, "gpios_ick", &gpios_ick, CK_243X),
CLK(NULL, "gpios_fck", &gpios_fck, CK_243X), CLK(NULL, "gpios_fck", &gpios_fck, CK_243X),
CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X), CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X),
CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X), CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_243X),
CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X), CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X), CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X), CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X),
...@@ -1975,9 +1975,9 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1975,9 +1975,9 @@ static struct omap_clk omap2430_clks[] = {
CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X), CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X), CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X),
CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X), CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X),
CLK("omap_i2c.1", "fck", &i2chs1_fck, CK_243X), CLK(NULL, "i2chs1_fck", &i2chs1_fck, CK_243X),
CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X), CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X),
CLK("omap_i2c.2", "fck", &i2chs2_fck, CK_243X), CLK(NULL, "i2chs2_fck", &i2chs2_fck, CK_243X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X), CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_243X), CLK(NULL, "sdma_fck", &sdma_fck, CK_243X),
CLK(NULL, "sdma_ick", &sdma_ick, CK_243X), CLK(NULL, "sdma_ick", &sdma_ick, CK_243X),
...@@ -1990,9 +1990,9 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1990,9 +1990,9 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "usb_fck", &usb_fck, CK_243X), CLK(NULL, "usb_fck", &usb_fck, CK_243X),
CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X), CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X),
CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X), CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X),
CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_243X), CLK(NULL, "mmchs1_fck", &mmchs1_fck, CK_243X),
CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X), CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X),
CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_243X), CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_243X),
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X), CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X),
CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X), CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X),
CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
......
...@@ -3289,25 +3289,25 @@ static struct omap_clk omap3xxx_clks[] = { ...@@ -3289,25 +3289,25 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
CLK("omap_hsmmc.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "mmchs3_fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_3XXX), CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_3XXX),
CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX), CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX),
CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_3XXX), CLK(NULL, "mmchs1_fck", &mmchs1_fck, CK_3XXX),
CLK("omap_i2c.3", "fck", &i2c3_fck, CK_3XXX), CLK(NULL, "i2c3_fck", &i2c3_fck, CK_3XXX),
CLK("omap_i2c.2", "fck", &i2c2_fck, CK_3XXX), CLK(NULL, "i2c2_fck", &i2c2_fck, CK_3XXX),
CLK("omap_i2c.1", "fck", &i2c1_fck, CK_3XXX), CLK(NULL, "i2c1_fck", &i2c1_fck, CK_3XXX),
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_3XXX), CLK(NULL, "mcbsp5_fck", &mcbsp5_fck, CK_3XXX),
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_3XXX), CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_3XXX),
CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX), CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX),
CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_3XXX), CLK(NULL, "mcspi4_fck", &mcspi4_fck, CK_3XXX),
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_3XXX), CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_3XXX),
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_3XXX), CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_3XXX),
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_3XXX), CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_3XXX),
CLK(NULL, "uart2_fck", &uart2_fck, CK_3XXX), CLK(NULL, "uart2_fck", &uart2_fck, CK_3XXX),
CLK(NULL, "uart1_fck", &uart1_fck, CK_3XXX), CLK(NULL, "uart1_fck", &uart1_fck, CK_3XXX),
CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX), CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX),
CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX), CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX),
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1), CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1),
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX), CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1), CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1),
...@@ -3356,11 +3356,11 @@ static struct omap_clk omap3xxx_clks[] = { ...@@ -3356,11 +3356,11 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1), CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX), CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_3XXX),
CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX), CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_3XXX),
CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX), CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_3XXX),
CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1), CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
...@@ -3385,7 +3385,7 @@ static struct omap_clk omap3xxx_clks[] = { ...@@ -3385,7 +3385,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX), CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX),
CLK("omap_wdt", "fck", &wdt2_fck, CK_3XXX), CLK(NULL, "wdt2_fck", &wdt2_fck, CK_3XXX),
CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX), CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX),
CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX), CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX),
CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX), CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX),
...@@ -3436,9 +3436,9 @@ static struct omap_clk omap3xxx_clks[] = { ...@@ -3436,9 +3436,9 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX), CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX),
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX), CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX),
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX), CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX),
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_3XXX), CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_3XXX),
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_3XXX), CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_3XXX),
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_3XXX), CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_3XXX),
CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX), CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX),
CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX), CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX),
CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX), CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX),
......
This diff is collapsed.
/* /*
* OMAP2/3/4 clockdomain framework functions * OMAP2/3/4 clockdomain framework functions
* *
* Copyright (C) 2008-2010 Texas Instruments, Inc. * Copyright (C) 2008-2011 Texas Instruments, Inc.
* Copyright (C) 2008-2010 Nokia Corporation * Copyright (C) 2008-2011 Nokia Corporation
* *
* Written by Paul Walmsley and Jouni Högander * Written by Paul Walmsley and Jouni Högander
* Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
...@@ -92,6 +92,8 @@ static int _clkdm_register(struct clockdomain *clkdm) ...@@ -92,6 +92,8 @@ static int _clkdm_register(struct clockdomain *clkdm)
pwrdm_add_clkdm(pwrdm, clkdm); pwrdm_add_clkdm(pwrdm, clkdm);
spin_lock_init(&clkdm->lock);
pr_debug("clockdomain: registered %s\n", clkdm->name); pr_debug("clockdomain: registered %s\n", clkdm->name);
return 0; return 0;
...@@ -690,6 +692,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) ...@@ -690,6 +692,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
*/ */
int clkdm_sleep(struct clockdomain *clkdm) int clkdm_sleep(struct clockdomain *clkdm)
{ {
int ret;
unsigned long flags;
if (!clkdm) if (!clkdm)
return -EINVAL; return -EINVAL;
...@@ -704,7 +709,11 @@ int clkdm_sleep(struct clockdomain *clkdm) ...@@ -704,7 +709,11 @@ int clkdm_sleep(struct clockdomain *clkdm)
pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
return arch_clkdm->clkdm_sleep(clkdm); spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
ret = arch_clkdm->clkdm_sleep(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
return ret;
} }
/** /**
...@@ -718,6 +727,9 @@ int clkdm_sleep(struct clockdomain *clkdm) ...@@ -718,6 +727,9 @@ int clkdm_sleep(struct clockdomain *clkdm)
*/ */
int clkdm_wakeup(struct clockdomain *clkdm) int clkdm_wakeup(struct clockdomain *clkdm)
{ {
int ret;
unsigned long flags;
if (!clkdm) if (!clkdm)
return -EINVAL; return -EINVAL;
...@@ -732,7 +744,11 @@ int clkdm_wakeup(struct clockdomain *clkdm) ...@@ -732,7 +744,11 @@ int clkdm_wakeup(struct clockdomain *clkdm)
pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
return arch_clkdm->clkdm_wakeup(clkdm); spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
ret = arch_clkdm->clkdm_wakeup(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
return ret;
} }
/** /**
...@@ -747,6 +763,8 @@ int clkdm_wakeup(struct clockdomain *clkdm) ...@@ -747,6 +763,8 @@ int clkdm_wakeup(struct clockdomain *clkdm)
*/ */
void clkdm_allow_idle(struct clockdomain *clkdm) void clkdm_allow_idle(struct clockdomain *clkdm)
{ {
unsigned long flags;
if (!clkdm) if (!clkdm)
return; return;
...@@ -762,8 +780,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm) ...@@ -762,8 +780,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: enabling automatic idle transitions for %s\n", pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
clkdm->name); clkdm->name);
spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;
arch_clkdm->clkdm_allow_idle(clkdm); arch_clkdm->clkdm_allow_idle(clkdm);
pwrdm_clkdm_state_switch(clkdm); pwrdm_clkdm_state_switch(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
} }
/** /**
...@@ -777,6 +798,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm) ...@@ -777,6 +798,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
*/ */
void clkdm_deny_idle(struct clockdomain *clkdm) void clkdm_deny_idle(struct clockdomain *clkdm)
{ {
unsigned long flags;
if (!clkdm) if (!clkdm)
return; return;
...@@ -792,11 +815,90 @@ void clkdm_deny_idle(struct clockdomain *clkdm) ...@@ -792,11 +815,90 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: disabling automatic idle transitions for %s\n", pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
clkdm->name); clkdm->name);
spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
arch_clkdm->clkdm_deny_idle(clkdm); arch_clkdm->clkdm_deny_idle(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
}
/**
* clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled?
* @clkdm: struct clockdomain *
*
* Returns true if clockdomain @clkdm currently has
* hardware-supervised idle enabled, or false if it does not or if
* @clkdm is NULL. It is only valid to call this function after
* clkdm_init() has been called. This function does not actually read
* bits from the hardware; it instead tests an in-memory flag that is
* changed whenever the clockdomain code changes the auto-idle mode.
*/
bool clkdm_in_hwsup(struct clockdomain *clkdm)
{
bool ret;
unsigned long flags;
if (!clkdm)
return false;
spin_lock_irqsave(&clkdm->lock, flags);
ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false;
spin_unlock_irqrestore(&clkdm->lock, flags);
return ret;
}
/* Clockdomain-to-clock/hwmod framework interface code */
static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
{
unsigned long flags;
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
return -EINVAL;
/*
* For arch's with no autodeps, clkcm_clk_enable
* should be called for every clock instance or hwmod that is
* enabled, so the clkdm can be force woken up.
*/
if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps)
return 0;
spin_lock_irqsave(&clkdm->lock, flags);
arch_clkdm->clkdm_clk_enable(clkdm);
pwrdm_wait_transition(clkdm->pwrdm.ptr);
pwrdm_clkdm_state_switch(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name);
return 0;
} }
static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
{
unsigned long flags;
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
return -EINVAL;
if (atomic_read(&clkdm->usecount) == 0) {
WARN_ON(1); /* underflow */
return -ERANGE;
}
if (atomic_dec_return(&clkdm->usecount) > 0)
return 0;
spin_lock_irqsave(&clkdm->lock, flags);
arch_clkdm->clkdm_clk_disable(clkdm);
pwrdm_clkdm_state_switch(clkdm);
spin_unlock_irqrestore(&clkdm->lock, flags);
/* Clockdomain-to-clock framework interface code */ pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name);
return 0;
}
/** /**
* clkdm_clk_enable - add an enabled downstream clock to this clkdm * clkdm_clk_enable - add an enabled downstream clock to this clkdm
...@@ -819,25 +921,10 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) ...@@ -819,25 +921,10 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
* downstream clocks for debugging purposes? * downstream clocks for debugging purposes?
*/ */
if (!clkdm || !clk) if (!clk)
return -EINVAL; return -EINVAL;
if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable) return _clkdm_clk_hwmod_enable(clkdm);
return -EINVAL;
if (atomic_inc_return(&clkdm->usecount) > 1)
return 0;
/* Clockdomain now has one enabled downstream clock */
pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
clk->name);
arch_clkdm->clkdm_clk_enable(clkdm);
pwrdm_wait_transition(clkdm->pwrdm.ptr);
pwrdm_clkdm_state_switch(clkdm);
return 0;
} }
/** /**
...@@ -850,9 +937,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) ...@@ -850,9 +937,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
* clockdomain usecount goes to 0, put the clockdomain to sleep * clockdomain usecount goes to 0, put the clockdomain to sleep
* (software-supervised mode) or remove the clkdm autodependencies * (software-supervised mode) or remove the clkdm autodependencies
* (hardware-supervised mode). Returns -EINVAL if passed null * (hardware-supervised mode). Returns -EINVAL if passed null
* pointers; -ERANGE if the @clkdm usecount underflows and debugging * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0
* is enabled; or returns 0 upon success or if the clockdomain is in * upon success or if the clockdomain is in hwsup idle mode.
* hwsup idle mode.
*/ */
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{ {
...@@ -861,30 +947,72 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) ...@@ -861,30 +947,72 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
* downstream clocks for debugging purposes? * downstream clocks for debugging purposes?
*/ */
if (!clkdm || !clk) if (!clk)
return -EINVAL; return -EINVAL;
if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable) return _clkdm_clk_hwmod_disable(clkdm);
}
/**
* clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
* @clkdm: struct clockdomain *
* @oh: struct omap_hwmod * of the enabled downstream hwmod
*
* Increment the usecount of the clockdomain @clkdm and ensure that it
* is awake before @oh is enabled. Intended to be called by
* module_enable() code.
* If the clockdomain is in software-supervised idle mode, force the
* clockdomain to wake. If the clockdomain is in hardware-supervised idle
* mode, add clkdm-pwrdm autodependencies, to ensure that devices in the
* clockdomain can be read from/written to by on-chip processors.
* Returns -EINVAL if passed null pointers;
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
*/
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
{
/* The clkdm attribute does not exist yet prior OMAP4 */
if (cpu_is_omap24xx() || cpu_is_omap34xx())
return 0;
/*
* XXX Rewrite this code to maintain a list of enabled
* downstream hwmods for debugging purposes?
*/
if (!oh)
return -EINVAL; return -EINVAL;
#ifdef DEBUG return _clkdm_clk_hwmod_enable(clkdm);
if (atomic_read(&clkdm->usecount) == 0) { }
WARN_ON(1); /* underflow */
return -ERANGE;
}
#endif
if (atomic_dec_return(&clkdm->usecount) > 0) /**
* clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm
* @clkdm: struct clockdomain *
* @oh: struct omap_hwmod * of the disabled downstream hwmod
*
* Decrement the usecount of this clockdomain @clkdm when @oh is
* disabled. Intended to be called by module_disable() code.
* If the clockdomain usecount goes to 0, put the clockdomain to sleep
* (software-supervised mode) or remove the clkdm autodependencies
* (hardware-supervised mode).
* Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount
* underflows; or returns 0 upon success or if the clockdomain is in hwsup
* idle mode.
*/
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
{
/* The clkdm attribute does not exist yet prior OMAP4 */
if (cpu_is_omap24xx() || cpu_is_omap34xx())
return 0; return 0;
/* All downstream clocks of this clockdomain are now disabled */ /*
* XXX Rewrite this code to maintain a list of enabled
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, * downstream hwmods for debugging purposes?
clk->name); */
arch_clkdm->clkdm_clk_disable(clkdm); if (!oh)
pwrdm_clkdm_state_switch(clkdm); return -EINVAL;
return 0; return _clkdm_clk_hwmod_disable(clkdm);
} }
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include "powerdomain.h" #include "powerdomain.h"
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/omap_hwmod.h>
#include <plat/cpu.h> #include <plat/cpu.h>
/* /*
...@@ -82,6 +84,9 @@ struct clkdm_dep { ...@@ -82,6 +84,9 @@ struct clkdm_dep {
const struct omap_chip_id omap_chip; const struct omap_chip_id omap_chip;
}; };
/* Possible flags for struct clockdomain._flags */
#define _CLKDM_FLAG_HWSUP_ENABLED BIT(0)
/** /**
* struct clockdomain - OMAP clockdomain * struct clockdomain - OMAP clockdomain
* @name: clockdomain name * @name: clockdomain name
...@@ -89,6 +94,7 @@ struct clkdm_dep { ...@@ -89,6 +94,7 @@ struct clkdm_dep {
* @clktrctrl_reg: CLKSTCTRL reg for the given clock domain * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain
* @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
* @flags: Clockdomain capability flags * @flags: Clockdomain capability flags
* @_flags: Flags for use only by internal clockdomain code
* @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
* @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers
* @cm_inst: (OMAP4 only) CM instance register offset * @cm_inst: (OMAP4 only) CM instance register offset
...@@ -113,6 +119,7 @@ struct clockdomain { ...@@ -113,6 +119,7 @@ struct clockdomain {
} pwrdm; } pwrdm;
const u16 clktrctrl_mask; const u16 clktrctrl_mask;
const u8 flags; const u8 flags;
u8 _flags;
const u8 dep_bit; const u8 dep_bit;
const u8 prcm_partition; const u8 prcm_partition;
const s16 cm_inst; const s16 cm_inst;
...@@ -122,6 +129,7 @@ struct clockdomain { ...@@ -122,6 +129,7 @@ struct clockdomain {
const struct omap_chip_id omap_chip; const struct omap_chip_id omap_chip;
atomic_t usecount; atomic_t usecount;
struct list_head node; struct list_head node;
spinlock_t lock;
}; };
/** /**
...@@ -177,12 +185,15 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); ...@@ -177,12 +185,15 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
void clkdm_allow_idle(struct clockdomain *clkdm); void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm); void clkdm_deny_idle(struct clockdomain *clkdm);
bool clkdm_in_hwsup(struct clockdomain *clkdm);
int clkdm_wakeup(struct clockdomain *clkdm); int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm); int clkdm_sleep(struct clockdomain *clkdm);
int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
extern void __init omap2xxx_clockdomains_init(void); extern void __init omap2xxx_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void); extern void __init omap3xxx_clockdomains_init(void);
......
...@@ -183,7 +183,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm) ...@@ -183,7 +183,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
_clkdm_add_autodeps(clkdm); _clkdm_add_autodeps(clkdm);
_enable_hwsup(clkdm); _enable_hwsup(clkdm);
} else { } else {
clkdm_wakeup(clkdm); if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
omap2_clkdm_wakeup(clkdm);
} }
return 0; return 0;
...@@ -205,7 +206,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm) ...@@ -205,7 +206,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
_clkdm_del_autodeps(clkdm); _clkdm_del_autodeps(clkdm);
_enable_hwsup(clkdm); _enable_hwsup(clkdm);
} else { } else {
clkdm_sleep(clkdm); if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
omap2_clkdm_sleep(clkdm);
} }
return 0; return 0;
......
...@@ -95,13 +95,8 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) ...@@ -95,13 +95,8 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
{ {
bool hwsup = false; if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
return omap4_clkdm_wakeup(clkdm);
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
clkdm->cm_inst, clkdm->clkdm_offs);
if (!hwsup)
clkdm_wakeup(clkdm);
return 0; return 0;
} }
...@@ -113,8 +108,8 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) ...@@ -113,8 +108,8 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
clkdm->cm_inst, clkdm->clkdm_offs); clkdm->cm_inst, clkdm->clkdm_offs);
if (!hwsup) if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
clkdm_sleep(clkdm); omap4_clkdm_sleep(clkdm);
return 0; return 0;
} }
......
...@@ -565,7 +565,7 @@ static struct clockdomain ducati_44xx_clkdm = { ...@@ -565,7 +565,7 @@ static struct clockdomain ducati_44xx_clkdm = {
}; };
static struct clockdomain mpu_44xx_clkdm = { static struct clockdomain mpu_44xx_clkdm = {
.name = "mpu_clkdm", .name = "mpuss_clkdm",
.pwrdm = { .name = "mpu_pwrdm" }, .pwrdm = { .name = "mpu_pwrdm" },
.prcm_partition = OMAP4430_CM1_PARTITION, .prcm_partition = OMAP4430_CM1_PARTITION,
.cm_inst = OMAP4430_CM1_MPU_INST, .cm_inst = OMAP4430_CM1_MPU_INST,
......
/* /*
* OMAP4 Clock Management (CM) definitions * OMAP4 Clock Management (CM) definitions
* *
* Copyright (C) 2007-2009 Texas Instruments, Inc. * Copyright (C) 2007-2011 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation * Copyright (C) 2007-2009 Nokia Corporation
* *
* Written by Paul Walmsley * Written by Paul Walmsley
...@@ -23,10 +23,4 @@ ...@@ -23,10 +23,4 @@
#define OMAP4_CM_CLKSTCTRL 0x0000 #define OMAP4_CM_CLKSTCTRL 0x0000
#define OMAP4_CM_STATICDEP 0x0004 #define OMAP4_CM_STATICDEP 0x0004
/* Function prototypes */
# ifndef __ASSEMBLER__
extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
# endif
#endif #endif
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* OMAP4 CM instance functions * OMAP4 CM instance functions
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley * Paul Walmsley
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -32,6 +33,22 @@ ...@@ -32,6 +33,22 @@
#include "prm44xx.h" #include "prm44xx.h"
#include "prcm_mpu44xx.h" #include "prcm_mpu44xx.h"
/*
* CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield:
*
* 0x0 func: Module is fully functional, including OCP
* 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
* abortion
* 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
* using separate functional clock
* 0x3 disabled: Module is disabled and cannot be accessed
*
*/
#define CLKCTRL_IDLEST_FUNCTIONAL 0x0
#define CLKCTRL_IDLEST_INTRANSITION 0x1
#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
#define CLKCTRL_IDLEST_DISABLED 0x3
static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
[OMAP4430_INVALID_PRCM_PARTITION] = 0, [OMAP4430_INVALID_PRCM_PARTITION] = 0,
[OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE, [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
...@@ -41,6 +58,48 @@ static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { ...@@ -41,6 +58,48 @@ static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
[OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE, [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
}; };
/* Private functions */
/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
* bit 0.
*/
static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{
u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
v &= OMAP4430_IDLEST_MASK;
v >>= OMAP4430_IDLEST_SHIFT;
return v;
}
/**
* _is_module_ready - can module registers be accessed without causing an abort?
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
* *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
*/
static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{
u32 v;
v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs);
return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
}
/* Public functions */
/* Read a register in a CM instance */ /* Read a register in a CM instance */
u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
{ {
...@@ -200,36 +259,93 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs) ...@@ -200,36 +259,93 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
*/ */
/** /**
* omap4_cm_wait_module_ready - wait for a module to be in 'func' state * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state
* @clkctrl_reg: CLKCTRL module address * @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
* *
* Wait for the module IDLEST to be functional. If the idle state is in any * Wait for the module IDLEST to be functional. If the idle state is in any
* the non functional state (trans, idle or disabled), module and thus the * the non functional state (trans, idle or disabled), module and thus the
* sysconfig cannot be accessed and will probably lead to an "imprecise * sysconfig cannot be accessed and will probably lead to an "imprecise
* external abort" * external abort"
*/
int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs)
{
int i = 0;
if (!clkctrl_offs)
return 0;
omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs),
MAX_MODULE_READY_TIME, i);
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
/**
* omap4_cminst_wait_module_idle - wait for a module to be in 'disabled'
* state
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
* *
* Module idle state: * Wait for the module IDLEST to be disabled. Some PRCM transition,
* 0x0 func: Module is fully functional, including OCP * like reset assertion or parent clock de-activation must wait the
* 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep * module to be fully disabled.
* abortion
* 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
* using separate functional clock
* 0x3 disabled: Module is disabled and cannot be accessed
*
*/ */
int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg) int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{ {
int i = 0; int i = 0;
if (!clkctrl_reg) if (!clkctrl_offs)
return 0; return 0;
omap_test_timeout(( omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) ==
((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) || CLKCTRL_IDLEST_DISABLED),
(((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >> MAX_MODULE_READY_TIME, i);
OMAP4430_IDLEST_SHIFT) == 0x2)),
MAX_MODULE_READY_TIME, i);
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
} }
/**
* omap4_cminst_module_enable - Enable the modulemode inside CLKCTRL
* @mode: Module mode (SW or HW)
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* No return value.
*/
void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs)
{
u32 v;
v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
v &= ~OMAP4430_MODULEMODE_MASK;
v |= mode << OMAP4430_MODULEMODE_SHIFT;
omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
}
/**
* omap4_cminst_module_disable - Disable the module inside CLKCTRL
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* No return value.
*/
void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs)
{
u32 v;
v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
v &= ~OMAP4430_MODULEMODE_MASK;
omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
}
...@@ -17,6 +17,14 @@ extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs); ...@@ -17,6 +17,14 @@ extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs); extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs);
extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs);
/* /*
* In an ideal world, we would not export these low-level functions, * In an ideal world, we would not export these low-level functions,
* but this will probably take some time to fix properly * but this will probably take some time to fix properly
...@@ -32,6 +40,4 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, ...@@ -32,6 +40,4 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
u32 mask); u32 mask);
extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
#endif #endif
This diff is collapsed.
This diff is collapsed.
...@@ -108,6 +108,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) ...@@ -108,6 +108,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
u32 cur_state; u32 cur_state;
int sleep_switch = -1; int sleep_switch = -1;
int ret = 0; int ret = 0;
int hwsup = 0;
if (pwrdm == NULL || IS_ERR(pwrdm)) if (pwrdm == NULL || IS_ERR(pwrdm))
return -EINVAL; return -EINVAL;
...@@ -127,6 +128,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) ...@@ -127,6 +128,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
sleep_switch = LOWPOWERSTATE_SWITCH; sleep_switch = LOWPOWERSTATE_SWITCH;
} else { } else {
hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
pwrdm_wait_transition(pwrdm); pwrdm_wait_transition(pwrdm);
sleep_switch = FORCEWAKEUP_SWITCH; sleep_switch = FORCEWAKEUP_SWITCH;
...@@ -142,7 +144,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) ...@@ -142,7 +144,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
switch (sleep_switch) { switch (sleep_switch) {
case FORCEWAKEUP_SWITCH: case FORCEWAKEUP_SWITCH:
if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO) if (hwsup)
clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
else else
clkdm_sleep(pwrdm->pwrdm_clkdms[0]); clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
......
...@@ -70,7 +70,7 @@ static void omap_prcm_arch_reset(char mode, const char *cmd) ...@@ -70,7 +70,7 @@ static void omap_prcm_arch_reset(char mode, const char *cmd)
prcm_offs = OMAP3430_GR_MOD; prcm_offs = OMAP3430_GR_MOD;
omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
} else if (cpu_is_omap44xx()) { } else if (cpu_is_omap44xx()) {
omap4_prm_global_warm_sw_reset(); /* never returns */ omap4_prminst_global_warm_sw_reset(); /* never returns */
} else { } else {
WARN_ON(1); WARN_ON(1);
} }
......
/* /*
* OMAP4 PRM module functions * OMAP4 PRM module functions
* *
* Copyright (C) 2010 Texas Instruments, Inc. * Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation * Copyright (C) 2010 Nokia Corporation
* Benoît Cousson * Benoît Cousson
* Paul Walmsley * Paul Walmsley
...@@ -24,12 +24,6 @@ ...@@ -24,12 +24,6 @@
#include "prm44xx.h" #include "prm44xx.h"
#include "prm-regbits-44xx.h" #include "prm-regbits-44xx.h"
/*
* Address offset (in bytes) between the reset control and the reset
* status registers: 4 bytes on OMAP4
*/
#define OMAP4_RST_CTRL_ST_OFFSET 4
/* PRM low-level functions */ /* PRM low-level functions */
/* Read a register in a CM/PRM instance in the PRM module */ /* Read a register in a CM/PRM instance in the PRM module */
...@@ -56,140 +50,3 @@ u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) ...@@ -56,140 +50,3 @@ u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
return v; return v;
} }
/* Read a PRM register, AND it, and shift the result down to bit 0 */
/* XXX deprecated */
u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
{
u32 v;
v = __raw_readl(reg);
v &= mask;
v >>= __ffs(mask);
return v;
}
/* Read-modify-write a register in a PRM module. Caller must lock */
/* XXX deprecated */
u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
{
u32 v;
v = __raw_readl(reg);
v &= ~mask;
v |= bits;
__raw_writel(v, reg);
return v;
}
u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 reg)
{
return omap4_prm_rmw_inst_reg_bits(bits, bits, inst, reg);
}
u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
{
return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
}
/**
* omap4_prm_is_hardreset_asserted - read the HW reset line state of
* submodules contained in the hwmod module
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to check
*
* Returns 1 if the (sub)module hardreset line is currently asserted,
* 0 if the (sub)module hardreset line is not currently asserted, or
* -EINVAL upon parameter error.
*/
int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
{
if (!cpu_is_omap44xx() || !rstctrl_reg)
return -EINVAL;
return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
}
/**
* omap4_prm_assert_hardreset - assert the HW reset line of a submodule
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to assert
*
* Some IPs like dsp, ipu or iva contain processors that require an HW
* reset line to be asserted / deasserted in order to fully enable the
* IP. These modules may have multiple hard-reset lines that reset
* different 'submodules' inside the IP block. This function will
* place the submodule into reset. Returns 0 upon success or -EINVAL
* upon an argument error.
*/
int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
{
u32 mask;
if (!cpu_is_omap44xx() || !rstctrl_reg)
return -EINVAL;
mask = 1 << shift;
omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
return 0;
}
/**
* omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to deassert
*
* Some IPs like dsp, ipu or iva contain processors that require an HW
* reset line to be asserted / deasserted in order to fully enable the
* IP. These modules may have multiple hard-reset lines that reset
* different 'submodules' inside the IP block. This function will
* take the submodule out of reset and wait until the PRCM indicates
* that the reset has completed before returning. Returns 0 upon success or
* -EINVAL upon an argument error, -EEXIST if the submodule was already out
* of reset, or -EBUSY if the submodule did not exit reset promptly.
*/
int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
{
u32 mask;
void __iomem *rstst_reg;
int c;
if (!cpu_is_omap44xx() || !rstctrl_reg)
return -EINVAL;
rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
mask = 1 << shift;
/* Check the current status to avoid de-asserting the line twice */
if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
return -EEXIST;
/* Clear the reset status by writing 1 to the status bit */
omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
/* de-assert the reset control line */
omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
/* wait the status to be set */
omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
MAX_MODULE_HARDRESET_WAIT, c);
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
void omap4_prm_global_warm_sw_reset(void)
{
u32 v;
v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
OMAP4_RM_RSTCTRL);
v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST,
OMAP4_RM_RSTCTRL);
/* OCP barrier */
v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
OMAP4_RM_RSTCTRL);
}
...@@ -750,16 +750,6 @@ ...@@ -750,16 +750,6 @@
extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx); extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx); extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
extern int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
extern int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
extern void omap4_prm_global_warm_sw_reset(void);
# endif # endif
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* OMAP4 PRM instance functions * OMAP4 PRM instance functions
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley * Paul Walmsley
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -53,7 +54,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) ...@@ -53,7 +54,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
/* Read-modify-write a register in PRM. Caller must lock */ /* Read-modify-write a register in PRM. Caller must lock */
u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
s16 idx) u16 idx)
{ {
u32 v; u32 v;
...@@ -64,3 +65,112 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, ...@@ -64,3 +65,112 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
return v; return v;
} }
/*
* Address offset (in bytes) between the reset control and the reset
* status registers: 4 bytes on OMAP4
*/
#define OMAP4_RST_CTRL_ST_OFFSET 4
/**
* omap4_prminst_is_hardreset_asserted - read the HW reset line state of
* submodules contained in the hwmod module
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to check
*
* Returns 1 if the (sub)module hardreset line is currently asserted,
* 0 if the (sub)module hardreset line is not currently asserted, or
* -EINVAL upon parameter error.
*/
int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs)
{
u32 v;
v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs);
v &= 1 << shift;
v >>= shift;
return v;
}
/**
* omap4_prminst_assert_hardreset - assert the HW reset line of a submodule
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to assert
*
* Some IPs like dsp, ipu or iva contain processors that require an HW
* reset line to be asserted / deasserted in order to fully enable the
* IP. These modules may have multiple hard-reset lines that reset
* different 'submodules' inside the IP block. This function will
* place the submodule into reset. Returns 0 upon success or -EINVAL
* upon an argument error.
*/
int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs)
{
u32 mask = 1 << shift;
omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs);
return 0;
}
/**
* omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
* wait
* @rstctrl_reg: RM_RSTCTRL register address for this module
* @shift: register bit shift corresponding to the reset line to deassert
*
* Some IPs like dsp, ipu or iva contain processors that require an HW
* reset line to be asserted / deasserted in order to fully enable the
* IP. These modules may have multiple hard-reset lines that reset
* different 'submodules' inside the IP block. This function will
* take the submodule out of reset and wait until the PRCM indicates
* that the reset has completed before returning. Returns 0 upon success or
* -EINVAL upon an argument error, -EEXIST if the submodule was already out
* of reset, or -EBUSY if the submodule did not exit reset promptly.
*/
int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs)
{
int c;
u32 mask = 1 << shift;
u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET;
/* Check the current status to avoid de-asserting the line twice */
if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
rstctrl_offs) == 0)
return -EEXIST;
/* Clear the reset status by writing 1 to the status bit */
omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst,
rstst_offs);
/* de-assert the reset control line */
omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
/* wait the status to be set */
omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst,
rstst_offs),
MAX_MODULE_HARDRESET_WAIT, c);
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
void omap4_prminst_global_warm_sw_reset(void)
{
u32 v;
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
OMAP4_PRM_RSTCTRL_OFFSET);
v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
OMAP4_PRM_RSTCTRL_OFFSET);
/* OCP barrier */
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
OMAP4_PRM_RSTCTRL_OFFSET);
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* OMAP4 Power/Reset Management (PRM) function prototypes * OMAP4 Power/Reset Management (PRM) function prototypes
* *
* Copyright (C) 2010 Nokia Corporation * Copyright (C) 2010 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley * Paul Walmsley
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -18,8 +19,15 @@ ...@@ -18,8 +19,15 @@
extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx); extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx);
extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
s16 inst, s16 idx); s16 inst, u16 idx);
extern void omap4_prm_global_warm_sw_reset(void); extern void omap4_prminst_global_warm_sw_reset(void);
extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs);
extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs);
extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
u16 rstctrl_offs);
#endif #endif
...@@ -80,11 +80,11 @@ static struct twl4030_madc_platform_data omap3_madc_pdata = { ...@@ -80,11 +80,11 @@ static struct twl4030_madc_platform_data omap3_madc_pdata = {
.irq_line = 1, .irq_line = 1,
}; };
static struct twl4030_codec_audio_data omap3_audio; static struct twl4030_codec_data omap3_codec;
static struct twl4030_codec_data omap3_codec_pdata = { static struct twl4030_audio_data omap3_audio_pdata = {
.audio_mclk = 26000000, .audio_mclk = 26000000,
.audio = &omap3_audio, .codec = &omap3_codec,
}; };
static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = { static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = {
...@@ -292,8 +292,8 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, ...@@ -292,8 +292,8 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc)
pmic_data->madc = &omap3_madc_pdata; pmic_data->madc = &omap3_madc_pdata;
if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->codec) if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio)
pmic_data->codec = &omap3_codec_pdata; pmic_data->audio = &omap3_audio_pdata;
/* Common regulator configurations */ /* Common regulator configurations */
if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac)
......
...@@ -475,8 +475,41 @@ int __init clk_init(struct clk_functions * custom_clocks) ...@@ -475,8 +475,41 @@ int __init clk_init(struct clk_functions * custom_clocks)
/* /*
* debugfs support to trace clock tree hierarchy and attributes * debugfs support to trace clock tree hierarchy and attributes
*/ */
#include <linux/debugfs.h>
#include <linux/seq_file.h>
static struct dentry *clk_debugfs_root; static struct dentry *clk_debugfs_root;
static int clk_dbg_show_summary(struct seq_file *s, void *unused)
{
struct clk *c;
struct clk *pa;
seq_printf(s, "%-30s %-30s %-10s %s\n",
"clock-name", "parent-name", "rate", "use-count");
list_for_each_entry(c, &clocks, node) {
pa = c->parent;
seq_printf(s, "%-30s %-30s %-10lu %d\n",
c->name, pa ? pa->name : "none", c->rate, c->usecount);
}
return 0;
}
static int clk_dbg_open(struct inode *inode, struct file *file)
{
return single_open(file, clk_dbg_show_summary, inode->i_private);
}
static const struct file_operations debug_clock_fops = {
.open = clk_dbg_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int clk_debugfs_register_one(struct clk *c) static int clk_debugfs_register_one(struct clk *c)
{ {
int err; int err;
...@@ -545,6 +578,12 @@ static int __init clk_debugfs_init(void) ...@@ -545,6 +578,12 @@ static int __init clk_debugfs_init(void)
if (err) if (err)
goto err_out; goto err_out;
} }
d = debugfs_create_file("summary", S_IRUGO,
d, NULL, &debug_clock_fops);
if (!d)
return -ENOMEM;
return 0; return 0;
err_out: err_out:
debugfs_remove_recursive(clk_debugfs_root); debugfs_remove_recursive(clk_debugfs_root);
......
...@@ -407,11 +407,19 @@ ...@@ -407,11 +407,19 @@
#endif #endif
#define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS) #define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
#define TWL6040_CODEC_IRQ_BASE TWL6030_IRQ_END
#ifdef CONFIG_TWL6040_CODEC
#define TWL6040_CODEC_NR_IRQS 6
#else
#define TWL6040_CODEC_NR_IRQS 0
#endif
#define TWL6040_CODEC_IRQ_END (TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS)
/* Total number of interrupts depends on the enabled blocks above */ /* Total number of interrupts depends on the enabled blocks above */
#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END) #if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END)
#define TWL_IRQ_END TWL4030_GPIO_IRQ_END #define TWL_IRQ_END TWL4030_GPIO_IRQ_END
#else #else
#define TWL_IRQ_END TWL6030_IRQ_END #define TWL_IRQ_END TWL6040_CODEC_IRQ_END
#endif #endif
/* GPMC related */ /* GPMC related */
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* omap_hwmod macros, structures * omap_hwmod macros, structures
* *
* Copyright (C) 2009-2011 Nokia Corporation * Copyright (C) 2009-2011 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley * Paul Walmsley
* *
* Created in collaboration with (alphabetical order): Benoît Cousson, * Created in collaboration with (alphabetical order): Benoît Cousson,
...@@ -79,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; ...@@ -79,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_SMART (1 << 2) #define HWMOD_IDLEMODE_SMART (1 << 2)
#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) #define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
/* modulemode control type (SW or HW) */
#define MODULEMODE_HWCTRL 1
#define MODULEMODE_SWCTRL 2
/** /**
* struct omap_hwmod_mux_info - hwmod specific mux configuration * struct omap_hwmod_mux_info - hwmod specific mux configuration
* @pads: array of omap_device_pad entries * @pads: array of omap_device_pad entries
...@@ -360,9 +366,11 @@ struct omap_hwmod_omap2_prcm { ...@@ -360,9 +366,11 @@ struct omap_hwmod_omap2_prcm {
* @submodule_wkdep_bit: bit shift of the WKDEP range * @submodule_wkdep_bit: bit shift of the WKDEP range
*/ */
struct omap_hwmod_omap4_prcm { struct omap_hwmod_omap4_prcm {
void __iomem *clkctrl_reg; u16 clkctrl_offs;
void __iomem *rstctrl_reg; u16 rstctrl_offs;
u16 context_offs;
u8 submodule_wkdep_bit; u8 submodule_wkdep_bit;
u8 modulemode;
}; };
...@@ -515,6 +523,8 @@ struct omap_hwmod { ...@@ -515,6 +523,8 @@ struct omap_hwmod {
const char *main_clk; const char *main_clk;
struct clk *_clk; struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks; struct omap_hwmod_opt_clk *opt_clks;
char *clkdm_name;
struct clockdomain *clkdm;
char *vdd_name; char *vdd_name;
struct voltagedomain *voltdm; struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
......
...@@ -236,56 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) ...@@ -236,56 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
return 0; return 0;
} }
static void _add_clkdev(struct omap_device *od, const char *clk_alias,
const char *clk_name)
{
struct clk *r;
struct clk_lookup *l;
if (!clk_alias || !clk_name)
return;
pr_debug("omap_device: %s: Creating %s -> %s\n",
dev_name(&od->pdev.dev), clk_alias, clk_name);
r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias);
if (!IS_ERR(r)) {
pr_warning("omap_device: %s: alias %s already exists\n",
dev_name(&od->pdev.dev), clk_alias);
clk_put(r);
return;
}
r = omap_clk_get_by_name(clk_name);
if (IS_ERR(r)) {
pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
dev_name(&od->pdev.dev), clk_name);
return;
}
l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev));
if (!l) {
pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
dev_name(&od->pdev.dev), clk_alias);
return;
}
clkdev_add(l);
}
/** /**
* _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks
* and main clock
* @od: struct omap_device *od * @od: struct omap_device *od
* @oh: struct omap_hwmod *oh
* *
* For every optional clock present per hwmod per omap_device, this function * For the main clock and every optional clock present per hwmod per
* adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role> * omap_device, this function adds an entry in the clkdev table of the
* if it does not exist already. * form <dev-id=dev_name, con-id=role> if it does not exist already.
* *
* The function is called from inside omap_device_build_ss(), after * The function is called from inside omap_device_build_ss(), after
* omap_device_register. * omap_device_register.
* *
* This allows drivers to get a pointer to its optional clocks based on its role * This allows drivers to get a pointer to its optional clocks based on its role
* by calling clk_get(<dev*>, <role>). * by calling clk_get(<dev*>, <role>).
* In the case of the main clock, a "fck" alias is used.
* *
* No return value. * No return value.
*/ */
static void _add_optional_clock_clkdev(struct omap_device *od, static void _add_hwmod_clocks_clkdev(struct omap_device *od,
struct omap_hwmod *oh) struct omap_hwmod *oh)
{ {
int i; int i;
for (i = 0; i < oh->opt_clks_cnt; i++) { _add_clkdev(od, "fck", oh->main_clk);
struct omap_hwmod_opt_clk *oc;
struct clk *r;
struct clk_lookup *l;
oc = &oh->opt_clks[i];
if (!oc->_clk)
continue;
r = clk_get_sys(dev_name(&od->pdev.dev), oc->role);
if (!IS_ERR(r))
continue; /* clkdev entry exists */
r = omap_clk_get_by_name((char *)oc->clk); for (i = 0; i < oh->opt_clks_cnt; i++)
if (IS_ERR(r)) { _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
dev_name(&od->pdev.dev), oc->clk);
continue;
}
l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev));
if (!l) {
pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
dev_name(&od->pdev.dev), oc->role);
return;
}
clkdev_add(l);
}
} }
...@@ -492,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, ...@@ -492,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
for (i = 0; i < oh_cnt; i++) { for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od; hwmods[i]->od = od;
_add_optional_clock_clkdev(od, hwmods[i]); _add_hwmod_clocks_clkdev(od, hwmods[i]);
} }
if (ret) if (ret)
......
...@@ -267,7 +267,7 @@ config INPUT_TWL4030_PWRBUTTON ...@@ -267,7 +267,7 @@ config INPUT_TWL4030_PWRBUTTON
config INPUT_TWL4030_VIBRA config INPUT_TWL4030_VIBRA
tristate "Support for TWL4030 Vibrator" tristate "Support for TWL4030 Vibrator"
depends on TWL4030_CORE depends on TWL4030_CORE
select TWL4030_CODEC select MFD_TWL4030_AUDIO
select INPUT_FF_MEMLESS select INPUT_FF_MEMLESS
help help
This option enables support for TWL4030 Vibrator Driver. This option enables support for TWL4030 Vibrator Driver.
...@@ -275,6 +275,17 @@ config INPUT_TWL4030_VIBRA ...@@ -275,6 +275,17 @@ config INPUT_TWL4030_VIBRA
To compile this driver as a module, choose M here. The module will To compile this driver as a module, choose M here. The module will
be called twl4030_vibra. be called twl4030_vibra.
config INPUT_TWL6040_VIBRA
tristate "Support for TWL6040 Vibrator"
depends on TWL4030_CORE
select TWL6040_CORE
select INPUT_FF_MEMLESS
help
This option enables support for TWL6040 Vibrator Driver.
To compile this driver as a module, choose M here. The module will
be called twl6040_vibra.
config INPUT_UINPUT config INPUT_UINPUT
tristate "User level driver support" tristate "User level driver support"
help help
......
...@@ -40,6 +40,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o ...@@ -40,6 +40,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/i2c/twl.h> #include <linux/i2c/twl.h>
#include <linux/mfd/twl4030-codec.h> #include <linux/mfd/twl4030-audio.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -67,7 +67,7 @@ static void vibra_enable(struct vibra_info *info) ...@@ -67,7 +67,7 @@ static void vibra_enable(struct vibra_info *info)
{ {
u8 reg; u8 reg;
twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
/* turn H-Bridge on */ /* turn H-Bridge on */
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
...@@ -75,7 +75,7 @@ static void vibra_enable(struct vibra_info *info) ...@@ -75,7 +75,7 @@ static void vibra_enable(struct vibra_info *info)
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
(reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); twl4030_audio_enable_resource(TWL4030_AUDIO_RES_APLL);
info->enabled = true; info->enabled = true;
} }
...@@ -90,8 +90,8 @@ static void vibra_disable(struct vibra_info *info) ...@@ -90,8 +90,8 @@ static void vibra_disable(struct vibra_info *info)
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
(reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); twl4030_audio_disable_resource(TWL4030_AUDIO_RES_APLL);
twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
info->enabled = false; info->enabled = false;
} }
...@@ -196,7 +196,7 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, ...@@ -196,7 +196,7 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
static int __devinit twl4030_vibra_probe(struct platform_device *pdev) static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
{ {
struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
struct vibra_info *info; struct vibra_info *info;
int ret; int ret;
......
This diff is collapsed.
...@@ -218,7 +218,7 @@ config TWL4030_POWER ...@@ -218,7 +218,7 @@ config TWL4030_POWER
and load scripts controlling which resources are switched off/on and load scripts controlling which resources are switched off/on
or reset when a sleep, wakeup or warm reset event occurs. or reset when a sleep, wakeup or warm reset event occurs.
config TWL4030_CODEC config MFD_TWL4030_AUDIO
bool bool
depends on TWL4030_CORE depends on TWL4030_CORE
select MFD_CORE select MFD_CORE
...@@ -233,6 +233,12 @@ config TWL6030_PWM ...@@ -233,6 +233,12 @@ config TWL6030_PWM
Say yes here if you want support for TWL6030 PWM. Say yes here if you want support for TWL6030 PWM.
This is used to control charging LED brightness. This is used to control charging LED brightness.
config TWL6040_CORE
bool
depends on TWL4030_CORE && GENERIC_HARDIRQS
select MFD_CORE
default n
config MFD_STMPE config MFD_STMPE
bool "Support STMicroelectronics STMPE" bool "Support STMicroelectronics STMPE"
depends on I2C=y && GENERIC_HARDIRQS depends on I2C=y && GENERIC_HARDIRQS
......
...@@ -40,8 +40,9 @@ obj-$(CONFIG_MENELAUS) += menelaus.o ...@@ -40,8 +40,9 @@ obj-$(CONFIG_MENELAUS) += menelaus.o
obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
......
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
#endif #endif
#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ #if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\
defined(CONFIG_SND_SOC_TWL6040) || defined(CONFIG_SND_SOC_TWL6040_MODULE) defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE)
#define twl_has_codec() true #define twl_has_codec() true
#else #else
#define twl_has_codec() false #define twl_has_codec() false
...@@ -815,20 +815,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) ...@@ -815,20 +815,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
return PTR_ERR(child); return PTR_ERR(child);
} }
if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { if (twl_has_codec() && pdata->audio && twl_class_is_4030()) {
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
child = add_child(sub_chip_id, "twl4030-audio", child = add_child(sub_chip_id, "twl4030-audio",
pdata->codec, sizeof(*pdata->codec), pdata->audio, sizeof(*pdata->audio),
false, 0, 0); false, 0, 0);
if (IS_ERR(child)) if (IS_ERR(child))
return PTR_ERR(child); return PTR_ERR(child);
} }
/* Phoenix codec driver is probed directly atm */ if (twl_has_codec() && pdata->audio && twl_class_is_6030()) {
if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
child = add_child(sub_chip_id, "twl6040-codec", child = add_child(sub_chip_id, "twl6040",
pdata->codec, sizeof(*pdata->codec), pdata->audio, sizeof(*pdata->audio),
false, 0, 0); false, 0, 0);
if (IS_ERR(child)) if (IS_ERR(child))
return PTR_ERR(child); return PTR_ERR(child);
......
/* /*
* MFD driver for twl4030 codec submodule * MFD driver for twl4030 audio submodule, which contains an audio codec, and
* the vibra control.
* *
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com> * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
* *
...@@ -29,55 +30,55 @@ ...@@ -29,55 +30,55 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c/twl.h> #include <linux/i2c/twl.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/twl4030-codec.h> #include <linux/mfd/twl4030-audio.h>
#define TWL4030_CODEC_CELLS 2 #define TWL4030_AUDIO_CELLS 2
static struct platform_device *twl4030_codec_dev; static struct platform_device *twl4030_audio_dev;
struct twl4030_codec_resource { struct twl4030_audio_resource {
int request_count; int request_count;
u8 reg; u8 reg;
u8 mask; u8 mask;
}; };
struct twl4030_codec { struct twl4030_audio {
unsigned int audio_mclk; unsigned int audio_mclk;
struct mutex mutex; struct mutex mutex;
struct twl4030_codec_resource resource[TWL4030_CODEC_RES_MAX]; struct twl4030_audio_resource resource[TWL4030_AUDIO_RES_MAX];
struct mfd_cell cells[TWL4030_CODEC_CELLS]; struct mfd_cell cells[TWL4030_AUDIO_CELLS];
}; };
/* /*
* Modify the resource, the function returns the content of the register * Modify the resource, the function returns the content of the register
* after the modification. * after the modification.
*/ */
static int twl4030_codec_set_resource(enum twl4030_codec_res id, int enable) static int twl4030_audio_set_resource(enum twl4030_audio_res id, int enable)
{ {
struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
u8 val; u8 val;
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
codec->resource[id].reg); audio->resource[id].reg);
if (enable) if (enable)
val |= codec->resource[id].mask; val |= audio->resource[id].mask;
else else
val &= ~codec->resource[id].mask; val &= ~audio->resource[id].mask;
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
val, codec->resource[id].reg); val, audio->resource[id].reg);
return val; return val;
} }
static inline int twl4030_codec_get_resource(enum twl4030_codec_res id) static inline int twl4030_audio_get_resource(enum twl4030_audio_res id)
{ {
struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
u8 val; u8 val;
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
codec->resource[id].reg); audio->resource[id].reg);
return val; return val;
} }
...@@ -86,79 +87,79 @@ static inline int twl4030_codec_get_resource(enum twl4030_codec_res id) ...@@ -86,79 +87,79 @@ static inline int twl4030_codec_get_resource(enum twl4030_codec_res id)
* Enable the resource. * Enable the resource.
* The function returns with error or the content of the register * The function returns with error or the content of the register
*/ */
int twl4030_codec_enable_resource(enum twl4030_codec_res id) int twl4030_audio_enable_resource(enum twl4030_audio_res id)
{ {
struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
int val; int val;
if (id >= TWL4030_CODEC_RES_MAX) { if (id >= TWL4030_AUDIO_RES_MAX) {
dev_err(&twl4030_codec_dev->dev, dev_err(&twl4030_audio_dev->dev,
"Invalid resource ID (%u)\n", id); "Invalid resource ID (%u)\n", id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&codec->mutex); mutex_lock(&audio->mutex);
if (!codec->resource[id].request_count) if (!audio->resource[id].request_count)
/* Resource was disabled, enable it */ /* Resource was disabled, enable it */
val = twl4030_codec_set_resource(id, 1); val = twl4030_audio_set_resource(id, 1);
else else
val = twl4030_codec_get_resource(id); val = twl4030_audio_get_resource(id);
codec->resource[id].request_count++; audio->resource[id].request_count++;
mutex_unlock(&codec->mutex); mutex_unlock(&audio->mutex);
return val; return val;
} }
EXPORT_SYMBOL_GPL(twl4030_codec_enable_resource); EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource);
/* /*
* Disable the resource. * Disable the resource.
* The function returns with error or the content of the register * The function returns with error or the content of the register
*/ */
int twl4030_codec_disable_resource(unsigned id) int twl4030_audio_disable_resource(unsigned id)
{ {
struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
int val; int val;
if (id >= TWL4030_CODEC_RES_MAX) { if (id >= TWL4030_AUDIO_RES_MAX) {
dev_err(&twl4030_codec_dev->dev, dev_err(&twl4030_audio_dev->dev,
"Invalid resource ID (%u)\n", id); "Invalid resource ID (%u)\n", id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&codec->mutex); mutex_lock(&audio->mutex);
if (!codec->resource[id].request_count) { if (!audio->resource[id].request_count) {
dev_err(&twl4030_codec_dev->dev, dev_err(&twl4030_audio_dev->dev,
"Resource has been disabled already (%u)\n", id); "Resource has been disabled already (%u)\n", id);
mutex_unlock(&codec->mutex); mutex_unlock(&audio->mutex);
return -EPERM; return -EPERM;
} }
codec->resource[id].request_count--; audio->resource[id].request_count--;
if (!codec->resource[id].request_count) if (!audio->resource[id].request_count)
/* Resource can be disabled now */ /* Resource can be disabled now */
val = twl4030_codec_set_resource(id, 0); val = twl4030_audio_set_resource(id, 0);
else else
val = twl4030_codec_get_resource(id); val = twl4030_audio_get_resource(id);
mutex_unlock(&codec->mutex); mutex_unlock(&audio->mutex);
return val; return val;
} }
EXPORT_SYMBOL_GPL(twl4030_codec_disable_resource); EXPORT_SYMBOL_GPL(twl4030_audio_disable_resource);
unsigned int twl4030_codec_get_mclk(void) unsigned int twl4030_audio_get_mclk(void)
{ {
struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
return codec->audio_mclk; return audio->audio_mclk;
} }
EXPORT_SYMBOL_GPL(twl4030_codec_get_mclk); EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
static int __devinit twl4030_codec_probe(struct platform_device *pdev) static int __devinit twl4030_audio_probe(struct platform_device *pdev)
{ {
struct twl4030_codec *codec; struct twl4030_audio *audio;
struct twl4030_codec_data *pdata = pdev->dev.platform_data; struct twl4030_audio_data *pdata = pdev->dev.platform_data;
struct mfd_cell *cell = NULL; struct mfd_cell *cell = NULL;
int ret, childs = 0; int ret, childs = 0;
u8 val; u8 val;
...@@ -187,33 +188,33 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) ...@@ -187,33 +188,33 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
val, TWL4030_REG_APLL_CTL); val, TWL4030_REG_APLL_CTL);
codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL); audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL);
if (!codec) if (!audio)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, codec); platform_set_drvdata(pdev, audio);
twl4030_codec_dev = pdev; twl4030_audio_dev = pdev;
mutex_init(&codec->mutex); mutex_init(&audio->mutex);
codec->audio_mclk = pdata->audio_mclk; audio->audio_mclk = pdata->audio_mclk;
/* Codec power */ /* Codec power */
codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE; audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ; audio->resource[TWL4030_AUDIO_RES_POWER].mask = TWL4030_CODECPDZ;
/* PLL */ /* PLL */
codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL; audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN; audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
if (pdata->audio) { if (pdata->codec) {
cell = &codec->cells[childs]; cell = &audio->cells[childs];
cell->name = "twl4030-codec"; cell->name = "twl4030-codec";
cell->platform_data = pdata->audio; cell->platform_data = pdata->codec;
cell->pdata_size = sizeof(*pdata->audio); cell->pdata_size = sizeof(*pdata->codec);
childs++; childs++;
} }
if (pdata->vibra) { if (pdata->vibra) {
cell = &codec->cells[childs]; cell = &audio->cells[childs];
cell->name = "twl4030-vibra"; cell->name = "twl4030-vibra";
cell->platform_data = pdata->vibra; cell->platform_data = pdata->vibra;
cell->pdata_size = sizeof(*pdata->vibra); cell->pdata_size = sizeof(*pdata->vibra);
...@@ -221,7 +222,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) ...@@ -221,7 +222,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
} }
if (childs) if (childs)
ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells, ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
childs, NULL, 0); childs, NULL, 0);
else { else {
dev_err(&pdev->dev, "No platform data found for childs\n"); dev_err(&pdev->dev, "No platform data found for childs\n");
...@@ -232,46 +233,45 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) ...@@ -232,46 +233,45 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
return 0; return 0;
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
kfree(codec); kfree(audio);
twl4030_codec_dev = NULL; twl4030_audio_dev = NULL;
return ret; return ret;
} }
static int __devexit twl4030_codec_remove(struct platform_device *pdev) static int __devexit twl4030_audio_remove(struct platform_device *pdev)
{ {
struct twl4030_codec *codec = platform_get_drvdata(pdev); struct twl4030_audio *audio = platform_get_drvdata(pdev);
mfd_remove_devices(&pdev->dev); mfd_remove_devices(&pdev->dev);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
kfree(codec); kfree(audio);
twl4030_codec_dev = NULL; twl4030_audio_dev = NULL;
return 0; return 0;
} }
MODULE_ALIAS("platform:twl4030-audio"); MODULE_ALIAS("platform:twl4030-audio");
static struct platform_driver twl4030_codec_driver = { static struct platform_driver twl4030_audio_driver = {
.probe = twl4030_codec_probe, .probe = twl4030_audio_probe,
.remove = __devexit_p(twl4030_codec_remove), .remove = __devexit_p(twl4030_audio_remove),
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "twl4030-audio", .name = "twl4030-audio",
}, },
}; };
static int __devinit twl4030_codec_init(void) static int __devinit twl4030_audio_init(void)
{ {
return platform_driver_register(&twl4030_codec_driver); return platform_driver_register(&twl4030_audio_driver);
} }
module_init(twl4030_codec_init); module_init(twl4030_audio_init);
static void __devexit twl4030_codec_exit(void) static void __devexit twl4030_audio_exit(void)
{ {
platform_driver_unregister(&twl4030_codec_driver); platform_driver_unregister(&twl4030_audio_driver);
} }
module_exit(twl4030_codec_exit); module_exit(twl4030_audio_exit);
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
This diff is collapsed.
/*
* Interrupt controller support for TWL6040
*
* Author: Misael Lopez Cruz <misael.lopez@ti.com>
*
* Copyright: (C) 2011 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 version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl6040.h>
struct twl6040_irq_data {
int mask;
int status;
};
static struct twl6040_irq_data twl6040_irqs[] = {
{
.mask = TWL6040_THMSK,
.status = TWL6040_THINT,
},
{
.mask = TWL6040_PLUGMSK,
.status = TWL6040_PLUGINT | TWL6040_UNPLUGINT,
},
{
.mask = TWL6040_HOOKMSK,
.status = TWL6040_HOOKINT,
},
{
.mask = TWL6040_HFMSK,
.status = TWL6040_HFINT,
},
{
.mask = TWL6040_VIBMSK,
.status = TWL6040_VIBINT,
},
{
.mask = TWL6040_READYMSK,
.status = TWL6040_READYINT,
},
};
static inline
struct twl6040_irq_data *irq_to_twl6040_irq(struct twl6040 *twl6040,
int irq)
{
return &twl6040_irqs[irq - twl6040->irq_base];
}
static void twl6040_irq_lock(struct irq_data *data)
{
struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data);
mutex_lock(&twl6040->irq_mutex);
}
static void twl6040_irq_sync_unlock(struct irq_data *data)
{
struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data);
/* write back to hardware any change in irq mask */
if (twl6040->irq_masks_cur != twl6040->irq_masks_cache) {
twl6040->irq_masks_cache = twl6040->irq_masks_cur;
twl6040_reg_write(twl6040, TWL6040_REG_INTMR,
twl6040->irq_masks_cur);
}
mutex_unlock(&twl6040->irq_mutex);
}
static void twl6040_irq_enable(struct irq_data *data)
{
struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data);
struct twl6040_irq_data *irq_data = irq_to_twl6040_irq(twl6040,
data->irq);
twl6040->irq_masks_cur &= ~irq_data->mask;
}
static void twl6040_irq_disable(struct irq_data *data)
{
struct twl6040 *twl6040 = irq_data_get_irq_chip_data(data);
struct twl6040_irq_data *irq_data = irq_to_twl6040_irq(twl6040,
data->irq);
twl6040->irq_masks_cur |= irq_data->mask;
}
static struct irq_chip twl6040_irq_chip = {
.name = "twl6040",
.irq_bus_lock = twl6040_irq_lock,
.irq_bus_sync_unlock = twl6040_irq_sync_unlock,
.irq_enable = twl6040_irq_enable,
.irq_disable = twl6040_irq_disable,
};
static irqreturn_t twl6040_irq_thread(int irq, void *data)
{
struct twl6040 *twl6040 = data;
u8 intid;
int i;
intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
/* apply masking and report (backwards to handle READYINT first) */
for (i = ARRAY_SIZE(twl6040_irqs) - 1; i >= 0; i--) {
if (twl6040->irq_masks_cur & twl6040_irqs[i].mask)
intid &= ~twl6040_irqs[i].status;
if (intid & twl6040_irqs[i].status)
handle_nested_irq(twl6040->irq_base + i);
}
/* ack unmasked irqs */
twl6040_reg_write(twl6040, TWL6040_REG_INTID, intid);
return IRQ_HANDLED;
}
int twl6040_irq_init(struct twl6040 *twl6040)
{
int cur_irq, ret;
u8 val;
mutex_init(&twl6040->irq_mutex);
/* mask the individual interrupt sources */
twl6040->irq_masks_cur = TWL6040_ALLINT_MSK;
twl6040->irq_masks_cache = TWL6040_ALLINT_MSK;
twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK);
/* Register them with genirq */
for (cur_irq = twl6040->irq_base;
cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs);
cur_irq++) {
irq_set_chip_data(cur_irq, twl6040);
irq_set_chip_and_handler(cur_irq, &twl6040_irq_chip,
handle_level_irq);
irq_set_nested_thread(cur_irq, 1);
/* ARM needs us to explicitly flag the IRQ as valid
* and will set them noprobe when we do so. */
#ifdef CONFIG_ARM
set_irq_flags(cur_irq, IRQF_VALID);
#else
irq_set_noprobe(cur_irq);
#endif
}
ret = request_threaded_irq(twl6040->irq, NULL, twl6040_irq_thread,
IRQF_ONESHOT, "twl6040", twl6040);
if (ret) {
dev_err(twl6040->dev, "failed to request IRQ %d: %d\n",
twl6040->irq, ret);
return ret;
}
/* reset interrupts */
val = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
/* interrupts cleared on write */
twl6040_clear_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_INTCLRMODE);
return 0;
}
EXPORT_SYMBOL(twl6040_irq_init);
void twl6040_irq_exit(struct twl6040 *twl6040)
{
free_irq(twl6040->irq, twl6040);
}
EXPORT_SYMBOL(twl6040_irq_exit);
...@@ -657,28 +657,41 @@ struct twl4030_power_data { ...@@ -657,28 +657,41 @@ struct twl4030_power_data {
extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
extern int twl4030_remove_script(u8 flags); extern int twl4030_remove_script(u8 flags);
struct twl4030_codec_audio_data { struct twl4030_codec_data {
unsigned int digimic_delay; /* in ms */ unsigned int digimic_delay; /* in ms */
unsigned int ramp_delay_value; unsigned int ramp_delay_value;
unsigned int offset_cncl_path; unsigned int offset_cncl_path;
unsigned int check_defaults:1; unsigned int check_defaults:1;
unsigned int reset_registers:1; unsigned int reset_registers:1;
unsigned int hs_extmute:1; unsigned int hs_extmute:1;
u16 hs_left_step;
u16 hs_right_step;
u16 hf_left_step;
u16 hf_right_step;
void (*set_hs_extmute)(int mute); void (*set_hs_extmute)(int mute);
}; };
struct twl4030_codec_vibra_data { struct twl4030_vibra_data {
unsigned int coexist; unsigned int coexist;
/* twl6040 */
unsigned int vibldrv_res; /* left driver resistance */
unsigned int vibrdrv_res; /* right driver resistance */
unsigned int viblmotor_res; /* left motor resistance */
unsigned int vibrmotor_res; /* right motor resistance */
int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */
int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
}; };
struct twl4030_codec_data { struct twl4030_audio_data {
unsigned int audio_mclk; unsigned int audio_mclk;
struct twl4030_codec_audio_data *audio; struct twl4030_codec_data *codec;
struct twl4030_codec_vibra_data *vibra; struct twl4030_vibra_data *vibra;
/* twl6040 */ /* twl6040 */
int audpwron_gpio; /* audio power-on gpio */ int audpwron_gpio; /* audio power-on gpio */
int naudint_irq; /* audio interrupt */ int naudint_irq; /* audio interrupt */
unsigned int irq_base;
}; };
struct twl4030_platform_data { struct twl4030_platform_data {
...@@ -690,7 +703,7 @@ struct twl4030_platform_data { ...@@ -690,7 +703,7 @@ struct twl4030_platform_data {
struct twl4030_keypad_data *keypad; struct twl4030_keypad_data *keypad;
struct twl4030_usb_data *usb; struct twl4030_usb_data *usb;
struct twl4030_power_data *power; struct twl4030_power_data *power;
struct twl4030_codec_data *codec; struct twl4030_audio_data *audio;
/* Common LDO regulators for TWL4030/TWL6030 */ /* Common LDO regulators for TWL4030/TWL6030 */
struct regulator_init_data *vdac; struct regulator_init_data *vdac;
......
/* /*
* MFD driver for twl4030 codec submodule * MFD driver for twl4030 audio submodule
* *
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com> * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
* *
...@@ -259,14 +259,14 @@ ...@@ -259,14 +259,14 @@
#define TWL4030_VIBRA_DIR_SEL 0x20 #define TWL4030_VIBRA_DIR_SEL 0x20
/* TWL4030 codec resource IDs */ /* TWL4030 codec resource IDs */
enum twl4030_codec_res { enum twl4030_audio_res {
TWL4030_CODEC_RES_POWER = 0, TWL4030_AUDIO_RES_POWER = 0,
TWL4030_CODEC_RES_APLL, TWL4030_AUDIO_RES_APLL,
TWL4030_CODEC_RES_MAX, TWL4030_AUDIO_RES_MAX,
}; };
int twl4030_codec_disable_resource(enum twl4030_codec_res id); int twl4030_audio_disable_resource(enum twl4030_audio_res id);
int twl4030_codec_enable_resource(enum twl4030_codec_res id); int twl4030_audio_enable_resource(enum twl4030_audio_res id);
unsigned int twl4030_codec_get_mclk(void); unsigned int twl4030_audio_get_mclk(void);
#endif /* End of __TWL4030_CODEC_H__ */ #endif /* End of __TWL4030_CODEC_H__ */
/*
* MFD driver for twl6040
*
* Authors: Jorge Eduardo Candelaria <jorge.candelaria@ti.com>
* Misael Lopez Cruz <misael.lopez@ti.com>
*
* Copyright: (C) 2011 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 version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#ifndef __TWL6040_CODEC_H__
#define __TWL6040_CODEC_H__
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#define TWL6040_REG_ASICID 0x01
#define TWL6040_REG_ASICREV 0x02
#define TWL6040_REG_INTID 0x03
#define TWL6040_REG_INTMR 0x04
#define TWL6040_REG_NCPCTL 0x05
#define TWL6040_REG_LDOCTL 0x06
#define TWL6040_REG_HPPLLCTL 0x07
#define TWL6040_REG_LPPLLCTL 0x08
#define TWL6040_REG_LPPLLDIV 0x09
#define TWL6040_REG_AMICBCTL 0x0A
#define TWL6040_REG_DMICBCTL 0x0B
#define TWL6040_REG_MICLCTL 0x0C
#define TWL6040_REG_MICRCTL 0x0D
#define TWL6040_REG_MICGAIN 0x0E
#define TWL6040_REG_LINEGAIN 0x0F
#define TWL6040_REG_HSLCTL 0x10
#define TWL6040_REG_HSRCTL 0x11
#define TWL6040_REG_HSGAIN 0x12
#define TWL6040_REG_EARCTL 0x13
#define TWL6040_REG_HFLCTL 0x14
#define TWL6040_REG_HFLGAIN 0x15
#define TWL6040_REG_HFRCTL 0x16
#define TWL6040_REG_HFRGAIN 0x17
#define TWL6040_REG_VIBCTLL 0x18
#define TWL6040_REG_VIBDATL 0x19
#define TWL6040_REG_VIBCTLR 0x1A
#define TWL6040_REG_VIBDATR 0x1B
#define TWL6040_REG_HKCTL1 0x1C
#define TWL6040_REG_HKCTL2 0x1D
#define TWL6040_REG_GPOCTL 0x1E
#define TWL6040_REG_ALB 0x1F
#define TWL6040_REG_DLB 0x20
#define TWL6040_REG_TRIM1 0x28
#define TWL6040_REG_TRIM2 0x29
#define TWL6040_REG_TRIM3 0x2A
#define TWL6040_REG_HSOTRIM 0x2B
#define TWL6040_REG_HFOTRIM 0x2C
#define TWL6040_REG_ACCCTL 0x2D
#define TWL6040_REG_STATUS 0x2E
#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
#define TWL6040_VIOREGNUM 18
#define TWL6040_VDDREGNUM 21
/* INTID (0x03) fields */
#define TWL6040_THINT 0x01
#define TWL6040_PLUGINT 0x02
#define TWL6040_UNPLUGINT 0x04
#define TWL6040_HOOKINT 0x08
#define TWL6040_HFINT 0x10
#define TWL6040_VIBINT 0x20
#define TWL6040_READYINT 0x40
/* INTMR (0x04) fields */
#define TWL6040_THMSK 0x01
#define TWL6040_PLUGMSK 0x02
#define TWL6040_HOOKMSK 0x08
#define TWL6040_HFMSK 0x10
#define TWL6040_VIBMSK 0x20
#define TWL6040_READYMSK 0x40
#define TWL6040_ALLINT_MSK 0x7B
/* NCPCTL (0x05) fields */
#define TWL6040_NCPENA 0x01
#define TWL6040_NCPOPEN 0x40
/* LDOCTL (0x06) fields */
#define TWL6040_LSLDOENA 0x01
#define TWL6040_HSLDOENA 0x04
#define TWL6040_REFENA 0x40
#define TWL6040_OSCENA 0x80
/* HPPLLCTL (0x07) fields */
#define TWL6040_HPLLENA 0x01
#define TWL6040_HPLLRST 0x02
#define TWL6040_HPLLBP 0x04
#define TWL6040_HPLLSQRENA 0x08
#define TWL6040_MCLK_12000KHZ (0 << 5)
#define TWL6040_MCLK_19200KHZ (1 << 5)
#define TWL6040_MCLK_26000KHZ (2 << 5)
#define TWL6040_MCLK_38400KHZ (3 << 5)
#define TWL6040_MCLK_MSK 0x60
/* LPPLLCTL (0x08) fields */
#define TWL6040_LPLLENA 0x01
#define TWL6040_LPLLRST 0x02
#define TWL6040_LPLLSEL 0x04
#define TWL6040_LPLLFIN 0x08
#define TWL6040_HPLLSEL 0x10
/* HSLCTL (0x10) fields */
#define TWL6040_HSDACMODEL 0x02
#define TWL6040_HSDRVMODEL 0x08
/* HSRCTL (0x11) fields */
#define TWL6040_HSDACMODER 0x02
#define TWL6040_HSDRVMODER 0x08
/* VIBCTLL (0x18) fields */
#define TWL6040_VIBENAL 0x01
#define TWL6040_VIBCTRLL 0x04
#define TWL6040_VIBCTRLLP 0x08
#define TWL6040_VIBCTRLLN 0x10
/* VIBDATL (0x19) fields */
#define TWL6040_VIBDAT_MAX 0x64
/* VIBCTLR (0x1A) fields */
#define TWL6040_VIBENAR 0x01
#define TWL6040_VIBCTRLR 0x04
#define TWL6040_VIBCTRLRP 0x08
#define TWL6040_VIBCTRLRN 0x10
/* GPOCTL (0x1E) fields */
#define TWL6040_GPO1 0x01
#define TWL6040_GPO2 0x02
#define TWL6040_GPO3 0x03
/* ACCCTL (0x2D) fields */
#define TWL6040_I2CSEL 0x01
#define TWL6040_RESETSPLIT 0x04
#define TWL6040_INTCLRMODE 0x08
/* STATUS (0x2E) fields */
#define TWL6040_PLUGCOMP 0x02
#define TWL6040_VIBLOCDET 0x10
#define TWL6040_VIBROCDET 0x20
#define TWL6040_TSHUTDET 0x40
#define TWL6040_CELLS 2
#define TWL6040_REV_ES1_0 0x00
#define TWL6040_REV_ES1_1 0x01
#define TWL6040_REV_ES1_2 0x02
#define TWL6040_IRQ_TH 0
#define TWL6040_IRQ_PLUG 1
#define TWL6040_IRQ_HOOK 2
#define TWL6040_IRQ_HF 3
#define TWL6040_IRQ_VIB 4
#define TWL6040_IRQ_READY 5
/* PLL selection */
#define TWL6040_SYSCLK_SEL_LPPLL 0
#define TWL6040_SYSCLK_SEL_HPPLL 1
struct twl6040 {
struct device *dev;
struct mutex mutex;
struct mutex io_mutex;
struct mutex irq_mutex;
struct mfd_cell cells[TWL6040_CELLS];
struct completion ready;
int audpwron;
int power_count;
int rev;
int pll;
unsigned int sysclk;
unsigned int irq;
unsigned int irq_base;
u8 irq_masks_cur;
u8 irq_masks_cache;
};
int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg);
int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg,
u8 val);
int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg,
u8 mask);
int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg,
u8 mask);
int twl6040_power(struct twl6040 *twl6040, int on);
int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
unsigned int freq_in, unsigned int freq_out);
int twl6040_get_pll(struct twl6040 *twl6040);
unsigned int twl6040_get_sysclk(struct twl6040 *twl6040);
int twl6040_irq_init(struct twl6040 *twl6040);
void twl6040_irq_exit(struct twl6040 *twl6040);
#endif /* End of __TWL6040_CODEC_H__ */
...@@ -250,10 +250,11 @@ config SND_SOC_TLV320DAC33 ...@@ -250,10 +250,11 @@ config SND_SOC_TLV320DAC33
tristate tristate
config SND_SOC_TWL4030 config SND_SOC_TWL4030
select TWL4030_CODEC select MFD_TWL4030_AUDIO
tristate tristate
config SND_SOC_TWL6040 config SND_SOC_TWL6040
select TWL6040_CORE
tristate tristate
config SND_SOC_UDA134X config SND_SOC_UDA134X
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <sound/tlv.h> #include <sound/tlv.h>
/* Register descriptions are here */ /* Register descriptions are here */
#include <linux/mfd/twl4030-codec.h> #include <linux/mfd/twl4030-audio.h>
/* Shadow register used by the audio driver */ /* Shadow register used by the audio driver */
#define TWL4030_REG_SW_SHADOW 0x4A #define TWL4030_REG_SW_SHADOW 0x4A
...@@ -251,9 +251,9 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) ...@@ -251,9 +251,9 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
return; return;
if (enable) if (enable)
mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); mode = twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
else else
mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
if (mode >= 0) { if (mode >= 0) {
twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode); twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
...@@ -297,7 +297,7 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec) ...@@ -297,7 +297,7 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
static void twl4030_init_chip(struct snd_soc_codec *codec) static void twl4030_init_chip(struct snd_soc_codec *codec)
{ {
struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev); struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 reg, byte; u8 reg, byte;
int i = 0; int i = 0;
...@@ -375,13 +375,13 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) ...@@ -375,13 +375,13 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
if (enable) { if (enable) {
twl4030->apll_enabled++; twl4030->apll_enabled++;
if (twl4030->apll_enabled == 1) if (twl4030->apll_enabled == 1)
status = twl4030_codec_enable_resource( status = twl4030_audio_enable_resource(
TWL4030_CODEC_RES_APLL); TWL4030_AUDIO_RES_APLL);
} else { } else {
twl4030->apll_enabled--; twl4030->apll_enabled--;
if (!twl4030->apll_enabled) if (!twl4030->apll_enabled)
status = twl4030_codec_disable_resource( status = twl4030_audio_disable_resource(
TWL4030_CODEC_RES_APLL); TWL4030_AUDIO_RES_APLL);
} }
if (status >= 0) if (status >= 0)
...@@ -732,7 +732,7 @@ static int aif_event(struct snd_soc_dapm_widget *w, ...@@ -732,7 +732,7 @@ static int aif_event(struct snd_soc_dapm_widget *w,
static void headset_ramp(struct snd_soc_codec *codec, int ramp) static void headset_ramp(struct snd_soc_codec *codec, int ramp)
{ {
struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; struct twl4030_codec_data *pdata = codec->dev->platform_data;
unsigned char hs_gain, hs_pop; unsigned char hs_gain, hs_pop;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
/* Base values for ramp delay calculation: 2^19 - 2^26 */ /* Base values for ramp delay calculation: 2^19 - 2^26 */
...@@ -2260,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) ...@@ -2260,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
} }
snd_soc_codec_set_drvdata(codec, twl4030); snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */ /* Set the defaults, and power up the codec */
twl4030->sysclk = twl4030_codec_get_mclk() / 1000; twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
codec->dapm.idle_bias_off = 1; codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec); twl4030_init_chip(codec);
...@@ -2297,7 +2297,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { ...@@ -2297,7 +2297,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
static int __devinit twl4030_codec_probe(struct platform_device *pdev) static int __devinit twl4030_codec_probe(struct platform_device *pdev)
{ {
struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; struct twl4030_codec_data *pdata = pdev->dev.platform_data;
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "platform_data is missing\n"); dev_err(&pdev->dev, "platform_data is missing\n");
......
This diff is collapsed.
This diff is collapsed.
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <plat/mcbsp.h> #include <plat/mcbsp.h>
/* Register descriptions for twl4030 codec part */ /* Register descriptions for twl4030 codec part */
#include <linux/mfd/twl4030-codec.h> #include <linux/mfd/twl4030-audio.h>
#include "omap-mcbsp.h" #include "omap-mcbsp.h"
#include "omap-pcm.h" #include "omap-pcm.h"
......
This diff is collapsed.
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <plat/mcbsp.h> #include <plat/mcbsp.h>
/* Register descriptions for twl4030 codec part */ /* Register descriptions for twl4030 codec part */
#include <linux/mfd/twl4030-codec.h> #include <linux/mfd/twl4030-audio.h>
#include "omap-mcbsp.h" #include "omap-mcbsp.h"
#include "omap-pcm.h" #include "omap-pcm.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment