From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Krzysztof Kozlowski To: Kukjin Kim , Krzysztof Kozlowski , Rob Herring , Mark Rutland , Tejun Heo , Sylwester Nawrocki , Tomasz Figa , Chanwoo Choi , Michael Turquette , Stephen Boyd , "Rafael J. Wysocki" , Viresh Kumar , Zhang Rui , Eduardo Valentin , Russell King , Hans de Goede , Linus Walleij , Andi Shyti , Mark Brown , Bartlomiej Zolnierkiewicz , Alan Stern , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org, linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, linux-spi@vger.kernel.org, linux-usb@vger.kernel.org Cc: Marek Szyprowski , Arnd Bergmann , Olof Johansson , Jaehoon Chung Subject: [RFC 03/10] cpufreq: exynos: Remove support for Exynos5440 Date: Tue, 24 Apr 2018 22:32:32 +0200 Message-Id: <20180424203239.21885-4-krzk@kernel.org> In-Reply-To: <20180424203239.21885-1-krzk@kernel.org> References: <20180424203239.21885-1-krzk@kernel.org> List-ID: The Exynos5440 is not actively developed, there are no development boards available and probably there are no real products with it. Remove wide-tree support for Exynos5440. Signed-off-by: Krzysztof Kozlowski --- .../bindings/cpufreq/cpufreq-exynos5440.txt | 28 -- drivers/cpufreq/Kconfig.arm | 14 - drivers/cpufreq/Makefile | 1 - drivers/cpufreq/exynos5440-cpufreq.c | 452 --------------------- 4 files changed, 495 deletions(-) delete mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt delete mode 100644 drivers/cpufreq/exynos5440-cpufreq.c diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt deleted file mode 100644 index caff1a57436f..000000000000 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt +++ /dev/null @@ -1,28 +0,0 @@ - -Exynos5440 cpufreq driver -------------------- - -Exynos5440 SoC cpufreq driver for CPU frequency scaling. - -Required properties: -- interrupts: Interrupt to know the completion of cpu frequency change. -- operating-points: Table of frequencies and voltage CPU could be transitioned into, - in the decreasing order. Frequency should be in KHz units and voltage - should be in microvolts. - -Optional properties: -- clock-latency: Clock monitor latency in microsecond. - -All the required listed above must be defined under node cpufreq. - -Example: --------- - cpufreq@160000 { - compatible = "samsung,exynos5440-cpufreq"; - reg = <0x160000 0x1000>; - interrupts = <0 57 0>; - operating-points = < - 1000000 975000 - 800000 925000>; - clock-latency = <100000>; - }; diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 7f56fe5183f2..538a4004a2c5 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -81,20 +81,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG If in doubt, say N. -config ARM_EXYNOS5440_CPUFREQ - tristate "SAMSUNG EXYNOS5440" - depends on SOC_EXYNOS5440 - depends on HAVE_CLK && OF - select PM_OPP - default y - help - This adds the CPUFreq driver for Samsung EXYNOS5440 - SoC. The nature of exynos5440 clock controller is - different than previous exynos controllers so not using - the common exynos framework. - - If in doubt, say N. - config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" depends on ARCH_HIGHBANK && CPUFREQ_DT && REGULATOR diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 8d24ade3bd02..56724f867f78 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -56,7 +56,6 @@ obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c deleted file mode 100644 index 932caa386ece..000000000000 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (c) 2013 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Amit Daniel Kachhap - * - * EXYNOS5440 - CPU frequency scaling support - * - * 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. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register definitions */ -#define XMU_DVFS_CTRL 0x0060 -#define XMU_PMU_P0_7 0x0064 -#define XMU_C0_3_PSTATE 0x0090 -#define XMU_P_LIMIT 0x00a0 -#define XMU_P_STATUS 0x00a4 -#define XMU_PMUEVTEN 0x00d0 -#define XMU_PMUIRQEN 0x00d4 -#define XMU_PMUIRQ 0x00d8 - -/* PMU mask and shift definations */ -#define P_VALUE_MASK 0x7 - -#define XMU_DVFS_CTRL_EN_SHIFT 0 - -#define P0_7_CPUCLKDEV_SHIFT 21 -#define P0_7_CPUCLKDEV_MASK 0x7 -#define P0_7_ATBCLKDEV_SHIFT 18 -#define P0_7_ATBCLKDEV_MASK 0x7 -#define P0_7_CSCLKDEV_SHIFT 15 -#define P0_7_CSCLKDEV_MASK 0x7 -#define P0_7_CPUEMA_SHIFT 28 -#define P0_7_CPUEMA_MASK 0xf -#define P0_7_L2EMA_SHIFT 24 -#define P0_7_L2EMA_MASK 0xf -#define P0_7_VDD_SHIFT 8 -#define P0_7_VDD_MASK 0x7f -#define P0_7_FREQ_SHIFT 0 -#define P0_7_FREQ_MASK 0xff - -#define C0_3_PSTATE_VALID_SHIFT 8 -#define C0_3_PSTATE_CURR_SHIFT 4 -#define C0_3_PSTATE_NEW_SHIFT 0 - -#define PSTATE_CHANGED_EVTEN_SHIFT 0 - -#define PSTATE_CHANGED_IRQEN_SHIFT 0 - -#define PSTATE_CHANGED_SHIFT 0 - -/* some constant values for clock divider calculation */ -#define CPU_DIV_FREQ_MAX 500 -#define CPU_DBG_FREQ_MAX 375 -#define CPU_ATB_FREQ_MAX 500 - -#define PMIC_LOW_VOLT 0x30 -#define PMIC_HIGH_VOLT 0x28 - -#define CPUEMA_HIGH 0x2 -#define CPUEMA_MID 0x4 -#define CPUEMA_LOW 0x7 - -#define L2EMA_HIGH 0x1 -#define L2EMA_MID 0x3 -#define L2EMA_LOW 0x4 - -#define DIV_TAB_MAX 2 -/* frequency unit is 20MHZ */ -#define FREQ_UNIT 20 -#define MAX_VOLTAGE 1550000 /* In microvolt */ -#define VOLTAGE_STEP 12500 /* In microvolt */ - -#define CPUFREQ_NAME "exynos5440_dvfs" -#define DEF_TRANS_LATENCY 100000 - -enum cpufreq_level_index { - L0, L1, L2, L3, L4, - L5, L6, L7, L8, L9, -}; -#define CPUFREQ_LEVEL_END (L7 + 1) - -struct exynos_dvfs_data { - void __iomem *base; - struct resource *mem; - int irq; - struct clk *cpu_clk; - unsigned int latency; - struct cpufreq_frequency_table *freq_table; - unsigned int freq_count; - struct device *dev; - bool dvfs_enabled; - struct work_struct irq_work; -}; - -static struct exynos_dvfs_data *dvfs_info; -static DEFINE_MUTEX(cpufreq_lock); -static struct cpufreq_freqs freqs; - -static int init_div_table(void) -{ - struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table; - unsigned int tmp, clk_div, ema_div, freq, volt_id, idx; - struct dev_pm_opp *opp; - - cpufreq_for_each_entry_idx(pos, freq_tbl, idx) { - opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, - pos->frequency * 1000, true); - if (IS_ERR(opp)) { - dev_err(dvfs_info->dev, - "failed to find valid OPP for %u KHZ\n", - pos->frequency); - return PTR_ERR(opp); - } - - freq = pos->frequency / 1000; /* In MHZ */ - clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) - << P0_7_CPUCLKDEV_SHIFT; - clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) - << P0_7_ATBCLKDEV_SHIFT; - clk_div |= ((freq / CPU_DBG_FREQ_MAX) & P0_7_CSCLKDEV_MASK) - << P0_7_CSCLKDEV_SHIFT; - - /* Calculate EMA */ - volt_id = dev_pm_opp_get_voltage(opp); - - volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; - if (volt_id < PMIC_HIGH_VOLT) { - ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | - (L2EMA_HIGH << P0_7_L2EMA_SHIFT); - } else if (volt_id > PMIC_LOW_VOLT) { - ema_div = (CPUEMA_LOW << P0_7_CPUEMA_SHIFT) | - (L2EMA_LOW << P0_7_L2EMA_SHIFT); - } else { - ema_div = (CPUEMA_MID << P0_7_CPUEMA_SHIFT) | - (L2EMA_MID << P0_7_L2EMA_SHIFT); - } - - tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) - | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); - - __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx); - dev_pm_opp_put(opp); - } - - return 0; -} - -static void exynos_enable_dvfs(unsigned int cur_frequency) -{ - unsigned int tmp, cpu; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - struct cpufreq_frequency_table *pos; - /* Disable DVFS */ - __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); - - /* Enable PSTATE Change Event */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN); - tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN); - - /* Enable PSTATE Change IRQ */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN); - tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); - - /* Set initial performance index */ - cpufreq_for_each_entry(pos, freq_table) - if (pos->frequency == cur_frequency) - break; - - if (pos->frequency == CPUFREQ_TABLE_END) { - dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); - /* Assign the highest frequency */ - pos = freq_table; - cur_frequency = pos->frequency; - } - - dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", - cur_frequency); - - for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - } - - /* Enable DVFS */ - __raw_writel(1 << XMU_DVFS_CTRL_EN_SHIFT, - dvfs_info->base + XMU_DVFS_CTRL); -} - -static int exynos_target(struct cpufreq_policy *policy, unsigned int index) -{ - unsigned int tmp; - int i; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - mutex_lock(&cpufreq_lock); - - freqs.old = policy->cur; - freqs.new = freq_table[index].frequency; - - cpufreq_freq_transition_begin(policy, &freqs); - - /* Set the target frequency in all C0_3_PSTATE register */ - for_each_cpu(i, policy->cpus) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= (index << C0_3_PSTATE_NEW_SHIFT); - - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - } - mutex_unlock(&cpufreq_lock); - return 0; -} - -static void exynos_cpufreq_work(struct work_struct *work) -{ - unsigned int cur_pstate, index; - struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */ - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - /* Ensure we can access cpufreq structures */ - if (unlikely(dvfs_info->dvfs_enabled == false)) - goto skip_work; - - mutex_lock(&cpufreq_lock); - freqs.old = policy->cur; - - cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); - if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) - index = (cur_pstate >> C0_3_PSTATE_CURR_SHIFT) & P_VALUE_MASK; - else - index = (cur_pstate >> C0_3_PSTATE_NEW_SHIFT) & P_VALUE_MASK; - - if (likely(index < dvfs_info->freq_count)) { - freqs.new = freq_table[index].frequency; - } else { - dev_crit(dvfs_info->dev, "New frequency out of range\n"); - freqs.new = freqs.old; - } - cpufreq_freq_transition_end(policy, &freqs, 0); - - cpufreq_cpu_put(policy); - mutex_unlock(&cpufreq_lock); -skip_work: - enable_irq(dvfs_info->irq); -} - -static irqreturn_t exynos_cpufreq_irq(int irq, void *id) -{ - unsigned int tmp; - - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQ); - if (tmp >> PSTATE_CHANGED_SHIFT & 0x1) { - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQ); - disable_irq_nosync(irq); - schedule_work(&dvfs_info->irq_work); - } - return IRQ_HANDLED; -} - -static void exynos_sort_descend_freq_table(void) -{ - struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; - int i = 0, index; - unsigned int tmp_freq; - /* - * Exynos5440 clock controller state logic expects the cpufreq table to - * be in descending order. But the OPP library constructs the table in - * ascending order. So to make the table descending we just need to - * swap the i element with the N - i element. - */ - for (i = 0; i < dvfs_info->freq_count / 2; i++) { - index = dvfs_info->freq_count - i - 1; - tmp_freq = freq_tbl[i].frequency; - freq_tbl[i].frequency = freq_tbl[index].frequency; - freq_tbl[index].frequency = tmp_freq; - } -} - -static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - policy->clk = dvfs_info->cpu_clk; - return cpufreq_generic_init(policy, dvfs_info->freq_table, - dvfs_info->latency); -} - -static struct cpufreq_driver exynos_driver = { - .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION | - CPUFREQ_NEED_INITIAL_FREQ_CHECK, - .verify = cpufreq_generic_frequency_table_verify, - .target_index = exynos_target, - .get = cpufreq_generic_get, - .init = exynos_cpufreq_cpu_init, - .name = CPUFREQ_NAME, - .attr = cpufreq_generic_attr, -}; - -static const struct of_device_id exynos_cpufreq_match[] = { - { - .compatible = "samsung,exynos5440-cpufreq", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, exynos_cpufreq_match); - -static int exynos_cpufreq_probe(struct platform_device *pdev) -{ - int ret = -EINVAL; - struct device_node *np; - struct resource res; - unsigned int cur_frequency; - - np = pdev->dev.of_node; - if (!np) - return -ENODEV; - - dvfs_info = devm_kzalloc(&pdev->dev, sizeof(*dvfs_info), GFP_KERNEL); - if (!dvfs_info) { - ret = -ENOMEM; - goto err_put_node; - } - - dvfs_info->dev = &pdev->dev; - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto err_put_node; - - dvfs_info->base = devm_ioremap_resource(dvfs_info->dev, &res); - if (IS_ERR(dvfs_info->base)) { - ret = PTR_ERR(dvfs_info->base); - goto err_put_node; - } - - dvfs_info->irq = irq_of_parse_and_map(np, 0); - if (!dvfs_info->irq) { - dev_err(dvfs_info->dev, "No cpufreq irq found\n"); - ret = -ENODEV; - goto err_put_node; - } - - ret = dev_pm_opp_of_add_table(dvfs_info->dev); - if (ret) { - dev_err(dvfs_info->dev, "failed to init OPP table: %d\n", ret); - goto err_put_node; - } - - ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, - &dvfs_info->freq_table); - if (ret) { - dev_err(dvfs_info->dev, - "failed to init cpufreq table: %d\n", ret); - goto err_free_opp; - } - dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); - exynos_sort_descend_freq_table(); - - if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) - dvfs_info->latency = DEF_TRANS_LATENCY; - - dvfs_info->cpu_clk = devm_clk_get(dvfs_info->dev, "armclk"); - if (IS_ERR(dvfs_info->cpu_clk)) { - dev_err(dvfs_info->dev, "Failed to get cpu clock\n"); - ret = PTR_ERR(dvfs_info->cpu_clk); - goto err_free_table; - } - - cur_frequency = clk_get_rate(dvfs_info->cpu_clk); - if (!cur_frequency) { - dev_err(dvfs_info->dev, "Failed to get clock rate\n"); - ret = -EINVAL; - goto err_free_table; - } - cur_frequency /= 1000; - - INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); - ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, - exynos_cpufreq_irq, IRQF_TRIGGER_NONE, - CPUFREQ_NAME, dvfs_info); - if (ret) { - dev_err(dvfs_info->dev, "Failed to register IRQ\n"); - goto err_free_table; - } - - ret = init_div_table(); - if (ret) { - dev_err(dvfs_info->dev, "Failed to initialise div table\n"); - goto err_free_table; - } - - exynos_enable_dvfs(cur_frequency); - ret = cpufreq_register_driver(&exynos_driver); - if (ret) { - dev_err(dvfs_info->dev, - "%s: failed to register cpufreq driver\n", __func__); - goto err_free_table; - } - - of_node_put(np); - dvfs_info->dvfs_enabled = true; - return 0; - -err_free_table: - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); -err_free_opp: - dev_pm_opp_of_remove_table(dvfs_info->dev); -err_put_node: - of_node_put(np); - dev_err(&pdev->dev, "%s: failed initialization\n", __func__); - return ret; -} - -static int exynos_cpufreq_remove(struct platform_device *pdev) -{ - cpufreq_unregister_driver(&exynos_driver); - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); - dev_pm_opp_of_remove_table(dvfs_info->dev); - return 0; -} - -static struct platform_driver exynos_cpufreq_platdrv = { - .driver = { - .name = "exynos5440-cpufreq", - .of_match_table = exynos_cpufreq_match, - }, - .probe = exynos_cpufreq_probe, - .remove = exynos_cpufreq_remove, -}; -module_platform_driver(exynos_cpufreq_platdrv); - -MODULE_AUTHOR("Amit Daniel Kachhap "); -MODULE_DESCRIPTION("Exynos5440 cpufreq driver"); -MODULE_LICENSE("GPL"); -- 2.14.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Krzysztof Kozlowski Subject: [RFC 03/10] cpufreq: exynos: Remove support for Exynos5440 Date: Tue, 24 Apr 2018 22:32:32 +0200 Message-ID: <20180424203239.21885-4-krzk@kernel.org> References: <20180424203239.21885-1-krzk@kernel.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20180424203239.21885-1-krzk@kernel.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Kukjin Kim , Krzysztof Kozlowski , Rob Herring , Mark Rutland , Tejun Heo , Sylwester Nawrocki , Tomasz Figa , Chanwoo Choi , Michael Turquette , Stephen Boyd , "Rafael J. Wysocki" , Viresh Kumar , Zhang Rui , Eduardo Valentin , Russell King , Hans de Goede , Linus Walleij , Andi Shyti , Mark Brown , Bartlomiej Zolnierkiewicz , Alan Stern , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org Cc: Olof Johansson , Jaehoon Chung , Arnd Bergmann , Marek Szyprowski List-Id: linux-samsung-soc@vger.kernel.org The Exynos5440 is not actively developed, there are no development boards available and probably there are no real products with it. Remove wide-tree support for Exynos5440. Signed-off-by: Krzysztof Kozlowski --- .../bindings/cpufreq/cpufreq-exynos5440.txt | 28 -- drivers/cpufreq/Kconfig.arm | 14 - drivers/cpufreq/Makefile | 1 - drivers/cpufreq/exynos5440-cpufreq.c | 452 --------------------- 4 files changed, 495 deletions(-) delete mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt delete mode 100644 drivers/cpufreq/exynos5440-cpufreq.c diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt deleted file mode 100644 index caff1a57436f..000000000000 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt +++ /dev/null @@ -1,28 +0,0 @@ - -Exynos5440 cpufreq driver -------------------- - -Exynos5440 SoC cpufreq driver for CPU frequency scaling. - -Required properties: -- interrupts: Interrupt to know the completion of cpu frequency change. -- operating-points: Table of frequencies and voltage CPU could be transitioned into, - in the decreasing order. Frequency should be in KHz units and voltage - should be in microvolts. - -Optional properties: -- clock-latency: Clock monitor latency in microsecond. - -All the required listed above must be defined under node cpufreq. - -Example: --------- - cpufreq@160000 { - compatible = "samsung,exynos5440-cpufreq"; - reg = <0x160000 0x1000>; - interrupts = <0 57 0>; - operating-points = < - 1000000 975000 - 800000 925000>; - clock-latency = <100000>; - }; diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 7f56fe5183f2..538a4004a2c5 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -81,20 +81,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG If in doubt, say N. -config ARM_EXYNOS5440_CPUFREQ - tristate "SAMSUNG EXYNOS5440" - depends on SOC_EXYNOS5440 - depends on HAVE_CLK && OF - select PM_OPP - default y - help - This adds the CPUFreq driver for Samsung EXYNOS5440 - SoC. The nature of exynos5440 clock controller is - different than previous exynos controllers so not using - the common exynos framework. - - If in doubt, say N. - config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" depends on ARCH_HIGHBANK && CPUFREQ_DT && REGULATOR diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 8d24ade3bd02..56724f867f78 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -56,7 +56,6 @@ obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c deleted file mode 100644 index 932caa386ece..000000000000 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (c) 2013 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Amit Daniel Kachhap - * - * EXYNOS5440 - CPU frequency scaling support - * - * 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. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register definitions */ -#define XMU_DVFS_CTRL 0x0060 -#define XMU_PMU_P0_7 0x0064 -#define XMU_C0_3_PSTATE 0x0090 -#define XMU_P_LIMIT 0x00a0 -#define XMU_P_STATUS 0x00a4 -#define XMU_PMUEVTEN 0x00d0 -#define XMU_PMUIRQEN 0x00d4 -#define XMU_PMUIRQ 0x00d8 - -/* PMU mask and shift definations */ -#define P_VALUE_MASK 0x7 - -#define XMU_DVFS_CTRL_EN_SHIFT 0 - -#define P0_7_CPUCLKDEV_SHIFT 21 -#define P0_7_CPUCLKDEV_MASK 0x7 -#define P0_7_ATBCLKDEV_SHIFT 18 -#define P0_7_ATBCLKDEV_MASK 0x7 -#define P0_7_CSCLKDEV_SHIFT 15 -#define P0_7_CSCLKDEV_MASK 0x7 -#define P0_7_CPUEMA_SHIFT 28 -#define P0_7_CPUEMA_MASK 0xf -#define P0_7_L2EMA_SHIFT 24 -#define P0_7_L2EMA_MASK 0xf -#define P0_7_VDD_SHIFT 8 -#define P0_7_VDD_MASK 0x7f -#define P0_7_FREQ_SHIFT 0 -#define P0_7_FREQ_MASK 0xff - -#define C0_3_PSTATE_VALID_SHIFT 8 -#define C0_3_PSTATE_CURR_SHIFT 4 -#define C0_3_PSTATE_NEW_SHIFT 0 - -#define PSTATE_CHANGED_EVTEN_SHIFT 0 - -#define PSTATE_CHANGED_IRQEN_SHIFT 0 - -#define PSTATE_CHANGED_SHIFT 0 - -/* some constant values for clock divider calculation */ -#define CPU_DIV_FREQ_MAX 500 -#define CPU_DBG_FREQ_MAX 375 -#define CPU_ATB_FREQ_MAX 500 - -#define PMIC_LOW_VOLT 0x30 -#define PMIC_HIGH_VOLT 0x28 - -#define CPUEMA_HIGH 0x2 -#define CPUEMA_MID 0x4 -#define CPUEMA_LOW 0x7 - -#define L2EMA_HIGH 0x1 -#define L2EMA_MID 0x3 -#define L2EMA_LOW 0x4 - -#define DIV_TAB_MAX 2 -/* frequency unit is 20MHZ */ -#define FREQ_UNIT 20 -#define MAX_VOLTAGE 1550000 /* In microvolt */ -#define VOLTAGE_STEP 12500 /* In microvolt */ - -#define CPUFREQ_NAME "exynos5440_dvfs" -#define DEF_TRANS_LATENCY 100000 - -enum cpufreq_level_index { - L0, L1, L2, L3, L4, - L5, L6, L7, L8, L9, -}; -#define CPUFREQ_LEVEL_END (L7 + 1) - -struct exynos_dvfs_data { - void __iomem *base; - struct resource *mem; - int irq; - struct clk *cpu_clk; - unsigned int latency; - struct cpufreq_frequency_table *freq_table; - unsigned int freq_count; - struct device *dev; - bool dvfs_enabled; - struct work_struct irq_work; -}; - -static struct exynos_dvfs_data *dvfs_info; -static DEFINE_MUTEX(cpufreq_lock); -static struct cpufreq_freqs freqs; - -static int init_div_table(void) -{ - struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table; - unsigned int tmp, clk_div, ema_div, freq, volt_id, idx; - struct dev_pm_opp *opp; - - cpufreq_for_each_entry_idx(pos, freq_tbl, idx) { - opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, - pos->frequency * 1000, true); - if (IS_ERR(opp)) { - dev_err(dvfs_info->dev, - "failed to find valid OPP for %u KHZ\n", - pos->frequency); - return PTR_ERR(opp); - } - - freq = pos->frequency / 1000; /* In MHZ */ - clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) - << P0_7_CPUCLKDEV_SHIFT; - clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) - << P0_7_ATBCLKDEV_SHIFT; - clk_div |= ((freq / CPU_DBG_FREQ_MAX) & P0_7_CSCLKDEV_MASK) - << P0_7_CSCLKDEV_SHIFT; - - /* Calculate EMA */ - volt_id = dev_pm_opp_get_voltage(opp); - - volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; - if (volt_id < PMIC_HIGH_VOLT) { - ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | - (L2EMA_HIGH << P0_7_L2EMA_SHIFT); - } else if (volt_id > PMIC_LOW_VOLT) { - ema_div = (CPUEMA_LOW << P0_7_CPUEMA_SHIFT) | - (L2EMA_LOW << P0_7_L2EMA_SHIFT); - } else { - ema_div = (CPUEMA_MID << P0_7_CPUEMA_SHIFT) | - (L2EMA_MID << P0_7_L2EMA_SHIFT); - } - - tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) - | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); - - __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx); - dev_pm_opp_put(opp); - } - - return 0; -} - -static void exynos_enable_dvfs(unsigned int cur_frequency) -{ - unsigned int tmp, cpu; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - struct cpufreq_frequency_table *pos; - /* Disable DVFS */ - __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); - - /* Enable PSTATE Change Event */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN); - tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN); - - /* Enable PSTATE Change IRQ */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN); - tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); - - /* Set initial performance index */ - cpufreq_for_each_entry(pos, freq_table) - if (pos->frequency == cur_frequency) - break; - - if (pos->frequency == CPUFREQ_TABLE_END) { - dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); - /* Assign the highest frequency */ - pos = freq_table; - cur_frequency = pos->frequency; - } - - dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", - cur_frequency); - - for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - } - - /* Enable DVFS */ - __raw_writel(1 << XMU_DVFS_CTRL_EN_SHIFT, - dvfs_info->base + XMU_DVFS_CTRL); -} - -static int exynos_target(struct cpufreq_policy *policy, unsigned int index) -{ - unsigned int tmp; - int i; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - mutex_lock(&cpufreq_lock); - - freqs.old = policy->cur; - freqs.new = freq_table[index].frequency; - - cpufreq_freq_transition_begin(policy, &freqs); - - /* Set the target frequency in all C0_3_PSTATE register */ - for_each_cpu(i, policy->cpus) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= (index << C0_3_PSTATE_NEW_SHIFT); - - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - } - mutex_unlock(&cpufreq_lock); - return 0; -} - -static void exynos_cpufreq_work(struct work_struct *work) -{ - unsigned int cur_pstate, index; - struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */ - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - /* Ensure we can access cpufreq structures */ - if (unlikely(dvfs_info->dvfs_enabled == false)) - goto skip_work; - - mutex_lock(&cpufreq_lock); - freqs.old = policy->cur; - - cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); - if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) - index = (cur_pstate >> C0_3_PSTATE_CURR_SHIFT) & P_VALUE_MASK; - else - index = (cur_pstate >> C0_3_PSTATE_NEW_SHIFT) & P_VALUE_MASK; - - if (likely(index < dvfs_info->freq_count)) { - freqs.new = freq_table[index].frequency; - } else { - dev_crit(dvfs_info->dev, "New frequency out of range\n"); - freqs.new = freqs.old; - } - cpufreq_freq_transition_end(policy, &freqs, 0); - - cpufreq_cpu_put(policy); - mutex_unlock(&cpufreq_lock); -skip_work: - enable_irq(dvfs_info->irq); -} - -static irqreturn_t exynos_cpufreq_irq(int irq, void *id) -{ - unsigned int tmp; - - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQ); - if (tmp >> PSTATE_CHANGED_SHIFT & 0x1) { - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQ); - disable_irq_nosync(irq); - schedule_work(&dvfs_info->irq_work); - } - return IRQ_HANDLED; -} - -static void exynos_sort_descend_freq_table(void) -{ - struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; - int i = 0, index; - unsigned int tmp_freq; - /* - * Exynos5440 clock controller state logic expects the cpufreq table to - * be in descending order. But the OPP library constructs the table in - * ascending order. So to make the table descending we just need to - * swap the i element with the N - i element. - */ - for (i = 0; i < dvfs_info->freq_count / 2; i++) { - index = dvfs_info->freq_count - i - 1; - tmp_freq = freq_tbl[i].frequency; - freq_tbl[i].frequency = freq_tbl[index].frequency; - freq_tbl[index].frequency = tmp_freq; - } -} - -static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - policy->clk = dvfs_info->cpu_clk; - return cpufreq_generic_init(policy, dvfs_info->freq_table, - dvfs_info->latency); -} - -static struct cpufreq_driver exynos_driver = { - .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION | - CPUFREQ_NEED_INITIAL_FREQ_CHECK, - .verify = cpufreq_generic_frequency_table_verify, - .target_index = exynos_target, - .get = cpufreq_generic_get, - .init = exynos_cpufreq_cpu_init, - .name = CPUFREQ_NAME, - .attr = cpufreq_generic_attr, -}; - -static const struct of_device_id exynos_cpufreq_match[] = { - { - .compatible = "samsung,exynos5440-cpufreq", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, exynos_cpufreq_match); - -static int exynos_cpufreq_probe(struct platform_device *pdev) -{ - int ret = -EINVAL; - struct device_node *np; - struct resource res; - unsigned int cur_frequency; - - np = pdev->dev.of_node; - if (!np) - return -ENODEV; - - dvfs_info = devm_kzalloc(&pdev->dev, sizeof(*dvfs_info), GFP_KERNEL); - if (!dvfs_info) { - ret = -ENOMEM; - goto err_put_node; - } - - dvfs_info->dev = &pdev->dev; - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto err_put_node; - - dvfs_info->base = devm_ioremap_resource(dvfs_info->dev, &res); - if (IS_ERR(dvfs_info->base)) { - ret = PTR_ERR(dvfs_info->base); - goto err_put_node; - } - - dvfs_info->irq = irq_of_parse_and_map(np, 0); - if (!dvfs_info->irq) { - dev_err(dvfs_info->dev, "No cpufreq irq found\n"); - ret = -ENODEV; - goto err_put_node; - } - - ret = dev_pm_opp_of_add_table(dvfs_info->dev); - if (ret) { - dev_err(dvfs_info->dev, "failed to init OPP table: %d\n", ret); - goto err_put_node; - } - - ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, - &dvfs_info->freq_table); - if (ret) { - dev_err(dvfs_info->dev, - "failed to init cpufreq table: %d\n", ret); - goto err_free_opp; - } - dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); - exynos_sort_descend_freq_table(); - - if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) - dvfs_info->latency = DEF_TRANS_LATENCY; - - dvfs_info->cpu_clk = devm_clk_get(dvfs_info->dev, "armclk"); - if (IS_ERR(dvfs_info->cpu_clk)) { - dev_err(dvfs_info->dev, "Failed to get cpu clock\n"); - ret = PTR_ERR(dvfs_info->cpu_clk); - goto err_free_table; - } - - cur_frequency = clk_get_rate(dvfs_info->cpu_clk); - if (!cur_frequency) { - dev_err(dvfs_info->dev, "Failed to get clock rate\n"); - ret = -EINVAL; - goto err_free_table; - } - cur_frequency /= 1000; - - INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); - ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, - exynos_cpufreq_irq, IRQF_TRIGGER_NONE, - CPUFREQ_NAME, dvfs_info); - if (ret) { - dev_err(dvfs_info->dev, "Failed to register IRQ\n"); - goto err_free_table; - } - - ret = init_div_table(); - if (ret) { - dev_err(dvfs_info->dev, "Failed to initialise div table\n"); - goto err_free_table; - } - - exynos_enable_dvfs(cur_frequency); - ret = cpufreq_register_driver(&exynos_driver); - if (ret) { - dev_err(dvfs_info->dev, - "%s: failed to register cpufreq driver\n", __func__); - goto err_free_table; - } - - of_node_put(np); - dvfs_info->dvfs_enabled = true; - return 0; - -err_free_table: - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); -err_free_opp: - dev_pm_opp_of_remove_table(dvfs_info->dev); -err_put_node: - of_node_put(np); - dev_err(&pdev->dev, "%s: failed initialization\n", __func__); - return ret; -} - -static int exynos_cpufreq_remove(struct platform_device *pdev) -{ - cpufreq_unregister_driver(&exynos_driver); - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); - dev_pm_opp_of_remove_table(dvfs_info->dev); - return 0; -} - -static struct platform_driver exynos_cpufreq_platdrv = { - .driver = { - .name = "exynos5440-cpufreq", - .of_match_table = exynos_cpufreq_match, - }, - .probe = exynos_cpufreq_probe, - .remove = exynos_cpufreq_remove, -}; -module_platform_driver(exynos_cpufreq_platdrv); - -MODULE_AUTHOR("Amit Daniel Kachhap "); -MODULE_DESCRIPTION("Exynos5440 cpufreq driver"); -MODULE_LICENSE("GPL"); -- 2.14.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [RFC,03/10] cpufreq: exynos: Remove support for Exynos5440 From: Krzysztof Kozlowski Message-Id: <20180424203239.21885-4-krzk@kernel.org> Date: Tue, 24 Apr 2018 22:32:32 +0200 To: Kukjin Kim , Krzysztof Kozlowski , Rob Herring , Mark Rutland , Tejun Heo , Sylwester Nawrocki , Tomasz Figa , Chanwoo Choi , Michael Turquette , Stephen Boyd , "Rafael J. Wysocki" , Viresh Kumar , Zhang Rui , Eduardo Valentin , Russell King , Hans de Goede , Linus Walleij , Andi Shyti , Mark Brown , Bartlomiej Zolnierkiewicz , Alan Stern , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org, linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, linux-spi@vger.kernel.org, linux-usb@vger.kernel.org Cc: Marek Szyprowski , Arnd Bergmann , Olof Johansson , Jaehoon Chung List-ID: VGhlIEV4eW5vczU0NDAgaXMgbm90IGFjdGl2ZWx5IGRldmVsb3BlZCwgdGhlcmUgYXJlIG5vIGRl dmVsb3BtZW50CmJvYXJkcyBhdmFpbGFibGUgYW5kIHByb2JhYmx5IHRoZXJlIGFyZSBubyByZWFs IHByb2R1Y3RzIHdpdGggaXQuClJlbW92ZSB3aWRlLXRyZWUgc3VwcG9ydCBmb3IgRXh5bm9zNTQ0 MC4KClNpZ25lZC1vZmYtYnk6IEtyenlzenRvZiBLb3psb3dza2kgPGtyemtAa2VybmVsLm9yZz4K LS0tCiAuLi4vYmluZGluZ3MvY3B1ZnJlcS9jcHVmcmVxLWV4eW5vczU0NDAudHh0ICAgICAgICB8 ICAyOCAtLQogZHJpdmVycy9jcHVmcmVxL0tjb25maWcuYXJtICAgICAgICAgICAgICAgICAgICAg ICAgfCAgMTQgLQogZHJpdmVycy9jcHVmcmVxL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAg ICAgICAgfCAgIDEgLQogZHJpdmVycy9jcHVmcmVxL2V4eW5vczU0NDAtY3B1ZnJlcS5jICAgICAg ICAgICAgICAgfCA0NTIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiA0IGZpbGVzIGNoYW5nZWQsIDQ5 NSBkZWxldGlvbnMoLSkKIGRlbGV0ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2RldmljZXRy ZWUvYmluZGluZ3MvY3B1ZnJlcS9jcHVmcmVxLWV4eW5vczU0NDAudHh0CiBkZWxldGUgbW9kZSAx MDA2NDQgZHJpdmVycy9jcHVmcmVxL2V4eW5vczU0NDAtY3B1ZnJlcS5jCgpkaWZmIC0tZ2l0IGEv RG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2NwdWZyZXEvY3B1ZnJlcS1leHlub3M1 NDQwLnR4dCBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jcHVmcmVxL2NwdWZy ZXEtZXh5bm9zNTQ0MC50eHQKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhZmYxYTU3 NDM2Zi4uMDAwMDAwMDAwMDAwCi0tLSBhL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5n cy9jcHVmcmVxL2NwdWZyZXEtZXh5bm9zNTQ0MC50eHQKKysrIC9kZXYvbnVsbApAQCAtMSwyOCAr MCwwIEBACi0KLUV4eW5vczU0NDAgY3B1ZnJlcSBkcml2ZXIKLS0tLS0tLS0tLS0tLS0tLS0tLS0K LQotRXh5bm9zNTQ0MCBTb0MgY3B1ZnJlcSBkcml2ZXIgZm9yIENQVSBmcmVxdWVuY3kgc2NhbGlu Zy4KLQotUmVxdWlyZWQgcHJvcGVydGllczoKLS0gaW50ZXJydXB0czogSW50ZXJydXB0IHRvIGtu b3cgdGhlIGNvbXBsZXRpb24gb2YgY3B1IGZyZXF1ZW5jeSBjaGFuZ2UuCi0tIG9wZXJhdGluZy1w b2ludHM6IFRhYmxlIG9mIGZyZXF1ZW5jaWVzIGFuZCB2b2x0YWdlIENQVSBjb3VsZCBiZSB0cmFu c2l0aW9uZWQgaW50bywKLQlpbiB0aGUgZGVjcmVhc2luZyBvcmRlci4gRnJlcXVlbmN5IHNob3Vs ZCBiZSBpbiBLSHogdW5pdHMgYW5kIHZvbHRhZ2UKLQlzaG91bGQgYmUgaW4gbWljcm92b2x0cy4K LQotT3B0aW9uYWwgcHJvcGVydGllczoKLS0gY2xvY2stbGF0ZW5jeTogQ2xvY2sgbW9uaXRvciBs YXRlbmN5IGluIG1pY3Jvc2Vjb25kLgotCi1BbGwgdGhlIHJlcXVpcmVkIGxpc3RlZCBhYm92ZSBt dXN0IGJlIGRlZmluZWQgdW5kZXIgbm9kZSBjcHVmcmVxLgotCi1FeGFtcGxlOgotLS0tLS0tLS0K LQljcHVmcmVxQDE2MDAwMCB7Ci0JCWNvbXBhdGlibGUgPSAic2Ftc3VuZyxleHlub3M1NDQwLWNw dWZyZXEiOwotCQlyZWcgPSA8MHgxNjAwMDAgMHgxMDAwPjsKLQkJaW50ZXJydXB0cyA9IDwwIDU3 IDA+OwotCQlvcGVyYXRpbmctcG9pbnRzID0gPAotCQkJCTEwMDAwMDAgOTc1MDAwCi0JCQkJODAw MDAwICA5MjUwMDA+OwotCQljbG9jay1sYXRlbmN5ID0gPDEwMDAwMD47Ci0JfTsKZGlmZiAtLWdp dCBhL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmlnLmFybSBiL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmln LmFybQppbmRleCA3ZjU2ZmU1MTgzZjIuLjUzOGE0MDA0YTJjNSAxMDA2NDQKLS0tIGEvZHJpdmVy cy9jcHVmcmVxL0tjb25maWcuYXJtCisrKyBiL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmlnLmFybQpA QCAtODEsMjAgKzgxLDYgQEAgY29uZmlnIEFSTV9CUkNNU1RCX0FWU19DUFVGUkVRX0RFQlVHCiAK IAkgIElmIGluIGRvdWJ0LCBzYXkgTi4KIAotY29uZmlnIEFSTV9FWFlOT1M1NDQwX0NQVUZSRVEK LQl0cmlzdGF0ZSAiU0FNU1VORyBFWFlOT1M1NDQwIgotCWRlcGVuZHMgb24gU09DX0VYWU5PUzU0 NDAKLQlkZXBlbmRzIG9uIEhBVkVfQ0xLICYmIE9GCi0Jc2VsZWN0IFBNX09QUAotCWRlZmF1bHQg eQotCWhlbHAKLQkgIFRoaXMgYWRkcyB0aGUgQ1BVRnJlcSBkcml2ZXIgZm9yIFNhbXN1bmcgRVhZ Tk9TNTQ0MAotCSAgU29DLiBUaGUgbmF0dXJlIG9mIGV4eW5vczU0NDAgY2xvY2sgY29udHJvbGxl ciBpcwotCSAgZGlmZmVyZW50IHRoYW4gcHJldmlvdXMgZXh5bm9zIGNvbnRyb2xsZXJzIHNvIG5v dCB1c2luZwotCSAgdGhlIGNvbW1vbiBleHlub3MgZnJhbWV3b3JrLgotCi0JICBJZiBpbiBkb3Vi dCwgc2F5IE4uCi0KIGNvbmZpZyBBUk1fSElHSEJBTktfQ1BVRlJFUQogCXRyaXN0YXRlICJDYWx4 ZWRhIEhpZ2hiYW5rLWJhc2VkIgogCWRlcGVuZHMgb24gQVJDSF9ISUdIQkFOSyAmJiBDUFVGUkVR X0RUICYmIFJFR1VMQVRPUgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9jcHVmcmVxL01ha2VmaWxlIGIv ZHJpdmVycy9jcHVmcmVxL01ha2VmaWxlCmluZGV4IDhkMjRhZGUzYmQwMi4uNTY3MjRmODY3Zjc4 IDEwMDY0NAotLS0gYS9kcml2ZXJzL2NwdWZyZXEvTWFrZWZpbGUKKysrIGIvZHJpdmVycy9jcHVm cmVxL01ha2VmaWxlCkBAIC01Niw3ICs1Niw2IEBAIG9iai0kKENPTkZJR19BUk1fQVJNQURBXzM3 WFhfQ1BVRlJFUSkJKz0gYXJtYWRhLTM3eHgtY3B1ZnJlcS5vCiBvYmotJChDT05GSUdfQVJNX0JS Q01TVEJfQVZTX0NQVUZSRVEpCSs9IGJyY21zdGItYXZzLWNwdWZyZXEubwogb2JqLSQoQ09ORklH X0FDUElfQ1BQQ19DUFVGUkVRKQkJKz0gY3BwY19jcHVmcmVxLm8KIG9iai0kKENPTkZJR19BUkNI X0RBVklOQ0kpCQkrPSBkYXZpbmNpLWNwdWZyZXEubwotb2JqLSQoQ09ORklHX0FSTV9FWFlOT1M1 NDQwX0NQVUZSRVEpCSs9IGV4eW5vczU0NDAtY3B1ZnJlcS5vCiBvYmotJChDT05GSUdfQVJNX0hJ R0hCQU5LX0NQVUZSRVEpCSs9IGhpZ2hiYW5rLWNwdWZyZXEubwogb2JqLSQoQ09ORklHX0FSTV9J TVg2UV9DUFVGUkVRKQkJKz0gaW14NnEtY3B1ZnJlcS5vCiBvYmotJChDT05GSUdfQVJNX0tJUktX T09EX0NQVUZSRVEpCSs9IGtpcmt3b29kLWNwdWZyZXEubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9j cHVmcmVxL2V4eW5vczU0NDAtY3B1ZnJlcS5jIGIvZHJpdmVycy9jcHVmcmVxL2V4eW5vczU0NDAt Y3B1ZnJlcS5jCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MzJjYWEzODZlY2UuLjAw MDAwMDAwMDAwMAotLS0gYS9kcml2ZXJzL2NwdWZyZXEvZXh5bm9zNTQ0MC1jcHVmcmVxLmMKKysr IC9kZXYvbnVsbApAQCAtMSw0NTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMyBT YW1zdW5nIEVsZWN0cm9uaWNzIENvLiwgTHRkLgotICoJCWh0dHA6Ly93d3cuc2Ftc3VuZy5jb20K LSAqCi0gKiBBbWl0IERhbmllbCBLYWNoaGFwIDxhbWl0LmRhbmllbEBzYW1zdW5nLmNvbT4KLSAq Ci0gKiBFWFlOT1M1NDQwIC0gQ1BVIGZyZXF1ZW5jeSBzY2FsaW5nIHN1cHBvcnQKLSAqCi0gKiBU aGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5k L29yIG1vZGlmeQotICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJs aWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2Fy ZSBGb3VuZGF0aW9uLgotKi8KLQotI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgotI2luY2x1ZGUgPGxp bnV4L2NwdS5oPgotI2luY2x1ZGUgPGxpbnV4L2NwdWZyZXEuaD4KLSNpbmNsdWRlIDxsaW51eC9l cnIuaD4KLSNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KLSNpbmNsdWRlIDxsaW51eC9pby5o PgotI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgotI2luY2x1ZGUgPGxpbnV4L29mX2FkZHJlc3Mu aD4KLSNpbmNsdWRlIDxsaW51eC9vZl9pcnEuaD4KLSNpbmNsdWRlIDxsaW51eC9wbV9vcHAuaD4K LSNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KLSNpbmNsdWRlIDxsaW51eC9zbGFi Lmg+Ci0KLS8qIFJlZ2lzdGVyIGRlZmluaXRpb25zICovCi0jZGVmaW5lIFhNVV9EVkZTX0NUUkwJ CTB4MDA2MAotI2RlZmluZSBYTVVfUE1VX1AwXzcJCTB4MDA2NAotI2RlZmluZSBYTVVfQzBfM19Q U1RBVEUJCTB4MDA5MAotI2RlZmluZSBYTVVfUF9MSU1JVAkJMHgwMGEwCi0jZGVmaW5lIFhNVV9Q X1NUQVRVUwkJMHgwMGE0Ci0jZGVmaW5lIFhNVV9QTVVFVlRFTgkJMHgwMGQwCi0jZGVmaW5lIFhN VV9QTVVJUlFFTgkJMHgwMGQ0Ci0jZGVmaW5lIFhNVV9QTVVJUlEJCTB4MDBkOAotCi0vKiBQTVUg bWFzayBhbmQgc2hpZnQgZGVmaW5hdGlvbnMgKi8KLSNkZWZpbmUgUF9WQUxVRV9NQVNLCQkweDcK LQotI2RlZmluZSBYTVVfRFZGU19DVFJMX0VOX1NISUZUCTAKLQotI2RlZmluZSBQMF83X0NQVUNM S0RFVl9TSElGVAkyMQotI2RlZmluZSBQMF83X0NQVUNMS0RFVl9NQVNLCTB4NwotI2RlZmluZSBQ MF83X0FUQkNMS0RFVl9TSElGVAkxOAotI2RlZmluZSBQMF83X0FUQkNMS0RFVl9NQVNLCTB4Nwot I2RlZmluZSBQMF83X0NTQ0xLREVWX1NISUZUCTE1Ci0jZGVmaW5lIFAwXzdfQ1NDTEtERVZfTUFT SwkweDcKLSNkZWZpbmUgUDBfN19DUFVFTUFfU0hJRlQJMjgKLSNkZWZpbmUgUDBfN19DUFVFTUFf TUFTSwkweGYKLSNkZWZpbmUgUDBfN19MMkVNQV9TSElGVAkyNAotI2RlZmluZSBQMF83X0wyRU1B X01BU0sJCTB4ZgotI2RlZmluZSBQMF83X1ZERF9TSElGVAkJOAotI2RlZmluZSBQMF83X1ZERF9N QVNLCQkweDdmCi0jZGVmaW5lIFAwXzdfRlJFUV9TSElGVAkJMAotI2RlZmluZSBQMF83X0ZSRVFf TUFTSwkJMHhmZgotCi0jZGVmaW5lIEMwXzNfUFNUQVRFX1ZBTElEX1NISUZUCTgKLSNkZWZpbmUg QzBfM19QU1RBVEVfQ1VSUl9TSElGVAk0Ci0jZGVmaW5lIEMwXzNfUFNUQVRFX05FV19TSElGVAkw Ci0KLSNkZWZpbmUgUFNUQVRFX0NIQU5HRURfRVZURU5fU0hJRlQJMAotCi0jZGVmaW5lIFBTVEFU RV9DSEFOR0VEX0lSUUVOX1NISUZUCTAKLQotI2RlZmluZSBQU1RBVEVfQ0hBTkdFRF9TSElGVAkJ MAotCi0vKiBzb21lIGNvbnN0YW50IHZhbHVlcyBmb3IgY2xvY2sgZGl2aWRlciBjYWxjdWxhdGlv biAqLwotI2RlZmluZSBDUFVfRElWX0ZSRVFfTUFYCTUwMAotI2RlZmluZSBDUFVfREJHX0ZSRVFf TUFYCTM3NQotI2RlZmluZSBDUFVfQVRCX0ZSRVFfTUFYCTUwMAotCi0jZGVmaW5lIFBNSUNfTE9X X1ZPTFQJCTB4MzAKLSNkZWZpbmUgUE1JQ19ISUdIX1ZPTFQJCTB4MjgKLQotI2RlZmluZSBDUFVF TUFfSElHSAkJMHgyCi0jZGVmaW5lIENQVUVNQV9NSUQJCTB4NAotI2RlZmluZSBDUFVFTUFfTE9X CQkweDcKLQotI2RlZmluZSBMMkVNQV9ISUdICQkweDEKLSNkZWZpbmUgTDJFTUFfTUlECQkweDMK LSNkZWZpbmUgTDJFTUFfTE9XCQkweDQKLQotI2RlZmluZSBESVZfVEFCX01BWAkyCi0vKiBmcmVx dWVuY3kgdW5pdCBpcyAyME1IWiAqLwotI2RlZmluZSBGUkVRX1VOSVQJMjAKLSNkZWZpbmUgTUFY X1ZPTFRBR0UJMTU1MDAwMCAvKiBJbiBtaWNyb3ZvbHQgKi8KLSNkZWZpbmUgVk9MVEFHRV9TVEVQ CTEyNTAwCS8qIEluIG1pY3Jvdm9sdCAqLwotCi0jZGVmaW5lIENQVUZSRVFfTkFNRQkJImV4eW5v czU0NDBfZHZmcyIKLSNkZWZpbmUgREVGX1RSQU5TX0xBVEVOQ1kJMTAwMDAwCi0KLWVudW0gY3B1 ZnJlcV9sZXZlbF9pbmRleCB7Ci0JTDAsIEwxLCBMMiwgTDMsIEw0LAotCUw1LCBMNiwgTDcsIEw4 LCBMOSwKLX07Ci0jZGVmaW5lIENQVUZSRVFfTEVWRUxfRU5ECShMNyArIDEpCi0KLXN0cnVjdCBl eHlub3NfZHZmc19kYXRhIHsKLQl2b2lkIF9faW9tZW0gKmJhc2U7Ci0Jc3RydWN0IHJlc291cmNl ICptZW07Ci0JaW50IGlycTsKLQlzdHJ1Y3QgY2xrICpjcHVfY2xrOwotCXVuc2lnbmVkIGludCBs YXRlbmN5OwotCXN0cnVjdCBjcHVmcmVxX2ZyZXF1ZW5jeV90YWJsZSAqZnJlcV90YWJsZTsKLQl1 bnNpZ25lZCBpbnQgZnJlcV9jb3VudDsKLQlzdHJ1Y3QgZGV2aWNlICpkZXY7Ci0JYm9vbCBkdmZz X2VuYWJsZWQ7Ci0Jc3RydWN0IHdvcmtfc3RydWN0IGlycV93b3JrOwotfTsKLQotc3RhdGljIHN0 cnVjdCBleHlub3NfZHZmc19kYXRhICpkdmZzX2luZm87Ci1zdGF0aWMgREVGSU5FX01VVEVYKGNw dWZyZXFfbG9jayk7Ci1zdGF0aWMgc3RydWN0IGNwdWZyZXFfZnJlcXMgZnJlcXM7Ci0KLXN0YXRp YyBpbnQgaW5pdF9kaXZfdGFibGUodm9pZCkKLXsKLQlzdHJ1Y3QgY3B1ZnJlcV9mcmVxdWVuY3lf dGFibGUgKnBvcywgKmZyZXFfdGJsID0gZHZmc19pbmZvLT5mcmVxX3RhYmxlOwotCXVuc2lnbmVk IGludCB0bXAsIGNsa19kaXYsIGVtYV9kaXYsIGZyZXEsIHZvbHRfaWQsIGlkeDsKLQlzdHJ1Y3Qg ZGV2X3BtX29wcCAqb3BwOwotCi0JY3B1ZnJlcV9mb3JfZWFjaF9lbnRyeV9pZHgocG9zLCBmcmVx X3RibCwgaWR4KSB7Ci0JCW9wcCA9IGRldl9wbV9vcHBfZmluZF9mcmVxX2V4YWN0KGR2ZnNfaW5m by0+ZGV2LAotCQkJCQlwb3MtPmZyZXF1ZW5jeSAqIDEwMDAsIHRydWUpOwotCQlpZiAoSVNfRVJS KG9wcCkpIHsKLQkJCWRldl9lcnIoZHZmc19pbmZvLT5kZXYsCi0JCQkJImZhaWxlZCB0byBmaW5k IHZhbGlkIE9QUCBmb3IgJXUgS0haXG4iLAotCQkJCXBvcy0+ZnJlcXVlbmN5KTsKLQkJCXJldHVy biBQVFJfRVJSKG9wcCk7Ci0JCX0KLQotCQlmcmVxID0gcG9zLT5mcmVxdWVuY3kgLyAxMDAwOyAv KiBJbiBNSFogKi8KLQkJY2xrX2RpdiA9ICgoZnJlcSAvIENQVV9ESVZfRlJFUV9NQVgpICYgUDBf N19DUFVDTEtERVZfTUFTSykKLQkJCQkJPDwgUDBfN19DUFVDTEtERVZfU0hJRlQ7Ci0JCWNsa19k aXYgfD0gKChmcmVxIC8gQ1BVX0FUQl9GUkVRX01BWCkgJiBQMF83X0FUQkNMS0RFVl9NQVNLKQot CQkJCQk8PCBQMF83X0FUQkNMS0RFVl9TSElGVDsKLQkJY2xrX2RpdiB8PSAoKGZyZXEgLyBDUFVf REJHX0ZSRVFfTUFYKSAmIFAwXzdfQ1NDTEtERVZfTUFTSykKLQkJCQkJPDwgUDBfN19DU0NMS0RF Vl9TSElGVDsKLQotCQkvKiBDYWxjdWxhdGUgRU1BICovCi0JCXZvbHRfaWQgPSBkZXZfcG1fb3Bw X2dldF92b2x0YWdlKG9wcCk7Ci0KLQkJdm9sdF9pZCA9IChNQVhfVk9MVEFHRSAtIHZvbHRfaWQp IC8gVk9MVEFHRV9TVEVQOwotCQlpZiAodm9sdF9pZCA8IFBNSUNfSElHSF9WT0xUKSB7Ci0JCQll bWFfZGl2ID0gKENQVUVNQV9ISUdIIDw8IFAwXzdfQ1BVRU1BX1NISUZUKSB8Ci0JCQkJKEwyRU1B X0hJR0ggPDwgUDBfN19MMkVNQV9TSElGVCk7Ci0JCX0gZWxzZSBpZiAodm9sdF9pZCA+IFBNSUNf TE9XX1ZPTFQpIHsKLQkJCWVtYV9kaXYgPSAoQ1BVRU1BX0xPVyA8PCBQMF83X0NQVUVNQV9TSElG VCkgfAotCQkJCShMMkVNQV9MT1cgPDwgUDBfN19MMkVNQV9TSElGVCk7Ci0JCX0gZWxzZSB7Ci0J CQllbWFfZGl2ID0gKENQVUVNQV9NSUQgPDwgUDBfN19DUFVFTUFfU0hJRlQpIHwKLQkJCQkoTDJF TUFfTUlEIDw8IFAwXzdfTDJFTUFfU0hJRlQpOwotCQl9Ci0KLQkJdG1wID0gKGNsa19kaXYgfCBl bWFfZGl2IHwgKHZvbHRfaWQgPDwgUDBfN19WRERfU0hJRlQpCi0JCQl8ICgoZnJlcSAvIEZSRVFf VU5JVCkgPDwgUDBfN19GUkVRX1NISUZUKSk7Ci0KLQkJX19yYXdfd3JpdGVsKHRtcCwgZHZmc19p bmZvLT5iYXNlICsgWE1VX1BNVV9QMF83ICsgNCAqIGlkeCk7Ci0JCWRldl9wbV9vcHBfcHV0KG9w cCk7Ci0JfQotCi0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyB2b2lkIGV4eW5vc19lbmFibGVfZHZm cyh1bnNpZ25lZCBpbnQgY3VyX2ZyZXF1ZW5jeSkKLXsKLQl1bnNpZ25lZCBpbnQgdG1wLCBjcHU7 Ci0Jc3RydWN0IGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlICpmcmVxX3RhYmxlID0gZHZmc19pbmZv LT5mcmVxX3RhYmxlOwotCXN0cnVjdCBjcHVmcmVxX2ZyZXF1ZW5jeV90YWJsZSAqcG9zOwotCS8q IERpc2FibGUgRFZGUyAqLwotCV9fcmF3X3dyaXRlbCgwLAlkdmZzX2luZm8tPmJhc2UgKyBYTVVf RFZGU19DVFJMKTsKLQotCS8qIEVuYWJsZSBQU1RBVEUgQ2hhbmdlIEV2ZW50ICovCi0JdG1wID0g X19yYXdfcmVhZGwoZHZmc19pbmZvLT5iYXNlICsgWE1VX1BNVUVWVEVOKTsKLQl0bXAgfD0gKDEg PDwgUFNUQVRFX0NIQU5HRURfRVZURU5fU0hJRlQpOwotCV9fcmF3X3dyaXRlbCh0bXAsIGR2ZnNf aW5mby0+YmFzZSArIFhNVV9QTVVFVlRFTik7Ci0KLQkvKiBFbmFibGUgUFNUQVRFIENoYW5nZSBJ UlEgKi8KLQl0bXAgPSBfX3Jhd19yZWFkbChkdmZzX2luZm8tPmJhc2UgKyBYTVVfUE1VSVJRRU4p OwotCXRtcCB8PSAoMSA8PCBQU1RBVEVfQ0hBTkdFRF9JUlFFTl9TSElGVCk7Ci0JX19yYXdfd3Jp dGVsKHRtcCwgZHZmc19pbmZvLT5iYXNlICsgWE1VX1BNVUlSUUVOKTsKLQotCS8qIFNldCBpbml0 aWFsIHBlcmZvcm1hbmNlIGluZGV4ICovCi0JY3B1ZnJlcV9mb3JfZWFjaF9lbnRyeShwb3MsIGZy ZXFfdGFibGUpCi0JCWlmIChwb3MtPmZyZXF1ZW5jeSA9PSBjdXJfZnJlcXVlbmN5KQotCQkJYnJl YWs7Ci0KLQlpZiAocG9zLT5mcmVxdWVuY3kgPT0gQ1BVRlJFUV9UQUJMRV9FTkQpIHsKLQkJZGV2 X2NyaXQoZHZmc19pbmZvLT5kZXYsICJCb290IHVwIGZyZXF1ZW5jeSBub3Qgc3VwcG9ydGVkXG4i KTsKLQkJLyogQXNzaWduIHRoZSBoaWdoZXN0IGZyZXF1ZW5jeSAqLwotCQlwb3MgPSBmcmVxX3Rh YmxlOwotCQljdXJfZnJlcXVlbmN5ID0gcG9zLT5mcmVxdWVuY3k7Ci0JfQotCi0JZGV2X2luZm8o ZHZmc19pbmZvLT5kZXYsICJTZXR0aW5nIGR2ZnMgaW5pdGlhbCBmcmVxdWVuY3kgPSAldUtIWiIs Ci0JCQkJCQljdXJfZnJlcXVlbmN5KTsKLQotCWZvciAoY3B1ID0gMDsgY3B1IDwgQ09ORklHX05S X0NQVVM7IGNwdSsrKSB7Ci0JCXRtcCA9IF9fcmF3X3JlYWRsKGR2ZnNfaW5mby0+YmFzZSArIFhN VV9DMF8zX1BTVEFURSArIGNwdSAqIDQpOwotCQl0bXAgJj0gfihQX1ZBTFVFX01BU0sgPDwgQzBf M19QU1RBVEVfTkVXX1NISUZUKTsKLQkJdG1wIHw9ICgocG9zIC0gZnJlcV90YWJsZSkgPDwgQzBf M19QU1RBVEVfTkVXX1NISUZUKTsKLQkJX19yYXdfd3JpdGVsKHRtcCwgZHZmc19pbmZvLT5iYXNl ICsgWE1VX0MwXzNfUFNUQVRFICsgY3B1ICogNCk7Ci0JfQotCi0JLyogRW5hYmxlIERWRlMgKi8K LQlfX3Jhd193cml0ZWwoMSA8PCBYTVVfRFZGU19DVFJMX0VOX1NISUZULAotCQkJCWR2ZnNfaW5m by0+YmFzZSArIFhNVV9EVkZTX0NUUkwpOwotfQotCi1zdGF0aWMgaW50IGV4eW5vc190YXJnZXQo c3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3ksIHVuc2lnbmVkIGludCBpbmRleCkKLXsKLQl1 bnNpZ25lZCBpbnQgdG1wOwotCWludCBpOwotCXN0cnVjdCBjcHVmcmVxX2ZyZXF1ZW5jeV90YWJs ZSAqZnJlcV90YWJsZSA9IGR2ZnNfaW5mby0+ZnJlcV90YWJsZTsKLQotCW11dGV4X2xvY2soJmNw dWZyZXFfbG9jayk7Ci0KLQlmcmVxcy5vbGQgPSBwb2xpY3ktPmN1cjsKLQlmcmVxcy5uZXcgPSBm cmVxX3RhYmxlW2luZGV4XS5mcmVxdWVuY3k7Ci0KLQljcHVmcmVxX2ZyZXFfdHJhbnNpdGlvbl9i ZWdpbihwb2xpY3ksICZmcmVxcyk7Ci0KLQkvKiBTZXQgdGhlIHRhcmdldCBmcmVxdWVuY3kgaW4g YWxsIEMwXzNfUFNUQVRFIHJlZ2lzdGVyICovCi0JZm9yX2VhY2hfY3B1KGksIHBvbGljeS0+Y3B1 cykgewotCQl0bXAgPSBfX3Jhd19yZWFkbChkdmZzX2luZm8tPmJhc2UgKyBYTVVfQzBfM19QU1RB VEUgKyBpICogNCk7Ci0JCXRtcCAmPSB+KFBfVkFMVUVfTUFTSyA8PCBDMF8zX1BTVEFURV9ORVdf U0hJRlQpOwotCQl0bXAgfD0gKGluZGV4IDw8IEMwXzNfUFNUQVRFX05FV19TSElGVCk7Ci0KLQkJ X19yYXdfd3JpdGVsKHRtcCwgZHZmc19pbmZvLT5iYXNlICsgWE1VX0MwXzNfUFNUQVRFICsgaSAq IDQpOwotCX0KLQltdXRleF91bmxvY2soJmNwdWZyZXFfbG9jayk7Ci0JcmV0dXJuIDA7Ci19Ci0K LXN0YXRpYyB2b2lkIGV4eW5vc19jcHVmcmVxX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3Jr KQotewotCXVuc2lnbmVkIGludCBjdXJfcHN0YXRlLCBpbmRleDsKLQlzdHJ1Y3QgY3B1ZnJlcV9w b2xpY3kgKnBvbGljeSA9IGNwdWZyZXFfY3B1X2dldCgwKTsgLyogYm9vdCBDUFUgKi8KLQlzdHJ1 Y3QgY3B1ZnJlcV9mcmVxdWVuY3lfdGFibGUgKmZyZXFfdGFibGUgPSBkdmZzX2luZm8tPmZyZXFf dGFibGU7Ci0KLQkvKiBFbnN1cmUgd2UgY2FuIGFjY2VzcyBjcHVmcmVxIHN0cnVjdHVyZXMgKi8K LQlpZiAodW5saWtlbHkoZHZmc19pbmZvLT5kdmZzX2VuYWJsZWQgPT0gZmFsc2UpKQotCQlnb3Rv IHNraXBfd29yazsKLQotCW11dGV4X2xvY2soJmNwdWZyZXFfbG9jayk7Ci0JZnJlcXMub2xkID0g cG9saWN5LT5jdXI7Ci0KLQljdXJfcHN0YXRlID0gX19yYXdfcmVhZGwoZHZmc19pbmZvLT5iYXNl ICsgWE1VX1BfU1RBVFVTKTsKLQlpZiAoY3VyX3BzdGF0ZSA+PiBDMF8zX1BTVEFURV9WQUxJRF9T SElGVCAmIDB4MSkKLQkJaW5kZXggPSAoY3VyX3BzdGF0ZSA+PiBDMF8zX1BTVEFURV9DVVJSX1NI SUZUKSAmIFBfVkFMVUVfTUFTSzsKLQllbHNlCi0JCWluZGV4ID0gKGN1cl9wc3RhdGUgPj4gQzBf M19QU1RBVEVfTkVXX1NISUZUKSAmIFBfVkFMVUVfTUFTSzsKLQotCWlmIChsaWtlbHkoaW5kZXgg PCBkdmZzX2luZm8tPmZyZXFfY291bnQpKSB7Ci0JCWZyZXFzLm5ldyA9IGZyZXFfdGFibGVbaW5k ZXhdLmZyZXF1ZW5jeTsKLQl9IGVsc2UgewotCQlkZXZfY3JpdChkdmZzX2luZm8tPmRldiwgIk5l dyBmcmVxdWVuY3kgb3V0IG9mIHJhbmdlXG4iKTsKLQkJZnJlcXMubmV3ID0gZnJlcXMub2xkOwot CX0KLQljcHVmcmVxX2ZyZXFfdHJhbnNpdGlvbl9lbmQocG9saWN5LCAmZnJlcXMsIDApOwotCi0J Y3B1ZnJlcV9jcHVfcHV0KHBvbGljeSk7Ci0JbXV0ZXhfdW5sb2NrKCZjcHVmcmVxX2xvY2spOwot c2tpcF93b3JrOgotCWVuYWJsZV9pcnEoZHZmc19pbmZvLT5pcnEpOwotfQotCi1zdGF0aWMgaXJx cmV0dXJuX3QgZXh5bm9zX2NwdWZyZXFfaXJxKGludCBpcnEsIHZvaWQgKmlkKQotewotCXVuc2ln bmVkIGludCB0bXA7Ci0KLQl0bXAgPSBfX3Jhd19yZWFkbChkdmZzX2luZm8tPmJhc2UgKyBYTVVf UE1VSVJRKTsKLQlpZiAodG1wID4+IFBTVEFURV9DSEFOR0VEX1NISUZUICYgMHgxKSB7Ci0JCV9f cmF3X3dyaXRlbCh0bXAsIGR2ZnNfaW5mby0+YmFzZSArIFhNVV9QTVVJUlEpOwotCQlkaXNhYmxl X2lycV9ub3N5bmMoaXJxKTsKLQkJc2NoZWR1bGVfd29yaygmZHZmc19pbmZvLT5pcnFfd29yayk7 Ci0JfQotCXJldHVybiBJUlFfSEFORExFRDsKLX0KLQotc3RhdGljIHZvaWQgZXh5bm9zX3NvcnRf ZGVzY2VuZF9mcmVxX3RhYmxlKHZvaWQpCi17Ci0Jc3RydWN0IGNwdWZyZXFfZnJlcXVlbmN5X3Rh YmxlICpmcmVxX3RibCA9IGR2ZnNfaW5mby0+ZnJlcV90YWJsZTsKLQlpbnQgaSA9IDAsIGluZGV4 OwotCXVuc2lnbmVkIGludCB0bXBfZnJlcTsKLQkvKgotCSAqIEV4eW5vczU0NDAgY2xvY2sgY29u dHJvbGxlciBzdGF0ZSBsb2dpYyBleHBlY3RzIHRoZSBjcHVmcmVxIHRhYmxlIHRvCi0JICogYmUg aW4gZGVzY2VuZGluZyBvcmRlci4gQnV0IHRoZSBPUFAgbGlicmFyeSBjb25zdHJ1Y3RzIHRoZSB0 YWJsZSBpbgotCSAqIGFzY2VuZGluZyBvcmRlci4gU28gdG8gbWFrZSB0aGUgdGFibGUgZGVzY2Vu ZGluZyB3ZSBqdXN0IG5lZWQgdG8KLQkgKiBzd2FwIHRoZSBpIGVsZW1lbnQgd2l0aCB0aGUgTiAt IGkgZWxlbWVudC4KLQkgKi8KLQlmb3IgKGkgPSAwOyBpIDwgZHZmc19pbmZvLT5mcmVxX2NvdW50 IC8gMjsgaSsrKSB7Ci0JCWluZGV4ID0gZHZmc19pbmZvLT5mcmVxX2NvdW50IC0gaSAtIDE7Ci0J CXRtcF9mcmVxID0gZnJlcV90YmxbaV0uZnJlcXVlbmN5OwotCQlmcmVxX3RibFtpXS5mcmVxdWVu Y3kgPSBmcmVxX3RibFtpbmRleF0uZnJlcXVlbmN5OwotCQlmcmVxX3RibFtpbmRleF0uZnJlcXVl bmN5ID0gdG1wX2ZyZXE7Ci0JfQotfQotCi1zdGF0aWMgaW50IGV4eW5vc19jcHVmcmVxX2NwdV9p bml0KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQotewotCXBvbGljeS0+Y2xrID0gZHZm c19pbmZvLT5jcHVfY2xrOwotCXJldHVybiBjcHVmcmVxX2dlbmVyaWNfaW5pdChwb2xpY3ksIGR2 ZnNfaW5mby0+ZnJlcV90YWJsZSwKLQkJCWR2ZnNfaW5mby0+bGF0ZW5jeSk7Ci19Ci0KLXN0YXRp YyBzdHJ1Y3QgY3B1ZnJlcV9kcml2ZXIgZXh5bm9zX2RyaXZlciA9IHsKLQkuZmxhZ3MJCT0gQ1BV RlJFUV9TVElDS1kgfCBDUFVGUkVRX0FTWU5DX05PVElGSUNBVElPTiB8Ci0JCQkJQ1BVRlJFUV9O RUVEX0lOSVRJQUxfRlJFUV9DSEVDSywKLQkudmVyaWZ5CQk9IGNwdWZyZXFfZ2VuZXJpY19mcmVx dWVuY3lfdGFibGVfdmVyaWZ5LAotCS50YXJnZXRfaW5kZXgJPSBleHlub3NfdGFyZ2V0LAotCS5n ZXQJCT0gY3B1ZnJlcV9nZW5lcmljX2dldCwKLQkuaW5pdAkJPSBleHlub3NfY3B1ZnJlcV9jcHVf aW5pdCwKLQkubmFtZQkJPSBDUFVGUkVRX05BTUUsCi0JLmF0dHIJCT0gY3B1ZnJlcV9nZW5lcmlj X2F0dHIsCi19OwotCi1zdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBleHlub3NfY3B1 ZnJlcV9tYXRjaFtdID0gewotCXsKLQkJLmNvbXBhdGlibGUgPSAic2Ftc3VuZyxleHlub3M1NDQw LWNwdWZyZXEiLAotCX0sCi0Je30sCi19OwotTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgZXh5bm9z X2NwdWZyZXFfbWF0Y2gpOwotCi1zdGF0aWMgaW50IGV4eW5vc19jcHVmcmVxX3Byb2JlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCi17Ci0JaW50IHJldCA9IC1FSU5WQUw7Ci0Jc3RydWN0 IGRldmljZV9ub2RlICpucDsKLQlzdHJ1Y3QgcmVzb3VyY2UgcmVzOwotCXVuc2lnbmVkIGludCBj dXJfZnJlcXVlbmN5OwotCi0JbnAgPSBwZGV2LT5kZXYub2Zfbm9kZTsKLQlpZiAoIW5wKQotCQly ZXR1cm4gLUVOT0RFVjsKLQotCWR2ZnNfaW5mbyA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBz aXplb2YoKmR2ZnNfaW5mbyksIEdGUF9LRVJORUwpOwotCWlmICghZHZmc19pbmZvKSB7Ci0JCXJl dCA9IC1FTk9NRU07Ci0JCWdvdG8gZXJyX3B1dF9ub2RlOwotCX0KLQotCWR2ZnNfaW5mby0+ZGV2 ID0gJnBkZXYtPmRldjsKLQotCXJldCA9IG9mX2FkZHJlc3NfdG9fcmVzb3VyY2UobnAsIDAsICZy ZXMpOwotCWlmIChyZXQpCi0JCWdvdG8gZXJyX3B1dF9ub2RlOwotCi0JZHZmc19pbmZvLT5iYXNl ID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKGR2ZnNfaW5mby0+ZGV2LCAmcmVzKTsKLQlpZiAoSVNf RVJSKGR2ZnNfaW5mby0+YmFzZSkpIHsKLQkJcmV0ID0gUFRSX0VSUihkdmZzX2luZm8tPmJhc2Up OwotCQlnb3RvIGVycl9wdXRfbm9kZTsKLQl9Ci0KLQlkdmZzX2luZm8tPmlycSA9IGlycV9vZl9w YXJzZV9hbmRfbWFwKG5wLCAwKTsKLQlpZiAoIWR2ZnNfaW5mby0+aXJxKSB7Ci0JCWRldl9lcnIo ZHZmc19pbmZvLT5kZXYsICJObyBjcHVmcmVxIGlycSBmb3VuZFxuIik7Ci0JCXJldCA9IC1FTk9E RVY7Ci0JCWdvdG8gZXJyX3B1dF9ub2RlOwotCX0KLQotCXJldCA9IGRldl9wbV9vcHBfb2ZfYWRk X3RhYmxlKGR2ZnNfaW5mby0+ZGV2KTsKLQlpZiAocmV0KSB7Ci0JCWRldl9lcnIoZHZmc19pbmZv LT5kZXYsICJmYWlsZWQgdG8gaW5pdCBPUFAgdGFibGU6ICVkXG4iLCByZXQpOwotCQlnb3RvIGVy cl9wdXRfbm9kZTsKLQl9Ci0KLQlyZXQgPSBkZXZfcG1fb3BwX2luaXRfY3B1ZnJlcV90YWJsZShk dmZzX2luZm8tPmRldiwKLQkJCQkJICAgICZkdmZzX2luZm8tPmZyZXFfdGFibGUpOwotCWlmIChy ZXQpIHsKLQkJZGV2X2VycihkdmZzX2luZm8tPmRldiwKLQkJCSJmYWlsZWQgdG8gaW5pdCBjcHVm cmVxIHRhYmxlOiAlZFxuIiwgcmV0KTsKLQkJZ290byBlcnJfZnJlZV9vcHA7Ci0JfQotCWR2ZnNf aW5mby0+ZnJlcV9jb3VudCA9IGRldl9wbV9vcHBfZ2V0X29wcF9jb3VudChkdmZzX2luZm8tPmRl dik7Ci0JZXh5bm9zX3NvcnRfZGVzY2VuZF9mcmVxX3RhYmxlKCk7Ci0KLQlpZiAob2ZfcHJvcGVy dHlfcmVhZF91MzIobnAsICJjbG9jay1sYXRlbmN5IiwgJmR2ZnNfaW5mby0+bGF0ZW5jeSkpCi0J CWR2ZnNfaW5mby0+bGF0ZW5jeSA9IERFRl9UUkFOU19MQVRFTkNZOwotCi0JZHZmc19pbmZvLT5j cHVfY2xrID0gZGV2bV9jbGtfZ2V0KGR2ZnNfaW5mby0+ZGV2LCAiYXJtY2xrIik7Ci0JaWYgKElT X0VSUihkdmZzX2luZm8tPmNwdV9jbGspKSB7Ci0JCWRldl9lcnIoZHZmc19pbmZvLT5kZXYsICJG YWlsZWQgdG8gZ2V0IGNwdSBjbG9ja1xuIik7Ci0JCXJldCA9IFBUUl9FUlIoZHZmc19pbmZvLT5j cHVfY2xrKTsKLQkJZ290byBlcnJfZnJlZV90YWJsZTsKLQl9Ci0KLQljdXJfZnJlcXVlbmN5ID0g Y2xrX2dldF9yYXRlKGR2ZnNfaW5mby0+Y3B1X2Nsayk7Ci0JaWYgKCFjdXJfZnJlcXVlbmN5KSB7 Ci0JCWRldl9lcnIoZHZmc19pbmZvLT5kZXYsICJGYWlsZWQgdG8gZ2V0IGNsb2NrIHJhdGVcbiIp OwotCQlyZXQgPSAtRUlOVkFMOwotCQlnb3RvIGVycl9mcmVlX3RhYmxlOwotCX0KLQljdXJfZnJl cXVlbmN5IC89IDEwMDA7Ci0KLQlJTklUX1dPUksoJmR2ZnNfaW5mby0+aXJxX3dvcmssIGV4eW5v c19jcHVmcmVxX3dvcmspOwotCXJldCA9IGRldm1fcmVxdWVzdF9pcnEoZHZmc19pbmZvLT5kZXYs IGR2ZnNfaW5mby0+aXJxLAotCQkJCWV4eW5vc19jcHVmcmVxX2lycSwgSVJRRl9UUklHR0VSX05P TkUsCi0JCQkJQ1BVRlJFUV9OQU1FLCBkdmZzX2luZm8pOwotCWlmIChyZXQpIHsKLQkJZGV2X2Vy cihkdmZzX2luZm8tPmRldiwgIkZhaWxlZCB0byByZWdpc3RlciBJUlFcbiIpOwotCQlnb3RvIGVy cl9mcmVlX3RhYmxlOwotCX0KLQotCXJldCA9IGluaXRfZGl2X3RhYmxlKCk7Ci0JaWYgKHJldCkg ewotCQlkZXZfZXJyKGR2ZnNfaW5mby0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpc2UgZGl2IHRh YmxlXG4iKTsKLQkJZ290byBlcnJfZnJlZV90YWJsZTsKLQl9Ci0KLQlleHlub3NfZW5hYmxlX2R2 ZnMoY3VyX2ZyZXF1ZW5jeSk7Ci0JcmV0ID0gY3B1ZnJlcV9yZWdpc3Rlcl9kcml2ZXIoJmV4eW5v c19kcml2ZXIpOwotCWlmIChyZXQpIHsKLQkJZGV2X2VycihkdmZzX2luZm8tPmRldiwKLQkJCSIl czogZmFpbGVkIHRvIHJlZ2lzdGVyIGNwdWZyZXEgZHJpdmVyXG4iLCBfX2Z1bmNfXyk7Ci0JCWdv dG8gZXJyX2ZyZWVfdGFibGU7Ci0JfQotCi0Jb2Zfbm9kZV9wdXQobnApOwotCWR2ZnNfaW5mby0+ ZHZmc19lbmFibGVkID0gdHJ1ZTsKLQlyZXR1cm4gMDsKLQotZXJyX2ZyZWVfdGFibGU6Ci0JZGV2 X3BtX29wcF9mcmVlX2NwdWZyZXFfdGFibGUoZHZmc19pbmZvLT5kZXYsICZkdmZzX2luZm8tPmZy ZXFfdGFibGUpOwotZXJyX2ZyZWVfb3BwOgotCWRldl9wbV9vcHBfb2ZfcmVtb3ZlX3RhYmxlKGR2 ZnNfaW5mby0+ZGV2KTsKLWVycl9wdXRfbm9kZToKLQlvZl9ub2RlX3B1dChucCk7Ci0JZGV2X2Vy cigmcGRldi0+ZGV2LCAiJXM6IGZhaWxlZCBpbml0aWFsaXphdGlvblxuIiwgX19mdW5jX18pOwot CXJldHVybiByZXQ7Ci19Ci0KLXN0YXRpYyBpbnQgZXh5bm9zX2NwdWZyZXFfcmVtb3ZlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCi17Ci0JY3B1ZnJlcV91bnJlZ2lzdGVyX2RyaXZlcigm ZXh5bm9zX2RyaXZlcik7Ci0JZGV2X3BtX29wcF9mcmVlX2NwdWZyZXFfdGFibGUoZHZmc19pbmZv LT5kZXYsICZkdmZzX2luZm8tPmZyZXFfdGFibGUpOwotCWRldl9wbV9vcHBfb2ZfcmVtb3ZlX3Rh YmxlKGR2ZnNfaW5mby0+ZGV2KTsKLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHN0cnVjdCBwbGF0 Zm9ybV9kcml2ZXIgZXh5bm9zX2NwdWZyZXFfcGxhdGRydiA9IHsKLQkuZHJpdmVyID0gewotCQku bmFtZQk9ICJleHlub3M1NDQwLWNwdWZyZXEiLAotCQkub2ZfbWF0Y2hfdGFibGUgPSBleHlub3Nf Y3B1ZnJlcV9tYXRjaCwKLQl9LAotCS5wcm9iZQkJPSBleHlub3NfY3B1ZnJlcV9wcm9iZSwKLQku cmVtb3ZlCQk9IGV4eW5vc19jcHVmcmVxX3JlbW92ZSwKLX07Ci1tb2R1bGVfcGxhdGZvcm1fZHJp dmVyKGV4eW5vc19jcHVmcmVxX3BsYXRkcnYpOwotCi1NT0RVTEVfQVVUSE9SKCJBbWl0IERhbmll bCBLYWNoaGFwIDxhbWl0LmRhbmllbEBzYW1zdW5nLmNvbT4iKTsKLU1PRFVMRV9ERVNDUklQVElP TigiRXh5bm9zNTQ0MCBjcHVmcmVxIGRyaXZlciIpOwotTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: krzk@kernel.org (Krzysztof Kozlowski) Date: Tue, 24 Apr 2018 22:32:32 +0200 Subject: [RFC 03/10] cpufreq: exynos: Remove support for Exynos5440 In-Reply-To: <20180424203239.21885-1-krzk@kernel.org> References: <20180424203239.21885-1-krzk@kernel.org> Message-ID: <20180424203239.21885-4-krzk@kernel.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org The Exynos5440 is not actively developed, there are no development boards available and probably there are no real products with it. Remove wide-tree support for Exynos5440. Signed-off-by: Krzysztof Kozlowski --- .../bindings/cpufreq/cpufreq-exynos5440.txt | 28 -- drivers/cpufreq/Kconfig.arm | 14 - drivers/cpufreq/Makefile | 1 - drivers/cpufreq/exynos5440-cpufreq.c | 452 --------------------- 4 files changed, 495 deletions(-) delete mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt delete mode 100644 drivers/cpufreq/exynos5440-cpufreq.c diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt deleted file mode 100644 index caff1a57436f..000000000000 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt +++ /dev/null @@ -1,28 +0,0 @@ - -Exynos5440 cpufreq driver -------------------- - -Exynos5440 SoC cpufreq driver for CPU frequency scaling. - -Required properties: -- interrupts: Interrupt to know the completion of cpu frequency change. -- operating-points: Table of frequencies and voltage CPU could be transitioned into, - in the decreasing order. Frequency should be in KHz units and voltage - should be in microvolts. - -Optional properties: -- clock-latency: Clock monitor latency in microsecond. - -All the required listed above must be defined under node cpufreq. - -Example: --------- - cpufreq at 160000 { - compatible = "samsung,exynos5440-cpufreq"; - reg = <0x160000 0x1000>; - interrupts = <0 57 0>; - operating-points = < - 1000000 975000 - 800000 925000>; - clock-latency = <100000>; - }; diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 7f56fe5183f2..538a4004a2c5 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -81,20 +81,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG If in doubt, say N. -config ARM_EXYNOS5440_CPUFREQ - tristate "SAMSUNG EXYNOS5440" - depends on SOC_EXYNOS5440 - depends on HAVE_CLK && OF - select PM_OPP - default y - help - This adds the CPUFreq driver for Samsung EXYNOS5440 - SoC. The nature of exynos5440 clock controller is - different than previous exynos controllers so not using - the common exynos framework. - - If in doubt, say N. - config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" depends on ARCH_HIGHBANK && CPUFREQ_DT && REGULATOR diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 8d24ade3bd02..56724f867f78 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -56,7 +56,6 @@ obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c deleted file mode 100644 index 932caa386ece..000000000000 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (c) 2013 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Amit Daniel Kachhap - * - * EXYNOS5440 - CPU frequency scaling support - * - * 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. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register definitions */ -#define XMU_DVFS_CTRL 0x0060 -#define XMU_PMU_P0_7 0x0064 -#define XMU_C0_3_PSTATE 0x0090 -#define XMU_P_LIMIT 0x00a0 -#define XMU_P_STATUS 0x00a4 -#define XMU_PMUEVTEN 0x00d0 -#define XMU_PMUIRQEN 0x00d4 -#define XMU_PMUIRQ 0x00d8 - -/* PMU mask and shift definations */ -#define P_VALUE_MASK 0x7 - -#define XMU_DVFS_CTRL_EN_SHIFT 0 - -#define P0_7_CPUCLKDEV_SHIFT 21 -#define P0_7_CPUCLKDEV_MASK 0x7 -#define P0_7_ATBCLKDEV_SHIFT 18 -#define P0_7_ATBCLKDEV_MASK 0x7 -#define P0_7_CSCLKDEV_SHIFT 15 -#define P0_7_CSCLKDEV_MASK 0x7 -#define P0_7_CPUEMA_SHIFT 28 -#define P0_7_CPUEMA_MASK 0xf -#define P0_7_L2EMA_SHIFT 24 -#define P0_7_L2EMA_MASK 0xf -#define P0_7_VDD_SHIFT 8 -#define P0_7_VDD_MASK 0x7f -#define P0_7_FREQ_SHIFT 0 -#define P0_7_FREQ_MASK 0xff - -#define C0_3_PSTATE_VALID_SHIFT 8 -#define C0_3_PSTATE_CURR_SHIFT 4 -#define C0_3_PSTATE_NEW_SHIFT 0 - -#define PSTATE_CHANGED_EVTEN_SHIFT 0 - -#define PSTATE_CHANGED_IRQEN_SHIFT 0 - -#define PSTATE_CHANGED_SHIFT 0 - -/* some constant values for clock divider calculation */ -#define CPU_DIV_FREQ_MAX 500 -#define CPU_DBG_FREQ_MAX 375 -#define CPU_ATB_FREQ_MAX 500 - -#define PMIC_LOW_VOLT 0x30 -#define PMIC_HIGH_VOLT 0x28 - -#define CPUEMA_HIGH 0x2 -#define CPUEMA_MID 0x4 -#define CPUEMA_LOW 0x7 - -#define L2EMA_HIGH 0x1 -#define L2EMA_MID 0x3 -#define L2EMA_LOW 0x4 - -#define DIV_TAB_MAX 2 -/* frequency unit is 20MHZ */ -#define FREQ_UNIT 20 -#define MAX_VOLTAGE 1550000 /* In microvolt */ -#define VOLTAGE_STEP 12500 /* In microvolt */ - -#define CPUFREQ_NAME "exynos5440_dvfs" -#define DEF_TRANS_LATENCY 100000 - -enum cpufreq_level_index { - L0, L1, L2, L3, L4, - L5, L6, L7, L8, L9, -}; -#define CPUFREQ_LEVEL_END (L7 + 1) - -struct exynos_dvfs_data { - void __iomem *base; - struct resource *mem; - int irq; - struct clk *cpu_clk; - unsigned int latency; - struct cpufreq_frequency_table *freq_table; - unsigned int freq_count; - struct device *dev; - bool dvfs_enabled; - struct work_struct irq_work; -}; - -static struct exynos_dvfs_data *dvfs_info; -static DEFINE_MUTEX(cpufreq_lock); -static struct cpufreq_freqs freqs; - -static int init_div_table(void) -{ - struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table; - unsigned int tmp, clk_div, ema_div, freq, volt_id, idx; - struct dev_pm_opp *opp; - - cpufreq_for_each_entry_idx(pos, freq_tbl, idx) { - opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, - pos->frequency * 1000, true); - if (IS_ERR(opp)) { - dev_err(dvfs_info->dev, - "failed to find valid OPP for %u KHZ\n", - pos->frequency); - return PTR_ERR(opp); - } - - freq = pos->frequency / 1000; /* In MHZ */ - clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) - << P0_7_CPUCLKDEV_SHIFT; - clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) - << P0_7_ATBCLKDEV_SHIFT; - clk_div |= ((freq / CPU_DBG_FREQ_MAX) & P0_7_CSCLKDEV_MASK) - << P0_7_CSCLKDEV_SHIFT; - - /* Calculate EMA */ - volt_id = dev_pm_opp_get_voltage(opp); - - volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; - if (volt_id < PMIC_HIGH_VOLT) { - ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | - (L2EMA_HIGH << P0_7_L2EMA_SHIFT); - } else if (volt_id > PMIC_LOW_VOLT) { - ema_div = (CPUEMA_LOW << P0_7_CPUEMA_SHIFT) | - (L2EMA_LOW << P0_7_L2EMA_SHIFT); - } else { - ema_div = (CPUEMA_MID << P0_7_CPUEMA_SHIFT) | - (L2EMA_MID << P0_7_L2EMA_SHIFT); - } - - tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) - | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); - - __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx); - dev_pm_opp_put(opp); - } - - return 0; -} - -static void exynos_enable_dvfs(unsigned int cur_frequency) -{ - unsigned int tmp, cpu; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - struct cpufreq_frequency_table *pos; - /* Disable DVFS */ - __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); - - /* Enable PSTATE Change Event */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN); - tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN); - - /* Enable PSTATE Change IRQ */ - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN); - tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); - - /* Set initial performance index */ - cpufreq_for_each_entry(pos, freq_table) - if (pos->frequency == cur_frequency) - break; - - if (pos->frequency == CPUFREQ_TABLE_END) { - dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); - /* Assign the highest frequency */ - pos = freq_table; - cur_frequency = pos->frequency; - } - - dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", - cur_frequency); - - for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT); - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); - } - - /* Enable DVFS */ - __raw_writel(1 << XMU_DVFS_CTRL_EN_SHIFT, - dvfs_info->base + XMU_DVFS_CTRL); -} - -static int exynos_target(struct cpufreq_policy *policy, unsigned int index) -{ - unsigned int tmp; - int i; - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - mutex_lock(&cpufreq_lock); - - freqs.old = policy->cur; - freqs.new = freq_table[index].frequency; - - cpufreq_freq_transition_begin(policy, &freqs); - - /* Set the target frequency in all C0_3_PSTATE register */ - for_each_cpu(i, policy->cpus) { - tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); - tmp |= (index << C0_3_PSTATE_NEW_SHIFT); - - __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); - } - mutex_unlock(&cpufreq_lock); - return 0; -} - -static void exynos_cpufreq_work(struct work_struct *work) -{ - unsigned int cur_pstate, index; - struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */ - struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; - - /* Ensure we can access cpufreq structures */ - if (unlikely(dvfs_info->dvfs_enabled == false)) - goto skip_work; - - mutex_lock(&cpufreq_lock); - freqs.old = policy->cur; - - cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); - if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) - index = (cur_pstate >> C0_3_PSTATE_CURR_SHIFT) & P_VALUE_MASK; - else - index = (cur_pstate >> C0_3_PSTATE_NEW_SHIFT) & P_VALUE_MASK; - - if (likely(index < dvfs_info->freq_count)) { - freqs.new = freq_table[index].frequency; - } else { - dev_crit(dvfs_info->dev, "New frequency out of range\n"); - freqs.new = freqs.old; - } - cpufreq_freq_transition_end(policy, &freqs, 0); - - cpufreq_cpu_put(policy); - mutex_unlock(&cpufreq_lock); -skip_work: - enable_irq(dvfs_info->irq); -} - -static irqreturn_t exynos_cpufreq_irq(int irq, void *id) -{ - unsigned int tmp; - - tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQ); - if (tmp >> PSTATE_CHANGED_SHIFT & 0x1) { - __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQ); - disable_irq_nosync(irq); - schedule_work(&dvfs_info->irq_work); - } - return IRQ_HANDLED; -} - -static void exynos_sort_descend_freq_table(void) -{ - struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; - int i = 0, index; - unsigned int tmp_freq; - /* - * Exynos5440 clock controller state logic expects the cpufreq table to - * be in descending order. But the OPP library constructs the table in - * ascending order. So to make the table descending we just need to - * swap the i element with the N - i element. - */ - for (i = 0; i < dvfs_info->freq_count / 2; i++) { - index = dvfs_info->freq_count - i - 1; - tmp_freq = freq_tbl[i].frequency; - freq_tbl[i].frequency = freq_tbl[index].frequency; - freq_tbl[index].frequency = tmp_freq; - } -} - -static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - policy->clk = dvfs_info->cpu_clk; - return cpufreq_generic_init(policy, dvfs_info->freq_table, - dvfs_info->latency); -} - -static struct cpufreq_driver exynos_driver = { - .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION | - CPUFREQ_NEED_INITIAL_FREQ_CHECK, - .verify = cpufreq_generic_frequency_table_verify, - .target_index = exynos_target, - .get = cpufreq_generic_get, - .init = exynos_cpufreq_cpu_init, - .name = CPUFREQ_NAME, - .attr = cpufreq_generic_attr, -}; - -static const struct of_device_id exynos_cpufreq_match[] = { - { - .compatible = "samsung,exynos5440-cpufreq", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, exynos_cpufreq_match); - -static int exynos_cpufreq_probe(struct platform_device *pdev) -{ - int ret = -EINVAL; - struct device_node *np; - struct resource res; - unsigned int cur_frequency; - - np = pdev->dev.of_node; - if (!np) - return -ENODEV; - - dvfs_info = devm_kzalloc(&pdev->dev, sizeof(*dvfs_info), GFP_KERNEL); - if (!dvfs_info) { - ret = -ENOMEM; - goto err_put_node; - } - - dvfs_info->dev = &pdev->dev; - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto err_put_node; - - dvfs_info->base = devm_ioremap_resource(dvfs_info->dev, &res); - if (IS_ERR(dvfs_info->base)) { - ret = PTR_ERR(dvfs_info->base); - goto err_put_node; - } - - dvfs_info->irq = irq_of_parse_and_map(np, 0); - if (!dvfs_info->irq) { - dev_err(dvfs_info->dev, "No cpufreq irq found\n"); - ret = -ENODEV; - goto err_put_node; - } - - ret = dev_pm_opp_of_add_table(dvfs_info->dev); - if (ret) { - dev_err(dvfs_info->dev, "failed to init OPP table: %d\n", ret); - goto err_put_node; - } - - ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, - &dvfs_info->freq_table); - if (ret) { - dev_err(dvfs_info->dev, - "failed to init cpufreq table: %d\n", ret); - goto err_free_opp; - } - dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); - exynos_sort_descend_freq_table(); - - if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) - dvfs_info->latency = DEF_TRANS_LATENCY; - - dvfs_info->cpu_clk = devm_clk_get(dvfs_info->dev, "armclk"); - if (IS_ERR(dvfs_info->cpu_clk)) { - dev_err(dvfs_info->dev, "Failed to get cpu clock\n"); - ret = PTR_ERR(dvfs_info->cpu_clk); - goto err_free_table; - } - - cur_frequency = clk_get_rate(dvfs_info->cpu_clk); - if (!cur_frequency) { - dev_err(dvfs_info->dev, "Failed to get clock rate\n"); - ret = -EINVAL; - goto err_free_table; - } - cur_frequency /= 1000; - - INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); - ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, - exynos_cpufreq_irq, IRQF_TRIGGER_NONE, - CPUFREQ_NAME, dvfs_info); - if (ret) { - dev_err(dvfs_info->dev, "Failed to register IRQ\n"); - goto err_free_table; - } - - ret = init_div_table(); - if (ret) { - dev_err(dvfs_info->dev, "Failed to initialise div table\n"); - goto err_free_table; - } - - exynos_enable_dvfs(cur_frequency); - ret = cpufreq_register_driver(&exynos_driver); - if (ret) { - dev_err(dvfs_info->dev, - "%s: failed to register cpufreq driver\n", __func__); - goto err_free_table; - } - - of_node_put(np); - dvfs_info->dvfs_enabled = true; - return 0; - -err_free_table: - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); -err_free_opp: - dev_pm_opp_of_remove_table(dvfs_info->dev); -err_put_node: - of_node_put(np); - dev_err(&pdev->dev, "%s: failed initialization\n", __func__); - return ret; -} - -static int exynos_cpufreq_remove(struct platform_device *pdev) -{ - cpufreq_unregister_driver(&exynos_driver); - dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); - dev_pm_opp_of_remove_table(dvfs_info->dev); - return 0; -} - -static struct platform_driver exynos_cpufreq_platdrv = { - .driver = { - .name = "exynos5440-cpufreq", - .of_match_table = exynos_cpufreq_match, - }, - .probe = exynos_cpufreq_probe, - .remove = exynos_cpufreq_remove, -}; -module_platform_driver(exynos_cpufreq_platdrv); - -MODULE_AUTHOR("Amit Daniel Kachhap "); -MODULE_DESCRIPTION("Exynos5440 cpufreq driver"); -MODULE_LICENSE("GPL"); -- 2.14.1