From 184cddd1e004d3ebd473f9e1ce20dec1d2576fd1 Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Sun, 23 Dec 2012 15:51:40 -0800 Subject: cpufreq: exynos: Remove unused variable & IS_ERR The variable 'max_support_idx, min_support_idx, pm_lock_idx" are never used, so remove the unused variable. Signed-off-by: Jonghwan Choi Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/cpufreq.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-exynos/include/mach/cpufreq.h b/arch/arm/mach-exynos/include/mach/cpufreq.h index 7517c3f417af..39f0dc62122b 100644 --- a/arch/arm/mach-exynos/include/mach/cpufreq.h +++ b/arch/arm/mach-exynos/include/mach/cpufreq.h @@ -21,9 +21,6 @@ enum cpufreq_level_index { struct exynos_dvfs_info { unsigned long mpll_freq_khz; unsigned int pll_safe_idx; - unsigned int pm_lock_idx; - unsigned int max_support_idx; - unsigned int min_support_idx; struct clk *cpu_clk; unsigned int *volt_table; struct cpufreq_frequency_table *freq_table; -- cgit v1.2.3 From 9d0554fff9a21d846adcfbd14cfb02e82773162c Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Sun, 23 Dec 2012 15:57:42 -0800 Subject: cpufreq: exynos: Use APLL_FREQ macro for cpu divider value Signed-off-by: Jonghwan Choi Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/cpufreq.h | 16 ++ drivers/cpufreq/exynos4210-cpufreq.c | 135 ++-------- drivers/cpufreq/exynos4x12-cpufreq.c | 378 +++++----------------------- drivers/cpufreq/exynos5250-cpufreq.c | 168 +++---------- 4 files changed, 136 insertions(+), 561 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-exynos/include/mach/cpufreq.h b/arch/arm/mach-exynos/include/mach/cpufreq.h index 39f0dc62122b..b5d39dd03b2a 100644 --- a/arch/arm/mach-exynos/include/mach/cpufreq.h +++ b/arch/arm/mach-exynos/include/mach/cpufreq.h @@ -18,6 +18,22 @@ enum cpufreq_level_index { L20, }; +#define APLL_FREQ(f, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, m, p, s) \ + { \ + .freq = (f) * 1000, \ + .clk_div_cpu0 = ((a0) | (a1) << 4 | (a2) << 8 | (a3) << 12 | \ + (a4) << 16 | (a5) << 20 | (a6) << 24 | (a7) << 28), \ + .clk_div_cpu1 = (b0 << 0 | b1 << 4 | b2 << 8), \ + .mps = ((m) << 16 | (p) << 8 | (s)), \ + } + +struct apll_freq { + unsigned int freq; + u32 clk_div_cpu0; + u32 clk_div_cpu1; + u32 mps; +}; + struct exynos_dvfs_info { unsigned long mpll_freq_khz; unsigned int pll_safe_idx; diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c index 5ae5c529fca7..250dcf0c0b22 100644 --- a/drivers/cpufreq/exynos4210-cpufreq.c +++ b/drivers/cpufreq/exynos4210-cpufreq.c @@ -20,94 +20,37 @@ #include #include -#define CPUFREQ_LEVEL_END L5 - static struct clk *cpu_clk; static struct clk *moutcore; static struct clk *mout_mpll; static struct clk *mout_apll; -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; -}; - -static unsigned int exynos4210_volt_table[CPUFREQ_LEVEL_END] = { +static unsigned int exynos4210_volt_table[] = { 1250000, 1150000, 1050000, 975000, 950000, }; - -static struct cpufreq_clkdiv exynos4210_clkdiv_table[CPUFREQ_LEVEL_END]; - static struct cpufreq_frequency_table exynos4210_freq_table[] = { - {L0, 1200*1000}, - {L1, 1000*1000}, - {L2, 800*1000}, - {L3, 500*1000}, - {L4, 200*1000}, + {L0, 1200 * 1000}, + {L1, 1000 * 1000}, + {L2, 800 * 1000}, + {L3, 500 * 1000}, + {L4, 200 * 1000}, {0, CPUFREQ_TABLE_END}, }; -static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = { +static struct apll_freq apll_freq_4210[] = { /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL } + * values: + * freq + * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, RESERVED + * clock divider for COPY, HPM, RESERVED + * PLL M, P, S */ - - /* ARM L0: 1200MHz */ - { 0, 3, 7, 3, 4, 1, 7 }, - - /* ARM L1: 1000MHz */ - { 0, 3, 7, 3, 4, 1, 7 }, - - /* ARM L2: 800MHz */ - { 0, 3, 7, 3, 3, 1, 7 }, - - /* ARM L3: 500MHz */ - { 0, 3, 7, 3, 3, 1, 7 }, - - /* ARM L4: 200MHz */ - { 0, 1, 3, 1, 3, 1, 0 }, -}; - -static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = { - /* - * Clock divider value for following - * { DIVCOPY, DIVHPM } - */ - - /* ARM L0: 1200MHz */ - { 5, 0 }, - - /* ARM L1: 1000MHz */ - { 4, 0 }, - - /* ARM L2: 800MHz */ - { 3, 0 }, - - /* ARM L3: 500MHz */ - { 3, 0 }, - - /* ARM L4: 200MHz */ - { 3, 0 }, -}; - -static unsigned int exynos4210_apll_pms_table[CPUFREQ_LEVEL_END] = { - /* APLL FOUT L0: 1200MHz */ - ((150 << 16) | (3 << 8) | 1), - - /* APLL FOUT L1: 1000MHz */ - ((250 << 16) | (6 << 8) | 1), - - /* APLL FOUT L2: 800MHz */ - ((200 << 16) | (6 << 8) | 1), - - /* APLL FOUT L3: 500MHz */ - ((250 << 16) | (6 << 8) | 2), - - /* APLL FOUT L4: 200MHz */ - ((200 << 16) | (6 << 8) | 3), + APLL_FREQ(1200, 0, 3, 7, 3, 4, 1, 7, 0, 5, 0, 0, 150, 3, 1), + APLL_FREQ(1000, 0, 3, 7, 3, 4, 1, 7, 0, 4, 0, 0, 250, 6, 1), + APLL_FREQ(800, 0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 200, 6, 1), + APLL_FREQ(500, 0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 250, 6, 2), + APLL_FREQ(200, 0, 1, 3, 1, 3, 1, 0, 0, 3, 0, 0, 200, 6, 3), }; static void exynos4210_set_clkdiv(unsigned int div_index) @@ -116,7 +59,7 @@ static void exynos4210_set_clkdiv(unsigned int div_index) /* Change Divider - CPU0 */ - tmp = exynos4210_clkdiv_table[div_index].clkdiv; + tmp = apll_freq_4210[div_index].clk_div_cpu0; __raw_writel(tmp, EXYNOS4_CLKDIV_CPU); @@ -126,12 +69,7 @@ static void exynos4210_set_clkdiv(unsigned int div_index) /* Change Divider - CPU1 */ - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1); - - tmp &= ~((0x7 << 4) | 0x7); - - tmp |= ((clkdiv_cpu1[div_index][0] << 4) | - (clkdiv_cpu1[div_index][1] << 0)); + tmp = apll_freq_4210[div_index].clk_div_cpu1; __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1); @@ -159,7 +97,7 @@ static void exynos4210_set_apll(unsigned int index) /* 3. Change PLL PMS values */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos4210_apll_pms_table[index]; + tmp |= apll_freq_4210[index].mps; __raw_writel(tmp, EXYNOS4_APLL_CON0); /* 4. wait_lock_time */ @@ -178,8 +116,8 @@ static void exynos4210_set_apll(unsigned int index) bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index) { - unsigned int old_pm = (exynos4210_apll_pms_table[old_index] >> 8); - unsigned int new_pm = (exynos4210_apll_pms_table[new_index] >> 8); + unsigned int old_pm = apll_freq_4210[old_index].mps >> 8; + unsigned int new_pm = apll_freq_4210[new_index].mps >> 8; return (old_pm == new_pm) ? 0 : 1; } @@ -197,7 +135,7 @@ static void exynos4210_set_frequency(unsigned int old_index, /* 2. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos4210_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_4210[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS4_APLL_CON0); } else { /* Clock Configuration Procedure */ @@ -211,7 +149,7 @@ static void exynos4210_set_frequency(unsigned int old_index, /* 1. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos4210_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_4210[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS4_APLL_CON0); /* 2. Change the system clock divider values */ @@ -228,8 +166,6 @@ static void exynos4210_set_frequency(unsigned int old_index, int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) { - int i; - unsigned int tmp; unsigned long rate; cpu_clk = clk_get(NULL, "armclk"); @@ -250,29 +186,8 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) if (IS_ERR(mout_apll)) goto err_mout_apll; - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU); - - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK | - EXYNOS4_CLKDIV_CPU0_COREM0_MASK | - EXYNOS4_CLKDIV_CPU0_COREM1_MASK | - EXYNOS4_CLKDIV_CPU0_PERIPH_MASK | - EXYNOS4_CLKDIV_CPU0_ATB_MASK | - EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK | - EXYNOS4_CLKDIV_CPU0_APLL_MASK); - - tmp |= ((clkdiv_cpu0[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)); - - exynos4210_clkdiv_table[i].clkdiv = tmp; - } - info->mpll_freq_khz = rate; + /* 800Mhz */ info->pll_safe_idx = L2; info->cpu_clk = cpu_clk; info->volt_table = exynos4210_volt_table; diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 29b41ab072f5..224445d3fd4f 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c @@ -20,23 +20,18 @@ #include #include -#define CPUFREQ_LEVEL_END (L13 + 1) - static struct clk *cpu_clk; static struct clk *moutcore; static struct clk *mout_mpll; static struct clk *mout_apll; -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; - unsigned int clkdiv1; +static unsigned int exynos4x12_volt_table[] = { + 1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500, + 1000000, 987500, 975000, 950000, 925000, 900000, 900000 }; -static unsigned int exynos4x12_volt_table[CPUFREQ_LEVEL_END]; - static struct cpufreq_frequency_table exynos4x12_freq_table[] = { - {L0, 1500 * 1000}, + {L0, CPUFREQ_ENTRY_INVALID}, {L1, 1400 * 1000}, {L2, 1300 * 1000}, {L3, 1200 * 1000}, @@ -53,247 +48,54 @@ static struct cpufreq_frequency_table exynos4x12_freq_table[] = { {0, CPUFREQ_TABLE_END}, }; -static struct cpufreq_clkdiv exynos4x12_clkdiv_table[CPUFREQ_LEVEL_END]; +static struct apll_freq *apll_freq_4x12; -static unsigned int clkdiv_cpu0_4212[CPUFREQ_LEVEL_END][8] = { +static struct apll_freq apll_freq_4212[] = { /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 } + * values: + * freq + * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2 + * clock divider for COPY, HPM, RESERVED + * PLL M, P, S */ - /* ARM L0: 1500 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L1: 1400 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L2: 1300 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L3: 1200 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L4: 1100 MHz */ - { 0, 3, 6, 0, 4, 1, 2, 0 }, - - /* ARM L5: 1000 MHz */ - { 0, 2, 5, 0, 4, 1, 1, 0 }, - - /* ARM L6: 900 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L7: 800 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L8: 700 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L9: 600 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L10: 500 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L11: 400 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L12: 300 MHz */ - { 0, 2, 4, 0, 2, 1, 1, 0 }, - - /* ARM L13: 200 MHz */ - { 0, 1, 3, 0, 1, 1, 1, 0 }, + APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 250, 4, 0), + APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 175, 3, 0), + APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 325, 6, 0), + APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 200, 4, 0), + APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 2, 0, 275, 6, 0), + APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 2, 0, 125, 3, 0), + APLL_FREQ(900, 0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 150, 4, 0), + APLL_FREQ(800, 0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 0), + APLL_FREQ(700, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 175, 3, 1), + APLL_FREQ(600, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 200, 4, 1), + APLL_FREQ(500, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 125, 3, 1), + APLL_FREQ(400, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 1), + APLL_FREQ(300, 0, 2, 4, 0, 2, 1, 1, 0, 3, 2, 0, 200, 4, 2), + APLL_FREQ(200, 0, 1, 3, 0, 1, 1, 1, 0, 3, 2, 0, 100, 3, 2), }; -static unsigned int clkdiv_cpu0_4412[CPUFREQ_LEVEL_END][8] = { +static struct apll_freq apll_freq_4412[] = { /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 } + * values: + * freq + * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2 + * clock divider for COPY, HPM, CORES + * PLL M, P, S */ - /* ARM L0: 1500 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L1: 1400 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L2: 1300 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L3: 1200 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L4: 1100 MHz */ - { 0, 3, 6, 0, 4, 1, 2, 0 }, - - /* ARM L5: 1000 MHz */ - { 0, 2, 5, 0, 4, 1, 1, 0 }, - - /* ARM L6: 900 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L7: 800 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L8: 700 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L9: 600 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L10: 500 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L11: 400 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L12: 300 MHz */ - { 0, 2, 4, 0, 2, 1, 1, 0 }, - - /* ARM L13: 200 MHz */ - { 0, 1, 3, 0, 1, 1, 1, 0 }, -}; - -static unsigned int clkdiv_cpu1_4212[CPUFREQ_LEVEL_END][2] = { - /* Clock divider value for following - * { DIVCOPY, DIVHPM } - */ - /* ARM L0: 1500 MHz */ - { 6, 0 }, - - /* ARM L1: 1400 MHz */ - { 6, 0 }, - - /* ARM L2: 1300 MHz */ - { 5, 0 }, - - /* ARM L3: 1200 MHz */ - { 5, 0 }, - - /* ARM L4: 1100 MHz */ - { 4, 0 }, - - /* ARM L5: 1000 MHz */ - { 4, 0 }, - - /* ARM L6: 900 MHz */ - { 3, 0 }, - - /* ARM L7: 800 MHz */ - { 3, 0 }, - - /* ARM L8: 700 MHz */ - { 3, 0 }, - - /* ARM L9: 600 MHz */ - { 3, 0 }, - - /* ARM L10: 500 MHz */ - { 3, 0 }, - - /* ARM L11: 400 MHz */ - { 3, 0 }, - - /* ARM L12: 300 MHz */ - { 3, 0 }, - - /* ARM L13: 200 MHz */ - { 3, 0 }, -}; - -static unsigned int clkdiv_cpu1_4412[CPUFREQ_LEVEL_END][3] = { - /* Clock divider value for following - * { DIVCOPY, DIVHPM, DIVCORES } - */ - /* ARM L0: 1500 MHz */ - { 6, 0, 7 }, - - /* ARM L1: 1400 MHz */ - { 6, 0, 6 }, - - /* ARM L2: 1300 MHz */ - { 5, 0, 6 }, - - /* ARM L3: 1200 MHz */ - { 5, 0, 5 }, - - /* ARM L4: 1100 MHz */ - { 4, 0, 5 }, - - /* ARM L5: 1000 MHz */ - { 4, 0, 4 }, - - /* ARM L6: 900 MHz */ - { 3, 0, 4 }, - - /* ARM L7: 800 MHz */ - { 3, 0, 3 }, - - /* ARM L8: 700 MHz */ - { 3, 0, 3 }, - - /* ARM L9: 600 MHz */ - { 3, 0, 2 }, - - /* ARM L10: 500 MHz */ - { 3, 0, 2 }, - - /* ARM L11: 400 MHz */ - { 3, 0, 1 }, - - /* ARM L12: 300 MHz */ - { 3, 0, 1 }, - - /* ARM L13: 200 MHz */ - { 3, 0, 0 }, -}; - -static unsigned int exynos4x12_apll_pms_table[CPUFREQ_LEVEL_END] = { - /* APLL FOUT L0: 1500 MHz */ - ((250 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L1: 1400 MHz */ - ((175 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L2: 1300 MHz */ - ((325 << 16) | (6 << 8) | (0x0)), - - /* APLL FOUT L3: 1200 MHz */ - ((200 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L4: 1100 MHz */ - ((275 << 16) | (6 << 8) | (0x0)), - - /* APLL FOUT L5: 1000 MHz */ - ((125 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L6: 900 MHz */ - ((150 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L7: 800 MHz */ - ((100 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L8: 700 MHz */ - ((175 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L9: 600 MHz */ - ((200 << 16) | (4 << 8) | (0x1)), - - /* APLL FOUT L10: 500 MHz */ - ((125 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L11 400 MHz */ - ((100 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L12: 300 MHz */ - ((200 << 16) | (4 << 8) | (0x2)), - - /* APLL FOUT L13: 200 MHz */ - ((100 << 16) | (3 << 8) | (0x2)), -}; - -static const unsigned int asv_voltage_4x12[CPUFREQ_LEVEL_END] = { - 1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500, - 1000000, 987500, 975000, 950000, 925000, 900000, 900000 + APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 7, 250, 4, 0), + APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 6, 175, 3, 0), + APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 6, 325, 6, 0), + APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 5, 200, 4, 0), + APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 0, 5, 275, 6, 0), + APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 0, 4, 125, 3, 0), + APLL_FREQ(900, 0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 4, 150, 4, 0), + APLL_FREQ(800, 0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 3, 100, 3, 0), + APLL_FREQ(700, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 3, 175, 3, 1), + APLL_FREQ(600, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 200, 4, 1), + APLL_FREQ(500, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 125, 3, 1), + APLL_FREQ(400, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 1, 100, 3, 1), + APLL_FREQ(300, 0, 2, 4, 0, 2, 1, 1, 0, 3, 0, 1, 200, 4, 2), + APLL_FREQ(200, 0, 1, 3, 0, 1, 1, 1, 0, 3, 0, 0, 100, 3, 2), }; static void exynos4x12_set_clkdiv(unsigned int div_index) @@ -303,7 +105,7 @@ static void exynos4x12_set_clkdiv(unsigned int div_index) /* Change Divider - CPU0 */ - tmp = exynos4x12_clkdiv_table[div_index].clkdiv; + tmp = apll_freq_4x12[div_index].clk_div_cpu0; __raw_writel(tmp, EXYNOS4_CLKDIV_CPU); @@ -311,7 +113,7 @@ static void exynos4x12_set_clkdiv(unsigned int div_index) cpu_relax(); /* Change Divider - CPU1 */ - tmp = exynos4x12_clkdiv_table[div_index].clkdiv1; + tmp = apll_freq_4x12[div_index].clk_div_cpu1; __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1); if (soc_is_exynos4212()) @@ -338,14 +140,14 @@ static void exynos4x12_set_apll(unsigned int index) } while (tmp != 0x2); /* 2. Set APLL Lock time */ - pdiv = ((exynos4x12_apll_pms_table[index] >> 8) & 0x3f); + pdiv = ((apll_freq_4x12[index].mps >> 8) & 0x3f); __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK); /* 3. Change PLL PMS values */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos4x12_apll_pms_table[index]; + tmp |= apll_freq_4x12[index].mps; __raw_writel(tmp, EXYNOS4_APLL_CON0); /* 4. wait_lock_time */ @@ -366,8 +168,8 @@ static void exynos4x12_set_apll(unsigned int index) bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index) { - unsigned int old_pm = exynos4x12_apll_pms_table[old_index] >> 8; - unsigned int new_pm = exynos4x12_apll_pms_table[new_index] >> 8; + unsigned int old_pm = apll_freq_4x12[old_index].mps >> 8; + unsigned int new_pm = apll_freq_4x12[new_index].mps >> 8; return (old_pm == new_pm) ? 0 : 1; } @@ -384,7 +186,7 @@ static void exynos4x12_set_frequency(unsigned int old_index, /* 2. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_4x12[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS4_APLL_CON0); } else { @@ -399,7 +201,7 @@ static void exynos4x12_set_frequency(unsigned int old_index, /* 1. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS4_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_4x12[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS4_APLL_CON0); /* 2. Change the system clock divider values */ exynos4x12_set_clkdiv(new_index); @@ -413,25 +215,10 @@ static void exynos4x12_set_frequency(unsigned int old_index, } } -static void __init set_volt_table(void) -{ - unsigned int i; - - /* Not supported */ - exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID; - - for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) - exynos4x12_volt_table[i] = asv_voltage_4x12[i]; -} - int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) { - int i; - unsigned int tmp; unsigned long rate; - set_volt_table(); - cpu_clk = clk_get(NULL, "armclk"); if (IS_ERR(cpu_clk)) return PTR_ERR(cpu_clk); @@ -450,62 +237,13 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) if (IS_ERR(mout_apll)) goto err_mout_apll; - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - - exynos4x12_clkdiv_table[i].index = i; - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU); - - tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK | - EXYNOS4_CLKDIV_CPU0_COREM0_MASK | - EXYNOS4_CLKDIV_CPU0_COREM1_MASK | - EXYNOS4_CLKDIV_CPU0_PERIPH_MASK | - EXYNOS4_CLKDIV_CPU0_ATB_MASK | - EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK | - EXYNOS4_CLKDIV_CPU0_APLL_MASK); - - if (soc_is_exynos4212()) { - tmp |= ((clkdiv_cpu0_4212[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0_4212[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0_4212[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0_4212[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0_4212[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0_4212[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0_4212[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)); - } else { - tmp &= ~EXYNOS4_CLKDIV_CPU0_CORE2_MASK; - - tmp |= ((clkdiv_cpu0_4412[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0_4412[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0_4412[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0_4412[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0_4412[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0_4412[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0_4412[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) | - (clkdiv_cpu0_4412[i][7] << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT)); - } - - exynos4x12_clkdiv_table[i].clkdiv = tmp; - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1); - - if (soc_is_exynos4212()) { - tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK | - EXYNOS4_CLKDIV_CPU1_HPM_MASK); - tmp |= ((clkdiv_cpu1_4212[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) | - (clkdiv_cpu1_4212[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT)); - } else { - tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK | - EXYNOS4_CLKDIV_CPU1_HPM_MASK | - EXYNOS4_CLKDIV_CPU1_CORES_MASK); - tmp |= ((clkdiv_cpu1_4412[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) | - (clkdiv_cpu1_4412[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) | - (clkdiv_cpu1_4412[i][2] << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT)); - } - exynos4x12_clkdiv_table[i].clkdiv1 = tmp; - } + if (soc_is_exynos4212()) + apll_freq_4x12 = apll_freq_4212; + else + apll_freq_4x12 = apll_freq_4412; info->mpll_freq_khz = rate; + /* 800Mhz */ info->pll_safe_idx = L7; info->cpu_clk = cpu_clk; info->volt_table = exynos4x12_volt_table; diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 8a5d7338b795..736a5cfdfd17 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c @@ -21,21 +21,18 @@ #include #include -#define CPUFREQ_LEVEL_END (L15 + 1) - static struct clk *cpu_clk; static struct clk *moutcore; static struct clk *mout_mpll; static struct clk *mout_apll; -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; - unsigned int clkdiv1; +static unsigned int exynos5250_volt_table[] = { + 1300000, 1250000, 1225000, 1200000, 1150000, + 1125000, 1100000, 1075000, 1050000, 1025000, + 1012500, 1000000, 975000, 950000, 937500, + 925000 }; -static unsigned int exynos5250_volt_table[CPUFREQ_LEVEL_END]; - static struct cpufreq_frequency_table exynos5250_freq_table[] = { {L0, 1700 * 1000}, {L1, 1600 * 1000}, @@ -45,8 +42,8 @@ static struct cpufreq_frequency_table exynos5250_freq_table[] = { {L5, 1200 * 1000}, {L6, 1100 * 1000}, {L7, 1000 * 1000}, - {L8, 900 * 1000}, - {L9, 800 * 1000}, + {L8, 900 * 1000}, + {L9, 800 * 1000}, {L10, 700 * 1000}, {L11, 600 * 1000}, {L12, 500 * 1000}, @@ -56,78 +53,30 @@ static struct cpufreq_frequency_table exynos5250_freq_table[] = { {0, CPUFREQ_TABLE_END}, }; -static struct cpufreq_clkdiv exynos5250_clkdiv_table[CPUFREQ_LEVEL_END]; - -static unsigned int clkdiv_cpu0_5250[CPUFREQ_LEVEL_END][8] = { +static struct apll_freq apll_freq_5250[] = { /* - * Clock divider value for following - * { ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2 } - */ - { 0, 3, 7, 7, 7, 3, 5, 0 }, /* 1700 MHz */ - { 0, 3, 7, 7, 7, 1, 4, 0 }, /* 1600 MHz */ - { 0, 2, 7, 7, 7, 1, 4, 0 }, /* 1500 MHz */ - { 0, 2, 7, 7, 6, 1, 4, 0 }, /* 1400 MHz */ - { 0, 2, 7, 7, 6, 1, 3, 0 }, /* 1300 MHz */ - { 0, 2, 7, 7, 5, 1, 3, 0 }, /* 1200 MHz */ - { 0, 3, 7, 7, 5, 1, 3, 0 }, /* 1100 MHz */ - { 0, 1, 7, 7, 4, 1, 2, 0 }, /* 1000 MHz */ - { 0, 1, 7, 7, 4, 1, 2, 0 }, /* 900 MHz */ - { 0, 1, 7, 7, 4, 1, 2, 0 }, /* 800 MHz */ - { 0, 1, 7, 7, 3, 1, 1, 0 }, /* 700 MHz */ - { 0, 1, 7, 7, 3, 1, 1, 0 }, /* 600 MHz */ - { 0, 1, 7, 7, 2, 1, 1, 0 }, /* 500 MHz */ - { 0, 1, 7, 7, 2, 1, 1, 0 }, /* 400 MHz */ - { 0, 1, 7, 7, 1, 1, 1, 0 }, /* 300 MHz */ - { 0, 1, 7, 7, 1, 1, 1, 0 }, /* 200 MHz */ -}; - -static unsigned int clkdiv_cpu1_5250[CPUFREQ_LEVEL_END][2] = { - /* Clock divider value for following - * { COPY, HPM } + * values: + * freq + * clock divider for ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2 + * clock divider for COPY, HPM, RESERVED + * PLL M, P, S */ - { 0, 2 }, /* 1700 MHz */ - { 0, 2 }, /* 1600 MHz */ - { 0, 2 }, /* 1500 MHz */ - { 0, 2 }, /* 1400 MHz */ - { 0, 2 }, /* 1300 MHz */ - { 0, 2 }, /* 1200 MHz */ - { 0, 2 }, /* 1100 MHz */ - { 0, 2 }, /* 1000 MHz */ - { 0, 2 }, /* 900 MHz */ - { 0, 2 }, /* 800 MHz */ - { 0, 2 }, /* 700 MHz */ - { 0, 2 }, /* 600 MHz */ - { 0, 2 }, /* 500 MHz */ - { 0, 2 }, /* 400 MHz */ - { 0, 2 }, /* 300 MHz */ - { 0, 2 }, /* 200 MHz */ -}; - -static unsigned int exynos5_apll_pms_table[CPUFREQ_LEVEL_END] = { - ((425 << 16) | (6 << 8) | 0), /* 1700 MHz */ - ((200 << 16) | (3 << 8) | 0), /* 1600 MHz */ - ((250 << 16) | (4 << 8) | 0), /* 1500 MHz */ - ((175 << 16) | (3 << 8) | 0), /* 1400 MHz */ - ((325 << 16) | (6 << 8) | 0), /* 1300 MHz */ - ((200 << 16) | (4 << 8) | 0), /* 1200 MHz */ - ((275 << 16) | (6 << 8) | 0), /* 1100 MHz */ - ((125 << 16) | (3 << 8) | 0), /* 1000 MHz */ - ((150 << 16) | (4 << 8) | 0), /* 900 MHz */ - ((100 << 16) | (3 << 8) | 0), /* 800 MHz */ - ((175 << 16) | (3 << 8) | 1), /* 700 MHz */ - ((200 << 16) | (4 << 8) | 1), /* 600 MHz */ - ((125 << 16) | (3 << 8) | 1), /* 500 MHz */ - ((100 << 16) | (3 << 8) | 1), /* 400 MHz */ - ((200 << 16) | (4 << 8) | 2), /* 300 MHz */ - ((100 << 16) | (3 << 8) | 2), /* 200 MHz */ -}; - -/* ASV group voltage table */ -static const unsigned int asv_voltage_5250[CPUFREQ_LEVEL_END] = { - 1300000, 1250000, 1225000, 1200000, 1150000, - 1125000, 1100000, 1075000, 1050000, 1025000, - 1012500, 1000000, 975000, 950000, 937500, - 925000 + APLL_FREQ(1700, 0, 3, 7, 7, 7, 3, 5, 0, 0, 2, 0, 425, 6, 0), + APLL_FREQ(1600, 0, 3, 7, 7, 7, 1, 4, 0, 0, 2, 0, 200, 3, 0), + APLL_FREQ(1500, 0, 2, 7, 7, 7, 1, 4, 0, 0, 2, 0, 250, 4, 0), + APLL_FREQ(1400, 0, 2, 7, 7, 6, 1, 4, 0, 0, 2, 0, 175, 3, 0), + APLL_FREQ(1300, 0, 2, 7, 7, 6, 1, 3, 0, 0, 2, 0, 325, 6, 0), + APLL_FREQ(1200, 0, 2, 7, 7, 5, 1, 3, 0, 0, 2, 0, 200, 4, 0), + APLL_FREQ(1100, 0, 3, 7, 7, 5, 1, 3, 0, 0, 2, 0, 275, 6, 0), + APLL_FREQ(1000, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 125, 3, 0), + APLL_FREQ(900, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 150, 4, 0), + APLL_FREQ(800, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 100, 3, 0), + APLL_FREQ(700, 0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 175, 3, 1), + APLL_FREQ(600, 0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 200, 4, 1), + APLL_FREQ(500, 0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 125, 3, 1), + APLL_FREQ(400, 0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 100, 3, 1), + APLL_FREQ(300, 0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 200, 4, 2), + APLL_FREQ(200, 0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 100, 3, 2), }; static void set_clkdiv(unsigned int div_index) @@ -136,7 +85,7 @@ static void set_clkdiv(unsigned int div_index) /* Change Divider - CPU0 */ - tmp = exynos5250_clkdiv_table[div_index].clkdiv; + tmp = apll_freq_5250[div_index].clk_div_cpu0; __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0); @@ -144,7 +93,7 @@ static void set_clkdiv(unsigned int div_index) cpu_relax(); /* Change Divider - CPU1 */ - tmp = exynos5250_clkdiv_table[div_index].clkdiv1; + tmp = apll_freq_5250[div_index].clk_div_cpu1; __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1); @@ -167,14 +116,14 @@ static void set_apll(unsigned int new_index, } while (tmp != 0x2); /* 2. Set APLL Lock time */ - pdiv = ((exynos5_apll_pms_table[new_index] >> 8) & 0x3f); + pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f); __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK); /* 3. Change PLL PMS values */ tmp = __raw_readl(EXYNOS5_APLL_CON0); tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos5_apll_pms_table[new_index]; + tmp |= apll_freq_5250[new_index].mps; __raw_writel(tmp, EXYNOS5_APLL_CON0); /* 4. wait_lock_time */ @@ -196,8 +145,8 @@ static void set_apll(unsigned int new_index, bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index) { - unsigned int old_pm = (exynos5_apll_pms_table[old_index] >> 8); - unsigned int new_pm = (exynos5_apll_pms_table[new_index] >> 8); + unsigned int old_pm = apll_freq_5250[old_index].mps >> 8; + unsigned int new_pm = apll_freq_5250[new_index].mps >> 8; return (old_pm == new_pm) ? 0 : 1; } @@ -214,7 +163,7 @@ static void exynos5250_set_frequency(unsigned int old_index, /* 2. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS5_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos5_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_5250[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS5_APLL_CON0); } else { @@ -229,7 +178,7 @@ static void exynos5250_set_frequency(unsigned int old_index, /* 1. Change just s value in apll m,p,s value */ tmp = __raw_readl(EXYNOS5_APLL_CON0); tmp &= ~(0x7 << 0); - tmp |= (exynos5_apll_pms_table[new_index] & 0x7); + tmp |= apll_freq_5250[new_index].mps & 0x7; __raw_writel(tmp, EXYNOS5_APLL_CON0); /* 2. Change the system clock divider values */ set_clkdiv(new_index); @@ -243,22 +192,10 @@ static void exynos5250_set_frequency(unsigned int old_index, } } -static void __init set_volt_table(void) -{ - unsigned int i; - - for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) - exynos5250_volt_table[i] = asv_voltage_5250[i]; -} - int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) { - int i; - unsigned int tmp; unsigned long rate; - set_volt_table(); - cpu_clk = clk_get(NULL, "armclk"); if (IS_ERR(cpu_clk)) return PTR_ERR(cpu_clk); @@ -277,37 +214,6 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) if (IS_ERR(mout_apll)) goto err_mout_apll; - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - - exynos5250_clkdiv_table[i].index = i; - - tmp = __raw_readl(EXYNOS5_CLKDIV_CPU0); - - tmp &= ~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | - (0x7 << 12) | (0x7 << 16) | (0x7 << 20) | - (0x7 << 24) | (0x7 << 28)); - - tmp |= ((clkdiv_cpu0_5250[i][0] << 0) | - (clkdiv_cpu0_5250[i][1] << 4) | - (clkdiv_cpu0_5250[i][2] << 8) | - (clkdiv_cpu0_5250[i][3] << 12) | - (clkdiv_cpu0_5250[i][4] << 16) | - (clkdiv_cpu0_5250[i][5] << 20) | - (clkdiv_cpu0_5250[i][6] << 24) | - (clkdiv_cpu0_5250[i][7] << 28)); - - exynos5250_clkdiv_table[i].clkdiv = tmp; - - tmp = __raw_readl(EXYNOS5_CLKDIV_CPU1); - - tmp &= ~((0x7 << 0) | (0x7 << 4)); - - tmp |= ((clkdiv_cpu1_5250[i][0] << 0) | - (clkdiv_cpu1_5250[i][1] << 4)); - - exynos5250_clkdiv_table[i].clkdiv1 = tmp; - } - info->mpll_freq_khz = rate; /* 800Mhz */ info->pll_safe_idx = L9; -- cgit v1.2.3 From 0947c6dee3f6f334fb3772175152853bd90c86ea Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 20 Dec 2012 01:07:15 +0000 Subject: ACPICA: Update compilation environment settings. This patch does not affect the generation of the Linux binary. This patch decreases 300 lines of 20121018 divergence.diff. This patch updates architecture specific environment settings for compiling ACPICA as such enhancement already has been done in ACPICA. Note that the appended compiler default settings in the will deprecate some of the macros defined in the architecture specific . Thus two of the headers have been cleaned up in this patch accordingly. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- arch/ia64/include/asm/acpi.h | 4 - arch/x86/include/asm/acpi.h | 4 - include/acpi/platform/acenv.h | 217 ++++++++++++++++++++---------------------- include/acpi/platform/acgcc.h | 4 - 4 files changed, 102 insertions(+), 127 deletions(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 359e68a03ca3..faa1bf0da815 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -52,10 +52,6 @@ /* Asm macros */ -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() local_irq_disable() -#define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() static inline int diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 0c44630d1789..b31bf97775fc 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -49,10 +49,6 @@ /* Asm macros */ -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() local_irq_disable() -#define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() int __acpi_acquire_global_lock(unsigned int *lock); diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index e3409b6cefbd..68a58a163fe1 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -44,6 +44,11 @@ #ifndef __ACENV_H__ #define __ACENV_H__ +/* + * Environment configuration. The purpose of this file is to interface ACPICA + * to the local environment. This includes compiler-specific, OS-specific, + * and machine-specific configuration. + */ /* Types for ACPI_MUTEX_TYPE */ #define ACPI_BINARY_SEMAPHORE 0 @@ -99,105 +104,131 @@ #define ACPI_DISASSEMBLER #endif -/* - * Environment configuration. The purpose of this file is to interface to the - * local generation environment. - * - * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library. - * Otherwise, local versions of string/memory functions will be used. - * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and - * the standard header files may be used. - * - * The ACPI subsystem only uses low level C library functions that do not call - * operating system services and may therefore be inlined in the code. - * - * It may be necessary to tailor these include files to the target - * generation environment. - * - * - * Functions and constants used from each header: - * - * string.h: memcpy - * memset - * strcat - * strcmp - * strcpy - * strlen - * strncmp - * strncat - * strncpy - * - * stdlib.h: strtoul - * - * stdarg.h: va_list - * va_arg - * va_start - * va_end - * - */ /*! [Begin] no source code translation */ +/****************************************************************************** + * + * Host configuration files. The compiler configuration files are included + * by the host files. + * + *****************************************************************************/ #if defined(_LINUX) || defined(__linux__) #include -#elif defined(_AED_EFI) -#include "acefi.h" - -#elif defined(WIN32) -#include "acwin.h" - -#elif defined(WIN64) -#include "acwin64.h" - -#elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */ -#include "acdos16.h" - #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include "acfreebsd.h" #elif defined(__NetBSD__) #include "acnetbsd.h" +#elif defined(__sun) +#include "acsolaris.h" + #elif defined(MODESTO) #include "acmodesto.h" #elif defined(NETWARE) #include "acnetware.h" -#elif defined(__sun) -#include "acsolaris.h" +#elif defined(_CYGWIN) +#include "accygwin.h" -#else +#elif defined(WIN32) +#include "acwin.h" + +#elif defined(WIN64) +#include "acwin64.h" -/* All other environments */ +#elif defined(_WRS_LIB_BUILD) +#include "acvxworks.h" -#define ACPI_USE_STANDARD_HEADERS +#elif defined(__OS2__) +#include "acos2.h" -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long +#elif defined(_AED_EFI) +#include "acefi.h" + +#elif defined(__HAIKU__) +#include "achaiku.h" + +#else + +/* Unknown environment */ +#error Unknown target environment #endif /*! [End] no source code translation !*/ /****************************************************************************** * - * Miscellaneous configuration + * Setup defaults for the required symbols that were not defined in one of + * the host/compiler files above. * *****************************************************************************/ +/* 64-bit data types */ + +#ifndef COMPILER_DEPENDENT_INT64 +#define COMPILER_DEPENDENT_INT64 long long +#endif + +#ifndef COMPILER_DEPENDENT_UINT64 +#define COMPILER_DEPENDENT_UINT64 unsigned long long +#endif + /* Type of mutex supported by host. Default is binary semaphores. */ #ifndef ACPI_MUTEX_TYPE #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE #endif +/* Global Lock acquire/release */ + +#ifndef ACPI_ACQUIRE_GLOBAL_LOCK +#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acquired) acquired = 1 +#endif + +#ifndef ACPI_RELEASE_GLOBAL_LOCK +#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, pending) pending = 0 +#endif + +/* Flush CPU cache - used when going to sleep. Wbinvd or similar. */ + +#ifndef ACPI_FLUSH_CPU_CACHE +#define ACPI_FLUSH_CPU_CACHE() +#endif + /* "inline" keywords - configurable since inline is not standardized */ #ifndef ACPI_INLINE #define ACPI_INLINE #endif +/* + * Configurable calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#ifndef ACPI_SYSTEM_XFACE +#define ACPI_SYSTEM_XFACE +#endif + +#ifndef ACPI_EXTERNAL_XFACE +#define ACPI_EXTERNAL_XFACE +#endif + +#ifndef ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#endif + +#ifndef ACPI_INTERNAL_VAR_XFACE +#define ACPI_INTERNAL_VAR_XFACE +#endif + /* * Debugger threading model * Use single threaded if the entire subsystem is contained in an application @@ -223,11 +254,22 @@ #define ACPI_IS_ASCII(c) ((c) < 0x80) -#ifdef ACPI_USE_SYSTEM_CLIBRARY /* - * Use the standard C library headers. - * We want to keep these to a minimum. + * ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library. + * Otherwise, local versions of string/memory functions will be used. + * ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and + * the standard header files may be used. + * + * The ACPICA subsystem only uses low level C library functions that do not call + * operating system services and may therefore be inlined in the code. + * + * It may be necessary to tailor these include files to the target + * generation environment. */ +#ifdef ACPI_USE_SYSTEM_CLIBRARY + +/* Use the standard C library headers. We want to keep these to a minimum. */ + #ifdef ACPI_USE_STANDARD_HEADERS /* Use the standard headers from the standard locations */ #include @@ -290,7 +332,7 @@ typedef char *va_list; /* Variable argument list macro definitions */ #define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) #define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) -#define va_end(ap) (void) 0 +#define va_end(ap) (ap = (va_list) NULL) #define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) #endif /* va_arg */ @@ -314,59 +356,4 @@ typedef char *va_list; #endif /* ACPI_USE_SYSTEM_CLIBRARY */ -/****************************************************************************** - * - * Assembly code macros - * - *****************************************************************************/ - -/* - * Handle platform- and compiler-specific assembly language differences. - * These should already have been defined by the platform includes above. - * - * Notes: - * 1) Interrupt 3 is used to break into a debugger - * 2) Interrupts are turned off during ACPI register setup - */ - -/* Unrecognized compiler, use defaults */ - -#ifndef ACPI_ASM_MACROS - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() -#define ACPI_ENABLE_IRQS() -#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq) -#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq) - -#endif /* ACPI_ASM_MACROS */ - -#ifdef ACPI_APPLICATION - -/* Don't want software interrupts within a ring3 application */ - -#undef BREAKPOINT3 -#define BREAKPOINT3 -#endif - -/****************************************************************************** - * - * Compiler-specific information is contained in the compiler-specific - * headers. - * - *****************************************************************************/ #endif /* __ACENV_H__ */ diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 72553b0c9f33..7433ad10d2a8 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -64,8 +64,4 @@ */ #define ACPI_UNUSED_VAR __attribute__ ((unused)) -#ifdef _ANSI -#define inline -#endif - #endif /* __ACGCC_H__ */ -- cgit v1.2.3 From 3d48aab1d5035fac04fe2fbce63eedc345c0e92e Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 18 Jan 2013 13:45:59 +0000 Subject: x86: add support for Intel Low Power Subsystem We are starting to see traditional SoC peripherals also in the x86 world in chips like Intel Lynxpoint. Typically we already have a Linux driver for the peripheral but it takes advantage of the common clk framework to control and retrieve information about the peripheral clock. So far there hasn't been a standard way on x86 to pass information such as clock rate from whatever the configuration system is used to the driver, but instead different variations have emerged, like adding this information to the platform data. Solve this by adding a new config option X86_INTEL_LPSS. If this is selected we enable common clk framework (and everything else) that is needed to support the Intel LPSS drivers. Enabling common clk framework on x86 was originally proposed by Mark Brown. Signed-off-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- arch/x86/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 79795af59810..c8c9b1403f17 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -454,6 +454,16 @@ config X86_MDFLD endif +config X86_INTEL_LPSS + bool "Intel Low Power Subsystem Support" + depends on ACPI + select COMMON_CLK + ---help--- + Select to build support for Intel Low Power Subsystem such as + found on Intel Lynxpoint PCH. Selecting this option enables + things like clock tree (common clock framework) which are needed + by the LPSS peripheral drivers. + config X86_RDC321X bool "RDC R-321x SoC" depends on X86_32 -- cgit v1.2.3 From 51fac8388a0325a43f0ae67453ece2c373e2ec28 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Jan 2013 00:24:48 +0100 Subject: ACPI: Remove useless type argument of driver .remove() operation The second argument of ACPI driver .remove() operation is only used by the ACPI processor driver and the value passed to that driver through it is always available from the given struct acpi_device object's removal_type field. For this reason, the second ACPI driver .remove() argument is in fact useless, so drop it. Signed-off-by: Rafael J. Wysocki Reviewed-by: Jiang Liu Acked-by: Toshi Kani Acked-by: Yinghai Lu --- arch/ia64/hp/common/aml_nfw.c | 2 +- arch/x86/platform/olpc/olpc-xo15-sci.c | 2 +- drivers/acpi/ac.c | 4 ++-- drivers/acpi/acpi_memhotplug.c | 4 ++-- drivers/acpi/acpi_pad.c | 3 +-- drivers/acpi/battery.c | 2 +- drivers/acpi/button.c | 4 ++-- drivers/acpi/container.c | 4 ++-- drivers/acpi/ec.c | 2 +- drivers/acpi/fan.c | 4 ++-- drivers/acpi/hed.c | 2 +- drivers/acpi/pci_link.c | 4 ++-- drivers/acpi/pci_root.c | 4 ++-- drivers/acpi/processor_driver.c | 6 +++--- drivers/acpi/sbs.c | 6 +++--- drivers/acpi/sbshc.c | 4 ++-- drivers/acpi/scan.c | 5 ++--- drivers/acpi/thermal.c | 4 ++-- drivers/acpi/video.c | 4 ++-- drivers/char/hpet.c | 2 +- drivers/char/sonypi.c | 2 +- drivers/hwmon/acpi_power_meter.c | 2 +- drivers/hwmon/asus_atk0110.c | 4 ++-- drivers/i2c/busses/i2c-scmi.c | 2 +- drivers/input/misc/atlas_btns.c | 2 +- drivers/platform/x86/asus-laptop.c | 2 +- drivers/platform/x86/classmate-laptop.c | 10 +++++----- drivers/platform/x86/eeepc-laptop.c | 2 +- drivers/platform/x86/fujitsu-laptop.c | 4 ++-- drivers/platform/x86/fujitsu-tablet.c | 2 +- drivers/platform/x86/hp_accel.c | 2 +- drivers/platform/x86/ideapad-laptop.c | 2 +- drivers/platform/x86/intel_menlow.c | 2 +- drivers/platform/x86/panasonic-laptop.c | 4 ++-- drivers/platform/x86/sony-laptop.c | 4 ++-- drivers/platform/x86/topstar-laptop.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 4 ++-- drivers/platform/x86/toshiba_bluetooth.c | 4 ++-- drivers/platform/x86/wmi.c | 4 ++-- drivers/platform/x86/xo15-ebook.c | 2 +- drivers/staging/quickstart/quickstart.c | 2 +- drivers/video/backlight/apple_bl.c | 2 +- drivers/xen/xen-acpi-pad.c | 3 +-- include/acpi/acpi_bus.h | 2 +- 44 files changed, 70 insertions(+), 73 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 6192f7188654..916ffe770bcf 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c @@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device) return aml_nfw_add_global_handler(); } -static int aml_nfw_remove(struct acpi_device *device, int type) +static int aml_nfw_remove(struct acpi_device *device) { return aml_nfw_remove_global_handler(); } diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 2fdca25905ae..fef7d0ba7e3a 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -195,7 +195,7 @@ err_sysfs: return r; } -static int xo15_sci_remove(struct acpi_device *device, int type) +static int xo15_sci_remove(struct acpi_device *device) { acpi_disable_gpe(NULL, xo15_sci_gpe); acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d5fdd36190cc..6d5bf649196d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); #endif static int acpi_ac_add(struct acpi_device *device); -static int acpi_ac_remove(struct acpi_device *device, int type); +static int acpi_ac_remove(struct acpi_device *device); static void acpi_ac_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id ac_device_ids[] = { @@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev) } #endif -static int acpi_ac_remove(struct acpi_device *device, int type) +static int acpi_ac_remove(struct acpi_device *device) { struct acpi_ac *ac = NULL; diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 03d18f290118..94c823b25138 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); #define MEMORY_POWER_OFF_STATE 2 static int acpi_memory_device_add(struct acpi_device *device); -static int acpi_memory_device_remove(struct acpi_device *device, int type); +static int acpi_memory_device_remove(struct acpi_device *device); static const struct acpi_device_id memory_device_ids[] = { {ACPI_MEMORY_DEVICE_HID, 0}, @@ -415,7 +415,7 @@ static int acpi_memory_device_add(struct acpi_device *device) return result; } -static int acpi_memory_device_remove(struct acpi_device *device, int type) +static int acpi_memory_device_remove(struct acpi_device *device) { struct acpi_memory_device *mem_device = NULL; int result; diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 16fa979f7180..31de1043eea0 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device) return 0; } -static int acpi_pad_remove(struct acpi_device *device, - int type) +static int acpi_pad_remove(struct acpi_device *device) { mutex_lock(&isolated_cpus_lock); acpi_pad_idle_cpus(0); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 7efaeaa53b88..c5cd5b5513e6 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1111,7 +1111,7 @@ fail: return result; } -static int acpi_battery_remove(struct acpi_device *device, int type) +static int acpi_battery_remove(struct acpi_device *device) { struct acpi_battery *battery = NULL; diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index f0d936b65e37..86c7d5445c38 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = { MODULE_DEVICE_TABLE(acpi, button_device_ids); static int acpi_button_add(struct acpi_device *device); -static int acpi_button_remove(struct acpi_device *device, int type); +static int acpi_button_remove(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); #ifdef CONFIG_PM_SLEEP @@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device) return error; } -static int acpi_button_remove(struct acpi_device *device, int type) +static int acpi_button_remove(struct acpi_device *device) { struct acpi_button *button = acpi_driver_data(device); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index cc79d3e53a39..cc0bf4613e0d 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -52,7 +52,7 @@ MODULE_DESCRIPTION("ACPI container driver"); MODULE_LICENSE("GPL"); static int acpi_container_add(struct acpi_device *device); -static int acpi_container_remove(struct acpi_device *device, int type); +static int acpi_container_remove(struct acpi_device *device); static const struct acpi_device_id container_device_ids[] = { {"ACPI0004", 0}, @@ -125,7 +125,7 @@ static int acpi_container_add(struct acpi_device *device) return 0; } -static int acpi_container_remove(struct acpi_device *device, int type) +static int acpi_container_remove(struct acpi_device *device) { acpi_status status = AE_OK; struct acpi_container *pc = NULL; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 354007d490d1..d45b2871d33b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device) return ret; } -static int acpi_ec_remove(struct acpi_device *device, int type) +static int acpi_ec_remove(struct acpi_device *device) { struct acpi_ec *ec; struct acpi_ec_query_handler *handler, *tmp; diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 3bd6a54702d6..f815da82c765 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver"); MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); -static int acpi_fan_remove(struct acpi_device *device, int type); +static int acpi_fan_remove(struct acpi_device *device); static const struct acpi_device_id fan_device_ids[] = { {"PNP0C0B", 0}, @@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device) return result; } -static int acpi_fan_remove(struct acpi_device *device, int type) +static int acpi_fan_remove(struct acpi_device *device) { struct thermal_cooling_device *cdev = acpi_driver_data(device); diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index a0cc796932f7..13b1d39d7cdf 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c @@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device) return 0; } -static int acpi_hed_remove(struct acpi_device *device, int type) +static int acpi_hed_remove(struct acpi_device *device) { hed_handle = NULL; return 0; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index a12808259dfb..b6592797f5b2 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -54,7 +54,7 @@ ACPI_MODULE_NAME("pci_link"); #define ACPI_PCI_LINK_MAX_POSSIBLE 16 static int acpi_pci_link_add(struct acpi_device *device); -static int acpi_pci_link_remove(struct acpi_device *device, int type); +static int acpi_pci_link_remove(struct acpi_device *device); static const struct acpi_device_id link_device_ids[] = { {"PNP0C0F", 0}, @@ -766,7 +766,7 @@ static void irqrouter_resume(void) } } -static int acpi_pci_link_remove(struct acpi_device *device, int type) +static int acpi_pci_link_remove(struct acpi_device *device) { struct acpi_pci_link *link; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 22a8458b4ec9..8890775e8b25 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -46,7 +46,7 @@ ACPI_MODULE_NAME("pci_root"); #define ACPI_PCI_ROOT_CLASS "pci_bridge" #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" static int acpi_pci_root_add(struct acpi_device *device); -static int acpi_pci_root_remove(struct acpi_device *device, int type); +static int acpi_pci_root_remove(struct acpi_device *device); #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | OSC_ACTIVE_STATE_PWR_SUPPORT \ @@ -627,7 +627,7 @@ end: return result; } -static int acpi_pci_root_remove(struct acpi_device *device, int type) +static int acpi_pci_root_remove(struct acpi_device *device) { acpi_status status; acpi_handle handle; diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9c5929a17d3a..c5d2fd85dbe0 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); MODULE_LICENSE("GPL"); static int acpi_processor_add(struct acpi_device *device); -static int acpi_processor_remove(struct acpi_device *device, int type); +static int acpi_processor_remove(struct acpi_device *device); static void acpi_processor_notify(struct acpi_device *device, u32 event); static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr); @@ -610,7 +610,7 @@ err_free_pr: return result; } -static int acpi_processor_remove(struct acpi_device *device, int type) +static int acpi_processor_remove(struct acpi_device *device) { struct acpi_processor *pr = NULL; @@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) if (pr->id >= nr_cpu_ids) goto free; - if (type == ACPI_BUS_REMOVAL_EJECT) { + if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) { if (acpi_processor_handle_eject(pr)) return -EINVAL; } diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index ff0740e0a9c2..e523245643ac 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -130,7 +130,7 @@ struct acpi_sbs { #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) -static int acpi_sbs_remove(struct acpi_device *device, int type); +static int acpi_sbs_remove(struct acpi_device *device); static int acpi_battery_get_state(struct acpi_battery *battery); static inline int battery_scale(int log) @@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device) acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); end: if (result) - acpi_sbs_remove(device, 0); + acpi_sbs_remove(device); return result; } -static int acpi_sbs_remove(struct acpi_device *device, int type) +static int acpi_sbs_remove(struct acpi_device *device) { struct acpi_sbs *sbs; int id; diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index cf6129a8af7c..b78bc605837e 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -33,7 +33,7 @@ struct acpi_smb_hc { }; static int acpi_smbus_hc_add(struct acpi_device *device); -static int acpi_smbus_hc_remove(struct acpi_device *device, int type); +static int acpi_smbus_hc_remove(struct acpi_device *device); static const struct acpi_device_id sbs_device_ids[] = { {"ACPI0001", 0}, @@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); -static int acpi_smbus_hc_remove(struct acpi_device *device, int type) +static int acpi_smbus_hc_remove(struct acpi_device *device) { struct acpi_smb_hc *hc; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bc8077f173da..0989b323e65f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -577,8 +577,7 @@ static int acpi_device_probe(struct device * dev) ret = acpi_device_install_notify_handler(acpi_dev); if (ret) { if (acpi_drv->ops.remove) - acpi_drv->ops.remove(acpi_dev, - acpi_dev->removal_type); + acpi_drv->ops.remove(acpi_dev); return ret; } } @@ -600,7 +599,7 @@ static int acpi_device_remove(struct device * dev) if (acpi_drv->ops.notify) acpi_device_remove_notify_handler(acpi_dev); if (acpi_drv->ops.remove) - acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); + acpi_drv->ops.remove(acpi_dev); } acpi_dev->driver = NULL; acpi_dev->driver_data = NULL; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 506fbd4b5733..da079d4e0baa 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -97,7 +97,7 @@ module_param(psv, int, 0644); MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); -static int acpi_thermal_remove(struct acpi_device *device, int type); +static int acpi_thermal_remove(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id thermal_device_ids[] = { @@ -1111,7 +1111,7 @@ end: return result; } -static int acpi_thermal_remove(struct acpi_device *device, int type) +static int acpi_thermal_remove(struct acpi_device *device) { struct acpi_thermal *tz = NULL; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index ac9a69cd45f5..5be60ad8381f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644); static int register_count = 0; static int acpi_video_bus_add(struct acpi_device *device); -static int acpi_video_bus_remove(struct acpi_device *device, int type); +static int acpi_video_bus_remove(struct acpi_device *device); static void acpi_video_bus_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id video_device_ids[] = { @@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device) return error; } -static int acpi_video_bus_remove(struct acpi_device *device, int type) +static int acpi_video_bus_remove(struct acpi_device *device) { struct acpi_video_bus *video = NULL; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index fe6d4be48296..e3f9a99b8522 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device) return hpet_alloc(&data); } -static int hpet_acpi_remove(struct acpi_device *device, int type) +static int hpet_acpi_remove(struct acpi_device *device) { /* XXX need to unregister clocksource, dealloc mem, etc */ return -EINVAL; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index d780295a1473..6386a98e43c1 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device) return 0; } -static int sonypi_acpi_remove(struct acpi_device *device, int type) +static int sonypi_acpi_remove(struct acpi_device *device) { sonypi_acpi_device = NULL; return 0; diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 1672e2a5db46..6351aba8819c 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -911,7 +911,7 @@ exit: return res; } -static int acpi_power_meter_remove(struct acpi_device *device, int type) +static int acpi_power_meter_remove(struct acpi_device *device) { struct acpi_power_meter_resource *resource; diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 56dbcfb3e301..b25c64302cbc 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -190,7 +190,7 @@ struct atk_acpi_input_buf { }; static int atk_add(struct acpi_device *device); -static int atk_remove(struct acpi_device *device, int type); +static int atk_remove(struct acpi_device *device); static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); static void atk_free_sensors(struct atk_data *data); @@ -1416,7 +1416,7 @@ out: return err; } -static int atk_remove(struct acpi_device *device, int type) +static int atk_remove(struct acpi_device *device) { struct atk_data *data = device->driver_data; dev_dbg(&device->dev, "removing...\n"); diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 6aafa3d88ff0..c447e8d40b78 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -406,7 +406,7 @@ err: return -EIO; } -static int acpi_smbus_cmi_remove(struct acpi_device *device, int type) +static int acpi_smbus_cmi_remove(struct acpi_device *device) { struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device); diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 26f13131639a..5d4402365a52 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) return err; } -static int atlas_acpi_button_remove(struct acpi_device *device, int type) +static int atlas_acpi_button_remove(struct acpi_device *device) { acpi_status status; diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index fcde4e528819..d9f9a0dbc6f3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1910,7 +1910,7 @@ fail_platform: return result; } -static int asus_acpi_remove(struct acpi_device *device, int type) +static int asus_acpi_remove(struct acpi_device *device) { struct asus_laptop *asus = acpi_driver_data(device); diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index c87ff16873f9..36e5e6c13db4 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -432,7 +432,7 @@ failed_sensitivity: return error; } -static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type) +static int cmpc_accel_remove_v4(struct acpi_device *acpi) { struct input_dev *inputdev; struct cmpc_accel *accel; @@ -668,7 +668,7 @@ failed_file: return error; } -static int cmpc_accel_remove(struct acpi_device *acpi, int type) +static int cmpc_accel_remove(struct acpi_device *acpi) { struct input_dev *inputdev; struct cmpc_accel *accel; @@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi) cmpc_tablet_idev_init); } -static int cmpc_tablet_remove(struct acpi_device *acpi, int type) +static int cmpc_tablet_remove(struct acpi_device *acpi) { return cmpc_remove_acpi_notify_device(acpi); } @@ -1000,7 +1000,7 @@ out_bd: return retval; } -static int cmpc_ipml_remove(struct acpi_device *acpi, int type) +static int cmpc_ipml_remove(struct acpi_device *acpi) { struct ipml200_dev *ipml; @@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi) cmpc_keys_idev_init); } -static int cmpc_keys_remove(struct acpi_device *acpi, int type) +static int cmpc_keys_remove(struct acpi_device *acpi) { return cmpc_remove_acpi_notify_device(acpi); } diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 528e9495458d..98935f945f53 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1501,7 +1501,7 @@ fail_platform: return result; } -static int eeepc_acpi_remove(struct acpi_device *device, int type) +static int eeepc_acpi_remove(struct acpi_device *device) { struct eeepc_laptop *eeepc = acpi_driver_data(device); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index c4c1a5444b38..1c9386e7c58c 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -733,7 +733,7 @@ err_stop: return result; } -static int acpi_fujitsu_remove(struct acpi_device *device, int type) +static int acpi_fujitsu_remove(struct acpi_device *device) { struct fujitsu_t *fujitsu = acpi_driver_data(device); struct input_dev *input = fujitsu->input; @@ -938,7 +938,7 @@ err_stop: return result; } -static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) +static int acpi_fujitsu_hotkey_remove(struct acpi_device *device) { struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); struct input_dev *input = fujitsu_hotkey->input; diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index 174ca01c4aa7..570926c10014 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c @@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev) return 0; } -static int acpi_fujitsu_remove(struct acpi_device *adev, int type) +static int acpi_fujitsu_remove(struct acpi_device *adev) { free_irq(fujitsu.irq, fujitsu_interrupt); release_region(fujitsu.io_base, fujitsu.io_length); diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 18d74f29dcb2..e64a7a870d42 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device) return ret; } -static int lis3lv02d_remove(struct acpi_device *device, int type) +static int lis3lv02d_remove(struct acpi_device *device) { if (!device) return -EINVAL; diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 64bfb30a52e9..17f00b8dc5cb 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -834,7 +834,7 @@ platform_failed: return ret; } -static int ideapad_acpi_remove(struct acpi_device *adevice, int type) +static int ideapad_acpi_remove(struct acpi_device *adevice) { struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); int i; diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 3271ac85115e..d6cfc1558c2f 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) } -static int intel_menlow_memory_remove(struct acpi_device *device, int type) +static int intel_menlow_memory_remove(struct acpi_device *device) { struct thermal_cooling_device *cdev = acpi_driver_data(device); diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 8e8caa767d6a..4add9a31bf60 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ static int acpi_pcc_hotkey_add(struct acpi_device *device); -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); +static int acpi_pcc_hotkey_remove(struct acpi_device *device); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id pcc_device_ids[] = { @@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void) return 0; } -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) +static int acpi_pcc_hotkey_remove(struct acpi_device *device) { struct pcc_acpi *pcc = acpi_driver_data(device); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b8ad71f7863f..ceb41eff4230 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2740,7 +2740,7 @@ outwalk: return result; } -static int sony_nc_remove(struct acpi_device *device, int type) +static int sony_nc_remove(struct acpi_device *device) { struct sony_nc_value *item; @@ -4111,7 +4111,7 @@ found: * ACPI driver * *****************/ -static int sony_pic_remove(struct acpi_device *device, int type) +static int sony_pic_remove(struct acpi_device *device) { struct sony_pic_ioport *io, *tmp_io; struct sony_pic_irq *irq, *tmp_irq; diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index d727bfee89a6..4ab618c63b45 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -157,7 +157,7 @@ add_err: return -ENODEV; } -static int acpi_topstar_remove(struct acpi_device *device, int type) +static int acpi_topstar_remove(struct acpi_device *device) { struct topstar_hkey *tps_hkey = acpi_driver_data(device); diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c2727895794c..904476b2fa8f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) return 0; } -static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) +static int toshiba_acpi_remove(struct acpi_device *acpi_dev) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); @@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) return 0; error: - toshiba_acpi_remove(acpi_dev, 0); + toshiba_acpi_remove(acpi_dev); return ret; } diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index e95be0b74859..74dd01ae343b 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); static int toshiba_bt_rfkill_add(struct acpi_device *device); -static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); +static int toshiba_bt_rfkill_remove(struct acpi_device *device); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id bt_device_ids[] = { @@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) return result; } -static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) +static int toshiba_bt_rfkill_remove(struct acpi_device *device) { /* clean up */ return 0; diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 42a4dcc25f92..e4ac38aca580 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444); MODULE_PARM_DESC(debug_dump_wdg, "Dump available WMI interfaces [0/1]"); -static int acpi_wmi_remove(struct acpi_device *device, int type); +static int acpi_wmi_remove(struct acpi_device *device); static int acpi_wmi_add(struct acpi_device *device); static void acpi_wmi_notify(struct acpi_device *device, u32 event); @@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) } } -static int acpi_wmi_remove(struct acpi_device *device, int type) +static int acpi_wmi_remove(struct acpi_device *device) { acpi_remove_address_space_handler(device->handle, ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 16d340c3b852..4b1377bd5944 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c @@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device) return error; } -static int ebook_switch_remove(struct acpi_device *device, int type) +static int ebook_switch_remove(struct acpi_device *device) { struct ebook_switch *button = acpi_driver_data(device); diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index cac320738142..adb8da564cf6 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -296,7 +296,7 @@ fail_config: return ret; } -static int quickstart_acpi_remove(struct acpi_device *device, int type) +static int quickstart_acpi_remove(struct acpi_device *device) { acpi_status status; struct quickstart_acpi *quickstart; diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c index f088d4c07381..d84329676689 100644 --- a/drivers/video/backlight/apple_bl.c +++ b/drivers/video/backlight/apple_bl.c @@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev) return 0; } -static int apple_bl_remove(struct acpi_device *dev, int type) +static int apple_bl_remove(struct acpi_device *dev) { backlight_device_unregister(apple_backlight_device); diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index da39191e7278..c763479ed85e 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c @@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device) return 0; } -static int acpi_pad_remove(struct acpi_device *device, - int type) +static int acpi_pad_remove(struct acpi_device *device) { mutex_lock(&xen_cpu_lock); xen_acpi_pad_idle_cpus(0); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 2c722deb2490..7714a1c2bbc5 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -89,7 +89,7 @@ struct acpi_device; */ typedef int (*acpi_op_add) (struct acpi_device * device); -typedef int (*acpi_op_remove) (struct acpi_device * device, int type); +typedef int (*acpi_op_remove) (struct acpi_device * device); typedef int (*acpi_op_start) (struct acpi_device * device); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); -- cgit v1.2.3 From 43720bd6014327ac454434496cb953edcdb9f8d6 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 11 Jan 2013 13:43:45 +0100 Subject: PM / tracing: remove deprecated power trace API The text in Documentation said it would be removed in 2.6.41; the text in the Kconfig said removal in the 3.1 release. Either way you look at it, we are well past both, so push it off a cliff. Note that the POWER_CSTATE and the POWER_PSTATE are part of the legacy tracing API. Remove all tracepoints which use these flags. As can be seen from context, most already have a trace entry via trace_cpu_idle anyways. Also, the cpufreq/cpufreq.c PSTATE one is actually unpaired, as compared to the CSTATE ones which all have a clear start/stop. As part of this, the trace_power_frequency also becomes orphaned, so it too is deleted. Signed-off-by: Paul Gortmaker Acked-by: Steven Rostedt Signed-off-by: Rafael J. Wysocki --- Documentation/trace/events-power.txt | 27 +---------- arch/arm/mach-omap2/pm34xx.c | 2 - arch/x86/kernel/process.c | 6 --- drivers/cpufreq/cpufreq.c | 1 - drivers/cpuidle/cpuidle.c | 2 - include/trace/events/power.h | 92 ------------------------------------ kernel/trace/Kconfig | 15 ------ kernel/trace/power-traces.c | 3 -- 8 files changed, 1 insertion(+), 147 deletions(-) (limited to 'arch') diff --git a/Documentation/trace/events-power.txt b/Documentation/trace/events-power.txt index cf794af22855..e1498ff8cf94 100644 --- a/Documentation/trace/events-power.txt +++ b/Documentation/trace/events-power.txt @@ -17,7 +17,7 @@ Cf. include/trace/events/power.h for the events definitions. 1. Power state switch events ============================ -1.1 New trace API +1.1 Trace API ----------------- A 'cpu' event class gathers the CPU-related events: cpuidle and @@ -41,31 +41,6 @@ The event which has 'state=4294967295' in the trace is very important to the use space tools which are using it to detect the end of the current state, and so to correctly draw the states diagrams and to calculate accurate statistics etc. -1.2 DEPRECATED trace API ------------------------- - -A new Kconfig option CONFIG_EVENT_POWER_TRACING_DEPRECATED with the default value of -'y' has been created. This allows the legacy trace power API to be used conjointly -with the new trace API. -The Kconfig option, the old trace API (in include/trace/events/power.h) and the -old trace points will disappear in a future release (namely 2.6.41). - -power_start "type=%lu state=%lu cpu_id=%lu" -power_frequency "type=%lu state=%lu cpu_id=%lu" -power_end "cpu_id=%lu" - -The 'type' parameter takes one of those macros: - . POWER_NONE = 0, - . POWER_CSTATE = 1, /* C-State */ - . POWER_PSTATE = 2, /* Frequency change or DVFS */ - -The 'state' parameter is set depending on the type: - . Target C-state for type=POWER_CSTATE, - . Target frequency for type=POWER_PSTATE, - -power_end is used to indicate the exit of a state, corresponding to the latest -power_start event. - 2. Clocks events ================ The clock events are used for clock enable/disable and for diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7be3622cfc85..2d93d8b23835 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -351,12 +351,10 @@ static void omap3_pm_idle(void) if (omap_irq_pending()) goto out; - trace_power_start(POWER_CSTATE, 1, smp_processor_id()); trace_cpu_idle(1, smp_processor_id()); omap_sram_idle(); - trace_power_end(smp_processor_id()); trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); out: diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2ed787f15bf0..dcfc1f410dc4 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -375,7 +375,6 @@ void cpu_idle(void) */ void default_idle(void) { - trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id()); trace_cpu_idle_rcuidle(1, smp_processor_id()); current_thread_info()->status &= ~TS_POLLING; /* @@ -389,7 +388,6 @@ void default_idle(void) else local_irq_enable(); current_thread_info()->status |= TS_POLLING; - trace_power_end_rcuidle(smp_processor_id()); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } #ifdef CONFIG_APM_MODULE @@ -423,7 +421,6 @@ void stop_this_cpu(void *dummy) static void mwait_idle(void) { if (!need_resched()) { - trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id()); trace_cpu_idle_rcuidle(1, smp_processor_id()); if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) clflush((void *)¤t_thread_info()->flags); @@ -434,7 +431,6 @@ static void mwait_idle(void) __sti_mwait(0, 0); else local_irq_enable(); - trace_power_end_rcuidle(smp_processor_id()); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } else local_irq_enable(); @@ -447,12 +443,10 @@ static void mwait_idle(void) */ static void poll_idle(void) { - trace_power_start_rcuidle(POWER_CSTATE, 0, smp_processor_id()); trace_cpu_idle_rcuidle(0, smp_processor_id()); local_irq_enable(); while (!need_resched()) cpu_relax(); - trace_power_end_rcuidle(smp_processor_id()); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1f93dbd72355..99faadf454ec 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -294,7 +294,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, (unsigned long)freqs->cpu); - trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu); trace_cpu_frequency(freqs->new, freqs->cpu); srcu_notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index e1f6860e069c..eba69290e074 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -144,7 +144,6 @@ int cpuidle_idle_call(void) return 0; } - trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu); trace_cpu_idle_rcuidle(next_state, dev->cpu); if (cpuidle_state_is_coupled(dev, drv, next_state)) @@ -153,7 +152,6 @@ int cpuidle_idle_call(void) else entered_state = cpuidle_enter_state(dev, drv, next_state); - trace_power_end_rcuidle(dev->cpu); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); /* give the governor an opportunity to reflect on the outcome */ diff --git a/include/trace/events/power.h b/include/trace/events/power.h index 0c9783841a30..427acab5d69a 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -99,98 +99,6 @@ DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, TP_ARGS(name, state) ); -#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED - -/* - * The power events are used for cpuidle & suspend (power_start, power_end) - * and for cpufreq (power_frequency) - */ -DECLARE_EVENT_CLASS(power, - - TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), - - TP_ARGS(type, state, cpu_id), - - TP_STRUCT__entry( - __field( u64, type ) - __field( u64, state ) - __field( u64, cpu_id ) - ), - - TP_fast_assign( - __entry->type = type; - __entry->state = state; - __entry->cpu_id = cpu_id; - ), - - TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, - (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) -); - -DEFINE_EVENT(power, power_start, - - TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), - - TP_ARGS(type, state, cpu_id) -); - -DEFINE_EVENT(power, power_frequency, - - TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), - - TP_ARGS(type, state, cpu_id) -); - -TRACE_EVENT(power_end, - - TP_PROTO(unsigned int cpu_id), - - TP_ARGS(cpu_id), - - TP_STRUCT__entry( - __field( u64, cpu_id ) - ), - - TP_fast_assign( - __entry->cpu_id = cpu_id; - ), - - TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) - -); - -/* Deprecated dummy functions must be protected against multi-declartion */ -#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED -#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED - -enum { - POWER_NONE = 0, - POWER_CSTATE = 1, - POWER_PSTATE = 2, -}; -#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ - -#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ - -#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED -#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED -enum { - POWER_NONE = 0, - POWER_CSTATE = 1, - POWER_PSTATE = 2, -}; - -/* These dummy declaration have to be ripped out when the deprecated - events get removed */ -static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; -static inline void trace_power_end(u64 cpuid) {}; -static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {}; -static inline void trace_power_end_rcuidle(u64 cpuid) {}; -static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; -#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ - -#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ - /* * The clock events are used for clock enable/disable and for * clock rate change diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 5d89335a485f..ad0a067ad4b3 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -78,21 +78,6 @@ config EVENT_TRACING select CONTEXT_SWITCH_TRACER bool -config EVENT_POWER_TRACING_DEPRECATED - depends on EVENT_TRACING - bool "Deprecated power event trace API, to be removed" - default y - help - Provides old power event types: - C-state/idle accounting events: - power:power_start - power:power_end - and old cpufreq accounting event: - power:power_frequency - This is for userspace compatibility - and will vanish after 5 kernel iterations, - namely 3.1. - config CONTEXT_SWITCH_TRACER bool diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index f55fcf61b223..1c71382b283d 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c @@ -13,8 +13,5 @@ #define CREATE_TRACE_POINTS #include -#ifdef EVENT_POWER_TRACING_DEPRECATED -EXPORT_TRACEPOINT_SYMBOL_GPL(power_start); -#endif EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); -- cgit v1.2.3 From bd603455f366bd66a5e1870bc285c05c9cb6a72d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 28 Jan 2013 16:13:12 +0000 Subject: ARM: use device tree to get smp_twd clock Move clk setup to twd_local_timer_common_register and rely on twd_timer_rate being 0 to force calibration if there is no clock. Remove common_setup_called as it is no longer needed. Signed-off-by: Rob Herring Signed-off-by: Mark Langsdorf Acked-by: Russell King Signed-off-by: Rafael J. Wysocki --- arch/arm/kernel/smp_twd.c | 53 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 49f335d301ba..ae0c7bb39ae8 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -31,7 +31,6 @@ static void __iomem *twd_base; static struct clk *twd_clk; static unsigned long twd_timer_rate; -static bool common_setup_called; static DEFINE_PER_CPU(bool, percpu_setup_called); static struct clock_event_device __percpu **twd_evt; @@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id) return IRQ_NONE; } -static struct clk *twd_get_clock(void) +static void twd_get_clock(struct device_node *np) { - struct clk *clk; int err; - clk = clk_get_sys("smp_twd", NULL); - if (IS_ERR(clk)) { - pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); - return clk; + if (np) + twd_clk = of_clk_get(np, 0); + else + twd_clk = clk_get_sys("smp_twd", NULL); + + if (IS_ERR(twd_clk)) { + pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk)); + return; } - err = clk_prepare_enable(clk); + err = clk_prepare_enable(twd_clk); if (err) { pr_err("smp_twd: clock failed to prepare+enable: %d\n", err); - clk_put(clk); - return ERR_PTR(err); + clk_put(twd_clk); + return; } - return clk; + twd_timer_rate = clk_get_rate(twd_clk); } /* @@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk) } per_cpu(percpu_setup_called, cpu) = true; - /* - * This stuff only need to be done once for the entire TWD cluster - * during the runtime of the system. - */ - if (!common_setup_called) { - twd_clk = twd_get_clock(); - - /* - * We use IS_ERR_OR_NULL() here, because if the clock stubs - * are active we will get a valid clk reference which is - * however NULL and will return the rate 0. In that case we - * need to calibrate the rate instead. - */ - if (!IS_ERR_OR_NULL(twd_clk)) - twd_timer_rate = clk_get_rate(twd_clk); - else - twd_calibrate_rate(); - - common_setup_called = true; - } + twd_calibrate_rate(); /* * The following is done once per CPU the first time .setup() is @@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = { .stop = twd_timer_stop, }; -static int __init twd_local_timer_common_register(void) +static int __init twd_local_timer_common_register(struct device_node *np) { int err; @@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void) if (err) goto out_irq; + twd_get_clock(np); + return 0; out_irq: @@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt) if (!twd_base) return -ENOMEM; - return twd_local_timer_common_register(); + return twd_local_timer_common_register(NULL); } #ifdef CONFIG_OF @@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void) goto out; } - err = twd_local_timer_common_register(); + err = twd_local_timer_common_register(np); out: WARN(err, "twd_local_timer_of_register failed (%d)\n", err); -- cgit v1.2.3 From 300586778d405f0a4d1f6dc51fcfb4fed567d020 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 28 Jan 2013 16:13:14 +0000 Subject: ARM / highbank: add support for pl320 IPC The pl320 IPC allows for interprocessor communication between the highbank A9 and the EnergyCore Management Engine. The pl320 implements a straightforward mailbox protocol. Signed-off-by: Mark Langsdorf Signed-off-by: Rob Herring Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-highbank/Kconfig | 2 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/mailbox/Kconfig | 19 ++++ drivers/mailbox/Makefile | 1 + drivers/mailbox/pl320-ipc.c | 199 +++++++++++++++++++++++++++++++++++++++++ include/linux/mailbox.h | 17 ++++ 7 files changed, 241 insertions(+) create mode 100644 drivers/mailbox/Kconfig create mode 100644 drivers/mailbox/Makefile create mode 100644 drivers/mailbox/pl320-ipc.c create mode 100644 include/linux/mailbox.h (limited to 'arch') diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig index 551c97e87a78..2388085beaa2 100644 --- a/arch/arm/mach-highbank/Kconfig +++ b/arch/arm/mach-highbank/Kconfig @@ -11,5 +11,7 @@ config ARCH_HIGHBANK select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU select HAVE_SMP + select MAILBOX + select PL320_MBOX select SPARSE_IRQ select USE_OF diff --git a/drivers/Kconfig b/drivers/Kconfig index f5fb0722a63a..2b4e89ba15ad 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -134,6 +134,8 @@ source "drivers/hwspinlock/Kconfig" source "drivers/clocksource/Kconfig" +source "drivers/mailbox/Kconfig" + source "drivers/iommu/Kconfig" source "drivers/remoteproc/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 7863b9fee50b..a8d32f1094b4 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -130,6 +130,7 @@ obj-y += platform/ #common clk code obj-y += clk/ +obj-$(CONFIG_MAILBOX) += mailbox/ obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ obj-$(CONFIG_NFC) += nfc/ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig new file mode 100644 index 000000000000..9545c9f03809 --- /dev/null +++ b/drivers/mailbox/Kconfig @@ -0,0 +1,19 @@ +menuconfig MAILBOX + bool "Mailbox Hardware Support" + help + Mailbox is a framework to control hardware communication between + on-chip processors through queued messages and interrupt driven + signals. Say Y if your platform supports hardware mailboxes. + +if MAILBOX +config PL320_MBOX + bool "ARM PL320 Mailbox" + depends on ARM_AMBA + help + An implementation of the ARM PL320 Interprocessor Communication + Mailbox (IPCM), tailored for the Calxeda Highbank. It is used to + send short messages between Highbank's A9 cores and the EnergyCore + Management Engine, primarily for cpufreq. Say Y here if you want + to use the PL320 IPCM support. + +endif diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile new file mode 100644 index 000000000000..543ad6a79505 --- /dev/null +++ b/drivers/mailbox/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c new file mode 100644 index 000000000000..c45b3aedafba --- /dev/null +++ b/drivers/mailbox/pl320-ipc.c @@ -0,0 +1,199 @@ +/* + * Copyright 2012 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define IPCMxSOURCE(m) ((m) * 0x40) +#define IPCMxDSET(m) (((m) * 0x40) + 0x004) +#define IPCMxDCLEAR(m) (((m) * 0x40) + 0x008) +#define IPCMxDSTATUS(m) (((m) * 0x40) + 0x00C) +#define IPCMxMODE(m) (((m) * 0x40) + 0x010) +#define IPCMxMSET(m) (((m) * 0x40) + 0x014) +#define IPCMxMCLEAR(m) (((m) * 0x40) + 0x018) +#define IPCMxMSTATUS(m) (((m) * 0x40) + 0x01C) +#define IPCMxSEND(m) (((m) * 0x40) + 0x020) +#define IPCMxDR(m, dr) (((m) * 0x40) + ((dr) * 4) + 0x024) + +#define IPCMMIS(irq) (((irq) * 8) + 0x800) +#define IPCMRIS(irq) (((irq) * 8) + 0x804) + +#define MBOX_MASK(n) (1 << (n)) +#define IPC_TX_MBOX 1 +#define IPC_RX_MBOX 2 + +#define CHAN_MASK(n) (1 << (n)) +#define A9_SOURCE 1 +#define M3_SOURCE 0 + +static void __iomem *ipc_base; +static int ipc_irq; +static DEFINE_MUTEX(ipc_m1_lock); +static DECLARE_COMPLETION(ipc_completion); +static ATOMIC_NOTIFIER_HEAD(ipc_notifier); + +static inline void set_destination(int source, int mbox) +{ + __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox)); + __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox)); +} + +static inline void clear_destination(int source, int mbox) +{ + __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox)); + __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox)); +} + +static void __ipc_send(int mbox, u32 *data) +{ + int i; + for (i = 0; i < 7; i++) + __raw_writel(data[i], ipc_base + IPCMxDR(mbox, i)); + __raw_writel(0x1, ipc_base + IPCMxSEND(mbox)); +} + +static u32 __ipc_rcv(int mbox, u32 *data) +{ + int i; + for (i = 0; i < 7; i++) + data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i)); + return data[1]; +} + +/* blocking implmentation from the A9 side, not usuable in interrupts! */ +int pl320_ipc_transmit(u32 *data) +{ + int ret; + + mutex_lock(&ipc_m1_lock); + + init_completion(&ipc_completion); + __ipc_send(IPC_TX_MBOX, data); + ret = wait_for_completion_timeout(&ipc_completion, + msecs_to_jiffies(1000)); + if (ret == 0) { + ret = -ETIMEDOUT; + goto out; + } + + ret = __ipc_rcv(IPC_TX_MBOX, data); +out: + mutex_unlock(&ipc_m1_lock); + return ret; +} +EXPORT_SYMBOL_GPL(pl320_ipc_transmit); + +static irqreturn_t ipc_handler(int irq, void *dev) +{ + u32 irq_stat; + u32 data[7]; + + irq_stat = __raw_readl(ipc_base + IPCMMIS(1)); + if (irq_stat & MBOX_MASK(IPC_TX_MBOX)) { + __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX)); + complete(&ipc_completion); + } + if (irq_stat & MBOX_MASK(IPC_RX_MBOX)) { + __ipc_rcv(IPC_RX_MBOX, data); + atomic_notifier_call_chain(&ipc_notifier, data[0], data + 1); + __raw_writel(2, ipc_base + IPCMxSEND(IPC_RX_MBOX)); + } + + return IRQ_HANDLED; +} + +int pl320_ipc_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&ipc_notifier, nb); +} +EXPORT_SYMBOL_GPL(pl320_ipc_register_notifier); + +int pl320_ipc_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&ipc_notifier, nb); +} +EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier); + +static int __init pl320_probe(struct amba_device *adev, + const struct amba_id *id) +{ + int ret; + + ipc_base = ioremap(adev->res.start, resource_size(&adev->res)); + if (ipc_base == NULL) + return -ENOMEM; + + __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX)); + + ipc_irq = adev->irq[0]; + ret = request_irq(ipc_irq, ipc_handler, 0, dev_name(&adev->dev), NULL); + if (ret < 0) + goto err; + + /* Init slow mailbox */ + __raw_writel(CHAN_MASK(A9_SOURCE), + ipc_base + IPCMxSOURCE(IPC_TX_MBOX)); + __raw_writel(CHAN_MASK(M3_SOURCE), + ipc_base + IPCMxDSET(IPC_TX_MBOX)); + __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE), + ipc_base + IPCMxMSET(IPC_TX_MBOX)); + + /* Init receive mailbox */ + __raw_writel(CHAN_MASK(M3_SOURCE), + ipc_base + IPCMxSOURCE(IPC_RX_MBOX)); + __raw_writel(CHAN_MASK(A9_SOURCE), + ipc_base + IPCMxDSET(IPC_RX_MBOX)); + __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE), + ipc_base + IPCMxMSET(IPC_RX_MBOX)); + + return 0; +err: + iounmap(ipc_base); + return ret; +} + +static struct amba_id pl320_ids[] = { + { + .id = 0x00041320, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver pl320_driver = { + .drv = { + .name = "pl320", + }, + .id_table = pl320_ids, + .probe = pl320_probe, +}; + +static int __init ipc_init(void) +{ + return amba_driver_register(&pl320_driver); +} +module_init(ipc_init); diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h new file mode 100644 index 000000000000..5161f63ec1c8 --- /dev/null +++ b/include/linux/mailbox.h @@ -0,0 +1,17 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +int pl320_ipc_transmit(u32 *data); +int pl320_ipc_register_notifier(struct notifier_block *nb); +int pl320_ipc_unregister_notifier(struct notifier_block *nb); -- cgit v1.2.3 From 6754f556103be5bd172263b1075ddbb7157afbad Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 28 Jan 2013 16:13:15 +0000 Subject: cpufreq / highbank: add support for highbank cpufreq Highbank processors depend on the external ECME to perform voltage management based on a requested frequency. Communication between the A9 cores and the ECME happens over the pl320 IPC channel. Signed-off-by: Mark Langsdorf Reviewed-by: Shawn Guo Reviewed-by: Mike Turquette Signed-off-by: Rafael J. Wysocki --- arch/arm/boot/dts/highbank.dts | 10 ++++ arch/arm/mach-highbank/Kconfig | 2 + drivers/cpufreq/Kconfig.arm | 15 +++++ drivers/cpufreq/Makefile | 3 +- drivers/cpufreq/cpufreq-cpu0.c | 6 +- drivers/cpufreq/highbank-cpufreq.c | 115 +++++++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 drivers/cpufreq/highbank-cpufreq.c (limited to 'arch') diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 5927a8df5625..6aad34ad9517 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -37,6 +37,16 @@ next-level-cache = <&L2>; clocks = <&a9pll>; clock-names = "cpu"; + operating-points = < + /* kHz ignored */ + 1300000 1000000 + 1200000 1000000 + 1100000 1000000 + 800000 1000000 + 400000 1000000 + 200000 1000000 + >; + clock-latency = <100000>; }; cpu@901 { diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig index 2388085beaa2..44b12f9c1584 100644 --- a/arch/arm/mach-highbank/Kconfig +++ b/arch/arm/mach-highbank/Kconfig @@ -1,5 +1,7 @@ config ARCH_HIGHBANK bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7 + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_AMBA select ARM_GIC diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index a0b3661d90b0..ffe55b8a98cc 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -83,3 +83,18 @@ config ARM_SPEAR_CPUFREQ default y help This adds the CPUFreq driver support for SPEAr SOCs. + +config ARM_HIGHBANK_CPUFREQ + tristate "Calxeda Highbank-based" + depends on ARCH_HIGHBANK + select CPU_FREQ_TABLE + select GENERIC_CPUFREQ_CPU0 + select PM_OPP + select REGULATOR + + default m + help + This adds the CPUFreq driver for Calxeda Highbank SoC + based boards. + + If in doubt, say N. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 24d4a63fd6cf..e2a5da77370f 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -51,8 +51,9 @@ obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o -obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o +obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o +obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o ################################################################################## # PowerPC platform drivers diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index debc5a7c8db6..38ae178ce4ef 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -182,7 +182,11 @@ static int cpu0_cpufreq_driver_init(void) struct device_node *np; int ret; - np = of_find_node_by_path("/cpus/cpu@0"); + for_each_child_of_node(of_find_node_by_path("/cpus"), np) { + if (of_get_property(np, "operating-points", NULL)) + break; + } + if (!np) { pr_err("failed to find cpu0 node\n"); return -ENOENT; diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c new file mode 100644 index 000000000000..53f25e5aa6b7 --- /dev/null +++ b/drivers/cpufreq/highbank-cpufreq.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2012 Calxeda, 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 driver provides the clk notifier callbacks that are used when + * the cpufreq-cpu0 driver changes to frequency to alert the highbank + * EnergyCore Management Engine (ECME) about the need to change + * voltage. The ECME interfaces with the actual voltage regulators. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include + +#define HB_CPUFREQ_CHANGE_NOTE 0x80000001 +#define HB_CPUFREQ_IPC_LEN 7 +#define HB_CPUFREQ_VOLT_RETRIES 15 + +static int hb_voltage_change(unsigned int freq) +{ + int i; + u32 msg[HB_CPUFREQ_IPC_LEN]; + + msg[0] = HB_CPUFREQ_CHANGE_NOTE; + msg[1] = freq / 1000000; + for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++) + msg[i] = 0; + + return pl320_ipc_transmit(msg); +} + +static int hb_cpufreq_clk_notify(struct notifier_block *nb, + unsigned long action, void *hclk) +{ + struct clk_notifier_data *clk_data = hclk; + int i = 0; + + if (action == PRE_RATE_CHANGE) { + if (clk_data->new_rate > clk_data->old_rate) + while (hb_voltage_change(clk_data->new_rate)) + if (i++ > HB_CPUFREQ_VOLT_RETRIES) + return NOTIFY_BAD; + } else if (action == POST_RATE_CHANGE) { + if (clk_data->new_rate < clk_data->old_rate) + while (hb_voltage_change(clk_data->new_rate)) + if (i++ > HB_CPUFREQ_VOLT_RETRIES) + return NOTIFY_BAD; + } + + return NOTIFY_DONE; +} + +static struct notifier_block hb_cpufreq_clk_nb = { + .notifier_call = hb_cpufreq_clk_notify, +}; + +static int hb_cpufreq_driver_init(void) +{ + struct device *cpu_dev; + struct clk *cpu_clk; + struct device_node *np; + int ret; + + if (!of_machine_is_compatible("calxeda,highbank")) + return -ENODEV; + + for_each_child_of_node(of_find_node_by_path("/cpus"), np) + if (of_get_property(np, "operating-points", NULL)) + break; + + if (!np) { + pr_err("failed to find highbank cpufreq node\n"); + return -ENOENT; + } + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) { + pr_err("failed to get highbank cpufreq device\n"); + ret = -ENODEV; + goto out_put_node; + } + + cpu_dev->of_node = np; + + cpu_clk = clk_get(cpu_dev, NULL); + if (IS_ERR(cpu_clk)) { + ret = PTR_ERR(cpu_clk); + pr_err("failed to get cpu0 clock: %d\n", ret); + goto out_put_node; + } + + ret = clk_notifier_register(cpu_clk, &hb_cpufreq_clk_nb); + if (ret) { + pr_err("failed to register clk notifier: %d\n", ret); + goto out_put_node; + } + +out_put_node: + of_node_put(np); + return ret; +} +module_init(hb_cpufreq_driver_init); + +MODULE_AUTHOR("Mark Langsdorf "); +MODULE_DESCRIPTION("Calxeda Highbank cpufreq driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 16a44f82674ddd8d5b5b2527979ac22a25c55c50 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 1 Feb 2013 06:40:00 +0000 Subject: cpufreq: TEGRA: Set policy->cpus from driver->init() For multicore SoC's, with cores sharing clock line, we are required to set policy->cpus and policy->related_cpus with mask of cpus. With following patch, we need to set policy->cpus with mask of all possible cpus and policy->related_cpus would be filled automatically by the cpufreq core. commit 4948b355e90080cd5ec1e91189f65a01e4186ef2 Author: Viresh Kumar Date: Tue Jan 29 14:39:08 2013 +0000 cpufreq: Simplify cpufreq_add_dev() Current Tegra driver fills only ->related_cpus and not ->cpus, which looks to be incorrect. Lets fix it. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-tegra/cpu-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index a74d3c7d2e26..e7ddcb2b5261 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -244,7 +244,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = 300 * 1000; policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - cpumask_copy(policy->related_cpus, cpu_possible_mask); + cpumask_copy(policy->cpus, cpu_possible_mask); if (policy->cpu == 0) register_pm_notifier(&tegra_cpu_pm_notifier); -- cgit v1.2.3 From 62b36cc1c83aca1cd252772e82cbc5d9ef8ff25b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 1 Feb 2013 06:40:02 +0000 Subject: cpufreq: Remove unnecessary use of policy->shared_type policy->shared_type field was added only for SoCs with ACPI support: commit 3b2d99429e3386b6e2ac949fc72486509c8bbe36 Author: Venkatesh Pallipadi Date: Wed Dec 14 15:05:00 2005 -0500 P-state software coordination for ACPI core http://bugzilla.kernel.org/show_bug.cgi?id=5737 Many non-ACPI systems are filling this field by mistake, which makes its usage confusing. Lets clean it. Signed-off-by: Viresh Kumar Acked-by: Santosh Shilimkar Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-tegra/cpu-tegra.c | 1 - drivers/cpufreq/cpufreq-cpu0.c | 1 - drivers/cpufreq/db8500-cpufreq.c | 2 -- drivers/cpufreq/omap-cpufreq.c | 4 +--- include/linux/cpufreq.h | 3 ++- 5 files changed, 3 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index e7ddcb2b5261..a36a03d3c9a0 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -243,7 +243,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) /* FIXME: what's the actual transition time? */ policy->cpuinfo.transition_latency = 300 * 1000; - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; cpumask_copy(policy->cpus, cpu_possible_mask); if (policy->cpu == 0) diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index a108f66271ee..4e5b7fb8927c 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -146,7 +146,6 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy) * share the clock and voltage and clock. Use cpufreq affected_cpus * interface to have all CPUs scaled together. */ - policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; cpumask_setall(policy->cpus); cpufreq_frequency_table_get_attr(freq_table, policy->cpu); diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index e12dff601b8a..79a84860ea56 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -130,8 +130,6 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) /* policy sharing between dual CPUs */ cpumask_setall(policy->cpus); - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - return 0; } diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 97102b05843f..9128c07bafba 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -214,10 +214,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) * interface to handle this scenario. Additional is_smp() check * is to keep SMP_ON_UP build working. */ - if (is_smp()) { - policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; + if (is_smp()) cpumask_setall(policy->cpus); - } /* FIXME: what's the actual transition time? */ policy->cpuinfo.transition_latency = 300 * 1000; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 6bf3f2d12c90..a22944ca0526 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -93,7 +93,7 @@ struct cpufreq_policy { cpumask_var_t cpus; /* Online CPUs only */ cpumask_var_t related_cpus; /* Online + Offline CPUs */ - unsigned int shared_type; /* ANY or ALL affected CPUs + unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs should set cpufreq */ unsigned int cpu; /* cpu nr of CPU managing this policy */ unsigned int last_cpu; /* cpu nr of previous CPU that managed @@ -122,6 +122,7 @@ struct cpufreq_policy { #define CPUFREQ_START (3) #define CPUFREQ_UPDATE_POLICY_CPU (4) +/* Only for ACPI */ #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ #define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ #define CPUFREQ_SHARED_TYPE_ALL (2) /* All dependent CPUs should set freq */ -- cgit v1.2.3 From 5af4a21c6efd270a334202fb1fc4a347ea4624e3 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 4 Feb 2013 12:01:41 +0000 Subject: Replace the flag by a simple global boolean in the cpuidle.c. That will allow to cleanup the rest of the code right after, because the ops won't make sense. Signed-off-by: Daniel Lezcano Acked-by: Sekhar Nori Signed-off-by: Len Brown --- arch/arm/mach-davinci/cpuidle.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index 9107691adbdb..5fbd470d46ca 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -26,8 +26,8 @@ #define DAVINCI_CPUIDLE_MAX_STATES 2 struct davinci_ops { - void (*enter) (u32 flags); - void (*exit) (u32 flags); + void (*enter) (void); + void (*exit) (void); u32 flags; }; @@ -40,20 +40,17 @@ static int davinci_enter_idle(struct cpuidle_device *dev, struct davinci_ops *ops = cpuidle_get_statedata(state_usage); if (ops && ops->enter) - ops->enter(ops->flags); + ops->enter(); index = cpuidle_wrap_enter(dev, drv, index, arm_cpuidle_simple_enter); if (ops && ops->exit) - ops->exit(ops->flags); + ops->exit(); return index; } -/* fields in davinci_ops.flags */ -#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) - static struct cpuidle_driver davinci_idle_driver = { .name = "cpuidle-davinci", .owner = THIS_MODULE, @@ -72,6 +69,7 @@ static struct cpuidle_driver davinci_idle_driver = { static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); static void __iomem *ddr2_reg_base; +static bool ddr2_pdown; static void davinci_save_ddr_power(int enter, bool pdown) { @@ -92,14 +90,14 @@ static void davinci_save_ddr_power(int enter, bool pdown) __raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET); } -static void davinci_c2state_enter(u32 flags) +static void davinci_c2state_enter(void) { - davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN)); + davinci_save_ddr_power(1, ddr2_pdown); } -static void davinci_c2state_exit(u32 flags) +static void davinci_c2state_exit(void) { - davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN)); + davinci_save_ddr_power(0, ddr2_pdown); } static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { @@ -124,8 +122,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) ddr2_reg_base = pdata->ddr2_ctlr_base; - if (pdata->ddr2_pdown) - davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; + ddr2_pdown = pdata->ddr2_pdown; cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); device->state_count = DAVINCI_CPUIDLE_MAX_STATES; -- cgit v1.2.3 From 8d60143a2367616a9d4f7c11656ade8521eb1874 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 4 Feb 2013 12:01:42 +0000 Subject: davinci: cpuidle - move code to prevent forward declaration The patch is mindless, it just moves the idle function below in the file in order to prevent forward declaration in the next patch. Signed-off-by: Daniel Lezcano Acked-by: Sekhar Nori Signed-off-by: Len Brown --- arch/arm/mach-davinci/cpuidle.c | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index 5fbd470d46ca..697febe5a8e5 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -31,42 +31,6 @@ struct davinci_ops { u32 flags; }; -/* Actual code that puts the SoC in different idle states */ -static int davinci_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; - struct davinci_ops *ops = cpuidle_get_statedata(state_usage); - - if (ops && ops->enter) - ops->enter(); - - index = cpuidle_wrap_enter(dev, drv, index, - arm_cpuidle_simple_enter); - - if (ops && ops->exit) - ops->exit(); - - return index; -} - -static struct cpuidle_driver davinci_idle_driver = { - .name = "cpuidle-davinci", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = davinci_enter_idle, - .exit_latency = 10, - .target_residency = 100000, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "DDR SR", - .desc = "WFI and DDR Self Refresh", - }, - .state_count = DAVINCI_CPUIDLE_MAX_STATES, -}; - static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); static void __iomem *ddr2_reg_base; static bool ddr2_pdown; @@ -107,6 +71,42 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { }, }; +/* Actual code that puts the SoC in different idle states */ +static int davinci_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + struct davinci_ops *ops = cpuidle_get_statedata(state_usage); + + if (ops && ops->enter) + ops->enter(); + + index = cpuidle_wrap_enter(dev, drv, index, + arm_cpuidle_simple_enter); + + if (ops && ops->exit) + ops->exit(); + + return index; +} + +static struct cpuidle_driver davinci_idle_driver = { + .name = "cpuidle-davinci", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = davinci_enter_idle, + .exit_latency = 10, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "DDR SR", + .desc = "WFI and DDR Self Refresh", + }, + .state_count = DAVINCI_CPUIDLE_MAX_STATES, +}; + static int __init davinci_cpuidle_probe(struct platform_device *pdev) { int ret; -- cgit v1.2.3 From 36ce8d4f5fecc20c2dfb08f24fe01c5eb81f6245 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 4 Feb 2013 12:01:43 +0000 Subject: davinci: cpuidle - remove the ops With one function handling the idle state and a single variable, the usage of the davinci_ops is overkill. This patch removes these ops and simplify the code. Furthermore, the 'driver_data' field is no longer used, we have 1 of the 3 remaining user of this field removed. Signed-off-by: Daniel Lezcano Acked-by: Sekhar Nori Signed-off-by: Len Brown --- arch/arm/mach-davinci/cpuidle.c | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index 697febe5a8e5..5e430bffb5d8 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -25,12 +25,6 @@ #define DAVINCI_CPUIDLE_MAX_STATES 2 -struct davinci_ops { - void (*enter) (void); - void (*exit) (void); - u32 flags; -}; - static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); static void __iomem *ddr2_reg_base; static bool ddr2_pdown; @@ -54,39 +48,17 @@ static void davinci_save_ddr_power(int enter, bool pdown) __raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET); } -static void davinci_c2state_enter(void) -{ - davinci_save_ddr_power(1, ddr2_pdown); -} - -static void davinci_c2state_exit(void) -{ - davinci_save_ddr_power(0, ddr2_pdown); -} - -static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { - [1] = { - .enter = davinci_c2state_enter, - .exit = davinci_c2state_exit, - }, -}; - /* Actual code that puts the SoC in different idle states */ static int davinci_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; - struct davinci_ops *ops = cpuidle_get_statedata(state_usage); - - if (ops && ops->enter) - ops->enter(); + davinci_save_ddr_power(1, ddr2_pdown); index = cpuidle_wrap_enter(dev, drv, index, arm_cpuidle_simple_enter); - if (ops && ops->exit) - ops->exit(); + davinci_save_ddr_power(0, ddr2_pdown); return index; } @@ -123,7 +95,6 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) ddr2_reg_base = pdata->ddr2_ctlr_base; ddr2_pdown = pdata->ddr2_pdown; - cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); device->state_count = DAVINCI_CPUIDLE_MAX_STATES; -- cgit v1.2.3 From 748f11772154b58426c856b7d90538a9b60ae29a Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 4 Feb 2013 12:01:44 +0000 Subject: davinci: cpuidle - remove useless initialization The device->state_count is initialized in the cpuidle_register_device function. Signed-off-by: Daniel Lezcano Acked-by: Sekhar Nori Signed-off-by: Len Brown --- arch/arm/mach-davinci/cpuidle.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index 5e430bffb5d8..5ac9e9384b15 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -96,8 +96,6 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) ddr2_pdown = pdata->ddr2_pdown; - device->state_count = DAVINCI_CPUIDLE_MAX_STATES; - ret = cpuidle_register_driver(&davinci_idle_driver); if (ret) { dev_err(&pdev->dev, "failed to register driver\n"); -- cgit v1.2.3 From 679204183472af16e8e75d2b1479459ad19bc67c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 31 Jan 2013 15:22:15 -0500 Subject: tools/power turbostat: decode MSR_IA32_POWER_CTL When verbose is enabled, print the C1E-Enable bit in MSR_IA32_POWER_CTL. also delete some redundant tests on the verbose variable. Signed-off-by: Len Brown --- arch/x86/include/uapi/asm/msr-index.h | 2 ++ tools/power/x86/turbostat/turbostat.c | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index 433a59fb1a74..7bdaf7c9b1e0 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -103,6 +103,8 @@ #define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) #define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) +#define MSR_IA32_POWER_CTL 0x000001fc + #define MSR_IA32_MC0_CTL 0x00000400 #define MSR_IA32_MC0_STATUS 0x00000401 #define MSR_IA32_MC0_ADDR 0x00000402 diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index b326878bd5d1..75f64e05ec30 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -908,8 +908,7 @@ void print_verbose_header(void) get_msr(0, MSR_NHM_PLATFORM_INFO, &msr); - if (verbose) - fprintf(stderr, "cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx\n", msr); + fprintf(stderr, "cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx\n", msr); ratio = (msr >> 40) & 0xFF; fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", @@ -919,13 +918,16 @@ void print_verbose_header(void) fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n", ratio, bclk, ratio * bclk); + get_msr(0, MSR_IA32_POWER_CTL, &msr); + fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E: %sabled)\n", + msr, msr & 0x2 ? "EN" : "DIS"); + if (!do_ivt_turbo_ratio_limit) goto print_nhm_turbo_ratio_limits; get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr); - if (verbose) - fprintf(stderr, "cpu0: MSR_IVT_TURBO_RATIO_LIMIT: 0x%08llx\n", msr); + fprintf(stderr, "cpu0: MSR_IVT_TURBO_RATIO_LIMIT: 0x%08llx\n", msr); ratio = (msr >> 56) & 0xFF; if (ratio) @@ -1016,8 +1018,7 @@ print_nhm_turbo_ratio_limits: get_msr(0, MSR_NHM_TURBO_RATIO_LIMIT, &msr); - if (verbose) - fprintf(stderr, "cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx\n", msr); + fprintf(stderr, "cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx\n", msr); ratio = (msr >> 56) & 0xFF; if (ratio) -- cgit v1.2.3 From 137ecc779c80138723677209730738d76262e810 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 1 Feb 2013 21:35:35 -0500 Subject: intel_idle: remove use and definition of MWAIT_MAX_NUM_CSTATES Cosmetic only. Replace use of MWAIT_MAX_NUM_CSTATES with CPUIDLE_STATE_MAX. They are both 8, so this patch has no functional change. The reason to change is that intel_idle will soon be able to export more than the 8 "major" states supported by MWAIT. When we hit that limit, it is important to know where the limit comes from. Signed-off-by: Len Brown --- arch/x86/include/asm/mwait.h | 1 - drivers/idle/intel_idle.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index bcdff997668c..3f447320ce87 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -4,7 +4,6 @@ #define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf #define MWAIT_SUBSTATE_SIZE 4 -#define MWAIT_MAX_NUM_CSTATES 8 #define CPUID_MWAIT_LEAF 5 #define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index fa714774b960..c949a6f25a83 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -74,7 +74,7 @@ static struct cpuidle_driver intel_idle_driver = { .en_core_tk_irqen = 1, }; /* intel_idle.max_cstate=0 disables driver */ -static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1; +static int max_cstate = CPUIDLE_STATE_MAX - 1; static unsigned int mwait_substates; @@ -123,7 +123,7 @@ static struct cpuidle_state *cpuidle_state_table; * which is also the index into the MWAIT hint array. * Thus C0 is a dummy. */ -static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { +static struct cpuidle_state nehalem_cstates[CPUIDLE_STATE_MAX] = { { /* MWAIT C0 */ }, { /* MWAIT C1 */ .name = "C1-NHM", @@ -148,7 +148,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { .enter = &intel_idle }, }; -static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { +static struct cpuidle_state snb_cstates[CPUIDLE_STATE_MAX] = { { /* MWAIT C0 */ }, { /* MWAIT C1 */ .name = "C1-SNB", @@ -180,7 +180,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { .enter = &intel_idle }, }; -static struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = { +static struct cpuidle_state ivb_cstates[CPUIDLE_STATE_MAX] = { { /* MWAIT C0 */ }, { /* MWAIT C1 */ .name = "C1-IVB", @@ -212,7 +212,7 @@ static struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = { .enter = &intel_idle }, }; -static struct cpuidle_state hsw_cstates[MWAIT_MAX_NUM_CSTATES] = { +static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = { { /* MWAIT C0 */ }, { /* MWAIT C1 */ .name = "C1-HSW", @@ -244,7 +244,7 @@ static struct cpuidle_state hsw_cstates[MWAIT_MAX_NUM_CSTATES] = { .enter = &intel_idle }, }; -static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { +static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = { { /* MWAIT C0 */ }, { /* MWAIT C1 */ .name = "C1-ATM", @@ -503,7 +503,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count = 1; - for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { + for (cstate = 1; cstate < CPUIDLE_STATE_MAX; ++cstate) { int num_substates; if (cstate > max_cstate) { @@ -560,7 +560,7 @@ static int intel_idle_cpu_init(int cpu) dev->state_count = 1; - for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { + for (cstate = 1; cstate < CPUIDLE_STATE_MAX; ++cstate) { int num_substates; if (cstate > max_cstate) { -- cgit v1.2.3 From e022e7eb90f3edb83f9ff77825eda3d1b3a2f2e0 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 1 Feb 2013 23:37:30 -0500 Subject: intel_idle: remove assumption of one C-state per MWAIT flag Remove the assumption that cstate_tables are indexed by MWAIT flag values. Each entry identifies itself via its own flags value. This change is needed to support multiple states that share the same MWAIT flags. Note that this can have an effect on what state is described by 'N' on cmdline intel_idle.max_cstate=N on some systems. intel_idle.max_cstate=0 still disables the driver intel_idle.max_cstate=1 still results in just C1(E) However, "place holders" in the sparse C-state name-space (eg. Atom) have been removed. Signed-off-by: Len Brown --- arch/x86/include/asm/mwait.h | 2 + drivers/idle/intel_idle.c | 110 +++++++++++++++++++++++-------------------- 2 files changed, 61 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index 3f447320ce87..2f366d0ac6b4 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -4,6 +4,8 @@ #define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf #define MWAIT_SUBSTATE_SIZE 4 +#define MWAIT_HINT2CSTATE(hint) (((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) +#define MWAIT_HINT2SUBSTATE(hint) ((hint) & MWAIT_CSTATE_MASK) #define CPUID_MWAIT_LEAF 5 #define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index c949a6f25a83..927cfb4d66f4 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -124,158 +124,161 @@ static struct cpuidle_state *cpuidle_state_table; * Thus C0 is a dummy. */ static struct cpuidle_state nehalem_cstates[CPUIDLE_STATE_MAX] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ + { .name = "C1-NHM", .desc = "MWAIT 0x00", .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 3, .target_residency = 6, .enter = &intel_idle }, - { /* MWAIT C2 */ + { .name = "C3-NHM", .desc = "MWAIT 0x10", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 20, .target_residency = 80, .enter = &intel_idle }, - { /* MWAIT C3 */ + { .name = "C6-NHM", .desc = "MWAIT 0x20", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 200, .target_residency = 800, .enter = &intel_idle }, + { + .enter = NULL } }; static struct cpuidle_state snb_cstates[CPUIDLE_STATE_MAX] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ + { .name = "C1-SNB", .desc = "MWAIT 0x00", .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 1, .target_residency = 1, .enter = &intel_idle }, - { /* MWAIT C2 */ + { .name = "C3-SNB", .desc = "MWAIT 0x10", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 80, .target_residency = 211, .enter = &intel_idle }, - { /* MWAIT C3 */ + { .name = "C6-SNB", .desc = "MWAIT 0x20", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 104, .target_residency = 345, .enter = &intel_idle }, - { /* MWAIT C4 */ + { .name = "C7-SNB", .desc = "MWAIT 0x30", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 109, .target_residency = 345, .enter = &intel_idle }, + { + .enter = NULL } }; static struct cpuidle_state ivb_cstates[CPUIDLE_STATE_MAX] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ + { .name = "C1-IVB", .desc = "MWAIT 0x00", .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 1, .target_residency = 1, .enter = &intel_idle }, - { /* MWAIT C2 */ + { .name = "C3-IVB", .desc = "MWAIT 0x10", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 59, .target_residency = 156, .enter = &intel_idle }, - { /* MWAIT C3 */ + { .name = "C6-IVB", .desc = "MWAIT 0x20", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 80, .target_residency = 300, .enter = &intel_idle }, - { /* MWAIT C4 */ + { .name = "C7-IVB", .desc = "MWAIT 0x30", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 87, .target_residency = 300, .enter = &intel_idle }, + { + .enter = NULL } }; static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ + { .name = "C1-HSW", .desc = "MWAIT 0x00", .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 2, .target_residency = 2, .enter = &intel_idle }, - { /* MWAIT C2 */ + { .name = "C3-HSW", .desc = "MWAIT 0x10", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 33, .target_residency = 100, .enter = &intel_idle }, - { /* MWAIT C3 */ + { .name = "C6-HSW", .desc = "MWAIT 0x20", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 133, .target_residency = 400, .enter = &intel_idle }, - { /* MWAIT C4 */ + { .name = "C7s-HSW", .desc = "MWAIT 0x32", .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 166, .target_residency = 500, .enter = &intel_idle }, + { + .enter = NULL } }; static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ + { .name = "C1-ATM", .desc = "MWAIT 0x00", .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 1, .target_residency = 4, .enter = &intel_idle }, - { /* MWAIT C2 */ + { .name = "C2-ATM", .desc = "MWAIT 0x10", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID, .exit_latency = 20, .target_residency = 80, .enter = &intel_idle }, - { /* MWAIT C3 */ }, - { /* MWAIT C4 */ + { .name = "C4-ATM", .desc = "MWAIT 0x30", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 100, .target_residency = 400, .enter = &intel_idle }, - { /* MWAIT C5 */ }, - { /* MWAIT C6 */ + { .name = "C6-ATM", .desc = "MWAIT 0x52", .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 140, .target_residency = 560, .enter = &intel_idle }, + { + .enter = NULL } }; /** @@ -503,32 +506,31 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count = 1; - for (cstate = 1; cstate < CPUIDLE_STATE_MAX; ++cstate) { - int num_substates; + for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { + int num_substates, mwait_hint, mwait_cstate, mwait_substate; - if (cstate > max_cstate) { + if (cpuidle_state_table[cstate].enter == NULL) + break; + + if (cstate + 1 > max_cstate) { printk(PREFIX "max_cstate %d reached\n", max_cstate); break; } + mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); + mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); + mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint); + /* does the state exist in CPUID.MWAIT? */ - num_substates = (mwait_substates >> ((cstate) * 4)) + num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) & MWAIT_SUBSTATE_MASK; - if (num_substates == 0) - continue; - /* is the state not enabled? */ - if (cpuidle_state_table[cstate].enter == NULL) { - /* does the driver not know about the state? */ - if (*cpuidle_state_table[cstate].name == '\0') - pr_debug(PREFIX "unaware of model 0x%x" - " MWAIT %d please" - " contact lenb@kernel.org\n", - boot_cpu_data.x86_model, cstate); + + /* if sub-state in table is not enumerated by CPUID */ + if ((mwait_substate + 1) > num_substates) continue; - } - if ((cstate > 2) && + if (((mwait_cstate + 1) > 2) && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) mark_tsc_unstable("TSC halts in idle" " states deeper than C2"); @@ -560,21 +562,27 @@ static int intel_idle_cpu_init(int cpu) dev->state_count = 1; - for (cstate = 1; cstate < CPUIDLE_STATE_MAX; ++cstate) { - int num_substates; + for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { + int num_substates, mwait_hint, mwait_cstate, mwait_substate; - if (cstate > max_cstate) { + if (cpuidle_state_table[cstate].enter == NULL) + continue; + + if (cstate + 1 > max_cstate) { printk(PREFIX "max_cstate %d reached\n", max_cstate); break; } + mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); + mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); + mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint); + /* does the state exist in CPUID.MWAIT? */ - num_substates = (mwait_substates >> ((cstate) * 4)) - & MWAIT_SUBSTATE_MASK; - if (num_substates == 0) - continue; - /* is the state not enabled? */ - if (cpuidle_state_table[cstate].enter == NULL) + num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) + & MWAIT_SUBSTATE_MASK; + + /* if sub-state in table is not enumerated by CPUID */ + if ((mwait_substate + 1) > num_substates) continue; dev->state_count += 1; -- cgit v1.2.3 From 6a377ddc4e4ede2eeb9cd46ada23bbe417704fc9 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 23:08:07 -0500 Subject: xen idle: make xen-specific macro xen-specific This macro is only invoked by Xen, so make its definition specific to Xen. > set_pm_idle_to_default() < xen_set_default_idle() Signed-off-by: Len Brown Cc: xen-devel@lists.xensource.com --- arch/x86/include/asm/processor.h | 6 +++++- arch/x86/kernel/process.c | 4 +++- arch/x86/xen/setup.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 888184b2fc85..c2f7f472275e 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -998,7 +998,11 @@ extern unsigned long arch_align_stack(unsigned long sp); extern void free_init_pages(char *what, unsigned long begin, unsigned long end); void default_idle(void); -bool set_pm_idle_to_default(void); +#ifdef CONFIG_XEN +bool xen_set_default_idle(void); +#else +#define xen_set_default_idle 0 +#endif void stop_this_cpu(void *dummy); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2ed787f15bf0..7ed9f6b08ba0 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -396,7 +396,8 @@ void default_idle(void) EXPORT_SYMBOL(default_idle); #endif -bool set_pm_idle_to_default(void) +#ifdef CONFIG_XEN +bool xen_set_default_idle(void) { bool ret = !!pm_idle; @@ -404,6 +405,7 @@ bool set_pm_idle_to_default(void) return ret; } +#endif void stop_this_cpu(void *dummy) { local_irq_disable(); diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 8971a26d21ab..2b73b5c8555f 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -561,7 +561,7 @@ void __init xen_arch_setup(void) #endif disable_cpuidle(); disable_cpufreq(); - WARN_ON(set_pm_idle_to_default()); + WARN_ON(xen_set_default_idle()); fiddle_vdso(); #ifdef CONFIG_NUMA numa_off = 1; -- cgit v1.2.3 From 69fb3676df3329a7142803bb3502fa59dc0db2e3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 10 Feb 2013 01:38:39 -0500 Subject: x86 idle: remove mwait_idle() and "idle=mwait" cmdline param mwait_idle() is a C1-only idle loop intended to be more efficient than HLT, starting on Pentium-4 HT-enabled processors. But mwait_idle() has been replaced by the more general mwait_idle_with_hints(), which handles both C1 and deeper C-states. ACPI processor_idle and intel_idle use only mwait_idle_with_hints(), and no longer use mwait_idle(). Here we simplify the x86 native idle code by removing mwait_idle(), and the "idle=mwait" bootparam used to invoke it. Since Linux 3.0 there has been a boot-time warning when "idle=mwait" was invoked saying it would be removed in 2012. This removal was also noted in the (now removed:-) feature-removal-schedule.txt. After this change, kernels configured with (CONFIG_ACPI=n && CONFIG_INTEL_IDLE=n) when run on hardware that supports MWAIT will simply use HLT. If MWAIT is desired on those systems, cpuidle and the cpuidle drivers above can be enabled. Signed-off-by: Len Brown Cc: x86@kernel.org --- Documentation/kernel-parameters.txt | 7 +--- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/process.c | 79 +------------------------------------ arch/x86/kernel/smpboot.c | 2 +- drivers/acpi/processor_idle.c | 1 - 5 files changed, 4 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 363e348bff9b..3b0cd1e612da 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1039,16 +1039,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Claim all unknown PCI IDE storage controllers. idle= [X86] - Format: idle=poll, idle=mwait, idle=halt, idle=nomwait + Format: idle=poll, idle=halt, idle=nomwait Poll forces a polling idle loop that can slightly improve the performance of waking up a idle CPU, but will use a lot of power and make the system run hot. Not recommended. - idle=mwait: On systems which support MONITOR/MWAIT but - the kernel chose to not use it because it doesn't save - as much power as a normal idle loop, use the - MONITOR/MWAIT idle loop anyways. Performance should be - the same as idle=poll. idle=halt: Halt is forced to be used for CPU idle. In such case C2/C3 won't be used again. idle=nomwait: Disable mwait for CPU C-states diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index c2f7f472275e..8a28feae1c92 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -725,7 +725,7 @@ extern unsigned long boot_option_idle_override; extern bool amd_e400_c1e_detected; enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, - IDLE_POLL, IDLE_FORCE_MWAIT}; + IDLE_POLL}; extern void enable_sep_cpu(void); extern int sysenter_setup(void); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7ed9f6b08ba0..cd5a4c9ef835 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -421,27 +421,6 @@ void stop_this_cpu(void *dummy) } } -/* Default MONITOR/MWAIT with no hints, used for default C1 state */ -static void mwait_idle(void) -{ - if (!need_resched()) { - trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id()); - trace_cpu_idle_rcuidle(1, smp_processor_id()); - if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) - clflush((void *)¤t_thread_info()->flags); - - __monitor((void *)¤t_thread_info()->flags, 0, 0); - smp_mb(); - if (!need_resched()) - __sti_mwait(0, 0); - else - local_irq_enable(); - trace_power_end_rcuidle(smp_processor_id()); - trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); - } else - local_irq_enable(); -} - /* * On SMP it's slightly faster (but much more power-consuming!) * to poll the ->work.need_resched flag instead of waiting for the @@ -458,53 +437,6 @@ static void poll_idle(void) trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } -/* - * mwait selection logic: - * - * It depends on the CPU. For AMD CPUs that support MWAIT this is - * wrong. Family 0x10 and 0x11 CPUs will enter C1 on HLT. Powersavings - * then depend on a clock divisor and current Pstate of the core. If - * all cores of a processor are in halt state (C1) the processor can - * enter the C1E (C1 enhanced) state. If mwait is used this will never - * happen. - * - * idle=mwait overrides this decision and forces the usage of mwait. - */ - -#define MWAIT_INFO 0x05 -#define MWAIT_ECX_EXTENDED_INFO 0x01 -#define MWAIT_EDX_C1 0xf0 - -int mwait_usable(const struct cpuinfo_x86 *c) -{ - u32 eax, ebx, ecx, edx; - - /* Use mwait if idle=mwait boot option is given */ - if (boot_option_idle_override == IDLE_FORCE_MWAIT) - return 1; - - /* - * Any idle= boot option other than idle=mwait means that we must not - * use mwait. Eg: idle=halt or idle=poll or idle=nomwait - */ - if (boot_option_idle_override != IDLE_NO_OVERRIDE) - return 0; - - if (c->cpuid_level < MWAIT_INFO) - return 0; - - cpuid(MWAIT_INFO, &eax, &ebx, &ecx, &edx); - /* Check, whether EDX has extended info about MWAIT */ - if (!(ecx & MWAIT_ECX_EXTENDED_INFO)) - return 1; - - /* - * edx enumeratios MONITOR/MWAIT extensions. Check, whether - * C1 supports MWAIT - */ - return (edx & MWAIT_EDX_C1); -} - bool amd_e400_c1e_detected; EXPORT_SYMBOL(amd_e400_c1e_detected); @@ -576,13 +508,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) if (pm_idle) return; - if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { - /* - * One CPU supports mwait => All CPUs supports mwait - */ - pr_info("using mwait in idle threads\n"); - pm_idle = mwait_idle; - } else if (cpu_has_amd_erratum(amd_erratum_400)) { + if (cpu_has_amd_erratum(amd_erratum_400)) { /* E400: APIC timer interrupt does not wake up CPU from C1e */ pr_info("using AMD E400 aware idle routine\n"); pm_idle = amd_e400_idle; @@ -606,9 +532,6 @@ static int __init idle_setup(char *str) pr_info("using polling idle threads\n"); pm_idle = poll_idle; boot_option_idle_override = IDLE_POLL; - } else if (!strcmp(str, "mwait")) { - boot_option_idle_override = IDLE_FORCE_MWAIT; - WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n"); } else if (!strcmp(str, "halt")) { /* * When the boot option of idle=halt is added, halt is diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index ed0fe385289d..a6ceaedc396a 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1369,7 +1369,7 @@ static inline void mwait_play_dead(void) void *mwait_ptr; struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); - if (!(this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c))) + if (!this_cpu_has(X86_FEATURE_MWAIT)) return; if (!this_cpu_has(X86_FEATURE_CLFLSH)) return; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ed9a1cc690be..52a5e3a4cdc3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -84,7 +84,6 @@ static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); static int disabled_by_idle_boot_param(void) { return boot_option_idle_override == IDLE_POLL || - boot_option_idle_override == IDLE_FORCE_MWAIT || boot_option_idle_override == IDLE_HALT; } -- cgit v1.2.3 From 27be457000211a6903968dfce06d5f73f051a217 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 10 Feb 2013 02:28:46 -0500 Subject: x86 idle: remove 32-bit-only "no-hlt" parameter, hlt_works_ok flag Remove 32-bit x86 a cmdline param "no-hlt", and the cpuinfo_x86.hlt_works_ok that it sets. If a user wants to avoid HLT, then "idle=poll" is much more useful, as it avoids invocation of HLT in idle, while "no-hlt" failed to do so. Indeed, hlt_works_ok was consulted in only 3 places. First, in /proc/cpuinfo where "hlt_bug yes" would be printed if and only if the user booted the system with "no-hlt" -- as there was no other code to set that flag. Second, check_hlt() would not invoke halt() if "no-hlt" were on the cmdline. Third, it was consulted in stop_this_cpu(), which is invoked by native_machine_halt()/reboot_interrupt()/smp_stop_nmi_callback() -- all cases where the machine is being shutdown/reset. The flag was not consulted in the more frequently invoked play_dead()/hlt_play_dead() used in processor offline and suspend. Since Linux-3.0 there has been a run-time notice upon "no-hlt" invocations indicating that it would be removed in 2012. Signed-off-by: Len Brown Cc: x86@kernel.org --- Documentation/kernel-parameters.txt | 4 ---- arch/x86/include/asm/processor.h | 10 ---------- arch/x86/kernel/cpu/bugs.c | 27 --------------------------- arch/x86/kernel/cpu/proc.c | 2 -- arch/x86/kernel/process.c | 6 ++---- arch/x86/xen/setup.c | 3 --- 6 files changed, 2 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 3b0cd1e612da..109ee45cf20d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1881,10 +1881,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. wfi(ARM) instruction doesn't work correctly and not to use it. This is also useful when using JTAG debugger. - no-hlt [BUGS=X86-32] Tells the kernel that the hlt - instruction doesn't work correctly and not to - use it. - no_file_caps Tells the kernel not to honor file capabilities. The only way then for a file to be executed with privilege is to be setuid root or executed by root. diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 8a28feae1c92..b9e7d279f8ef 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -89,7 +89,6 @@ struct cpuinfo_x86 { char wp_works_ok; /* It doesn't on 386's */ /* Problems on some 486Dx4's and old 386's: */ - char hlt_works_ok; char hard_math; char rfu; char fdiv_bug; @@ -165,15 +164,6 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); extern const struct seq_operations cpuinfo_op; -static inline int hlt_works(int cpu) -{ -#ifdef CONFIG_X86_32 - return cpu_data(cpu).hlt_works_ok; -#else - return 1; -#endif -} - #define cache_line_size() (boot_cpu_data.x86_cache_alignment) extern void cpu_detect(struct cpuinfo_x86 *c); diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 92dfec986a48..af6455e3fcc9 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -17,15 +17,6 @@ #include #include -static int __init no_halt(char *s) -{ - WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n"); - boot_cpu_data.hlt_works_ok = 0; - return 1; -} - -__setup("no-hlt", no_halt); - static int __init no_387(char *s) { boot_cpu_data.hard_math = 0; @@ -89,23 +80,6 @@ static void __init check_fpu(void) pr_warn("Hmm, FPU with FDIV bug\n"); } -static void __init check_hlt(void) -{ - if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) - return; - - pr_info("Checking 'hlt' instruction... "); - if (!boot_cpu_data.hlt_works_ok) { - pr_cont("disabled\n"); - return; - } - halt(); - halt(); - halt(); - halt(); - pr_cont("OK\n"); -} - /* * Check whether we are able to run this kernel safely on SMP. * @@ -129,7 +103,6 @@ void __init check_bugs(void) print_cpu_info(&boot_cpu_data); #endif check_config(); - check_hlt(); init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); alternative_instructions(); diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 3286a92e662a..e280253f6f94 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -28,7 +28,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) { seq_printf(m, "fdiv_bug\t: %s\n" - "hlt_bug\t\t: %s\n" "f00f_bug\t: %s\n" "coma_bug\t: %s\n" "fpu\t\t: %s\n" @@ -36,7 +35,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) "cpuid level\t: %d\n" "wp\t\t: %s\n", c->fdiv_bug ? "yes" : "no", - c->hlt_works_ok ? "no" : "yes", c->f00f_bug ? "yes" : "no", c->coma_bug ? "yes" : "no", c->hard_math ? "yes" : "no", diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index cd5a4c9ef835..aef852eac292 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -415,10 +415,8 @@ void stop_this_cpu(void *dummy) set_cpu_online(smp_processor_id(), false); disable_local_APIC(); - for (;;) { - if (hlt_works(smp_processor_id())) - halt(); - } + for (;;) + halt(); } /* diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 2b73b5c8555f..94eac5c85cdc 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -556,9 +556,6 @@ void __init xen_arch_setup(void) COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE); /* Set up idle, making sure it calls safe_halt() pvop */ -#ifdef CONFIG_X86_32 - boot_cpu_data.hlt_works_ok = 1; -#endif disable_cpuidle(); disable_cpufreq(); WARN_ON(xen_set_default_idle()); -- cgit v1.2.3 From 1ed51011af7450991780f9a7fd916554be19d2a3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 10 Feb 2013 17:19:24 -0500 Subject: tools/power turbostat: display SMI count by default The SMI counter is popular -- so display it by default rather than requiring an option. What the heck, we've blown the 80 column budget on many systems already... Note that the value displayed is the delta during the measurement interval. The absolute value of the counter can still be seen with the generic 32-bit MSR option, ie. -m 0x34 Signed-off-by: Len Brown --- arch/x86/include/uapi/asm/msr-index.h | 1 + tools/power/x86/turbostat/turbostat.8 | 36 ++++++++++++++++------------------- tools/power/x86/turbostat/turbostat.c | 26 +++++++++++++++++++++---- 3 files changed, 39 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index 7bdaf7c9b1e0..8d013f5153bc 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -274,6 +274,7 @@ #define MSR_IA32_PLATFORM_ID 0x00000017 #define MSR_IA32_EBL_CR_POWERON 0x0000002a #define MSR_EBC_FREQUENCY_ID 0x0000002c +#define MSR_SMI_COUNT 0x00000034 #define MSR_IA32_FEATURE_CONTROL 0x0000003a #define MSR_IA32_TSC_ADJUST 0x0000003b diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 0d7dc2cfefb5..b4ddb748356c 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -31,8 +31,6 @@ The \fB-S\fP option limits output to a 1-line System Summary for each interval. .PP The \fB-v\fP option increases verbosity. .PP -The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34" -.PP The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter. .PP The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter. @@ -186,26 +184,24 @@ This is a weighted average, where the weight is %c0. ie. it is the total number un-halted cycles elapsed per time divided by the number of CPUs. .SH SMI COUNTING EXAMPLE On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter. -Using the -m option, you can display how many SMIs have fired since reset, or if there -are SMIs during the measurement interval, you can display the delta using the -d option. +This counter is shown by default under the "SMI" column. .nf -[root@x980 ~]# turbostat -m 0x34 -cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6 - 1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55 - 0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55 - 0 6 0.14 1.63 3.38 0x00000056 5.30 - 1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52 - 1 8 0.10 1.65 3.38 0x00000056 18.05 - 2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50 - 2 10 0.10 1.63 3.38 0x00000056 6.93 - 8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16 - 8 7 0.08 1.64 3.38 0x00000056 5.12 - 9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38 - 9 9 0.09 1.68 3.38 0x00000056 9.32 - 10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23 - 10 11 1.72 1.65 3.38 0x00000056 15.05 +[root@x980 ~]# turbostat +cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 CTMP %pc3 %pc6 + 0.11 1.91 3.38 0 1.84 0.26 97.79 29 0.82 83.87 + 0 0 0.40 1.63 3.38 0 10.27 0.12 89.20 20 0.82 83.88 + 0 6 0.06 1.63 3.38 0 10.61 + 1 2 0.37 2.63 3.38 0 0.02 0.10 99.51 22 + 1 8 0.01 1.62 3.38 0 0.39 + 2 4 0.07 1.62 3.38 0 0.04 0.07 99.82 23 + 2 10 0.02 1.62 3.38 0 0.09 + 8 1 0.23 1.64 3.38 0 0.10 1.07 98.60 24 + 8 7 0.02 1.64 3.38 0 0.31 + 9 3 0.03 1.62 3.38 0 0.03 0.05 99.89 29 + 9 9 0.02 1.62 3.38 0 0.05 + 10 5 0.07 1.62 3.38 0 0.08 0.12 99.73 27 + 10 11 0.03 1.62 3.38 0 0.13 ^C -[root@x980 ~]# .fi .SH NOTES diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 75f64e05ec30..6f3214ed4444 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -58,6 +58,7 @@ unsigned int extra_msr_offset32; unsigned int extra_msr_offset64; unsigned int extra_delta_offset32; unsigned int extra_delta_offset64; +int do_smi; double bclk; unsigned int show_pkg; unsigned int show_core; @@ -99,6 +100,7 @@ struct thread_data { unsigned long long extra_delta64; unsigned long long extra_msr32; unsigned long long extra_delta32; + unsigned int smi_count; unsigned int cpu_id; unsigned int flags; #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 @@ -248,6 +250,8 @@ void print_header(void) if (has_aperf) outp += sprintf(outp, " GHz"); outp += sprintf(outp, " TSC"); + if (do_smi) + outp += sprintf(outp, " SMI"); if (extra_delta_offset32) outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); if (extra_delta_offset64) @@ -314,6 +318,8 @@ int dump_counters(struct thread_data *t, struct core_data *c, extra_msr_offset32, t->extra_msr32); fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset64, t->extra_msr64); + if (do_smi) + fprintf(stderr, "SMI: %08X\n", t->smi_count); } if (c) { @@ -352,6 +358,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, * RAM_W: %5.2 * GHz: "GHz" 3 columns %3.2 * TSC: "TSC" 3 columns %3.2 + * SMI: "SMI" 4 columns %4d * percentage " %pc3" %6.2 * Perf Status percentage: %5.2 * "CTMP" 4 columns %4d @@ -431,6 +438,10 @@ int format_counters(struct thread_data *t, struct core_data *c, /* TSC */ outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); + /* SMI */ + if (do_smi) + outp += sprintf(outp, "%4d", t->smi_count); + /* delta */ if (extra_delta_offset32) outp += sprintf(outp, " %11llu", t->extra_delta32); @@ -645,6 +656,9 @@ delta_thread(struct thread_data *new, struct thread_data *old, */ old->extra_msr32 = new->extra_msr32; old->extra_msr64 = new->extra_msr64; + + if (do_smi) + old->smi_count = new->smi_count - old->smi_count; } int delta_cpu(struct thread_data *t, struct core_data *c, @@ -672,6 +686,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data t->mperf = 0; t->c1 = 0; + t->smi_count = 0; t->extra_delta32 = 0; t->extra_delta64 = 0; @@ -802,6 +817,11 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) return -4; } + if (do_smi) { + if (get_msr(cpu, MSR_SMI_COUNT, &msr)) + return -5; + t->smi_count = msr & 0xFFFFFFFF; + } if (extra_delta_offset32) { if (get_msr(cpu, extra_delta_offset32, &msr)) return -5; @@ -1893,6 +1913,7 @@ void check_cpuid() do_nehalem_platform_info = genuine_intel && has_invariant_tsc; do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ + do_smi = do_nhm_cstates; do_snb_cstates = is_snb(family, model); bclk = discover_bclk(family, model); @@ -2229,9 +2250,6 @@ void cmdline(int argc, char **argv) case 'c': sscanf(optarg, "%x", &extra_delta_offset32); break; - case 's': - extra_delta_offset32 = 0x34; /* SMI counter */ - break; case 'C': sscanf(optarg, "%x", &extra_delta_offset64); break; @@ -2258,7 +2276,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose) - fprintf(stderr, "turbostat v3.1 January 8, 2013" + fprintf(stderr, "turbostat v3.2 February 11, 2013" " - Len Brown \n"); turbostat_init(); -- cgit v1.2.3 From dd8af076262cc1ff85a8d5e0c5b1a4716d19fe25 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 21:10:04 -0500 Subject: APM idle: register apm_cpu_idle via cpuidle Update APM to register its local idle routine with cpuidle. This allows us to stop exporting pm_idle to modules on x86. The Kconfig sub-option, APM_CPU_IDLE, now depends on on CPU_IDLE. Compile-tested only. Signed-off-by: Len Brown Reviewed-by: Daniel Lezcano Cc: Jiri Kosina --- arch/x86/Kconfig | 1 + arch/x86/kernel/apm_32.c | 57 ++++++++++++++++++++++++++++------------------- arch/x86/kernel/process.c | 3 --- 3 files changed, 35 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 225543bf45a5..1b635861401c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1912,6 +1912,7 @@ config APM_DO_ENABLE this feature. config APM_CPU_IDLE + depends on CPU_IDLE bool "Make CPU Idle calls when idle" ---help--- Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index d65464e43503..9f4bc6a1164d 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -232,6 +232,7 @@ #include #include #include +#include #include #include @@ -360,13 +361,35 @@ struct apm_user { * idle percentage above which bios idle calls are done */ #ifdef CONFIG_APM_CPU_IDLE -#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012 #define DEFAULT_IDLE_THRESHOLD 95 #else #define DEFAULT_IDLE_THRESHOLD 100 #endif #define DEFAULT_IDLE_PERIOD (100 / 3) +static int apm_cpu_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); + +static struct cpuidle_driver apm_idle_driver = { + .name = "apm_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states = { + { /* entry 0 is for polling */ }, + { /* entry 1 is for APM idle */ + .name = "APM", + .desc = "APM idle", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 250, /* WAG */ + .target_residency = 500, /* WAG */ + .enter = &apm_cpu_idle + }, + }, + .state_count = 2, +}; + +static struct cpuidle_device apm_cpuidle_device; + /* * Local variables */ @@ -377,7 +400,6 @@ static struct { static int clock_slowed; static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; -static int set_pm_idle; static int suspends_pending; static int standbys_pending; static int ignore_sys_suspend; @@ -884,8 +906,6 @@ static void apm_do_busy(void) #define IDLE_CALC_LIMIT (HZ * 100) #define IDLE_LEAKY_MAX 16 -static void (*original_pm_idle)(void) __read_mostly; - /** * apm_cpu_idle - cpu idling for APM capable Linux * @@ -894,7 +914,8 @@ static void (*original_pm_idle)(void) __read_mostly; * Furthermore it calls the system default idle routine. */ -static void apm_cpu_idle(void) +static int apm_cpu_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { static int use_apm_idle; /* = 0 */ static unsigned int last_jiffies; /* = 0 */ @@ -904,7 +925,6 @@ static void apm_cpu_idle(void) unsigned int jiffies_since_last_check = jiffies - last_jiffies; unsigned int bucket; - WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012"); recalc: if (jiffies_since_last_check > IDLE_CALC_LIMIT) { use_apm_idle = 0; @@ -950,10 +970,7 @@ recalc: break; } } - if (original_pm_idle) - original_pm_idle(); - else - default_idle(); + default_idle(); local_irq_disable(); jiffies_since_last_check = jiffies - last_jiffies; if (jiffies_since_last_check > idle_period) @@ -963,7 +980,7 @@ recalc: if (apm_idle_done) apm_do_busy(); - local_irq_enable(); + return index; } /** @@ -2381,9 +2398,9 @@ static int __init apm_init(void) if (HZ != 100) idle_period = (idle_period * HZ) / 100; if (idle_threshold < 100) { - original_pm_idle = pm_idle; - pm_idle = apm_cpu_idle; - set_pm_idle = 1; + if (!cpuidle_register_driver(&apm_idle_driver)) + if (cpuidle_register_device(&apm_cpuidle_device)) + cpuidle_unregister_driver(&apm_idle_driver); } return 0; @@ -2393,15 +2410,9 @@ static void __exit apm_exit(void) { int error; - if (set_pm_idle) { - pm_idle = original_pm_idle; - /* - * We are about to unload the current idle thread pm callback - * (pm_idle), Wait for all processors to update cached/local - * copies of pm_idle before proceeding. - */ - kick_all_cpus_sync(); - } + cpuidle_unregister_device(&apm_cpuidle_device); + cpuidle_unregister_driver(&apm_idle_driver); + if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0) && (apm_info.connection_version > 0x0100)) { error = apm_engage_power_management(APM_DEVICE_ALL, 0); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2ed787f15bf0..f571a6e08710 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -272,9 +272,6 @@ EXPORT_SYMBOL(boot_option_idle_override); * Powermanagement idle function, if any.. */ void (*pm_idle)(void); -#ifdef CONFIG_APM_MODULE -EXPORT_SYMBOL(pm_idle); -#endif #ifndef CONFIG_SMP static inline void play_dead(void) -- cgit v1.2.3 From a476bda30baf7efa7f305793a340aae07b6e5780 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 21:45:03 -0500 Subject: x86 idle: rename global pm_idle to static x86_idle (pm_idle)() is being removed from linux/pm.h because Linux does not have such a cross-architecture concept. x86 uses an idle function pointer in its architecture specific code as a backup to cpuidle. So we re-name x86 use of pm_idle to x86_idle, and make it static to x86. Signed-off-by: Len Brown Cc: x86@kernel.org --- arch/x86/kernel/process.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f571a6e08710..ceb05db59be1 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -268,10 +268,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; EXPORT_SYMBOL(boot_option_idle_override); -/* - * Powermanagement idle function, if any.. - */ -void (*pm_idle)(void); +static void (*x86_idle)(void); #ifndef CONFIG_SMP static inline void play_dead(void) @@ -348,7 +345,7 @@ void cpu_idle(void) rcu_idle_enter(); if (cpuidle_idle_call()) - pm_idle(); + x86_idle(); rcu_idle_exit(); start_critical_timings(); @@ -395,9 +392,9 @@ EXPORT_SYMBOL(default_idle); bool set_pm_idle_to_default(void) { - bool ret = !!pm_idle; + bool ret = !!x86_idle; - pm_idle = default_idle; + x86_idle = default_idle; return ret; } @@ -564,11 +561,10 @@ static void amd_e400_idle(void) void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP - if (pm_idle == poll_idle && smp_num_siblings > 1) { + if (x86_idle == poll_idle && smp_num_siblings > 1) pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n"); - } #endif - if (pm_idle) + if (x86_idle) return; if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { @@ -576,19 +572,19 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) * One CPU supports mwait => All CPUs supports mwait */ pr_info("using mwait in idle threads\n"); - pm_idle = mwait_idle; + x86_idle = mwait_idle; } else if (cpu_has_amd_erratum(amd_erratum_400)) { /* E400: APIC timer interrupt does not wake up CPU from C1e */ pr_info("using AMD E400 aware idle routine\n"); - pm_idle = amd_e400_idle; + x86_idle = amd_e400_idle; } else - pm_idle = default_idle; + x86_idle = default_idle; } void __init init_amd_e400_c1e_mask(void) { /* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */ - if (pm_idle == amd_e400_idle) + if (x86_idle == amd_e400_idle) zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL); } @@ -599,7 +595,7 @@ static int __init idle_setup(char *str) if (!strcmp(str, "poll")) { pr_info("using polling idle threads\n"); - pm_idle = poll_idle; + x86_idle = poll_idle; boot_option_idle_override = IDLE_POLL; } else if (!strcmp(str, "mwait")) { boot_option_idle_override = IDLE_FORCE_MWAIT; @@ -612,7 +608,7 @@ static int __init idle_setup(char *str) * To continue to load the CPU idle driver, don't touch * the boot_option_idle_override. */ - pm_idle = default_idle; + x86_idle = default_idle; boot_option_idle_override = IDLE_HALT; } else if (!strcmp(str, "nomwait")) { /* -- cgit v1.2.3 From 3738fa5bbc3acaf6a807cb45f4367cbab412faee Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:52:57 -0500 Subject: sh idle: rename global pm_idle to static sh_idle SH idle code could use some simplification. This patch enables that by guaranteeing that "sh_idle" is local, and thus architecture specific. Signed-off-by: Len Brown Cc: linux-sh@vger.kernel.org --- arch/sh/kernel/idle.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 0c910163caa3..3d5a1b387cc0 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -22,7 +22,7 @@ #include #include -void (*pm_idle)(void); +static void (*sh_idle)(void); static int hlt_counter; @@ -103,9 +103,9 @@ void cpu_idle(void) /* Don't trace irqs off for idle */ stop_critical_timings(); if (cpuidle_idle_call()) - pm_idle(); + sh_idle(); /* - * Sanity check to ensure that pm_idle() returns + * Sanity check to ensure that sh_idle() returns * with IRQs enabled */ WARN_ON(irqs_disabled()); @@ -123,13 +123,13 @@ void __init select_idle_routine(void) /* * If a platform has set its own idle routine, leave it alone. */ - if (pm_idle) + if (sh_idle) return; if (hlt_works()) - pm_idle = default_idle; + sh_idle = default_idle; else - pm_idle = poll_idle; + sh_idle = poll_idle; } void stop_this_cpu(void *unused) -- cgit v1.2.3 From d472ba840d622e48f5c94369263ef3af18ab64f8 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 23:27:26 -0500 Subject: sparc idle: rename pm_idle to sparc_idle (pm_idle)() is being removed from linux/pm.h because Linux does not have such a cross-architecture concept. sparc uses an idle function pointer in its architecture specific code. So we re-name sparc use of pm_idle to sparc_idle. Signed-off-by: Len Brown Acked-by: David S. Miller Acked-by: Sam Ravnborg --- arch/sparc/include/asm/processor_32.h | 1 + arch/sparc/kernel/apc.c | 3 ++- arch/sparc/kernel/leon_pmc.c | 5 +++-- arch/sparc/kernel/pmc.c | 3 ++- arch/sparc/kernel/process_32.c | 7 +++---- 5 files changed, 11 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index c1e01914fd98..2c7baa4c4505 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h @@ -118,6 +118,7 @@ extern unsigned long get_wchan(struct task_struct *); extern struct task_struct *last_task_used_math; #define cpu_relax() barrier() +extern void (*sparc_idle)(void); #endif diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 348fa1aeabce..eefda32b595e 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Debugging * @@ -158,7 +159,7 @@ static int apc_probe(struct platform_device *op) /* Assign power management IDLE handler */ if (!apc_no_idle) - pm_idle = apc_swift_idle; + sparc_idle = apc_swift_idle; printk(KERN_INFO "%s: power management initialized%s\n", APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index 4e174321097d..708bca435219 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c @@ -9,6 +9,7 @@ #include #include #include +#include /* List of Systems that need fixup instructions around power-down instruction */ unsigned int pmc_leon_fixup_ids[] = { @@ -69,9 +70,9 @@ static int __init leon_pmc_install(void) if (sparc_cpu_model == sparc_leon) { /* Assign power management IDLE handler */ if (pmc_leon_need_fixup()) - pm_idle = pmc_leon_idle_fixup; + sparc_idle = pmc_leon_idle_fixup; else - pm_idle = pmc_leon_idle; + sparc_idle = pmc_leon_idle; printk(KERN_INFO "leon: power management initialized\n"); } diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index dcbb62f63068..8b7297faca79 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -17,6 +17,7 @@ #include #include #include +#include /* Debug * @@ -63,7 +64,7 @@ static int pmc_probe(struct platform_device *op) #ifndef PMC_NO_IDLE /* Assign power management IDLE handler */ - pm_idle = pmc_swift_idle; + sparc_idle = pmc_swift_idle; #endif printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME); diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index be8e862badaf..62eede13831a 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -43,8 +43,7 @@ * Power management idle function * Set in pm platform drivers (apc.c and pmc.c) */ -void (*pm_idle)(void); -EXPORT_SYMBOL(pm_idle); +void (*sparc_idle)(void); /* * Power-off handler instantiation for pm.h compliance @@ -75,8 +74,8 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ for (;;) { while (!need_resched()) { - if (pm_idle) - (*pm_idle)(); + if (sparc_idle) + (*sparc_idle)(); else cpu_relax(); } -- cgit v1.2.3 From 26bab0c976c5984e313d17d54997b74641f32544 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:17:47 -0500 Subject: blackfin idle: delete pm_idle pm_idle is dead code on blackfin. Signed-off-by: Len Brown Cc: uclinux-dist-devel@blackfin.uclinux.org --- arch/blackfin/kernel/process.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 3e16ad9b0a99..8061426b7df5 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -39,12 +39,6 @@ int nr_l1stack_tasks; void *l1_stack_base; unsigned long l1_stack_len; -/* - * Powermanagement idle function, if any.. - */ -void (*pm_idle)(void) = NULL; -EXPORT_SYMBOL(pm_idle); - void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); @@ -81,7 +75,6 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { - void (*idle)(void) = pm_idle; #ifdef CONFIG_HOTPLUG_CPU if (cpu_is_offline(smp_processor_id())) -- cgit v1.2.3 From b0ea11497c8cbc5a66019814efa1733e47e47ab1 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:22:38 -0500 Subject: ARM idle: delete pm_idle pm_idle() on ARM was a synonym for default_idle(), so simply invoke default_idle() directly. Signed-off-by: Len Brown Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman --- arch/arm/kernel/process.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index c6dec5fc20aa..047d3e40e470 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -172,14 +172,9 @@ static void default_idle(void) local_irq_enable(); } -void (*pm_idle)(void) = default_idle; -EXPORT_SYMBOL(pm_idle); - /* - * The idle thread, has rather strange semantics for calling pm_idle, - * but this is what x86 does and we need to do the same, so that - * things like cpuidle get called in the same way. The only difference - * is that we always respect 'hlt_counter' to prevent low power idle. + * The idle thread. + * We always respect 'hlt_counter' to prevent low power idle. */ void cpu_idle(void) { @@ -210,10 +205,10 @@ void cpu_idle(void) } else if (!need_resched()) { stop_critical_timings(); if (cpuidle_idle_call()) - pm_idle(); + default_idle(); start_critical_timings(); /* - * pm_idle functions must always + * default_idle functions must always * return with IRQs enabled. */ WARN_ON(irqs_disabled()); -- cgit v1.2.3 From dc883ca34a4e8a309d652c86daab6f1b4edd9d4b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 23:15:13 -0500 Subject: ARM64 idle: delete pm_idle pm_idle() on arm64 was a synonym for default_idle(), so remove it and invoke default_idle() directly. Signed-off-by: Len Brown Acked-by: Catalin Marinas --- arch/arm64/kernel/process.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index cb0956bc96ed..c7002d40a9b0 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -97,14 +97,9 @@ static void default_idle(void) local_irq_enable(); } -void (*pm_idle)(void) = default_idle; -EXPORT_SYMBOL_GPL(pm_idle); - /* - * The idle thread, has rather strange semantics for calling pm_idle, - * but this is what x86 does and we need to do the same, so that - * things like cpuidle get called in the same way. The only difference - * is that we always respect 'hlt_counter' to prevent low power idle. + * The idle thread. + * We always respect 'hlt_counter' to prevent low power idle. */ void cpu_idle(void) { @@ -122,10 +117,10 @@ void cpu_idle(void) local_irq_disable(); if (!need_resched()) { stop_critical_timings(); - pm_idle(); + default_idle(); start_critical_timings(); /* - * pm_idle functions should always return + * default_idle functions should always return * with IRQs enabled. */ WARN_ON(irqs_disabled()); -- cgit v1.2.3 From 28f14185c818c3b6a02b4e0dc00d9aca100ce024 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:34:18 -0500 Subject: cris idle: delete idle and pm_idle pm_idle() and idle() served no purpose on cris -- invoke default_idle() directly. Signed-off-by: Len Brown Acked-by: Jesper Nilsson --- arch/cris/kernel/process.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 7f65be6f7f17..104ff4dd9b98 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -54,11 +54,6 @@ void enable_hlt(void) EXPORT_SYMBOL(enable_hlt); -/* - * The following aren't currently used. - */ -void (*pm_idle)(void); - extern void default_idle(void); void (*pm_power_off)(void); @@ -77,16 +72,12 @@ void cpu_idle (void) while (1) { rcu_idle_enter(); while (!need_resched()) { - void (*idle)(void); /* * Mark this as an RCU critical section so that * synchronize_kernel() in the unload path waits * for our completion. */ - idle = pm_idle; - if (!idle) - idle = default_idle; - idle(); + default_idle(); } rcu_idle_exit(); schedule_preempt_disabled(); -- cgit v1.2.3 From 3e7fc708eb41f6385cf5cf64a68417a4be822be8 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:28:34 -0500 Subject: ia64 idle: delete pm_idle pm_idle() on ia64 was a synonym for default_idle(). So simply invoke default_idle() directly. Signed-off-by: Len Brown Cc: linux-ia64@vger.kernel.org --- arch/ia64/kernel/process.c | 3 --- arch/ia64/kernel/setup.c | 1 - 2 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 31360cbbd5f8..e34f565f595a 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -57,8 +57,6 @@ void (*ia64_mark_idle)(int); unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; EXPORT_SYMBOL(boot_option_idle_override); -void (*pm_idle) (void); -EXPORT_SYMBOL(pm_idle); void (*pm_power_off) (void); EXPORT_SYMBOL(pm_power_off); @@ -301,7 +299,6 @@ cpu_idle (void) if (mark_idle) (*mark_idle)(1); - idle = pm_idle; if (!idle) idle = default_idle; (*idle)(); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index aaefd9b94f2f..2029cc0d2fc6 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -1051,7 +1051,6 @@ cpu_init (void) max_num_phys_stacked = num_phys_stacked; } platform_cpu_init(); - pm_idle = default_idle; } void __init -- cgit v1.2.3 From 1d8225661e2407241dbf16143180ff673668d6d7 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:42:39 -0500 Subject: m32r idle: delete pm_idle, and other dead idle code All paths on m32r lead to cpu_relax(). So delete the dead code and simply call cpu_relax() directly. Signed-off-by: Len Brown Cc: linux-m32r@ml.linux-m32r.org --- arch/m32r/kernel/process.c | 51 ++-------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 765d0f57c787..bde899e155d3 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -44,35 +44,9 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return tsk->thread.lr; } -/* - * Powermanagement idle function, if any.. - */ -static void (*pm_idle)(void) = NULL; - void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); -/* - * We use this is we don't have any better - * idle routine.. - */ -static void default_idle(void) -{ - /* M32R_FIXME: Please use "cpu_sleep" mode. */ - cpu_relax(); -} - -/* - * On SMP it's slightly faster (but much more power-consuming!) - * to poll the ->work.need_resched flag instead of waiting for the - * cross-CPU IPI to arrive. Use this option with caution. - */ -static void poll_idle (void) -{ - /* M32R_FIXME */ - cpu_relax(); -} - /* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a @@ -84,14 +58,8 @@ void cpu_idle (void) /* endless idle loop with no priority at all */ while (1) { rcu_idle_enter(); - while (!need_resched()) { - void (*idle)(void) = pm_idle; - - if (!idle) - idle = default_idle; - - idle(); - } + while (!need_resched()) + cpu_relax(); rcu_idle_exit(); schedule_preempt_disabled(); } @@ -120,21 +88,6 @@ void machine_power_off(void) /* M32R_FIXME */ } -static int __init idle_setup (char *str) -{ - if (!strncmp(str, "poll", 4)) { - printk("using poll in idle threads.\n"); - pm_idle = poll_idle; - } else if (!strncmp(str, "sleep", 4)) { - printk("using sleep in idle threads.\n"); - pm_idle = default_idle; - } - - return 1; -} - -__setup("idle=", idle_setup); - void show_regs(struct pt_regs * regs) { printk("\n"); -- cgit v1.2.3 From def82035a81dd1f46b88cd2cd3f2f8a75b3d6b6d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:31:57 -0500 Subject: microblaze idle: delete pm_idle pm_idle on microblaze served no purpose. Signed-off-by: Len Brown Cc: microblaze-uclinux@itee.uq.edu.au --- arch/microblaze/kernel/process.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index a5b74f729e5b..6ff2dcff3410 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c @@ -41,7 +41,6 @@ void show_regs(struct pt_regs *regs) regs->msr, regs->ear, regs->esr, regs->fsr); } -void (*pm_idle)(void); void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); @@ -98,8 +97,6 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { - void (*idle)(void) = pm_idle; - if (!idle) idle = default_idle; -- cgit v1.2.3 From 7626f93316aeb05575a8f46106c5507f8604fd74 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:30:27 -0500 Subject: mn10300 idle: delete pm_idle pm_idle on mn10300 served no purpose. Signed-off-by: Len Brown Cc: linux-am33-list@redhat.com --- arch/mn10300/kernel/process.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index eb09f5a552ff..84f4e97e3074 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c @@ -36,12 +36,6 @@ #include #include "internal.h" -/* - * power management idle function, if any.. - */ -void (*pm_idle)(void); -EXPORT_SYMBOL(pm_idle); - /* * return saved PC of a blocked thread. */ @@ -113,7 +107,6 @@ void cpu_idle(void) void (*idle)(void); smp_rmb(); - idle = pm_idle; if (!idle) { #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU) idle = poll_idle; -- cgit v1.2.3 From ed9831407bcc73abd6cb80549d5d028a8809a488 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:26:31 -0500 Subject: openrisc idle: delete pm_idle pm_idle() on openrisc was dead code. Signed-off-by: Len Brown Cc: linux@lists.openrisc.net --- arch/openrisc/kernel/idle.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/openrisc/kernel/idle.c b/arch/openrisc/kernel/idle.c index 7d618feb1b72..5e8a3b6d6bc6 100644 --- a/arch/openrisc/kernel/idle.c +++ b/arch/openrisc/kernel/idle.c @@ -39,11 +39,6 @@ void (*powersave) (void) = NULL; -static inline void pm_idle(void) -{ - barrier(); -} - void cpu_idle(void) { set_thread_flag(TIF_POLLING_NRFLAG); -- cgit v1.2.3 From 6ae236c05d46f48ac3d002a8643cda422f6e79dd Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 9 Feb 2013 22:47:22 -0500 Subject: unicore32 idle: delete stray pm_idle comment as pm_idle() has already been deleted from this code, the comment was a stray. Signed-off-by: Len Brown Cc: Guan Xuetao --- arch/unicore32/kernel/process.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index 62bad9fed03e..872d7e22d847 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -45,11 +45,6 @@ static const char * const processor_modes[] = { "UK18", "UK19", "UK1A", "EXTN", "UK1C", "UK1D", "UK1E", "SUSR" }; -/* - * The idle thread, has rather strange semantics for calling pm_idle, - * but this is what x86 does and we need to do the same, so that - * things like cpuidle get called in the same way. - */ void cpu_idle(void) { /* endless idle loop with no priority at all */ -- cgit v1.2.3