Linux Power Management development
 help / color / mirror / Atom feed
* [PATCH] PM/Devfreq: Add Exynos5-bus devfreq driver for Exynos5250.
From: Abhilash Kesavan @ 2012-12-28  9:22 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park, rjw, linux-kernel, linux-pm
  Cc: kgene.kim, jhbird.choi, Abhilash Kesavan
In-Reply-To: <CAJ0PZbTTDdAXJ378R7CDO2=spx7WF_RpztG5ch7iFZWx-v3N2Q@mail.gmail.com>

Exynos5-bus device devfreq driver monitors PPMU counters and
adjusts operating frequencies and voltages with OPP. ASV should
be used to provide appropriate voltages as per the speed group
of the SoC rather than using a constant 1.025V.

Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Cc: Jonghwan Choi <jhbird.choi@samsung.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
---
Changes since RFC v1:
* Moved the Exynos5 PPMU driver to machine specific directory
* Migrated to the PM QOS framework

This patch depends on PPMU support which has now been posted as part of
the arch-side support patch.
Tested after merging for-rafael branch of
git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
with for-next branch of
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git

 drivers/devfreq/Kconfig       |  10 +
 drivers/devfreq/Makefile      |   1 +
 drivers/devfreq/exynos5_bus.c | 469 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 480 insertions(+)
 create mode 100644 drivers/devfreq/exynos5_bus.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 0f079be..5b5a978 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -78,4 +78,14 @@ config ARM_EXYNOS4_BUS_DEVFREQ
 	  To operate with optimal voltages, ASV support is required
 	  (CONFIG_EXYNOS_ASV).
 
+config ARM_EXYNOS5_BUS_DEVFREQ
+	bool "ARM Exynos5250 Bus DEVFREQ Driver"
+	depends on SOC_EXYNOS5250 && EXYNOS5250_PPMU
+	select ARCH_HAS_OPP
+	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	help
+	  This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int).
+	  It reads PPMU counters of memory controllers and adjusts the
+	  operating frequencies and voltages with OPP support.
+
 endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 8c46423..1771276 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 
 # DEVFREQ Drivers
 obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos5_bus.o
diff --git a/drivers/devfreq/exynos5_bus.c b/drivers/devfreq/exynos5_bus.c
new file mode 100644
index 0000000..ad442a4
--- /dev/null
+++ b/drivers/devfreq/exynos5_bus.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS5 INT clock frequency scaling support using DEVFREQ framework
+ * Based on work done by Jonghwan Choi <jhbird.choi@samsung.com>
+ * Support for only EXYNOS5250 is present.
+ *
+ * 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 <linux/module.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/exynos_ppmu.h>
+#include <mach/exynos5_ppmu.h>
+#include "governor.h"
+
+#define MAX_SAFEVOLT			1100000 /* 1.10V */
+/* Assume that the bus is saturated if the utilization is 25% */
+#define INT_BUS_SATURATION_RATIO	25
+#define EXYNOS5_BUS_INT_POLL_TIME	msecs_to_jiffies(100)
+
+enum int_level_idx {
+	LV_0,
+	LV_1,
+	LV_2,
+	LV_3,
+	LV_4,
+	_LV_END
+};
+
+struct busfreq_data_int {
+	struct device *dev;
+	struct devfreq *devfreq;
+	bool disabled;
+	struct regulator *vdd_int;
+	unsigned long curr_freq;
+	struct notifier_block pm_notifier;
+	struct mutex lock;
+	struct pm_qos_request int_req;
+	struct clk *int_clk;
+	struct exynos5_ppmu_handle *ppmu;
+	struct delayed_work work;
+	int busy;
+};
+
+struct int_bus_opp_table {
+	unsigned int idx;
+	unsigned long clk;
+	unsigned long volt;
+};
+
+static struct int_bus_opp_table exynos5_int_opp_table[] = {
+	{LV_0, 266000, 1025000},
+	{LV_1, 200000, 1025000},
+	{LV_2, 160000, 1025000},
+	{LV_3, 133000, 1025000},
+	{LV_4, 100000, 1025000},
+	{0, 0, 0},
+};
+
+static int exynos5_int_setvolt(struct busfreq_data_int *data,
+		unsigned long volt)
+{
+	return regulator_set_voltage(data->vdd_int, volt, MAX_SAFEVOLT);
+}
+
+static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq,
+			      u32 flags)
+{
+	int err = 0;
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+	struct opp *opp;
+	unsigned long old_freq, freq;
+	unsigned long volt;
+
+	rcu_read_lock();
+	opp = devfreq_recommended_opp(dev, _freq, flags);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		dev_err(dev, "%s: Invalid OPP.\n", __func__);
+		return PTR_ERR(opp);
+	}
+
+	freq = opp_get_freq(opp);
+	volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	old_freq = data->curr_freq;
+
+	if (old_freq == freq)
+		return 0;
+
+	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, volt);
+
+	mutex_lock(&data->lock);
+
+	if (data->disabled)
+		goto out;
+
+	if (freq > exynos5_int_opp_table[_LV_END - 1].clk)
+		pm_qos_update_request(&data->int_req,
+				data->busy * old_freq * 16 / 100000);
+	else
+		pm_qos_update_request(&data->int_req, -1);
+
+	if (old_freq < freq)
+		err = exynos5_int_setvolt(data, volt);
+	if (err)
+		goto out;
+
+	err = clk_set_rate(data->int_clk, freq * 1000);
+
+	if (err)
+		goto out;
+
+	if (old_freq > freq)
+		err = exynos5_int_setvolt(data, volt);
+	if (err)
+		goto out;
+
+	data->curr_freq = freq;
+out:
+	mutex_unlock(&data->lock);
+	return err;
+}
+
+static int exynos5_int_get_dev_status(struct device *dev,
+				      struct devfreq_dev_status *stat)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	stat->current_frequency = data->curr_freq;
+	stat->busy_time = data->busy;
+	stat->total_time = 100;
+
+	return 0;
+}
+
+static void exynos5_int_poll_start(struct busfreq_data_int *data)
+{
+	schedule_delayed_work(&data->work, EXYNOS5_BUS_INT_POLL_TIME);
+}
+
+static void exynos5_int_poll_stop(struct busfreq_data_int *data)
+{
+	cancel_delayed_work_sync(&data->work);
+}
+
+static void exynos5_int_poll(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct busfreq_data_int *data;
+	int ret;
+
+	dwork = to_delayed_work(work);
+	data = container_of(dwork, struct busfreq_data_int, work);
+
+	ret = exynos5_ppmu_get_busy(data->ppmu, PPMU_SET_RIGHT);
+
+	if (ret >= 0) {
+		data->busy = ret;
+		mutex_lock(&data->devfreq->lock);
+		update_devfreq(data->devfreq);
+		mutex_unlock(&data->devfreq->lock);
+	}
+
+	schedule_delayed_work(&data->work, EXYNOS5_BUS_INT_POLL_TIME);
+}
+
+static void exynos5_int_exit(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	devfreq_unregister_opp_notifier(dev, data->devfreq);
+}
+
+static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
+	.initial_freq		= 160000,
+	.polling_ms		= 0,
+	.target			= exynos5_busfreq_int_target,
+	.get_dev_status		= exynos5_int_get_dev_status,
+	.exit			= exynos5_int_exit,
+};
+
+static int exynos5250_init_int_tables(struct busfreq_data_int *data)
+{
+	int i, err = 0;
+
+	for (i = LV_0; i < _LV_END; i++) {
+		err = opp_add(data->dev, exynos5_int_opp_table[i].clk,
+				exynos5_int_opp_table[i].volt);
+		if (err) {
+			dev_err(data->dev, "Cannot add opp entries.\n");
+			return err;
+		}
+	}
+
+	return 0;
+}
+static struct devfreq_simple_ondemand_data exynos5_int_ondemand_data = {
+	.downdifferential = 2,
+	.upthreshold = INT_BUS_SATURATION_RATIO,
+};
+
+static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	struct busfreq_data_int *data = container_of(this,
+					struct busfreq_data_int, pm_notifier);
+	struct opp *opp;
+	unsigned long maxfreq = ULONG_MAX;
+	unsigned long freq;
+	unsigned long volt;
+	int err = 0;
+
+	switch (event) {
+	case PM_SUSPEND_PREPARE:
+		/* Set Fastest and Deactivate DVFS */
+		mutex_lock(&data->lock);
+
+		data->disabled = true;
+
+		rcu_read_lock();
+		opp = opp_find_freq_floor(data->dev, &maxfreq);
+		if (IS_ERR(opp)) {
+			rcu_read_unlock();
+			err = PTR_ERR(opp);
+			goto unlock;
+		}
+		freq = opp_get_freq(opp);
+		volt = opp_get_voltage(opp);
+		rcu_read_unlock();
+
+		err = exynos5_int_setvolt(data, volt);
+		if (err)
+			goto unlock;
+
+		err = clk_set_rate(data->int_clk, freq * 1000);
+
+		if (err)
+			goto unlock;
+
+		data->curr_freq = freq;
+unlock:
+		mutex_unlock(&data->lock);
+		if (err)
+			return NOTIFY_BAD;
+		return NOTIFY_OK;
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		/* Reactivate */
+		mutex_lock(&data->lock);
+		data->disabled = false;
+		mutex_unlock(&data->lock);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static __devinit int exynos5_busfreq_int_probe(struct platform_device *pdev)
+{
+	struct busfreq_data_int *data;
+	struct opp *opp;
+	struct device *dev = &pdev->dev;
+	unsigned long initial_freq;
+	unsigned long initial_volt;
+	int err = 0;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
+				GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(dev, "Cannot allocate memory.\n");
+		return -ENOMEM;
+	}
+
+	data->pm_notifier.notifier_call = exynos5_busfreq_int_pm_notifier_event;
+	data->dev = dev;
+	mutex_init(&data->lock);
+
+	err = exynos5250_init_int_tables(data);
+	if (err)
+		goto err_regulator;
+
+	data->vdd_int = regulator_get(dev, "vdd_int");
+	if (IS_ERR(data->vdd_int)) {
+		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
+		err = PTR_ERR(data->vdd_int);
+		goto err_regulator;
+	}
+
+	data->int_clk = clk_get(dev, "int_clk");
+	if (IS_ERR(data->int_clk)) {
+		dev_err(dev, "Cannot get clock \"int_clk\"\n");
+		err = PTR_ERR(data->int_clk);
+		goto err_clock;
+	}
+
+	rcu_read_lock();
+	opp = opp_find_freq_floor(dev,
+			&exynos5_devfreq_int_profile.initial_freq);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
+		       exynos5_devfreq_int_profile.initial_freq);
+		err = PTR_ERR(opp);
+		goto err_opp_add;
+	}
+	initial_freq = opp_get_freq(opp);
+	initial_volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+	data->curr_freq = initial_freq;
+
+	err = clk_set_rate(data->int_clk, initial_freq * 1000);
+	if (err) {
+		dev_err(dev, "Failed to set initial frequency\n");
+		goto err_opp_add;
+	}
+
+	err = exynos5_int_setvolt(data, initial_volt);
+	if (err)
+		goto err_opp_add;
+
+	platform_set_drvdata(pdev, data);
+
+	data->ppmu = exynos5_ppmu_get();
+	if (!data->ppmu)
+		goto err_ppmu_get;
+
+	INIT_DELAYED_WORK(&data->work, exynos5_int_poll);
+	exynos5_int_poll_start(data);
+
+	data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
+					   "simple_ondemand",
+					   &exynos5_int_ondemand_data);
+
+	if (IS_ERR(data->devfreq)) {
+		err = PTR_ERR(data->devfreq);
+		goto err_devfreq_add;
+	}
+
+	devfreq_register_opp_notifier(dev, data->devfreq);
+
+	err = register_pm_notifier(&data->pm_notifier);
+	if (err) {
+		dev_err(dev, "Failed to setup pm notifier\n");
+		goto err_devfreq_add;
+	}
+
+	/* TODO: Add a new QOS class for int/mif bus */
+	pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
+
+	return 0;
+
+err_devfreq_add:
+	devfreq_remove_device(data->devfreq);
+	exynos5_int_poll_stop(data);
+err_ppmu_get:
+	platform_set_drvdata(pdev, NULL);
+err_opp_add:
+	clk_put(data->int_clk);
+err_clock:
+	regulator_put(data->vdd_int);
+err_regulator:
+	return err;
+}
+
+static __devexit int exynos5_busfreq_int_remove(struct platform_device *pdev)
+{
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	pm_qos_remove_request(&data->int_req);
+	unregister_pm_notifier(&data->pm_notifier);
+	devfreq_remove_device(data->devfreq);
+	regulator_put(data->vdd_int);
+	clk_put(data->int_clk);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos5_busfreq_int_suspend(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	exynos5_int_poll_stop(data);
+	return 0;
+}
+
+static int exynos5_busfreq_int_resume(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	exynos5_int_poll_start(data);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(exynos5_busfreq_int_pm, exynos5_busfreq_int_suspend,
+		exynos5_busfreq_int_resume);
+
+/* platform device pointer for exynos5 devfreq device. */
+static struct platform_device *exynos5_devfreq_pdev;
+
+static struct platform_driver exynos5_busfreq_int_driver = {
+	.probe		= exynos5_busfreq_int_probe,
+	.remove		= __devexit_p(exynos5_busfreq_int_remove),
+	.driver		= {
+		.name		= "exynos5-bus-int",
+		.owner		= THIS_MODULE,
+		.pm		= &exynos5_busfreq_int_pm,
+	},
+};
+
+static int __init exynos5_busfreq_int_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&exynos5_busfreq_int_driver);
+	if (ret < 0)
+		goto out;
+
+	exynos5_devfreq_pdev =
+		platform_device_register_simple("exynos5-bus-int", -1, NULL, 0);
+	if (IS_ERR_OR_NULL(exynos5_devfreq_pdev)) {
+		ret = PTR_ERR(exynos5_devfreq_pdev);
+		goto out1;
+	}
+
+	return 0;
+out1:
+	platform_driver_unregister(&exynos5_busfreq_int_driver);
+out:
+	return ret;
+}
+late_initcall(exynos5_busfreq_int_init);
+
+static void __exit exynos5_busfreq_int_exit(void)
+{
+	platform_device_unregister(exynos5_devfreq_pdev);
+	platform_driver_unregister(&exynos5_busfreq_int_driver);
+}
+module_exit(exynos5_busfreq_int_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EXYNOS5 busfreq driver with devfreq framework");
-- 
1.8.1-rc3


^ permalink raw reply related

* [PATCH] ARM: EXYNOS5: Support Exynos5-bus devfreq driver
From: Abhilash Kesavan @ 2012-12-28  9:24 UTC (permalink / raw)
  To: linux-kernel, linux-pm, kgene.kim
  Cc: myungjoo.ham, kyungmin.park, rjw, jhbird.choi, Abhilash Kesavan
In-Reply-To: <1355141166-17205-1-git-send-email-a.kesavan@samsung.com>

- Setup the INT clock ops to control/vary INT frequency
- Add PPMU support for Exynos5250
- Add mappings initially for the PPMU device

Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
Changes since RFC v1:
* Fixed the unnecessary clock manipulations being done
* Moved the PPMU driver from drivers/devfreq to machine specific directory

 arch/arm/mach-exynos/Kconfig                     |   8 +
 arch/arm/mach-exynos/Makefile                    |   4 +
 arch/arm/mach-exynos/clock-exynos5.c             | 143 ++++++++
 arch/arm/mach-exynos/common.c                    |  25 ++
 arch/arm/mach-exynos/exynos5_ppmu.c              | 396 +++++++++++++++++++++++
 arch/arm/mach-exynos/exynos_ppmu.c               |  56 ++++
 arch/arm/mach-exynos/include/mach/exynos5_ppmu.h |  26 ++
 arch/arm/mach-exynos/include/mach/exynos_ppmu.h  |  79 +++++
 arch/arm/mach-exynos/include/mach/map.h          |   6 +
 arch/arm/mach-exynos/include/mach/regs-clock.h   |  37 +++
 arch/arm/plat-samsung/include/plat/map-s5p.h     |   6 +
 11 files changed, 786 insertions(+)
 create mode 100644 arch/arm/mach-exynos/exynos5_ppmu.c
 create mode 100644 arch/arm/mach-exynos/exynos_ppmu.c
 create mode 100644 arch/arm/mach-exynos/include/mach/exynos5_ppmu.h
 create mode 100644 arch/arm/mach-exynos/include/mach/exynos_ppmu.h

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 91d5b6f..38bde0e 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -179,6 +179,14 @@ config EXYNOS_SETUP_SPI
 	help
 	  Common setup code for SPI GPIO configurations.
 
+config EXYNOS5250_PPMU
+	bool "Exynos5250 PPMU Driver"
+        depends on SOC_EXYNOS5250
+        help
+          This adds the Performance Profiling Monitoring Unit (PPMU) support
+	  for Exynos5250. This code is used by the devfreq driver to read the
+	  PPMU counters and vary the INT bus frequency/voltage.
+
 # machine support
 
 if ARCH_EXYNOS4
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 7e53a3a..b0b4cc9 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -74,3 +74,7 @@ obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)	+= setup-keypad.o
 obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
 obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)	+= setup-usb-phy.o
 obj-$(CONFIG_EXYNOS_SETUP_SPI)		+= setup-spi.o
+
+# ppmu support
+
+obj-$(CONFIG_EXYNOS5250_PPMU)		+= exynos_ppmu.o exynos5_ppmu.o
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 0208c3a..050879c 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -108,6 +108,11 @@ static struct clk exynos5_clk_sclk_usbphy = {
 	.rate		= 48000000,
 };
 
+/* Virtual Bus INT clock */
+static struct clk exynos5_int_clk = {
+	.name		= "int_clk",
+};
+
 static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
@@ -1426,6 +1431,141 @@ static struct clk *exynos5_clks[] __initdata = {
 	&clk_fout_cpll,
 	&clk_fout_mpll_div2,
 	&exynos5_clk_armclk,
+	&exynos5_int_clk,
+};
+
+#define INT_FREQ(f, a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, \
+			c0, c1, d0, e0) \
+	{ \
+		.freq = (f) * 1000000, \
+		.clk_div_top0 = ((a0) << 0 | (a1) << 8 | (a2) << 12 | \
+				(a3) << 16 | (a4) << 20 | (a5) << 28), \
+		.clk_div_top1 = ((b0) << 12 | (b1) << 16 | (b2) << 20 | \
+				(b3) << 24), \
+		.clk_div_lex = ((c0) << 4 | (c1) << 8), \
+		.clk_div_r0x = ((d0) << 4), \
+		.clk_div_r1x = ((e0) << 4), \
+	}
+
+static struct {
+	unsigned long freq;
+	u32 clk_div_top0;
+	u32 clk_div_top1;
+	u32 clk_div_lex;
+	u32 clk_div_r0x;
+	u32 clk_div_r1x;
+} int_freq[] = {
+	/*
+	 * values:
+	 * freq
+	 * clock divider for ACLK66, ACLK166, ACLK200, ACLK266,
+			ACLK333, ACLK300_DISP1
+	 * clock divider for ACLK300_GSCL, ACLK400_IOP, ACLK400_ISP, ACLK66_PRE
+	 * clock divider for PCLK_LEX, ATCLK_LEX
+	 * clock divider for ACLK_PR0X
+	 * clock divider for ACLK_PR1X
+	 */
+	INT_FREQ(266, 1, 1, 3, 2, 0, 0, 0, 1, 1, 5, 1, 0, 1, 1),
+	INT_FREQ(200, 1, 2, 4, 3, 1, 0, 0, 3, 2, 5, 1, 0, 1, 1),
+	INT_FREQ(160, 1, 3, 4, 4, 2, 0, 0, 3, 3, 5, 1, 0, 1, 1),
+	INT_FREQ(133, 1, 3, 5, 5, 2, 1, 1, 4, 4, 5, 1, 0, 1, 1),
+	INT_FREQ(100, 1, 7, 7, 7, 7, 3, 7, 7, 7, 5, 1, 0, 1, 1),
+};
+
+static unsigned long exynos5_clk_int_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+
+static void exynos5_int_set_clkdiv(unsigned int div_index)
+{
+	unsigned int tmp;
+
+	/* Change Divider - TOP0 */
+	tmp = __raw_readl(EXYNOS5_CLKDIV_TOP0);
+
+	tmp &= ~(EXYNOS5_CLKDIV_TOP0_ACLK266_MASK |
+		EXYNOS5_CLKDIV_TOP0_ACLK200_MASK |
+		EXYNOS5_CLKDIV_TOP0_ACLK66_MASK |
+		EXYNOS5_CLKDIV_TOP0_ACLK333_MASK |
+		EXYNOS5_CLKDIV_TOP0_ACLK166_MASK |
+		EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_MASK);
+
+	tmp |= int_freq[div_index].clk_div_top0;
+
+	__raw_writel(tmp, EXYNOS5_CLKDIV_TOP0);
+
+	/* Wait for TOP0 divider to stabilize */
+	while (__raw_readl(EXYNOS5_CLKDIV_STAT_TOP0) & 0x151101)
+		cpu_relax();
+
+	/* Change Divider - TOP1 */
+	tmp = __raw_readl(EXYNOS5_CLKDIV_TOP1);
+
+	tmp &= ~(EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_MASK |
+		EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_MASK |
+		EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_MASK |
+		EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_MASK);
+
+	tmp |= int_freq[div_index].clk_div_top1;
+
+	__raw_writel(tmp, EXYNOS5_CLKDIV_TOP1);
+
+	/* Wait for TOP0 and TOP1 dividers to stabilize */
+	while ((__raw_readl(EXYNOS5_CLKDIV_STAT_TOP1) & 0x1110000) &&
+		(__raw_readl(EXYNOS5_CLKDIV_STAT_TOP0) & 0x80000))
+		cpu_relax();
+
+	/* Change Divider - LEX */
+	tmp = int_freq[div_index].clk_div_lex;
+
+	__raw_writel(tmp, EXYNOS5_CLKDIV_LEX);
+
+	/* Wait for LEX divider to stabilize */
+	while (__raw_readl(EXYNOS5_CLKDIV_STAT_LEX) & 0x110)
+		cpu_relax();
+
+	/* Change Divider - R0X */
+	tmp = int_freq[div_index].clk_div_r0x;
+
+	__raw_writel(tmp, EXYNOS5_CLKDIV_R0X);
+
+	/* Wait for R0X divider to stabilize */
+	while (__raw_readl(EXYNOS5_CLKDIV_STAT_R0X) & 0x10)
+		cpu_relax();
+
+	/* Change Divider - R1X */
+	tmp = int_freq[div_index].clk_div_r1x;
+
+	__raw_writel(tmp, EXYNOS5_CLKDIV_R1X);
+
+	/* Wait for R1X divider to stabilize */
+	while (__raw_readl(EXYNOS5_CLKDIV_STAT_R1X) & 0x10)
+		cpu_relax();
+}
+
+static int exynos5_clk_int_set_rate(struct clk *clk, unsigned long rate)
+{
+	int index;
+
+	for (index = 0; index < ARRAY_SIZE(int_freq); index++)
+		if (int_freq[index].freq == rate)
+			break;
+
+	if (index == ARRAY_SIZE(int_freq))
+		return -EINVAL;
+
+	/* Change the system clock divider values */
+	exynos5_int_set_clkdiv(index);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+static struct clk_ops exynos5_clk_int_ops = {
+	.get_rate = exynos5_clk_int_get_rate,
+	.set_rate = exynos5_clk_int_set_rate
 };
 
 static u32 epll_div[][6] = {
@@ -1620,6 +1760,9 @@ void __init_or_cpufreq exynos5_setup_clocks(void)
 
 	clk_fout_epll.ops = &exynos5_epll_ops;
 
+	exynos5_int_clk.ops = &exynos5_clk_int_ops;
+	exynos5_int_clk.rate = aclk_266;
+
 	if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
 		printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
 				clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 578a610..a285080 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -308,6 +308,31 @@ static struct map_desc exynos5_iodesc[] __initdata = {
 		.pfn		= __phys_to_pfn(EXYNOS5_PA_UART),
 		.length		= SZ_512K,
 		.type		= MT_DEVICE,
+	}, {
+		.virtual        = (unsigned long)S5P_VA_PPMU_CPU,
+		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_CPU),
+		.length         = SZ_8K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_C,
+		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_C),
+		.length         = SZ_8K,
+		.type           = MT_DEVICE,
+	}, {
+		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_R1,
+		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_R1),
+		.length         = SZ_8K,
+		.type           = MT_DEVICE,
+	}, {
+		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_L,
+		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_L),
+		.length         = SZ_8K,
+		.type           = MT_DEVICE,
+	}, {
+		.virtual        = (unsigned long)S5P_VA_PPMU_RIGHT,
+		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_RIGHT),
+		.length         = SZ_8K,
+		.type           = MT_DEVICE,
 	},
 };
 
diff --git a/arch/arm/mach-exynos/exynos5_ppmu.c b/arch/arm/mach-exynos/exynos5_ppmu.c
new file mode 100644
index 0000000..3fecef4
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos5_ppmu.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS5 PPMU support
+ * Support for only EXYNOS5250 is present.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/hrtimer.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/map.h>
+
+#include <mach/exynos_ppmu.h>
+#include <mach/exynos5_ppmu.h>
+
+#define FIXED_POINT_OFFSET 8
+#define FIXED_POINT_MASK ((1 << FIXED_POINT_OFFSET) - 1)
+
+enum exynos5_ppmu_list {
+	PPMU_DDR_C,
+	PPMU_DDR_R1,
+	PPMU_DDR_L,
+	PPMU_RIGHT,
+	PPMU_CPU,
+	PPMU_END,
+};
+
+struct exynos5_ppmu_handle {
+	struct list_head node;
+	struct exynos_ppmu ppmu[PPMU_END];
+};
+
+static DEFINE_SPINLOCK(exynos5_ppmu_lock);
+static LIST_HEAD(exynos5_ppmu_handle_list);
+static struct exynos5_ppmu_handle *exynos5_ppmu_trace_handle;
+
+static const char *exynos5_ppmu_name[PPMU_END] = {
+	[PPMU_DDR_C]	= "DDR_C",
+	[PPMU_DDR_R1]	= "DDR_R1",
+	[PPMU_DDR_L]	= "DDR_L",
+	[PPMU_RIGHT]	= "RIGHT",
+	[PPMU_CPU]	= "CPU",
+};
+
+static struct exynos_ppmu ppmu[PPMU_END] = {
+	[PPMU_DDR_C] = {
+		.hw_base = S5P_VA_PPMU_DDR_C,
+	},
+	[PPMU_DDR_R1] = {
+		.hw_base = S5P_VA_PPMU_DDR_R1,
+	},
+	[PPMU_DDR_L] = {
+		.hw_base = S5P_VA_PPMU_DDR_L,
+	},
+	[PPMU_RIGHT] = {
+		.hw_base = S5P_VA_PPMU_RIGHT,
+	},
+	[PPMU_CPU] = {
+		.hw_base = S5P_VA_PPMU_CPU,
+	},
+};
+
+static void exynos5_ppmu_reset(struct exynos_ppmu *ppmu)
+{
+	unsigned long flags;
+
+	void __iomem *ppmu_base = ppmu->hw_base;
+
+	/* Reset PPMU */
+	exynos_ppmu_reset(ppmu_base);
+
+	/* Set PPMU Event */
+	ppmu->event[PPMU_PMNCNT0] = RD_DATA_COUNT;
+	exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT0,
+			ppmu->event[PPMU_PMNCNT0]);
+	ppmu->event[PPMU_PMCCNT1] = WR_DATA_COUNT;
+	exynos_ppmu_setevent(ppmu_base, PPMU_PMCCNT1,
+			ppmu->event[PPMU_PMCCNT1]);
+	ppmu->event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
+	exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
+			ppmu->event[PPMU_PMNCNT3]);
+
+	local_irq_save(flags);
+	ppmu->reset_time = ktime_get();
+	/* Start PPMU */
+	exynos_ppmu_start(ppmu_base);
+	local_irq_restore(flags);
+}
+
+static void exynos5_ppmu_read(struct exynos_ppmu *ppmu)
+{
+	int j;
+	unsigned long flags;
+	ktime_t read_time;
+	ktime_t t;
+	u32 reg;
+
+	void __iomem *ppmu_base = ppmu->hw_base;
+
+	local_irq_save(flags);
+	read_time = ktime_get();
+	/* Stop PPMU */
+	exynos_ppmu_stop(ppmu_base);
+	local_irq_restore(flags);
+
+	/* Update local data from PPMU */
+	ppmu->ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
+	reg = __raw_readl(ppmu_base + PPMU_FLAG);
+	ppmu->ccnt_overflow = reg & PPMU_CCNT_OVERFLOW;
+
+	for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+		if (ppmu->event[j] == 0)
+			ppmu->count[j] = 0;
+		else
+			ppmu->count[j] = exynos_ppmu_read(ppmu_base, j);
+	}
+	t = ktime_sub(read_time, ppmu->reset_time);
+	ppmu->ns = ktime_to_ns(t);
+}
+
+static void exynos5_ppmu_add(struct exynos_ppmu *to, struct exynos_ppmu *from)
+{
+	int i;
+	int j;
+
+	for (i = 0; i < PPMU_END; i++) {
+		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++)
+			to[i].count[j] += from[i].count[j];
+
+		to[i].ccnt += from[i].ccnt;
+		if (to[i].ccnt < from[i].ccnt)
+			to[i].ccnt_overflow = true;
+
+		to[i].ns += from[i].ns;
+
+		if (from[i].ccnt_overflow)
+			to[i].ccnt_overflow = true;
+	}
+}
+
+static void exynos5_ppmu_handle_clear(struct exynos5_ppmu_handle *handle)
+{
+	memset(&handle->ppmu, 0, sizeof(struct exynos_ppmu) * PPMU_END);
+}
+
+static void exynos5_ppmu_update(void)
+{
+	int i;
+	struct exynos5_ppmu_handle *handle;
+
+	for (i = 0; i < PPMU_END; i++) {
+		exynos5_ppmu_read(&ppmu[i]);
+		exynos5_ppmu_reset(&ppmu[i]);
+	}
+
+	list_for_each_entry(handle, &exynos5_ppmu_handle_list, node)
+		exynos5_ppmu_add(handle->ppmu, ppmu);
+}
+
+static int exynos5_ppmu_get_filter(enum exynos5_ppmu_sets filter,
+	enum exynos5_ppmu_list *start, enum exynos5_ppmu_list *end)
+{
+	switch (filter) {
+	case PPMU_SET_DDR:
+		*start = PPMU_DDR_C;
+		*end = PPMU_DDR_L;
+		break;
+	case PPMU_SET_RIGHT:
+		*start = PPMU_RIGHT;
+		*end = PPMU_RIGHT;
+		break;
+	case PPMU_SET_CPU:
+		*start = PPMU_CPU;
+		*end = PPMU_CPU;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int exynos5_ppmu_get_busy(struct exynos5_ppmu_handle *handle,
+	enum exynos5_ppmu_sets filter)
+{
+	unsigned long flags;
+	int i;
+	int busy = 0;
+	int temp;
+	enum exynos5_ppmu_list start;
+	enum exynos5_ppmu_list end;
+	int ret;
+
+	ret = exynos5_ppmu_get_filter(filter, &start, &end);
+	if (ret < 0)
+		return ret;
+
+	spin_lock_irqsave(&exynos5_ppmu_lock, flags);
+
+	exynos5_ppmu_update();
+
+	for (i = start; i <= end; i++) {
+		if (handle->ppmu[i].ccnt_overflow) {
+			busy = -EOVERFLOW;
+			break;
+		}
+		temp = handle->ppmu[i].count[PPMU_PMNCNT3] * 100;
+		if (handle->ppmu[i].ccnt > 0)
+			temp /= handle->ppmu[i].ccnt;
+		if (temp > busy)
+			busy = temp;
+	}
+
+	exynos5_ppmu_handle_clear(handle);
+
+	spin_unlock_irqrestore(&exynos5_ppmu_lock, flags);
+
+	return busy;
+}
+
+static void exynos5_ppmu_put(struct exynos5_ppmu_handle *handle)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&exynos5_ppmu_lock, flags);
+
+	list_del(&handle->node);
+
+	spin_unlock_irqrestore(&exynos5_ppmu_lock, flags);
+
+	kfree(handle);
+}
+
+struct exynos5_ppmu_handle *exynos5_ppmu_get(void)
+{
+	struct exynos5_ppmu_handle *handle;
+	unsigned long flags;
+
+	handle = kzalloc(sizeof(struct exynos5_ppmu_handle), GFP_KERNEL);
+	if (!handle)
+		return NULL;
+
+	spin_lock_irqsave(&exynos5_ppmu_lock, flags);
+
+	exynos5_ppmu_update();
+	list_add_tail(&handle->node, &exynos5_ppmu_handle_list);
+
+	spin_unlock_irqrestore(&exynos5_ppmu_lock, flags);
+
+	return handle;
+}
+
+static int exynos5_ppmu_trace_init(void)
+{
+	exynos5_ppmu_trace_handle = exynos5_ppmu_get();
+	return 0;
+}
+late_initcall(exynos5_ppmu_trace_init);
+
+static void exynos5_ppmu_debug_compute(struct exynos_ppmu *ppmu,
+	enum ppmu_counter i, u32 *sat, u32 *freq, u32 *bw)
+{
+	u64 ns = ppmu->ns;
+	u32 busy = ppmu->count[i];
+	u32 total = ppmu->ccnt;
+
+	u64 s;
+	u64 f;
+	u64 b;
+
+	s = (u64)busy * 100 * (1 << FIXED_POINT_OFFSET);
+	s += total / 2;
+	do_div(s, total);
+
+	f = (u64)total * 1000 * (1 << FIXED_POINT_OFFSET);
+	f += ns / 2;
+	f = div64_u64(f, ns);
+
+	b = (u64)busy * (128 / 8) * 1000 * (1 << FIXED_POINT_OFFSET);
+	b += ns / 2;
+	b = div64_u64(b, ns);
+
+	*sat = s;
+	*freq = f;
+	*bw = b;
+}
+
+static void exynos5_ppmu_debug_show_one_counter(struct seq_file *s,
+	const char *name, const char *type, struct exynos_ppmu *ppmu,
+	enum ppmu_counter i, u32 *bw_total)
+{
+	u32 sat;
+	u32 freq;
+	u32 bw;
+
+	exynos5_ppmu_debug_compute(ppmu, i, &sat, &freq, &bw);
+
+	seq_printf(s, "%-10s %-10s %4u.%02u MBps %3u.%02u MHz %2u.%02u%%\n",
+		name, type,
+		bw >> FIXED_POINT_OFFSET,
+		(bw & FIXED_POINT_MASK) * 100 / (1 << FIXED_POINT_OFFSET),
+		freq >> FIXED_POINT_OFFSET,
+		(freq & FIXED_POINT_MASK) * 100 / (1 << FIXED_POINT_OFFSET),
+		sat >> FIXED_POINT_OFFSET,
+		(sat & FIXED_POINT_MASK) * 100 / (1 << FIXED_POINT_OFFSET));
+
+	*bw_total += bw;
+}
+
+static void exynos5_ppmu_debug_show_one(struct seq_file *s,
+	const char *name, struct exynos_ppmu *ppmu,
+	u32 *bw_total)
+{
+	exynos5_ppmu_debug_show_one_counter(s, name, "read+write",
+		ppmu, PPMU_PMNCNT3, &bw_total[PPMU_PMNCNT3]);
+	exynos5_ppmu_debug_show_one_counter(s, "", "read",
+		ppmu, PPMU_PMNCNT0, &bw_total[PPMU_PMNCNT0]);
+	exynos5_ppmu_debug_show_one_counter(s, "", "write",
+		ppmu, PPMU_PMCCNT1, &bw_total[PPMU_PMCCNT1]);
+
+}
+
+static int exynos5_ppmu_debug_show(struct seq_file *s, void *d)
+{
+	int i;
+	u32 bw_total[PPMU_PMNCNT_MAX];
+	struct exynos5_ppmu_handle *handle;
+	unsigned long flags;
+
+	memset(bw_total, 0, sizeof(bw_total));
+
+	handle = exynos5_ppmu_get();
+	msleep(100);
+
+	spin_lock_irqsave(&exynos5_ppmu_lock, flags);
+
+	exynos5_ppmu_update();
+
+	for (i = 0; i < PPMU_CPU; i++)
+		exynos5_ppmu_debug_show_one(s, exynos5_ppmu_name[i],
+				&handle->ppmu[i], bw_total);
+
+	seq_printf(s, "%-10s %-10s %4u.%02u MBps\n", "total", "read+write",
+		bw_total[PPMU_PMNCNT3] >> FIXED_POINT_OFFSET,
+		(bw_total[PPMU_PMNCNT3] & FIXED_POINT_MASK) *
+				100 / (1 << FIXED_POINT_OFFSET));
+	seq_printf(s, "%-10s %-10s %4u.%02u MBps\n", "", "read",
+		bw_total[PPMU_PMNCNT0] >> FIXED_POINT_OFFSET,
+		(bw_total[PPMU_PMNCNT0] & FIXED_POINT_MASK) *
+				100 / (1 << FIXED_POINT_OFFSET));
+	seq_printf(s, "%-10s %-10s %4u.%02u MBps\n", "", "write",
+		bw_total[PPMU_PMCCNT1] >> FIXED_POINT_OFFSET,
+		(bw_total[PPMU_PMCCNT1] & FIXED_POINT_MASK) *
+				100 / (1 << FIXED_POINT_OFFSET));
+
+	seq_printf(s, "\n");
+
+	exynos5_ppmu_debug_show_one(s, exynos5_ppmu_name[PPMU_CPU],
+			&ppmu[PPMU_CPU], bw_total);
+
+	spin_unlock_irqrestore(&exynos5_ppmu_lock, flags);
+
+	exynos5_ppmu_put(handle);
+
+	return 0;
+}
+
+static int exynos5_ppmu_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, exynos5_ppmu_debug_show, inode->i_private);
+}
+
+static const struct file_operations exynos5_ppmu_debug_fops = {
+	.open		= exynos5_ppmu_debug_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init exynos5_ppmu_debug_init(void)
+{
+	debugfs_create_file("exynos5_bus", S_IRUGO, NULL, NULL,
+		&exynos5_ppmu_debug_fops);
+	return 0;
+}
+late_initcall(exynos5_ppmu_debug_init);
diff --git a/arch/arm/mach-exynos/exynos_ppmu.c b/arch/arm/mach-exynos/exynos_ppmu.c
new file mode 100644
index 0000000..f627813
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos_ppmu.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS - PPMU 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <mach/exynos_ppmu.h>
+
+void exynos_ppmu_reset(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_CYCLE_RESET | PPMU_COUNTER_RESET, ppmu_base);
+	__raw_writel(PPMU_ENABLE_CYCLE  |
+		     PPMU_ENABLE_COUNT0 |
+		     PPMU_ENABLE_COUNT1 |
+		     PPMU_ENABLE_COUNT2 |
+		     PPMU_ENABLE_COUNT3,
+		     ppmu_base + PPMU_CNTENS);
+}
+
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+			unsigned int evt)
+{
+	__raw_writel(evt, ppmu_base + PPMU_BEVTSEL(ch));
+}
+
+void exynos_ppmu_start(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_ENABLE, ppmu_base);
+}
+
+void exynos_ppmu_stop(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_DISABLE, ppmu_base);
+}
+
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch)
+{
+	unsigned int total;
+
+	if (ch == PPMU_PMNCNT3)
+		total = ((__raw_readl(ppmu_base + PMCNT_OFFSET(ch)) << 8) |
+			  __raw_readl(ppmu_base + PMCNT_OFFSET(ch + 1)));
+	else
+		total = __raw_readl(ppmu_base + PMCNT_OFFSET(ch));
+
+	return total;
+}
diff --git a/arch/arm/mach-exynos/include/mach/exynos5_ppmu.h b/arch/arm/mach-exynos/include/mach/exynos5_ppmu.h
new file mode 100644
index 0000000..9f492c1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/exynos5_ppmu.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS5 PPMU header
+ *
+ * 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.
+*/
+
+#ifndef __DEVFREQ_EXYNOS5_PPMU_H
+#define __DEVFREQ_EXYNOS5_PPMU_H __FILE__
+
+enum exynos5_ppmu_sets {
+	PPMU_SET_DDR,
+	PPMU_SET_RIGHT,
+	PPMU_SET_CPU,
+};
+
+struct exynos5_ppmu_handle *exynos5_ppmu_get(void);
+extern int exynos5_ppmu_get_busy(struct exynos5_ppmu_handle *handle,
+	enum exynos5_ppmu_sets filter);
+
+#endif /* __DEVFREQ_EXYNOS5_PPMU_H */
+
diff --git a/arch/arm/mach-exynos/include/mach/exynos_ppmu.h b/arch/arm/mach-exynos/include/mach/exynos_ppmu.h
new file mode 100644
index 0000000..b46d31b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/exynos_ppmu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS PPMU header
+ *
+ * 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.
+*/
+
+#ifndef __DEVFREQ_EXYNOS_PPMU_H
+#define __DEVFREQ_EXYNOS_PPMU_H __FILE__
+
+#include <linux/ktime.h>
+
+/* For PPMU Control */
+#define PPMU_ENABLE             BIT(0)
+#define PPMU_DISABLE            0x0
+#define PPMU_CYCLE_RESET        BIT(1)
+#define PPMU_COUNTER_RESET      BIT(2)
+
+#define PPMU_ENABLE_COUNT0      BIT(0)
+#define PPMU_ENABLE_COUNT1      BIT(1)
+#define PPMU_ENABLE_COUNT2      BIT(2)
+#define PPMU_ENABLE_COUNT3      BIT(3)
+#define PPMU_ENABLE_CYCLE       BIT(31)
+
+#define PPMU_CNTENS		0x10
+#define PPMU_FLAG		0x50
+#define PPMU_CCNT_OVERFLOW	BIT(31)
+#define PPMU_CCNT		0x100
+
+#define PPMU_PMCNT0		0x110
+#define PPMU_PMCNT_OFFSET	0x10
+#define PMCNT_OFFSET(x)		(PPMU_PMCNT0 + (PPMU_PMCNT_OFFSET * x))
+
+#define PPMU_BEVT0SEL		0x1000
+#define PPMU_BEVTSEL_OFFSET	0x100
+#define PPMU_BEVTSEL(x)		(PPMU_BEVT0SEL + (ch * PPMU_BEVTSEL_OFFSET))
+
+/* For Event Selection */
+#define RD_DATA_COUNT		0x5
+#define WR_DATA_COUNT		0x6
+#define RDWR_DATA_COUNT		0x7
+
+enum ppmu_counter {
+	PPMU_PMNCNT0,
+	PPMU_PMCCNT1,
+	PPMU_PMNCNT2,
+	PPMU_PMNCNT3,
+	PPMU_PMNCNT_MAX,
+};
+
+struct bus_opp_table {
+	unsigned int idx;
+	unsigned long clk;
+	unsigned long volt;
+};
+
+struct exynos_ppmu {
+	void __iomem *hw_base;
+	unsigned int ccnt;
+	unsigned int event[PPMU_PMNCNT_MAX];
+	unsigned int count[PPMU_PMNCNT_MAX];
+	unsigned long long ns;
+	ktime_t reset_time;
+	bool ccnt_overflow;
+	bool count_overflow[PPMU_PMNCNT_MAX];
+};
+
+void exynos_ppmu_reset(void __iomem *ppmu_base);
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+			unsigned int evt);
+void exynos_ppmu_start(void __iomem *ppmu_base);
+void exynos_ppmu_stop(void __iomem *ppmu_base);
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch);
+#endif /* __DEVFREQ_EXYNOS_PPMU_H */
+
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index b8ea67e..9af6e06 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -229,6 +229,12 @@
 #define EXYNOS4_PA_SDRAM		0x40000000
 #define EXYNOS5_PA_SDRAM		0x40000000
 
+#define EXYNOS5_PA_PPMU_DDR_C		0x10C40000
+#define EXYNOS5_PA_PPMU_DDR_R1		0x10C50000
+#define EXYNOS5_PA_PPMU_CPU		0x10C60000
+#define EXYNOS5_PA_PPMU_DDR_L		0x10CB0000
+#define EXYNOS5_PA_PPMU_RIGHT		0x13660000
+
 /* Compatibiltiy Defines */
 
 #define S3C_PA_HSMMC0			EXYNOS4_PA_HSMMC(0)
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
index d36ad76..3d3cbc8 100644
--- a/arch/arm/mach-exynos/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
@@ -323,6 +323,9 @@
 #define EXYNOS5_CLKDIV_PERIC5			EXYNOS_CLKREG(0x1056C)
 #define EXYNOS5_SCLK_DIV_ISP			EXYNOS_CLKREG(0x10580)
 
+#define EXYNOS5_CLKDIV_STAT_TOP0		EXYNOS_CLKREG(0x10610)
+#define EXYNOS5_CLKDIV_STAT_TOP1		EXYNOS_CLKREG(0x10614)
+
 #define EXYNOS5_CLKGATE_IP_ACP			EXYNOS_CLKREG(0x08800)
 #define EXYNOS5_CLKGATE_IP_ISP0			EXYNOS_CLKREG(0x0C800)
 #define EXYNOS5_CLKGATE_IP_ISP1			EXYNOS_CLKREG(0x0C804)
@@ -337,6 +340,18 @@
 #define EXYNOS5_CLKGATE_IP_PERIS		EXYNOS_CLKREG(0x10960)
 #define EXYNOS5_CLKGATE_BLOCK			EXYNOS_CLKREG(0x10980)
 
+#define EXYNOS5_CLKGATE_BUS_SYSLFT		EXYNOS_CLKREG(0x08920)
+
+#define EXYNOS5_CLKOUT_CMU_TOP			EXYNOS_CLKREG(0x10A00)
+
+#define EXYNOS5_CLKDIV_LEX			EXYNOS_CLKREG(0x14500)
+#define EXYNOS5_CLKDIV_STAT_LEX			EXYNOS_CLKREG(0x14600)
+
+#define EXYNOS5_CLKDIV_R0X			EXYNOS_CLKREG(0x18500)
+#define EXYNOS5_CLKDIV_STAT_R0X			EXYNOS_CLKREG(0x18600)
+
+#define EXYNOS5_CLKDIV_R1X			EXYNOS_CLKREG(0x1C500)
+#define EXYNOS5_CLKDIV_STAT_R1X			EXYNOS_CLKREG(0x1C600)
 #define EXYNOS5_BPLL_CON0			EXYNOS_CLKREG(0x20110)
 #define EXYNOS5_CLKSRC_CDREX			EXYNOS_CLKREG(0x20200)
 #define EXYNOS5_CLKDIV_CDREX			EXYNOS_CLKREG(0x20500)
@@ -347,6 +362,28 @@
 
 #define EXYNOS5_EPLLCON0_LOCKED_SHIFT		(29)
 
+#define EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_SHIFT	(28)
+#define EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_MASK	(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK333_SHIFT	(20)
+#define EXYNOS5_CLKDIV_TOP0_ACLK333_MASK	(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK333_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK266_SHIFT	(16)
+#define EXYNOS5_CLKDIV_TOP0_ACLK266_MASK	(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK266_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK200_SHIFT	(12)
+#define EXYNOS5_CLKDIV_TOP0_ACLK200_MASK	(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK200_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK166_SHIFT	(8)
+#define EXYNOS5_CLKDIV_TOP0_ACLK166_MASK	(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK166_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK66_SHIFT	(0)
+#define EXYNOS5_CLKDIV_TOP0_ACLK66_MASK		(0x7 << EXYNOS5_CLKDIV_TOP0_ACLK66_SHIFT)
+
+#define EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_SHIFT	(24)
+#define EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_MASK	(0x7 << EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_SHIFT	(20)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_MASK	(0x7 << EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_SHIFT	(16)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_MASK	(0x7 << EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_SHIFT	(12)
+#define EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_MASK	(0x7 << EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_SHIFT)
+
 #define PWR_CTRL1_CORE2_DOWN_RATIO		(7 << 28)
 #define PWR_CTRL1_CORE1_DOWN_RATIO		(7 << 16)
 #define PWR_CTRL1_DIV2_DOWN_EN			(1 << 9)
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index c186786..9399f2d 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -41,6 +41,12 @@
 #define S5P_VA_GIC_CPU		S3C_ADDR(0x02810000)
 #define S5P_VA_GIC_DIST		S3C_ADDR(0x02820000)
 
+#define S5P_VA_PPMU_CPU		S3C_ADDR(0x02830000)
+#define S5P_VA_PPMU_DDR_C	S3C_ADDR(0x02832000)
+#define S5P_VA_PPMU_DDR_R1	S3C_ADDR(0x02834000)
+#define S5P_VA_PPMU_DDR_L	S3C_ADDR(0x02836000)
+#define S5P_VA_PPMU_RIGHT	S3C_ADDR(0x02838000)
+
 #define VA_VIC(x)		(S3C_VA_IRQ + ((x) * 0x10000))
 #define VA_VIC0			VA_VIC(0)
 #define VA_VIC1			VA_VIC(1)
-- 
1.8.1-rc3


^ permalink raw reply related

* Re: [PATCH v9 06/10] ata: zpodd: check zero power ready status
From: Tejun Heo @ 2012-12-28 21:16 UTC (permalink / raw)
  To: Aaron Lu
  Cc: James Bottomley, Rafael J. Wysocki, linux-pm, Jeff Garzik,
	Alan Stern, Jeff Wu, Aaron Lu, linux-ide, linux-scsi, linux-acpi
In-Reply-To: <50DA55F6.8080706@intel.com>

Hello,

On Wed, Dec 26, 2012 at 09:42:14AM +0800, Aaron Lu wrote:
> > This is really a round-about way to find out the matching device and
> > it wouldn't work if the disk device nests deeper.  Doesn't really look
> > like a good idea to me.
> 
> I don't quite understand the 'disk device nests deeper' case, can you
> please elaborate? My understanding is, as long as the disk's part0
> device has a parent, this function should work. For LLDs want to take

Hmmm, maybe I misread but it looked like it wouldn't work if there are
intermediate nodes between the parent device and part0.  It might not
happen for sata but I don't think it's a good idea to assume that the
part0 and hardware device are connected directly.

In general, it's a quite roundabout way to do it.  Let's just push it
through SCSI.  That's how everything else is routed after all.  It's
confusing to do this one differently.

Thanks.

-- 
tejun

^ permalink raw reply

* [PATCH] Fix problem with cpufreq_pndemand or cpufreq_conservative
From: Larry Finger @ 2012-12-28 22:17 UTC (permalink / raw)
  To: viresh kumar, Rafael J. Wysocki; +Cc: cpufreq, Linux PM list, LKML

Since commit 2aacdff entitled "cpufreq: Move common part from governors to 
separate file", whenever the drivers that depend on this new file 
(cpufreq_ondemand or cpufreq_conservative) are built as modules, a new module 
named cpufreq_governor is created. It seems that kmake is smart enough to create 
a separate module whenever more than one module includes the same object file. 
As drivers/cpufreq/cpufreq_governor.c contains no MODULE directives, the 
resulting module has no license specified, which results in logging of a "module 
license 'unspecified' taints kernel". In addition, a number of globals are 
exported GPL only, and are therefore not available.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---

This particular patch is the simplest possible; however, it hides the intent. I 
have prepared the longer version that makes the reason clearer by adding a new 
configuration variable that is dependent on the other two, and rearranges 
drivers/cpufreq/Makefile. That version could be submitted if that is what is 
desired. The changes to cpufreq_governor.c are the same as in this version.

Larry


       cpufreq_governor.c |    5 +++++
       1 file changed, 5 insertions(+)
---
Index: wireless-testing-new/drivers/cpufreq/cpufreq_governor.c
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/cpufreq_governor.c
+++ wireless-testing-new/drivers/cpufreq/cpufreq_governor.c
@@ -25,6 +25,7 @@
  #include <linux/tick.h>
  #include <linux/types.h>
  #include <linux/workqueue.h>
+#include <linux/module.h>

  #include "cpufreq_governor.h"

@@ -316,3 +317,7 @@ second_time:
  	return 0;
  }
  EXPORT_SYMBOL_GPL(cpufreq_governor_dbs);
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("'cpufreq_governor' - A mini-module containing "
+		"common code for cpufreq_conservative and cpufreq_ondemand");
+MODULE_LICENSE("GPL");







^ permalink raw reply

* Re: [PATCH] Fix problem with cpufreq_pndemand or cpufreq_conservative
From: Rafael J. Wysocki @ 2012-12-28 23:01 UTC (permalink / raw)
  To: Larry Finger; +Cc: viresh kumar, cpufreq, Linux PM list, LKML
In-Reply-To: <50DE1A74.4040607@lwfinger.net>

On Friday, December 28, 2012 04:17:24 PM Larry Finger wrote:
> Since commit 2aacdff entitled "cpufreq: Move common part from governors to 
> separate file", whenever the drivers that depend on this new file 
> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new module 
> named cpufreq_governor is created. It seems that kmake is smart enough to create 
> a separate module whenever more than one module includes the same object file. 
> As drivers/cpufreq/cpufreq_governor.c contains no MODULE directives, the 
> resulting module has no license specified, which results in logging of a "module 
> license 'unspecified' taints kernel". In addition, a number of globals are 
> exported GPL only, and are therefore not available.
> 
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
> 
> This particular patch is the simplest possible; however, it hides the intent. I 
> have prepared the longer version that makes the reason clearer by adding a new 
> configuration variable that is dependent on the other two, and rearranges 
> drivers/cpufreq/Makefile. That version could be submitted if that is what is 
> desired.

Yes, please.

> The changes to cpufreq_governor.c are the same as in this version.

I wonder if that's avoidable?  The intention is not to create an additional
module, clearly.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH] Fix problem with cpufreq_pndemand or cpufreq_conservative
From: Larry Finger @ 2012-12-28 23:45 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: viresh kumar, cpufreq, Linux PM list, LKML
In-Reply-To: <3226192.H2BxHSuKio@vostro.rjw.lan>

On 12/28/2012 05:01 PM, Rafael J. Wysocki wrote:
> On Friday, December 28, 2012 04:17:24 PM Larry Finger wrote:
>> Since commit 2aacdff entitled "cpufreq: Move common part from governors to
>> separate file", whenever the drivers that depend on this new file
>> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new module
>> named cpufreq_governor is created. It seems that kmake is smart enough to create
>> a separate module whenever more than one module includes the same object file.
>> As drivers/cpufreq/cpufreq_governor.c contains no MODULE directives, the
>> resulting module has no license specified, which results in logging of a "module
>> license 'unspecified' taints kernel". In addition, a number of globals are
>> exported GPL only, and are therefore not available.
>>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> ---
>>
>> This particular patch is the simplest possible; however, it hides the intent. I
>> have prepared the longer version that makes the reason clearer by adding a new
>> configuration variable that is dependent on the other two, and rearranges
>> drivers/cpufreq/Makefile. That version could be submitted if that is what is
>> desired.
>
> Yes, please.

I'll send it shortly.

>> The changes to cpufreq_governor.c are the same as in this version.
>
> I wonder if that's avoidable?  The intention is not to create an additional
> module, clearly.

It appears not to be possible. I don't know enough about to kmake to understand 
why it is forcing a new module. Perhaps some expert knows what Kconfig or 
Makefile magic will prevent that.

Larry




^ permalink raw reply

* [PATCH V2] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Larry Finger @ 2012-12-29  0:21 UTC (permalink / raw)
  To: viresh kumar, Rafael J. Wysocki; +Cc: cpufreq, Linux PM list, LKML

Since commit 2aacdff entitled "cpufreq: Move common part from governors to separate file", whenever the drivers that 
depend on this new file (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new module named 
cpufreq_governor is created. It seems that kmake is smart enough to create a separate module whenever more than one 
module includes the same object file. As drivers/cpufreq/cpufreq_governor.c contains no MODULE directives, the resulting 
module has no license specified, which results in logging of a "module license 'unspecified' taints kernel". In 
addition, a number of globals are exported GPL only, and are therefore not available.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---

V2 is the more complicated version that makes clear what is happening.

Larry
---

  Kconfig            |    5 +++++
  Makefile           |    5 +++--
  cpufreq_governor.c |    5 +++++
  3 files changed, 13 insertions(+), 2 deletions(-)
---

Index: wireless-testing-new/drivers/cpufreq/Makefile
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/Makefile
+++ wireless-testing-new/drivers/cpufreq/Makefile
@@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT)
  obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
  obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)	+= cpufreq_powersave.o
  obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
-obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o cpufreq_governor.o
-obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o cpufreq_governor.o
+obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
+obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
+obj-$(CONFIG_CPU_FREQ_GOVERNOR)		+= cpufreq_governor.o

  # CPUfreq cross-arch helpers
  obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
Index: wireless-testing-new/drivers/cpufreq/Kconfig
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/Kconfig
+++ wireless-testing-new/drivers/cpufreq/Kconfig
@@ -20,6 +20,9 @@ if CPU_FREQ
  config CPU_FREQ_TABLE
  	tristate

+config CPU_FREQ_GOVERNOR
+	tristate
+
  config CPU_FREQ_STAT
  	tristate "CPU frequency translation statistics"
  	select CPU_FREQ_TABLE
@@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE
  config CPU_FREQ_GOV_ONDEMAND
  	tristate "'ondemand' cpufreq policy governor"
  	select CPU_FREQ_TABLE
+	select CPU_FREQ_GOVERNOR
  	help
  	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
  	  The governor does a periodic polling and
@@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND
  config CPU_FREQ_GOV_CONSERVATIVE
  	tristate "'conservative' cpufreq governor"
  	depends on CPU_FREQ
+	select CPU_FREQ_GOVERNOR
  	help
  	  'conservative' - this driver is rather similar to the 'ondemand'
  	  governor both in its source code and its purpose, the difference is
Index: wireless-testing-new/drivers/cpufreq/cpufreq_governor.c
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/cpufreq_governor.c
+++ wireless-testing-new/drivers/cpufreq/cpufreq_governor.c
@@ -316,3 +316,8 @@ second_time:
  	return 0;
  }
  EXPORT_SYMBOL_GPL(cpufreq_governor_dbs);
+
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("'cpufreq_governor' - A mini-module containing common code "
+		   "for cpufreq_conservative and cpufreq_ondemand");
+MODULE_LICENSE("GPL");

^ permalink raw reply

* Re: [PATCH] Fix problem with cpufreq_pndemand or cpufreq_conservative
From: Fabio Baltieri @ 2012-12-29  0:33 UTC (permalink / raw)
  To: Larry Finger
  Cc: Rafael J. Wysocki, viresh kumar, cpufreq, Linux PM list, LKML
In-Reply-To: <50DE2F32.1010207@lwfinger.net>

On Fri, Dec 28, 2012 at 05:45:54PM -0600, Larry Finger wrote:
> >I wonder if that's avoidable?  The intention is not to create an additional
> >module, clearly.
> 
> It appears not to be possible. I don't know enough about to kmake to
> understand why it is forcing a new module. Perhaps some expert knows
> what Kconfig or Makefile magic will prevent that.

kbuild is building an additional module just because the makefile is
adding the new objects in the obj-m list directly, as in:

obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)     += cpufreq_ondemand.o cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o

To build just two modules the Makefile would have to be modified [1]
into something into something like:

obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)     += cpufreq_ondemand_mod.o
cpufreq_ondemand_mod-y                  := cpufreq_ondemand.o cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative_mod.o
cpufreq_conservative_mod-y              := cpufreq_conservative.o cpufreq_governor.o

so that only two .o are added to obj-m, but that's not correct either as
you end up with cpufreq_governor symbols exported twice.

I think the only way would be to force cpufreq_governor as builtin with
an automatic Kconfig option.

Fabio

1. http://lxr.linux.no/#linux+v3.7.1/Documentation/kbuild/makefiles.txt#L191

-- 
Fabio Baltieri

^ permalink raw reply

* Re: [PATCH] Fix problem with cpufreq_pndemand or cpufreq_conservative
From: Larry Finger @ 2012-12-29  0:53 UTC (permalink / raw)
  To: Fabio Baltieri, Rafael J. Wysocki, viresh kumar, cpufreq,
	Linux PM list, LKML
In-Reply-To: <20121229003341.GA30982@balto.lan>

On 12/28/2012 06:33 PM, Fabio Baltieri wrote:
> On Fri, Dec 28, 2012 at 05:45:54PM -0600, Larry Finger wrote:
>>> I wonder if that's avoidable?  The intention is not to create an additional
>>> module, clearly.
>>
>> It appears not to be possible. I don't know enough about to kmake to
>> understand why it is forcing a new module. Perhaps some expert knows
>> what Kconfig or Makefile magic will prevent that.
>
> kbuild is building an additional module just because the makefile is
> adding the new objects in the obj-m list directly, as in:
>
> obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)     += cpufreq_ondemand.o cpufreq_governor.o
> obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o
>
> To build just two modules the Makefile would have to be modified [1]
> into something into something like:
>
> obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)     += cpufreq_ondemand_mod.o
> cpufreq_ondemand_mod-y                  := cpufreq_ondemand.o cpufreq_governor.o
> obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative_mod.o
> cpufreq_conservative_mod-y              := cpufreq_conservative.o cpufreq_governor.o
>
> so that only two .o are added to obj-m, but that's not correct either as
> you end up with cpufreq_governor symbols exported twice.
>
> I think the only way would be to force cpufreq_governor as builtin with
> an automatic Kconfig option.
>
> Fabio
>
> 1. http://lxr.linux.no/#linux+v3.7.1/Documentation/kbuild/makefiles.txt#L191

Fabio,

Thanks for the explanation. Now I think I know how to do it.

V3 follows.

Larry



^ permalink raw reply

* [PATCH V3] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Larry Finger @ 2012-12-29  1:55 UTC (permalink / raw)
  To: rjw; +Cc: fabio.baltieri, viresh.kumar, linux-kernel, linux-pm

Since commit 2aacdff entitled "cpufreq: Move common part from governors
to separate file", whenever the drivers that depend on this new file
(cpufreq_ondemand or cpufreq_conservative) are built as modules, a new
module named cpufreq_governor is created because the Makefile includes
cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no
MODULE directives, the resulting module has no license specified, which
results in logging of a "module license 'unspecified' taints kernel". In
addition, a number of globals are exported GPL only, and are therefore
not available. This fix establishes a new boolean configuration variable
that forces cpufreq_governor.o to be linked into the kernel whenever
either cpufreq_ondemand or cpufreq_conservative is selected.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
V3 changes only Kconfig and Makefile and avoids creating a new module.

Larry

 Kconfig  |    5 +++++
 Makefile |    5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)

Index: wireless-testing-new/drivers/cpufreq/Kconfig
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/Kconfig
+++ wireless-testing-new/drivers/cpufreq/Kconfig
@@ -20,6 +20,9 @@ if CPU_FREQ
 config CPU_FREQ_TABLE
 	tristate
 
+config CPU_FREQ_GOVERNOR
+	bool
+
 config CPU_FREQ_STAT
 	tristate "CPU frequency translation statistics"
 	select CPU_FREQ_TABLE
@@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
 	select CPU_FREQ_TABLE
+	select CPU_FREQ_GOVERNOR
 	help
 	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
 	  The governor does a periodic polling and 
@@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND
 config CPU_FREQ_GOV_CONSERVATIVE
 	tristate "'conservative' cpufreq governor"
 	depends on CPU_FREQ
+	select CPU_FREQ_GOVERNOR
 	help
 	  'conservative' - this driver is rather similar to the 'ondemand'
 	  governor both in its source code and its purpose, the difference is
Index: wireless-testing-new/drivers/cpufreq/Makefile
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/Makefile
+++ wireless-testing-new/drivers/cpufreq/Makefile
@@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT)
 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
 obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)	+= cpufreq_powersave.o
 obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
-obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o cpufreq_governor.o
-obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o cpufreq_governor.o
+obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
+obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
+obj-$(CONFIG_CPU_FREQ_GOVERNOR)		+= cpufreq_governor.o
 
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o

^ permalink raw reply

* Re: [PATCH] cpuidle - fix lock contention in the idle path
From: Daniel Lezcano @ 2012-12-29 10:03 UTC (permalink / raw)
  To: rafael.j.wysocki, rja; +Cc: linux-pm, pdeschrijver, akpm, linux-kernel
In-Reply-To: <1356516108-11191-1-git-send-email-daniel.lezcano@linaro.org>


Hi Russ,

Is it possible you try this patch on your 2048 cpus ?

Thanks

  -- Daniel

On 12/26/2012 11:01 AM, Daniel Lezcano wrote:
> The commit bf4d1b5ddb78f86078ac6ae0415802d5f0c68f92 introduces
> a lock in the cpuidle_get_cpu_driver function. This function
> is used in the idle_call function.
> 
> The problem is the contention with a large number of cpus because
> they try to access the idle routine at the same time.
> 
> The lock could be safely removed because of how is used the
> cpuidle api. The cpuidle_register_driver is called first but
> until the cpuidle_register_device is not called we don't
> enter in the cpuidle idle call function because the device
> is not enabled.
> 
> The cpuidle_unregister_driver function, leading the a NULL driver,
> is not called before the cpuidle_unregister_device.
> 
> This is how is used the cpuidle api from the different drivers.
> 
> However, a cleanup around the lock and a proper refcounting
> mechanism should be used to ensure the consistency in the api,
> like cpuidle_unregister_driver should failed if its refcounting
> is not 0.
> 
> These modifications will need some code reorganization and rewrite
> which does not fit with a fix.
> 
> The following patch is a hot fix by returning to the initial behavior
> by removing the lock when getting the driver.
> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
>  drivers/cpuidle/driver.c |    8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
> index 3af841f..c2b281a 100644
> --- a/drivers/cpuidle/driver.c
> +++ b/drivers/cpuidle/driver.c
> @@ -235,16 +235,10 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver);
>   */
>  struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
>  {
> -	struct cpuidle_driver *drv;
> -
>  	if (!dev)
>  		return NULL;
>  
> -	spin_lock(&cpuidle_driver_lock);
> -	drv = __cpuidle_get_cpu_driver(dev->cpu);
> -	spin_unlock(&cpuidle_driver_lock);
> -
> -	return drv;
> +	return __cpuidle_get_cpu_driver(dev->cpu);
>  }
>  EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
>  
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply

* Re: [PATCH V3] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Rafael J. Wysocki @ 2012-12-29 13:27 UTC (permalink / raw)
  To: Larry Finger; +Cc: fabio.baltieri, viresh.kumar, linux-kernel, linux-pm
In-Reply-To: <50de4d88.M3WYPilXC8de/dVl%Larry.Finger@lwfinger.net>

On Friday, December 28, 2012 07:55:20 PM Larry Finger wrote:
> Since commit 2aacdff entitled "cpufreq: Move common part from governors
> to separate file", whenever the drivers that depend on this new file
> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new
> module named cpufreq_governor is created because the Makefile includes
> cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no
> MODULE directives, the resulting module has no license specified, which
> results in logging of a "module license 'unspecified' taints kernel". In
> addition, a number of globals are exported GPL only, and are therefore
> not available. This fix establishes a new boolean configuration variable
> that forces cpufreq_governor.o to be linked into the kernel whenever
> either cpufreq_ondemand or cpufreq_conservative is selected.
> 
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
> V3 changes only Kconfig and Makefile and avoids creating a new module.

OK, thanks for the patch!

If you don't mind, I'll rename CONFIG_CPU_FREQ_GOVERNOR to
CONFIG_CPU_FREQ_GOV_COMMON when applying it, though.

Thanks,
Rafael


>  Kconfig  |    5 +++++
>  Makefile |    5 +++--
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> Index: wireless-testing-new/drivers/cpufreq/Kconfig
> ===================================================================
> --- wireless-testing-new.orig/drivers/cpufreq/Kconfig
> +++ wireless-testing-new/drivers/cpufreq/Kconfig
> @@ -20,6 +20,9 @@ if CPU_FREQ
>  config CPU_FREQ_TABLE
>  	tristate
>  
> +config CPU_FREQ_GOVERNOR
> +	bool
> +
>  config CPU_FREQ_STAT
>  	tristate "CPU frequency translation statistics"
>  	select CPU_FREQ_TABLE
> @@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE
>  config CPU_FREQ_GOV_ONDEMAND
>  	tristate "'ondemand' cpufreq policy governor"
>  	select CPU_FREQ_TABLE
> +	select CPU_FREQ_GOVERNOR
>  	help
>  	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
>  	  The governor does a periodic polling and 
> @@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND
>  config CPU_FREQ_GOV_CONSERVATIVE
>  	tristate "'conservative' cpufreq governor"
>  	depends on CPU_FREQ
> +	select CPU_FREQ_GOVERNOR
>  	help
>  	  'conservative' - this driver is rather similar to the 'ondemand'
>  	  governor both in its source code and its purpose, the difference is
> Index: wireless-testing-new/drivers/cpufreq/Makefile
> ===================================================================
> --- wireless-testing-new.orig/drivers/cpufreq/Makefile
> +++ wireless-testing-new/drivers/cpufreq/Makefile
> @@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT)
>  obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
>  obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)	+= cpufreq_powersave.o
>  obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
> -obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o cpufreq_governor.o
> -obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o cpufreq_governor.o
> +obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
> +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
> +obj-$(CONFIG_CPU_FREQ_GOVERNOR)		+= cpufreq_governor.o
>  
>  # CPUfreq cross-arch helpers
>  obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH V3] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Larry Finger @ 2012-12-29 15:39 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: fabio.baltieri, viresh.kumar, linux-kernel, linux-pm
In-Reply-To: <2035804.da5iyiYDGE@vostro.rjw.lan>

On 12/29/2012 07:27 AM, Rafael J. Wysocki wrote:
> On Friday, December 28, 2012 07:55:20 PM Larry Finger wrote:
>> Since commit 2aacdff entitled "cpufreq: Move common part from governors
>> to separate file", whenever the drivers that depend on this new file
>> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new
>> module named cpufreq_governor is created because the Makefile includes
>> cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no
>> MODULE directives, the resulting module has no license specified, which
>> results in logging of a "module license 'unspecified' taints kernel". In
>> addition, a number of globals are exported GPL only, and are therefore
>> not available. This fix establishes a new boolean configuration variable
>> that forces cpufreq_governor.o to be linked into the kernel whenever
>> either cpufreq_ondemand or cpufreq_conservative is selected.
>>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> ---
>> V3 changes only Kconfig and Makefile and avoids creating a new module.
>
> OK, thanks for the patch!
>
> If you don't mind, I'll rename CONFIG_CPU_FREQ_GOVERNOR to
> CONFIG_CPU_FREQ_GOV_COMMON when applying it, though.

No problem. It occurred to me that if one can do logic in a Makefile, then the 
extra configuration variable can be eliminated. I still need to check if that is 
possible.

Larry

>
> Thanks,
> Rafael
>
>
>>   Kconfig  |    5 +++++
>>   Makefile |    5 +++--
>>   2 files changed, 8 insertions(+), 2 deletions(-)
>>
>> Index: wireless-testing-new/drivers/cpufreq/Kconfig
>> ===================================================================
>> --- wireless-testing-new.orig/drivers/cpufreq/Kconfig
>> +++ wireless-testing-new/drivers/cpufreq/Kconfig
>> @@ -20,6 +20,9 @@ if CPU_FREQ
>>   config CPU_FREQ_TABLE
>>   	tristate
>>
>> +config CPU_FREQ_GOVERNOR
>> +	bool
>> +
>>   config CPU_FREQ_STAT
>>   	tristate "CPU frequency translation statistics"
>>   	select CPU_FREQ_TABLE
>> @@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE
>>   config CPU_FREQ_GOV_ONDEMAND
>>   	tristate "'ondemand' cpufreq policy governor"
>>   	select CPU_FREQ_TABLE
>> +	select CPU_FREQ_GOVERNOR
>>   	help
>>   	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
>>   	  The governor does a periodic polling and
>> @@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND
>>   config CPU_FREQ_GOV_CONSERVATIVE
>>   	tristate "'conservative' cpufreq governor"
>>   	depends on CPU_FREQ
>> +	select CPU_FREQ_GOVERNOR
>>   	help
>>   	  'conservative' - this driver is rather similar to the 'ondemand'
>>   	  governor both in its source code and its purpose, the difference is
>> Index: wireless-testing-new/drivers/cpufreq/Makefile
>> ===================================================================
>> --- wireless-testing-new.orig/drivers/cpufreq/Makefile
>> +++ wireless-testing-new/drivers/cpufreq/Makefile
>> @@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT)
>>   obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
>>   obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)	+= cpufreq_powersave.o
>>   obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
>> -obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o cpufreq_governor.o
>> -obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o cpufreq_governor.o
>> +obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
>> +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
>> +obj-$(CONFIG_CPU_FREQ_GOVERNOR)		+= cpufreq_governor.o
>>
>>   # CPUfreq cross-arch helpers
>>   obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o

^ permalink raw reply

* Re: [PATCH V3] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Larry Finger @ 2012-12-29 17:24 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: fabio.baltieri, viresh.kumar, linux-kernel, linux-pm
In-Reply-To: <2035804.da5iyiYDGE@vostro.rjw.lan>

On 12/29/2012 07:27 AM, Rafael J. Wysocki wrote:
> On Friday, December 28, 2012 07:55:20 PM Larry Finger wrote:
>> Since commit 2aacdff entitled "cpufreq: Move common part from governors
>> to separate file", whenever the drivers that depend on this new file
>> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new
>> module named cpufreq_governor is created because the Makefile includes
>> cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no
>> MODULE directives, the resulting module has no license specified, which
>> results in logging of a "module license 'unspecified' taints kernel". In
>> addition, a number of globals are exported GPL only, and are therefore
>> not available. This fix establishes a new boolean configuration variable
>> that forces cpufreq_governor.o to be linked into the kernel whenever
>> either cpufreq_ondemand or cpufreq_conservative is selected.
>>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> ---
>> V3 changes only Kconfig and Makefile and avoids creating a new module.
>
> OK, thanks for the patch!
>
> If you don't mind, I'll rename CONFIG_CPU_FREQ_GOVERNOR to
> CONFIG_CPU_FREQ_GOV_COMMON when applying it, though.

The following does the job and is somewhat cleaner. If you want, I can remove 
the line wrap and submit it as V4. The downside of this approach is that the 
nested ifs will get cumbersome is more governors need cpufreq_governor.o.

Larry

Index: wireless-testing-new/drivers/cpufreq/Makefile
===================================================================
--- wireless-testing-new.orig/drivers/cpufreq/Makefile
+++ wireless-testing-new/drivers/cpufreq/Makefile
@@ -7,8 +7,15 @@ obj-$(CONFIG_CPU_FREQ_STAT)
  obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
  obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)   += cpufreq_powersave.o
  obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)   += cpufreq_userspace.o
-obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)    += cpufreq_ondemand.o cpufreq_governor.o
-obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)        += cpufreq_conservative.o 
cpufreq_governor.o
+obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)    += cpufreq_ondemand.o
+obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)        += cpufreq_conservative.o
+ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND
+  obj-y += cpufreq_governor.o
+else
+  ifdef CONFIG_CPU_FREQ_GOV_CONSERVATIVE
+    obj-y += cpufreq_governor.o
+  endif
+endif

  # CPUfreq cross-arch helpers
  obj-$(CONFIG_CPU_FREQ_TABLE)           += freq_table.o

^ permalink raw reply

* Re: [PATCH] [RFC] cpufreq: can't raise max frequency with cpu_thermal
From: Sonny Rao @ 2012-12-29 21:04 UTC (permalink / raw)
  To: amit daniel kachhap
  Cc: Doug Anderson, linux-pm, linux-kernel@vger.kernel.org, Zhang Rui,
	Sameer Nanda
In-Reply-To: <CADGdYn7m-rE_jJG_qV7hS_Lh=3Z+hx+9BjmqPpRrxt_BeMA5tA@mail.gmail.com>

On Wed, Dec 26, 2012 at 11:32 AM, amit daniel kachhap
<amit.daniel@samsung.com> wrote:
>
> On Tue, Dec 18, 2012 at 9:45 PM, Doug Anderson <dianders@chromium.org> wrote:
> > Amit,
> >
> > On Tue, Dec 18, 2012 at 8:17 PM, amit daniel kachhap
> > <amit.daniel@samsung.com> wrote:
> >> On Tue, Dec 18, 2012 at 12:29 AM, Sonny Rao <sonnyrao@chromium.org> wrote:
> >>> The cpu_thermal generic thermal management code has a bug where once
> >>> max cpu frequency has been lowered in sysfs (scaling_max_freq) it is
> >>> not possible to raise the max back up later.  The bug is that the
> >>> notifer gets called by __cpufreq_set_policy() before the user policy
> >>> max is raised, and is incorrectly trying to enforce the max frequency
> >>> policy even when we are trying to change the policy.  It is also not
> >>> clear why this driver is looking at the user policy since it is
> >>> primarily supposed to enforce thermal policy, not user set policy.
> >>
> >> Hi Sunny,
> >>
> >> I am not sure if this change is needed.
> >
> > Do you have a machine that's running with your code?  Can you go into
> > sysfs (/sys/devices/system/cpu/cpu0/cpufreq/) and try lowering then
> > raising the max frequency by doing something like this (assumes that
> > you can scale down to 200MHz):
> >
> >   cd /sys/devices/system/cpu/cpu0/cpufreq/
> >   OLD_VAL=$(cat scaling_max_freq)
> >   cat scaling_min_freq > scaling_max_freq
> >   echo ${OLD_VAL} > scaling_max_freq
> >
> >   echo "$(cat scaling_max_freq) should be ${OLD_VAL}.  Is it?"
> >
> > ...when I run the above without Sonny's patch on my system I see:
> >   200000 should be 1700000. Is it?
> >
> > ...after Sonny's patch then the above works.
> Hi Doug,
>
> I tested the above steps on exynos origen board with all cpufreq
> cooling configs enabled in kernel version 3.8-rc1.
> In my tests I am able to vary scaling_max_freq to all values. Also I
> am in normal temperature threshold. So basically I am not able to
> reproduce the error reported,
>
> Thanks,
> Amit Daniel


Hi, thanks for checking it out.  I'm a bit surprised that you couldn't
reproduce it, but it might just be that it will only manifest on a
platform which is using that driver - like Exynos 5?  We'll try it out
on a 3.8-rc on an Exynos and let you know if we see it or not.

Thanks again,
Sonny


>
> >
> >> There is a check in cpufreq_thermal_notifier function to return 0 if
> >> notify_device == NOTIFY_INVALID. So the user will be always able to
> >> change the max frequency in normal situation. Did you tested this for
> >> some corner cases?
> >> The reason behind putting this check is that I don't want to override
> >> the user constraints.
> >>
> >> Thanks,
> >> Amit Daniel
> >>
> >>>
> >>> Signed-off-by: Sonny Rao <sonnyrao@chromium.org>
> >>> ---
> >>>  drivers/thermal/cpu_cooling.c |    4 ----
> >>>  1 files changed, 0 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
> >>> index 836828e..63bc708 100644
> >>> --- a/drivers/thermal/cpu_cooling.c
> >>> +++ b/drivers/thermal/cpu_cooling.c
> >>> @@ -219,10 +219,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
> >>>         if (cpumask_test_cpu(policy->cpu, &notify_device->allowed_cpus))
> >>>                 max_freq = notify_device->cpufreq_val;
> >>>
> >>> -       /* Never exceed user_policy.max*/
> >>> -       if (max_freq > policy->user_policy.max)
> >>> -               max_freq = policy->user_policy.max;
> >>> -
> >>>         if (policy->max != max_freq)
> >>>                 cpufreq_verify_within_limits(policy, 0, max_freq);
> >>>
> >>> --
> >>> 1.7.7.3
> >>>
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> >>> the body of a message to majordomo@vger.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>> Please read the FAQ at  http://www.tux.org/lkml/
> >
> > -Doug
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Rafael J. Wysocki @ 2012-12-29 21:57 UTC (permalink / raw)
  To: Tim Hockin; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <CAAAKZwsU=jMb6SCvUrAZqRn-uD8HNX3cJ8VFqrG-dqiOoW3+QQ@mail.gmail.com>

On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
> resume worked flawlessly every time.
> 
> Then I upgraded to Ubuntu Precise.

Well, do you use a distro kernel or a kernel.org kernel?

> Suspend seems to work, but resume
> fails every time. The video never initializes.  By the flashing
> keyboard lights, I guess it's a kernel panic. It fails from the Live
> CD and from a fresh install.
> 
> Here is my debug so far.
> 
> Install all updates (3.2 kernel, nouveau driver)
> Reboot
> Try suspend = fails
> 
> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
> Reboot
> Try suspend = fails
> 
> Install nVidia's 304 driver
> Reboot
> Try suspend = fails
> 
> From within X:
>   echo core > /sys/power/pm_test
>   echo mem > /sys/power/state
> The system acts like it is going to sleep, and then wakes up a few
> seconds later. dmesg shows:
> 
> [ 1230.083404] ------------[ cut here ]------------
> [ 1230.083410] WARNING: at
> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
> suspend_test_finish+0x86/0x90()
> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
> [ 1230.083412] Component: resume devices, time: 14424
> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
> pata_marvell
> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
> #32~precise1-Ubuntu
> [ 1230.083446] Call Trace:
> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
> 
> Boot with init=/bin/bash
> unload all modules except USBHID
> echo core > /sys/power/pm_test
> echo mem > /sys/power/state
> system acts like it is going to sleep, and then wakes up a few seconds later
> echo none > /sys/power/pm_test
> echo mem > /sys/power/state
> system goes to sleep
> press power to resume = fails
> 
> At this point I am stumped on how to debug. This is a "modern"
> computer with no serial ports. It worked under Lucid, so I know it is
> POSSIBLE.
> 
> Mobo: ASRock X58 single-socket
> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
> RAM: 12 GB ECC
> Disk: sda = Intel SSD, mounted on /
> Disk: sdb = Intel SSD, not mounted
> Disk: sdc = Seagate HDD, not mounted
> Disk: sdd = Seagate HDD, not mounted
> NIC = Onboard RTL8168e/8111e
> Sound = EMU1212 (emu10k1, not even configured yet)
> Video = nVidia GeForce 7600 GT
> KB = PS2 (also tried USB)
> Mouse = USB
> 
> I have not updated to a more current kernel than 3.5, but I will if
> there's evidence that this is resolved.  Any other clever trick to
> try?

There is no evidence and there won't be if you don't try a newer kernel.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH V3] Fix problem with cpufreq_ondemand or cpufreq_conservative
From: Rafael J. Wysocki @ 2012-12-29 21:54 UTC (permalink / raw)
  To: Larry Finger; +Cc: fabio.baltieri, viresh.kumar, linux-kernel, linux-pm
In-Reply-To: <50DF275D.1080702@lwfinger.net>

On Saturday, December 29, 2012 11:24:45 AM Larry Finger wrote:
> On 12/29/2012 07:27 AM, Rafael J. Wysocki wrote:
> > On Friday, December 28, 2012 07:55:20 PM Larry Finger wrote:
> >> Since commit 2aacdff entitled "cpufreq: Move common part from governors
> >> to separate file", whenever the drivers that depend on this new file
> >> (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new
> >> module named cpufreq_governor is created because the Makefile includes
> >> cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no
> >> MODULE directives, the resulting module has no license specified, which
> >> results in logging of a "module license 'unspecified' taints kernel". In
> >> addition, a number of globals are exported GPL only, and are therefore
> >> not available. This fix establishes a new boolean configuration variable
> >> that forces cpufreq_governor.o to be linked into the kernel whenever
> >> either cpufreq_ondemand or cpufreq_conservative is selected.
> >>
> >> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> >> ---
> >> V3 changes only Kconfig and Makefile and avoids creating a new module.
> >
> > OK, thanks for the patch!
> >
> > If you don't mind, I'll rename CONFIG_CPU_FREQ_GOVERNOR to
> > CONFIG_CPU_FREQ_GOV_COMMON when applying it, though.
> 
> The following does the job and is somewhat cleaner. If you want, I can remove 
> the line wrap and submit it as V4. The downside of this approach is that the 
> nested ifs will get cumbersome is more governors need cpufreq_governor.o.

I actually prefer the Kconfig-based one.  The extra config option is not
a problem to me.

Thanks,
Rafael


> Index: wireless-testing-new/drivers/cpufreq/Makefile
> ===================================================================
> --- wireless-testing-new.orig/drivers/cpufreq/Makefile
> +++ wireless-testing-new/drivers/cpufreq/Makefile
> @@ -7,8 +7,15 @@ obj-$(CONFIG_CPU_FREQ_STAT)
>   obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
>   obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)   += cpufreq_powersave.o
>   obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)   += cpufreq_userspace.o
> -obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)    += cpufreq_ondemand.o cpufreq_governor.o
> -obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)        += cpufreq_conservative.o 
> cpufreq_governor.o
> +obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)    += cpufreq_ondemand.o
> +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)        += cpufreq_conservative.o
> +ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND
> +  obj-y += cpufreq_governor.o
> +else
> +  ifdef CONFIG_CPU_FREQ_GOV_CONSERVATIVE
> +    obj-y += cpufreq_governor.o
> +  endif
> +endif
> 
>   # CPUfreq cross-arch helpers
>   obj-$(CONFIG_CPU_FREQ_TABLE)           += freq_table.o
> 
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Tim Hockin @ 2012-12-30  5:34 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <22263901.MJnoQmEgLn@vostro.rjw.lan>

Running a suspend with pm_trace set, I get:

aer 0000:00:03.0:pcie02: hash matches

I don't know what magic might be needed here, though.

I guess next step is to try to build a non-distro kernel.

On Sat, Dec 29, 2012 at 1:57 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
>> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
>> resume worked flawlessly every time.
>>
>> Then I upgraded to Ubuntu Precise.
>
> Well, do you use a distro kernel or a kernel.org kernel?
>
>> Suspend seems to work, but resume
>> fails every time. The video never initializes.  By the flashing
>> keyboard lights, I guess it's a kernel panic. It fails from the Live
>> CD and from a fresh install.
>>
>> Here is my debug so far.
>>
>> Install all updates (3.2 kernel, nouveau driver)
>> Reboot
>> Try suspend = fails
>>
>> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
>> Reboot
>> Try suspend = fails
>>
>> Install nVidia's 304 driver
>> Reboot
>> Try suspend = fails
>>
>> From within X:
>>   echo core > /sys/power/pm_test
>>   echo mem > /sys/power/state
>> The system acts like it is going to sleep, and then wakes up a few
>> seconds later. dmesg shows:
>>
>> [ 1230.083404] ------------[ cut here ]------------
>> [ 1230.083410] WARNING: at
>> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
>> suspend_test_finish+0x86/0x90()
>> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
>> [ 1230.083412] Component: resume devices, time: 14424
>> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
>> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
>> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
>> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
>> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
>> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
>> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
>> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
>> pata_marvell
>> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
>> #32~precise1-Ubuntu
>> [ 1230.083446] Call Trace:
>> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
>> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
>> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
>> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
>> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
>> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
>> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
>> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
>> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
>> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
>> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
>> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
>> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
>>
>> Boot with init=/bin/bash
>> unload all modules except USBHID
>> echo core > /sys/power/pm_test
>> echo mem > /sys/power/state
>> system acts like it is going to sleep, and then wakes up a few seconds later
>> echo none > /sys/power/pm_test
>> echo mem > /sys/power/state
>> system goes to sleep
>> press power to resume = fails
>>
>> At this point I am stumped on how to debug. This is a "modern"
>> computer with no serial ports. It worked under Lucid, so I know it is
>> POSSIBLE.
>>
>> Mobo: ASRock X58 single-socket
>> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
>> RAM: 12 GB ECC
>> Disk: sda = Intel SSD, mounted on /
>> Disk: sdb = Intel SSD, not mounted
>> Disk: sdc = Seagate HDD, not mounted
>> Disk: sdd = Seagate HDD, not mounted
>> NIC = Onboard RTL8168e/8111e
>> Sound = EMU1212 (emu10k1, not even configured yet)
>> Video = nVidia GeForce 7600 GT
>> KB = PS2 (also tried USB)
>> Mouse = USB
>>
>> I have not updated to a more current kernel than 3.5, but I will if
>> there's evidence that this is resolved.  Any other clever trick to
>> try?
>
> There is no evidence and there won't be if you don't try a newer kernel.
>
> Thanks,
> Rafael
>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH] ARM: EXYNOS5: Support Exynos5-bus devfreq driver
From: Olof Johansson @ 2012-12-30  6:15 UTC (permalink / raw)
  To: Abhilash Kesavan
  Cc: linux-kernel, linux-pm, kgene.kim, myungjoo.ham, kyungmin.park,
	rjw, jhbird.choi
In-Reply-To: <1356686649-15856-1-git-send-email-a.kesavan@samsung.com>

Hi,


Just a quick hit of review, I haven't done anything more in-depth yet.

On Fri, Dec 28, 2012 at 04:24:09AM -0500, Abhilash Kesavan wrote:
> - Setup the INT clock ops to control/vary INT frequency
> - Add PPMU support for Exynos5250
> - Add mappings initially for the PPMU device
> 
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> ---
> +config EXYNOS5250_PPMU
> +	bool "Exynos5250 PPMU Driver"
> +        depends on SOC_EXYNOS5250
> +        help
> +          This adds the Performance Profiling Monitoring Unit (PPMU) support
> +	  for Exynos5250. This code is used by the devfreq driver to read the
> +	  PPMU counters and vary the INT bus frequency/voltage.

Whitespace seems munged here.

> --- a/arch/arm/mach-exynos/Makefile
> +++ b/arch/arm/mach-exynos/Makefile
> @@ -74,3 +74,7 @@ obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)	+= setup-keypad.o
>  obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
>  obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)	+= setup-usb-phy.o
>  obj-$(CONFIG_EXYNOS_SETUP_SPI)		+= setup-spi.o
> +
> +# ppmu support
> +
> +obj-$(CONFIG_EXYNOS5250_PPMU)		+= exynos_ppmu.o exynos5_ppmu.o

Quite obvious that it's ppmu support from the file names. No need for
a comment.

> diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
> index 578a610..a285080 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -308,6 +308,31 @@ static struct map_desc exynos5_iodesc[] __initdata = {
>  		.pfn		= __phys_to_pfn(EXYNOS5_PA_UART),
>  		.length		= SZ_512K,
>  		.type		= MT_DEVICE,
> +	}, {
> +		.virtual        = (unsigned long)S5P_VA_PPMU_CPU,
> +		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_CPU),
> +		.length         = SZ_8K,
> +		.type		= MT_DEVICE,
> +	}, {
> +		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_C,
> +		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_C),
> +		.length         = SZ_8K,
> +		.type           = MT_DEVICE,
> +	}, {
> +		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_R1,
> +		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_R1),
> +		.length         = SZ_8K,
> +		.type           = MT_DEVICE,
> +	}, {
> +		.virtual        = (unsigned long)S5P_VA_PPMU_DDR_L,
> +		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_L),
> +		.length         = SZ_8K,
> +		.type           = MT_DEVICE,
> +	}, {
> +		.virtual        = (unsigned long)S5P_VA_PPMU_RIGHT,
> +		.pfn            = __phys_to_pfn(EXYNOS5_PA_PPMU_RIGHT),
> +		.length         = SZ_8K,
> +		.type           = MT_DEVICE,
>  	},

You should add the ppmu device to the device tree, and get the addresses from
there instead (via ioremap).

That way you can make this driver probe using regular methods too.

> --- /dev/null
> +++ b/arch/arm/mach-exynos/exynos5_ppmu.c
> @@ -0,0 +1,396 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com/
> + *
> + * EXYNOS5 PPMU support
> + * Support for only EXYNOS5250 is present.
> + *
> + * 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 <linux/kernel.h>
> +#include <linux/debugfs.h>
> +#include <linux/delay.h>
> +#include <linux/hrtimer.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#include <mach/map.h>
> +
> +#include <mach/exynos_ppmu.h>
> +#include <mach/exynos5_ppmu.h>

Can you avoid adding new mach includes for this, perhaps? We're working hard on
removing them for all platforms, even though exynos is lagging behind on it.
Local defines that are used in just one C file can either go in that file, or
in a header file that sits next to it instead of in the shared directory. For
the devfreq driver, include/linux/* is a better location.

> +#define FIXED_POINT_OFFSET 8
> +#define FIXED_POINT_MASK ((1 << FIXED_POINT_OFFSET) - 1)

0xff. Easier to read for a single entry like this.


> +enum exynos5_ppmu_list {
> +	PPMU_DDR_C,
> +	PPMU_DDR_R1,
> +	PPMU_DDR_L,
> +	PPMU_RIGHT,
> +	PPMU_CPU,
> +	PPMU_END,
> +};
> +
> +struct exynos5_ppmu_handle {
> +	struct list_head node;
> +	struct exynos_ppmu ppmu[PPMU_END];
> +};
> +
> +static DEFINE_SPINLOCK(exynos5_ppmu_lock);
> +static LIST_HEAD(exynos5_ppmu_handle_list);
> +static struct exynos5_ppmu_handle *exynos5_ppmu_trace_handle;
> +
> +static const char *exynos5_ppmu_name[PPMU_END] = {
> +	[PPMU_DDR_C]	= "DDR_C",
> +	[PPMU_DDR_R1]	= "DDR_R1",
> +	[PPMU_DDR_L]	= "DDR_L",
> +	[PPMU_RIGHT]	= "RIGHT",
> +	[PPMU_CPU]	= "CPU",
> +};
> +
> +static struct exynos_ppmu ppmu[PPMU_END] = {
> +	[PPMU_DDR_C] = {
> +		.hw_base = S5P_VA_PPMU_DDR_C,
> +	},
> +	[PPMU_DDR_R1] = {
> +		.hw_base = S5P_VA_PPMU_DDR_R1,
> +	},
> +	[PPMU_DDR_L] = {
> +		.hw_base = S5P_VA_PPMU_DDR_L,
> +	},
> +	[PPMU_RIGHT] = {
> +		.hw_base = S5P_VA_PPMU_RIGHT,
> +	},
> +	[PPMU_CPU] = {
> +		.hw_base = S5P_VA_PPMU_CPU,
> +	},
> +};
> +
> +static void exynos5_ppmu_reset(struct exynos_ppmu *ppmu)
> +{
> +	unsigned long flags;
> +
> +	void __iomem *ppmu_base = ppmu->hw_base;

No need for whitespace between these two declarations.

> +	/* Reset PPMU */
> +	exynos_ppmu_reset(ppmu_base);

Quite obvious from looking at the function call.

> +	/* Set PPMU Event */

Obvious. Comment on why you do things, not _what_ you are doing.

> +	ppmu->event[PPMU_PMNCNT0] = RD_DATA_COUNT;
> +	exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT0,
> +			ppmu->event[PPMU_PMNCNT0]);
> +	ppmu->event[PPMU_PMCCNT1] = WR_DATA_COUNT;
> +	exynos_ppmu_setevent(ppmu_base, PPMU_PMCCNT1,
> +			ppmu->event[PPMU_PMCCNT1]);
> +	ppmu->event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
> +	exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
> +			ppmu->event[PPMU_PMNCNT3]);
> +
> +	local_irq_save(flags);
> +	ppmu->reset_time = ktime_get();
> +	/* Start PPMU */
> +	exynos_ppmu_start(ppmu_base);

Again, quite obvious.

> +	local_irq_restore(flags);
> +}
> +
> +static void exynos5_ppmu_read(struct exynos_ppmu *ppmu)
> +{
> +	int j;
> +	unsigned long flags;
> +	ktime_t read_time;
> +	ktime_t t;
> +	u32 reg;
> +
> +	void __iomem *ppmu_base = ppmu->hw_base;

Again, no need for empty line. Also, all these base references will go away
once you switch over to a device/driver model.

> +	local_irq_save(flags);
> +	read_time = ktime_get();
> +	/* Stop PPMU */
> +	exynos_ppmu_stop(ppmu_base);
> +	local_irq_restore(flags);
> +
> +	/* Update local data from PPMU */
> +	ppmu->ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
> +	reg = __raw_readl(ppmu_base + PPMU_FLAG);
> +	ppmu->ccnt_overflow = reg & PPMU_CCNT_OVERFLOW;
> +
> +	for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
> +		if (ppmu->event[j] == 0)
> +			ppmu->count[j] = 0;
> +		else
> +			ppmu->count[j] = exynos_ppmu_read(ppmu_base, j);
> +	}
> +	t = ktime_sub(read_time, ppmu->reset_time);
> +	ppmu->ns = ktime_to_ns(t);
> +}

[...]

-Olof

^ permalink raw reply

* Re: [PATCH RFC] PM/Devfreq: Add Exynos5-bus devfreq driver for Exynos5250.
From: Olof Johansson @ 2012-12-30  6:18 UTC (permalink / raw)
  To: myungjoo.ham
  Cc: Abhilash Kesavan, kyungmin.park, rjw, linux-kernel, linux-pm,
	kgene.kim, jhbird.choi
In-Reply-To: <CAJ0PZbTTDdAXJ378R7CDO2=spx7WF_RpztG5ch7iFZWx-v3N2Q@mail.gmail.com>

Hi,

On Tue, Dec 11, 2012 at 10:20:51AM +0900, MyungJoo Ham wrote:
> On Fri, Nov 30, 2012 at 5:42 PM, Abhilash Kesavan <a.kesavan@samsung.com> wrote:
> >  drivers/devfreq/Kconfig        |   10 +
> >  drivers/devfreq/Makefile       |    1 +
> >  drivers/devfreq/exynos5_bus.c  |  595 ++++++++++++++++++++++++++++++++++++++++
> >  drivers/devfreq/exynos5_ppmu.c |  395 ++++++++++++++++++++++++++
> >  drivers/devfreq/exynos5_ppmu.h |   26 ++
> >  drivers/devfreq/exynos_ppmu.c  |   56 ++++
> >  drivers/devfreq/exynos_ppmu.h  |   79 ++++++
> >  7 files changed, 1162 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/devfreq/exynos5_bus.c
> >  create mode 100644 drivers/devfreq/exynos5_ppmu.c
> >  create mode 100644 drivers/devfreq/exynos5_ppmu.h
> >  create mode 100644 drivers/devfreq/exynos_ppmu.c
> >  create mode 100644 drivers/devfreq/exynos_ppmu.h
> 
> I understand that Exynos PPMU drivers seem not to be used (at least in
> mainline Linux) widely and it'd be convinent for a bus driver to have
> ppmu driver located in the same source directory.
> 
> However, I don't feel very comfortable to have ppmu drivers explicitly
> landing in devfreq directory. Would it be possible to place them
> somewhere else? (in drivers/misc, arch/arm/mach-exynos, or somewhere
> appropriate?) If PPMU drivers really have nowhere to relocate, they
> may be located along with its sole user (exynos5_bus.c) anyway.

Why can't they be in drivers/busfreq? Create a subdirectory for
platform-specific subdrivers if needed, but they definitiely do NOT
belong in drivers/misc, and there seems to be little reason to have them
in arch/arm.



-Olof

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Tim Hockin @ 2012-12-30  6:19 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <CAAAKZwsn8cYURZZ9dSAHqUzAFGXQBU_jNYBsX30rvAMZfZvdFw@mail.gmail.com>

Quick update: booting with 'noapic' on the commandline seems to make
it resume successfully.

The main dmesg diffs, other than the obvious "Skipping IOAPIC probe"
and IRG number diffs) are:

-nr_irqs_gsi: 40
+nr_irqs_gsi: 16

-NR_IRQS:16640 nr_irqs:776 16
+NR_IRQS:16640 nr_irqs:368 16

-system 00:0a: [mem 0xfec00000-0xfec00fff] could not be reserved
+system 00:0a: [mem 0xfec00000-0xfec00fff] has been reserved

and a new warning about irq 5: nobody cared (try booting with the
"irqpoll" option)

I'll see if I can sort out further differences, but I thought it was
worth sending this new info along, anyway.

It did not require 'noapic' on the Lucid (2.6.32?) kernel


On Sat, Dec 29, 2012 at 9:34 PM, Tim Hockin <thockin@hockin.org> wrote:
> Running a suspend with pm_trace set, I get:
>
> aer 0000:00:03.0:pcie02: hash matches
>
> I don't know what magic might be needed here, though.
>
> I guess next step is to try to build a non-distro kernel.
>
> On Sat, Dec 29, 2012 at 1:57 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
>>> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
>>> resume worked flawlessly every time.
>>>
>>> Then I upgraded to Ubuntu Precise.
>>
>> Well, do you use a distro kernel or a kernel.org kernel?
>>
>>> Suspend seems to work, but resume
>>> fails every time. The video never initializes.  By the flashing
>>> keyboard lights, I guess it's a kernel panic. It fails from the Live
>>> CD and from a fresh install.
>>>
>>> Here is my debug so far.
>>>
>>> Install all updates (3.2 kernel, nouveau driver)
>>> Reboot
>>> Try suspend = fails
>>>
>>> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
>>> Reboot
>>> Try suspend = fails
>>>
>>> Install nVidia's 304 driver
>>> Reboot
>>> Try suspend = fails
>>>
>>> From within X:
>>>   echo core > /sys/power/pm_test
>>>   echo mem > /sys/power/state
>>> The system acts like it is going to sleep, and then wakes up a few
>>> seconds later. dmesg shows:
>>>
>>> [ 1230.083404] ------------[ cut here ]------------
>>> [ 1230.083410] WARNING: at
>>> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
>>> suspend_test_finish+0x86/0x90()
>>> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
>>> [ 1230.083412] Component: resume devices, time: 14424
>>> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
>>> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
>>> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
>>> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
>>> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
>>> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
>>> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
>>> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
>>> pata_marvell
>>> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
>>> #32~precise1-Ubuntu
>>> [ 1230.083446] Call Trace:
>>> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
>>> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
>>> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
>>> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
>>> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
>>> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
>>> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
>>> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
>>> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
>>> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
>>> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
>>> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
>>> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
>>>
>>> Boot with init=/bin/bash
>>> unload all modules except USBHID
>>> echo core > /sys/power/pm_test
>>> echo mem > /sys/power/state
>>> system acts like it is going to sleep, and then wakes up a few seconds later
>>> echo none > /sys/power/pm_test
>>> echo mem > /sys/power/state
>>> system goes to sleep
>>> press power to resume = fails
>>>
>>> At this point I am stumped on how to debug. This is a "modern"
>>> computer with no serial ports. It worked under Lucid, so I know it is
>>> POSSIBLE.
>>>
>>> Mobo: ASRock X58 single-socket
>>> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
>>> RAM: 12 GB ECC
>>> Disk: sda = Intel SSD, mounted on /
>>> Disk: sdb = Intel SSD, not mounted
>>> Disk: sdc = Seagate HDD, not mounted
>>> Disk: sdd = Seagate HDD, not mounted
>>> NIC = Onboard RTL8168e/8111e
>>> Sound = EMU1212 (emu10k1, not even configured yet)
>>> Video = nVidia GeForce 7600 GT
>>> KB = PS2 (also tried USB)
>>> Mouse = USB
>>>
>>> I have not updated to a more current kernel than 3.5, but I will if
>>> there's evidence that this is resolved.  Any other clever trick to
>>> try?
>>
>> There is no evidence and there won't be if you don't try a newer kernel.
>>
>> Thanks,
>> Rafael
>>
>>
>> --
>> I speak only for myself.
>> Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Tim Hockin @ 2012-12-30  7:17 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <CAAAKZwuQ2-2fSg4oX-PxyJdnh_rkNiF14WtKojr3W3coqHs81A@mail.gmail.com>

Best guess:

With 'noapic', I see the "irq 5: nobody cared" message on resume,
along with 10000 IRQ5 counts in /proc/interrupts (the devices claiming
that IRQ are quiescent).

Without 'noapic' that must be triggering something else to go haywire,
perhaps the AER logic (though that is all MSI, so probably not).  I'm
flying blind on those boots.

I bet that, if I can recall how to re-enable IRQ5, I'll see it
continuously asserting.  Chipset or BIOS bug maybe.  I don't know if I
had AER enabled under Lucid, so that might be the difference.

I'll try a vanilla kernel next, maybe hack on AER a bit, to see if I
can make it progress.


On Sat, Dec 29, 2012 at 10:19 PM, Tim Hockin <thockin@hockin.org> wrote:
> Quick update: booting with 'noapic' on the commandline seems to make
> it resume successfully.
>
> The main dmesg diffs, other than the obvious "Skipping IOAPIC probe"
> and IRG number diffs) are:
>
> -nr_irqs_gsi: 40
> +nr_irqs_gsi: 16
>
> -NR_IRQS:16640 nr_irqs:776 16
> +NR_IRQS:16640 nr_irqs:368 16
>
> -system 00:0a: [mem 0xfec00000-0xfec00fff] could not be reserved
> +system 00:0a: [mem 0xfec00000-0xfec00fff] has been reserved
>
> and a new warning about irq 5: nobody cared (try booting with the
> "irqpoll" option)
>
> I'll see if I can sort out further differences, but I thought it was
> worth sending this new info along, anyway.
>
> It did not require 'noapic' on the Lucid (2.6.32?) kernel
>
>
> On Sat, Dec 29, 2012 at 9:34 PM, Tim Hockin <thockin@hockin.org> wrote:
>> Running a suspend with pm_trace set, I get:
>>
>> aer 0000:00:03.0:pcie02: hash matches
>>
>> I don't know what magic might be needed here, though.
>>
>> I guess next step is to try to build a non-distro kernel.
>>
>> On Sat, Dec 29, 2012 at 1:57 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>>> On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
>>>> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
>>>> resume worked flawlessly every time.
>>>>
>>>> Then I upgraded to Ubuntu Precise.
>>>
>>> Well, do you use a distro kernel or a kernel.org kernel?
>>>
>>>> Suspend seems to work, but resume
>>>> fails every time. The video never initializes.  By the flashing
>>>> keyboard lights, I guess it's a kernel panic. It fails from the Live
>>>> CD and from a fresh install.
>>>>
>>>> Here is my debug so far.
>>>>
>>>> Install all updates (3.2 kernel, nouveau driver)
>>>> Reboot
>>>> Try suspend = fails
>>>>
>>>> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
>>>> Reboot
>>>> Try suspend = fails
>>>>
>>>> Install nVidia's 304 driver
>>>> Reboot
>>>> Try suspend = fails
>>>>
>>>> From within X:
>>>>   echo core > /sys/power/pm_test
>>>>   echo mem > /sys/power/state
>>>> The system acts like it is going to sleep, and then wakes up a few
>>>> seconds later. dmesg shows:
>>>>
>>>> [ 1230.083404] ------------[ cut here ]------------
>>>> [ 1230.083410] WARNING: at
>>>> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
>>>> suspend_test_finish+0x86/0x90()
>>>> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
>>>> [ 1230.083412] Component: resume devices, time: 14424
>>>> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
>>>> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
>>>> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
>>>> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
>>>> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
>>>> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
>>>> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
>>>> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
>>>> pata_marvell
>>>> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
>>>> #32~precise1-Ubuntu
>>>> [ 1230.083446] Call Trace:
>>>> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
>>>> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
>>>> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
>>>> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
>>>> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
>>>> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
>>>> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
>>>> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
>>>> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
>>>> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
>>>> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
>>>> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
>>>> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
>>>>
>>>> Boot with init=/bin/bash
>>>> unload all modules except USBHID
>>>> echo core > /sys/power/pm_test
>>>> echo mem > /sys/power/state
>>>> system acts like it is going to sleep, and then wakes up a few seconds later
>>>> echo none > /sys/power/pm_test
>>>> echo mem > /sys/power/state
>>>> system goes to sleep
>>>> press power to resume = fails
>>>>
>>>> At this point I am stumped on how to debug. This is a "modern"
>>>> computer with no serial ports. It worked under Lucid, so I know it is
>>>> POSSIBLE.
>>>>
>>>> Mobo: ASRock X58 single-socket
>>>> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
>>>> RAM: 12 GB ECC
>>>> Disk: sda = Intel SSD, mounted on /
>>>> Disk: sdb = Intel SSD, not mounted
>>>> Disk: sdc = Seagate HDD, not mounted
>>>> Disk: sdd = Seagate HDD, not mounted
>>>> NIC = Onboard RTL8168e/8111e
>>>> Sound = EMU1212 (emu10k1, not even configured yet)
>>>> Video = nVidia GeForce 7600 GT
>>>> KB = PS2 (also tried USB)
>>>> Mouse = USB
>>>>
>>>> I have not updated to a more current kernel than 3.5, but I will if
>>>> there's evidence that this is resolved.  Any other clever trick to
>>>> try?
>>>
>>> There is no evidence and there won't be if you don't try a newer kernel.
>>>
>>> Thanks,
>>> Rafael
>>>
>>>
>>> --
>>> I speak only for myself.
>>> Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Rafael J. Wysocki @ 2012-12-30 22:55 UTC (permalink / raw)
  To: Tim Hockin; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <CAAAKZwt97VbscerxL+FqxWADVp++ysUFe5oJcgGb6TAHW+x=sA@mail.gmail.com>

On Saturday, December 29, 2012 11:17:11 PM Tim Hockin wrote:
> Best guess:
> 
> With 'noapic', I see the "irq 5: nobody cared" message on resume,
> along with 10000 IRQ5 counts in /proc/interrupts (the devices claiming
> that IRQ are quiescent).
> 
> Without 'noapic' that must be triggering something else to go haywire,
> perhaps the AER logic (though that is all MSI, so probably not).  I'm
> flying blind on those boots.
> 
> I bet that, if I can recall how to re-enable IRQ5, I'll see it
> continuously asserting.  Chipset or BIOS bug maybe.  I don't know if I
> had AER enabled under Lucid, so that might be the difference.
> 
> I'll try a vanilla kernel next, maybe hack on AER a bit, to see if I
> can make it progress.

I wonder what happens if you simply disable AER for starters?

There is the pci=noaer kernel command line switch for that.

Thanks,
Rafael


> On Sat, Dec 29, 2012 at 10:19 PM, Tim Hockin <thockin@hockin.org> wrote:
> > Quick update: booting with 'noapic' on the commandline seems to make
> > it resume successfully.
> >
> > The main dmesg diffs, other than the obvious "Skipping IOAPIC probe"
> > and IRG number diffs) are:
> >
> > -nr_irqs_gsi: 40
> > +nr_irqs_gsi: 16
> >
> > -NR_IRQS:16640 nr_irqs:776 16
> > +NR_IRQS:16640 nr_irqs:368 16
> >
> > -system 00:0a: [mem 0xfec00000-0xfec00fff] could not be reserved
> > +system 00:0a: [mem 0xfec00000-0xfec00fff] has been reserved
> >
> > and a new warning about irq 5: nobody cared (try booting with the
> > "irqpoll" option)
> >
> > I'll see if I can sort out further differences, but I thought it was
> > worth sending this new info along, anyway.
> >
> > It did not require 'noapic' on the Lucid (2.6.32?) kernel
> >
> >
> > On Sat, Dec 29, 2012 at 9:34 PM, Tim Hockin <thockin@hockin.org> wrote:
> >> Running a suspend with pm_trace set, I get:
> >>
> >> aer 0000:00:03.0:pcie02: hash matches
> >>
> >> I don't know what magic might be needed here, though.
> >>
> >> I guess next step is to try to build a non-distro kernel.
> >>
> >> On Sat, Dec 29, 2012 at 1:57 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >>> On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
> >>>> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
> >>>> resume worked flawlessly every time.
> >>>>
> >>>> Then I upgraded to Ubuntu Precise.
> >>>
> >>> Well, do you use a distro kernel or a kernel.org kernel?
> >>>
> >>>> Suspend seems to work, but resume
> >>>> fails every time. The video never initializes.  By the flashing
> >>>> keyboard lights, I guess it's a kernel panic. It fails from the Live
> >>>> CD and from a fresh install.
> >>>>
> >>>> Here is my debug so far.
> >>>>
> >>>> Install all updates (3.2 kernel, nouveau driver)
> >>>> Reboot
> >>>> Try suspend = fails
> >>>>
> >>>> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
> >>>> Reboot
> >>>> Try suspend = fails
> >>>>
> >>>> Install nVidia's 304 driver
> >>>> Reboot
> >>>> Try suspend = fails
> >>>>
> >>>> From within X:
> >>>>   echo core > /sys/power/pm_test
> >>>>   echo mem > /sys/power/state
> >>>> The system acts like it is going to sleep, and then wakes up a few
> >>>> seconds later. dmesg shows:
> >>>>
> >>>> [ 1230.083404] ------------[ cut here ]------------
> >>>> [ 1230.083410] WARNING: at
> >>>> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
> >>>> suspend_test_finish+0x86/0x90()
> >>>> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
> >>>> [ 1230.083412] Component: resume devices, time: 14424
> >>>> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
> >>>> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
> >>>> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
> >>>> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
> >>>> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
> >>>> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
> >>>> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
> >>>> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
> >>>> pata_marvell
> >>>> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
> >>>> #32~precise1-Ubuntu
> >>>> [ 1230.083446] Call Trace:
> >>>> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
> >>>> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
> >>>> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
> >>>> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
> >>>> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
> >>>> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
> >>>> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
> >>>> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
> >>>> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
> >>>> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
> >>>> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
> >>>> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
> >>>> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
> >>>>
> >>>> Boot with init=/bin/bash
> >>>> unload all modules except USBHID
> >>>> echo core > /sys/power/pm_test
> >>>> echo mem > /sys/power/state
> >>>> system acts like it is going to sleep, and then wakes up a few seconds later
> >>>> echo none > /sys/power/pm_test
> >>>> echo mem > /sys/power/state
> >>>> system goes to sleep
> >>>> press power to resume = fails
> >>>>
> >>>> At this point I am stumped on how to debug. This is a "modern"
> >>>> computer with no serial ports. It worked under Lucid, so I know it is
> >>>> POSSIBLE.
> >>>>
> >>>> Mobo: ASRock X58 single-socket
> >>>> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
> >>>> RAM: 12 GB ECC
> >>>> Disk: sda = Intel SSD, mounted on /
> >>>> Disk: sdb = Intel SSD, not mounted
> >>>> Disk: sdc = Seagate HDD, not mounted
> >>>> Disk: sdd = Seagate HDD, not mounted
> >>>> NIC = Onboard RTL8168e/8111e
> >>>> Sound = EMU1212 (emu10k1, not even configured yet)
> >>>> Video = nVidia GeForce 7600 GT
> >>>> KB = PS2 (also tried USB)
> >>>> Mouse = USB
> >>>>
> >>>> I have not updated to a more current kernel than 3.5, but I will if
> >>>> there's evidence that this is resolved.  Any other clever trick to
> >>>> try?
> >>>
> >>> There is no evidence and there won't be if you don't try a newer kernel.
> >>>
> >>> Thanks,
> >>> Rafael
> >>>
> >>>
> >>> --
> >>> I speak only for myself.
> >>> Rafael J. Wysocki, Intel Open Source Technology Center.
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: kernel panic on resume from S3 - stumped
From: Tim Hockin @ 2012-12-31  1:22 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-kernel, Pavel Machek, Linux PM list
In-Reply-To: <1407183.Lv2JEWpizy@vostro.rjw.lan>

On Sun, Dec 30, 2012 at 2:55 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday, December 29, 2012 11:17:11 PM Tim Hockin wrote:
>> Best guess:
>>
>> With 'noapic', I see the "irq 5: nobody cared" message on resume,
>> along with 10000 IRQ5 counts in /proc/interrupts (the devices claiming
>> that IRQ are quiescent).
>>
>> Without 'noapic' that must be triggering something else to go haywire,
>> perhaps the AER logic (though that is all MSI, so probably not).  I'm
>> flying blind on those boots.
>>
>> I bet that, if I can recall how to re-enable IRQ5, I'll see it
>> continuously asserting.  Chipset or BIOS bug maybe.  I don't know if I
>> had AER enabled under Lucid, so that might be the difference.
>>
>> I'll try a vanilla kernel next, maybe hack on AER a bit, to see if I
>> can make it progress.
>
> I wonder what happens if you simply disable AER for starters?
>
> There is the pci=noaer kernel command line switch for that.

That still panics on resume.  Damn.  I really think it is down to that
interrupt storm at resume.  Something somewhere is getting stuck
asserting, and we don't know how to EOI it.  PIC vs APIC is just
changing the operating mode.

Now the question is whether I am going to track through Intel errata
(more than I have already) and through chipset docs to figure out what
it could be, or just leave it at noapic.

I've already got one new PCI quirk to code up.

> Thanks,
> Rafael
>
>
>> On Sat, Dec 29, 2012 at 10:19 PM, Tim Hockin <thockin@hockin.org> wrote:
>> > Quick update: booting with 'noapic' on the commandline seems to make
>> > it resume successfully.
>> >
>> > The main dmesg diffs, other than the obvious "Skipping IOAPIC probe"
>> > and IRG number diffs) are:
>> >
>> > -nr_irqs_gsi: 40
>> > +nr_irqs_gsi: 16
>> >
>> > -NR_IRQS:16640 nr_irqs:776 16
>> > +NR_IRQS:16640 nr_irqs:368 16
>> >
>> > -system 00:0a: [mem 0xfec00000-0xfec00fff] could not be reserved
>> > +system 00:0a: [mem 0xfec00000-0xfec00fff] has been reserved
>> >
>> > and a new warning about irq 5: nobody cared (try booting with the
>> > "irqpoll" option)
>> >
>> > I'll see if I can sort out further differences, but I thought it was
>> > worth sending this new info along, anyway.
>> >
>> > It did not require 'noapic' on the Lucid (2.6.32?) kernel
>> >
>> >
>> > On Sat, Dec 29, 2012 at 9:34 PM, Tim Hockin <thockin@hockin.org> wrote:
>> >> Running a suspend with pm_trace set, I get:
>> >>
>> >> aer 0000:00:03.0:pcie02: hash matches
>> >>
>> >> I don't know what magic might be needed here, though.
>> >>
>> >> I guess next step is to try to build a non-distro kernel.
>> >>
>> >> On Sat, Dec 29, 2012 at 1:57 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> >>> On Saturday, December 29, 2012 12:03:13 PM Tim Hockin wrote:
>> >>>> 4 days ago I had Ubuntu Lucid running on this computer. Suspend and
>> >>>> resume worked flawlessly every time.
>> >>>>
>> >>>> Then I upgraded to Ubuntu Precise.
>> >>>
>> >>> Well, do you use a distro kernel or a kernel.org kernel?
>> >>>
>> >>>> Suspend seems to work, but resume
>> >>>> fails every time. The video never initializes.  By the flashing
>> >>>> keyboard lights, I guess it's a kernel panic. It fails from the Live
>> >>>> CD and from a fresh install.
>> >>>>
>> >>>> Here is my debug so far.
>> >>>>
>> >>>> Install all updates (3.2 kernel, nouveau driver)
>> >>>> Reboot
>> >>>> Try suspend = fails
>> >>>>
>> >>>> Install Ubuntu's linux-generic-lts-quantal (3.5 kernel, nouveau driver)
>> >>>> Reboot
>> >>>> Try suspend = fails
>> >>>>
>> >>>> Install nVidia's 304 driver
>> >>>> Reboot
>> >>>> Try suspend = fails
>> >>>>
>> >>>> From within X:
>> >>>>   echo core > /sys/power/pm_test
>> >>>>   echo mem > /sys/power/state
>> >>>> The system acts like it is going to sleep, and then wakes up a few
>> >>>> seconds later. dmesg shows:
>> >>>>
>> >>>> [ 1230.083404] ------------[ cut here ]------------
>> >>>> [ 1230.083410] WARNING: at
>> >>>> /build/buildd/linux-lts-quantal-3.5.0/kernel/power/suspend_test.c:53
>> >>>> suspend_test_finish+0x86/0x90()
>> >>>> [ 1230.083411] Hardware name: To Be Filled By O.E.M.
>> >>>> [ 1230.083412] Component: resume devices, time: 14424
>> >>>> [ 1230.083412] Modules linked in: snd_emu10k1_synth snd_emux_synth
>> >>>> snd_seq_virmidi snd_seq_midi_emul bnep rfcomm parport_pc ppdev
>> >>>> nvidia(PO) snd_emu10k1 snd_ac97_codec ac97_bus snd_pcm snd_page_alloc
>> >>>> snd_util_mem snd_hwdep snd_seq_midi snd_rawmidi snd_seq_midi_event
>> >>>> snd_seq snd_timer coretemp snd_seq_device kvm_intel kvm snd
>> >>>> ghash_clmulni_intel soundcore aesni_intel btusb cryptd aes_x86_64
>> >>>> bluetooth i7core_edac edac_core microcode mac_hid lpc_ich mxm_wmi
>> >>>> shpchp serio_raw wmi hid_generic lp parport usbhid hid r8169
>> >>>> pata_marvell
>> >>>> [ 1230.083445] Pid: 3329, comm: bash Tainted: P O 3.5.0-21-generic
>> >>>> #32~precise1-Ubuntu
>> >>>> [ 1230.083446] Call Trace:
>> >>>> [ 1230.083448] [<ffffffff81052c9f>] warn_slowpath_common+0x7f/0xc0
>> >>>> [ 1230.083452] [<ffffffff81052d96>] warn_slowpath_fmt+0x46/0x50
>> >>>> [ 1230.083455] [<ffffffff8109b836>] suspend_test_finish+0x86/0x90
>> >>>> [ 1230.083457] [<ffffffff8109b53b>] suspend_devices_and_enter+0x10b/0x200
>> >>>> [ 1230.083460] [<ffffffff8109b701>] enter_state+0xd1/0x100
>> >>>> [ 1230.083463] [<ffffffff8109b74b>] pm_suspend+0x1b/0x60
>> >>>> [ 1230.083465] [<ffffffff8109a7a5>] state_store+0x45/0x70
>> >>>> [ 1230.083467] [<ffffffff81331d2f>] kobj_attr_store+0xf/0x30
>> >>>> [ 1230.083471] [<ffffffff811f77ff>] sysfs_write_file+0xef/0x170
>> >>>> [ 1230.083476] [<ffffffff811879d3>] vfs_write+0xb3/0x180
>> >>>> [ 1230.083480] [<ffffffff81187cfa>] sys_write+0x4a/0x90
>> >>>> [ 1230.083483] [<ffffffff816a6e69>] system_call_fastpath+0x16/0x1b
>> >>>> [ 1230.083488] ---[ end trace 839cdd0078b3ce03 ]---
>> >>>>
>> >>>> Boot with init=/bin/bash
>> >>>> unload all modules except USBHID
>> >>>> echo core > /sys/power/pm_test
>> >>>> echo mem > /sys/power/state
>> >>>> system acts like it is going to sleep, and then wakes up a few seconds later
>> >>>> echo none > /sys/power/pm_test
>> >>>> echo mem > /sys/power/state
>> >>>> system goes to sleep
>> >>>> press power to resume = fails
>> >>>>
>> >>>> At this point I am stumped on how to debug. This is a "modern"
>> >>>> computer with no serial ports. It worked under Lucid, so I know it is
>> >>>> POSSIBLE.
>> >>>>
>> >>>> Mobo: ASRock X58 single-socket
>> >>>> CPU: Westmere 6 core (12 hyperthreads) 3.2 GHz
>> >>>> RAM: 12 GB ECC
>> >>>> Disk: sda = Intel SSD, mounted on /
>> >>>> Disk: sdb = Intel SSD, not mounted
>> >>>> Disk: sdc = Seagate HDD, not mounted
>> >>>> Disk: sdd = Seagate HDD, not mounted
>> >>>> NIC = Onboard RTL8168e/8111e
>> >>>> Sound = EMU1212 (emu10k1, not even configured yet)
>> >>>> Video = nVidia GeForce 7600 GT
>> >>>> KB = PS2 (also tried USB)
>> >>>> Mouse = USB
>> >>>>
>> >>>> I have not updated to a more current kernel than 3.5, but I will if
>> >>>> there's evidence that this is resolved.  Any other clever trick to
>> >>>> try?
>> >>>
>> >>> There is no evidence and there won't be if you don't try a newer kernel.
>> >>>
>> >>> Thanks,
>> >>> Rafael
>> >>>
>> >>>
>> >>> --
>> >>> I speak only for myself.
>> >>> Rafael J. Wysocki, Intel Open Source Technology Center.
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH RFC] PM/Devfreq: Add Exynos5-bus devfreq driver for Exynos5250.
From: Abhilash Kesavan @ 2012-12-31  2:11 UTC (permalink / raw)
  To: Olof Johansson
  Cc: myungjoo.ham, kyungmin.park, rjw, linux-kernel, linux-pm,
	kgene.kim, jhbird.choi
In-Reply-To: <20121230061843.GB21331@quad.lixom.net>

Hi,

[...]
> Why can't they be in drivers/busfreq? Create a subdirectory for
> platform-specific subdrivers if needed, but they definitiely do NOT
> belong in drivers/misc, and there seems to be little reason to have them
> in arch/arm.
Myungjoo, can you please indicate your preference with respect to where
I should place the PPMU driver. I'll re-work based on that.

Abhilash

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox