linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
@ 2015-12-14  6:38 Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver Chanwoo Choi
                   ` (21 more replies)
  0 siblings, 22 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch-set includes the two features as following. The generic exynos bus
frequency driver is able to support almost Exynos SoCs for bus frequency
scaling. And the new passive governor is able to make the dependency on
between devices for frequency/voltage scaling. I had posted the patch-set[2]
with the similiar concept. This is is revised version for exynos bus frequency.
- Generic exynos bus frequency driver
- New passive governor of DEVFREQ framework

Depend on:
- next-20151210 tag of linux-next (master branch).
- Merge the latest devfreq patches on devfreq.git[2] (for-rafael branch).
[1] https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/ (branch: for-rafael)
[2] https://lkml.org/lkml/2015/1/7/872
   : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver

Changes from v3:
(https://lkml.org/lkml/2015/12/11/75)
- Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17)
- Fix typo of the description on patch14
- Modify the subject and description of patch17
- Reorder the 'bus_xxx' device tree node alphabetically in 
  both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3

Changes from v2:
(https://lkml.org/lkml/2015/12/8/869)
- Fix typo on documentation
- Modify the more appropriate sentence on patch description
- Add the detailed description about both parent and passive bus device
- Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz)
- Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> 825mV)
- Rename OPP nodes as 'opp@<opp-hz>'
- Delete the duplicate 'opp-microvolt' property of passive devfreq device
- Reorder the 'bus_xxx' device tree node alphabetically in exynos3250-rinato/monk.dts
- Reorder the 'bus_xxx' device tree node alphabetically in exynos4412-trats/odroidu3
- Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node
  on rinato/monk/trats2/odroid-u3 board
- Add the log message if bus device is registered to devfreq framework successfully
- Add the reviewed-by tag from Krzysztof Kozlowski
- Add the tested-by tag from Anand Moon on Odroid U3
- Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS

Changes from v1:
(https://lkml.org/lkml/2015/11/26/260)
- Check whether the instance of regulator is NULL or not
  when executing regulator_disable() because of only parent
  devfreq device has the regulator instance. After fixing it,
  the wake-up from suspend state is well working. (patch1)
- Fix bug which checks 'bus-clk' instead of 'bus->regulator'
  after calling devm_clk_get() (on patch1)
- Update the documentation to remove the description about
  DEVFREQ-EVENT subsystem (on patch2)
- Add the full name of DMC (Dynamic Memory Controller) (on patch2)
- Modify the detailed correlation of buses for Exynos3250
  on documentation (patch2)
- Add the MFC bus node for Exynos3250 (on patch11, patch12)
- Fix the duplicate frequency of bus_display on Exynos4x12.dtsi
- Add the PPMU node for exynos4412-odroidu3
- Add the support of bus frequency for exynos4412-odroidu3

Detailed descirption for patch-set:
1. Add generic exynos bus frequency driver
: This patch-set adds the generic exynos bus frequency driver for AXI bus
of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common
architecture for bus between DRAM and sub-blocks in SoC.

 There are the different buses according to Exynos SoC because Exynos SoC
has the differnt sub-blocks and bus speed. In spite of this difference
among Exynos SoCs, this driver is able to support almost Exynos SoC by adding
unique data of each bus in the devicetree file.

 In devicetree, each bus node has a bus clock, regulator, operation-point
and devfreq-event devices which measure the utilization of each bus block.

For example,
- The bus of DMC block in exynos3250.dtsi are listed below:

	bus_dmc: bus_dmc {
		compatible = "samsung,exynos-bus";
		clocks = <&cmu_dmc CLK_DIV_DMC>;
		clock-names = "bus";
		operating-points-v2 = <&bus_dmc_opp_table>;
		status = "disabled";
	};

	bus_dmc_opp_table: opp_table1 {
		compatible = "operating-points-v2";
		opp-shared;

		opp@50000000 {
			opp-hz = /bits/ 64 <50000000>;
			opp-microvolt = <800000>;
		};
		opp@100000000 {
			opp-hz = /bits/ 64 <100000000>;
			opp-microvolt = <800000>;
		};
		opp@134000000 {
			opp-hz = /bits/ 64 <134000000>;
			opp-microvolt = <800000>;
		};
		opp@200000000 {
			opp-hz = /bits/ 64 <200000000>;
			opp-microvolt = <825000>;
		};
		opp@400000000 {
			opp-hz = /bits/ 64 <400000000>;
			opp-microvolt = <875000>;
		};
	};

- Usage case to handle the frequency and voltage of bus on runtime
  in exynos3250-rinato.dts are listed below:

	&bus_dmc {
		devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
		vdd-supply = <&buck1_reg>;	/* VDD_MIF */
		status = "okay";
	};

2. Add new passive governor of DEVFREQ framework (patch5-patch7)
: This patch-set add the new passive governor for DEVFREQ framework.
The existing governors (ondemand, performance and so on) are used for DVFS
(Dynamic Voltage and Frequency Scaling) drivers. The existing governors
are independently used for specific device driver which don't give the
influence to other device drviers and also don't receive the effect from
other device drivers.

 The passive governor depends on operation of parent driver with existing
governors(ondemand, performance and so on) extremely and is not able to
decide the new frequency by oneself. According to the decided new frequency
of parent driver with governor, the passive governor uses it to decide
the appropriate frequency for own device driver. The passive governor
must need the following information from device tree:

For exameple,
 There are one more bus device drivers in Exynos3250 which need to
change their source clock according to their utilization on runtime.
But, they share the same power line (e.g., regulator). So, LEFTBUS bus
driver is operated as parent with ondemand governor and then the rest
device driver with passive governor.

 The buses of Internal block in exynos3250.dtsi are listed below:
When LEFTBUS bus driver (parent) changes the bus frequency with
ondemand governor on runtime, the rest bus devices which sharing
the same power line (VDD_INT) will change the each bus frequency
according to the decision of LEFTBUS bus driver (parent).

- INT (Internal) block
	: VDD_INT |--- LEFTBUS
		  |--- PERIL
		  |--- MFC
		  |--- G3D
		  |--- RIGHTBUS
		  |--- FSYS
		  |--- LCD0
		  |--- PERIR
		  |--- ISP
		  |--- CAM

- The buss of INT block in exynos3250.dtsi are listed below:
	bus_leftbus: bus_leftbus {
		compatible = "samsung,exynos-bus";
		clocks = <&cmu CLK_DIV_GDL>;
		clock-names = "bus";
		operating-points-v2 = <&bus_leftbus_opp_table>;
		status = "disabled";
	};

	bus_rightbus: bus_rightbus {
		compatible = "samsung,exynos-bus";
		clocks = <&cmu CLK_DIV_GDR>;
		clock-names = "bus";
		operating-points-v2 = <&bus_leftbus_opp_table>;
		status = "disabled";
	};

	(Omit the rest bus dt node)

- Usage case to handle the frequency and voltage of bus on runtime
  in exynos3250-rinato.dts are listed below:
	/* Parent bus device of VDD_INT */
	&bus_leftbus {
		devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
		vdd-supply = <&buck3_reg>;
		status = "okay";
	};

	/* Passive bus device depend on LEFTBUS bus. */
	&bus_rightbus {
		devfreq = <&bus_leftbus>; /* 'devfreq' property indicates
					     the phandle of parent device. */
		status = "okay";
	};

	(Omit the rest bus dt node)

Chanwoo Choi (20):
  PM / devfreq: exynos: Add generic exynos bus frequency driver
  PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
  ARM: dts: Add DMC bus node for Exynos3250
  ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
  PM / devfreq: Add new passive governor
  PM / devfreq: Add devfreq_get_devfreq_by_phandle()
  PM / devfreq: Show the related information according to governor type
  PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
  PM / devfreq: exynos: Update documentation for bus devices using passive governor
  PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
  PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
  MAINTAINERS: Add samsung bus frequency driver entry
  ARM: dts: Add bus nodes using VDD_INT for Exynos3250
  ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
  ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
  ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
  ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
  ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
  ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
  ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3

 .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++
 MAINTAINERS                                        |    9 +
 arch/arm/boot/dts/exynos3250-monk.dts              |   47 +-
 arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +-
 arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++
 arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +-
 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 +
 arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +-
 arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++
 drivers/devfreq/Kconfig                            |   37 +-
 drivers/devfreq/Makefile                           |    2 +
 drivers/devfreq/devfreq.c                          |  120 ++-
 drivers/devfreq/exynos/Makefile                    |    3 +-
 drivers/devfreq/exynos/exynos-bus.c                |  556 +++++++++++
 drivers/devfreq/exynos/exynos4_bus.c               | 1055 --------------------
 drivers/devfreq/exynos/exynos4_bus.h               |  110 --
 drivers/devfreq/exynos/exynos5_bus.c               |  431 --------
 drivers/devfreq/exynos/exynos_ppmu.c               |  119 ---
 drivers/devfreq/exynos/exynos_ppmu.h               |   86 --
 drivers/devfreq/governor.h                         |    7 +
 drivers/devfreq/governor_passive.c                 |  109 ++
 drivers/devfreq/governor_performance.c             |    1 +
 drivers/devfreq/governor_powersave.c               |    1 +
 drivers/devfreq/governor_simpleondemand.c          |    1 +
 drivers/devfreq/governor_userspace.c               |    1 +
 include/linux/devfreq.h                            |   26 +
 27 files changed, 1955 insertions(+), 1948 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt
 create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi
 create mode 100644 drivers/devfreq/exynos/exynos-bus.c
 delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c
 delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h
 delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c
 delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c
 delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h
 create mode 100644 drivers/devfreq/governor_passive.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-15  3:41   ` Krzysztof Kozlowski
  2015-12-14  6:38 ` [PATCH v4 02/20] PM / devfreq: exynos: Add documentation for " Chanwoo Choi
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the generic exynos bus frequency driver for AMBA AXI bus
of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
have the common architecture for bus between DRAM and sub-blocks in SoC.
This driver can support the generic bus frequency driver for Exynos SoCs.

In devicetree, Each bus block has a bus clock, regulator, operation-point
and devfreq-event devices which measure the utilization of each bus block.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/devfreq/Kconfig             |  15 ++
 drivers/devfreq/Makefile            |   1 +
 drivers/devfreq/exynos/Makefile     |   1 +
 drivers/devfreq/exynos/exynos-bus.c | 449 ++++++++++++++++++++++++++++++++++++
 4 files changed, 466 insertions(+)
 create mode 100644 drivers/devfreq/exynos/exynos-bus.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 64281bb2f650..55ec774f794c 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE
 
 comment "DEVFREQ Drivers"
 
+config ARM_EXYNOS_BUS_DEVFREQ
+	bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver"
+	depends on ARCH_EXYNOS
+	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select DEVFREQ_EVENT_EXYNOS_PPMU
+	select PM_DEVFREQ_EVENT
+	select PM_OPP
+	help
+	  This adds the common DEVFREQ driver for Exynos Memory bus. Exynos
+	  Memory bus has one more group of memory bus (e.g, MIF and INT block).
+	  Each memory bus group could contain many memoby bus block. It reads
+	  PPMU counters of memory controllers by using DEVFREQ-event device
+	  and adjusts the operating frequencies and voltages with OPP support.
+	  This does not yet operate with optimal voltages.
+
 config ARM_EXYNOS4_BUS_DEVFREQ
 	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
 	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 5134f9ee983d..375ebbb4fcfb 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
 obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 
 # DEVFREQ Drivers
+obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
 obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
 obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/
 obj-$(CONFIG_ARM_TEGRA_DEVFREQ)		+= tegra-devfreq.o
diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile
index 49bc9175f923..4ec06d322996 100644
--- a/drivers/devfreq/exynos/Makefile
+++ b/drivers/devfreq/exynos/Makefile
@@ -1,3 +1,4 @@
 # Exynos DEVFREQ Drivers
+obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
 obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos_ppmu.o exynos4_bus.o
 obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos_ppmu.o exynos5_bus.o
diff --git a/drivers/devfreq/exynos/exynos-bus.c b/drivers/devfreq/exynos/exynos-bus.c
new file mode 100644
index 000000000000..f1bc20839650
--- /dev/null
+++ b/drivers/devfreq/exynos/exynos-bus.c
@@ -0,0 +1,449 @@
+/*
+ * Generic Exynos Bus frequency driver with DEVFREQ Framework
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author : Chanwoo Choi <cw00.choi@samsung.com>
+ *
+ * This driver support Exynos Bus frequency feature by using
+ * DEVFREQ framework and is based on drivers/devfreq/exynos/exynos4_bus.c.
+ *
+ * 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/clk.h>
+#include <linux/devfreq.h>
+#include <linux/devfreq-event.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_opp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#define DEFAULT_SATURATION_RATIO	40
+
+struct exynos_bus {
+	struct device *dev;
+
+	struct devfreq *devfreq;
+	struct devfreq_event_dev **edev;
+	unsigned int edev_count;
+	struct mutex lock;
+
+	struct dev_pm_opp *curr_opp;
+
+	struct regulator *regulator;
+	struct clk *clk;
+	int ratio;
+};
+
+/*
+ * Control the devfreq-event device to get the current state of bus
+ */
+#define exynos_bus_ops_edev(ops)				\
+static int exynos_bus_##ops(struct exynos_bus *bus)		\
+{								\
+	int i, ret;						\
+								\
+	for (i = 0; i < bus->edev_count; i++) {			\
+		if (!bus->edev[i])				\
+			continue;				\
+		ret = devfreq_event_##ops(bus->edev[i]);	\
+		if (ret < 0)					\
+			return ret;				\
+	}							\
+								\
+	return 0;						\
+}
+exynos_bus_ops_edev(enable_edev);
+exynos_bus_ops_edev(disable_edev);
+exynos_bus_ops_edev(set_event);
+
+static int exynos_bus_get_event(struct exynos_bus *bus,
+				struct devfreq_event_data *edata)
+{
+	struct devfreq_event_data event_data;
+	unsigned long load_count = 0, total_count = 0;
+	int i, ret = 0;
+
+	for (i = 0; i < bus->edev_count; i++) {
+		if (!bus->edev[i])
+			continue;
+
+		ret = devfreq_event_get_event(bus->edev[i], &event_data);
+		if (ret < 0)
+			return ret;
+
+		if (i == 0 || event_data.load_count > load_count) {
+			load_count = event_data.load_count;
+			total_count = event_data.total_count;
+		}
+	}
+
+	edata->load_count = load_count;
+	edata->total_count = total_count;
+
+	return ret;
+}
+
+/*
+ * Must necessary function for devfreq governor
+ */
+static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
+{
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	struct dev_pm_opp *new_opp;
+	unsigned long old_freq, new_freq, old_volt, new_volt;
+	int ret = 0;
+
+	/* Get new opp-bus instance according to new bus clock */
+	rcu_read_lock();
+	new_opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR_OR_NULL(new_opp)) {
+		dev_err(dev, "failed to get recommed opp instance\n");
+		rcu_read_unlock();
+		return PTR_ERR(new_opp);
+	}
+
+	new_freq = dev_pm_opp_get_freq(new_opp);
+	new_volt = dev_pm_opp_get_voltage(new_opp);
+	old_freq = dev_pm_opp_get_freq(bus->curr_opp);
+	old_volt = dev_pm_opp_get_voltage(bus->curr_opp);
+	rcu_read_unlock();
+
+	if (old_freq == new_freq)
+		return 0;
+
+	/* Change voltage and frequency according to new OPP level */
+	mutex_lock(&bus->lock);
+
+	if (old_freq < new_freq) {
+		ret = regulator_set_voltage(bus->regulator, new_volt, new_volt);
+		if (ret < 0) {
+			dev_err(bus->dev, "failed to set voltage\n");
+			regulator_set_voltage(bus->regulator, old_volt,
+						old_volt);
+			goto out;
+		}
+	}
+
+	ret = clk_set_rate(bus->clk, new_freq);
+	if (ret < 0) {
+		dev_err(dev, "failed to change clock of bus\n");
+		clk_set_rate(bus->clk, old_freq);
+		goto out;
+	}
+
+	if (old_freq > new_freq) {
+		ret = regulator_set_voltage(bus->regulator, new_volt, new_volt);
+		if (ret < 0) {
+			dev_err(bus->dev, "failed to set voltage\n");
+			regulator_set_voltage(bus->regulator, old_volt,
+						old_volt);
+			goto out;
+		}
+	}
+	bus->curr_opp = new_opp;
+
+	dev_dbg(dev, "Set the frequency of bus (%ldkHz -> %ldkHz)\n",
+			old_freq/1000, new_freq/1000);
+out:
+	mutex_unlock(&bus->lock);
+
+	return ret;
+}
+
+static int exynos_bus_get_dev_status(struct device *dev,
+				     struct devfreq_dev_status *stat)
+{
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	struct devfreq_event_data edata;
+	int ret;
+
+	rcu_read_lock();
+	stat->current_frequency = dev_pm_opp_get_freq(bus->curr_opp);
+	rcu_read_unlock();
+
+	ret = exynos_bus_get_event(bus, &edata);
+	if (ret < 0) {
+		stat->total_time = stat->busy_time = 0;
+		goto err;
+	}
+
+	stat->busy_time = (edata.load_count * 100) / bus->ratio;
+	stat->total_time = edata.total_count;
+
+	dev_dbg(dev, "Usage of devfreq-event : %ld/%ld\n", stat->busy_time,
+							stat->total_time);
+
+err:
+	ret = exynos_bus_set_event(bus);
+	if (ret < 0) {
+		dev_err(dev, "failed to set event to devfreq-event devices\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static void exynos_bus_exit(struct device *dev)
+{
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	int ret;
+
+	ret = exynos_bus_disable_edev(bus);
+	if (ret < 0)
+		dev_warn(dev, "failed to disable the devfreq-event devices\n");
+
+	if (bus->regulator)
+		regulator_disable(bus->regulator);
+
+	dev_pm_opp_of_remove_table(dev);
+}
+
+static int exynos_bus_parse_of(struct device_node *np,
+			      struct exynos_bus *bus)
+{
+	struct device *dev = bus->dev;
+	unsigned long rate;
+	int i, ret, count, size;
+
+	/* Get the clock to provide each bus with source clock */
+	bus->clk = devm_clk_get(dev, "bus");
+	if (IS_ERR(bus->clk)) {
+		dev_err(dev, "failed to get bus clock\n");
+		return PTR_ERR(bus->clk);
+	}
+
+	ret = clk_prepare_enable(bus->clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get enable clock\n");
+		return ret;
+	}
+
+	/* Get the freq/voltage OPP table to scale the bus frequency */
+	rcu_read_lock();
+	ret = dev_pm_opp_of_add_table(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to get OPP table\n");
+		rcu_read_unlock();
+		return ret;
+	}
+
+	rate = clk_get_rate(bus->clk);
+	bus->curr_opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+	if (IS_ERR(bus->curr_opp)) {
+		dev_err(dev, "failed to find dev_pm_opp\n");
+		rcu_read_unlock();
+		ret = PTR_ERR(bus->curr_opp);
+		goto err_opp;
+	}
+	rcu_read_unlock();
+
+	/* Get the regulator to provide each bus with the power */
+	bus->regulator = devm_regulator_get(dev, "vdd");
+	if (IS_ERR(bus->regulator)) {
+		dev_err(dev, "failed to get VDD regulator\n");
+		ret = PTR_ERR(bus->regulator);
+		goto err_opp;
+	}
+
+	ret = regulator_enable(bus->regulator);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable VDD regulator\n");
+		goto err_opp;
+	}
+
+	/*
+	 * Get the devfreq-event devices to get the current utilization of
+	 * buses. This raw data will be used in devfreq ondemand governor.
+	 */
+	count = devfreq_event_get_edev_count(dev);
+	if (count < 0) {
+		dev_err(dev, "failed to get the count of devfreq-event dev\n");
+		ret = count;
+		goto err_regulator;
+	}
+	bus->edev_count = count;
+
+	size = sizeof(*bus->edev) * count;
+	bus->edev = devm_kzalloc(dev, size, GFP_KERNEL);
+	if (!bus->edev) {
+		ret = -ENOMEM;
+		goto err_regulator;
+	}
+
+	for (i = 0; i < count; i++) {
+		bus->edev[i] = devfreq_event_get_edev_by_phandle(dev, i);
+		if (IS_ERR(bus->edev[i])) {
+			ret = -EPROBE_DEFER;
+			goto err_regulator;
+		}
+	}
+
+	/*
+	 * Optionally, Get the saturation ratio according to Exynos SoC
+	 * When measuring the utilization of each AXI bus with devfreq-event
+	 * devices, the measured real cycle might be much lower than the
+	 * total cycle of bus during sampling rate. In result, the devfreq
+	 * simple-ondemand governor might not decide to change the current
+	 * frequency due to too utilization (= real cycle/total cycle).
+	 * So, this property is used to adjust the utilization when calculating
+	 * the busy_time in exynos_bus_get_dev_status().
+	 */
+	if (of_property_read_u32(np, "exynos,saturation-ratio", &bus->ratio))
+		bus->ratio = DEFAULT_SATURATION_RATIO;
+
+	return 0;
+
+err_regulator:
+	regulator_disable(bus->regulator);
+err_opp:
+	dev_pm_opp_of_remove_table(dev);
+
+	return ret;
+}
+
+static int exynos_bus_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct devfreq_dev_profile *profile;
+	struct devfreq_simple_ondemand_data *ondemand_data;
+	struct exynos_bus *bus;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "failed to find devicetree node\n");
+		return -EINVAL;
+	}
+
+	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return -ENOMEM;
+	mutex_init(&bus->lock);
+	bus->dev = &pdev->dev;
+	platform_set_drvdata(pdev, bus);
+
+	/* Parse the device-tree to get the resource information */
+	ret = exynos_bus_parse_of(np, bus);
+	if (ret < 0)
+		return ret;
+
+	/* Initalize the struct profile and governor data */
+	profile = devm_kzalloc(dev, sizeof(*profile), GFP_KERNEL);
+	if (!profile)
+		return -ENOMEM;
+	profile->polling_ms = 50;
+	profile->target = exynos_bus_target;
+	profile->get_dev_status = exynos_bus_get_dev_status;
+	profile->exit = exynos_bus_exit;
+
+	ondemand_data = devm_kzalloc(dev, sizeof(*ondemand_data), GFP_KERNEL);
+	if (!ondemand_data)
+		return -ENOMEM;
+	ondemand_data->upthreshold = 40;
+	ondemand_data->downdifferential = 5;
+
+	/* Add devfreq device to monitor and handle the exynos bus */
+	bus->devfreq = devm_devfreq_add_device(dev, profile, "simple_ondemand",
+						ondemand_data);
+	if (IS_ERR_OR_NULL(bus->devfreq)) {
+		dev_err(dev, "failed to add devfreq device\n");
+		return  PTR_ERR(bus->devfreq);
+	}
+
+	/* Register opp_notifier to catch the change of OPP  */
+	ret = devm_devfreq_register_opp_notifier(dev, bus->devfreq);
+	if (ret < 0) {
+		dev_err(dev, "failed to register opp notifier\n");
+		return ret;
+	}
+
+	/*
+	 * Enable devfreq-event to get raw data which is used to determine
+	 * current bus load.
+	 */
+	ret = exynos_bus_enable_edev(bus);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable devfreq-event devices\n");
+		return ret;
+	}
+
+	ret = exynos_bus_set_event(bus);
+	if (ret < 0) {
+		dev_err(dev, "failed to set event to devfreq-event devices\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_bus_resume(struct device *dev)
+{
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	int ret;
+
+	if (bus->regulator) {
+		ret = regulator_enable(bus->regulator);
+		if (ret < 0) {
+			dev_err(dev, "failed to enable VDD regulator\n");
+			return ret;
+		}
+	}
+
+	ret = exynos_bus_enable_edev(bus);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable the devfreq-event devices\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int exynos_bus_suspend(struct device *dev)
+{
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	int ret;
+
+	ret = exynos_bus_disable_edev(bus);
+	if (ret < 0) {
+		dev_err(dev, "failed to disable the devfreq-event devices\n");
+		return ret;
+	}
+
+	if (bus->regulator)
+		regulator_disable(bus->regulator);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops exynos_bus_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(exynos_bus_suspend, exynos_bus_resume)
+};
+
+static const struct of_device_id exynos_bus_of_match[] = {
+	{ .compatible = "samsung,exynos-bus", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, exynos_bus_of_match);
+
+static struct platform_driver exynos_bus_platdrv = {
+	.probe		= exynos_bus_probe,
+	.driver = {
+		.name	= "exynos-bus",
+		.pm	= &exynos_bus_pm,
+		.of_match_table = of_match_ptr(exynos_bus_of_match),
+	},
+};
+module_platform_driver(exynos_bus_platdrv);
+
+MODULE_DESCRIPTION("Generic Exynos Bus frequency driver");
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 02/20] PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 03/20] ARM: dts: Add DMC bus node for Exynos3250 Chanwoo Choi
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the documentation for generic exynos bus frequency
driver.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 .../devicetree/bindings/devfreq/exynos-bus.txt     | 93 ++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt

diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
new file mode 100644
index 000000000000..e32daef328da
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -0,0 +1,93 @@
+* Generic Exynos Bus frequency device
+
+The Samsung Exynos SoC have many buses for data transfer between DRAM
+and sub-blocks in SoC. Almost Exynos SoC have the common architecture
+for buses. Generally, the each bus of Exynos SoC includes the source clock
+and power line and then is able to change the clock according to the usage
+of each buses on runtime. When gathering the usage of each buses on runtime,
+the driver uses the PPMU (Platform Performance Monitoring Unit) which
+is able to measure the current load of sub-blocks.
+
+There are a little different composition among Exynos SoC because each Exynos
+SoC has the different sub-blocks. So, this difference should be specified
+in devicetree file instead of each device driver. In result, this driver
+is able to support the bus frequency for all Exynos SoCs.
+
+Required properties for bus device:
+- compatible: Should be "samsung,exynos-bus".
+- clock-names : the name of clock used by the bus, "bus".
+- clocks : phandles for clock specified in "clock-names" property.
+- operating-points-v2: the OPP table including frequency/voltage information
+  to support DVFS (Dynamic Voltage/Frequency Scaling) feature.
+- vdd-supply: the regulator to provide the buses with the voltage.
+- devfreq-events: the devfreq-event device to monitor the current utilization
+  of buses.
+
+Optional properties for bus device:
+- exynos,saturation-ratio: the percentage value which is used to calibrate
+                   the performance count against total cycle count.
+
+Example1:
+	Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to
+	power line (regulator). The MIF (Memory Interface) AXI bus is used to
+	transfer data between DRAM and CPU and uses the VDD_MIF regualtor.
+
+	- power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block
+
+	- MIF bus's frequency/voltage table
+	-----------------------
+	|Lv| Freq   | Voltage |
+	-----------------------
+	|L1| 50000  |800000   |
+	|L2| 100000 |800000   |
+	|L3| 134000 |800000   |
+	|L4| 200000 |825000   |
+	|L5| 400000 |875000   |
+	-----------------------
+
+Example2 :
+	The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi
+	is listed below:
+
+	bus_dmc: bus_dmc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu_dmc CLK_DIV_DMC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_dmc_opp_table>;
+		status = "disabled";
+	};
+
+	bus_dmc_opp_table: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+			opp-microvolt = <800000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <800000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+			opp-microvolt = <800000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <825000>;
+		};
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <875000>;
+		};
+	};
+
+	Usage case to handle the frequency and voltage of bus on runtime
+	in exynos3250-rinato.dts is listed below:
+
+	&bus_dmc {
+		devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+		vdd-supply = <&buck1_reg>;	/* VDD_MIF */
+		status = "okay";
+	};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 03/20] ARM: dts: Add DMC bus node for Exynos3250
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 02/20] PM / devfreq: exynos: Add documentation for " Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 04/20] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk Chanwoo Choi
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the DMC (Dynamic Memory Controller) bus node for Exynos3250 SoC.
The DMC is an AMBA AXI-compliant slave to interface external JEDEC standard
SDRAM devices. The bus includes the OPP tables and the source clock for DMC
block.

Following list specifies the detailed relation between the clock and DMC block:
- The source clock of DMC block : div_dmc

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250.dtsi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 18e3deffbf48..262b3b1995fd 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -701,6 +701,40 @@
 			clock-names = "ppmu";
 			status = "disabled";
 		};
+
+		bus_dmc: bus_dmc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu_dmc CLK_DIV_DMC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_dmc_opp_table>;
+			status = "disabled";
+		};
+
+		bus_dmc_opp_table: opp_table1 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp@50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+				opp-microvolt = <800000>;
+			};
+			opp@100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				opp-microvolt = <800000>;
+			};
+			opp@134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+				opp-microvolt = <800000>;
+			};
+			opp@200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				opp-microvolt = <825000>;
+			};
+			opp@400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				opp-microvolt = <875000>;
+			};
+		};
 	};
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 04/20] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (2 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 03/20] ARM: dts: Add DMC bus node for Exynos3250 Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 05/20] PM / devfreq: Add new passive governor Chanwoo Choi
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the DMC (Dynamic Memory Controller) bus frequency node
which includes the devfreq-events and regulator properties. The bus
frequency support the DVFS (Dynamic Voltage Frequency Scaling) feature
with ondemand governor.

The devfreq-events (ppmu_dmc0*) can monitor the utilization of DMC bus
on runtime and the buck1_reg (VDD_MIF power line) supplies the power to
the DMC block.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250-monk.dts   | 6 ++++++
 arch/arm/boot/dts/exynos3250-rinato.dts | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 443a35085846..456844a81189 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -156,6 +156,12 @@
 	};
 };
 
+&bus_dmc {
+	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+	vdd-supply = <&buck1_reg>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 3e64d5dcdd60..d6bb990ce931 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -147,6 +147,12 @@
 	};
 };
 
+&bus_dmc {
+	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+	vdd-supply = <&buck1_reg>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 05/20] PM / devfreq: Add new passive governor
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (3 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 04/20] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 06/20] PM / devfreq: Add devfreq_get_devfreq_by_phandle() Chanwoo Choi
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the new passive governor for DEVFREQ framework. The following
governors are already present and used for DVFS (Dynamic Voltage and Frequency
Scaling) drivers. The following governors are independently used for one device
driver which don't give the influence to other device drviers and also don't
receive the effect from other device drivers.
- ondemand / performance / powersave / userspace

The passive governor depends on operation of parent driver with specific
governos extremely and is not able to decide the new frequency by oneself.
According to the decided new frequency of parent driver with governor,
the passive governor uses it to decide the appropriate frequency for own
device driver. The passive governor must need the following information
from device tree:
- the source clock and OPP tables
- the instance of parent device

For exameple,
there are one more devfreq device drivers which need to change their source
clock according to their utilization on runtime. But, they share the same
power line (e.g., regulator). So, specific device driver is operated as parent
with ondemand governor and then the rest device driver with passive governor
is influenced by parent device.

Suggested-by: Myungjoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/devfreq/Kconfig            |   9 ++++
 drivers/devfreq/Makefile           |   1 +
 drivers/devfreq/devfreq.c          |  47 ++++++++++++++++
 drivers/devfreq/governor_passive.c | 108 +++++++++++++++++++++++++++++++++++++
 include/linux/devfreq.h            |  15 ++++++
 5 files changed, 180 insertions(+)
 create mode 100644 drivers/devfreq/governor_passive.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 55ec774f794c..d03f635a93e1 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -64,6 +64,15 @@ config DEVFREQ_GOV_USERSPACE
 	  Otherwise, the governor does not change the frequnecy
 	  given at the initialization.
 
+config DEVFREQ_GOV_PASSIVE
+	tristate "Passive"
+	help
+	  Sets the frequency by other governors (simple_ondemand, performance,
+	  powersave, usersapce) of a parent devfreq device. This governor
+	  always has the dependency on the chosen frequency from paired
+	  governor. This governor does not change the frequency by oneself
+	  through sysfs entry.
+
 comment "DEVFREQ Drivers"
 
 config ARM_EXYNOS_BUS_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 375ebbb4fcfb..f81c313b4b79 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)	+= governor_simpleondemand.o
 obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE)	+= governor_performance.o
 obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
 obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
+obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)	+= governor_passive.o
 
 # DEVFREQ Drivers
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 984c5e9e7bdd..15e58779e4c0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -190,6 +190,31 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
 
 /* Load monitoring helper functions for governors use */
 
+static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
+{
+	struct devfreq *passive;
+	unsigned long rate;
+	int ret;
+
+	list_for_each_entry(passive, &devfreq->passive_dev_list, passive_node) {
+		if (!passive->governor)
+			continue;
+		rate = freq;
+
+		ret = passive->governor->get_target_freq(passive, &rate);
+		if (ret)
+			return ret;
+
+		ret = passive->profile->target(passive->dev.parent, &rate, 0);
+		if (ret)
+			return ret;
+
+		passive->previous_freq = rate;
+	}
+
+	return 0;
+}
+
 /**
  * update_devfreq() - Reevaluate the device and configure frequency.
  * @devfreq:	the devfreq instance.
@@ -233,10 +258,18 @@ int update_devfreq(struct devfreq *devfreq)
 		flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
 	}
 
+	if (!list_empty(&devfreq->passive_dev_list)
+		&& devfreq->previous_freq > freq)
+		update_devfreq_passive(devfreq, freq);
+
 	err = devfreq->profile->target(devfreq->dev.parent, &freq, flags);
 	if (err)
 		return err;
 
+	if (!list_empty(&devfreq->passive_dev_list)
+		&& devfreq->previous_freq < freq)
+		update_devfreq_passive(devfreq, freq);
+
 	if (devfreq->profile->freq_table)
 		if (devfreq_update_status(devfreq, freq))
 			dev_err(&devfreq->dev,
@@ -442,6 +475,10 @@ static void _remove_devfreq(struct devfreq *devfreq)
 		return;
 	}
 	list_del(&devfreq->node);
+	list_del(&devfreq->passive_node);
+	if (!list_empty(&devfreq->passive_dev_list))
+		list_del_init(&devfreq->passive_dev_list);
+
 	mutex_unlock(&devfreq_list_lock);
 
 	if (devfreq->governor)
@@ -559,6 +596,16 @@ struct devfreq *devfreq_add_device(struct device *dev,
 		goto err_init;
 	}
 
+	if (!strncmp(devfreq->governor_name, "passive", 7)) {
+		struct devfreq *parent_devfreq =
+			((struct devfreq_passive_data *)data)->parent;
+
+		list_add(&devfreq->passive_node,
+			&parent_devfreq->passive_dev_list);
+	} else {
+		INIT_LIST_HEAD(&devfreq->passive_dev_list);
+	}
+
 	return devfreq;
 
 err_init:
diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
new file mode 100644
index 000000000000..7443ae4b92f9
--- /dev/null
+++ b/drivers/devfreq/governor_passive.c
@@ -0,0 +1,108 @@
+/*
+ * linux/drivers/devfreq/governor_passive.c
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ * Author: Chanwoo Choi <cw00.choi@samsung.com>
+ *
+ * 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/devfreq.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/devfreq.h>
+#include "governor.h"
+
+static int devfreq_passive_get_target_freq(struct devfreq *passive,
+					unsigned long *freq)
+{
+	struct devfreq_passive_data *passive_data = passive->data;
+	struct devfreq *parent_devfreq = passive_data->parent;
+	unsigned long child_freq = ULONG_MAX;
+	int i, count;
+
+	/*
+	 * Each devfreq has the OPP table. After deciding the new frequency
+	 * from the governor of parent devfreq device, the passive governor
+	 * need to get the index of new frequency on OPP table of parent
+	 * device. And then the index is used for getting the suitable
+	 * new frequency for passive devfreq device.
+	 */
+
+	if (!passive->profile || !passive->profile->freq_table
+		|| passive->profile->max_state <= 0)
+		return -EINVAL;
+
+	/*
+	 * When new frequency is lower than previous frequency of parent
+	 * devfreq device, passive governor get the correct frequency from OPP
+	 * list of parent device. Because in this case, *freq is temporary
+	 * value which is decided by ondemand governor.
+	 */
+	if (parent_devfreq->previous_freq > *freq) {
+		struct dev_pm_opp *opp;
+		opp = devfreq_recommended_opp(parent_devfreq->dev.parent,
+						freq, 0);
+		if (IS_ERR_OR_NULL(opp))
+			return PTR_ERR(opp);
+	}
+
+	/*
+	 * Get the OPP table's index of decided freqeuncy by governor
+	 * of parent device.
+	 */
+	for (i = 0; i < parent_devfreq->profile->max_state; i++)
+		if (parent_devfreq->profile->freq_table[i] == *freq)
+			break;
+
+	if (i == parent_devfreq->profile->max_state)
+		return -EINVAL;
+	count = passive->profile->max_state;
+
+	/* Get the suitable frequency by using index of parent device. */
+	if (i < passive->profile->max_state)
+		child_freq = passive->profile->freq_table[i];
+	else
+		child_freq = passive->profile->freq_table[count - 1];
+
+	/* Return the suitable frequency for passive device. */
+	*freq = child_freq;
+
+	return 0;
+}
+
+static int devfreq_passive_event_handler(struct devfreq *devfreq,
+				unsigned int event, void *data)
+{
+	return 0;
+}
+
+static struct devfreq_governor devfreq_passive = {
+	.name = "passive",
+	.get_target_freq = devfreq_passive_get_target_freq,
+	.event_handler = devfreq_passive_event_handler,
+};
+
+static int __init devfreq_passive_init(void)
+{
+	return devfreq_add_governor(&devfreq_passive);
+}
+subsys_initcall(devfreq_passive_init);
+
+static void __exit devfreq_passive_exit(void)
+{
+	int ret;
+
+	ret = devfreq_remove_governor(&devfreq_passive);
+	if (ret)
+		pr_err("%s: failed remove governor %d\n", __func__, ret);
+
+	return;
+}
+module_exit(devfreq_passive_exit);
+
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
+MODULE_DESCRIPTION("DEVFREQ Passive governor");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 6fa02a20eb63..95c54578a1b4 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -177,6 +177,9 @@ struct devfreq {
 	unsigned int *trans_table;
 	unsigned long *time_in_state;
 	unsigned long last_stat_updated;
+
+	struct list_head passive_dev_list;
+	struct list_head passive_node;
 };
 
 #if defined(CONFIG_PM_DEVFREQ)
@@ -241,6 +244,18 @@ struct devfreq_simple_ondemand_data {
 };
 #endif
 
+/**
+ * struct devfreq_passive_data - void *data fed to struct devfreq
+ *	and devfreq_add_device
+ * @parent:		The parent devfreq device.
+ *
+ * If the fed devfreq_passive_data pointer is NULL to the governor,
+ * the governor return ERROR.
+ */
+struct devfreq_passive_data {
+	struct devfreq *parent;
+};
+
 #else /* !CONFIG_PM_DEVFREQ */
 static inline struct devfreq *devfreq_add_device(struct device *dev,
 					  struct devfreq_dev_profile *profile,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 06/20] PM / devfreq: Add devfreq_get_devfreq_by_phandle()
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (4 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 05/20] PM / devfreq: Add new passive governor Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 07/20] PM / devfreq: Show the related information according to governor type Chanwoo Choi
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the new devfreq_get_devfreq_by_phandle() OF helper function
which can find the instance of devfreq device by using phandle ("devfreq").

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/devfreq/devfreq.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/devfreq.h   |  9 +++++++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 15e58779e4c0..78ea4cdaa82c 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include <linux/printk.h>
 #include <linux/hrtimer.h>
+#include <linux/of.h>
 #include "governor.h"
 
 static struct class *devfreq_class;
@@ -686,6 +687,49 @@ struct devfreq *devm_devfreq_add_device(struct device *dev,
 }
 EXPORT_SYMBOL(devm_devfreq_add_device);
 
+#ifdef CONFIG_OF
+/*
+ * devfreq_get_devfreq_by_phandle - Get the devfreq device from devicetree
+ * @dev - instance to the given device
+ * @index - index into list of devfreq
+ *
+ * return the instance of devfreq device
+ */
+struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index)
+{
+	struct device_node *node;
+	struct devfreq *devfreq;
+
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	if (!dev->of_node)
+		return ERR_PTR(-EINVAL);
+
+	node = of_parse_phandle(dev->of_node, "devfreq", index);
+	if (!node)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&devfreq_list_lock);
+	list_for_each_entry(devfreq, &devfreq_list, node) {
+		if (devfreq->dev.parent
+			&& devfreq->dev.parent->of_node == node) {
+			mutex_unlock(&devfreq_list_lock);
+			return devfreq;
+		}
+	}
+	mutex_unlock(&devfreq_list_lock);
+
+	return ERR_PTR(-EPROBE_DEFER);
+}
+#else
+struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif /* CONFIG_OF */
+EXPORT_SYMBOL_GPL(devfreq_get_devfreq_by_phandle);
+
 /**
  * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device()
  * @dev:	the device to add devfreq feature.
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 95c54578a1b4..cf972befca2b 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -211,6 +211,9 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev,
 extern void devm_devfreq_unregister_opp_notifier(struct device *dev,
 						struct devfreq *devfreq);
 
+extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
+						int index);
+
 /**
  * devfreq_update_stats() - update the last_status pointer in struct devfreq
  * @df:		the devfreq instance whose status needs updating
@@ -322,6 +325,12 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
 {
 }
 
+static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
+							int index)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline int devfreq_update_stats(struct devfreq *df)
 {
 	return -EINVAL;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 07/20] PM / devfreq: Show the related information according to governor type
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (5 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 06/20] PM / devfreq: Add devfreq_get_devfreq_by_phandle() Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 08/20] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor Chanwoo Choi
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch modifies the following sysfs entry of DEVFREQ framework
because the devfreq device using passive governor don't need the same
information of the devfreq device using rest governor.
- polling_interval    : passive gov don't use the sampling rate.
- available_governors : passive gov don't be changed on runtime in this version.
- trans_stat          : passive governor don't support trans_stat in this version.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/devfreq/devfreq.c                 | 31 +++++++++++++++++++++++++------
 drivers/devfreq/governor.h                |  7 +++++++
 drivers/devfreq/governor_passive.c        |  1 +
 drivers/devfreq/governor_performance.c    |  1 +
 drivers/devfreq/governor_powersave.c      |  1 +
 drivers/devfreq/governor_simpleondemand.c |  1 +
 drivers/devfreq/governor_userspace.c      |  1 +
 include/linux/devfreq.h                   |  2 ++
 8 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 78ea4cdaa82c..18ad956fec93 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -597,7 +597,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
 		goto err_init;
 	}
 
-	if (!strncmp(devfreq->governor_name, "passive", 7)) {
+	if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) {
 		struct devfreq *parent_devfreq =
 			((struct devfreq_passive_data *)data)->parent;
 
@@ -963,13 +963,23 @@ static ssize_t available_governors_show(struct device *d,
 					struct device_attribute *attr,
 					char *buf)
 {
-	struct devfreq_governor *tmp_governor;
+	struct devfreq *devfreq = to_devfreq(d);
 	ssize_t count = 0;
 
 	mutex_lock(&devfreq_list_lock);
-	list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
+	if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) {
 		count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
-				   "%s ", tmp_governor->name);
+					   "%s ", devfreq->governor->name);
+	} else {
+		struct devfreq_governor *tmp_governor;
+
+		list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
+			if (tmp_governor->type == DEVFREQ_GOV_PASSIVE)
+				continue;
+			count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
+					   "%s ", tmp_governor->name);
+		}
+	}
 	mutex_unlock(&devfreq_list_lock);
 
 	/* Truncate the trailing space */
@@ -1006,6 +1016,11 @@ static DEVICE_ATTR_RO(target_freq);
 static ssize_t polling_interval_show(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct devfreq *df = to_devfreq(dev);
+
+	if (df->governor->type == DEVFREQ_GOV_PASSIVE)
+		return sprintf(buf, "Not Supported.\n");
+
 	return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms);
 }
 
@@ -1020,6 +1035,9 @@ static ssize_t polling_interval_store(struct device *dev,
 	if (!df->governor)
 		return -EINVAL;
 
+	if (df->governor->type == DEVFREQ_GOV_PASSIVE)
+		return -EINVAL;
+
 	ret = sscanf(buf, "%u", &value);
 	if (ret != 1)
 		return -EINVAL;
@@ -1137,11 +1155,12 @@ static ssize_t trans_stat_show(struct device *dev,
 	int i, j;
 	unsigned int max_state = devfreq->profile->max_state;
 
+	if (max_state == 0 || devfreq->governor->type == DEVFREQ_GOV_PASSIVE)
+		return sprintf(buf, "Not Supported.\n");
+
 	if (!devfreq->stop_polling &&
 			devfreq_update_status(devfreq, devfreq->previous_freq))
 		return 0;
-	if (max_state == 0)
-		return sprintf(buf, "Not Supported.\n");
 
 	len = sprintf(buf, "     From  :   To\n");
 	len += sprintf(buf + len, "           :");
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index fad7d6321978..43513a58f5bf 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -18,6 +18,13 @@
 
 #define to_devfreq(DEV)	container_of((DEV), struct devfreq, dev)
 
+/* Devfreq governor type */
+#define DEVFREQ_GOV_ONDEMAND			0x1
+#define DEVFREQ_GOV_PERFORMANCE			0x2
+#define DEVFREQ_GOV_POWERSAVE			0x3
+#define DEVFREQ_GOV_USERSPACE			0x4
+#define DEVFREQ_GOV_PASSIVE			0x4
+
 /* Devfreq events */
 #define DEVFREQ_GOV_START			0x1
 #define DEVFREQ_GOV_STOP			0x2
diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
index 7443ae4b92f9..adfdee9a9cd1 100644
--- a/drivers/devfreq/governor_passive.c
+++ b/drivers/devfreq/governor_passive.c
@@ -81,6 +81,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
 
 static struct devfreq_governor devfreq_passive = {
 	.name = "passive",
+	.type = DEVFREQ_GOV_PASSIVE,
 	.get_target_freq = devfreq_passive_get_target_freq,
 	.event_handler = devfreq_passive_event_handler,
 };
diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c
index c72f942f30a8..594d8ecb13fb 100644
--- a/drivers/devfreq/governor_performance.c
+++ b/drivers/devfreq/governor_performance.c
@@ -43,6 +43,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq,
 
 static struct devfreq_governor devfreq_performance = {
 	.name = "performance",
+	.type = DEVFREQ_GOV_PERFORMANCE,
 	.get_target_freq = devfreq_performance_func,
 	.event_handler = devfreq_performance_handler,
 };
diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c
index 0c6bed567e6d..e2817e1f2a31 100644
--- a/drivers/devfreq/governor_powersave.c
+++ b/drivers/devfreq/governor_powersave.c
@@ -40,6 +40,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq,
 
 static struct devfreq_governor devfreq_powersave = {
 	.name = "powersave",
+	.type = DEVFREQ_GOV_POWERSAVE,
 	.get_target_freq = devfreq_powersave_func,
 	.event_handler = devfreq_powersave_handler,
 };
diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c
index ae72ba5e78df..b905a535d486 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -126,6 +126,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
 
 static struct devfreq_governor devfreq_simple_ondemand = {
 	.name = "simple_ondemand",
+	.type = DEVFREQ_GOV_ONDEMAND,
 	.get_target_freq = devfreq_simple_ondemand_func,
 	.event_handler = devfreq_simple_ondemand_handler,
 };
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 35de6e83c1fe..c78ab78a5220 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -138,6 +138,7 @@ static int devfreq_userspace_handler(struct devfreq *devfreq,
 
 static struct devfreq_governor devfreq_userspace = {
 	.name = "userspace",
+	.type = DEVFREQ_GOV_USERSPACE,
 	.get_target_freq = devfreq_userspace_func,
 	.event_handler = devfreq_userspace_handler,
 };
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index cf972befca2b..64a9a0fe3d7e 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -97,6 +97,7 @@ struct devfreq_dev_profile {
  * struct devfreq_governor - Devfreq policy governor
  * @node:		list node - contains registered devfreq governors
  * @name:		Governor's name
+ * @type:		Governor's type
  * @get_target_freq:	Returns desired operating frequency for the device.
  *			Basically, get_target_freq will run
  *			devfreq_dev_profile.get_dev_status() to get the
@@ -114,6 +115,7 @@ struct devfreq_governor {
 	struct list_head node;
 
 	const char name[DEVFREQ_NAME_LEN];
+	const int type;
 	int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
 	int (*event_handler)(struct devfreq *devfreq,
 				unsigned int event, void *data);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 08/20] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (6 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 07/20] PM / devfreq: Show the related information according to governor type Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 09/20] PM / devfreq: exynos: Update documentation for bus devices " Chanwoo Choi
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the support of bus frequency feature for sub-blocks which share
the one power line. If each bus depends on the power line, each bus is not able
to change the voltage by oneself. To optimize the power-consumption on runtime,
some buses using the same power line should change the source clock and
regulator at the same time. So, this patch uses the passive governor to support
the bus frequency for all buses which sharing the one power line.

For example,

Exynos3250 include the two power line for AXI buses as following:
: VDD_MIF : MIF (Memory Interface) provide the DMC (Dynamic Memory Controller)
  with the power (regulator).
: VDD_INT : INT (Internal) provide the various sub-blocks with the power
  (regulator).

Each bus is included in as follwoing block. In the case of VDD_MIF, only DMC bus
use the power line. So, there is no any depencency between buese. But, in the
case of VDD_INT, various buses share the one power line of VDD_INT. We need to
make the depenency between buses. When using passive governor, there is no
problem to support the bus frequency as DVFS for all buses. One bus should be
operated as the parent bus device which gathering the current load of INT block
and then decides the new frequency with some governors except of passive
governor. After deciding the new frequency by the parent bus device, the rest
bus devices will change the each source clock according to new frequency of the
parent bus device.

- MIF (Memory Interface) block
: VDD_MIF |--- DMC

- INT (Internal) block
: VDD_INT |--- LEFTBUS (parent)
          |--- PERIL
          |--- MFC
          |--- G3D
          |--- RIGHTBUS
          |--- FSYS
          |--- LCD0
          |--- PERIR
          |--- ISP
          |--- CAM

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/devfreq/Kconfig             |   1 +
 drivers/devfreq/exynos/exynos-bus.c | 179 ++++++++++++++++++++++++++++--------
 2 files changed, 144 insertions(+), 36 deletions(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index d03f635a93e1..88f7cc4539b8 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -79,6 +79,7 @@ config ARM_EXYNOS_BUS_DEVFREQ
 	bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver"
 	depends on ARCH_EXYNOS
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select DEVFREQ_GOV_PASSIVE
 	select DEVFREQ_EVENT_EXYNOS_PPMU
 	select PM_DEVFREQ_EVENT
 	select PM_OPP
diff --git a/drivers/devfreq/exynos/exynos-bus.c b/drivers/devfreq/exynos/exynos-bus.c
index f1bc20839650..d1c137ea22ca 100644
--- a/drivers/devfreq/exynos/exynos-bus.c
+++ b/drivers/devfreq/exynos/exynos-bus.c
@@ -91,7 +91,7 @@ static int exynos_bus_get_event(struct exynos_bus *bus,
 }
 
 /*
- * Must necessary function for devfreq governor
+ * Must necessary function for devfreq simple-ondemand governor
  */
 static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
 {
@@ -205,57 +205,74 @@ static void exynos_bus_exit(struct device *dev)
 	dev_pm_opp_of_remove_table(dev);
 }
 
-static int exynos_bus_parse_of(struct device_node *np,
-			      struct exynos_bus *bus)
+/*
+ * Must necessary function for devfreq passive governor
+ */
+static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
+					u32 flags)
 {
-	struct device *dev = bus->dev;
-	unsigned long rate;
-	int i, ret, count, size;
+	struct exynos_bus *bus = dev_get_drvdata(dev);
+	struct dev_pm_opp *new_opp;
+	unsigned long old_freq, new_freq;
+	int ret = 0;
 
-	/* Get the clock to provide each bus with source clock */
-	bus->clk = devm_clk_get(dev, "bus");
-	if (IS_ERR(bus->clk)) {
-		dev_err(dev, "failed to get bus clock\n");
-		return PTR_ERR(bus->clk);
+	/* Get new opp-bus instance according to new bus clock */
+	rcu_read_lock();
+	new_opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR_OR_NULL(new_opp)) {
+		dev_err(dev, "failed to get recommed opp instance\n");
+		rcu_read_unlock();
+		return PTR_ERR(new_opp);
 	}
 
-	ret = clk_prepare_enable(bus->clk);
-	if (ret < 0) {
-		dev_err(dev, "failed to get enable clock\n");
-		return ret;
-	}
+	new_freq = dev_pm_opp_get_freq(new_opp);
+	old_freq = dev_pm_opp_get_freq(bus->curr_opp);
+	rcu_read_unlock();
 
-	/* Get the freq/voltage OPP table to scale the bus frequency */
-	rcu_read_lock();
-	ret = dev_pm_opp_of_add_table(dev);
+	if (old_freq == new_freq)
+		return 0;
+
+	/* Change the frequency according to new OPP level */
+	mutex_lock(&bus->lock);
+
+	ret = clk_set_rate(bus->clk, new_freq);
 	if (ret < 0) {
-		dev_err(dev, "failed to get OPP table\n");
-		rcu_read_unlock();
-		return ret;
+		dev_err(dev, "failed to set the clock of bus\n");
+		goto out;
 	}
 
-	rate = clk_get_rate(bus->clk);
-	bus->curr_opp = dev_pm_opp_find_freq_ceil(dev, &rate);
-	if (IS_ERR(bus->curr_opp)) {
-		dev_err(dev, "failed to find dev_pm_opp\n");
-		rcu_read_unlock();
-		ret = PTR_ERR(bus->curr_opp);
-		goto err_opp;
-	}
-	rcu_read_unlock();
+	bus->curr_opp = new_opp;
+
+	dev_dbg(dev, "Set the frequency of bus (%ldkHz -> %ldkHz)\n",
+			old_freq/1000, new_freq/1000);
+out:
+	mutex_unlock(&bus->lock);
+
+	return ret;
+}
+
+static void exynos_bus_passive_exit(struct device *dev)
+{
+	dev_pm_opp_of_remove_table(dev);
+}
+
+static int exynos_bus_parent_parse_of(struct device_node *np,
+					struct exynos_bus *bus)
+{
+	struct device *dev = bus->dev;
+	int i, ret, count, size;
 
 	/* Get the regulator to provide each bus with the power */
 	bus->regulator = devm_regulator_get(dev, "vdd");
 	if (IS_ERR(bus->regulator)) {
 		dev_err(dev, "failed to get VDD regulator\n");
-		ret = PTR_ERR(bus->regulator);
-		goto err_opp;
+		return PTR_ERR(bus->regulator);
 	}
 
 	ret = regulator_enable(bus->regulator);
 	if (ret < 0) {
 		dev_err(dev, "failed to enable VDD regulator\n");
-		goto err_opp;
+		return ret;
 	}
 
 	/*
@@ -302,6 +319,51 @@ static int exynos_bus_parse_of(struct device_node *np,
 
 err_regulator:
 	regulator_disable(bus->regulator);
+
+	return ret;
+}
+
+static int exynos_bus_parse_of(struct device_node *np,
+			      struct exynos_bus *bus)
+{
+	struct device *dev = bus->dev;
+	unsigned long rate;
+	int ret;
+
+	/* Get the clock to provide each bus with source clock */
+	bus->clk = devm_clk_get(dev, "bus");
+	if (IS_ERR(bus->clk)) {
+		dev_err(dev, "failed to get bus clock\n");
+		return PTR_ERR(bus->clk);
+	}
+
+	ret = clk_prepare_enable(bus->clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get enable clock\n");
+		return ret;
+	}
+
+	/* Get the freq and voltage from OPP table to scale the bus freq */
+	rcu_read_lock();
+	ret = dev_pm_opp_of_add_table(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to get OPP table\n");
+		rcu_read_unlock();
+		return ret;
+	}
+
+	rate = clk_get_rate(bus->clk);
+	bus->curr_opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+	if (IS_ERR(bus->curr_opp)) {
+		dev_err(dev, "failed to find dev_pm_opp\n");
+		rcu_read_unlock();
+		ret = PTR_ERR(bus->curr_opp);
+		goto err_opp;
+	}
+	rcu_read_unlock();
+
+	return 0;
+
 err_opp:
 	dev_pm_opp_of_remove_table(dev);
 
@@ -314,8 +376,11 @@ static int exynos_bus_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct devfreq_dev_profile *profile;
 	struct devfreq_simple_ondemand_data *ondemand_data;
+	struct devfreq_passive_data *passive_data;
+	struct devfreq *parent_devfreq;
 	struct exynos_bus *bus;
-	int ret;
+	int ret, max_state;
+	unsigned long min_freq, max_freq;
 
 	if (!np) {
 		dev_err(dev, "failed to find devicetree node\n");
@@ -334,10 +399,19 @@ static int exynos_bus_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	/* Initalize the struct profile and governor data */
 	profile = devm_kzalloc(dev, sizeof(*profile), GFP_KERNEL);
 	if (!profile)
 		return -ENOMEM;
+
+	if (of_parse_phandle(dev->of_node, "devfreq", 0))
+		goto passive;
+	else
+		ret = exynos_bus_parent_parse_of(np, bus);
+
+	if (ret < 0)
+		return ret;
+
+	/* Initalize the struct profile and governor data for parent device */
 	profile->polling_ms = 50;
 	profile->target = exynos_bus_target;
 	profile->get_dev_status = exynos_bus_get_dev_status;
@@ -380,6 +454,39 @@ static int exynos_bus_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	goto out;
+passive:
+	/* Initalize the struct profile and governor data for passive device */
+	profile->target = exynos_bus_passive_target;
+	profile->exit = exynos_bus_passive_exit;
+
+	passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
+	if (!passive_data)
+		return -ENOMEM;
+
+	/* Get the instance of parent devfreq device */
+	parent_devfreq = devfreq_get_devfreq_by_phandle(dev, 0);
+	if (IS_ERR(parent_devfreq)) {
+		return -EPROBE_DEFER;
+	}
+	passive_data->parent = parent_devfreq;
+
+	/* Add devfreq device for exynos bus with passive governor */
+	bus->devfreq = devm_devfreq_add_device(dev, profile, "passive",
+						passive_data);
+	if (IS_ERR_OR_NULL(bus->devfreq)) {
+		dev_err(dev,
+			"failed to add devfreq dev with passive governor\n");
+		return -EPROBE_DEFER;
+	}
+
+out:
+	max_state = bus->devfreq->profile->max_state;
+	min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
+	max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
+	pr_info("exynos-bus: new bus device registered: %s (%6ld KHz ~ %6ld KHz)\n",
+			dev_name(dev), min_freq, max_freq);
+
 	return 0;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 09/20] PM / devfreq: exynos: Update documentation for bus devices using passive governor
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (7 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 08/20] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 10/20] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line Chanwoo Choi
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch updates the documentation for passive bus devices and adds the
detailed example of Exynos3250.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 .../devicetree/bindings/devfreq/exynos-bus.txt     | 250 ++++++++++++++++++++-
 1 file changed, 247 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index e32daef328da..a251f9120561 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -8,22 +8,46 @@ of each buses on runtime. When gathering the usage of each buses on runtime,
 the driver uses the PPMU (Platform Performance Monitoring Unit) which
 is able to measure the current load of sub-blocks.
 
+The Exynos SoC includes the various sub-blocks which have the each AXI bus.
+The each AXI bus has the owned source clock but, has not the only owned
+power line. The power line might be shared among one more sub-blocks.
+So, we can divide into two type of device as the role of each sub-block.
+There are two type of bus devices as following:
+- parent bus device
+- passive bus device
+
+Basically, parent and passive bus device share the same power line.
+The parent bus device can only change the voltage of shared power line
+and the rest bus devices (passive bus device) depend on the decision of
+the parent bus device. If there are three blocks which share the VDD_xxx
+power line, Only one block should be parent device and then the rest blocks
+should depend on the parent device as passive device.
+
+	VDD_xxx |--- A block (parent)
+		|--- B block (passive)
+		|--- C block (passive)
+
 There are a little different composition among Exynos SoC because each Exynos
 SoC has the different sub-blocks. So, this difference should be specified
 in devicetree file instead of each device driver. In result, this driver
 is able to support the bus frequency for all Exynos SoCs.
 
-Required properties for bus device:
+Required properties for all bus devices:
 - compatible: Should be "samsung,exynos-bus".
 - clock-names : the name of clock used by the bus, "bus".
 - clocks : phandles for clock specified in "clock-names" property.
 - operating-points-v2: the OPP table including frequency/voltage information
   to support DVFS (Dynamic Voltage/Frequency Scaling) feature.
+
+Required properties only for parent bus device:
 - vdd-supply: the regulator to provide the buses with the voltage.
 - devfreq-events: the devfreq-event device to monitor the current utilization
   of buses.
 
-Optional properties for bus device:
+Required properties only for passive bus device:
+- devfreq: the parent bus device.
+
+Optional properties only for parent bus device:
 - exynos,saturation-ratio: the percentage value which is used to calibrate
                    the performance count against total cycle count.
 
@@ -32,7 +56,20 @@ Example1:
 	power line (regulator). The MIF (Memory Interface) AXI bus is used to
 	transfer data between DRAM and CPU and uses the VDD_MIF regualtor.
 
-	- power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block
+	- MIF (Memory Interface) block
+	: VDD_MIF |--- DMC (Dynamic Memory Controller)
+
+	- INT (Internal) block
+	: VDD_INT |--- LEFTBUS (parent device)
+		  |--- PERIL
+		  |--- MFC
+		  |--- G3D
+		  |--- RIGHTBUS
+		  |--- FSYS
+		  |--- LCD0
+		  |--- PERIR
+		  |--- ISP
+		  |--- CAM
 
 	- MIF bus's frequency/voltage table
 	-----------------------
@@ -45,6 +82,24 @@ Example1:
 	|L5| 400000 |875000   |
 	-----------------------
 
+	- INT bus's frequency/voltage table
+	----------------------------------------------------------
+	|Block|LEFTBUS|RIGHTBUS|MCUISP |ISP    |PERIL  ||VDD_INT |
+	| name|       |LCD0    |       |       |       ||        |
+	|     |       |FSYS    |       |       |       ||        |
+	|     |       |MFC     |       |       |       ||        |
+	----------------------------------------------------------
+	|Mode |*parent|passive |passive|passive|passive||        |
+	----------------------------------------------------------
+	|Lv   |Frequency                               ||Voltage |
+	----------------------------------------------------------
+	|L1   |50000  |50000   |50000  |50000  |50000  ||900000  |
+	|L2   |80000  |80000   |80000  |80000  |80000  ||900000  |
+	|L3   |100000 |100000  |100000 |100000 |100000 ||1000000 |
+	|L4   |134000 |134000  |200000 |200000 |       ||1000000 |
+	|L5   |200000 |200000  |400000 |300000 |       ||1000000 |
+	----------------------------------------------------------
+
 Example2 :
 	The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi
 	is listed below:
@@ -83,6 +138,154 @@ Example2 :
 		};
 	};
 
+	bus_leftbus: bus_leftbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_GDL>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_rightbus: bus_rightbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_GDR>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_lcd0: bus_lcd0 {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_ACLK_160>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_fsys: bus_fsys {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_ACLK_200>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_mcuisp: bus_mcuisp {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_ACLK_400_MCUISP>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_mcuisp_opp_table>;
+		status = "disabled";
+	};
+
+	bus_isp: bus_isp {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_ACLK_266>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_isp_opp_table>;
+		status = "disabled";
+	};
+
+	bus_peril: bus_peril {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_DIV_ACLK_100>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_peril_opp_table>;
+		status = "disabled";
+	};
+
+	bus_mfc: bus_mfc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&cmu CLK_SCLK_MFC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_leftbus_opp_table: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@80000000 {
+			opp-hz = /bits/ 64 <80000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <1000000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+			opp-microvolt = <1000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <1000000>;
+		};
+	};
+
+	bus_mcuisp_opp_table: opp_table2 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+		};
+		opp@80000000 {
+			opp-hz = /bits/ 64 <80000000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+		};
+	};
+
+	bus_isp_opp_table: opp_table3 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+		};
+		opp@80000000 {
+			opp-hz = /bits/ 64 <80000000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+		opp@300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+		};
+	};
+
+	bus_peril_opp_table: opp_table4 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+		};
+		opp@80000000 {
+			opp-hz = /bits/ 64 <80000000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+	};
+
+
 	Usage case to handle the frequency and voltage of bus on runtime
 	in exynos3250-rinato.dts is listed below:
 
@@ -91,3 +294,44 @@ Example2 :
 		vdd-supply = <&buck1_reg>;	/* VDD_MIF */
 		status = "okay";
 	};
+
+	&bus_leftbus {
+		devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+		vdd-supply = <&buck3_reg>;
+		status = "okay";
+	};
+
+	&bus_rightbus {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_lcd0 {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_fsys {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_mcuisp {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_isp {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_peril {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
+
+	&bus_mfc {
+		devfreq = <&bus_leftbus>;
+		status = "okay";
+	};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 10/20] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (8 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 09/20] PM / devfreq: exynos: Update documentation for bus devices " Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 11/20] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver Chanwoo Choi
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the detailed corrleation between sub-blocks and power line
for Exynos3250, Exynos4210 and Exynos4x12.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 .../devicetree/bindings/devfreq/exynos-bus.txt     | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index a251f9120561..f3a32b310dc7 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -51,6 +51,57 @@ Optional properties only for parent bus device:
 - exynos,saturation-ratio: the percentage value which is used to calibrate
                    the performance count against total cycle count.
 
+Detailed correlation between sub-blocks and power line according to Exynos SoC:
+- In case of Exynos3250, there are two power line as following:
+	VDD_MIF |--- DMC
+
+	VDD_INT |--- LEFTBUS (parent device)
+		|--- PERIL
+		|--- MFC
+		|--- G3D
+		|--- RIGHTBUS
+		|--- PERIR
+		|--- FSYS
+		|--- LCD0
+		|--- PERIR
+		|--- ISP
+		|--- CAM
+
+- In case of Exynos4210, there is one power line as following:
+	VDD_INT |--- DMC (parent device)
+		|--- LEFTBUS
+		|--- PERIL
+		|--- MFC(L)
+		|--- G3D
+		|--- TV
+		|--- LCD0
+		|--- RIGHTBUS
+		|--- PERIR
+		|--- MFC(R)
+		|--- CAM
+		|--- FSYS
+		|--- GPS
+		|--- LCD0
+		|--- LCD1
+
+- In case of Exynos4x12, there are two power line as following:
+	VDD_MIF |--- DMC
+
+	VDD_INT |--- LEFTBUS (parent device)
+		|--- PERIL
+		|--- MFC(L)
+		|--- G3D
+		|--- TV
+		|--- IMAGE
+		|--- RIGHTBUS
+		|--- PERIR
+		|--- MFC(R)
+		|--- CAM
+		|--- FSYS
+		|--- GPS
+		|--- LCD0
+		|--- ISP
+
 Example1:
 	Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to
 	power line (regulator). The MIF (Memory Interface) AXI bus is used to
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 11/20] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (9 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 10/20] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 12/20] MAINTAINERS: Add samsung bus frequency driver entry Chanwoo Choi
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch removes the unused exynos4/5 busfreq driver. Instead,
generic exynos-bus frequency driver support the all Exynos SoCs.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/Kconfig              |   22 -
 drivers/devfreq/exynos/Makefile      |    2 -
 drivers/devfreq/exynos/exynos4_bus.c | 1055 ----------------------------------
 drivers/devfreq/exynos/exynos4_bus.h |  110 ----
 drivers/devfreq/exynos/exynos5_bus.c |  431 --------------
 drivers/devfreq/exynos/exynos_ppmu.c |  119 ----
 drivers/devfreq/exynos/exynos_ppmu.h |   86 ---
 7 files changed, 1825 deletions(-)
 delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c
 delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h
 delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c
 delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c
 delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 88f7cc4539b8..e82b1d8cd200 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -91,28 +91,6 @@ config ARM_EXYNOS_BUS_DEVFREQ
 	  and adjusts the operating frequencies and voltages with OPP support.
 	  This does not yet operate with optimal voltages.
 
-config ARM_EXYNOS4_BUS_DEVFREQ
-	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
-	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
-	select DEVFREQ_GOV_SIMPLE_ONDEMAND
-	select PM_OPP
-	help
-	  This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int)
-	  and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int).
-	  It reads PPMU counters of memory controllers and adjusts
-	  the operating frequencies and voltages with OPP support.
-	  This does not yet operate with optimal voltages.
-
-config ARM_EXYNOS5_BUS_DEVFREQ
-	tristate "ARM Exynos5250 Bus DEVFREQ Driver"
-	depends on SOC_EXYNOS5250
-	select DEVFREQ_GOV_SIMPLE_ONDEMAND
-	select PM_OPP
-	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.
-
 config ARM_TEGRA_DEVFREQ
        tristate "Tegra DEVFREQ Driver"
        depends on ARCH_TEGRA_124_SOC
diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile
index 4ec06d322996..bc695ad81c7d 100644
--- a/drivers/devfreq/exynos/Makefile
+++ b/drivers/devfreq/exynos/Makefile
@@ -1,4 +1,2 @@
 # Exynos DEVFREQ Drivers
 obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
-obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos_ppmu.o exynos4_bus.o
-obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos_ppmu.o exynos5_bus.o
diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
deleted file mode 100644
index da9509205169..000000000000
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/* drivers/devfreq/exynos4210_memorybus.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *	MyungJoo Ham <myungjoo.ham@samsung.com>
- *
- * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework
- *	This version supports EXYNOS4210 only. This changes bus frequencies
- *	and vddint voltages. Exynos4412/4212 should be able to be supported
- *	with minor modifications.
- *
- * 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/io.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/suspend.h>
-#include <linux/pm_opp.h>
-#include <linux/devfreq.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-#include <mach/map.h>
-
-#include "exynos_ppmu.h"
-#include "exynos4_bus.h"
-
-#define MAX_SAFEVOLT	1200000 /* 1.2V */
-
-enum exynos4_busf_type {
-	TYPE_BUSF_EXYNOS4210,
-	TYPE_BUSF_EXYNOS4x12,
-};
-
-/* Assume that the bus is saturated if the utilization is 40% */
-#define BUS_SATURATION_RATIO	40
-
-enum busclk_level_idx {
-	LV_0 = 0,
-	LV_1,
-	LV_2,
-	LV_3,
-	LV_4,
-	_LV_END
-};
-
-enum exynos_ppmu_idx {
-	PPMU_DMC0,
-	PPMU_DMC1,
-	PPMU_END,
-};
-
-#define EX4210_LV_MAX	LV_2
-#define EX4x12_LV_MAX	LV_4
-#define EX4210_LV_NUM	(LV_2 + 1)
-#define EX4x12_LV_NUM	(LV_4 + 1)
-
-/**
- * struct busfreq_opp_info - opp information for bus
- * @rate:	Frequency in hertz
- * @volt:	Voltage in microvolts corresponding to this OPP
- */
-struct busfreq_opp_info {
-	unsigned long rate;
-	unsigned long volt;
-};
-
-struct busfreq_data {
-	enum exynos4_busf_type type;
-	struct device *dev;
-	struct devfreq *devfreq;
-	bool disabled;
-	struct regulator *vdd_int;
-	struct regulator *vdd_mif; /* Exynos4412/4212 only */
-	struct busfreq_opp_info curr_oppinfo;
-	struct busfreq_ppmu_data ppmu_data;
-
-	struct notifier_block pm_notifier;
-	struct mutex lock;
-
-	/* Dividers calculated at boot/probe-time */
-	unsigned int dmc_divtable[_LV_END]; /* DMC0 */
-	unsigned int top_divtable[_LV_END];
-};
-
-/* 4210 controls clock of mif and voltage of int */
-static struct bus_opp_table exynos4210_busclk_table[] = {
-	{LV_0, 400000, 1150000},
-	{LV_1, 267000, 1050000},
-	{LV_2, 133000, 1025000},
-	{0, 0, 0},
-};
-
-/*
- * MIF is the main control knob clock for Exynos4x12 MIF/INT
- * clock and voltage of both mif/int are controlled.
- */
-static struct bus_opp_table exynos4x12_mifclk_table[] = {
-	{LV_0, 400000, 1100000},
-	{LV_1, 267000, 1000000},
-	{LV_2, 160000, 950000},
-	{LV_3, 133000, 950000},
-	{LV_4, 100000, 950000},
-	{0, 0, 0},
-};
-
-/*
- * INT is not the control knob of 4x12. LV_x is not meant to represent
- * the current performance. (MIF does)
- */
-static struct bus_opp_table exynos4x12_intclk_table[] = {
-	{LV_0, 200000, 1000000},
-	{LV_1, 160000, 950000},
-	{LV_2, 133000, 925000},
-	{LV_3, 100000, 900000},
-	{0, 0, 0},
-};
-
-/* TODO: asv volt definitions are "__initdata"? */
-/* Some chips have different operating voltages */
-static unsigned int exynos4210_asv_volt[][EX4210_LV_NUM] = {
-	{1150000, 1050000, 1050000},
-	{1125000, 1025000, 1025000},
-	{1100000, 1000000, 1000000},
-	{1075000, 975000, 975000},
-	{1050000, 950000, 950000},
-};
-
-static unsigned int exynos4x12_mif_step_50[][EX4x12_LV_NUM] = {
-	/* 400      267     160     133     100 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV0 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV1 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV2 */
-	{1050000, 900000, 900000, 900000, 900000}, /* ASV3 */
-	{1050000, 900000, 900000, 900000, 850000}, /* ASV4 */
-	{1050000, 900000, 900000, 850000, 850000}, /* ASV5 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV6 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV7 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV8 */
-};
-
-static unsigned int exynos4x12_int_volt[][EX4x12_LV_NUM] = {
-	/* 200    160      133     100 */
-	{1000000, 950000, 925000, 900000}, /* ASV0 */
-	{975000,  925000, 925000, 900000}, /* ASV1 */
-	{950000,  925000, 900000, 875000}, /* ASV2 */
-	{950000,  900000, 900000, 875000}, /* ASV3 */
-	{925000,  875000, 875000, 875000}, /* ASV4 */
-	{900000,  850000, 850000, 850000}, /* ASV5 */
-	{900000,  850000, 850000, 850000}, /* ASV6 */
-	{900000,  850000, 850000, 850000}, /* ASV7 */
-	{900000,  850000, 850000, 850000}, /* ASV8 */
-};
-
-/*** Clock Divider Data for Exynos4210 ***/
-static unsigned int exynos4210_clkdiv_dmc0[][8] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
-	 *		DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
-	 */
-
-	/* DMC L0: 400MHz */
-	{ 3, 1, 1, 1, 1, 1, 3, 1 },
-	/* DMC L1: 266.7MHz */
-	{ 4, 1, 1, 2, 1, 1, 3, 1 },
-	/* DMC L2: 133MHz */
-	{ 5, 1, 1, 5, 1, 1, 3, 1 },
-};
-static unsigned int exynos4210_clkdiv_top[][5] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
-	 */
-	/* ACLK200 L0: 200MHz */
-	{ 3, 7, 4, 5, 1 },
-	/* ACLK200 L1: 160MHz */
-	{ 4, 7, 5, 6, 1 },
-	/* ACLK200 L2: 133MHz */
-	{ 5, 7, 7, 7, 1 },
-};
-static unsigned int exynos4210_clkdiv_lr_bus[][2] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVGDL/R, DIVGPL/R }
-	 */
-	/* ACLK_GDL/R L1: 200MHz */
-	{ 3, 1 },
-	/* ACLK_GDL/R L2: 160MHz */
-	{ 4, 1 },
-	/* ACLK_GDL/R L3: 133MHz */
-	{ 5, 1 },
-};
-
-/*** Clock Divider Data for Exynos4212/4412 ***/
-static unsigned int exynos4x12_clkdiv_dmc0[][6] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
-	 *              DIVDMCP}
-	 */
-
-	/* DMC L0: 400MHz */
-	{3, 1, 1, 1, 1, 1},
-	/* DMC L1: 266.7MHz */
-	{4, 1, 1, 2, 1, 1},
-	/* DMC L2: 160MHz */
-	{5, 1, 1, 4, 1, 1},
-	/* DMC L3: 133MHz */
-	{5, 1, 1, 5, 1, 1},
-	/* DMC L4: 100MHz */
-	{7, 1, 1, 7, 1, 1},
-};
-static unsigned int exynos4x12_clkdiv_dmc1[][6] = {
-	/*
-	 * Clock divider value for following
-	 * { G2DACP, DIVC2C, DIVC2C_ACLK }
-	 */
-
-	/* DMC L0: 400MHz */
-	{3, 1, 1},
-	/* DMC L1: 266.7MHz */
-	{4, 2, 1},
-	/* DMC L2: 160MHz */
-	{5, 4, 1},
-	/* DMC L3: 133MHz */
-	{5, 5, 1},
-	/* DMC L4: 100MHz */
-	{7, 7, 1},
-};
-static unsigned int exynos4x12_clkdiv_top[][5] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACLK266_GPS, DIVACLK100, DIVACLK160,
-		DIVACLK133, DIVONENAND }
-	 */
-
-	/* ACLK_GDL/R L0: 200MHz */
-	{2, 7, 4, 5, 1},
-	/* ACLK_GDL/R L1: 200MHz */
-	{2, 7, 4, 5, 1},
-	/* ACLK_GDL/R L2: 160MHz */
-	{4, 7, 5, 7, 1},
-	/* ACLK_GDL/R L3: 133MHz */
-	{4, 7, 5, 7, 1},
-	/* ACLK_GDL/R L4: 100MHz */
-	{7, 7, 7, 7, 1},
-};
-static unsigned int exynos4x12_clkdiv_lr_bus[][2] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVGDL/R, DIVGPL/R }
-	 */
-
-	/* ACLK_GDL/R L0: 200MHz */
-	{3, 1},
-	/* ACLK_GDL/R L1: 200MHz */
-	{3, 1},
-	/* ACLK_GDL/R L2: 160MHz */
-	{4, 1},
-	/* ACLK_GDL/R L3: 133MHz */
-	{5, 1},
-	/* ACLK_GDL/R L4: 100MHz */
-	{7, 1},
-};
-static unsigned int exynos4x12_clkdiv_sclkip[][3] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVMFC, DIVJPEG, DIVFIMC0~3}
-	 */
-
-	/* SCLK_MFC: 200MHz */
-	{3, 3, 4},
-	/* SCLK_MFC: 200MHz */
-	{3, 3, 4},
-	/* SCLK_MFC: 160MHz */
-	{4, 4, 5},
-	/* SCLK_MFC: 133MHz */
-	{5, 5, 5},
-	/* SCLK_MFC: 100MHz */
-	{7, 7, 7},
-};
-
-
-static int exynos4210_set_busclk(struct busfreq_data *data,
-				 struct busfreq_opp_info *oppi)
-{
-	unsigned int index;
-	unsigned int tmp;
-
-	for (index = LV_0; index < EX4210_LV_NUM; index++)
-		if (oppi->rate == exynos4210_busclk_table[index].clk)
-			break;
-
-	if (index == EX4210_LV_NUM)
-		return -EINVAL;
-
-	/* Change Divider - DMC0 */
-	tmp = data->dmc_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
-	} while (tmp & 0x11111111);
-
-	/* Change Divider - TOP */
-	tmp = data->top_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
-	} while (tmp & 0x11111);
-
-	/* Change Divider - LEFTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4210_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - RIGHTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4210_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
-	} while (tmp & 0x11);
-
-	return 0;
-}
-
-static int exynos4x12_set_busclk(struct busfreq_data *data,
-				 struct busfreq_opp_info *oppi)
-{
-	unsigned int index;
-	unsigned int tmp;
-
-	for (index = LV_0; index < EX4x12_LV_NUM; index++)
-		if (oppi->rate == exynos4x12_mifclk_table[index].clk)
-			break;
-
-	if (index == EX4x12_LV_NUM)
-		return -EINVAL;
-
-	/* Change Divider - DMC0 */
-	tmp = data->dmc_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
-	} while (tmp & 0x11111111);
-
-	/* Change Divider - DMC1 */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
-
-	tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
-		EXYNOS4_CLKDIV_DMC1_C2C_MASK |
-		EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_dmc1[index][0] <<
-				EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
-		(exynos4x12_clkdiv_dmc1[index][1] <<
-				EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
-		(exynos4x12_clkdiv_dmc1[index][2] <<
-				EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
-	} while (tmp & 0x111111);
-
-	/* Change Divider - TOP */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
-
-	tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
-		EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_top[index][0] <<
-				EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
-		(exynos4x12_clkdiv_top[index][1] <<
-				EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
-		(exynos4x12_clkdiv_top[index][2] <<
-				EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
-		(exynos4x12_clkdiv_top[index][3] <<
-				EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
-		(exynos4x12_clkdiv_top[index][4] <<
-				EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
-	} while (tmp & 0x11111);
-
-	/* Change Divider - LEFTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4x12_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - RIGHTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4x12_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - MFC */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
-
-	tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][0] <<
-				EXYNOS4_CLKDIV_MFC_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
-	} while (tmp & 0x1);
-
-	/* Change Divider - JPEG */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
-
-	tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][1] <<
-				EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
-	} while (tmp & 0x1);
-
-	/* Change Divider - FIMC0~3 */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
-
-	tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
-		EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
-	} while (tmp & 0x1111);
-
-	return 0;
-}
-
-static int exynos4x12_get_intspec(unsigned long mifclk)
-{
-	int i = 0;
-
-	while (exynos4x12_intclk_table[i].clk) {
-		if (exynos4x12_intclk_table[i].clk <= mifclk)
-			return i;
-		i++;
-	}
-
-	return -EINVAL;
-}
-
-static int exynos4_bus_setvolt(struct busfreq_data *data,
-			       struct busfreq_opp_info *oppi,
-			       struct busfreq_opp_info *oldoppi)
-{
-	int err = 0, tmp;
-	unsigned long volt = oppi->volt;
-
-	switch (data->type) {
-	case TYPE_BUSF_EXYNOS4210:
-		/* OPP represents DMC clock + INT voltage */
-		err = regulator_set_voltage(data->vdd_int, volt,
-					    MAX_SAFEVOLT);
-		break;
-	case TYPE_BUSF_EXYNOS4x12:
-		/* OPP represents MIF clock + MIF voltage */
-		err = regulator_set_voltage(data->vdd_mif, volt,
-					    MAX_SAFEVOLT);
-		if (err)
-			break;
-
-		tmp = exynos4x12_get_intspec(oppi->rate);
-		if (tmp < 0) {
-			err = tmp;
-			regulator_set_voltage(data->vdd_mif,
-					      oldoppi->volt,
-					      MAX_SAFEVOLT);
-			break;
-		}
-		err = regulator_set_voltage(data->vdd_int,
-					    exynos4x12_intclk_table[tmp].volt,
-					    MAX_SAFEVOLT);
-		/*  Try to recover */
-		if (err)
-			regulator_set_voltage(data->vdd_mif,
-					      oldoppi->volt,
-					      MAX_SAFEVOLT);
-		break;
-	default:
-		err = -EINVAL;
-	}
-
-	return err;
-}
-
-static int exynos4_bus_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 *data = platform_get_drvdata(pdev);
-	struct dev_pm_opp *opp;
-	unsigned long freq;
-	unsigned long old_freq = data->curr_oppinfo.rate;
-	struct busfreq_opp_info	new_oppinfo;
-
-	rcu_read_lock();
-	opp = devfreq_recommended_opp(dev, _freq, flags);
-	if (IS_ERR(opp)) {
-		rcu_read_unlock();
-		return PTR_ERR(opp);
-	}
-	new_oppinfo.rate = dev_pm_opp_get_freq(opp);
-	new_oppinfo.volt = dev_pm_opp_get_voltage(opp);
-	rcu_read_unlock();
-	freq = new_oppinfo.rate;
-
-	if (old_freq == freq)
-		return 0;
-
-	dev_dbg(dev, "targeting %lukHz %luuV\n", freq, new_oppinfo.volt);
-
-	mutex_lock(&data->lock);
-
-	if (data->disabled)
-		goto out;
-
-	if (old_freq < freq)
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-	if (err)
-		goto out;
-
-	if (old_freq != freq) {
-		switch (data->type) {
-		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, &new_oppinfo);
-			break;
-		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, &new_oppinfo);
-			break;
-		default:
-			err = -EINVAL;
-		}
-	}
-	if (err)
-		goto out;
-
-	if (old_freq > freq)
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-	if (err)
-		goto out;
-
-	data->curr_oppinfo = new_oppinfo;
-out:
-	mutex_unlock(&data->lock);
-	return err;
-}
-
-static int exynos4_bus_get_dev_status(struct device *dev,
-				      struct devfreq_dev_status *stat)
-{
-	struct busfreq_data *data = dev_get_drvdata(dev);
-	struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
-	int busier;
-
-	exynos_read_ppmu(ppmu_data);
-	busier = exynos_get_busier_ppmu(ppmu_data);
-	stat->current_frequency = data->curr_oppinfo.rate;
-
-	/* Number of cycles spent on memory access */
-	stat->busy_time = ppmu_data->ppmu[busier].count[PPMU_PMNCNT3];
-	stat->busy_time *= 100 / BUS_SATURATION_RATIO;
-	stat->total_time = ppmu_data->ppmu[busier].ccnt;
-
-	/* If the counters have overflown, retry */
-	if (ppmu_data->ppmu[busier].ccnt_overflow ||
-	    ppmu_data->ppmu[busier].count_overflow[0])
-		return -EAGAIN;
-
-	return 0;
-}
-
-static struct devfreq_dev_profile exynos4_devfreq_profile = {
-	.initial_freq	= 400000,
-	.polling_ms	= 50,
-	.target		= exynos4_bus_target,
-	.get_dev_status	= exynos4_bus_get_dev_status,
-};
-
-static int exynos4210_init_tables(struct busfreq_data *data)
-{
-	u32 tmp;
-	int mgrp;
-	int i, err = 0;
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
-	for (i = LV_0; i < EX4210_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
-			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
-			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
-			EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
-			EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
-
-		tmp |= ((exynos4210_clkdiv_dmc0[i][0] <<
-					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][1] <<
-					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][2] <<
-					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][3] <<
-					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][4] <<
-					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][5] <<
-					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][6] <<
-					EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][7] <<
-					EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
-
-		data->dmc_divtable[i] = tmp;
-	}
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
-	for (i = LV_0; i <  EX4210_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
-			EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
-
-		tmp |= ((exynos4210_clkdiv_top[i][0] <<
-					EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
-			(exynos4210_clkdiv_top[i][1] <<
-					EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
-			(exynos4210_clkdiv_top[i][2] <<
-					EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
-			(exynos4210_clkdiv_top[i][3] <<
-					EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
-			(exynos4210_clkdiv_top[i][4] <<
-					EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
-
-		data->top_divtable[i] = tmp;
-	}
-
-	/*
-	 * TODO: init tmp based on busfreq_data
-	 * (device-tree or platform-data)
-	 */
-	tmp = 0; /* Max voltages for the reliability of the unknown */
-
-	pr_debug("ASV Group of Exynos4 is %d\n", tmp);
-	/* Use merged grouping for voltage */
-	switch (tmp) {
-	case 0:
-		mgrp = 0;
-		break;
-	case 1:
-	case 2:
-		mgrp = 1;
-		break;
-	case 3:
-	case 4:
-		mgrp = 2;
-		break;
-	case 5:
-	case 6:
-		mgrp = 3;
-		break;
-	case 7:
-		mgrp = 4;
-		break;
-	default:
-		pr_warn("Unknown ASV Group. Use max voltage.\n");
-		mgrp = 0;
-	}
-
-	for (i = LV_0; i < EX4210_LV_NUM; i++)
-		exynos4210_busclk_table[i].volt = exynos4210_asv_volt[mgrp][i];
-
-	for (i = LV_0; i < EX4210_LV_NUM; i++) {
-		err = dev_pm_opp_add(data->dev, exynos4210_busclk_table[i].clk,
-			      exynos4210_busclk_table[i].volt);
-		if (err) {
-			dev_err(data->dev, "Cannot add opp entries.\n");
-			return err;
-		}
-	}
-
-
-	return 0;
-}
-
-static int exynos4x12_init_tables(struct busfreq_data *data)
-{
-	unsigned int i;
-	unsigned int tmp;
-	int ret;
-
-	/* Enable pause function for DREX2 DVFS */
-	tmp = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
-	tmp |= EXYNOS4_DMC_PAUSE_ENABLE;
-	__raw_writel(tmp, EXYNOS4_DMC_PAUSE_CTRL);
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
-
-	for (i = 0; i <  EX4x12_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
-			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
-			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
-
-		tmp |= ((exynos4x12_clkdiv_dmc0[i][0] <<
-					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][1] <<
-					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][2] <<
-					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][3] <<
-					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][4] <<
-					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][5] <<
-					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
-
-		data->dmc_divtable[i] = tmp;
-	}
-
-	tmp = 0; /* Max voltages for the reliability of the unknown */
-
-	if (tmp > 8)
-		tmp = 0;
-	pr_debug("ASV Group of Exynos4x12 is %d\n", tmp);
-
-	for (i = 0; i < EX4x12_LV_NUM; i++) {
-		exynos4x12_mifclk_table[i].volt =
-			exynos4x12_mif_step_50[tmp][i];
-		exynos4x12_intclk_table[i].volt =
-			exynos4x12_int_volt[tmp][i];
-	}
-
-	for (i = 0; i < EX4x12_LV_NUM; i++) {
-		ret = dev_pm_opp_add(data->dev, exynos4x12_mifclk_table[i].clk,
-			      exynos4x12_mifclk_table[i].volt);
-		if (ret) {
-			dev_err(data->dev, "Fail to add opp entries.\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
-		unsigned long event, void *ptr)
-{
-	struct busfreq_data *data = container_of(this, struct busfreq_data,
-						 pm_notifier);
-	struct dev_pm_opp *opp;
-	struct busfreq_opp_info	new_oppinfo;
-	unsigned long maxfreq = ULONG_MAX;
-	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 = dev_pm_opp_find_freq_floor(data->dev, &maxfreq);
-		if (IS_ERR(opp)) {
-			rcu_read_unlock();
-			dev_err(data->dev, "%s: unable to find a min freq\n",
-				__func__);
-			mutex_unlock(&data->lock);
-			return PTR_ERR(opp);
-		}
-		new_oppinfo.rate = dev_pm_opp_get_freq(opp);
-		new_oppinfo.volt = dev_pm_opp_get_voltage(opp);
-		rcu_read_unlock();
-
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-		if (err)
-			goto unlock;
-
-		switch (data->type) {
-		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, &new_oppinfo);
-			break;
-		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, &new_oppinfo);
-			break;
-		default:
-			err = -EINVAL;
-		}
-		if (err)
-			goto unlock;
-
-		data->curr_oppinfo = new_oppinfo;
-unlock:
-		mutex_unlock(&data->lock);
-		if (err)
-			return err;
-		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 int exynos4_busfreq_probe(struct platform_device *pdev)
-{
-	struct busfreq_data *data;
-	struct busfreq_ppmu_data *ppmu_data;
-	struct dev_pm_opp *opp;
-	struct device *dev = &pdev->dev;
-	int err = 0;
-
-	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(dev, "Cannot allocate memory.\n");
-		return -ENOMEM;
-	}
-
-	ppmu_data = &data->ppmu_data;
-	ppmu_data->ppmu_end = PPMU_END;
-	ppmu_data->ppmu = devm_kzalloc(dev,
-				       sizeof(struct exynos_ppmu) * PPMU_END,
-				       GFP_KERNEL);
-	if (!ppmu_data->ppmu) {
-		dev_err(dev, "Failed to allocate memory for exynos_ppmu\n");
-		return -ENOMEM;
-	}
-
-	data->type = pdev->id_entry->driver_data;
-	ppmu_data->ppmu[PPMU_DMC0].hw_base = S5P_VA_DMC0;
-	ppmu_data->ppmu[PPMU_DMC1].hw_base = S5P_VA_DMC1;
-	data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
-	data->dev = dev;
-	mutex_init(&data->lock);
-
-	switch (data->type) {
-	case TYPE_BUSF_EXYNOS4210:
-		err = exynos4210_init_tables(data);
-		break;
-	case TYPE_BUSF_EXYNOS4x12:
-		err = exynos4x12_init_tables(data);
-		break;
-	default:
-		dev_err(dev, "Cannot determine the device id %d\n", data->type);
-		err = -EINVAL;
-	}
-	if (err) {
-		dev_err(dev, "Cannot initialize busfreq table %d\n",
-			     data->type);
-		return err;
-	}
-
-	data->vdd_int = devm_regulator_get(dev, "vdd_int");
-	if (IS_ERR(data->vdd_int)) {
-		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
-		return PTR_ERR(data->vdd_int);
-	}
-	if (data->type == TYPE_BUSF_EXYNOS4x12) {
-		data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
-		if (IS_ERR(data->vdd_mif)) {
-			dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
-			return PTR_ERR(data->vdd_mif);
-		}
-	}
-
-	rcu_read_lock();
-	opp = dev_pm_opp_find_freq_floor(dev,
-					 &exynos4_devfreq_profile.initial_freq);
-	if (IS_ERR(opp)) {
-		rcu_read_unlock();
-		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
-			exynos4_devfreq_profile.initial_freq);
-		return PTR_ERR(opp);
-	}
-	data->curr_oppinfo.rate = dev_pm_opp_get_freq(opp);
-	data->curr_oppinfo.volt = dev_pm_opp_get_voltage(opp);
-	rcu_read_unlock();
-
-	platform_set_drvdata(pdev, data);
-
-	data->devfreq = devm_devfreq_add_device(dev, &exynos4_devfreq_profile,
-					   "simple_ondemand", NULL);
-	if (IS_ERR(data->devfreq))
-		return PTR_ERR(data->devfreq);
-
-	/*
-	 * Start PPMU (Performance Profiling Monitoring Unit) to check
-	 * utilization of each IP in the Exynos4 SoC.
-	 */
-	busfreq_mon_reset(ppmu_data);
-
-	/* Register opp_notifier for Exynos4 busfreq */
-	err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
-	if (err < 0) {
-		dev_err(dev, "Failed to register opp notifier\n");
-		return err;
-	}
-
-	/* Register pm_notifier for Exynos4 busfreq */
-	err = register_pm_notifier(&data->pm_notifier);
-	if (err) {
-		dev_err(dev, "Failed to setup pm notifier\n");
-		return err;
-	}
-
-	return 0;
-}
-
-static int exynos4_busfreq_remove(struct platform_device *pdev)
-{
-	struct busfreq_data *data = platform_get_drvdata(pdev);
-
-	/* Unregister all of notifier chain */
-	unregister_pm_notifier(&data->pm_notifier);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_busfreq_resume(struct device *dev)
-{
-	struct busfreq_data *data = dev_get_drvdata(dev);
-	struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
-
-	busfreq_mon_reset(ppmu_data);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(exynos4_busfreq_pm_ops, NULL, exynos4_busfreq_resume);
-
-static const struct platform_device_id exynos4_busfreq_id[] = {
-	{ "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 },
-	{ "exynos4412-busfreq", TYPE_BUSF_EXYNOS4x12 },
-	{ "exynos4212-busfreq", TYPE_BUSF_EXYNOS4x12 },
-	{ },
-};
-
-static struct platform_driver exynos4_busfreq_driver = {
-	.probe	= exynos4_busfreq_probe,
-	.remove	= exynos4_busfreq_remove,
-	.id_table = exynos4_busfreq_id,
-	.driver = {
-		.name	= "exynos4-busfreq",
-		.pm	= &exynos4_busfreq_pm_ops,
-	},
-};
-
-static int __init exynos4_busfreq_init(void)
-{
-	return platform_driver_register(&exynos4_busfreq_driver);
-}
-late_initcall(exynos4_busfreq_init);
-
-static void __exit exynos4_busfreq_exit(void)
-{
-	platform_driver_unregister(&exynos4_busfreq_driver);
-}
-module_exit(exynos4_busfreq_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework");
-MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff --git a/drivers/devfreq/exynos/exynos4_bus.h b/drivers/devfreq/exynos/exynos4_bus.h
deleted file mode 100644
index 94c73c18d28c..000000000000
--- a/drivers/devfreq/exynos/exynos4_bus.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * EXYNOS4 BUS 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_EXYNOS4_BUS_H
-#define __DEVFREQ_EXYNOS4_BUS_H __FILE__
-
-#include <mach/map.h>
-
-#define EXYNOS4_CLKDIV_LEFTBUS			(S5P_VA_CMU + 0x04500)
-#define EXYNOS4_CLKDIV_STAT_LEFTBUS		(S5P_VA_CMU + 0x04600)
-
-#define EXYNOS4_CLKDIV_RIGHTBUS			(S5P_VA_CMU + 0x08500)
-#define EXYNOS4_CLKDIV_STAT_RIGHTBUS		(S5P_VA_CMU + 0x08600)
-
-#define EXYNOS4_CLKDIV_TOP			(S5P_VA_CMU + 0x0C510)
-#define EXYNOS4_CLKDIV_CAM			(S5P_VA_CMU + 0x0C520)
-#define EXYNOS4_CLKDIV_MFC			(S5P_VA_CMU + 0x0C528)
-
-#define EXYNOS4_CLKDIV_STAT_TOP			(S5P_VA_CMU + 0x0C610)
-#define EXYNOS4_CLKDIV_STAT_MFC			(S5P_VA_CMU + 0x0C628)
-
-#define EXYNOS4210_CLKGATE_IP_IMAGE		(S5P_VA_CMU + 0x0C930)
-#define EXYNOS4212_CLKGATE_IP_IMAGE		(S5P_VA_CMU + 0x04930)
-
-#define EXYNOS4_CLKDIV_DMC0			(S5P_VA_CMU + 0x10500)
-#define EXYNOS4_CLKDIV_DMC1			(S5P_VA_CMU + 0x10504)
-#define EXYNOS4_CLKDIV_STAT_DMC0		(S5P_VA_CMU + 0x10600)
-#define EXYNOS4_CLKDIV_STAT_DMC1		(S5P_VA_CMU + 0x10604)
-
-#define EXYNOS4_DMC_PAUSE_CTRL			(S5P_VA_CMU + 0x11094)
-#define EXYNOS4_DMC_PAUSE_ENABLE		(1 << 0)
-
-#define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT		(0)
-#define EXYNOS4_CLKDIV_DMC0_ACP_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT	(4)
-#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK	(0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT		(8)
-#define EXYNOS4_CLKDIV_DMC0_DPHY_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT		(12)
-#define EXYNOS4_CLKDIV_DMC0_DMC_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT		(16)
-#define EXYNOS4_CLKDIV_DMC0_DMCD_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT		(20)
-#define EXYNOS4_CLKDIV_DMC0_DMCP_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT		(24)
-#define EXYNOS4_CLKDIV_DMC0_COPY2_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT)
-#define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT	(28)
-#define EXYNOS4_CLKDIV_DMC0_CORETI_MASK		(0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT)
-
-#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT	(0)
-#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK	(0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT)
-#define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT		(4)
-#define EXYNOS4_CLKDIV_DMC1_C2C_MASK		(0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT)
-#define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT		(8)
-#define EXYNOS4_CLKDIV_DMC1_PWI_MASK		(0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT)
-#define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT	(12)
-#define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK	(0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT)
-#define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT		(16)
-#define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK		(0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT)
-#define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT		(24)
-#define EXYNOS4_CLKDIV_DMC1_DPM_MASK		(0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT)
-
-#define EXYNOS4_CLKDIV_MFC_SHIFT		(0)
-#define EXYNOS4_CLKDIV_MFC_MASK			(0x7 << EXYNOS4_CLKDIV_MFC_SHIFT)
-
-#define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT	(0)
-#define EXYNOS4_CLKDIV_TOP_ACLK200_MASK		(0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT	(4)
-#define EXYNOS4_CLKDIV_TOP_ACLK100_MASK		(0xF << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT	(8)
-#define EXYNOS4_CLKDIV_TOP_ACLK160_MASK		(0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT	(12)
-#define EXYNOS4_CLKDIV_TOP_ACLK133_MASK		(0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT	(16)
-#define EXYNOS4_CLKDIV_TOP_ONENAND_MASK		(0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT	(20)
-#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK	(0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT)
-#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT	(24)
-#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK	(0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT)
-
-#define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT		(0)
-#define EXYNOS4_CLKDIV_BUS_GDLR_MASK		(0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT)
-#define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT		(4)
-#define EXYNOS4_CLKDIV_BUS_GPLR_MASK		(0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT)
-
-#define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT		(0)
-#define EXYNOS4_CLKDIV_CAM_FIMC0_MASK		(0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT)
-#define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT		(4)
-#define EXYNOS4_CLKDIV_CAM_FIMC1_MASK		(0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT)
-#define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT		(8)
-#define EXYNOS4_CLKDIV_CAM_FIMC2_MASK		(0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT)
-#define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT		(12)
-#define EXYNOS4_CLKDIV_CAM_FIMC3_MASK		(0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT)
-
-#define EXYNOS4_CLKDIV_CAM1			(S5P_VA_CMU + 0x0C568)
-
-#define EXYNOS4_CLKDIV_STAT_CAM1		(S5P_VA_CMU + 0x0C668)
-
-#define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT		(0)
-#define EXYNOS4_CLKDIV_CAM1_JPEG_MASK		(0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT)
-
-#endif /* __DEVFREQ_EXYNOS4_BUS_H */
diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c
deleted file mode 100644
index 297ea30d4159..000000000000
--- a/drivers/devfreq/exynos/exynos5_bus.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * 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/devfreq.h>
-#include <linux/io.h>
-#include <linux/pm_opp.h>
-#include <linux/slab.h>
-#include <linux/suspend.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 <linux/of_address.h>
-#include <linux/of_platform.h>
-
-#include "exynos_ppmu.h"
-
-#define MAX_SAFEVOLT			1100000 /* 1.10V */
-/* Assume that the bus is saturated if the utilization is 25% */
-#define INT_BUS_SATURATION_RATIO	25
-
-enum int_level_idx {
-	LV_0,
-	LV_1,
-	LV_2,
-	LV_3,
-	LV_4,
-	_LV_END
-};
-
-enum exynos_ppmu_list {
-	PPMU_RIGHT,
-	PPMU_END,
-};
-
-struct busfreq_data_int {
-	struct device *dev;
-	struct devfreq *devfreq;
-	struct regulator *vdd_int;
-	struct busfreq_ppmu_data ppmu_data;
-	unsigned long curr_freq;
-	bool disabled;
-
-	struct notifier_block pm_notifier;
-	struct mutex lock;
-	struct pm_qos_request int_req;
-	struct clk *int_clk;
-};
-
-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 dev_pm_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 = dev_pm_opp_get_freq(opp);
-	volt = dev_pm_opp_get_voltage(opp);
-	rcu_read_unlock();
-
-	old_freq = data->curr_freq;
-
-	if (old_freq == freq)
-		return 0;
-
-	dev_dbg(dev, "targeting %lukHz %luuV\n", freq, volt);
-
-	mutex_lock(&data->lock);
-
-	if (data->disabled)
-		goto out;
-
-	if (freq > exynos5_int_opp_table[0].clk)
-		pm_qos_update_request(&data->int_req, freq * 16 / 1000);
-	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);
-	struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
-	int busier_dmc;
-
-	exynos_read_ppmu(ppmu_data);
-	busier_dmc = exynos_get_busier_ppmu(ppmu_data);
-
-	stat->current_frequency = data->curr_freq;
-
-	/* Number of cycles spent on memory access */
-	stat->busy_time = ppmu_data->ppmu[busier_dmc].count[PPMU_PMNCNT3];
-	stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO;
-	stat->total_time = ppmu_data->ppmu[busier_dmc].ccnt;
-
-	return 0;
-}
-
-static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
-	.initial_freq		= 160000,
-	.polling_ms		= 100,
-	.target			= exynos5_busfreq_int_target,
-	.get_dev_status		= exynos5_int_get_dev_status,
-};
-
-static int exynos5250_init_int_tables(struct busfreq_data_int *data)
-{
-	int i, err = 0;
-
-	for (i = LV_0; i < _LV_END; i++) {
-		err = dev_pm_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 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 dev_pm_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 = dev_pm_opp_find_freq_floor(data->dev, &maxfreq);
-		if (IS_ERR(opp)) {
-			rcu_read_unlock();
-			err = PTR_ERR(opp);
-			goto unlock;
-		}
-		freq = dev_pm_opp_get_freq(opp);
-		volt = dev_pm_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 int exynos5_busfreq_int_probe(struct platform_device *pdev)
-{
-	struct busfreq_data_int *data;
-	struct busfreq_ppmu_data *ppmu_data;
-	struct dev_pm_opp *opp;
-	struct device *dev = &pdev->dev;
-	struct device_node *np;
-	unsigned long initial_freq;
-	unsigned long initial_volt;
-	int err = 0;
-	int i;
-
-	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
-				GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(dev, "Cannot allocate memory.\n");
-		return -ENOMEM;
-	}
-
-	ppmu_data = &data->ppmu_data;
-	ppmu_data->ppmu_end = PPMU_END;
-	ppmu_data->ppmu = devm_kzalloc(dev,
-				       sizeof(struct exynos_ppmu) * PPMU_END,
-				       GFP_KERNEL);
-	if (!ppmu_data->ppmu) {
-		dev_err(dev, "Failed to allocate memory for exynos_ppmu\n");
-		return -ENOMEM;
-	}
-
-	np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu");
-	if (np == NULL) {
-		pr_err("Unable to find PPMU node\n");
-		return -ENOENT;
-	}
-
-	for (i = 0; i < ppmu_data->ppmu_end; i++) {
-		/* map PPMU memory region */
-		ppmu_data->ppmu[i].hw_base = of_iomap(np, i);
-		if (ppmu_data->ppmu[i].hw_base == NULL) {
-			dev_err(&pdev->dev, "failed to map memory region\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)
-		return err;
-
-	data->vdd_int = devm_regulator_get(dev, "vdd_int");
-	if (IS_ERR(data->vdd_int)) {
-		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
-		return PTR_ERR(data->vdd_int);
-	}
-
-	data->int_clk = devm_clk_get(dev, "int_clk");
-	if (IS_ERR(data->int_clk)) {
-		dev_err(dev, "Cannot get clock \"int_clk\"\n");
-		return PTR_ERR(data->int_clk);
-	}
-
-	rcu_read_lock();
-	opp = dev_pm_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);
-		return PTR_ERR(opp);
-	}
-	initial_freq = dev_pm_opp_get_freq(opp);
-	initial_volt = dev_pm_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");
-		return err;
-	}
-
-	err = exynos5_int_setvolt(data, initial_volt);
-	if (err)
-		return err;
-
-	platform_set_drvdata(pdev, data);
-
-	busfreq_mon_reset(ppmu_data);
-
-	data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile,
-					   "simple_ondemand", NULL);
-	if (IS_ERR(data->devfreq))
-		return PTR_ERR(data->devfreq);
-
-	err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
-	if (err < 0) {
-		dev_err(dev, "Failed to register opp notifier\n");
-		return err;
-	}
-
-	err = register_pm_notifier(&data->pm_notifier);
-	if (err) {
-		dev_err(dev, "Failed to setup pm notifier\n");
-		return err;
-	}
-
-	/* TODO: Add a new QOS class for int/mif bus */
-	pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
-
-	return 0;
-}
-
-static 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);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-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);
-	struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
-
-	busfreq_mon_reset(ppmu_data);
-	return 0;
-}
-static const struct dev_pm_ops exynos5_busfreq_int_pm = {
-	.resume	= exynos5_busfreq_int_resume,
-};
-#endif
-static SIMPLE_DEV_PM_OPS(exynos5_busfreq_int_pm_ops, NULL,
-			 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		= exynos5_busfreq_int_remove,
-	.driver		= {
-		.name		= "exynos5-bus-int",
-		.pm		= &exynos5_busfreq_int_pm_ops,
-	},
-};
-
-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(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");
diff --git a/drivers/devfreq/exynos/exynos_ppmu.c b/drivers/devfreq/exynos/exynos_ppmu.c
deleted file mode 100644
index 97b75e513d29..000000000000
--- a/drivers/devfreq/exynos/exynos_ppmu.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 "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;
-}
-
-void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data)
-{
-	unsigned int i;
-
-	for (i = 0; i < ppmu_data->ppmu_end; i++) {
-		void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
-
-		/* Reset the performance and cycle counters */
-		exynos_ppmu_reset(ppmu_base);
-
-		/* Setup count registers to monitor read/write transactions */
-		ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
-		exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
-					ppmu_data->ppmu[i].event[PPMU_PMNCNT3]);
-
-		exynos_ppmu_start(ppmu_base);
-	}
-}
-EXPORT_SYMBOL(busfreq_mon_reset);
-
-void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data)
-{
-	int i, j;
-
-	for (i = 0; i < ppmu_data->ppmu_end; i++) {
-		void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
-
-		exynos_ppmu_stop(ppmu_base);
-
-		/* Update local data from PPMU */
-		ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
-
-		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
-			if (ppmu_data->ppmu[i].event[j] == 0)
-				ppmu_data->ppmu[i].count[j] = 0;
-			else
-				ppmu_data->ppmu[i].count[j] =
-					exynos_ppmu_read(ppmu_base, j);
-		}
-	}
-
-	busfreq_mon_reset(ppmu_data);
-}
-EXPORT_SYMBOL(exynos_read_ppmu);
-
-int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data)
-{
-	unsigned int count = 0;
-	int i, j, busy = 0;
-
-	for (i = 0; i < ppmu_data->ppmu_end; i++) {
-		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
-			if (ppmu_data->ppmu[i].count[j] > count) {
-				count = ppmu_data->ppmu[i].count[j];
-				busy = i;
-			}
-		}
-	}
-
-	return busy;
-}
-EXPORT_SYMBOL(exynos_get_busier_ppmu);
diff --git a/drivers/devfreq/exynos/exynos_ppmu.h b/drivers/devfreq/exynos/exynos_ppmu.h
deleted file mode 100644
index 71f17ba3563c..000000000000
--- a/drivers/devfreq/exynos/exynos_ppmu.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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];
-};
-
-struct busfreq_ppmu_data {
-	struct exynos_ppmu *ppmu;
-	int ppmu_end;
-};
-
-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);
-void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data);
-void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data);
-int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data);
-#endif /* __DEVFREQ_EXYNOS_PPMU_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 12/20] MAINTAINERS: Add samsung bus frequency driver entry
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (10 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 11/20] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 13/20] ARM: dts: Add bus nodes using VDD_INT for Exynos3250 Chanwoo Choi
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the 'SAMSUNG BUS FREQUENCY DRIVER' entry to review the
patches as supporter. Patches will be picked up by DEVFREQ maintainer
on devfreq git repository.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ff2d20173d98..89e645688a3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3434,6 +3434,15 @@ F:	drivers/devfreq/devfreq-event.c
 F:	include/linux/devfreq-event.h
 F:	Documentation/devicetree/bindings/devfreq/event/
 
+SAMSUNG BUS FREQUENCY DRIVER
+M:	Chanwoo Choi <cw00.choi@samsung.com>
+L:	linux-pm@vger.kernel.org
+L:	linux-samsung-soc@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
+S:	Supported
+F:	drivers/devfreq/exynos/exynos-bus.c
+F:	Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+
 DEVICE NUMBER REGISTRY
 M:	Torben Mathiasen <device@lanana.org>
 W:	http://lanana.org/docs/device-list/index.html
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 13/20] ARM: dts: Add bus nodes using VDD_INT for Exynos3250
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (11 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 12/20] MAINTAINERS: Add samsung bus frequency driver entry Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 14/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 Chanwoo Choi
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the bus nodes using VDD_INT for Exynos3250 SoC.
Exynos3250 has following AXI buses to translate data between
DRAM and sub-blocks.

Following list specifies the detailed relation between DRAM and sub-blocks:
- ACLK400 clock for MCUISP
- ACLK266 clock for ISP
- ACLK200 clock for FSYS
- ACLK160 clock for LCD0
- ACLK100 clock for PERIL
- GDL clock for LEFTBUS
- GDR clock for RIGHTBUS
- SCLK_MFC clock for MFC

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250.dtsi | 147 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 262b3b1995fd..5cc98cf13173 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -735,6 +735,153 @@
 				opp-microvolt = <875000>;
 			};
 		};
+
+		bus_leftbus: bus_leftbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_GDL>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_rightbus: bus_rightbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_GDR>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_lcd0: bus_lcd0 {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_ACLK_160>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_fsys: bus_fsys {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_ACLK_200>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_mcuisp: bus_mcuisp {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_ACLK_400_MCUISP>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_mcuisp_opp_table>;
+			status = "disabled";
+		};
+
+		bus_isp: bus_isp {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_ACLK_266>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_isp_opp_table>;
+			status = "disabled";
+		};
+
+		bus_peril: bus_peril {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_DIV_ACLK_100>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_peril_opp_table>;
+			status = "disabled";
+		};
+
+		bus_mfc: bus_mfc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&cmu CLK_SCLK_MFC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_leftbus_opp_table: opp_table2 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp@50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+				opp-microvolt = <900000>;
+			};
+			opp@80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				opp-microvolt = <900000>;
+			};
+			opp@100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				opp-microvolt = <1000000>;
+			};
+			opp@134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+				opp-microvolt = <1000000>;
+			};
+			opp@200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				opp-microvolt = <1000000>;
+			};
+		};
+
+		bus_mcuisp_opp_table: opp_table3 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp@50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+			};
+			opp@80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+			};
+			opp@100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp@200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
+			opp@400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+			};
+		};
+
+		bus_isp_opp_table: opp_table4 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp@50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+			};
+			opp@80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+			};
+			opp@100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp@200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
+			opp@300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+			};
+		};
+
+		bus_peril_opp_table: opp_table5 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp@50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+			};
+			opp@80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+			};
+			opp@100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+		};
 	};
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 14/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (12 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 13/20] ARM: dts: Add bus nodes using VDD_INT for Exynos3250 Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 15/20] ARM: dts: Add bus nodes using VDD_INT " Chanwoo Choi
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the bus nodes using VDD_MIF for Exynos4x12 SoC.
Exynos4x12 has the following AXI buses to translate data
between DRAM and DMC/ACP/C2C.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos4x12.dtsi | 68 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 84a23f962946..99a0f4ca3d47 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -281,6 +281,74 @@
 		clocks = <&clock CLK_SMMU_LITE1>, <&clock CLK_FIMC_LITE1>;
 		#iommu-cells = <0>;
 	};
+
+	bus_dmc: bus_dmc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_DMC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_dmc_opp_table>;
+		status = "disabled";
+	};
+
+	bus_acp: bus_acp {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_ACP>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_acp_opp_table>;
+		status = "disabled";
+	};
+
+	bus_c2c: bus_c2c {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_C2C>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_dmc_opp_table>;
+		status = "disabled";
+	};
+
+	bus_dmc_opp_table: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@267000000 {
+			opp-hz = /bits/ 64 <267000000>;
+			opp-microvolt = <950000>;
+		};
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1050000>;
+		};
+	};
+
+	bus_acp_opp_table: opp_table2 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+		};
+		opp@267000000 {
+			opp-hz = /bits/ 64 <267000000>;
+		};
+	};
 };
 
 &combiner {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 15/20] ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (13 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 14/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 16/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210 Chanwoo Choi
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the bus nodes using VDD_INT for Exynos4x12 SoC.
Exynos4x12 has the following AXI buses to translate data between
DRAM and sub-blocks.

Following list specifies the detailed relation between DRAM and sub-blocks:
- ACLK100 clock for PERIL/PERIR/MFC(PCLK)
- ACLK160 clock for CAM/TV/LCD
: The minimum clock of ACLK160 should be over 160MHz.
  When drop the clock under 160MHz, show the broken image.
- ACLK133 clock for FSYS
- GDL clock for LEFTBUS
- GDR clock for RIGHTBUS
- SCLK_MFC clock for MFC

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos4x12.dtsi | 106 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 99a0f4ca3d47..e5173107ed44 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -349,6 +349,112 @@
 			opp-hz = /bits/ 64 <267000000>;
 		};
 	};
+
+	bus_leftbus: bus_leftbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_GDL>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_rightbus: bus_rightbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_GDR>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_display: bus_display {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK160>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_display_opp_table>;
+		status = "disabled";
+	};
+
+	bus_fsys: bus_fsys {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK133>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_fsys_opp_table>;
+		status = "disabled";
+	};
+
+	bus_peri: bus_peri {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK100>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_peri_opp_table>;
+		status = "disabled";
+	};
+
+	bus_mfc: bus_mfc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_SCLK_MFC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_leftbus_opp_table: opp_table3 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <900000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+			opp-microvolt = <925000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+			opp-microvolt = <950000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <1000000>;
+		};
+	};
+
+	bus_display_opp_table: opp_table4 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+	};
+
+	bus_fsys_opp_table: opp_table5 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+		};
+	};
+
+	bus_peri_opp_table: opp_table6 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+	};
 };
 
 &combiner {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 16/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (14 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 15/20] ARM: dts: Add bus nodes using VDD_INT " Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 17/20] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes Chanwoo Choi
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the bus nodes for Exynos4210 SoC. Exynos4210 SoC has
one power line for all buses to translate data between DRAM and sub-blocks.

Following list specifies the detailed relation between DRAM and sub-blocks:
- DMC/ACP clock for DMC (Dynamic Memory Controller)
- ACLK200 clock for LCD0
- ACLK100 clock for PERIL/PERIR/MFC(PCLK)
- ACLK160 clock for CAM/TV/LCD0/LCD1
- ACLK133 clock for FSYS/GPS
- GDL/GDR clock for LEFTBUS/RIGHTBUS
- SCLK_MFC clock for MFC

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos4210.dtsi | 159 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index c1cb8df6da07..2d9b02967105 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -257,6 +257,165 @@
 		power-domains = <&pd_lcd1>;
 		#iommu-cells = <0>;
 	};
+
+	bus_dmc: bus_dmc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_DMC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_dmc_opp_table>;
+		status = "disabled";
+	};
+
+	bus_acp: bus_acp {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_ACP>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_acp_opp_table>;
+		status = "disabled";
+	};
+
+	bus_peri: bus_peri {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK100>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_peri_opp_table>;
+		status = "disabled";
+	};
+
+	bus_fsys: bus_fsys {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK133>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_fsys_opp_table>;
+		status = "disabled";
+	};
+
+	bus_display: bus_display {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK160>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_display_opp_table>;
+		status = "disabled";
+	};
+
+	bus_lcd0: bus_lcd0 {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_ACLK200>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_leftbus: bus_leftbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_GDL>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_rightbus: bus_rightbus {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_DIV_GDR>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_mfc: bus_mfc {
+		compatible = "samsung,exynos-bus";
+		clocks = <&clock CLK_SCLK_MFC>;
+		clock-names = "bus";
+		operating-points-v2 = <&bus_leftbus_opp_table>;
+		status = "disabled";
+	};
+
+	bus_dmc_opp_table: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+			opp-microvolt = <1025000>;
+		};
+		opp@267000000 {
+			opp-hz = /bits/ 64 <267000000>;
+			opp-microvolt = <1050000>;
+		};
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1150000>;
+		};
+	};
+
+	bus_acp_opp_table: opp_table2 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+	};
+
+	bus_peri_opp_table: opp_table3 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@5000000 {
+			opp-hz = /bits/ 64 <5000000>;
+		};
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+	};
+
+	bus_fsys_opp_table: opp_table4 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@10000000 {
+			opp-hz = /bits/ 64 <10000000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+		};
+	};
+
+	bus_display_opp_table: opp_table5 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@134000000 {
+			opp-hz = /bits/ 64 <134000000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+		};
+	};
+
+	bus_leftbus_opp_table: opp_table6 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+		opp@160000000 {
+			opp-hz = /bits/ 64 <160000000>;
+		};
+		opp@200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+	};
 };
 
 &gic {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 17/20] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (15 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 16/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210 Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 18/20] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato Chanwoo Choi
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the exynos4412-ppmu-common.dtsi to remove duplicate PPMU nodes
because exynos3250-rinato/monk, exynos4412-trats2/odroidu3 has the same
PPMU device tree node.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250-monk.dts           | 41 +-------------------
 arch/arm/boot/dts/exynos3250-rinato.dts         | 41 +-------------------
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  1 +
 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi   | 50 +++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4412-trats2.dts         | 41 +-------------------
 5 files changed, 54 insertions(+), 120 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi

diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 456844a81189..a4e525e5e6e4 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -14,6 +14,7 @@
 
 /dts-v1/;
 #include "exynos3250.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/samsung,s2mps11.h>
@@ -464,46 +465,6 @@
 	status = "okay";
 };
 
-&ppmu_dmc0 {
-	status = "okay";
-
-	events {
-		ppmu_dmc0_3: ppmu-event3-dmc0 {
-			event-name = "ppmu-event3-dmc0";
-		};
-	};
-};
-
-&ppmu_dmc1 {
-	status = "okay";
-
-	events {
-		ppmu_dmc1_3: ppmu-event3-dmc1 {
-			event-name = "ppmu-event3-dmc1";
-		};
-	};
-};
-
-&ppmu_leftbus {
-	status = "okay";
-
-	events {
-		ppmu_leftbus_3: ppmu-event3-leftbus {
-			event-name = "ppmu-event3-leftbus";
-		};
-	};
-};
-
-&ppmu_rightbus {
-	status = "okay";
-
-	events {
-		ppmu_rightbus_3: ppmu-event3-rightbus {
-			event-name = "ppmu-event3-rightbus";
-		};
-	};
-};
-
 &xusbxti {
 	clock-frequency = <24000000>;
 };
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index d6bb990ce931..2a1c22598fdc 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -14,6 +14,7 @@
 
 /dts-v1/;
 #include "exynos3250.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/samsung,s2mps11.h>
@@ -641,46 +642,6 @@
 	status = "okay";
 };
 
-&ppmu_dmc0 {
-	status = "okay";
-
-	events {
-		ppmu_dmc0_3: ppmu-event3-dmc0 {
-			event-name = "ppmu-event3-dmc0";
-		};
-	};
-};
-
-&ppmu_dmc1 {
-	status = "okay";
-
-	events {
-		ppmu_dmc1_3: ppmu-event3-dmc1 {
-			event-name = "ppmu-event3-dmc1";
-		};
-	};
-};
-
-&ppmu_leftbus {
-	status = "okay";
-
-	events {
-		ppmu_leftbus_3: ppmu-event3-leftbus {
-			event-name = "ppmu-event3-leftbus";
-		};
-	};
-};
-
-&ppmu_rightbus {
-	status = "okay";
-
-	events {
-		ppmu_rightbus_3: ppmu-event3-rightbus {
-			event-name = "ppmu-event3-rightbus";
-		};
-	};
-};
-
 &xusbxti {
 	clock-frequency = <24000000>;
 };
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 395c3ca9601e..cda1ec86dfba 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/clock/maxim,max77686.h>
 #include "exynos4412.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
diff --git a/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi
new file mode 100644
index 000000000000..16e4b77d8cb1
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi
@@ -0,0 +1,50 @@
+/*
+ * Device tree sources for Exynos4412 PPMU common device tree
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ * Author: Chanwoo Choi <cw00.choi@samsung.com>
+ *
+ * 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.
+ */
+
+&ppmu_dmc0 {
+       status = "okay";
+
+       events {
+	       ppmu_dmc0_3: ppmu-event3-dmc0 {
+		       event-name = "ppmu-event3-dmc0";
+	       };
+       };
+};
+
+&ppmu_dmc1 {
+       status = "okay";
+
+       events {
+	       ppmu_dmc1_3: ppmu-event3-dmc1 {
+		       event-name = "ppmu-event3-dmc1";
+	       };
+       };
+};
+
+&ppmu_leftbus {
+       status = "okay";
+
+       events {
+	       ppmu_leftbus_3: ppmu-event3-leftbus {
+		       event-name = "ppmu-event3-leftbus";
+	       };
+       };
+};
+
+&ppmu_rightbus {
+       status = "okay";
+
+       events {
+	       ppmu_rightbus_3: ppmu-event3-rightbus {
+		       event-name = "ppmu-event3-rightbus";
+	       };
+       };
+};
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index a6f78c3da935..92438eb6eec6 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -14,6 +14,7 @@
 
 /dts-v1/;
 #include "exynos4412.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/maxim,max77686.h>
@@ -871,46 +872,6 @@
 	assigned-clock-parents =  <&clock CLK_XUSBXTI>;
 };
 
-&ppmu_dmc0 {
-	status = "okay";
-
-	events {
-		ppmu_dmc0_3: ppmu-event3-dmc0 {
-			event-name = "ppmu-event3-dmc0";
-		};
-	};
-};
-
-&ppmu_dmc1 {
-	status = "okay";
-
-	events {
-		ppmu_dmc1_3: ppmu-event3-dmc1 {
-			event-name = "ppmu-event3-dmc1";
-		};
-	};
-};
-
-&ppmu_leftbus {
-	status = "okay";
-
-	events {
-		ppmu_leftbus_3: ppmu-event3-leftbus {
-			event-name = "ppmu-event3-leftbus";
-		};
-	};
-};
-
-&ppmu_rightbus {
-	status = "okay";
-
-	events {
-		ppmu_rightbus_3: ppmu-event3-rightbus {
-			event-name = "ppmu-event3-rightbus";
-		};
-	};
-};
-
 &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep0>;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 18/20] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (16 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 17/20] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 19/20] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3 Chanwoo Choi
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch adds the bus device-tree nodes of INT (internal) block
to enable the bus frequency scaling. The following sub-blocks share
the VDD_INT power source:
- LEFTBUS (parent device)
- RIGHTBUS
- PERIL
- LCD0
- FSYS
- MCUISP / ISP
- MFC

The LEFTBUS is parent device with devfreq ondemand governor
and the rest of devices depend on the LEFTBUS device.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 arch/arm/boot/dts/exynos3250-rinato.dts | 41 +++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 2a1c22598fdc..c29d5533ec1f 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -154,6 +154,47 @@
 	status = "okay";
 };
 
+&bus_leftbus {
+	devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+	vdd-supply = <&buck3_reg>;
+	status = "okay";
+};
+
+&bus_rightbus {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_lcd0 {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_fsys {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_mcuisp {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_isp {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_peril {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_mfc {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 19/20] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (17 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 18/20] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-14  6:38 ` [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3 Chanwoo Choi
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

This patch expands the voltage range of buck1/3 regulator due to as following:
- MIF (Memory Interface) bus frequency needs the range of '900 - 1050 mV'.
- INT (Internal) bus frequency needs the range of '900 - 1000 mV'.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index cda1ec86dfba..7bd65026761e 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -356,8 +356,8 @@
 
 			buck1_reg: BUCK1 {
 				regulator-name = "vdd_mif";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <1050000>;
 				regulator-always-on;
 				regulator-boot-on;
 			};
@@ -372,7 +372,7 @@
 
 			buck3_reg: BUCK3 {
 				regulator-name = "vdd_int";
-				regulator-min-microvolt = <1000000>;
+				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1000000>;
 				regulator-always-on;
 				regulator-boot-on;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (18 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 19/20] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3 Chanwoo Choi
@ 2015-12-14  6:38 ` Chanwoo Choi
  2015-12-15  0:34   ` Krzysztof Kozlowski
  2016-01-19  9:13 ` [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Tobias Jakobi
  2016-02-19 15:05 ` Tobias Jakobi
  21 siblings, 1 reply; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  6:38 UTC (permalink / raw)
  To: myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, cw00.choi, linux-kernel,
	linux-pm, linux-samsung-soc, devicetree

THis patch adds the bus device tree nodes for both MIF (Memory) and INT
(Internal) block to enable the bus frequency.

The DMC bus is parent device in MIF block using VDD_MIF and the LEFTBUS
bus is parent device in INT block using VDD_INT.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[linux.amoon: Tested on Odroid U3]
Tested-by: Anand Moon <linux.amoon@gmail.com>
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 47 +++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4412-trats2.dts         | 47 +++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 7bd65026761e..cb7e54df6a23 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -109,6 +109,53 @@
 	};
 };
 
+&bus_dmc {
+	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+	vdd-supply = <&buck1_reg>;
+	status = "okay";
+};
+
+&bus_acp {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_c2c {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_leftbus {
+	devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+	vdd-supply = <&buck3_reg>;
+	status = "okay";
+};
+
+&bus_rightbus {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_display {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_fsys {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_peri {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_mfc {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 92438eb6eec6..9f33c651e37a 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -289,6 +289,53 @@
 	status = "okay";
 };
 
+&bus_dmc {
+	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+	vdd-supply = <&buck1_reg>;
+	status = "okay";
+};
+
+&bus_acp {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_c2c {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_leftbus {
+	devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+	vdd-supply = <&buck3_reg>;
+	status = "okay";
+};
+
+&bus_rightbus {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_display {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_fsys {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_peri {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_mfc {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
  2015-12-14  6:38 ` [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3 Chanwoo Choi
@ 2015-12-15  0:34   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 33+ messages in thread
From: Krzysztof Kozlowski @ 2015-12-15  0:34 UTC (permalink / raw)
  To: Chanwoo Choi, myungjoo.ham, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

On 14.12.2015 15:38, Chanwoo Choi wrote:
> THis patch adds the bus device tree nodes for both MIF (Memory) and INT
> (Internal) block to enable the bus frequency.
> 
> The DMC bus is parent device in MIF block using VDD_MIF and the LEFTBUS
> bus is parent device in INT block using VDD_INT.
> 
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> [linux.amoon: Tested on Odroid U3]
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> ---
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 47 +++++++++++++++++++++++++
>  arch/arm/boot/dts/exynos4412-trats2.dts         | 47 +++++++++++++++++++++++++
>  2 files changed, 94 insertions(+)
> 

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-14  6:38 ` [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver Chanwoo Choi
@ 2015-12-15  3:41   ` Krzysztof Kozlowski
  2015-12-18  0:34     ` Chanwoo Choi
  0 siblings, 1 reply; 33+ messages in thread
From: Krzysztof Kozlowski @ 2015-12-15  3:41 UTC (permalink / raw)
  To: Chanwoo Choi, myungjoo.ham, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

On 14.12.2015 15:38, Chanwoo Choi wrote:
> This patch adds the generic exynos bus frequency driver for AMBA AXI bus
> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
> have the common architecture for bus between DRAM and sub-blocks in SoC.
> This driver can support the generic bus frequency driver for Exynos SoCs.
> 
> In devicetree, Each bus block has a bus clock, regulator, operation-point
> and devfreq-event devices which measure the utilization of each bus block.
> 
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> [linux.amoon: Tested on Odroid U3]
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> ---
>  drivers/devfreq/Kconfig             |  15 ++
>  drivers/devfreq/Makefile            |   1 +
>  drivers/devfreq/exynos/Makefile     |   1 +
>  drivers/devfreq/exynos/exynos-bus.c | 449 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 466 insertions(+)
>  create mode 100644 drivers/devfreq/exynos/exynos-bus.c
> 
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 64281bb2f650..55ec774f794c 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE
>  
>  comment "DEVFREQ Drivers"
>  
> +config ARM_EXYNOS_BUS_DEVFREQ
> +	bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver"
> +	depends on ARCH_EXYNOS
> +	select DEVFREQ_GOV_SIMPLE_ONDEMAND
> +	select DEVFREQ_EVENT_EXYNOS_PPMU
> +	select PM_DEVFREQ_EVENT
> +	select PM_OPP
> +	help
> +	  This adds the common DEVFREQ driver for Exynos Memory bus. Exynos
> +	  Memory bus has one more group of memory bus (e.g, MIF and INT block).
> +	  Each memory bus group could contain many memoby bus block. It reads
> +	  PPMU counters of memory controllers by using DEVFREQ-event device
> +	  and adjusts the operating frequencies and voltages with OPP support.
> +	  This does not yet operate with optimal voltages.
> +
>  config ARM_EXYNOS4_BUS_DEVFREQ
>  	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
>  	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
> index 5134f9ee983d..375ebbb4fcfb 100644
> --- a/drivers/devfreq/Makefile
> +++ b/drivers/devfreq/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>  
>  # DEVFREQ Drivers
> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/

Why limiting it to ARCH_EXYNOS? Are there real dependencies on exynos
mach code? Or on ARM code?

If not, then this probably should be obj-y to allow compile testing.
Particular objects would be selected by ARM_EXYNOS_BUS_DEVFREQ.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-15  3:41   ` Krzysztof Kozlowski
@ 2015-12-18  0:34     ` Chanwoo Choi
  2015-12-18  0:43       ` Chanwoo Choi
  0 siblings, 1 reply; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-18  0:34 UTC (permalink / raw)
  To: Krzysztof Kozlowski, myungjoo.ham, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

Hi,

On 2015년 12월 15일 12:41, Krzysztof Kozlowski wrote:
> On 14.12.2015 15:38, Chanwoo Choi wrote:
>> This patch adds the generic exynos bus frequency driver for AMBA AXI bus
>> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
>> have the common architecture for bus between DRAM and sub-blocks in SoC.
>> This driver can support the generic bus frequency driver for Exynos SoCs.
>>
>> In devicetree, Each bus block has a bus clock, regulator, operation-point
>> and devfreq-event devices which measure the utilization of each bus block.
>>
>> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
>> [linux.amoon: Tested on Odroid U3]
>> Tested-by: Anand Moon <linux.amoon@gmail.com>
>> ---
>>  drivers/devfreq/Kconfig             |  15 ++
>>  drivers/devfreq/Makefile            |   1 +
>>  drivers/devfreq/exynos/Makefile     |   1 +
>>  drivers/devfreq/exynos/exynos-bus.c | 449 ++++++++++++++++++++++++++++++++++++
>>  4 files changed, 466 insertions(+)
>>  create mode 100644 drivers/devfreq/exynos/exynos-bus.c
>>
>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>> index 64281bb2f650..55ec774f794c 100644
>> --- a/drivers/devfreq/Kconfig
>> +++ b/drivers/devfreq/Kconfig
>> @@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE
>>  
>>  comment "DEVFREQ Drivers"
>>  
>> +config ARM_EXYNOS_BUS_DEVFREQ
>> +	bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver"
>> +	depends on ARCH_EXYNOS
>> +	select DEVFREQ_GOV_SIMPLE_ONDEMAND
>> +	select DEVFREQ_EVENT_EXYNOS_PPMU
>> +	select PM_DEVFREQ_EVENT
>> +	select PM_OPP
>> +	help
>> +	  This adds the common DEVFREQ driver for Exynos Memory bus. Exynos
>> +	  Memory bus has one more group of memory bus (e.g, MIF and INT block).
>> +	  Each memory bus group could contain many memoby bus block. It reads
>> +	  PPMU counters of memory controllers by using DEVFREQ-event device
>> +	  and adjusts the operating frequencies and voltages with OPP support.
>> +	  This does not yet operate with optimal voltages.
>> +
>>  config ARM_EXYNOS4_BUS_DEVFREQ
>>  	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
>>  	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 5134f9ee983d..375ebbb4fcfb 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>>  
>>  # DEVFREQ Drivers
>> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
> 
> Why limiting it to ARCH_EXYNOS? Are there real dependencies on exynos
> mach code? Or on ARM code?

There is no dependency.

> 
> If not, then this probably should be obj-y to allow compile testing.
> Particular objects would be selected by ARM_EXYNOS_BUS_DEVFREQ.

OK. I'll alter it as obj-y.

Best Regards,
Chanwoo Choi




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-18  0:34     ` Chanwoo Choi
@ 2015-12-18  0:43       ` Chanwoo Choi
  0 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-18  0:43 UTC (permalink / raw)
  To: Krzysztof Kozlowski, myungjoo.ham, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

On 2015년 12월 18일 09:34, Chanwoo Choi wrote:
> Hi,
> 
> On 2015년 12월 15일 12:41, Krzysztof Kozlowski wrote:
>> On 14.12.2015 15:38, Chanwoo Choi wrote:
>>> This patch adds the generic exynos bus frequency driver for AMBA AXI bus
>>> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
>>> have the common architecture for bus between DRAM and sub-blocks in SoC.
>>> This driver can support the generic bus frequency driver for Exynos SoCs.
>>>
>>> In devicetree, Each bus block has a bus clock, regulator, operation-point
>>> and devfreq-event devices which measure the utilization of each bus block.
>>>
>>> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
>>> [linux.amoon: Tested on Odroid U3]
>>> Tested-by: Anand Moon <linux.amoon@gmail.com>
>>> ---
>>>  drivers/devfreq/Kconfig             |  15 ++
>>>  drivers/devfreq/Makefile            |   1 +
>>>  drivers/devfreq/exynos/Makefile     |   1 +
>>>  drivers/devfreq/exynos/exynos-bus.c | 449 ++++++++++++++++++++++++++++++++++++
>>>  4 files changed, 466 insertions(+)
>>>  create mode 100644 drivers/devfreq/exynos/exynos-bus.c
>>>
>>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>>> index 64281bb2f650..55ec774f794c 100644
>>> --- a/drivers/devfreq/Kconfig
>>> +++ b/drivers/devfreq/Kconfig
>>> @@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE
>>>  
>>>  comment "DEVFREQ Drivers"
>>>  
>>> +config ARM_EXYNOS_BUS_DEVFREQ
>>> +	bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver"
>>> +	depends on ARCH_EXYNOS
>>> +	select DEVFREQ_GOV_SIMPLE_ONDEMAND
>>> +	select DEVFREQ_EVENT_EXYNOS_PPMU
>>> +	select PM_DEVFREQ_EVENT
>>> +	select PM_OPP
>>> +	help
>>> +	  This adds the common DEVFREQ driver for Exynos Memory bus. Exynos
>>> +	  Memory bus has one more group of memory bus (e.g, MIF and INT block).
>>> +	  Each memory bus group could contain many memoby bus block. It reads
>>> +	  PPMU counters of memory controllers by using DEVFREQ-event device
>>> +	  and adjusts the operating frequencies and voltages with OPP support.
>>> +	  This does not yet operate with optimal voltages.
>>> +
>>>  config ARM_EXYNOS4_BUS_DEVFREQ
>>>  	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
>>>  	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
>>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>>> index 5134f9ee983d..375ebbb4fcfb 100644
>>> --- a/drivers/devfreq/Makefile
>>> +++ b/drivers/devfreq/Makefile
>>> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>>>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>>>  
>>>  # DEVFREQ Drivers
>>> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
>>
>> Why limiting it to ARCH_EXYNOS? Are there real dependencies on exynos
>> mach code? Or on ARM code?
> 
> There is no dependency.
> 
>>
>> If not, then this probably should be obj-y to allow compile testing.
>> Particular objects would be selected by ARM_EXYNOS_BUS_DEVFREQ.
> 
> OK. I'll alter it as obj-y.

As you commented, CONFIG_ARM_EXYNOS_BUS_DEVFREQ is more appropriate
without exynos/ directory as following:

+obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o

Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (19 preceding siblings ...)
  2015-12-14  6:38 ` [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3 Chanwoo Choi
@ 2016-01-19  9:13 ` Tobias Jakobi
  2016-01-20  1:09   ` Chanwoo Choi
  2016-02-19 15:05 ` Tobias Jakobi
  21 siblings, 1 reply; 33+ messages in thread
From: Tobias Jakobi @ 2016-01-19  9:13 UTC (permalink / raw)
  To: Chanwoo Choi, myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello,

I've tested this on my Odroid-X2 but ran into issues. Patch 08/20
introduces some pr_info() to exynos_bus_probe().

In my case both max_state and freq_table are zero though, so getting
{min,max}_freq triggers an kernel oops. If I just remove the code the
drivers probes correctly.

With best wishes,
Tobias



Chanwoo Choi wrote:
> This patch-set includes the two features as following. The generic
> exynos bus frequency driver is able to support almost Exynos SoCs
> for bus frequency scaling. And the new passive governor is able to
> make the dependency on between devices for frequency/voltage
> scaling. I had posted the patch-set[2] with the similiar concept.
> This is is revised version for exynos bus frequency. - Generic
> exynos bus frequency driver - New passive governor of DEVFREQ
> framework
> 
> Depend on: - next-20151210 tag of linux-next (master branch). -
> Merge the latest devfreq patches on devfreq.git[2] (for-rafael
> branch). [1]
> https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/
> (branch: for-rafael) [2] https://lkml.org/lkml/2015/1/7/872 :
> [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency
> driver
> 
> Changes from v3: (https://lkml.org/lkml/2015/12/11/75) - Add the
> reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) 
> - Fix typo of the description on patch14 - Modify the subject and
> description of patch17 - Reorder the 'bus_xxx' device tree node
> alphabetically in both exynos3250-rinato/monk.dts and
> exynos4412-trats/odroidu3
> 
> Changes from v2: (https://lkml.org/lkml/2015/12/8/869) - Fix typo
> on documentation - Modify the more appropriate sentence on patch
> description - Add the detailed description about both parent and
> passive bus device - Modify the DMC frequency for Exynos4x12 DMC
> bus (200MHz -> 267MHz) - Modify the voltage of 200MHz was included
> in Exynos3250 DMC bus (800mV -> 825mV) - Rename OPP nodes as
> 'opp@<opp-hz>' - Delete the duplicate 'opp-microvolt' property of
> passive devfreq device - Reorder the 'bus_xxx' device tree node
> alphabetically in exynos3250-rinato/monk.dts - Reorder the
> 'bus_xxx' device tree node alphabetically in
> exynos4412-trats/odroidu3 - Add new exynos4412-ppmu-common.dtsi to
> remove the duplicate PPMU dt node on rinato/monk/trats2/odroid-u3
> board - Add the log message if bus device is registered to devfreq
> framework successfully - Add the reviewed-by tag from Krzysztof
> Kozlowski - Add the tested-by tag from Anand Moon on Odroid U3 -
> Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS
> 
> Changes from v1: (https://lkml.org/lkml/2015/11/26/260) - Check
> whether the instance of regulator is NULL or not when executing
> regulator_disable() because of only parent devfreq device has the
> regulator instance. After fixing it, the wake-up from suspend state
> is well working. (patch1) - Fix bug which checks 'bus-clk' instead
> of 'bus->regulator' after calling devm_clk_get() (on patch1) -
> Update the documentation to remove the description about 
> DEVFREQ-EVENT subsystem (on patch2) - Add the full name of DMC
> (Dynamic Memory Controller) (on patch2) - Modify the detailed
> correlation of buses for Exynos3250 on documentation (patch2) - Add
> the MFC bus node for Exynos3250 (on patch11, patch12) - Fix the
> duplicate frequency of bus_display on Exynos4x12.dtsi - Add the
> PPMU node for exynos4412-odroidu3 - Add the support of bus
> frequency for exynos4412-odroidu3
> 
> Detailed descirption for patch-set: 1. Add generic exynos bus
> frequency driver : This patch-set adds the generic exynos bus
> frequency driver for AXI bus of sub-blocks in exynos SoC. The
> Samsung Exynos SoC have the common architecture for bus between
> DRAM and sub-blocks in SoC.
> 
> There are the different buses according to Exynos SoC because
> Exynos SoC has the differnt sub-blocks and bus speed. In spite of
> this difference among Exynos SoCs, this driver is able to support
> almost Exynos SoC by adding unique data of each bus in the
> devicetree file.
> 
> In devicetree, each bus node has a bus clock, regulator,
> operation-point and devfreq-event devices which measure the
> utilization of each bus block.
> 
> For example, - The bus of DMC block in exynos3250.dtsi are listed
> below:
> 
> bus_dmc: bus_dmc { compatible = "samsung,exynos-bus"; clocks =
> <&cmu_dmc CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 =
> <&bus_dmc_opp_table>; status = "disabled"; };
> 
> bus_dmc_opp_table: opp_table1 { compatible =
> "operating-points-v2"; opp-shared;
> 
> opp@50000000 { opp-hz = /bits/ 64 <50000000>; opp-microvolt =
> <800000>; }; opp@100000000 { opp-hz = /bits/ 64 <100000000>; 
> opp-microvolt = <800000>; }; opp@134000000 { opp-hz = /bits/ 64
> <134000000>; opp-microvolt = <800000>; }; opp@200000000 { opp-hz =
> /bits/ 64 <200000000>; opp-microvolt = <825000>; }; opp@400000000
> { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <875000>; }; };
> 
> - Usage case to handle the frequency and voltage of bus on runtime 
> in exynos3250-rinato.dts are listed below:
> 
> &bus_dmc { devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>; 
> vdd-supply = <&buck1_reg>;	/* VDD_MIF */ status = "okay"; };
> 
> 2. Add new passive governor of DEVFREQ framework (patch5-patch7) :
> This patch-set add the new passive governor for DEVFREQ framework. 
> The existing governors (ondemand, performance and so on) are used
> for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The
> existing governors are independently used for specific device
> driver which don't give the influence to other device drviers and
> also don't receive the effect from other device drivers.
> 
> The passive governor depends on operation of parent driver with
> existing governors(ondemand, performance and so on) extremely and
> is not able to decide the new frequency by oneself. According to
> the decided new frequency of parent driver with governor, the
> passive governor uses it to decide the appropriate frequency for
> own device driver. The passive governor must need the following
> information from device tree:
> 
> For exameple, There are one more bus device drivers in Exynos3250
> which need to change their source clock according to their
> utilization on runtime. But, they share the same power line (e.g.,
> regulator). So, LEFTBUS bus driver is operated as parent with
> ondemand governor and then the rest device driver with passive
> governor.
> 
> The buses of Internal block in exynos3250.dtsi are listed below: 
> When LEFTBUS bus driver (parent) changes the bus frequency with 
> ondemand governor on runtime, the rest bus devices which sharing 
> the same power line (VDD_INT) will change the each bus frequency 
> according to the decision of LEFTBUS bus driver (parent).
> 
> - INT (Internal) block : VDD_INT |--- LEFTBUS |--- PERIL |--- MFC 
> |--- G3D |--- RIGHTBUS |--- FSYS |--- LCD0 |--- PERIR |--- ISP |---
> CAM
> 
> - The buss of INT block in exynos3250.dtsi are listed below: 
> bus_leftbus: bus_leftbus { compatible = "samsung,exynos-bus"; 
> clocks = <&cmu CLK_DIV_GDL>; clock-names = "bus"; 
> operating-points-v2 = <&bus_leftbus_opp_table>; status =
> "disabled"; };
> 
> bus_rightbus: bus_rightbus { compatible = "samsung,exynos-bus"; 
> clocks = <&cmu CLK_DIV_GDR>; clock-names = "bus"; 
> operating-points-v2 = <&bus_leftbus_opp_table>; status =
> "disabled"; };
> 
> (Omit the rest bus dt node)
> 
> - Usage case to handle the frequency and voltage of bus on runtime 
> in exynos3250-rinato.dts are listed below: /* Parent bus device of
> VDD_INT */ &bus_leftbus { devfreq-events = <&ppmu_leftbus_3>,
> <&ppmu_rightbus_3>; vdd-supply = <&buck3_reg>; status = "okay"; };
> 
> /* Passive bus device depend on LEFTBUS bus. */ &bus_rightbus { 
> devfreq = <&bus_leftbus>; /* 'devfreq' property indicates the
> phandle of parent device. */ status = "okay"; };
> 
> (Omit the rest bus dt node)
> 
> Chanwoo Choi (20): PM / devfreq: exynos: Add generic exynos bus
> frequency driver PM / devfreq: exynos: Add documentation for
> generic exynos bus frequency driver ARM: dts: Add DMC bus node for
> Exynos3250 ARM: dts: Add DMC bus frequency for
> exynos3250-rinato/monk PM / devfreq: Add new passive governor PM /
> devfreq: Add devfreq_get_devfreq_by_phandle() PM / devfreq: Show
> the related information according to governor type PM / devfreq:
> exynos: Add support of bus frequency of sub-blocks using passive
> governor PM / devfreq: exynos: Update documentation for bus devices
> using passive governor PM / devfreq: exynos: Add the detailed
> correlation between sub-blocks and power line PM / devfreq: exynos:
> Remove unused exynos4/5 busfreq driver MAINTAINERS: Add samsung bus
> frequency driver entry ARM: dts: Add bus nodes using VDD_INT for
> Exynos3250 ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 
> ARM: dts: Add bus nodes using VDD_INT for Exynos4x12 ARM: dts: Add
> bus nodes using VDD_MIF for Exynos4210 ARM: dts: Add
> exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes ARM:
> dts: Add support of bus frequency using VDD_INT for
> exynos3250-rinato ARM: dts: Expand the voltage range of buck1/3
> regulator for exynos4412-odroidu3 ARM: dts: Add support of bus
> frequency for exynos4412-trats/odroidu3
> 
> .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++ 
> MAINTAINERS                                        |    9 + 
> arch/arm/boot/dts/exynos3250-monk.dts              |   47 +- 
> arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +- 
> arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++ 
> arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++ 
> arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +- 
> arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 + 
> arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +- 
> arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++ 
> drivers/devfreq/Kconfig                            |   37 +- 
> drivers/devfreq/Makefile                           |    2 + 
> drivers/devfreq/devfreq.c                          |  120 ++- 
> drivers/devfreq/exynos/Makefile                    |    3 +- 
> drivers/devfreq/exynos/exynos-bus.c                |  556
> +++++++++++ drivers/devfreq/exynos/exynos4_bus.c               |
> 1055 -------------------- drivers/devfreq/exynos/exynos4_bus.h
> |  110 -- drivers/devfreq/exynos/exynos5_bus.c               |  431
> -------- drivers/devfreq/exynos/exynos_ppmu.c               |  119
> --- drivers/devfreq/exynos/exynos_ppmu.h               |   86 -- 
> drivers/devfreq/governor.h                         |    7 + 
> drivers/devfreq/governor_passive.c                 |  109 ++ 
> drivers/devfreq/governor_performance.c             |    1 + 
> drivers/devfreq/governor_powersave.c               |    1 + 
> drivers/devfreq/governor_simpleondemand.c          |    1 + 
> drivers/devfreq/governor_userspace.c               |    1 + 
> include/linux/devfreq.h                            |   26 + 27
> files changed, 1955 insertions(+), 1948 deletions(-) create mode
> 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt 
> create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi 
> create mode 100644 drivers/devfreq/exynos/exynos-bus.c delete mode
> 100644 drivers/devfreq/exynos/exynos4_bus.c delete mode 100644
> drivers/devfreq/exynos/exynos4_bus.h delete mode 100644
> drivers/devfreq/exynos/exynos5_bus.c delete mode 100644
> drivers/devfreq/exynos/exynos_ppmu.c delete mode 100644
> drivers/devfreq/exynos/exynos_ppmu.h create mode 100644
> drivers/devfreq/governor_passive.c
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWnf5NAAoJED7hu3+zyiIosLoP/0Axz84pD1ZE5Ctd1LK7dR4A
QiKq1fxbrryCiIJLqIjl4VVEGiDoPh0ofl9FbhX/qn6u+iu18O0CBsyr+LkaxH0Y
xA1fZK5N/4FbsMaCrbmu+52o4bdHYjZGGLahClLHAQ8K3ADkqJtwsoADCI+XbCVx
Yut5HI6WCc4wmItAOKW3N5nTU9SCWJ+V2N1dcC4qUShx2XEU8jJOsLgJcALNJB6g
p1OdFtdY7kLUgL51pFrtHuuchEfnqaoJtuKZx+dW8TM8/yD34NzSufOyU9Pdw1zN
1hiXSbgPSZTVzlUH2CmbKxAmSxdPDuh9sAMpiJyy1iFst3N0zsSw7hH7QH3goj8y
Epsc1/TisBmvFw+ILbBVnFXCJWpfebzjB+4z0HsqvPcjfy/JNAl0rWigDo5EbdT9
N/hJj5QeCxkv6zqGY0/MKKDFZlti5ecUBW/GzKqsZ730x8SvBvHK77ikJryFYLXT
HUhAHrYvsvZ/yZYQpRvsCUlcDykhaOT6JFdvbNJZ6mIPWc+AxU2pu72GfhjE5y7o
S2NcskLzRhcadQDRjn8Gt8fUwqry1xv+brzscn1n1wtdwPi+T2ltH6gRJs9r00UT
ZqxEH8LmLNpK0wpeEyG9i2LnJN3pH9C56//PVLzej9JJM8cWLL/4nwHh7zH5QAT4
0/4ww0+Zn24h1nbEZjbt
=mWFs
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
  2016-01-19  9:13 ` [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Tobias Jakobi
@ 2016-01-20  1:09   ` Chanwoo Choi
  2016-01-22 11:01     ` Tobias Jakobi
  0 siblings, 1 reply; 33+ messages in thread
From: Chanwoo Choi @ 2016-01-20  1:09 UTC (permalink / raw)
  To: Tobias Jakobi, myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

Hi Tobias,

On 2016년 01월 19일 18:13, Tobias Jakobi wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> Hello,
> 
> I've tested this on my Odroid-X2 but ran into issues. Patch 08/20
> introduces some pr_info() to exynos_bus_probe().
> 
> In my case both max_state and freq_table are zero though, so getting
> {min,max}_freq triggers an kernel oops. If I just remove the code the
> drivers probes correctly.

Thanks for your test. If you ok, could you give me a kernel oops message?
It is helpful to remove the corner case of this driver.

Best Regards,
Chanwoo Choi

> 
> 
> 
> Chanwoo Choi wrote:
>> This patch-set includes the two features as following. The generic
>> exynos bus frequency driver is able to support almost Exynos SoCs
>> for bus frequency scaling. And the new passive governor is able to
>> make the dependency on between devices for frequency/voltage
>> scaling. I had posted the patch-set[2] with the similiar concept.
>> This is is revised version for exynos bus frequency. - Generic
>> exynos bus frequency driver - New passive governor of DEVFREQ
>> framework
>>
>> Depend on: - next-20151210 tag of linux-next (master branch). -
>> Merge the latest devfreq patches on devfreq.git[2] (for-rafael
>> branch). [1]
>> https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/
>> (branch: for-rafael) [2] https://lkml.org/lkml/2015/1/7/872 :
>> [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency
>> driver
>>
>> Changes from v3: (https://lkml.org/lkml/2015/12/11/75) - Add the
>> reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) 
>> - Fix typo of the description on patch14 - Modify the subject and
>> description of patch17 - Reorder the 'bus_xxx' device tree node
>> alphabetically in both exynos3250-rinato/monk.dts and
>> exynos4412-trats/odroidu3
>>
>> Changes from v2: (https://lkml.org/lkml/2015/12/8/869) - Fix typo
>> on documentation - Modify the more appropriate sentence on patch
>> description - Add the detailed description about both parent and
>> passive bus device - Modify the DMC frequency for Exynos4x12 DMC
>> bus (200MHz -> 267MHz) - Modify the voltage of 200MHz was included
>> in Exynos3250 DMC bus (800mV -> 825mV) - Rename OPP nodes as
>> 'opp@<opp-hz>' - Delete the duplicate 'opp-microvolt' property of
>> passive devfreq device - Reorder the 'bus_xxx' device tree node
>> alphabetically in exynos3250-rinato/monk.dts - Reorder the
>> 'bus_xxx' device tree node alphabetically in
>> exynos4412-trats/odroidu3 - Add new exynos4412-ppmu-common.dtsi to
>> remove the duplicate PPMU dt node on rinato/monk/trats2/odroid-u3
>> board - Add the log message if bus device is registered to devfreq
>> framework successfully - Add the reviewed-by tag from Krzysztof
>> Kozlowski - Add the tested-by tag from Anand Moon on Odroid U3 -
>> Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS
>>
>> Changes from v1: (https://lkml.org/lkml/2015/11/26/260) - Check
>> whether the instance of regulator is NULL or not when executing
>> regulator_disable() because of only parent devfreq device has the
>> regulator instance. After fixing it, the wake-up from suspend state
>> is well working. (patch1) - Fix bug which checks 'bus-clk' instead
>> of 'bus->regulator' after calling devm_clk_get() (on patch1) -
>> Update the documentation to remove the description about 
>> DEVFREQ-EVENT subsystem (on patch2) - Add the full name of DMC
>> (Dynamic Memory Controller) (on patch2) - Modify the detailed
>> correlation of buses for Exynos3250 on documentation (patch2) - Add
>> the MFC bus node for Exynos3250 (on patch11, patch12) - Fix the
>> duplicate frequency of bus_display on Exynos4x12.dtsi - Add the
>> PPMU node for exynos4412-odroidu3 - Add the support of bus
>> frequency for exynos4412-odroidu3
>>
>> Detailed descirption for patch-set: 1. Add generic exynos bus
>> frequency driver : This patch-set adds the generic exynos bus
>> frequency driver for AXI bus of sub-blocks in exynos SoC. The
>> Samsung Exynos SoC have the common architecture for bus between
>> DRAM and sub-blocks in SoC.
>>
>> There are the different buses according to Exynos SoC because
>> Exynos SoC has the differnt sub-blocks and bus speed. In spite of
>> this difference among Exynos SoCs, this driver is able to support
>> almost Exynos SoC by adding unique data of each bus in the
>> devicetree file.
>>
>> In devicetree, each bus node has a bus clock, regulator,
>> operation-point and devfreq-event devices which measure the
>> utilization of each bus block.
>>
>> For example, - The bus of DMC block in exynos3250.dtsi are listed
>> below:
>>
>> bus_dmc: bus_dmc { compatible = "samsung,exynos-bus"; clocks =
>> <&cmu_dmc CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 =
>> <&bus_dmc_opp_table>; status = "disabled"; };
>>
>> bus_dmc_opp_table: opp_table1 { compatible =
>> "operating-points-v2"; opp-shared;
>>
>> opp@50000000 { opp-hz = /bits/ 64 <50000000>; opp-microvolt =
>> <800000>; }; opp@100000000 { opp-hz = /bits/ 64 <100000000>; 
>> opp-microvolt = <800000>; }; opp@134000000 { opp-hz = /bits/ 64
>> <134000000>; opp-microvolt = <800000>; }; opp@200000000 { opp-hz =
>> /bits/ 64 <200000000>; opp-microvolt = <825000>; }; opp@400000000
>> { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <875000>; }; };
>>
>> - Usage case to handle the frequency and voltage of bus on runtime 
>> in exynos3250-rinato.dts are listed below:
>>
>> &bus_dmc { devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>; 
>> vdd-supply = <&buck1_reg>;	/* VDD_MIF */ status = "okay"; };
>>
>> 2. Add new passive governor of DEVFREQ framework (patch5-patch7) :
>> This patch-set add the new passive governor for DEVFREQ framework. 
>> The existing governors (ondemand, performance and so on) are used
>> for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The
>> existing governors are independently used for specific device
>> driver which don't give the influence to other device drviers and
>> also don't receive the effect from other device drivers.
>>
>> The passive governor depends on operation of parent driver with
>> existing governors(ondemand, performance and so on) extremely and
>> is not able to decide the new frequency by oneself. According to
>> the decided new frequency of parent driver with governor, the
>> passive governor uses it to decide the appropriate frequency for
>> own device driver. The passive governor must need the following
>> information from device tree:
>>
>> For exameple, There are one more bus device drivers in Exynos3250
>> which need to change their source clock according to their
>> utilization on runtime. But, they share the same power line (e.g.,
>> regulator). So, LEFTBUS bus driver is operated as parent with
>> ondemand governor and then the rest device driver with passive
>> governor.
>>
>> The buses of Internal block in exynos3250.dtsi are listed below: 
>> When LEFTBUS bus driver (parent) changes the bus frequency with 
>> ondemand governor on runtime, the rest bus devices which sharing 
>> the same power line (VDD_INT) will change the each bus frequency 
>> according to the decision of LEFTBUS bus driver (parent).
>>
>> - INT (Internal) block : VDD_INT |--- LEFTBUS |--- PERIL |--- MFC 
>> |--- G3D |--- RIGHTBUS |--- FSYS |--- LCD0 |--- PERIR |--- ISP |---
>> CAM
>>
>> - The buss of INT block in exynos3250.dtsi are listed below: 
>> bus_leftbus: bus_leftbus { compatible = "samsung,exynos-bus"; 
>> clocks = <&cmu CLK_DIV_GDL>; clock-names = "bus"; 
>> operating-points-v2 = <&bus_leftbus_opp_table>; status =
>> "disabled"; };
>>
>> bus_rightbus: bus_rightbus { compatible = "samsung,exynos-bus"; 
>> clocks = <&cmu CLK_DIV_GDR>; clock-names = "bus"; 
>> operating-points-v2 = <&bus_leftbus_opp_table>; status =
>> "disabled"; };
>>
>> (Omit the rest bus dt node)
>>
>> - Usage case to handle the frequency and voltage of bus on runtime 
>> in exynos3250-rinato.dts are listed below: /* Parent bus device of
>> VDD_INT */ &bus_leftbus { devfreq-events = <&ppmu_leftbus_3>,
>> <&ppmu_rightbus_3>; vdd-supply = <&buck3_reg>; status = "okay"; };
>>
>> /* Passive bus device depend on LEFTBUS bus. */ &bus_rightbus { 
>> devfreq = <&bus_leftbus>; /* 'devfreq' property indicates the
>> phandle of parent device. */ status = "okay"; };
>>
>> (Omit the rest bus dt node)
>>
>> Chanwoo Choi (20): PM / devfreq: exynos: Add generic exynos bus
>> frequency driver PM / devfreq: exynos: Add documentation for
>> generic exynos bus frequency driver ARM: dts: Add DMC bus node for
>> Exynos3250 ARM: dts: Add DMC bus frequency for
>> exynos3250-rinato/monk PM / devfreq: Add new passive governor PM /
>> devfreq: Add devfreq_get_devfreq_by_phandle() PM / devfreq: Show
>> the related information according to governor type PM / devfreq:
>> exynos: Add support of bus frequency of sub-blocks using passive
>> governor PM / devfreq: exynos: Update documentation for bus devices
>> using passive governor PM / devfreq: exynos: Add the detailed
>> correlation between sub-blocks and power line PM / devfreq: exynos:
>> Remove unused exynos4/5 busfreq driver MAINTAINERS: Add samsung bus
>> frequency driver entry ARM: dts: Add bus nodes using VDD_INT for
>> Exynos3250 ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 
>> ARM: dts: Add bus nodes using VDD_INT for Exynos4x12 ARM: dts: Add
>> bus nodes using VDD_MIF for Exynos4210 ARM: dts: Add
>> exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes ARM:
>> dts: Add support of bus frequency using VDD_INT for
>> exynos3250-rinato ARM: dts: Expand the voltage range of buck1/3
>> regulator for exynos4412-odroidu3 ARM: dts: Add support of bus
>> frequency for exynos4412-trats/odroidu3
>>
>> .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++ 
>> MAINTAINERS                                        |    9 + 
>> arch/arm/boot/dts/exynos3250-monk.dts              |   47 +- 
>> arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +- 
>> arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++ 
>> arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++ 
>> arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +- 
>> arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 + 
>> arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +- 
>> arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++ 
>> drivers/devfreq/Kconfig                            |   37 +- 
>> drivers/devfreq/Makefile                           |    2 + 
>> drivers/devfreq/devfreq.c                          |  120 ++- 
>> drivers/devfreq/exynos/Makefile                    |    3 +- 
>> drivers/devfreq/exynos/exynos-bus.c                |  556
>> +++++++++++ drivers/devfreq/exynos/exynos4_bus.c               |
>> 1055 -------------------- drivers/devfreq/exynos/exynos4_bus.h
>> |  110 -- drivers/devfreq/exynos/exynos5_bus.c               |  431
>> -------- drivers/devfreq/exynos/exynos_ppmu.c               |  119
>> --- drivers/devfreq/exynos/exynos_ppmu.h               |   86 -- 
>> drivers/devfreq/governor.h                         |    7 + 
>> drivers/devfreq/governor_passive.c                 |  109 ++ 
>> drivers/devfreq/governor_performance.c             |    1 + 
>> drivers/devfreq/governor_powersave.c               |    1 + 
>> drivers/devfreq/governor_simpleondemand.c          |    1 + 
>> drivers/devfreq/governor_userspace.c               |    1 + 
>> include/linux/devfreq.h                            |   26 + 27
>> files changed, 1955 insertions(+), 1948 deletions(-) create mode
>> 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt 
>> create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi 
>> create mode 100644 drivers/devfreq/exynos/exynos-bus.c delete mode
>> 100644 drivers/devfreq/exynos/exynos4_bus.c delete mode 100644
>> drivers/devfreq/exynos/exynos4_bus.h delete mode 100644
>> drivers/devfreq/exynos/exynos5_bus.c delete mode 100644
>> drivers/devfreq/exynos/exynos_ppmu.c delete mode 100644
>> drivers/devfreq/exynos/exynos_ppmu.h create mode 100644
>> drivers/devfreq/governor_passive.c
>>
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2
> 
> iQIcBAEBCAAGBQJWnf5NAAoJED7hu3+zyiIosLoP/0Axz84pD1ZE5Ctd1LK7dR4A
> QiKq1fxbrryCiIJLqIjl4VVEGiDoPh0ofl9FbhX/qn6u+iu18O0CBsyr+LkaxH0Y
> xA1fZK5N/4FbsMaCrbmu+52o4bdHYjZGGLahClLHAQ8K3ADkqJtwsoADCI+XbCVx
> Yut5HI6WCc4wmItAOKW3N5nTU9SCWJ+V2N1dcC4qUShx2XEU8jJOsLgJcALNJB6g
> p1OdFtdY7kLUgL51pFrtHuuchEfnqaoJtuKZx+dW8TM8/yD34NzSufOyU9Pdw1zN
> 1hiXSbgPSZTVzlUH2CmbKxAmSxdPDuh9sAMpiJyy1iFst3N0zsSw7hH7QH3goj8y
> Epsc1/TisBmvFw+ILbBVnFXCJWpfebzjB+4z0HsqvPcjfy/JNAl0rWigDo5EbdT9
> N/hJj5QeCxkv6zqGY0/MKKDFZlti5ecUBW/GzKqsZ730x8SvBvHK77ikJryFYLXT
> HUhAHrYvsvZ/yZYQpRvsCUlcDykhaOT6JFdvbNJZ6mIPWc+AxU2pu72GfhjE5y7o
> S2NcskLzRhcadQDRjn8Gt8fUwqry1xv+brzscn1n1wtdwPi+T2ltH6gRJs9r00UT
> ZqxEH8LmLNpK0wpeEyG9i2LnJN3pH9C56//PVLzej9JJM8cWLL/4nwHh7zH5QAT4
> 0/4ww0+Zn24h1nbEZjbt
> =mWFs
> -----END PGP SIGNATURE-----
> 
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
  2016-01-20  1:09   ` Chanwoo Choi
@ 2016-01-22 11:01     ` Tobias Jakobi
  0 siblings, 0 replies; 33+ messages in thread
From: Tobias Jakobi @ 2016-01-22 11:01 UTC (permalink / raw)
  To: Chanwoo Choi, Tobias Jakobi, myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

[-- Attachment #1: Type: text/plain, Size: 12766 bytes --]

Hey Chanwoo,


Chanwoo Choi wrote:
> Hi Tobias,
> 
> On 2016년 01월 19일 18:13, Tobias Jakobi wrote:
> Hello,
> 
> I've tested this on my Odroid-X2 but ran into issues. Patch 08/20
> introduces some pr_info() to exynos_bus_probe().
> 
> In my case both max_state and freq_table are zero though, so getting
> {min,max}_freq triggers an kernel oops. If I just remove the code the
> drivers probes correctly.
> 
>> Thanks for your test. If you ok, could you give me a kernel oops message?
>> It is helpful to remove the corner case of this driver.
sure, I've sttached the kernel oops.

- Tobias


>> Best Regards,
>> Chanwoo Choi
> 
> 
> 
> 
> Chanwoo Choi wrote:
>>>> This patch-set includes the two features as following. The generic
>>>> exynos bus frequency driver is able to support almost Exynos SoCs
>>>> for bus frequency scaling. And the new passive governor is able to
>>>> make the dependency on between devices for frequency/voltage
>>>> scaling. I had posted the patch-set[2] with the similiar concept.
>>>> This is is revised version for exynos bus frequency. - Generic
>>>> exynos bus frequency driver - New passive governor of DEVFREQ
>>>> framework
>>>>
>>>> Depend on: - next-20151210 tag of linux-next (master branch). -
>>>> Merge the latest devfreq patches on devfreq.git[2] (for-rafael
>>>> branch). [1]
>>>> https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/
>>>> (branch: for-rafael) [2] https://lkml.org/lkml/2015/1/7/872 :
>>>> [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency
>>>> driver
>>>>
>>>> Changes from v3: (https://lkml.org/lkml/2015/12/11/75) - Add the
>>>> reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) 
>>>> - Fix typo of the description on patch14 - Modify the subject and
>>>> description of patch17 - Reorder the 'bus_xxx' device tree node
>>>> alphabetically in both exynos3250-rinato/monk.dts and
>>>> exynos4412-trats/odroidu3
>>>>
>>>> Changes from v2: (https://lkml.org/lkml/2015/12/8/869) - Fix typo
>>>> on documentation - Modify the more appropriate sentence on patch
>>>> description - Add the detailed description about both parent and
>>>> passive bus device - Modify the DMC frequency for Exynos4x12 DMC
>>>> bus (200MHz -> 267MHz) - Modify the voltage of 200MHz was included
>>>> in Exynos3250 DMC bus (800mV -> 825mV) - Rename OPP nodes as
>>>> 'opp@<opp-hz>' - Delete the duplicate 'opp-microvolt' property of
>>>> passive devfreq device - Reorder the 'bus_xxx' device tree node
>>>> alphabetically in exynos3250-rinato/monk.dts - Reorder the
>>>> 'bus_xxx' device tree node alphabetically in
>>>> exynos4412-trats/odroidu3 - Add new exynos4412-ppmu-common.dtsi to
>>>> remove the duplicate PPMU dt node on rinato/monk/trats2/odroid-u3
>>>> board - Add the log message if bus device is registered to devfreq
>>>> framework successfully - Add the reviewed-by tag from Krzysztof
>>>> Kozlowski - Add the tested-by tag from Anand Moon on Odroid U3 -
>>>> Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS
>>>>
>>>> Changes from v1: (https://lkml.org/lkml/2015/11/26/260) - Check
>>>> whether the instance of regulator is NULL or not when executing
>>>> regulator_disable() because of only parent devfreq device has the
>>>> regulator instance. After fixing it, the wake-up from suspend state
>>>> is well working. (patch1) - Fix bug which checks 'bus-clk' instead
>>>> of 'bus->regulator' after calling devm_clk_get() (on patch1) -
>>>> Update the documentation to remove the description about 
>>>> DEVFREQ-EVENT subsystem (on patch2) - Add the full name of DMC
>>>> (Dynamic Memory Controller) (on patch2) - Modify the detailed
>>>> correlation of buses for Exynos3250 on documentation (patch2) - Add
>>>> the MFC bus node for Exynos3250 (on patch11, patch12) - Fix the
>>>> duplicate frequency of bus_display on Exynos4x12.dtsi - Add the
>>>> PPMU node for exynos4412-odroidu3 - Add the support of bus
>>>> frequency for exynos4412-odroidu3
>>>>
>>>> Detailed descirption for patch-set: 1. Add generic exynos bus
>>>> frequency driver : This patch-set adds the generic exynos bus
>>>> frequency driver for AXI bus of sub-blocks in exynos SoC. The
>>>> Samsung Exynos SoC have the common architecture for bus between
>>>> DRAM and sub-blocks in SoC.
>>>>
>>>> There are the different buses according to Exynos SoC because
>>>> Exynos SoC has the differnt sub-blocks and bus speed. In spite of
>>>> this difference among Exynos SoCs, this driver is able to support
>>>> almost Exynos SoC by adding unique data of each bus in the
>>>> devicetree file.
>>>>
>>>> In devicetree, each bus node has a bus clock, regulator,
>>>> operation-point and devfreq-event devices which measure the
>>>> utilization of each bus block.
>>>>
>>>> For example, - The bus of DMC block in exynos3250.dtsi are listed
>>>> below:
>>>>
>>>> bus_dmc: bus_dmc { compatible = "samsung,exynos-bus"; clocks =
>>>> <&cmu_dmc CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 =
>>>> <&bus_dmc_opp_table>; status = "disabled"; };
>>>>
>>>> bus_dmc_opp_table: opp_table1 { compatible =
>>>> "operating-points-v2"; opp-shared;
>>>>
>>>> opp@50000000 { opp-hz = /bits/ 64 <50000000>; opp-microvolt =
>>>> <800000>; }; opp@100000000 { opp-hz = /bits/ 64 <100000000>; 
>>>> opp-microvolt = <800000>; }; opp@134000000 { opp-hz = /bits/ 64
>>>> <134000000>; opp-microvolt = <800000>; }; opp@200000000 { opp-hz =
>>>> /bits/ 64 <200000000>; opp-microvolt = <825000>; }; opp@400000000
>>>> { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <875000>; }; };
>>>>
>>>> - Usage case to handle the frequency and voltage of bus on runtime 
>>>> in exynos3250-rinato.dts are listed below:
>>>>
>>>> &bus_dmc { devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>; 
>>>> vdd-supply = <&buck1_reg>;	/* VDD_MIF */ status = "okay"; };
>>>>
>>>> 2. Add new passive governor of DEVFREQ framework (patch5-patch7) :
>>>> This patch-set add the new passive governor for DEVFREQ framework. 
>>>> The existing governors (ondemand, performance and so on) are used
>>>> for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The
>>>> existing governors are independently used for specific device
>>>> driver which don't give the influence to other device drviers and
>>>> also don't receive the effect from other device drivers.
>>>>
>>>> The passive governor depends on operation of parent driver with
>>>> existing governors(ondemand, performance and so on) extremely and
>>>> is not able to decide the new frequency by oneself. According to
>>>> the decided new frequency of parent driver with governor, the
>>>> passive governor uses it to decide the appropriate frequency for
>>>> own device driver. The passive governor must need the following
>>>> information from device tree:
>>>>
>>>> For exameple, There are one more bus device drivers in Exynos3250
>>>> which need to change their source clock according to their
>>>> utilization on runtime. But, they share the same power line (e.g.,
>>>> regulator). So, LEFTBUS bus driver is operated as parent with
>>>> ondemand governor and then the rest device driver with passive
>>>> governor.
>>>>
>>>> The buses of Internal block in exynos3250.dtsi are listed below: 
>>>> When LEFTBUS bus driver (parent) changes the bus frequency with 
>>>> ondemand governor on runtime, the rest bus devices which sharing 
>>>> the same power line (VDD_INT) will change the each bus frequency 
>>>> according to the decision of LEFTBUS bus driver (parent).
>>>>
>>>> - INT (Internal) block : VDD_INT |--- LEFTBUS |--- PERIL |--- MFC 
>>>> |--- G3D |--- RIGHTBUS |--- FSYS |--- LCD0 |--- PERIR |--- ISP |---
>>>> CAM
>>>>
>>>> - The buss of INT block in exynos3250.dtsi are listed below: 
>>>> bus_leftbus: bus_leftbus { compatible = "samsung,exynos-bus"; 
>>>> clocks = <&cmu CLK_DIV_GDL>; clock-names = "bus"; 
>>>> operating-points-v2 = <&bus_leftbus_opp_table>; status =
>>>> "disabled"; };
>>>>
>>>> bus_rightbus: bus_rightbus { compatible = "samsung,exynos-bus"; 
>>>> clocks = <&cmu CLK_DIV_GDR>; clock-names = "bus"; 
>>>> operating-points-v2 = <&bus_leftbus_opp_table>; status =
>>>> "disabled"; };
>>>>
>>>> (Omit the rest bus dt node)
>>>>
>>>> - Usage case to handle the frequency and voltage of bus on runtime 
>>>> in exynos3250-rinato.dts are listed below: /* Parent bus device of
>>>> VDD_INT */ &bus_leftbus { devfreq-events = <&ppmu_leftbus_3>,
>>>> <&ppmu_rightbus_3>; vdd-supply = <&buck3_reg>; status = "okay"; };
>>>>
>>>> /* Passive bus device depend on LEFTBUS bus. */ &bus_rightbus { 
>>>> devfreq = <&bus_leftbus>; /* 'devfreq' property indicates the
>>>> phandle of parent device. */ status = "okay"; };
>>>>
>>>> (Omit the rest bus dt node)
>>>>
>>>> Chanwoo Choi (20): PM / devfreq: exynos: Add generic exynos bus
>>>> frequency driver PM / devfreq: exynos: Add documentation for
>>>> generic exynos bus frequency driver ARM: dts: Add DMC bus node for
>>>> Exynos3250 ARM: dts: Add DMC bus frequency for
>>>> exynos3250-rinato/monk PM / devfreq: Add new passive governor PM /
>>>> devfreq: Add devfreq_get_devfreq_by_phandle() PM / devfreq: Show
>>>> the related information according to governor type PM / devfreq:
>>>> exynos: Add support of bus frequency of sub-blocks using passive
>>>> governor PM / devfreq: exynos: Update documentation for bus devices
>>>> using passive governor PM / devfreq: exynos: Add the detailed
>>>> correlation between sub-blocks and power line PM / devfreq: exynos:
>>>> Remove unused exynos4/5 busfreq driver MAINTAINERS: Add samsung bus
>>>> frequency driver entry ARM: dts: Add bus nodes using VDD_INT for
>>>> Exynos3250 ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 
>>>> ARM: dts: Add bus nodes using VDD_INT for Exynos4x12 ARM: dts: Add
>>>> bus nodes using VDD_MIF for Exynos4210 ARM: dts: Add
>>>> exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes ARM:
>>>> dts: Add support of bus frequency using VDD_INT for
>>>> exynos3250-rinato ARM: dts: Expand the voltage range of buck1/3
>>>> regulator for exynos4412-odroidu3 ARM: dts: Add support of bus
>>>> frequency for exynos4412-trats/odroidu3
>>>>
>>>> .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++ 
>>>> MAINTAINERS                                        |    9 + 
>>>> arch/arm/boot/dts/exynos3250-monk.dts              |   47 +- 
>>>> arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +- 
>>>> arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++ 
>>>> arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++ 
>>>> arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +- 
>>>> arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 + 
>>>> arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +- 
>>>> arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++ 
>>>> drivers/devfreq/Kconfig                            |   37 +- 
>>>> drivers/devfreq/Makefile                           |    2 + 
>>>> drivers/devfreq/devfreq.c                          |  120 ++- 
>>>> drivers/devfreq/exynos/Makefile                    |    3 +- 
>>>> drivers/devfreq/exynos/exynos-bus.c                |  556
>>>> +++++++++++ drivers/devfreq/exynos/exynos4_bus.c               |
>>>> 1055 -------------------- drivers/devfreq/exynos/exynos4_bus.h
>>>> |  110 -- drivers/devfreq/exynos/exynos5_bus.c               |  431
>>>> -------- drivers/devfreq/exynos/exynos_ppmu.c               |  119
>>>> --- drivers/devfreq/exynos/exynos_ppmu.h               |   86 -- 
>>>> drivers/devfreq/governor.h                         |    7 + 
>>>> drivers/devfreq/governor_passive.c                 |  109 ++ 
>>>> drivers/devfreq/governor_performance.c             |    1 + 
>>>> drivers/devfreq/governor_powersave.c               |    1 + 
>>>> drivers/devfreq/governor_simpleondemand.c          |    1 + 
>>>> drivers/devfreq/governor_userspace.c               |    1 + 
>>>> include/linux/devfreq.h                            |   26 + 27
>>>> files changed, 1955 insertions(+), 1948 deletions(-) create mode
>>>> 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt 
>>>> create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi 
>>>> create mode 100644 drivers/devfreq/exynos/exynos-bus.c delete mode
>>>> 100644 drivers/devfreq/exynos/exynos4_bus.c delete mode 100644
>>>> drivers/devfreq/exynos/exynos4_bus.h delete mode 100644
>>>> drivers/devfreq/exynos/exynos5_bus.c delete mode 100644
>>>> drivers/devfreq/exynos/exynos_ppmu.c delete mode 100644
>>>> drivers/devfreq/exynos/exynos_ppmu.h create mode 100644
>>>> drivers/devfreq/governor_passive.c
>>>>
> 
>>
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


[-- Attachment #2: oops.txt --]
[-- Type: text/plain, Size: 33579 bytes --]

[    3.976906] s3c-rtc 10070000.rtc: s3c2410_rtc: tick irq 65, alarm irq 64
[    3.982663] s3c-rtc 10070000.rtc: s3c2410_rtc: RTCCON=01
[    3.987704] s3c-rtc 10070000.rtc: read time 2015.04.08 16:29:25
[    3.993571] s3c-rtc 10070000.rtc: read time 2015.04.08 16:29:25
[    3.999456] s3c-rtc 10070000.rtc: read alarm 0, 1900.00.00 00:00:00
[    4.005708] s3c-rtc 10070000.rtc: read time 2015.04.08 16:29:25
[    4.011604] rtc rtc1: alarm rollover: day
[    4.015599] s3c-rtc 10070000.rtc: read time 2015.04.08 16:29:25
[    4.021734] rtc rtc1: s3c: dev (254:1)
[    4.024371] mmc0: new high speed SDXC card at address aaaa
[    4.024856] mmcblk0: mmc0:aaaa SE64G 59.4 GiB 
[    4.025959]  mmcblk0: p1 p2 p3
[    4.038156] s3c-rtc 10070000.rtc: rtc core: registered s3c as rtc1
[    4.044704] exynos-bus bus_dmc: Looking up vdd-supply from device tree
[    4.051322] Unable to handle kernel paging request at virtual address fffffffc
[    4.058045] pgd = c0004000
[    4.060724] [fffffffc] *pgd=6fffd861, *pte=00000000, *ppte=00000000
[    4.066961] Internal error: Oops: 37 [#1] PREEMPT SMP ARM
[    4.072341] Modules linked in:
[    4.075381] CPU: 2 PID: 29 Comm: kworker/u8:1 Not tainted 4.4.0-debug+ #2
[    4.079067] usb 1-2.1: new high-speed USB device number 3 using exynos-ehci
[    4.089093] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[    4.095176] Workqueue: deferwq deferred_probe_work_func
[    4.100377] task: ee9e8bc0 ti: eea0c000 task.ti: eea0c000
[    4.105763] PC is at exynos_bus_probe+0x220/0x6c8
[    4.110450] LR is at trace_hardirqs_on+0x14/0x18
[    4.115047] pc : [<c0458a68>]    lr : [<c00749dc>]    psr: 60000053
[    4.115047] sp : eea0dd30  ip : eea0dcc0  fp : eea0dd7c
[    4.126504] r10: eebf6c10  r9 : eefcc8c4  r8 : ee9464d0
[    4.131712] r7 : eebf6c00  r6 : eebf6c10  r5 : 00000000  r4 : 10624dd3
[    4.138222] r3 : 3fffffff  r2 : 00000000  r1 : eeba8480  r0 : c076141c
[    4.144733] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
[    4.151936] Control: 10c5387d  Table: 4000404a  DAC: 00000051
[    4.157665] Process kworker/u8:1 (pid: 29, stack limit = 0xeea0c218)
[    4.164002] Stack: (0xeea0dd30 to 0xeea0e000)
[    4.168343] dd20:                                     00000000 00000000 c04588e4 c03385c8
[    4.176503] dd40: 00000002 ee946250 c10203b4 17d78400 c082e820 fffffffe eebf6c10 c082e820
[    4.184427] usb 1-2.1: New USB device found, idVendor=0424, idProduct=9514
[    4.184432] usb 1-2.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    4.185131] hub 1-2.1:1.0: USB hub found
[    4.185297] hub 1-2.1:1.0: 5 ports detected
[    4.206883] dd60: fffffdfb 00000003 c083b258 00000001 eea0dd9c eea0dd80 c033dc78 c0458854
[    4.215042] dd80: c10203b4 eebf6c10 00000000 c082e820 eea0ddc4 eea0dda0 c033bad4 c033dc2c
[    4.223201] dda0: 00000000 c082e820 eea0de10 eebf6c10 00000001 eea0dea8 eea0dde4 eea0ddc8
[    4.231360] ddc0: c033bd30 c033b8d0 ee2bba60 00000000 eea0de10 c033bca8 eea0de0c eea0dde8
[    4.239520] dde0: c0339dcc c033bcb4 ee8036d4 ee2bba54 eebf6c10 eebf6c10 eebf6c10 eebf6c44
[    4.247679] de00: eea0de34 eea0de10 c033b820 c0339d6c eebf6c10 00000001 eebf6c10 eebf6c10
[    4.255838] de20: c08237c8 ee21ae00 eea0de44 eea0de38 c033be8c c033b77c eea0de64 eea0de48
[    4.263997] de40: c033ae78 c033be84 00000000 eebf6c10 c0823488 c08234cc eea0de84 eea0de68
[    4.269061] usb 1-2.2: new high-speed USB device number 4 using exynos-ehci
[    4.279101] de60: c033b2c8 c033adf4 c033b258 c0823504 ee867100 ee80ac00 eea0dee4 eea0de88
[    4.287260] de80: c00455bc c033b264 00000001 00000000 c00454e0 ee80ac00 ee80ac00 00000000
[    4.295419] dea0: 00000000 00000000 c0823504 00000000 00000000 c072e1f4 c05b6158 ee80ac00
[    4.303578] dec0: ee867118 ee80ac30 00000088 c0045bc4 ee80ac00 ee867100 eea0df24 eea0dee8
[    4.311737] dee0: c0045b4c c00453bc ee8fe040 ee80ada0 c07f8100 c083a796 00000000 00000000
[    4.319896] df00: ee8fe040 ee867100 c0045afc 00000000 00000000 00000000 eea0dfac eea0df28
[    4.328056] df20: c004c3ac c0045b08 00000000 eea0df38 ee867100 00000000 00000000 dead4ead
[    4.336215] df40: ffffffff ffffffff c0841040 00000000 00000000 c06f3c20 eea0df58 eea0df58
[    4.344374] df60: 00000000 00000000 dead4ead ffffffff ffffffff c0841040 00000000 00000000
[    4.352533] df80: c06f3c20 eea0df84 eea0df84 dc8ba600 ee8fe040 c004c2a4 00000000 00000000
[    4.360692] dfa0: 00000000 eea0dfb0 c000feb0 c004c2b0 00000000 00000000 00000000 00000000
[    4.368851] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    4.377011] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 eea0dff4 00000000
[    4.379664] usb 1-2.2: New USB device found, idVendor=8564, idProduct=1000
[    4.379669] usb 1-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    4.379672] usb 1-2.2: Product: Mass Storage Device
[    4.379676] usb 1-2.2: Manufacturer: JetFlash
[    4.379679] usb 1-2.2: SerialNumber: 059FKI3OMNH24FV4
[    4.413550] Backtrace: 
[    4.415990] [<c0458848>] (exynos_bus_probe) from [<c033dc78>] (platform_drv_probe+0x58/0xb4)
[    4.424401]  r10:00000001 r9:c083b258 r8:00000003 r7:fffffdfb r6:c082e820 r5:eebf6c10
[    4.432212]  r4:fffffffe
[    4.434735] [<c033dc20>] (platform_drv_probe) from [<c033bad4>] (driver_probe_device+0x210/0x304)
[    4.443583]  r7:c082e820 r6:00000000 r5:eebf6c10 r4:c10203b4
[    4.449229] [<c033b8c4>] (driver_probe_device) from [<c033bd30>] (__device_attach_driver+0x88/0x94)
[    4.458253]  r8:eea0dea8 r7:00000001 r6:eebf6c10 r5:eea0de10 r4:c082e820 r3:00000000
[    4.465982] [<c033bca8>] (__device_attach_driver) from [<c0339dcc>] (bus_for_each_drv+0x6c/0xa0)
[    4.469060] usb 1-2.1.1: new high-speed USB device number 5 using exynos-ehci
[    4.481862]  r6:c033bca8 r5:eea0de10 r4:00000000 r3:ee2bba60
[    4.487507] [<c0339d60>] (bus_for_each_drv) from [<c033b820>] (__device_attach+0xb0/0x110)
[    4.495750]  r6:eebf6c44 r5:eebf6c10 r4:eebf6c10
[    4.500353] [<c033b770>] (__device_attach) from [<c033be8c>] (device_initial_probe+0x14/0x18)
[    4.508857]  r7:ee21ae00 r6:c08237c8 r5:eebf6c10 r4:eebf6c10
[    4.514502] [<c033be78>] (device_initial_probe) from [<c033ae78>] (bus_probe_device+0x90/0x98)
[    4.523095] [<c033ade8>] (bus_probe_device) from [<c033b2c8>] (deferred_probe_work_func+0x70/0xa4)
[    4.532033]  r6:c08234cc r5:c0823488 r4:eebf6c10 r3:00000000
[    4.537680] [<c033b258>] (deferred_probe_work_func) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[    4.546789]  r6:ee80ac00 r5:ee867100 r4:c0823504 r3:c033b258
[    4.552433] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[    4.560503]  r10:ee867100 r9:ee80ac00 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee867118
[    4.568315]  r4:ee80ac00
[    4.570836] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[    4.574421] usb 1-2.1.1: New USB device found, idVendor=0424, idProduct=ec00
[    4.574426] usb 1-2.1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    4.577128] smsc95xx v1.0.4
[    4.595484]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee867100 r5:ee8fe040
[    4.603295]  r4:00000000
[    4.605819] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[    4.613017]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee8fe040
[    4.618662] Code: e5922018 e34c0076 e2433107 05971018 (e7923103) 
[    4.624806] DEBUG: in exynos_bus_target()
[    4.624830] ---[ end trace 963a396567424827 ]---
[    4.624862] Unable to handle kernel paging request at virtual address ffffffd0
[    4.624864] pgd = c0004000
[    4.624870] [ffffffd0] *pgd=6fffd861, *pte=00000000, *ppte=00000000
[    4.624874] Internal error: Oops: 37 [#2] PREEMPT SMP ARM
[    4.624878] Modules linked in:
[    4.624882] CPU: 2 PID: 29 Comm: kworker/u8:1 Tainted: G      D         4.4.0-debug+ #2
[    4.624884] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[    4.624891] task: ee9e8bc0 ti: eea0c000 task.ti: eea0c000
[    4.624896] PC is at kthread_data+0x10/0x18
[    4.624900] LR is at wq_worker_sleeping+0x14/0xd8
[    4.624903] pc : [<c004cddc>]    lr : [<c00469b4>]    psr: 000001d3
[    4.624903] sp : eea0da68  ip : eea0da78  fp : eea0da74
[    4.624906] r10: 00000000  r9 : c07f86bc  r8 : 00000002
[    4.624908] r7 : ee9e8e88  r6 : c07f3480  r5 : ee9e8bc0  r4 : 00000002
[    4.624911] r3 : 00000000  r2 : 00000000  r1 : 00000002  r0 : ee9e8bc0
[    4.624914] Flags: nzcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
[    4.624916] Control: 10c5387d  Table: 4000404a  DAC: 00000051
[    4.624919] Process kworker/u8:1 (pid: 29, stack limit = 0xeea0c218)
[    4.624922] Stack: (0xeea0da68 to 0xeea0e000)
[    4.624927] da60:                   eea0da8c eea0da78 c00469b4 c004cdd8 eef87480 ee9e8bc0
[    4.624932] da80: eea0dae4 eea0da90 c05affec c00469ac c0014320 c0012700 c0012724 00000000
[    4.624937] daa0: eea0d8d0 eea0db10 eea0dae4 eea0dab8 c05b070c eef87490 00000000 eea0c000
[    4.624941] dac0: eea0d8d0 eea0db10 ee9e8de4 c0458a6a ee878000 00000000 eea0dafc eea0dae8
[    4.624946] dae0: c05b070c c05afb78 0420806c ee9e8bc0 eea0db2c eea0db00 c002c95c c05b06c8
[    4.624951] db00: c0458a6c c0458a6a 00000001 00000001 eea0db10 eea0db10 c0029a2c c0458a6c
[    4.624956] db20: eea0dbbc eea0db30 c0014de0 c002c218 eea0c218 0000000b c06efe18 00000008
[    4.624961] db40: 00000000 eea0c000 00000000 60000153 c008358c 65082dcc 32323935 20383130
[    4.624965] db60: 63343365 36373030 34326520 30313333 35302037 30313739 28203831 32393765
[    4.624970] db80: 33303133 ee002029 c001f5bc dc8ba600 c074c41c fffffffc 00000037 eea0dce0
[    4.624975] dba0: 00000000 fffffffc eefcc8c4 eebf6c10 eea0dbd4 eea0dbc0 c0023ee4 c0014974
[    4.624980] dbc0: eea0dce0 00000037 eea0dc2c eea0dbd8 c001f96c c0023e84 00000000 00000002
[    4.624985] dbe0: eea0dbfc eea0dbf0 c0071480 c00713a8 00000000 eea0dc00 00000000 c0052804
[    4.624989] dc00: eef83440 c07fd524 00000037 c001f5d0 fffffffc eea0dce0 eefcc8c4 eebf6c10
[    4.624994] dc20: eea0dcdc eea0dc30 c0009390 c001f5dc c083b488 ee36527c 00000000 00000000
[    4.624999] dc40: 00000000 60000053 eea0dca4 eea0dc58 c00776b8 c0074d44 00000001 00000000
[    4.625004] dc60: eea0dccc eea0dc70 c0077898 c008d3e0 c0056180 c0078fcc 00000005 ee36524c
[    4.625008] dc80: 60000053 c101032c eea0dca4 eea0dc98 c00749dc c00747d4 600000d3 eea0dca8
[    4.625013] dca0: 00000006 ee365248 ee36526c 60000053 eea0dccc eea0dcc0 c00749dc c0458a68
[    4.625018] dcc0: 60000053 ffffffff eea0dd14 ee9464d0 eea0dd7c eea0dce0 c00154a4 c000935c
[    4.625023] dce0: c076141c eeba8480 00000000 3fffffff 10624dd3 00000000 eebf6c10 eebf6c00
[    4.625028] dd00: ee9464d0 eefcc8c4 eebf6c10 eea0dd7c eea0dcc0 eea0dd30 c00749dc c0458a68
[    4.625033] dd20: 60000053 ffffffff 00000051 c04580f0 00000000 00000000 c04588e4 c03385c8
[    4.625037] dd40: 00000002 ee946250 c10203b4 17d78400 c082e820 fffffffe eebf6c10 c082e820
[    4.625042] dd60: fffffdfb 00000003 c083b258 00000001 eea0dd9c eea0dd80 c033dc78 c0458854
[    4.625047] dd80: c10203b4 eebf6c10 00000000 c082e820 eea0ddc4 eea0dda0 c033bad4 c033dc2c
[    4.625052] dda0: 00000000 c082e820 eea0de10 eebf6c10 00000001 eea0dea8 eea0dde4 eea0ddc8
[    4.625056] ddc0: c033bd30 c033b8d0 ee2bba60 00000000 eea0de10 c033bca8 eea0de0c eea0dde8
[    4.625061] dde0: c0339dcc c033bcb4 ee8036d4 ee2bba54 eebf6c10 eebf6c10 eebf6c10 eebf6c44
[    4.625066] de00: eea0de34 eea0de10 c033b820 c0339d6c eebf6c10 00000001 eebf6c10 eebf6c10
[    4.625071] de20: c08237c8 ee21ae00 eea0de44 eea0de38 c033be8c c033b77c eea0de64 eea0de48
[    4.625075] de40: c033ae78 c033be84 00000000 eebf6c10 c0823488 c08234cc eea0de84 eea0de68
[    4.625080] de60: c033b2c8 c033adf4 c033b258 c0823504 ee867100 ee80ac00 eea0dee4 eea0de88
[    4.625085] de80: c00455bc c033b264 00000001 00000000 c00454e0 ee80ac00 ee80ac00 00000000
[    4.625090] dea0: 00000000 00000000 c0823504 00000000 00000000 c072e1f4 c05b6158 ee80ac00
[    4.625094] dec0: ee867118 ee80ac30 00000088 c0045bc4 ee80ac00 ee867100 eea0df24 eea0dee8
[    4.625099] dee0: c0045b4c c00453bc ee8fe040 ee80ada0 c07f8100 c083a796 00000000 00000000
[    4.625104] df00: ee8fe040 ee867100 c0045afc 00000000 00000000 00000000 eea0dfac eea0df28
[    4.625109] df20: c004c3ac c0045b08 00000000 eea0df38 ee867100 00000000 00000000 dead4ead
[    4.625113] df40: ffffffff ffffffff c0841040 00000000 00000000 c06f3c20 eea0df58 eea0df58
[    4.625118] df60: 00000001 00010001 dead4ead ffffffff ffffffff c0841040 00000000 00000000
[    4.625123] df80: c06f3c20 eea0df84 eea0df84 dc8ba600 ee8fe040 c004c2a4 00000000 00000000
[    4.625127] dfa0: 00000000 eea0dfb0 c000feb0 c004c2b0 00000000 00000000 00000000 00000000
[    4.625132] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    4.625136] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 eea0dff4 00000000
[    4.625139] Backtrace: 
[    4.625145] [<c004cdcc>] (kthread_data) from [<c00469b4>] (wq_worker_sleeping+0x14/0xd8)
[    4.625153] [<c00469a0>] (wq_worker_sleeping) from [<c05affec>] (__schedule+0x480/0x994)
[    4.625157]  r5:ee9e8bc0 r4:eef87480
[    4.625162] [<c05afb6c>] (__schedule) from [<c05b070c>] (schedule+0x50/0xb0)
[    4.625171]  r10:00000000 r9:ee878000 r8:c0458a6a r7:ee9e8de4 r6:eea0db10 r5:eea0d8d0
[    4.625174]  r4:eea0c000
[    4.625180] [<c05b06bc>] (schedule) from [<c002c95c>] (do_exit+0x750/0xbe8)
[    4.625184]  r4:ee9e8bc0 r3:0420806c
[    4.625189] [<c002c20c>] (do_exit) from [<c0014de0>] (die+0x478/0x490)
[    4.625192]  r7:c0458a6c
[    4.625200] [<c0014968>] (die) from [<c0023ee4>] (__do_kernel_fault.part.0+0x6c/0x1ec)
[    4.625209]  r10:eebf6c10 r9:eefcc8c4 r8:fffffffc r7:00000000 r6:eea0dce0 r5:00000037
[    4.625212]  r4:fffffffc
[    4.625217] [<c0023e78>] (__do_kernel_fault.part.0) from [<c001f96c>] (do_page_fault+0x39c/0x3ac)
[    4.625221]  r7:00000037 r3:eea0dce0
[    4.625226] [<c001f5d0>] (do_page_fault) from [<c0009390>] (do_DataAbort+0x40/0xbc)
[    4.625234]  r10:eebf6c10 r9:eefcc8c4 r8:eea0dce0 r7:fffffffc r6:c001f5d0 r5:00000037
[    4.625237]  r4:c07fd524
[    4.625241] [<c0009350>] (do_DataAbort) from [<c00154a4>] (__dabt_svc+0x44/0x80)
[    4.625244] Exception stack(0xeea0dce0 to 0xeea0dd28)
[    4.625249] dce0: c076141c eeba8480 00000000 3fffffff 10624dd3 00000000 eebf6c10 eebf6c00
[    4.625254] dd00: ee9464d0 eefcc8c4 eebf6c10 eea0dd7c eea0dcc0 eea0dd30 c00749dc c0458a68
[    4.625257] dd20: 60000053 ffffffff
[    4.625265]  r8:ee9464d0 r7:eea0dd14 r6:ffffffff r5:60000053 r4:c0458a68
[    4.625272] [<c0458848>] (exynos_bus_probe) from [<c033dc78>] (platform_drv_probe+0x58/0xb4)
[    4.625281]  r10:00000001 r9:c083b258 r8:00000003 r7:fffffdfb r6:c082e820 r5:eebf6c10
[    4.625284]  r4:fffffffe
[    4.625289] [<c033dc20>] (platform_drv_probe) from [<c033bad4>] (driver_probe_device+0x210/0x304)
[    4.625296]  r7:c082e820 r6:00000000 r5:eebf6c10 r4:c10203b4
[    4.625301] [<c033b8c4>] (driver_probe_device) from [<c033bd30>] (__device_attach_driver+0x88/0x94)
[    4.625309]  r8:eea0dea8 r7:00000001 r6:eebf6c10 r5:eea0de10 r4:c082e820 r3:00000000
[    4.625314] [<c033bca8>] (__device_attach_driver) from [<c0339dcc>] (bus_for_each_drv+0x6c/0xa0)
[    4.625320]  r6:c033bca8 r5:eea0de10 r4:00000000 r3:ee2bba60
[    4.625325] [<c0339d60>] (bus_for_each_drv) from [<c033b820>] (__device_attach+0xb0/0x110)
[    4.625330]  r6:eebf6c44 r5:eebf6c10 r4:eebf6c10
[    4.625334] [<c033b770>] (__device_attach) from [<c033be8c>] (device_initial_probe+0x14/0x18)
[    4.625341]  r7:ee21ae00 r6:c08237c8 r5:eebf6c10 r4:eebf6c10
[    4.625345] [<c033be78>] (device_initial_probe) from [<c033ae78>] (bus_probe_device+0x90/0x98)
[    4.625350] [<c033ade8>] (bus_probe_device) from [<c033b2c8>] (deferred_probe_work_func+0x70/0xa4)
[    4.625356]  r6:c08234cc r5:c0823488 r4:eebf6c10 r3:00000000
[    4.625361] [<c033b258>] (deferred_probe_work_func) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[    4.625368]  r6:ee80ac00 r5:ee867100 r4:c0823504 r3:c033b258
[    4.625372] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[    4.625380]  r10:ee867100 r9:ee80ac00 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee867118
[    4.625383]  r4:ee80ac00
[    4.625388] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[    4.625397]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee867100 r5:ee8fe040
[    4.625399]  r4:00000000
[    4.625405] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[    4.625412]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee8fe040
[    4.625416] Code: e1a0c00d e92dd800 e24cb004 e590327c (e5130030) 
[    4.625419] ---[ end trace 963a396567424828 ]---
[    4.625422] Fixing recursive fault but reboot is needed!
[   38.324856] BUG: spinlock lockup suspected on CPU#2, kworker/u8:1/29
[   38.325573]  lock: 0xeef87480, .magic: dead4ead, .owner: kworker/u8:1/29, .owner_cpu: 2
[   38.331622] BUG: spinlock lockup suspected on CPU#3, kworker/u8:0/6
[   38.331630]  lock: 0xeef87480, .magic: dead4ead, .owner: kworker/u8:1/29, .owner_cpu: 2
[   38.331637] CPU: 3 PID: 6 Comm: kworker/u8:0 Tainted: G      D         4.4.0-debug+ #2
[   38.331639] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   38.331663] Workqueue: events_unbound call_usermodehelper_exec_work
[   38.331667] Backtrace: 
[   38.331680] [<c0014768>] (dump_backtrace) from [<c0014964>] (show_stack+0x18/0x1c)
[   38.331689]  r6:c081a80c r5:c081a80c r4:00000000 r3:dc8ba600
[   38.331703] [<c001494c>] (show_stack) from [<c0271b38>] (dump_stack+0x8c/0xcc)
[   38.331717] [<c0271aac>] (dump_stack) from [<c007b0d8>] (spin_dump+0x84/0xa4)
[   38.331725]  r6:02700600 r5:eef87480 r4:ee9e8bc0 r3:00000000
[   38.331730] [<c007b054>] (spin_dump) from [<c007b294>] (do_raw_spin_lock+0x104/0x1b8)
[   38.331735]  r5:c081a7f4 r4:eef87480
[   38.331747] [<c007b190>] (do_raw_spin_lock) from [<c05b5f2c>] (_raw_spin_lock+0x4c/0x54)
[   38.331756]  r9:c07f86bc r8:40000053 r7:ee165600 r6:c07f3480 r5:c0055944 r4:eef87480
[   38.331774] [<c05b5ee0>] (_raw_spin_lock) from [<c0055944>] (wake_up_new_task+0xf8/0x3c4)
[   38.331778] BUG: spinlock lockup suspected on CPU#0, kworker/u8:3/47
[   38.331785]  r5:eef87480
[   38.331786]  lock: 0xeef87480, .magic: dead4ead, .owner: kworker/u8:1/29, .owner_cpu: 2
[   38.331789]  r4:ee165240
[   38.331797] [<c005584c>] (wake_up_new_task) from [<c00288b4>] (_do_fork+0x130/0x7c4)
[   38.331806]  r10:00000001 r9:eebc93c0 r8:00000000 r7:0000035a r6:c07f8448 r5:00000000
[   38.331809]  r4:ee165240
[   38.331814] [<c0028784>] (_do_fork) from [<c0028fa8>] (kernel_thread+0x38/0x40)
[   38.331823]  r10:00000001 r9:c083b258 r8:ee8a5ea8 r7:ee80cc00 r6:ee80ac00 r5:ee849f80
[   38.331826]  r4:ee37fc80
[   38.331832] [<c0028f70>] (kernel_thread) from [<c0041824>] (call_usermodehelper_exec_work+0x34/0xc4)
[   38.331837] [<c00417f0>] (call_usermodehelper_exec_work) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[   38.331840]  r4:ee37fc80
[   38.331844] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[   38.331853]  r10:ee849f80 r9:ee80ac00 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee849f98
[   38.331856]  r4:ee80ac00
[   38.331862] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[   38.331870]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee849f80 r5:ee84b700
[   38.331873]  r4:00000000
[   38.331879] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[   38.331886]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee84b700
[   38.331890] CPU: 0 PID: 47 Comm: kworker/u8:3 Tainted: G      D         4.4.0-debug+ #2
[   38.331892] Sending NMI to all CPUs:
[   38.331894] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   38.331902] Workqueue: events_unbound call_usermodehelper_exec_work
[   38.331905] Backtrace: 
[   38.331913] [<c0014768>] (dump_backtrace) from [<c0014964>] (show_stack+0x18/0x1c)
[   38.331922]  r6:c081a80c r5:c081a80c r4:00000000 r3:dc8ba600
[   38.331928] [<c001494c>] (show_stack) from [<c0271b38>] (dump_stack+0x8c/0xcc)
[   38.331933] [<c0271aac>] (dump_stack) from [<c007b0d8>] (spin_dump+0x84/0xa4)
[   38.331941]  r6:02700600 r5:eef87480 r4:ee9e8bc0 r3:00000000
[   38.331946] [<c007b054>] (spin_dump) from [<c007b294>] (do_raw_spin_lock+0x104/0x1b8)
[   38.331951]  r5:c081a7f4 r4:eef87480
[   38.331957] [<c007b190>] (do_raw_spin_lock) from [<c05b5f2c>] (_raw_spin_lock+0x4c/0x54)
[   38.331966]  r9:c07f86bc r8:40000053 r7:ee08a700 r6:c07f3480 r5:c0055944 r4:eef87480
[   38.331972] [<c05b5ee0>] (_raw_spin_lock) from [<c0055944>] (wake_up_new_task+0xf8/0x3c4)
[   38.331977]  r5:eef87480 r4:ee08a340
[   38.331983] [<c005584c>] (wake_up_new_task) from [<c00288b4>] (_do_fork+0x130/0x7c4)
[   38.331992]  r10:00000001 r9:ee3a2080 r8:00000000 r7:0000035b r6:c07f8448 r5:00000000
[   38.331995]  r4:ee08a340
[   38.331999] [<c0028784>] (_do_fork) from [<c0028fa8>] (kernel_thread+0x38/0x40)
[   38.332008]  r10:00000001 r9:c083b258 r8:eea17ea8 r7:ee80cc00 r6:ee80ac00 r5:ee867280
[   38.332012]  r4:ee37fd00
[   38.332018] [<c0028f70>] (kernel_thread) from [<c0041824>] (call_usermodehelper_exec_work+0x34/0xc4)
[   38.332024] [<c00417f0>] (call_usermodehelper_exec_work) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[   38.332027]  r4:ee37fd00
[   38.332032] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[   38.332041]  r10:ee867280 r9:00000000 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee867298
[   38.332044]  r4:ee80ac00
[   38.332049] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[   38.332058]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee867280 r5:ee8fe080
[   38.332061]  r4:00000000
[   38.332066] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[   38.332073]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee8fe080
[   38.768246] CPU: 2 PID: 29 Comm: kworker/u8:1 Tainted: G      D         4.4.0-debug+ #2
[   38.776230] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   38.782311] Backtrace: 
[   38.784742] [<c0014768>] (dump_backtrace) from [<c0014964>] (show_stack+0x18/0x1c)
[   38.792288]  r6:c081a80c r5:c081a80c r4:00000000 r3:dc8ba600
[   38.797933] [<c001494c>] (show_stack) from [<c0271b38>] (dump_stack+0x8c/0xcc)
[   38.805138] [<c0271aac>] (dump_stack) from [<c007b0d8>] (spin_dump+0x84/0xa4)
[   38.812252]  r6:02700600 r5:eef87480 r4:ee9e8bc0 r3:00000000
[   38.817897] [<c007b054>] (spin_dump) from [<c007b294>] (do_raw_spin_lock+0x104/0x1b8)
[   38.825706]  r5:c081a7f4 r4:eef87480
[   38.829269] [<c007b190>] (do_raw_spin_lock) from [<c05b6158>] (_raw_spin_lock_irq+0x54/0x5c)
[   38.837684]  r9:c07f86bc r8:00000002 r7:c004cde0 r6:c07f3480 r5:c05afc40 r4:eef87480
[   38.845413] [<c05b6104>] (_raw_spin_lock_irq) from [<c05afc40>] (__schedule+0xd4/0x994)
[   38.853395]  r5:ee9e8bc0 r4:eef87480
[   38.856956] [<c05afb6c>] (__schedule) from [<c05b070c>] (schedule+0x50/0xb0)
[   38.863984]  r10:c08402c4 r9:00000001 r8:c004cdde r7:c004cde0 r6:0000000b r5:0000000b
[   38.871796]  r4:eea0c000
[   38.874319] [<c05b06bc>] (schedule) from [<c002cb4c>] (do_exit+0x940/0xbe8)
[   38.881258]  r4:ee9e8bc0 r3:ee9e8bc0
[   38.884819] [<c002c20c>] (do_exit) from [<c0014de0>] (die+0x478/0x490)
[   38.891326]  r7:c004cde0
[   38.893851] [<c0014968>] (die) from [<c0023ee4>] (__do_kernel_fault.part.0+0x6c/0x1ec)
[   38.901742]  r10:00000000 r9:c07f86bc r8:ffffffd0 r7:00000000 r6:eea0da18 r5:00000037
[   38.909554]  r4:ffffffd0
[   38.912076] [<c0023e78>] (__do_kernel_fault.part.0) from [<c001f96c>] (do_page_fault+0x39c/0x3ac)
[   38.920925]  r7:00000037 r3:eea0da18
[   38.924486] [<c001f5d0>] (do_page_fault) from [<c0009390>] (do_DataAbort+0x40/0xbc)
[   38.932122]  r10:00000000 r9:c07f86bc r8:eea0da18 r7:ffffffd0 r6:c001f5d0 r5:00000037
[   38.939934]  r4:c07fd524
[   38.942454] [<c0009350>] (do_DataAbort) from [<c00154a4>] (__dabt_svc+0x44/0x80)
[   38.949830] Exception stack(0xeea0da18 to 0xeea0da60)
[   38.954867] da00:                                                       ee9e8bc0 00000002
[   38.963027] da20: 00000000 00000000 00000002 ee9e8bc0 c07f3480 ee9e8e88 00000002 c07f86bc
[   38.971186] da40: 00000000 eea0da74 eea0da78 eea0da68 c00469b4 c004cddc 000001d3 ffffffff
[   38.979341]  r8:00000002 r7:eea0da4c r6:ffffffff r5:000001d3 r4:c004cddc
[   38.986029] [<c004cdcc>] (kthread_data) from [<c00469b4>] (wq_worker_sleeping+0x14/0xd8)
[   38.994100] [<c00469a0>] (wq_worker_sleeping) from [<c05affec>] (__schedule+0x480/0x994)
[   39.002170]  r5:ee9e8bc0 r4:eef87480
[   39.005731] [<c05afb6c>] (__schedule) from [<c05b070c>] (schedule+0x50/0xb0)
[   39.012760]  r10:00000000 r9:ee878000 r8:c0458a6a r7:ee9e8de4 r6:eea0db10 r5:eea0d8d0
[   39.020571]  r4:eea0c000
[   39.023092] [<c05b06bc>] (schedule) from [<c002c95c>] (do_exit+0x750/0xbe8)
[   39.030033]  r4:ee9e8bc0 r3:0420806c
[   39.033594] [<c002c20c>] (do_exit) from [<c0014de0>] (die+0x478/0x490)
[   39.040102]  r7:c0458a6c
[   39.042622] [<c0014968>] (die) from [<c0023ee4>] (__do_kernel_fault.part.0+0x6c/0x1ec)
[   39.050517]  r10:eebf6c10 r9:eefcc8c4 r8:fffffffc r7:00000000 r6:eea0dce0 r5:00000037
[   39.058329]  r4:fffffffc
[   39.060852] [<c0023e78>] (__do_kernel_fault.part.0) from [<c001f96c>] (do_page_fault+0x39c/0x3ac)
[   39.069700]  r7:00000037 r3:eea0dce0
[   39.073262] [<c001f5d0>] (do_page_fault) from [<c0009390>] (do_DataAbort+0x40/0xbc)
[   39.080898]  r10:eebf6c10 r9:eefcc8c4 r8:eea0dce0 r7:fffffffc r6:c001f5d0 r5:00000037
[   39.088709]  r4:c07fd524
[   39.091229] [<c0009350>] (do_DataAbort) from [<c00154a4>] (__dabt_svc+0x44/0x80)
[   39.098605] Exception stack(0xeea0dce0 to 0xeea0dd28)
[   39.103643] dce0: c076141c eeba8480 00000000 3fffffff 10624dd3 00000000 eebf6c10 eebf6c00
[   39.111802] dd00: ee9464d0 eefcc8c4 eebf6c10 eea0dd7c eea0dcc0 eea0dd30 c00749dc c0458a68
[   39.119958] dd20: 60000053 ffffffff
[   39.123430]  r8:ee9464d0 r7:eea0dd14 r6:ffffffff r5:60000053 r4:c0458a68
[   39.130127] [<c0458848>] (exynos_bus_probe) from [<c033dc78>] (platform_drv_probe+0x58/0xb4)
[   39.138533]  r10:00000001 r9:c083b258 r8:00000003 r7:fffffdfb r6:c082e820 r5:eebf6c10
[   39.146345]  r4:fffffffe
[   39.148867] [<c033dc20>] (platform_drv_probe) from [<c033bad4>] (driver_probe_device+0x210/0x304)
[   39.157716]  r7:c082e820 r6:00000000 r5:eebf6c10 r4:c10203b4
[   39.163360] [<c033b8c4>] (driver_probe_device) from [<c033bd30>] (__device_attach_driver+0x88/0x94)
[   39.172385]  r8:eea0dea8 r7:00000001 r6:eebf6c10 r5:eea0de10 r4:c082e820 r3:00000000
[   39.180115] [<c033bca8>] (__device_attach_driver) from [<c0339dcc>] (bus_for_each_drv+0x6c/0xa0)
[   39.188877]  r6:c033bca8 r5:eea0de10 r4:00000000 r3:ee2bba60
[   39.194521] [<c0339d60>] (bus_for_each_drv) from [<c033b820>] (__device_attach+0xb0/0x110)
[   39.202765]  r6:eebf6c44 r5:eebf6c10 r4:eebf6c10
[   39.207368] [<c033b770>] (__device_attach) from [<c033be8c>] (device_initial_probe+0x14/0x18)
[   39.215872]  r7:ee21ae00 r6:c08237c8 r5:eebf6c10 r4:eebf6c10
[   39.221516] [<c033be78>] (device_initial_probe) from [<c033ae78>] (bus_probe_device+0x90/0x98)
[   39.230111] [<c033ade8>] (bus_probe_device) from [<c033b2c8>] (deferred_probe_work_func+0x70/0xa4)
[   39.239047]  r6:c08234cc r5:c0823488 r4:eebf6c10 r3:00000000
[   39.244692] [<c033b258>] (deferred_probe_work_func) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[   39.253803]  r6:ee80ac00 r5:ee867100 r4:c0823504 r3:c033b258
[   39.259448] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[   39.267518]  r10:ee867100 r9:ee80ac00 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee867118
[   39.275330]  r4:ee80ac00
[   39.277850] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[   39.285225]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee867100 r5:ee8fe040
[   39.293036]  r4:00000000
[   39.295558] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[   39.302758]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee8fe040
[   48.337745] NMI backtrace for cpu 1
[   48.337807] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G      D         4.4.0-debug+ #2
[   48.343221] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   48.349297] task: ee8b0bc0 ti: ee8b8000 task.ti: ee8b8000
[   48.354679] PC is at arch_cpu_idle+0x2c/0x44
[   48.358932] LR is at trace_hardirqs_on+0x14/0x18
[   48.363532] pc : [<c0010964>]    lr : [<c00749dc>]    psr: 60000053
[   48.369782] sp : ee8b9f98  ip : ee8b9f88  fp : ee8b9fa4
[   48.374990] r10: 00000000  r9 : 00000000  r8 : c083a82e
[   48.380199] r7 : c05b9ed0  r6 : c083b7d0  r5 : c07f8520  r4 : ee8b8000
[   48.386708] r3 : c0022c20  r2 : 00000000  r1 : 00000000  r0 : c0010960
[   48.393218] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
[   48.400422] Control: 10c5387d  Table: 4000404a  DAC: 00000051
[   48.406151] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G      D         4.4.0-debug+ #2
[   48.413790] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   48.419865] Backtrace: 
[   48.422296] [<c0014768>] (dump_backtrace) from [<c0014964>] (show_stack+0x18/0x1c)
[   48.429848]  r6:c081a80c r5:c081a80c r4:00000000 r3:dc8ba600
[   48.435491] [<c001494c>] (show_stack) from [<c0271b38>] (dump_stack+0x8c/0xcc)
[   48.442695] [<c0271aac>] (dump_stack) from [<c0010bec>] (show_regs+0x14/0x18)
[   48.449811]  r6:c07ef3f0 r5:00000001 r4:ee8b9f48 r3:dc8ba600
[   48.455454] [<c0010bd8>] (show_regs) from [<c027674c>] (nmi_cpu_backtrace+0xd4/0x11c)
[   48.463266] [<c0276678>] (nmi_cpu_backtrace) from [<c0016ecc>] (handle_IPI+0x144/0x3b4)
[   48.471251]  r7:ee8b9f48 r6:c07f064c r5:c07f064c r4:0000000f
[   48.476893] [<c0016d88>] (handle_IPI) from [<c0009544>] (gic_handle_irq+0x98/0x9c)
[   48.484445]  r10:00000000 r9:f0825000 r8:f0824000 r7:ee8b9f48 r6:f082400c r5:c081acf4
[   48.492257]  r4:c07f8844
[   48.494774] [<c00094ac>] (gic_handle_irq) from [<c0015538>] (__irq_svc+0x58/0x98)
[   48.502239] Exception stack(0xee8b9f48 to 0xee8b9f90)
[   48.507274] 9f40:                   c0010960 00000000 00000000 c0022c20 ee8b8000 c07f8520
[   48.515433] 9f60: c083b7d0 c05b9ed0 c083a82e 00000000 00000000 ee8b9fa4 ee8b9f88 ee8b9f98
[   48.523591] 9f80: c00749dc c0010964 60000053 ffffffff
[   48.528626]  r9:00000000 r8:c083a82e r7:ee8b9f7c r6:ffffffff r5:60000053 r4:c0010964
[   48.536351] [<c0010938>] (arch_cpu_idle) from [<c006e578>] (default_idle_call+0x28/0x38)
[   48.544424] [<c006e550>] (default_idle_call) from [<c006e9a8>] (cpu_startup_entry+0x3c8/0x434)
[   48.553017] [<c006e5e0>] (cpu_startup_entry) from [<c0016b90>] (secondary_start_kernel+0xf4/0xfc)
[   48.561870]  r7:c0840328
[   48.564388] [<c0016a9c>] (secondary_start_kernel) from [<400095ec>] (0x400095ec)
[   48.571765]  r5:00000051 r4:6e89406a
[   48.575326] NMI backtrace for cpu 3
[   48.578797] CPU: 3 PID: 6 Comm: kworker/u8:0 Tainted: G      D         4.4.0-debug+ #2
[   48.586695] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   48.592771] Workqueue: events_unbound call_usermodehelper_exec_work
[   48.599020] Backtrace: 
[   48.601452] [<c0014768>] (dump_backtrace) from [<c0014964>] (show_stack+0x18/0x1c)
[   48.609003]  r6:c081a80c r5:c081a80c r4:00000000 r3:dc8ba600
[   48.614645] [<c001494c>] (show_stack) from [<c0271b38>] (dump_stack+0x8c/0xcc)
[   48.621849] [<c0271aac>] (dump_stack) from [<c0276790>] (nmi_cpu_backtrace+0x118/0x11c)
[   48.629835]  r6:c07ef3f0 r5:00000003 r4:00000000 r3:ee8a4000
[   48.635477] [<c0276678>] (nmi_cpu_backtrace) from [<c0016748>] (raise_nmi+0x5c/0x60)
[   48.643202]  r7:c07f85a0 r6:c07f86bc r5:c07f8818 r4:c07f8818
[   48.648845] [<c00166ec>] (raise_nmi) from [<c027666c>] (nmi_trigger_all_cpu_backtrace+0x29c/0x2a8)
[   48.657784]  r4:c07f0650 r3:c00166ec
[   48.661344] [<c02763d0>] (nmi_trigger_all_cpu_backtrace) from [<c0017258>] (arch_trigger_all_cpu_backtrace+0x18/0x1c)
[   48.671933]  r10:00000001 r9:00000000 r8:02700600 r7:00000000 r6:02700600 r5:c081a7f4
[   48.679745]  r4:eef87480
[   48.682262] [<c0017240>] (arch_trigger_all_cpu_backtrace) from [<c007b29c>] (do_raw_spin_lock+0x10c/0x1b8)
[   48.691897] [<c007b190>] (do_raw_spin_lock) from [<c05b5f2c>] (_raw_spin_lock+0x4c/0x54)
[   48.699969]  r9:c07f86bc r8:40000053 r7:ee165600 r6:c07f3480 r5:c0055944 r4:eef87480
[   48.707695] [<c05b5ee0>] (_raw_spin_lock) from [<c0055944>] (wake_up_new_task+0xf8/0x3c4)
[   48.715853]  r5:eef87480 r4:ee165240
[   48.719413] [<c005584c>] (wake_up_new_task) from [<c00288b4>] (_do_fork+0x130/0x7c4)
[   48.727138]  r10:00000001 r9:eebc93c0 r8:00000000 r7:0000035a r6:c07f8448 r5:00000000
[   48.734949]  r4:ee165240
[   48.737467] [<c0028784>] (_do_fork) from [<c0028fa8>] (kernel_thread+0x38/0x40)
[   48.744758]  r10:00000001 r9:c083b258 r8:ee8a5ea8 r7:ee80cc00 r6:ee80ac00 r5:ee849f80
[   48.752570]  r4:ee37fc80
[   48.755087] [<c0028f70>] (kernel_thread) from [<c0041824>] (call_usermodehelper_exec_work+0x34/0xc4)
[   48.764201] [<c00417f0>] (call_usermodehelper_exec_work) from [<c00455bc>] (process_one_work+0x20c/0x74c)
[   48.773749]  r4:ee37fc80
[   48.776268] [<c00453b0>] (process_one_work) from [<c0045b4c>] (worker_thread+0x50/0x4f0)
[   48.784340]  r10:ee849f80 r9:ee80ac00 r8:c0045bc4 r7:00000088 r6:ee80ac30 r5:ee849f98
[   48.792150]  r4:ee80ac00
[   48.794670] [<c0045afc>] (worker_thread) from [<c004c3ac>] (kthread+0x108/0x120)
[   48.802046]  r10:00000000 r9:00000000 r8:00000000 r7:c0045afc r6:ee849f80 r5:ee84b700
[   48.809858]  r4:00000000
[   48.812375] [<c004c2a4>] (kthread) from [<c000feb0>] (ret_from_fork+0x14/0x24)
[   48.819579]  r7:00000000 r6:00000000 r5:c004c2a4 r4:ee84b700

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
  2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
                   ` (20 preceding siblings ...)
  2016-01-19  9:13 ` [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Tobias Jakobi
@ 2016-02-19 15:05 ` Tobias Jakobi
  2016-02-22  1:00   ` Chanwoo Choi
  21 siblings, 1 reply; 33+ messages in thread
From: Tobias Jakobi @ 2016-02-19 15:05 UTC (permalink / raw)
  To: Chanwoo Choi, myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, tjakobi, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

[-- Attachment #1: Type: text/plain, Size: 12889 bytes --]

Hello,

I've applied the patchset to 4.5-rc4 and I'm now encountering two
additional problems. The first related to debugfs entries, the second
cocerning RCU locking.

Here are the debugfs lines:
exynos-bus bus_dmc: device_opp_debug_create_link: Failed to create link
exynos-bus bus_dmc: _add_list_dev: Failed to register opp debugfs (-12)
exynos-bus bus_dmc: Looking up vdd-supply from device tree
exynos-bus: new bus device registered: bus_dmc (100000 KHz ~ 400000 KHz)
exynos-bus bus_acp: device_opp_debug_create_link: Failed to create link
exynos-bus bus_acp: _add_list_dev: Failed to register opp debugfs (-12)
exynos-bus: new bus device registered: bus_acp (100000 KHz ~ 267000 KHz)
exynos-bus bus_c2c: device_opp_debug_create_link: Failed to create link
exynos-bus bus_c2c: _add_list_dev: Failed to register opp debugfs (-12)
exynos-bus: new bus device registered: bus_c2c (100000 KHz ~ 400000 KHz)
exynos-bus bus_leftbus: device_opp_debug_create_link: Failed to create link
devfreq bus_dmc: Couldn't update frequency transition information.
exynos-bus bus_leftbus: _add_list_dev: Failed to register opp debugfs (-12)
exynos-bus bus_leftbus: Looking up vdd-supply from device tree


The RCU output is a bit longer, so I attached it.


With best wishes,
Tobias


Chanwoo Choi wrote:
> This patch-set includes the two features as following. The generic exynos bus
> frequency driver is able to support almost Exynos SoCs for bus frequency
> scaling. And the new passive governor is able to make the dependency on
> between devices for frequency/voltage scaling. I had posted the patch-set[2]
> with the similiar concept. This is is revised version for exynos bus frequency.
> - Generic exynos bus frequency driver
> - New passive governor of DEVFREQ framework
> 
> Depend on:
> - next-20151210 tag of linux-next (master branch).
> - Merge the latest devfreq patches on devfreq.git[2] (for-rafael branch).
> [1] https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/ (branch: for-rafael)
> [2] https://lkml.org/lkml/2015/1/7/872
>    : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver
> 
> Changes from v3:
> (https://lkml.org/lkml/2015/12/11/75)
> - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17)
> - Fix typo of the description on patch14
> - Modify the subject and description of patch17
> - Reorder the 'bus_xxx' device tree node alphabetically in 
>   both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3
> 
> Changes from v2:
> (https://lkml.org/lkml/2015/12/8/869)
> - Fix typo on documentation
> - Modify the more appropriate sentence on patch description
> - Add the detailed description about both parent and passive bus device
> - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz)
> - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> 825mV)
> - Rename OPP nodes as 'opp@<opp-hz>'
> - Delete the duplicate 'opp-microvolt' property of passive devfreq device
> - Reorder the 'bus_xxx' device tree node alphabetically in exynos3250-rinato/monk.dts
> - Reorder the 'bus_xxx' device tree node alphabetically in exynos4412-trats/odroidu3
> - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node
>   on rinato/monk/trats2/odroid-u3 board
> - Add the log message if bus device is registered to devfreq framework successfully
> - Add the reviewed-by tag from Krzysztof Kozlowski
> - Add the tested-by tag from Anand Moon on Odroid U3
> - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS
> 
> Changes from v1:
> (https://lkml.org/lkml/2015/11/26/260)
> - Check whether the instance of regulator is NULL or not
>   when executing regulator_disable() because of only parent
>   devfreq device has the regulator instance. After fixing it,
>   the wake-up from suspend state is well working. (patch1)
> - Fix bug which checks 'bus-clk' instead of 'bus->regulator'
>   after calling devm_clk_get() (on patch1)
> - Update the documentation to remove the description about
>   DEVFREQ-EVENT subsystem (on patch2)
> - Add the full name of DMC (Dynamic Memory Controller) (on patch2)
> - Modify the detailed correlation of buses for Exynos3250
>   on documentation (patch2)
> - Add the MFC bus node for Exynos3250 (on patch11, patch12)
> - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi
> - Add the PPMU node for exynos4412-odroidu3
> - Add the support of bus frequency for exynos4412-odroidu3
> 
> Detailed descirption for patch-set:
> 1. Add generic exynos bus frequency driver
> : This patch-set adds the generic exynos bus frequency driver for AXI bus
> of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common
> architecture for bus between DRAM and sub-blocks in SoC.
> 
>  There are the different buses according to Exynos SoC because Exynos SoC
> has the differnt sub-blocks and bus speed. In spite of this difference
> among Exynos SoCs, this driver is able to support almost Exynos SoC by adding
> unique data of each bus in the devicetree file.
> 
>  In devicetree, each bus node has a bus clock, regulator, operation-point
> and devfreq-event devices which measure the utilization of each bus block.
> 
> For example,
> - The bus of DMC block in exynos3250.dtsi are listed below:
> 
> 	bus_dmc: bus_dmc {
> 		compatible = "samsung,exynos-bus";
> 		clocks = <&cmu_dmc CLK_DIV_DMC>;
> 		clock-names = "bus";
> 		operating-points-v2 = <&bus_dmc_opp_table>;
> 		status = "disabled";
> 	};
> 
> 	bus_dmc_opp_table: opp_table1 {
> 		compatible = "operating-points-v2";
> 		opp-shared;
> 
> 		opp@50000000 {
> 			opp-hz = /bits/ 64 <50000000>;
> 			opp-microvolt = <800000>;
> 		};
> 		opp@100000000 {
> 			opp-hz = /bits/ 64 <100000000>;
> 			opp-microvolt = <800000>;
> 		};
> 		opp@134000000 {
> 			opp-hz = /bits/ 64 <134000000>;
> 			opp-microvolt = <800000>;
> 		};
> 		opp@200000000 {
> 			opp-hz = /bits/ 64 <200000000>;
> 			opp-microvolt = <825000>;
> 		};
> 		opp@400000000 {
> 			opp-hz = /bits/ 64 <400000000>;
> 			opp-microvolt = <875000>;
> 		};
> 	};
> 
> - Usage case to handle the frequency and voltage of bus on runtime
>   in exynos3250-rinato.dts are listed below:
> 
> 	&bus_dmc {
> 		devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
> 		vdd-supply = <&buck1_reg>;	/* VDD_MIF */
> 		status = "okay";
> 	};
> 
> 2. Add new passive governor of DEVFREQ framework (patch5-patch7)
> : This patch-set add the new passive governor for DEVFREQ framework.
> The existing governors (ondemand, performance and so on) are used for DVFS
> (Dynamic Voltage and Frequency Scaling) drivers. The existing governors
> are independently used for specific device driver which don't give the
> influence to other device drviers and also don't receive the effect from
> other device drivers.
> 
>  The passive governor depends on operation of parent driver with existing
> governors(ondemand, performance and so on) extremely and is not able to
> decide the new frequency by oneself. According to the decided new frequency
> of parent driver with governor, the passive governor uses it to decide
> the appropriate frequency for own device driver. The passive governor
> must need the following information from device tree:
> 
> For exameple,
>  There are one more bus device drivers in Exynos3250 which need to
> change their source clock according to their utilization on runtime.
> But, they share the same power line (e.g., regulator). So, LEFTBUS bus
> driver is operated as parent with ondemand governor and then the rest
> device driver with passive governor.
> 
>  The buses of Internal block in exynos3250.dtsi are listed below:
> When LEFTBUS bus driver (parent) changes the bus frequency with
> ondemand governor on runtime, the rest bus devices which sharing
> the same power line (VDD_INT) will change the each bus frequency
> according to the decision of LEFTBUS bus driver (parent).
> 
> - INT (Internal) block
> 	: VDD_INT |--- LEFTBUS
> 		  |--- PERIL
> 		  |--- MFC
> 		  |--- G3D
> 		  |--- RIGHTBUS
> 		  |--- FSYS
> 		  |--- LCD0
> 		  |--- PERIR
> 		  |--- ISP
> 		  |--- CAM
> 
> - The buss of INT block in exynos3250.dtsi are listed below:
> 	bus_leftbus: bus_leftbus {
> 		compatible = "samsung,exynos-bus";
> 		clocks = <&cmu CLK_DIV_GDL>;
> 		clock-names = "bus";
> 		operating-points-v2 = <&bus_leftbus_opp_table>;
> 		status = "disabled";
> 	};
> 
> 	bus_rightbus: bus_rightbus {
> 		compatible = "samsung,exynos-bus";
> 		clocks = <&cmu CLK_DIV_GDR>;
> 		clock-names = "bus";
> 		operating-points-v2 = <&bus_leftbus_opp_table>;
> 		status = "disabled";
> 	};
> 
> 	(Omit the rest bus dt node)
> 
> - Usage case to handle the frequency and voltage of bus on runtime
>   in exynos3250-rinato.dts are listed below:
> 	/* Parent bus device of VDD_INT */
> 	&bus_leftbus {
> 		devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
> 		vdd-supply = <&buck3_reg>;
> 		status = "okay";
> 	};
> 
> 	/* Passive bus device depend on LEFTBUS bus. */
> 	&bus_rightbus {
> 		devfreq = <&bus_leftbus>; /* 'devfreq' property indicates
> 					     the phandle of parent device. */
> 		status = "okay";
> 	};
> 
> 	(Omit the rest bus dt node)
> 
> Chanwoo Choi (20):
>   PM / devfreq: exynos: Add generic exynos bus frequency driver
>   PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
>   ARM: dts: Add DMC bus node for Exynos3250
>   ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
>   PM / devfreq: Add new passive governor
>   PM / devfreq: Add devfreq_get_devfreq_by_phandle()
>   PM / devfreq: Show the related information according to governor type
>   PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
>   PM / devfreq: exynos: Update documentation for bus devices using passive governor
>   PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
>   PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
>   MAINTAINERS: Add samsung bus frequency driver entry
>   ARM: dts: Add bus nodes using VDD_INT for Exynos3250
>   ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
>   ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
>   ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
>   ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
>   ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
>   ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
>   ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
> 
>  .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++
>  MAINTAINERS                                        |    9 +
>  arch/arm/boot/dts/exynos3250-monk.dts              |   47 +-
>  arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +-
>  arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++
>  arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +-
>  arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 +
>  arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +-
>  arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++
>  drivers/devfreq/Kconfig                            |   37 +-
>  drivers/devfreq/Makefile                           |    2 +
>  drivers/devfreq/devfreq.c                          |  120 ++-
>  drivers/devfreq/exynos/Makefile                    |    3 +-
>  drivers/devfreq/exynos/exynos-bus.c                |  556 +++++++++++
>  drivers/devfreq/exynos/exynos4_bus.c               | 1055 --------------------
>  drivers/devfreq/exynos/exynos4_bus.h               |  110 --
>  drivers/devfreq/exynos/exynos5_bus.c               |  431 --------
>  drivers/devfreq/exynos/exynos_ppmu.c               |  119 ---
>  drivers/devfreq/exynos/exynos_ppmu.h               |   86 --
>  drivers/devfreq/governor.h                         |    7 +
>  drivers/devfreq/governor_passive.c                 |  109 ++
>  drivers/devfreq/governor_performance.c             |    1 +
>  drivers/devfreq/governor_powersave.c               |    1 +
>  drivers/devfreq/governor_simpleondemand.c          |    1 +
>  drivers/devfreq/governor_userspace.c               |    1 +
>  include/linux/devfreq.h                            |   26 +
>  27 files changed, 1955 insertions(+), 1948 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt
>  create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi
>  create mode 100644 drivers/devfreq/exynos/exynos-bus.c
>  delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c
>  delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h
>  delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c
>  delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c
>  delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h
>  create mode 100644 drivers/devfreq/governor_passive.c
> 


[-- Attachment #2: devfreq_rcu.txt --]
[-- Type: text/plain, Size: 3330 bytes --]

[    3.041556] ===============================
[    3.041560] [ INFO: suspicious RCU usage. ]
[    3.041569] 4.5.0-rc4-debug+ #2 Tainted: G        W      
[    3.041572] -------------------------------
[    3.041578] drivers/base/power/opp/core.c:377 Missing rcu_read_lock() or dev_opp_list_lock protection!
[    3.041580] 
               other info that might help us debug this:

[    3.041586] 
               rcu_scheduler_active = 1, debug_locks = 0
[    3.041592] 3 locks held by kworker/u8:3/861:
[    3.041635]  #0:  ("%s"("devfreq_wq")){.+.+..}, at: [<c00463a0>] process_one_work+0x134/0x7ac
[    3.041648]  #1:  ((&(&devfreq->work)->work)){+.+...}, at: [<c00463a0>] process_one_work+0x134/0x7ac
[    3.041675]  #2:  (&devfreq->lock){+.+.+.}, at: [<c0470c98>] devfreq_monitor+0x24/0x80
[    3.041678] 
               stack backtrace:
[    3.041686] CPU: 1 PID: 861 Comm: kworker/u8:3 Tainted: G        W       4.5.0-rc4-debug+ #2
[    3.041688] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[    3.041699] Workqueue: devfreq_wq devfreq_monitor
[    3.041706] Backtrace: 
[    3.041736] [<c0014818>] (dump_backtrace) from [<c0014a14>] (show_stack+0x18/0x1c)
[    3.041749]  r6:c0845660 r5:60000053 r4:00000000 r3:dc8ba700
[    3.041773] [<c00149fc>] (show_stack) from [<c0283f9c>] (dump_stack+0xb0/0xdc)
[    3.041787] [<c0283eec>] (dump_stack) from [<c007435c>] (lockdep_rcu_suspicious+0xe8/0x11c)
[    3.041800]  r8:ee381ea8 r7:c0757330 r6:00000179 r5:c0757350 r4:ee098c80 r3:00000000
[    3.041817] [<c0074274>] (lockdep_rcu_suspicious) from [<c0366bb4>] (dev_pm_opp_find_freq_ceil+0xe8/0x100)
[    3.041827]  r7:ee932a00 r6:c0865ac0 r5:eeb43410 r4:ee381e1c
[    3.041835] [<c0366acc>] (dev_pm_opp_find_freq_ceil) from [<c0472928>] (devfreq_recommended_opp+0x3c/0x54)
[    3.041845]  r6:ee381e1c r5:eeb43410 r4:ee381e1c r3:03c1f399
[    3.041852] [<c04728ec>] (devfreq_recommended_opp) from [<c0473568>] (devfreq_passive_get_target_freq+0xd8/0xfc)
[    3.041858]  r5:ee35e400 r4:ee35dc00
[    3.041864] [<c0473490>] (devfreq_passive_get_target_freq) from [<c0470950>] (update_devfreq_passive+0x48/0x94)
[    3.041875]  r6:03c1f399 r5:ee35df3c r4:ee35e400 r3:c0473490
[    3.041881] [<c0470908>] (update_devfreq_passive) from [<c0470b50>] (update_devfreq+0x12c/0x168)
[    3.041889]  r6:00000000 r5:ee35df3c r4:ee35dc00
[    3.041895] [<c0470a24>] (update_devfreq) from [<c0470ca0>] (devfreq_monitor+0x2c/0x80)
[    3.041904]  r6:ee35dc00 r5:ee35dc08 r4:ee35deb4
[    3.041910] [<c0470c74>] (devfreq_monitor) from [<c0046474>] (process_one_work+0x208/0x7ac)
[    3.041920]  r6:ee80ac00 r5:ee35deb4 r4:ee12d600 r3:c0470c74
[    3.041925] [<c004626c>] (process_one_work) from [<c0046a64>] (worker_thread+0x4c/0x514)
[    3.041938]  r10:ee12d600 r9:ee380000 r8:c0822100 r7:ee80ac34 r6:00000088 r5:ee12d618
[    3.041942]  r4:ee80ac00
[    3.041956] [<c0046a18>] (worker_thread) from [<c004d74c>] (kthread+0x108/0x120)
[    3.041969]  r10:00000000 r9:00000000 r8:00000000 r7:c0046a18 r6:ee12d600 r5:ee1ea340
[    3.041973]  r4:00000000
[    3.041982] [<c004d644>] (kthread) from [<c000ff30>] (ret_from_fork+0x14/0x24)
[    3.041992]  r7:00000000 r6:00000000 r5:c004d644 r4:ee1ea340
[    3.083806] devfreq bus_leftbus: Couldn't update frequency transition information.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor
  2016-02-19 15:05 ` Tobias Jakobi
@ 2016-02-22  1:00   ` Chanwoo Choi
  0 siblings, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2016-02-22  1:00 UTC (permalink / raw)
  To: Tobias Jakobi, myungjoo.ham, k.kozlowski, kgene
  Cc: kyungmin.park, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux, linux.amoon, linux-kernel, linux-pm,
	linux-samsung-soc, devicetree

Hello Tobias,

On 2016년 02월 20일 00:05, Tobias Jakobi wrote:
> Hello,
> 
> I've applied the patchset to 4.5-rc4 and I'm now encountering two
> additional problems. The first related to debugfs entries, the second
> cocerning RCU locking.
> 
> Here are the debugfs lines:
> exynos-bus bus_dmc: device_opp_debug_create_link: Failed to create link
> exynos-bus bus_dmc: _add_list_dev: Failed to register opp debugfs (-12)
> exynos-bus bus_dmc: Looking up vdd-supply from device tree
> exynos-bus: new bus device registered: bus_dmc (100000 KHz ~ 400000 KHz)
> exynos-bus bus_acp: device_opp_debug_create_link: Failed to create link
> exynos-bus bus_acp: _add_list_dev: Failed to register opp debugfs (-12)
> exynos-bus: new bus device registered: bus_acp (100000 KHz ~ 267000 KHz)
> exynos-bus bus_c2c: device_opp_debug_create_link: Failed to create link
> exynos-bus bus_c2c: _add_list_dev: Failed to register opp debugfs (-12)
> exynos-bus: new bus device registered: bus_c2c (100000 KHz ~ 400000 KHz)
> exynos-bus bus_leftbus: device_opp_debug_create_link: Failed to create link
> devfreq bus_dmc: Couldn't update frequency transition information.
> exynos-bus bus_leftbus: _add_list_dev: Failed to register opp debugfs (-12)
> exynos-bus bus_leftbus: Looking up vdd-supply from device tree
> 
> 
> The RCU output is a bit longer, so I attached it.

Thanks for your test and report.

I'm re-implementing this patchset related to devfreq core.
I'll check the issue and resolve it.

Best Regards,
Chanwoo Choi

> 
> 
> With best wishes,
> Tobias
> 
> 
> Chanwoo Choi wrote:
>> This patch-set includes the two features as following. The generic exynos bus
>> frequency driver is able to support almost Exynos SoCs for bus frequency
>> scaling. And the new passive governor is able to make the dependency on
>> between devices for frequency/voltage scaling. I had posted the patch-set[2]
>> with the similiar concept. This is is revised version for exynos bus frequency.
>> - Generic exynos bus frequency driver
>> - New passive governor of DEVFREQ framework
>>
>> Depend on:
>> - next-20151210 tag of linux-next (master branch).
>> - Merge the latest devfreq patches on devfreq.git[2] (for-rafael branch).
>> [1] https://git.kernel.org/cgit/linux/kernel/git/mzx/devfreq.git/ (branch: for-rafael)
>> [2] https://lkml.org/lkml/2015/1/7/872
>>    : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver
>>
>> Changes from v3:
>> (https://lkml.org/lkml/2015/12/11/75)
>> - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17)
>> - Fix typo of the description on patch14
>> - Modify the subject and description of patch17
>> - Reorder the 'bus_xxx' device tree node alphabetically in 
>>   both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3
>>
>> Changes from v2:
>> (https://lkml.org/lkml/2015/12/8/869)
>> - Fix typo on documentation
>> - Modify the more appropriate sentence on patch description
>> - Add the detailed description about both parent and passive bus device
>> - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz)
>> - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> 825mV)
>> - Rename OPP nodes as 'opp@<opp-hz>'
>> - Delete the duplicate 'opp-microvolt' property of passive devfreq device
>> - Reorder the 'bus_xxx' device tree node alphabetically in exynos3250-rinato/monk.dts
>> - Reorder the 'bus_xxx' device tree node alphabetically in exynos4412-trats/odroidu3
>> - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node
>>   on rinato/monk/trats2/odroid-u3 board
>> - Add the log message if bus device is registered to devfreq framework successfully
>> - Add the reviewed-by tag from Krzysztof Kozlowski
>> - Add the tested-by tag from Anand Moon on Odroid U3
>> - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS
>>
>> Changes from v1:
>> (https://lkml.org/lkml/2015/11/26/260)
>> - Check whether the instance of regulator is NULL or not
>>   when executing regulator_disable() because of only parent
>>   devfreq device has the regulator instance. After fixing it,
>>   the wake-up from suspend state is well working. (patch1)
>> - Fix bug which checks 'bus-clk' instead of 'bus->regulator'
>>   after calling devm_clk_get() (on patch1)
>> - Update the documentation to remove the description about
>>   DEVFREQ-EVENT subsystem (on patch2)
>> - Add the full name of DMC (Dynamic Memory Controller) (on patch2)
>> - Modify the detailed correlation of buses for Exynos3250
>>   on documentation (patch2)
>> - Add the MFC bus node for Exynos3250 (on patch11, patch12)
>> - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi
>> - Add the PPMU node for exynos4412-odroidu3
>> - Add the support of bus frequency for exynos4412-odroidu3
>>
>> Detailed descirption for patch-set:
>> 1. Add generic exynos bus frequency driver
>> : This patch-set adds the generic exynos bus frequency driver for AXI bus
>> of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common
>> architecture for bus between DRAM and sub-blocks in SoC.
>>
>>  There are the different buses according to Exynos SoC because Exynos SoC
>> has the differnt sub-blocks and bus speed. In spite of this difference
>> among Exynos SoCs, this driver is able to support almost Exynos SoC by adding
>> unique data of each bus in the devicetree file.
>>
>>  In devicetree, each bus node has a bus clock, regulator, operation-point
>> and devfreq-event devices which measure the utilization of each bus block.
>>
>> For example,
>> - The bus of DMC block in exynos3250.dtsi are listed below:
>>
>> 	bus_dmc: bus_dmc {
>> 		compatible = "samsung,exynos-bus";
>> 		clocks = <&cmu_dmc CLK_DIV_DMC>;
>> 		clock-names = "bus";
>> 		operating-points-v2 = <&bus_dmc_opp_table>;
>> 		status = "disabled";
>> 	};
>>
>> 	bus_dmc_opp_table: opp_table1 {
>> 		compatible = "operating-points-v2";
>> 		opp-shared;
>>
>> 		opp@50000000 {
>> 			opp-hz = /bits/ 64 <50000000>;
>> 			opp-microvolt = <800000>;
>> 		};
>> 		opp@100000000 {
>> 			opp-hz = /bits/ 64 <100000000>;
>> 			opp-microvolt = <800000>;
>> 		};
>> 		opp@134000000 {
>> 			opp-hz = /bits/ 64 <134000000>;
>> 			opp-microvolt = <800000>;
>> 		};
>> 		opp@200000000 {
>> 			opp-hz = /bits/ 64 <200000000>;
>> 			opp-microvolt = <825000>;
>> 		};
>> 		opp@400000000 {
>> 			opp-hz = /bits/ 64 <400000000>;
>> 			opp-microvolt = <875000>;
>> 		};
>> 	};
>>
>> - Usage case to handle the frequency and voltage of bus on runtime
>>   in exynos3250-rinato.dts are listed below:
>>
>> 	&bus_dmc {
>> 		devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
>> 		vdd-supply = <&buck1_reg>;	/* VDD_MIF */
>> 		status = "okay";
>> 	};
>>
>> 2. Add new passive governor of DEVFREQ framework (patch5-patch7)
>> : This patch-set add the new passive governor for DEVFREQ framework.
>> The existing governors (ondemand, performance and so on) are used for DVFS
>> (Dynamic Voltage and Frequency Scaling) drivers. The existing governors
>> are independently used for specific device driver which don't give the
>> influence to other device drviers and also don't receive the effect from
>> other device drivers.
>>
>>  The passive governor depends on operation of parent driver with existing
>> governors(ondemand, performance and so on) extremely and is not able to
>> decide the new frequency by oneself. According to the decided new frequency
>> of parent driver with governor, the passive governor uses it to decide
>> the appropriate frequency for own device driver. The passive governor
>> must need the following information from device tree:
>>
>> For exameple,
>>  There are one more bus device drivers in Exynos3250 which need to
>> change their source clock according to their utilization on runtime.
>> But, they share the same power line (e.g., regulator). So, LEFTBUS bus
>> driver is operated as parent with ondemand governor and then the rest
>> device driver with passive governor.
>>
>>  The buses of Internal block in exynos3250.dtsi are listed below:
>> When LEFTBUS bus driver (parent) changes the bus frequency with
>> ondemand governor on runtime, the rest bus devices which sharing
>> the same power line (VDD_INT) will change the each bus frequency
>> according to the decision of LEFTBUS bus driver (parent).
>>
>> - INT (Internal) block
>> 	: VDD_INT |--- LEFTBUS
>> 		  |--- PERIL
>> 		  |--- MFC
>> 		  |--- G3D
>> 		  |--- RIGHTBUS
>> 		  |--- FSYS
>> 		  |--- LCD0
>> 		  |--- PERIR
>> 		  |--- ISP
>> 		  |--- CAM
>>
>> - The buss of INT block in exynos3250.dtsi are listed below:
>> 	bus_leftbus: bus_leftbus {
>> 		compatible = "samsung,exynos-bus";
>> 		clocks = <&cmu CLK_DIV_GDL>;
>> 		clock-names = "bus";
>> 		operating-points-v2 = <&bus_leftbus_opp_table>;
>> 		status = "disabled";
>> 	};
>>
>> 	bus_rightbus: bus_rightbus {
>> 		compatible = "samsung,exynos-bus";
>> 		clocks = <&cmu CLK_DIV_GDR>;
>> 		clock-names = "bus";
>> 		operating-points-v2 = <&bus_leftbus_opp_table>;
>> 		status = "disabled";
>> 	};
>>
>> 	(Omit the rest bus dt node)
>>
>> - Usage case to handle the frequency and voltage of bus on runtime
>>   in exynos3250-rinato.dts are listed below:
>> 	/* Parent bus device of VDD_INT */
>> 	&bus_leftbus {
>> 		devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
>> 		vdd-supply = <&buck3_reg>;
>> 		status = "okay";
>> 	};
>>
>> 	/* Passive bus device depend on LEFTBUS bus. */
>> 	&bus_rightbus {
>> 		devfreq = <&bus_leftbus>; /* 'devfreq' property indicates
>> 					     the phandle of parent device. */
>> 		status = "okay";
>> 	};
>>
>> 	(Omit the rest bus dt node)
>>
>> Chanwoo Choi (20):
>>   PM / devfreq: exynos: Add generic exynos bus frequency driver
>>   PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
>>   ARM: dts: Add DMC bus node for Exynos3250
>>   ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
>>   PM / devfreq: Add new passive governor
>>   PM / devfreq: Add devfreq_get_devfreq_by_phandle()
>>   PM / devfreq: Show the related information according to governor type
>>   PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
>>   PM / devfreq: exynos: Update documentation for bus devices using passive governor
>>   PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
>>   PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
>>   MAINTAINERS: Add samsung bus frequency driver entry
>>   ARM: dts: Add bus nodes using VDD_INT for Exynos3250
>>   ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
>>   ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
>>   ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
>>   ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
>>   ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
>>   ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
>>   ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
>>
>>  .../devicetree/bindings/devfreq/exynos-bus.txt     |  388 +++++++
>>  MAINTAINERS                                        |    9 +
>>  arch/arm/boot/dts/exynos3250-monk.dts              |   47 +-
>>  arch/arm/boot/dts/exynos3250-rinato.dts            |   88 +-
>>  arch/arm/boot/dts/exynos3250.dtsi                  |  181 ++++
>>  arch/arm/boot/dts/exynos4210.dtsi                  |  159 +++
>>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   54 +-
>>  arch/arm/boot/dts/exynos4412-ppmu-common.dtsi      |   50 +
>>  arch/arm/boot/dts/exynos4412-trats2.dts            |   88 +-
>>  arch/arm/boot/dts/exynos4x12.dtsi                  |  174 ++++
>>  drivers/devfreq/Kconfig                            |   37 +-
>>  drivers/devfreq/Makefile                           |    2 +
>>  drivers/devfreq/devfreq.c                          |  120 ++-
>>  drivers/devfreq/exynos/Makefile                    |    3 +-
>>  drivers/devfreq/exynos/exynos-bus.c                |  556 +++++++++++
>>  drivers/devfreq/exynos/exynos4_bus.c               | 1055 --------------------
>>  drivers/devfreq/exynos/exynos4_bus.h               |  110 --
>>  drivers/devfreq/exynos/exynos5_bus.c               |  431 --------
>>  drivers/devfreq/exynos/exynos_ppmu.c               |  119 ---
>>  drivers/devfreq/exynos/exynos_ppmu.h               |   86 --
>>  drivers/devfreq/governor.h                         |    7 +
>>  drivers/devfreq/governor_passive.c                 |  109 ++
>>  drivers/devfreq/governor_performance.c             |    1 +
>>  drivers/devfreq/governor_powersave.c               |    1 +
>>  drivers/devfreq/governor_simpleondemand.c          |    1 +
>>  drivers/devfreq/governor_userspace.c               |    1 +
>>  include/linux/devfreq.h                            |   26 +
>>  27 files changed, 1955 insertions(+), 1948 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt
>>  create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi
>>  create mode 100644 drivers/devfreq/exynos/exynos-bus.c
>>  delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c
>>  delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h
>>  delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c
>>  delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c
>>  delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h
>>  create mode 100644 drivers/devfreq/governor_passive.c
>>
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-14  8:28 [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver MyungJoo Ham
  2015-12-14  8:44 ` Chanwoo Choi
@ 2015-12-15  3:32 ` Chanwoo Choi
  1 sibling, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-15  3:32 UTC (permalink / raw)
  To: myungjoo.ham, 크쉬시토프, kgene
  Cc: 박경민,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, linux,
	tjakobi, linux.amoon, linux-kernel, linux-pm, linux-samsung-soc,
	devicetree

On 2015년 12월 14일 17:28, MyungJoo Ham wrote:
>>   
>>  This patch adds the generic exynos bus frequency driver for AMBA AXI bus
>> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
>> have the common architecture for bus between DRAM and sub-blocks in SoC.
>> This driver can support the generic bus frequency driver for Exynos SoCs.
>>
>> In devicetree, Each bus block has a bus clock, regulator, operation-point
>> and devfreq-event devices which measure the utilization of each bus block.
>>
>> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
>> [linux.amoon: Tested on Odroid U3]
>> Tested-by: Anand Moon <linux.amoon@gmail.com>
>>
> 
> Chanwoo, could you please show me testing this set of patches in your site?
> Please let me know when is ok to visit you.
> (I do not have exynos machines right now.)
> 
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 5134f9ee983d..375ebbb4fcfb 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>>  
>>  # DEVFREQ Drivers
>> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
>>  obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
>>  obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/
> 
> CONFIG_ARCH_EXYNOS is true if
> 	CONFIG_ARM_EXYNOS4_BUS_DEVFREQ is true 
> 	or
> 	CONFIG_ARM_EXYNOS5_BUS_DEVFREQ is true
> Thus, the two lines after you've added have become useless. (dead code)
> 
> Please delete them.

In this series, patch11 deletes all of both exynos4_bus.c and exynos5_bus.c.

> 
> []
>> --- /dev/null
>> +++ b/drivers/devfreq/exynos/exynos-bus.c
> []
>> +static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
>> +{
>> +	struct exynos_bus *bus = dev_get_drvdata(dev);
>> +	struct dev_pm_opp *new_opp;
>> +	unsigned long old_freq, new_freq, old_volt, new_volt;
>> +	int ret = 0;
>> +
>> +	/* Get new opp-bus instance according to new bus clock */
>> +	rcu_read_lock();
>> +	new_opp = devfreq_recommended_opp(dev, freq, flags);
>> +	if (IS_ERR_OR_NULL(new_opp)) {
>> +		dev_err(dev, "failed to get recommed opp instance\n");
>> +		rcu_read_unlock();
>> +		return PTR_ERR(new_opp);
>> +	}
>> +
>> +	new_freq = dev_pm_opp_get_freq(new_opp);
>> +	new_volt = dev_pm_opp_get_voltage(new_opp);
>> +	old_freq = dev_pm_opp_get_freq(bus->curr_opp);
>> +	old_volt = dev_pm_opp_get_voltage(bus->curr_opp);
>> +	rcu_read_unlock();
>> +
>> +	if (old_freq == new_freq)
>> +		return 0;
>> +
>> +	/* Change voltage and frequency according to new OPP level */
>> +	mutex_lock(&bus->lock);
>> +
>> +	if (old_freq < new_freq) {
>> +		ret = regulator_set_voltage(bus->regulator, new_volt, new_volt);
> 
> Setting the maximum volt same as the minimum volt is not recommended.
> Especially for any DVFS mechanisms, I recommend to set values as:
> min_volt = minimum voltage that does not harm the stability
> max_volt = maximum voltage that does not break the circuit
> 
> Please refer to /include/linux/regulator/driver.h
> "@set_voltage" comments.
> 
> For the rest of regulator_set_voltage usages, I'd say the same.

OK.
I'll add the 'voltage-tolerance' property as cpufreq-dt.c driver.
The cpufreq-dt.c get the percentage value by using 'voltage-tolerance'
devicetree property.

For example,
	if (of_property_read_u32(np, "exynos,voltage-tolerance",
			&bus->voltage_tolerance))
		bus->voltage_tolerance = DEFAULT_VOLTAGE_TOLERANCE;

	tol = new_volt * bus->voltage_tolerance / 100;
	regulator_set_voltage_tol(regulator, new_volt, tol);

> 
> []
>> +static int exynos_bus_get_dev_status(struct device *dev,
>> +				     struct devfreq_dev_status *stat)
>> +{
>> +	struct exynos_bus *bus = dev_get_drvdata(dev);
>> +	struct devfreq_event_data edata;
>> +	int ret;
>> +
>> +	rcu_read_lock();
>> +	stat->current_frequency = dev_pm_opp_get_freq(bus->curr_opp);
>> +	rcu_read_unlock();
>> +
>> +	ret = exynos_bus_get_event(bus, &edata);
>> +	if (ret < 0) {
>> +		stat->total_time = stat->busy_time = 0;
>> +		goto err;
>> +	}
>> +
>> +	stat->busy_time = (edata.load_count * 100) / bus->ratio;
>> +	stat->total_time = edata.total_count;
>> +
>> +	dev_dbg(dev, "Usage of devfreq-event : %ld/%ld\n", stat->busy_time,
>> +							stat->total_time);
> 
> These two values are unsigned long.

OK. I'll modify it (%ld -> %lu)

> 
> []
>> +static int exynos_bus_parse_of(struct device_node *np,
>> +			      struct exynos_bus *bus)
>> +{
>> +	struct device *dev = bus->dev;
>> +	unsigned long rate;
>> +	int i, ret, count, size;
>> +
>> +	/* Get the clock to provide each bus with source clock */
>> +	bus->clk = devm_clk_get(dev, "bus");
>> +	if (IS_ERR(bus->clk)) {
>> +		dev_err(dev, "failed to get bus clock\n");
>> +		return PTR_ERR(bus->clk);
>> +	}
>> +
>> +	ret = clk_prepare_enable(bus->clk);
>> +	if (ret < 0) {
>> +		dev_err(dev, "failed to get enable clock\n");
>> +		return ret;
>> +	}
> 
> []
> 
>> +err_regulator:
>> +	regulator_disable(bus->regulator);
>> +err_opp:
>> +	dev_pm_opp_of_remove_table(dev);
>> +
>> +	return ret;
> 
> No clk_disable_unprepare() somewhere in the error handling routines?

OK. I'll handle the error of clock control.

> 
> []
> 
>> +#ifdef CONFIG_PM_SLEEP
>> +static int exynos_bus_resume(struct device *dev)
>> +{
> []
>> +		ret = regulator_enable(bus->regulator);
> []
>> +}
>> +
>> +static int exynos_bus_suspend(struct device *dev)
>> +{
> []
>> +		regulator_disable(bus->regulator);
> []
>> +}
>> +#endif
> 
> Isn't there any possibility that you should not disable at suspend callbacks?
> If I remember correctly, we should not disable VDD-INT/VDD-MIF of Exynos4412
> for suspend-to-RAM although it is "mostly" ok to do so, but not "always" ok.

Yes. It is not always same. I'll pass the role of handling the VDD_INT/VDD_MIF
regulator to regulator framework. The regulator framework handles the state
in suspend state by using 'regulator-off-in-suspend' property as following:

For example, in arch/arm/boot/dts/exynos4412-trats.dts:
	buck1_reg: BUCK1 {
		regulator-name = "vdd_mif";
		regulator-min-microvolt = <850000>;
		regulator-max-microvolt = <1100000>;
		regulator-always-on;
		regulator-boot-on;
		regulator-state-mem {
			regulator-off-in-suspend;
		};
	};

	buck3_reg: BUCK3 {
		regulator-name = "vdd_int";
		regulator-min-microvolt = <850000>;
		regulator-max-microvolt = <1150000>;
		regulator-always-on;
		regulator-boot-on;
		regulator-state-mem {
			regulator-off-in-suspend;
		};
	};

> 
> In such cases, I guess it should be "selectively" disabled for suspend.
> (some regulators support special "low power if suspended" modes for such cases)

Thanks,
Chanwoo Choi



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
  2015-12-14  8:28 [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver MyungJoo Ham
@ 2015-12-14  8:44 ` Chanwoo Choi
  2015-12-15  3:32 ` Chanwoo Choi
  1 sibling, 0 replies; 33+ messages in thread
From: Chanwoo Choi @ 2015-12-14  8:44 UTC (permalink / raw)
  To: myungjoo.ham, 크쉬시토프, kgene
  Cc: 박경민,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, linux,
	tjakobi, linux.amoon, linux-kernel, linux-pm, linux-samsung-soc,
	devicetree

On 2015년 12월 14일 17:28, MyungJoo Ham wrote:
>>   
>>  This patch adds the generic exynos bus frequency driver for AMBA AXI bus
>> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
>> have the common architecture for bus between DRAM and sub-blocks in SoC.
>> This driver can support the generic bus frequency driver for Exynos SoCs.
>>
>> In devicetree, Each bus block has a bus clock, regulator, operation-point
>> and devfreq-event devices which measure the utilization of each bus block.
>>
>> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
>> [linux.amoon: Tested on Odroid U3]
>> Tested-by: Anand Moon <linux.amoon@gmail.com>
>>
> 
> Chanwoo, could you please show me testing this set of patches in your site?
> Please let me know when is ok to visit you.
> (I do not have exynos machines right now.)

Sure. I can show it tomorrow whenever you want.
Before visiting to me, just let me know. I'll prepare the demonstartion.

Regards,
Chanwo oChoi

> 
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 5134f9ee983d..375ebbb4fcfb 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>>  
>>  # DEVFREQ Drivers
>> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
>>  obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
>>  obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/
> 
> CONFIG_ARCH_EXYNOS is true if
> 	CONFIG_ARM_EXYNOS4_BUS_DEVFREQ is true 
> 	or
> 	CONFIG_ARM_EXYNOS5_BUS_DEVFREQ is true
> Thus, the two lines after you've added have become useless. (dead code)
> 
> Please delete them.
> 
> []
>> --- /dev/null
>> +++ b/drivers/devfreq/exynos/exynos-bus.c
> []
>> +static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
>> +{
>> +	struct exynos_bus *bus = dev_get_drvdata(dev);
>> +	struct dev_pm_opp *new_opp;
>> +	unsigned long old_freq, new_freq, old_volt, new_volt;
>> +	int ret = 0;
>> +
>> +	/* Get new opp-bus instance according to new bus clock */
>> +	rcu_read_lock();
>> +	new_opp = devfreq_recommended_opp(dev, freq, flags);
>> +	if (IS_ERR_OR_NULL(new_opp)) {
>> +		dev_err(dev, "failed to get recommed opp instance\n");
>> +		rcu_read_unlock();
>> +		return PTR_ERR(new_opp);
>> +	}
>> +
>> +	new_freq = dev_pm_opp_get_freq(new_opp);
>> +	new_volt = dev_pm_opp_get_voltage(new_opp);
>> +	old_freq = dev_pm_opp_get_freq(bus->curr_opp);
>> +	old_volt = dev_pm_opp_get_voltage(bus->curr_opp);
>> +	rcu_read_unlock();
>> +
>> +	if (old_freq == new_freq)
>> +		return 0;
>> +
>> +	/* Change voltage and frequency according to new OPP level */
>> +	mutex_lock(&bus->lock);
>> +
>> +	if (old_freq < new_freq) {
>> +		ret = regulator_set_voltage(bus->regulator, new_volt, new_volt);
> 
> Setting the maximum volt same as the minimum volt is not recommended.
> Especially for any DVFS mechanisms, I recommend to set values as:
> min_volt = minimum voltage that does not harm the stability
> max_volt = maximum voltage that does not break the circuit
> 
> Please refer to /include/linux/regulator/driver.h
> "@set_voltage" comments.
> 
> For the rest of regulator_set_voltage usages, I'd say the same.
> 
> []
>> +static int exynos_bus_get_dev_status(struct device *dev,
>> +				     struct devfreq_dev_status *stat)
>> +{
>> +	struct exynos_bus *bus = dev_get_drvdata(dev);
>> +	struct devfreq_event_data edata;
>> +	int ret;
>> +
>> +	rcu_read_lock();
>> +	stat->current_frequency = dev_pm_opp_get_freq(bus->curr_opp);
>> +	rcu_read_unlock();
>> +
>> +	ret = exynos_bus_get_event(bus, &edata);
>> +	if (ret < 0) {
>> +		stat->total_time = stat->busy_time = 0;
>> +		goto err;
>> +	}
>> +
>> +	stat->busy_time = (edata.load_count * 100) / bus->ratio;
>> +	stat->total_time = edata.total_count;
>> +
>> +	dev_dbg(dev, "Usage of devfreq-event : %ld/%ld\n", stat->busy_time,
>> +							stat->total_time);
> 
> These two values are unsigned long.
> 
> []
>> +static int exynos_bus_parse_of(struct device_node *np,
>> +			      struct exynos_bus *bus)
>> +{
>> +	struct device *dev = bus->dev;
>> +	unsigned long rate;
>> +	int i, ret, count, size;
>> +
>> +	/* Get the clock to provide each bus with source clock */
>> +	bus->clk = devm_clk_get(dev, "bus");
>> +	if (IS_ERR(bus->clk)) {
>> +		dev_err(dev, "failed to get bus clock\n");
>> +		return PTR_ERR(bus->clk);
>> +	}
>> +
>> +	ret = clk_prepare_enable(bus->clk);
>> +	if (ret < 0) {
>> +		dev_err(dev, "failed to get enable clock\n");
>> +		return ret;
>> +	}
> 
> []
> 
>> +err_regulator:
>> +	regulator_disable(bus->regulator);
>> +err_opp:
>> +	dev_pm_opp_of_remove_table(dev);
>> +
>> +	return ret;
> 
> No clk_disable_unprepare() somewhere in the error handling routines?
> 
> []
> 
>> +#ifdef CONFIG_PM_SLEEP
>> +static int exynos_bus_resume(struct device *dev)
>> +{
> []
>> +		ret = regulator_enable(bus->regulator);
> []
>> +}
>> +
>> +static int exynos_bus_suspend(struct device *dev)
>> +{
> []
>> +		regulator_disable(bus->regulator);
> []
>> +}
>> +#endif
> 
> Isn't there any possibility that you should not disable at suspend callbacks?
> If I remember correctly, we should not disable VDD-INT/VDD-MIF of Exynos4412
> for suspend-to-RAM although it is "mostly" ok to do so, but not "always" ok.
> 
> In such cases, I guess it should be "selectively" disabled for suspend.
> (some regulators support special "low power if suspended" modes for such cases)
> 
> []
> N�����r��y���b�X��ǧv�^�)޺{.n�+����{�����x,�ȧ�\x17��ܨ}���Ơz�&j:+v���\a����zZ+��+zf���h���~����i���z�\x1e�w���?����&�)ߢ^[fl===
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver
@ 2015-12-14  8:28 MyungJoo Ham
  2015-12-14  8:44 ` Chanwoo Choi
  2015-12-15  3:32 ` Chanwoo Choi
  0 siblings, 2 replies; 33+ messages in thread
From: MyungJoo Ham @ 2015-12-14  8:28 UTC (permalink / raw)
  To: 최찬우,
	크쉬시토프,
	kgene
  Cc: 박경민,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, linux,
	tjakobi, linux.amoon, linux-kernel, linux-pm, linux-samsung-soc,
	devicetree

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 5235 bytes --]

>   
>  This patch adds the generic exynos bus frequency driver for AMBA AXI bus
> of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC
> have the common architecture for bus between DRAM and sub-blocks in SoC.
> This driver can support the generic bus frequency driver for Exynos SoCs.
> 
> In devicetree, Each bus block has a bus clock, regulator, operation-point
> and devfreq-event devices which measure the utilization of each bus block.
> 
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> [linux.amoon: Tested on Odroid U3]
> Tested-by: Anand Moon <linux.amoon@gmail.com>
> 

Chanwoo, could you please show me testing this set of patches in your site?
Please let me know when is ok to visit you.
(I do not have exynos machines right now.)

> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
> index 5134f9ee983d..375ebbb4fcfb 100644
> --- a/drivers/devfreq/Makefile
> +++ b/drivers/devfreq/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
>  obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
>  
>  # DEVFREQ Drivers
> +obj-$(CONFIG_ARCH_EXYNOS)		+= exynos/
>  obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
>  obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/

CONFIG_ARCH_EXYNOS is true if
	CONFIG_ARM_EXYNOS4_BUS_DEVFREQ is true 
	or
	CONFIG_ARM_EXYNOS5_BUS_DEVFREQ is true
Thus, the two lines after you've added have become useless. (dead code)

Please delete them.

[]
> --- /dev/null
> +++ b/drivers/devfreq/exynos/exynos-bus.c
[]
> +static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
> +{
> +	struct exynos_bus *bus = dev_get_drvdata(dev);
> +	struct dev_pm_opp *new_opp;
> +	unsigned long old_freq, new_freq, old_volt, new_volt;
> +	int ret = 0;
> +
> +	/* Get new opp-bus instance according to new bus clock */
> +	rcu_read_lock();
> +	new_opp = devfreq_recommended_opp(dev, freq, flags);
> +	if (IS_ERR_OR_NULL(new_opp)) {
> +		dev_err(dev, "failed to get recommed opp instance\n");
> +		rcu_read_unlock();
> +		return PTR_ERR(new_opp);
> +	}
> +
> +	new_freq = dev_pm_opp_get_freq(new_opp);
> +	new_volt = dev_pm_opp_get_voltage(new_opp);
> +	old_freq = dev_pm_opp_get_freq(bus->curr_opp);
> +	old_volt = dev_pm_opp_get_voltage(bus->curr_opp);
> +	rcu_read_unlock();
> +
> +	if (old_freq == new_freq)
> +		return 0;
> +
> +	/* Change voltage and frequency according to new OPP level */
> +	mutex_lock(&bus->lock);
> +
> +	if (old_freq < new_freq) {
> +		ret = regulator_set_voltage(bus->regulator, new_volt, new_volt);

Setting the maximum volt same as the minimum volt is not recommended.
Especially for any DVFS mechanisms, I recommend to set values as:
min_volt = minimum voltage that does not harm the stability
max_volt = maximum voltage that does not break the circuit

Please refer to /include/linux/regulator/driver.h
"@set_voltage" comments.

For the rest of regulator_set_voltage usages, I'd say the same.

[]
> +static int exynos_bus_get_dev_status(struct device *dev,
> +				     struct devfreq_dev_status *stat)
> +{
> +	struct exynos_bus *bus = dev_get_drvdata(dev);
> +	struct devfreq_event_data edata;
> +	int ret;
> +
> +	rcu_read_lock();
> +	stat->current_frequency = dev_pm_opp_get_freq(bus->curr_opp);
> +	rcu_read_unlock();
> +
> +	ret = exynos_bus_get_event(bus, &edata);
> +	if (ret < 0) {
> +		stat->total_time = stat->busy_time = 0;
> +		goto err;
> +	}
> +
> +	stat->busy_time = (edata.load_count * 100) / bus->ratio;
> +	stat->total_time = edata.total_count;
> +
> +	dev_dbg(dev, "Usage of devfreq-event : %ld/%ld\n", stat->busy_time,
> +							stat->total_time);

These two values are unsigned long.

[]
> +static int exynos_bus_parse_of(struct device_node *np,
> +			      struct exynos_bus *bus)
> +{
> +	struct device *dev = bus->dev;
> +	unsigned long rate;
> +	int i, ret, count, size;
> +
> +	/* Get the clock to provide each bus with source clock */
> +	bus->clk = devm_clk_get(dev, "bus");
> +	if (IS_ERR(bus->clk)) {
> +		dev_err(dev, "failed to get bus clock\n");
> +		return PTR_ERR(bus->clk);
> +	}
> +
> +	ret = clk_prepare_enable(bus->clk);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to get enable clock\n");
> +		return ret;
> +	}

[]

> +err_regulator:
> +	regulator_disable(bus->regulator);
> +err_opp:
> +	dev_pm_opp_of_remove_table(dev);
> +
> +	return ret;

No clk_disable_unprepare() somewhere in the error handling routines?

[]

> +#ifdef CONFIG_PM_SLEEP
> +static int exynos_bus_resume(struct device *dev)
> +{
[]
> +		ret = regulator_enable(bus->regulator);
[]
> +}
> +
> +static int exynos_bus_suspend(struct device *dev)
> +{
[]
> +		regulator_disable(bus->regulator);
[]
> +}
> +#endif

Isn't there any possibility that you should not disable at suspend callbacks?
If I remember correctly, we should not disable VDD-INT/VDD-MIF of Exynos4412
for suspend-to-RAM although it is "mostly" ok to do so, but not "always" ok.

In such cases, I guess it should be "selectively" disabled for suspend.
(some regulators support special "low power if suspended" modes for such cases)

[]
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2016-02-22  1:00 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-14  6:38 [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver Chanwoo Choi
2015-12-15  3:41   ` Krzysztof Kozlowski
2015-12-18  0:34     ` Chanwoo Choi
2015-12-18  0:43       ` Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 02/20] PM / devfreq: exynos: Add documentation for " Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 03/20] ARM: dts: Add DMC bus node for Exynos3250 Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 04/20] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 05/20] PM / devfreq: Add new passive governor Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 06/20] PM / devfreq: Add devfreq_get_devfreq_by_phandle() Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 07/20] PM / devfreq: Show the related information according to governor type Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 08/20] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 09/20] PM / devfreq: exynos: Update documentation for bus devices " Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 10/20] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 11/20] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 12/20] MAINTAINERS: Add samsung bus frequency driver entry Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 13/20] ARM: dts: Add bus nodes using VDD_INT for Exynos3250 Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 14/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12 Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 15/20] ARM: dts: Add bus nodes using VDD_INT " Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 16/20] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210 Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 17/20] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 18/20] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 19/20] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3 Chanwoo Choi
2015-12-14  6:38 ` [PATCH v4 20/20] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3 Chanwoo Choi
2015-12-15  0:34   ` Krzysztof Kozlowski
2016-01-19  9:13 ` [PATCH v4 00/20] PM / devferq: Add generic exynos bus frequency driver and new passive governor Tobias Jakobi
2016-01-20  1:09   ` Chanwoo Choi
2016-01-22 11:01     ` Tobias Jakobi
2016-02-19 15:05 ` Tobias Jakobi
2016-02-22  1:00   ` Chanwoo Choi
2015-12-14  8:28 [PATCH v4 01/20] PM / devfreq: exynos: Add generic exynos bus frequency driver MyungJoo Ham
2015-12-14  8:44 ` Chanwoo Choi
2015-12-15  3:32 ` Chanwoo Choi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).