linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/3] ARM: mxs: add recording support for saif
       [not found] <a>
@ 2011-11-22 15:54 ` Dong Aisheng
  2011-11-24  7:36   ` Shawn Guo
  2011-11-22 15:54 ` [PATCH v7 1/3] ARM: mxs: add saif clkmux functions Dong Aisheng
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 91+ messages in thread
From: Dong Aisheng @ 2011-11-22 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Changes since v6:
 * fix a typo suggested by Shawn
 * add tag from Marek Vasut

Changes since v5:
 Only one change is that:
 * remove the unneccesary parenthesis for [PATCH 1/3] suggested
   by Marek Vasut.

Changes since v4:
 * use new added master_id and master_mode in platform_data.
 The new changes depend on another patch:
 0001-ASoC-mxs-saif-remove-function-in-platform_data.patch

Changes since v3:
 * remove unneeded locking according to Sascha.
The patches are based on imx-features branch since commit:
ca4e419c2.

Changes since v2:
 * separate clkmux code into another patch according to Uwe
 * add lock according to Wolfram
 * Other minus fixes suggested by Uwe and Wolfram.
 * remove Wolfram's fix saif clock setting patch which is in v2 series
   since Wolfram will reform the clock code and send it out himself.
   For test purpose, user still needs that patch. People can get it
   from v2 series.
   The patch is:
   [PATCH v2 3/3] arm: mxs: disable clock-gates when setting saif-clocks

The patches are based on imx-features branch since commit:
f4f01e31835f.

Changes since v1:
The main changes are move mach-specific code(clkmux in DIGCTL) from
saif driver to mach-specific layer based on Wolfram's suggestion.

Note that the last patch is a RFC patch and sent out for testing
since without that patch the saif may not work.

Dong Aisheng (3):
  ARM: mxs: add saif clkmux functions
  ARM: mx28evk: add platform data for saif
  ARM: mx28evk: set a initial clock rate for saif

 arch/arm/mach-mxs/clock-mx28.c                  |   38 +++++++++++++++++++++++
 arch/arm/mach-mxs/devices-mx28.h                |    3 +-
 arch/arm/mach-mxs/devices/platform-mxs-saif.c   |    5 ++-
 arch/arm/mach-mxs/include/mach/common.h         |    1 +
 arch/arm/mach-mxs/include/mach/devices-common.h |    4 ++-
 arch/arm/mach-mxs/include/mach/digctl.h         |   21 ++++++++++++
 arch/arm/mach-mxs/mach-mx28evk.c                |   18 +++++++++-
 7 files changed, 84 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/digctl.h

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

* [PATCH v7 1/3] ARM: mxs: add saif clkmux functions
       [not found] <a>
  2011-11-22 15:54 ` [PATCH v7 0/3] ARM: mxs: add recording support for saif Dong Aisheng
@ 2011-11-22 15:54 ` Dong Aisheng
  2011-11-22 15:54 ` [PATCH v7 2/3] ARM: mx28evk: add platform data for saif Dong Aisheng
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Dong Aisheng @ 2011-11-22 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Liam Girdwood <lrg@ti.com>

---
changes since v5:
 * remove unneeded parenthesis
changes since v4:
 * remove get_master_id function.
   Instead, we use master_mode and master_id in platform_data to tell
   saif driver the correct master id for each saifs.
changes since v3:
 * remove the unneeded locking according to Sascha
changes since v2:
 * This patch is separated from the following patch based on
   suggestions from Uwe.
   [PATCH 2/3] ARM: mx28evk: add platform data for saif
---
 arch/arm/mach-mxs/clock-mx28.c          |   29 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/include/mach/digctl.h |   21 +++++++++++++++++++++
 3 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 7954013..c51fe85 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/clkdev.h>
+#include <linux/spinlock.h>
 
 #include <asm/clkdev.h>
 #include <asm/div64.h>
@@ -29,6 +30,7 @@
 #include <mach/mx28.h>
 #include <mach/common.h>
 #include <mach/clock.h>
+#include <mach/digctl.h>
 
 #include "regs-clkctrl-mx28.h"
 
@@ -43,6 +45,33 @@ static struct clk emi_clk;
 static struct clk saif0_clk;
 static struct clk saif1_clk;
 static struct clk clk32k_clk;
+static DEFINE_SPINLOCK(clkmux_lock);
+
+/*
+ * HW_SAIF_CLKMUX_SEL:
+ *  DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
+ *		clock pins selected for SAIF1 input clocks.
+ *  CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
+ *		SAIF0 clock inputs selected for SAIF1 input clocks.
+ *  EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
+ *		clocks.
+ *  EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
+ *		clocks.
+ */
+int mxs_saif_clkmux_select(unsigned int clkmux)
+{
+	if (clkmux > 0x3)
+		return -EINVAL;
+
+	spin_lock(&clkmux_lock);
+	__raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
+			DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
+	__raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
+			DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
+	spin_unlock(&clkmux_lock);
+
+	return 0;
+}
 
 static int _raw_clk_enable(struct clk *clk)
 {
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 635bb5d..3bbb94f 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -16,6 +16,7 @@ struct clk;
 extern const u32 *mxs_get_ocotp(void);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
+extern int mxs_saif_clkmux_select(unsigned int clkmux);
 
 extern int mx23_register_gpios(void);
 extern int mx23_clocks_init(void);
diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h
new file mode 100644
index 0000000..49a888c
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/digctl.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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 __MACH_DIGCTL_H__
+#define __MACH_DIGCTL_H__
+
+/* MXS DIGCTL SAIF CLKMUX */
+#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT		0x0
+#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT	0x1
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0		0x2
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1		0x3
+
+#define HW_DIGCTL_CTRL			0x0
+#define  BP_DIGCTL_CTRL_SAIF_CLKMUX	10
+#define  BM_DIGCTL_CTRL_SAIF_CLKMUX	(0x3 << 10)
+#endif
-- 
1.7.0.4

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

* [PATCH v7 2/3] ARM: mx28evk: add platform data for saif
       [not found] <a>
  2011-11-22 15:54 ` [PATCH v7 0/3] ARM: mxs: add recording support for saif Dong Aisheng
  2011-11-22 15:54 ` [PATCH v7 1/3] ARM: mxs: add saif clkmux functions Dong Aisheng
@ 2011-11-22 15:54 ` Dong Aisheng
  2011-11-22 15:54 ` [PATCH v7 3/3] ARM: mx28evk: set a initial clock rate " Dong Aisheng
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Dong Aisheng @ 2011-11-22 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

This is for supporting saif record function.

Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Liam Girdwood <lrg@ti.com>

---
Changes since v6:
 * fix a typo suggested by Shawn
Changes since v4:
 * Using the new added master_id and master_mode in platfrom_data
No changes since v3:
Changes since v2:
 * separate clkmux code into another patch
 * A few minus fixes suggested by Uwe & Wolfram.
Changes since v1:
 * move saif clkmux code into mach-specific part
---
 arch/arm/mach-mxs/devices-mx28.h                |    3 ++-
 arch/arm/mach-mxs/devices/platform-mxs-saif.c   |    5 +++--
 arch/arm/mach-mxs/include/mach/devices-common.h |    4 +++-
 arch/arm/mach-mxs/mach-mx28evk.c                |   18 ++++++++++++++++--
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index c888710..4f50094 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -47,6 +47,7 @@ struct platform_device *__init mx28_add_mxsfb(
 		const struct mxsfb_platform_data *pdata);
 
 extern const struct mxs_saif_data mx28_saif_data[] __initconst;
-#define mx28_add_saif(id)              mxs_add_saif(&mx28_saif_data[id])
+#define mx28_add_saif(id, pdata) \
+	mxs_add_saif(&mx28_saif_data[id], pdata)
 
 struct platform_device *__init mx28_add_rtc_stmp3xxx(void);
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-saif.c b/arch/arm/mach-mxs/devices/platform-mxs-saif.c
index 1ec965e..f6e3a60 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-saif.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-saif.c
@@ -32,7 +32,8 @@ const struct mxs_saif_data mx28_saif_data[] __initconst = {
 };
 #endif
 
-struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data)
+struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data,
+				const struct mxs_saif_platform_data *pdata)
 {
 	struct resource res[] = {
 		{
@@ -56,5 +57,5 @@ struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data)
 	};
 
 	return mxs_add_platform_device("mxs-saif", data->id, res,
-					ARRAY_SIZE(res), NULL, 0);
+				ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index a8080f4..dc369c1 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -94,6 +94,7 @@ struct platform_device *__init mxs_add_mxs_pwm(
 		resource_size_t iobase, int id);
 
 /* saif */
+#include <sound/saif.h>
 struct mxs_saif_data {
 	int id;
 	resource_size_t iobase;
@@ -103,4 +104,5 @@ struct mxs_saif_data {
 };
 
 struct platform_device *__init mxs_add_saif(
-		const struct mxs_saif_data *data);
+		const struct mxs_saif_data *data,
+		const struct mxs_saif_platform_data *pdata);
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index 4a3cca3..1bad69e 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -28,6 +28,7 @@
 
 #include <mach/common.h>
 #include <mach/iomux-mx28.h>
+#include <mach/digctl.h>
 
 #include "devices-mx28.h"
 
@@ -417,6 +418,18 @@ static void __init mx28evk_add_regulators(void)
 static void __init mx28evk_add_regulators(void) {}
 #endif
 
+static const struct mxs_saif_platform_data
+			mx28evk_mxs_saif_pdata[] __initconst = {
+	/* working on EXTMSTR0 mode (saif0 master, saif1 slave) */
+	{
+		.master_mode = 1,
+		.master_id = 0,
+	}, {
+		.master_mode = 0,
+		.master_id = 0,
+	},
+};
+
 static void __init mx28evk_init(void)
 {
 	int ret;
@@ -457,8 +470,9 @@ static void __init mx28evk_init(void)
 
 	mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
 
-	mx28_add_saif(0);
-	mx28_add_saif(1);
+	mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+	mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]);
+	mx28_add_saif(1, &mx28evk_mxs_saif_pdata[1]);
 
 	mx28_add_mxs_i2c(0);
 	i2c_register_board_info(0, mxs_i2c0_board_info,
-- 
1.7.0.4

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

* [PATCH v7 3/3] ARM: mx28evk: set a initial clock rate for saif
       [not found] <a>
                   ` (2 preceding siblings ...)
  2011-11-22 15:54 ` [PATCH v7 2/3] ARM: mx28evk: add platform data for saif Dong Aisheng
@ 2011-11-22 15:54 ` Dong Aisheng
  2012-03-13 12:33 ` [PATCH 1/5 v4] i2c/gpio: add DT support Jean-Christophe PLAGNIOL-VILLARD
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Dong Aisheng @ 2011-11-22 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Liam Girdwood <lrg@ti.com>

---
Changes since v1:
 * make comments a little better.
   It's originally suggested by Uwe.
---
 arch/arm/mach-mxs/clock-mx28.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index c51fe85..b0c248d 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -808,6 +808,15 @@ int __init mx28_clocks_init(void)
 	clk_set_parent(&saif0_clk, &pll0_clk);
 	clk_set_parent(&saif1_clk, &pll0_clk);
 
+	/*
+	 * Set an initial clock rate for the saif internal logic to work
+	 * properly. This is important when working in EXTMASTER mode that
+	 * uses the other saif's BITCLK&LRCLK but it still needs a basic
+	 * clock which should be fast enough for the internal logic.
+	 */
+	clk_set_rate(&saif0_clk, 24000000);
+	clk_set_rate(&saif1_clk, 24000000);
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
-- 
1.7.0.4

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-22 15:54 ` [PATCH v7 0/3] ARM: mxs: add recording support for saif Dong Aisheng
@ 2011-11-24  7:36   ` Shawn Guo
  2011-11-24  7:46     ` Shawn Guo
  0 siblings, 1 reply; 91+ messages in thread
From: Shawn Guo @ 2011-11-24  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 22, 2011 at 11:54:22PM +0800, Dong Aisheng wrote:
[...]
> Dong Aisheng (3):
>   ARM: mxs: add saif clkmux functions
>   ARM: mx28evk: add platform data for saif
>   ARM: mx28evk: set a initial clock rate for saif
> 
>  arch/arm/mach-mxs/clock-mx28.c                  |   38 +++++++++++++++++++++++
>  arch/arm/mach-mxs/devices-mx28.h                |    3 +-
>  arch/arm/mach-mxs/devices/platform-mxs-saif.c   |    5 ++-
>  arch/arm/mach-mxs/include/mach/common.h         |    1 +
>  arch/arm/mach-mxs/include/mach/devices-common.h |    4 ++-
>  arch/arm/mach-mxs/include/mach/digctl.h         |   21 ++++++++++++
>  arch/arm/mach-mxs/mach-mx28evk.c                |   18 +++++++++-
>  7 files changed, 84 insertions(+), 6 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/digctl.h
> 
Applied, thanks.

During the testing, the saif driver's dependency on
REGULATOR_FIXED_VOLTAGE was found.  I guess it should be resolved
in sound/soc/mxs/Kconfig rather than leaving it to users.

-- 
Regards,
Shawn

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-24  7:46     ` Shawn Guo
@ 2011-11-24  7:41       ` Uwe Kleine-König
  2011-11-24  7:49       ` Wolfram Sang
  1 sibling, 0 replies; 91+ messages in thread
From: Uwe Kleine-König @ 2011-11-24  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 24, 2011 at 03:46:20PM +0800, Shawn Guo wrote:
> On Thu, Nov 24, 2011 at 03:36:05PM +0800, Shawn Guo wrote:
> > During the testing, the saif driver's dependency on
> > REGULATOR_FIXED_VOLTAGE was found.  I guess it should be resolved
> > in sound/soc/mxs/Kconfig rather than leaving it to users.
> > 
> Also SND_SOC_MXS_SGTL5000 should probably depends on I2C_MXS than I2C.
Hmm, I think it's common and accepted that an i2c device doesn't depend
on an i2c bus driver. In this case it's quite probable that you want
I2C_MXS, but technically you could also use I2C_GPIO.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-24  7:36   ` Shawn Guo
@ 2011-11-24  7:46     ` Shawn Guo
  2011-11-24  7:41       ` Uwe Kleine-König
  2011-11-24  7:49       ` Wolfram Sang
  0 siblings, 2 replies; 91+ messages in thread
From: Shawn Guo @ 2011-11-24  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 24, 2011 at 03:36:05PM +0800, Shawn Guo wrote:
> During the testing, the saif driver's dependency on
> REGULATOR_FIXED_VOLTAGE was found.  I guess it should be resolved
> in sound/soc/mxs/Kconfig rather than leaving it to users.
> 
Also SND_SOC_MXS_SGTL5000 should probably depends on I2C_MXS than I2C.

-- 
Regards,
Shawn

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-24  7:46     ` Shawn Guo
  2011-11-24  7:41       ` Uwe Kleine-König
@ 2011-11-24  7:49       ` Wolfram Sang
  2011-11-24  8:23         ` Shawn Guo
  1 sibling, 1 reply; 91+ messages in thread
From: Wolfram Sang @ 2011-11-24  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 24, 2011 at 03:46:20PM +0800, Shawn Guo wrote:
> On Thu, Nov 24, 2011 at 03:36:05PM +0800, Shawn Guo wrote:
> > During the testing, the saif driver's dependency on
> > REGULATOR_FIXED_VOLTAGE was found.  I guess it should be resolved
> > in sound/soc/mxs/Kconfig rather than leaving it to users.
> > 
> Also SND_SOC_MXS_SGTL5000 should probably depends on I2C_MXS than I2C.

Please explain.

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111124/be61508b/attachment.sig>

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-24  7:49       ` Wolfram Sang
@ 2011-11-24  8:23         ` Shawn Guo
  2011-11-24 10:46           ` Wolfram Sang
  0 siblings, 1 reply; 91+ messages in thread
From: Shawn Guo @ 2011-11-24  8:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 24, 2011 at 08:49:38AM +0100, Wolfram Sang wrote:
> On Thu, Nov 24, 2011 at 03:46:20PM +0800, Shawn Guo wrote:
> > On Thu, Nov 24, 2011 at 03:36:05PM +0800, Shawn Guo wrote:
> > > During the testing, the saif driver's dependency on
> > > REGULATOR_FIXED_VOLTAGE was found.  I guess it should be resolved
> > > in sound/soc/mxs/Kconfig rather than leaving it to users.
> > > 
> > Also SND_SOC_MXS_SGTL5000 should probably depends on I2C_MXS than I2C.
> 
> Please explain.
> 
Sorry.  I meant 'select I2C_MXS'.

-- 
Regards,
Shawn

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

* [PATCH v7 0/3] ARM: mxs: add recording support for saif
  2011-11-24  8:23         ` Shawn Guo
@ 2011-11-24 10:46           ` Wolfram Sang
  0 siblings, 0 replies; 91+ messages in thread
From: Wolfram Sang @ 2011-11-24 10:46 UTC (permalink / raw)
  To: linux-arm-kernel


> > > Also SND_SOC_MXS_SGTL5000 should probably depends on I2C_MXS than I2C.
> > 
> > Please explain.
> > 
> Sorry.  I meant 'select I2C_MXS'.

>From kconfig-language.txt:

  Note:
        select should be used with care. select will force
        a symbol to a value without visiting the dependencies.
        By abusing select you are able to select a symbol FOO even
        if FOO depends on BAR that is not set.
        In general use select only for non-visible symbols
        (no prompts anywhere) and for symbols with no dependencies.
        That will limit the usefulness but on the other hand avoid
        the illegal configurations all over.

So, NACK from me.

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111124/ea4d9bd3/attachment.sig>

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

* [PATCH 1/5 v4] i2c/gpio: add DT support
       [not found] <a>
                   ` (3 preceding siblings ...)
  2011-11-22 15:54 ` [PATCH v7 3/3] ARM: mx28evk: set a initial clock rate " Dong Aisheng
@ 2012-03-13 12:33 ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 14:08   ` Wolfram Sang
  2012-03-15 15:56   ` [PATCH 1/5 v5] " Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 12:33 ` [PATCH 2/5 v4] ARM: at91: sam9g20 add i2c " Jean-Christophe PLAGNIOL-VILLARD
                   ` (16 subsequent siblings)
  21 siblings, 2 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

update to use devm_kzalloc for private data

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: linux-i2c at vger.kernel.org
Cc: devicetree-discuss at lists.ozlabs.org
---
v4:

	fix timeout
	use gpio_is_valid
 .../devicetree/bindings/gpio/gpio_i2c.txt          |   32 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |   94 +++++++++++++++----
 2 files changed, 106 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio_i2c.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio_i2c.txt b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt
new file mode 100644
index 0000000..4f8ec94
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt
@@ -0,0 +1,32 @@
+Device-Tree bindings for i2c gpio driver
+
+Required properties:
+	- compatible = "i2c-gpio";
+	- gpios: sda and scl gpio
+
+
+Optional properties:
+	- i2c-gpio,sda-open-drain: sda as open drain
+	- i2c-gpio,scl-open-drain: scl as open drain
+	- i2c-gpio,scl-output-only: scl as output only
+	- i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform)
+	- i2c-gpio,timeout-ms: timeout to get data
+
+Example nodes:
+
+i2c at 0 {
+	compatible = "i2c-gpio";
+	gpios = <&pioA 23 0 /* sda */
+		 &pioA 24 0 /* scl */
+		>;
+	i2c-gpio,sda-open-drain;
+	i2c-gpio,scl-open-drain;
+	i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	rv3029c2 at 56 {
+		compatible = "rv3029c2";
+		reg = <0x56>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index a651779..c0330a4 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,15 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+static int __devinit of_i2c_gpio_probe(struct device_node *np,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	u32 reg;
+
+	if (of_gpio_count(np) < 2)
+		return -ENODEV;
+
+	pdata->sda_pin = of_get_gpio(np, 0);
+	pdata->scl_pin = of_get_gpio(np, 1);
+
+	if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, pdata->sda_pin, pdata->scl_pin);
+		return -ENODEV;
+	}
+
+	of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
+
+	if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
+		pdata->timeout = msecs_to_jiffies(reg);
+
+	pdata->sda_is_open_drain =
+		of_property_read_bool(np, "i2c-gpio,sda-open-drain");
+	pdata->scl_is_open_drain =
+		of_property_read_bool(np, "i2c-gpio,scl-open-drain");
+	pdata->scl_is_output_only =
+		of_property_read_bool(np, "i2c-gpio,scl-output-only");
+
+	return 0;
+}
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.of_node) {
+		ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata);
+		if (ret)
+			return ret;
+	} else {
+		if (!pdev->dev.platform_data)
+			return -ENXIO;
+		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	of_i2c_register_devices(adap);
+
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
@@ -168,34 +216,40 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id i2c_gpio_dt_ids[] = {
+	{ .compatible = "i2c-gpio", },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids);
+#endif
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(i2c_gpio_dt_ids),
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.7

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

* [PATCH 2/5 v4] ARM: at91: sam9g20 add i2c DT support
       [not found] <a>
                   ` (4 preceding siblings ...)
  2012-03-13 12:33 ` [PATCH 1/5 v4] i2c/gpio: add DT support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 12:33 ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 12:33 ` [PATCH 3/5 v4] ARM: at91: usb_a9g20 add DT i2c support Jean-Christophe PLAGNIOL-VILLARD
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

For now on use i2c-gpio driver on the same pin as the hardware IP.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: devicetree-discuss at lists.ozlabs.org
---
 arch/arm/boot/dts/at91sam9g20.dtsi |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index 4b0dc99..a885a30 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -189,4 +189,17 @@
 			status = "disabled";
 		};
 	};
+
+	i2c at 0 {
+		compatible = "i2c-gpio";
+		gpios = <&pioA 23 0 /* sda */
+			 &pioA 24 0 /* scl */
+			>;
+		i2c-gpio,sda-open-drain;
+		i2c-gpio,scl-open-drain;
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
 };
-- 
1.7.7

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

* [PATCH 3/5 v4] ARM: at91: usb_a9g20 add DT i2c support
       [not found] <a>
                   ` (5 preceding siblings ...)
  2012-03-13 12:33 ` [PATCH 2/5 v4] ARM: at91: sam9g20 add i2c " Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 12:33 ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 12:33 ` [PATCH 4/5 v4] ARM: at91: sam9g45 add i2c DT support Jean-Christophe PLAGNIOL-VILLARD
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

Use i2c-gpio and enable rv3029 RTC.

Enable the rtc in the sam9g20 defconfig.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: devicetree-discuss at lists.ozlabs.org
---
 arch/arm/boot/dts/usb_a9g20.dts        |    9 +++++++++
 arch/arm/configs/at91sam9g20_defconfig |    3 +++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts
index 71d83ef..0ea90b5 100644
--- a/arch/arm/boot/dts/usb_a9g20.dts
+++ b/arch/arm/boot/dts/usb_a9g20.dts
@@ -97,4 +97,13 @@
 			gpio-key,wakeup;
 		};
 	};
+
+	i2c at 0 {
+		status = "okay";
+
+		rv3029c2 at 56 {
+			compatible = "rv3029c2";
+			reg = <0x56>;
+		};
+	};
 };
diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig
index 9123568..994d331 100644
--- a/arch/arm/configs/at91sam9g20_defconfig
+++ b/arch/arm/configs/at91sam9g20_defconfig
@@ -74,6 +74,8 @@ CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 CONFIG_SPI_SPIDEV=y
@@ -105,6 +107,7 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RV3029C2=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
 CONFIG_MSDOS_FS=y
-- 
1.7.7

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

* [PATCH 4/5 v4] ARM: at91: sam9g45 add i2c DT support
       [not found] <a>
                   ` (6 preceding siblings ...)
  2012-03-13 12:33 ` [PATCH 3/5 v4] ARM: at91: usb_a9g20 add DT i2c support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 12:33 ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 12:33 ` [PATCH 5/5 v4] ARM: at91: sam9x5 " Jean-Christophe PLAGNIOL-VILLARD
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

For now on use i2c-gpio driver on the same pin as the hardware IP.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: devicetree-discuss at lists.ozlabs.org
---
 arch/arm/boot/dts/at91sam9g45.dtsi |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index d79021b..92fe5a5 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -197,4 +197,17 @@
 			status = "disabled";
 		};
 	};
+
+	i2c at 0 {
+		compatible = "i2c-gpio";
+		gpios = <&pioA 20 0 /* sda */
+			 &pioA 21 0 /* scl */
+			>;
+		i2c-gpio,sda-open-drain;
+		i2c-gpio,scl-open-drain;
+		i2c-gpio,delay-us = <5>;	/* ~100 kHz */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
 };
-- 
1.7.7

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

* [PATCH 5/5 v4] ARM: at91: sam9x5 add i2c DT support
       [not found] <a>
                   ` (7 preceding siblings ...)
  2012-03-13 12:33 ` [PATCH 4/5 v4] ARM: at91: sam9g45 add i2c DT support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 12:33 ` Jean-Christophe PLAGNIOL-VILLARD
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

For now on use i2c-gpio driver on the same pin as the hardware IP.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: devicetree-discuss at lists.ozlabs.org
---
 arch/arm/boot/dts/at91sam9x5.dtsi |   39 +++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index c294657..f0104f4 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -188,4 +188,43 @@
 			status = "disabled";
 		};
 	};
+
+	i2c at 0 {
+		compatible = "i2c-gpio";
+		gpios = <&pioA 30 0 /* sda */
+			 &pioA 31 0 /* scl */
+			>;
+		i2c-gpio,sda-open-drain;
+		i2c-gpio,scl-open-drain;
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c at 1 {
+		compatible = "i2c-gpio";
+		gpios = <&pioC 0 0 /* sda */
+			 &pioC 1 0 /* scl */
+			>;
+		i2c-gpio,sda-open-drain;
+		i2c-gpio,scl-open-drain;
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c at 2 {
+		compatible = "i2c-gpio";
+		gpios = <&pioB 4 0 /* sda */
+			 &pioB 5 0 /* scl */
+			>;
+		i2c-gpio,sda-open-drain;
+		i2c-gpio,scl-open-drain;
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
 };
-- 
1.7.7

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

* [PATCH 1/5 v4] i2c/gpio: add DT support
  2012-03-13 12:33 ` [PATCH 1/5 v4] i2c/gpio: add DT support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 14:08   ` Wolfram Sang
  2012-03-13 16:47     ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-15 15:56   ` [PATCH 1/5 v5] " Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 91+ messages in thread
From: Wolfram Sang @ 2012-03-13 14:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 13, 2012 at 01:33:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:

> update to use devm_kzalloc for private data

Hmm, you need really to work on the commit messages, not everybody is
familiar with DT and its implications:

"To achieve DT support, we need to populate a custom platform_data in a
private struct from DT information. To simplify code, the adapter and
algorithm are also put into the private struct."

Something like this?

> ---
> v4:
> 
> 	fix timeout

You need to work on the changelogs as well :)

> 	use gpio_is_valid

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120313/913aa960/attachment.sig>

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

* [PATCH 1/5 v4] i2c/gpio: add DT support
  2012-03-13 14:08   ` Wolfram Sang
@ 2012-03-13 16:47     ` Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 19:46       ` Wolfram Sang
  0 siblings, 1 reply; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-13 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 15:08 Tue 13 Mar     , Wolfram Sang wrote:
> On Tue, Mar 13, 2012 at 01:33:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> 
> > update to use devm_kzalloc for private data
> 
> Hmm, you need really to work on the commit messages, not everybody is
> familiar with DT and its implications:
> 
> "To achieve DT support, we need to populate a custom platform_data in a
> private struct from DT information. To simplify code, the adapter and
> algorithm are also put into the private struct."
> 
ok I put this can I get the Ack ?

I need to send the pull asap

Best Regards,
J.

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

* [PATCH 1/5 v4] i2c/gpio: add DT support
  2012-03-13 16:47     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2012-03-13 19:46       ` Wolfram Sang
  0 siblings, 0 replies; 91+ messages in thread
From: Wolfram Sang @ 2012-03-13 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 13, 2012 at 05:47:56PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 15:08 Tue 13 Mar     , Wolfram Sang wrote:
> > On Tue, Mar 13, 2012 at 01:33:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > 
> > > update to use devm_kzalloc for private data
> > 
> > Hmm, you need really to work on the commit messages, not everybody is
> > familiar with DT and its implications:
> > 
> > "To achieve DT support, we need to populate a custom platform_data in a
> > private struct from DT information. To simplify code, the adapter and
> > algorithm are also put into the private struct."
> > 
> ok I put this can I get the Ack ?

Yes.

> I need to send the pull asap

Please, no rush. Makes it too easy for bugs to slip in...

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120313/7cf3bc0a/attachment.sig>

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

* [PATCH 1/5 v5] i2c/gpio: add DT support
  2012-03-13 12:33 ` [PATCH 1/5 v4] i2c/gpio: add DT support Jean-Christophe PLAGNIOL-VILLARD
  2012-03-13 14:08   ` Wolfram Sang
@ 2012-03-15 15:56   ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 0 replies; 91+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-03-15 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

To achieve DT support, we need to populate a custom platform_data in a
private struct from DT information. To simplify code, the adapter and
algorithm are also put into the private struct.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 .../devicetree/bindings/gpio/gpio_i2c.txt          |   32 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |   94 +++++++++++++++----
 2 files changed, 106 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio_i2c.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio_i2c.txt b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt
new file mode 100644
index 0000000..4f8ec94
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt
@@ -0,0 +1,32 @@
+Device-Tree bindings for i2c gpio driver
+
+Required properties:
+	- compatible = "i2c-gpio";
+	- gpios: sda and scl gpio
+
+
+Optional properties:
+	- i2c-gpio,sda-open-drain: sda as open drain
+	- i2c-gpio,scl-open-drain: scl as open drain
+	- i2c-gpio,scl-output-only: scl as output only
+	- i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform)
+	- i2c-gpio,timeout-ms: timeout to get data
+
+Example nodes:
+
+i2c at 0 {
+	compatible = "i2c-gpio";
+	gpios = <&pioA 23 0 /* sda */
+		 &pioA 24 0 /* scl */
+		>;
+	i2c-gpio,sda-open-drain;
+	i2c-gpio,scl-open-drain;
+	i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	rv3029c2 at 56 {
+		compatible = "rv3029c2";
+		reg = <0x56>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index a651779..c0330a4 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,15 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+static int __devinit of_i2c_gpio_probe(struct device_node *np,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	u32 reg;
+
+	if (of_gpio_count(np) < 2)
+		return -ENODEV;
+
+	pdata->sda_pin = of_get_gpio(np, 0);
+	pdata->scl_pin = of_get_gpio(np, 1);
+
+	if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, pdata->sda_pin, pdata->scl_pin);
+		return -ENODEV;
+	}
+
+	of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
+
+	if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
+		pdata->timeout = msecs_to_jiffies(reg);
+
+	pdata->sda_is_open_drain =
+		of_property_read_bool(np, "i2c-gpio,sda-open-drain");
+	pdata->scl_is_open_drain =
+		of_property_read_bool(np, "i2c-gpio,scl-open-drain");
+	pdata->scl_is_output_only =
+		of_property_read_bool(np, "i2c-gpio,scl-output-only");
+
+	return 0;
+}
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.of_node) {
+		ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata);
+		if (ret)
+			return ret;
+	} else {
+		if (!pdev->dev.platform_data)
+			return -ENXIO;
+		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	of_i2c_register_devices(adap);
+
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
@@ -168,34 +216,40 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id i2c_gpio_dt_ids[] = {
+	{ .compatible = "i2c-gpio", },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids);
+#endif
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(i2c_gpio_dt_ids),
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.7

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

* [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13
       [not found] <a>
                   ` (8 preceding siblings ...)
  2012-03-13 12:33 ` [PATCH 5/5 v4] ARM: at91: sam9x5 " Jean-Christophe PLAGNIOL-VILLARD
@ 2013-08-13 13:31 ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine Viresh Kumar
                     ` (36 more replies)
  2014-01-03  3:01 ` [PATCH 0/3] mtd: gpmi: add subpage read support Huang Shijie
                   ` (11 subsequent siblings)
  21 siblings, 37 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Currently prototype of cpufreq_drivers target routines is:

int target(struct cpufreq_policy *policy, unsigned int target_freq,
        unsigned int relation);

And most of the drivers call cpufreq_frequency_table_target() to get a valid
index of their frequency table which is closest to the target_freq. And they
don't use target_freq and relation after it.

So, it makes sense to just do this work in cpufreq core before calling
cpufreq_frequency_table_target() and simply pass index instead. But this can be
done only with drivers which expose their frequency table with cpufreq core. For
others we need to stick with the old prototype of target() until those drivers
are converted to expose frequency tables.

There are 7 drivers after this patchset which still use the heavy weight
version, i.e. target() and 44 drivers have adopted this new approach, i.e.
target_index().

Once those 7 drivers are also moved to use .target_index(), .target() will be
removed completely.

This is part 3 of my generic cpufreq cleanup stuff.. First two are posted here
and this one is rebased of them:

1: cpufreq: Introduce cpufreq_table_validate_and_show()
https://lkml.org/lkml/2013/8/8/263

2: cpufreq: define generic routines for cpufreq drivers
https://lkml.org/lkml/2013/8/10/48

All these are pushed here:
https://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/for-v3.13

V1->V2:
------
- Must be less ugly this time :)
- new interface is named as target_index() instead of target()
- old interface is kept as target() instead of target_old()
- few more drivers got converted to use this infrastructure (5)
- Documentation updates
- CONFIG_CPU_FREQ_TABLE removed completely as core depends on it now

Cc: Andrew Lunn <andrew@lunn.ch>
Cc: David S. Miller <davem@davemloft.net>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: John Crispin <blogic@openwrt.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-cris-kernel at axis.com
Cc: Mikael Starvik <starvik@axis.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: sparclinux at vger.kernel.org
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Tony Luck <tony.luck@intel.com>

Viresh Kumar (35):
  cpufreq: Implement light weight ->target_index() routine
  cpufreq: remove CONFIG_CPU_FREQ_TABLE
  cpufreq: acpi: Covert to light weight ->target_index() routine
  cpufreq: arm_big_little: Covert to light weight ->target_index()
    routine
  cpufreq: at32ap: Covert to light weight ->target_index() routine
  cpufreq: blackfin: Covert to light weight ->target_index() routine
  cpufreq: cpu0: Covert to light weight ->target_index() routine
  cpufreq: cris: Covert to light weight ->target_index() routine
  cpufreq: davinci: Covert to light weight ->target_index() routine
  cpufreq: dbx500: Covert to light weight ->target_index() routine
  cpufreq: e_powersaver: Covert to light weight ->target_index()
    routine
  cpufreq: elanfreq: Covert to light weight ->target_index() routine
  cpufreq: exynos: Covert to light weight ->target_index() routine
  cpufreq: ia64: Covert to light weight ->target_index() routine
  cpufreq: imx6q: Covert to light weight ->target_index() routine
  cpufreq: kirkwood: Covert to light weight ->target_index() routine
  cpufreq: longhaul: Covert to light weight ->target_index() routine
  cpufreq: loongson2: Covert to light weight ->target_index() routine
  cpufreq: maple: Covert to light weight ->target_index() routine
  cpufreq: omap: Covert to light weight ->target_index() routine
  cpufreq: p4: Covert to light weight ->target_index() routine
  cpufreq: pasemi: Covert to light weight ->target_index() routine
  cpufreq: pmac32: Covert to light weight ->target_index() routine
  cpufreq: powernow: Covert to light weight ->target_index() routine
  cpufreq: ppc: Covert to light weight ->target_index() routine
  cpufreq: pxa: Covert to light weight ->target_index() routine
  cpufreq: s3c2416: Covert to light weight ->target_index() routine
  cpufreq: s3c64xx: Covert to light weight ->target_index() routine
  cpufreq: s5pv210: Covert to light weight ->target_index() routine
  cpufreq: sa11x0: Covert to light weight ->target_index() routine
  cpufreq: sc520: Covert to light weight ->target_index() routine
  cpufreq: sparc: Covert to light weight ->target_index() routine
  cpufreq: SPEAr: Covert to light weight ->target_index() routine
  cpufreq: speedstep: Covert to light weight ->target_index() routine
  cpufreq: tegra: Covert to light weight ->target_index() routine

 Documentation/cpu-freq/cpu-drivers.txt | 27 ++++++++++------
 Documentation/cpu-freq/governors.txt   |  4 +--
 arch/arm/mach-davinci/Kconfig          |  1 -
 arch/arm/mach-pxa/Kconfig              |  3 --
 arch/arm/mach-sa1100/generic.c         | 20 ------------
 arch/arm/mach-sa1100/generic.h         |  2 --
 arch/arm/mach-ux500/Kconfig            |  1 -
 arch/blackfin/Kconfig                  |  1 -
 arch/cris/Kconfig                      |  2 --
 drivers/cpufreq/Kconfig                | 11 -------
 drivers/cpufreq/Kconfig.arm            | 11 -------
 drivers/cpufreq/Kconfig.powerpc        |  6 ----
 drivers/cpufreq/Kconfig.x86            | 13 --------
 drivers/cpufreq/Makefile               |  5 +--
 drivers/cpufreq/acpi-cpufreq.c         | 21 ++++---------
 drivers/cpufreq/arm_big_little.c       | 17 +++-------
 drivers/cpufreq/at32ap-cpufreq.c       | 23 +++-----------
 drivers/cpufreq/blackfin-cpufreq.c     | 17 +++-------
 drivers/cpufreq/cpufreq-cpu0.c         | 17 ++--------
 drivers/cpufreq/cpufreq.c              | 57 ++++++++++++++++++++++++++--------
 drivers/cpufreq/cris-artpec3-cpufreq.c | 18 ++---------
 drivers/cpufreq/cris-etraxfs-cpufreq.c | 17 ++--------
 drivers/cpufreq/davinci-cpufreq.c      | 16 ++--------
 drivers/cpufreq/dbx500-cpufreq.c       | 16 ++--------
 drivers/cpufreq/e_powersaver.c         | 17 ++--------
 drivers/cpufreq/elanfreq.c             | 34 ++------------------
 drivers/cpufreq/exynos-cpufreq.c       | 21 ++-----------
 drivers/cpufreq/exynos5440-cpufreq.c   | 13 ++------
 drivers/cpufreq/ia64-acpi-cpufreq.c    | 21 ++-----------
 drivers/cpufreq/imx6q-cpufreq.c        | 17 ++--------
 drivers/cpufreq/kirkwood-cpufreq.c     | 19 ++----------
 drivers/cpufreq/longhaul.c             | 13 ++------
 drivers/cpufreq/loongson2_cpufreq.c    | 21 +++----------
 drivers/cpufreq/maple-cpufreq.c        | 16 +++-------
 drivers/cpufreq/omap-cpufreq.c         | 31 ++----------------
 drivers/cpufreq/p4-clockmod.c          | 18 +++--------
 drivers/cpufreq/pasemi-cpufreq.c       | 12 ++-----
 drivers/cpufreq/pmac32-cpufreq.c       | 12 ++-----
 drivers/cpufreq/pmac64-cpufreq.c       | 17 +++-------
 drivers/cpufreq/powernow-k6.c          | 35 +++------------------
 drivers/cpufreq/powernow-k7.c          | 22 +++----------
 drivers/cpufreq/powernow-k8.c          | 24 +++++---------
 drivers/cpufreq/ppc-corenet-cpufreq.c  | 15 +++------
 drivers/cpufreq/ppc_cbe_cpufreq.c      | 12 ++-----
 drivers/cpufreq/pxa2xx-cpufreq.c       | 13 ++------
 drivers/cpufreq/pxa3xx-cpufreq.c       | 17 ++--------
 drivers/cpufreq/s3c2416-cpufreq.c      | 17 +++-------
 drivers/cpufreq/s3c64xx-cpufreq.c      | 18 +++--------
 drivers/cpufreq/s5pv210-cpufreq.c      | 54 +++++++++-----------------------
 drivers/cpufreq/sa1100-cpufreq.c       | 24 +++-----------
 drivers/cpufreq/sa1110-cpufreq.c       | 26 +++-------------
 drivers/cpufreq/sc520_freq.c           | 19 ++----------
 drivers/cpufreq/sparc-us2e-cpufreq.c   | 21 ++-----------
 drivers/cpufreq/sparc-us3-cpufreq.c    | 23 ++------------
 drivers/cpufreq/spear-cpufreq.c        | 12 +++----
 drivers/cpufreq/speedstep-centrino.c   | 26 +++++-----------
 drivers/cpufreq/speedstep-ich.c        | 24 ++++----------
 drivers/cpufreq/speedstep-smi.c        | 20 +++---------
 drivers/cpufreq/tegra-cpufreq.c        | 12 ++-----
 drivers/thermal/Kconfig                |  1 -
 include/linux/cpufreq.h                |  4 ++-
 61 files changed, 238 insertions(+), 809 deletions(-)

-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-18 10:41     ` amit daniel kachhap
  2013-08-13 13:32   ` [PATCH V2 02/35] cpufreq: remove CONFIG_CPU_FREQ_TABLE Viresh Kumar
                     ` (35 subsequent siblings)
  36 siblings, 1 reply; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

Currently prototype of cpufreq_drivers target routines is:

int target(struct cpufreq_policy *policy, unsigned int target_freq,
		unsigned int relation);

And most of the drivers call cpufreq_frequency_table_target() to get a valid
index of their frequency table which is closest to the target_freq. And they
don't use target_freq and relation after it.

So, it makes sense to just do this work in cpufreq core before calling
cpufreq_frequency_table_target() and simply pass index instead. But this can be
done only with drivers which expose their frequency table with cpufreq core. For
others we need to stick with the old prototype of target() until those drivers
are converted to expose frequency tables.

This patch implements the new light weight prototype for target_index() routine.
It looks like this:

int target_index(struct cpufreq_policy *policy, unsigned int index);

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and pass index to it. Because CPUFreq core now requires to call routines
present in freq_table.c CONFIG_CPU_FREQ_TABLE must be enabled all the time.

This also marks target() interface as deprecated. So, that new drivers avoid
using it. And

Documentation is updated accordingly.

Cc: Andrew Lunn <andrew@lunn.ch>
Cc: David S. Miller <davem@davemloft.net>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: John Crispin <blogic@openwrt.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-cris-kernel at axis.com
Cc: Mikael Starvik <starvik@axis.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: sparclinux at vger.kernel.org
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Tony Luck <tony.luck@intel.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 Documentation/cpu-freq/cpu-drivers.txt | 27 +++++++++++------
 Documentation/cpu-freq/governors.txt   |  4 +--
 drivers/cpufreq/Kconfig                |  1 +
 drivers/cpufreq/cpufreq.c              | 55 +++++++++++++++++++++++++++-------
 include/linux/cpufreq.h                |  4 ++-
 5 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
index 40282e6..8b1a445 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -23,8 +23,8 @@ Contents:
 1.1  Initialization
 1.2  Per-CPU Initialization
 1.3  verify
-1.4  target or setpolicy?
-1.5  target
+1.4  target/target_index or setpolicy?
+1.5  target/target_index
 1.6  setpolicy
 2.   Frequency Table Helpers
 
@@ -56,7 +56,8 @@ cpufreq_driver.init -		A pointer to the per-CPU initialization
 cpufreq_driver.verify -		A pointer to a "verification" function.
 
 cpufreq_driver.setpolicy _or_ 
-cpufreq_driver.target -		See below on the differences.
+cpufreq_driver.target/
+target_index		-	See below on the differences.
 
 And optionally
 
@@ -66,7 +67,7 @@ cpufreq_driver.resume -		A pointer to a per-CPU resume function
 				which is called with interrupts disabled
 				and _before_ the pre-suspend frequency
 				and/or policy is restored by a call to
-				->target or ->setpolicy.
+				->target/target_index or ->setpolicy.
 
 cpufreq_driver.attr -		A pointer to a NULL-terminated list of
 				"struct freq_attr" which allow to
@@ -103,8 +104,8 @@ policy->governor		must contain the "default policy" for
 				this CPU. A few moments later,
 				cpufreq_driver.verify and either
 				cpufreq_driver.setpolicy or
-				cpufreq_driver.target is called with
-				these values.
+				cpufreq_driver.target/target_index is called
+				with these values.
 
 For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
 frequency table helpers might be helpful. See the section 2 for more information
@@ -133,20 +134,28 @@ range) is within policy->min and policy->max. If necessary, increase
 policy->max first, and only if this is no solution, decrease policy->min.
 
 
-1.4 target or setpolicy?
+1.4 target/target_index or setpolicy?
 ----------------------------
 
 Most cpufreq drivers or even most cpu frequency scaling algorithms 
 only allow the CPU to be set to one frequency. For these, you use the
-->target call.
+->target/target_index call.
 
 Some cpufreq-capable processors switch the frequency between certain
 limits on their own. These shall use the ->setpolicy call
 
 
-1.4. target
+1.4. target/target_index
 -------------
 
+The target_index call has two arguments: struct cpufreq_policy *policy,
+and unsigned int index (into the exposed frequency table).
+
+The CPUfreq driver must set the new frequency when called here. The
+actual frequency must be determined by freq_table[index].frequency.
+
+Deprecated:
+----------
 The target call has three arguments: struct cpufreq_policy *policy,
 unsigned int target_frequency, unsigned int relation.
 
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 219970b..77ec215 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -40,7 +40,7 @@ Most cpufreq drivers (in fact, all except one, longrun) or even most
 cpu frequency scaling algorithms only offer the CPU to be set to one
 frequency. In order to offer dynamic frequency scaling, the cpufreq
 core must be able to tell these drivers of a "target frequency". So
-these specific drivers will be transformed to offer a "->target"
+these specific drivers will be transformed to offer a "->target/target_index"
 call instead of the existing "->setpolicy" call. For "longrun", all
 stays the same, though.
 
@@ -71,7 +71,7 @@ CPU can be set to switch independently	 |	   CPU can only be set
 		    /			       the limits of policy->{min,max}
 		   /			            \
 		  /				     \
-	Using the ->setpolicy call,		 Using the ->target call,
+	Using the ->setpolicy call,		 Using the ->target/target_index call,
 	    the limits and the			  the frequency closest
 	     "policy" is set.			  to target_freq is set.
 						  It is assured that it
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 534fcb8..2d06754 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -2,6 +2,7 @@ menu "CPU Frequency scaling"
 
 config CPU_FREQ
 	bool "CPU Frequency scaling"
+	select CPU_FREQ_TABLE
 	help
 	  CPU Frequency scaling allows you to change the clock speed of 
 	  CPUs on the fly. This is a nice method to save power, because 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 37a6874..f1b0e0f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list);
 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
 #endif
 
+static inline bool has_target(void)
+{
+	return cpufreq_driver->target_index || cpufreq_driver->target;
+}
+
 /*
  * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
  * all cpufreq/hotplug/workqueue/etc related lock issues.
@@ -377,7 +382,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
 			*policy = CPUFREQ_POLICY_POWERSAVE;
 			err = 0;
 		}
-	} else if (cpufreq_driver->target) {
+	} else if (has_target()) {
 		struct cpufreq_governor *t;
 
 		mutex_lock(&cpufreq_governor_mutex);
@@ -539,7 +544,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
 	ssize_t i = 0;
 	struct cpufreq_governor *t;
 
-	if (!cpufreq_driver->target) {
+	if (!has_target()) {
 		i += sprintf(buf, "performance powersave");
 		goto out;
 	}
@@ -822,7 +827,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
 		if (ret)
 			goto err_out_kobj_put;
 	}
-	if (cpufreq_driver->target) {
+	if (has_target()) {
 		ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
 		if (ret)
 			goto err_out_kobj_put;
@@ -871,10 +876,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
 				  unsigned int cpu, struct device *dev,
 				  bool frozen)
 {
-	int ret = 0, has_target = !!cpufreq_driver->target;
+	int ret = 0;
 	unsigned long flags;
 
-	if (has_target) {
+	if (has_target()) {
 		ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
 		if (ret) {
 			pr_err("%s: Failed to stop governor\n", __func__);
@@ -893,7 +898,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
 
 	unlock_policy_rwsem_write(policy->cpu);
 
-	if (has_target) {
+	if (has_target()) {
 		if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
 			(ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
 			pr_err("%s: Failed to start governor\n", __func__);
@@ -1204,7 +1209,7 @@ static int __cpufreq_remove_dev(struct device *dev,
 		return -EINVAL;
 	}
 
-	if (cpufreq_driver->target) {
+	if (has_target()) {
 		ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
 		if (ret) {
 			pr_err("%s: Failed to stop governor\n", __func__);
@@ -1244,7 +1249,7 @@ static int __cpufreq_remove_dev(struct device *dev,
 
 	/* If cpu is last user of policy, free policy */
 	if (cpus == 1) {
-		if (cpufreq_driver->target) {
+		if (has_target()) {
 			ret = __cpufreq_governor(policy,
 					CPUFREQ_GOV_POLICY_EXIT);
 			if (ret) {
@@ -1282,7 +1287,7 @@ static int __cpufreq_remove_dev(struct device *dev,
 		if (!frozen)
 			cpufreq_policy_free(policy);
 	} else {
-		if (cpufreq_driver->target) {
+		if (has_target()) {
 			if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
 					(ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
 				pr_err("%s: Failed to start governor\n",
@@ -1646,11 +1651,39 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
 	pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
 			policy->cpu, target_freq, relation, old_target_freq);
 
+	/*
+	 * This might look like a redundant call as we are checking it again
+	 * after finding index. But it is left intentionally for cases where
+	 * exactly same freq is called again and so we can save on few function
+	 * calls.
+	 */
 	if (target_freq == policy->cur)
 		return 0;
 
 	if (cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
+	else if (cpufreq_driver->target_index) {
+		struct cpufreq_frequency_table *freq_table;
+		int index;
+
+		freq_table = cpufreq_frequency_get_table(policy->cpu);
+		if (unlikely(!freq_table)) {
+			pr_err("%s: Unable to find freq_table\n", __func__);
+			return retval;
+		}
+
+		retval = cpufreq_frequency_table_target(policy, freq_table,
+				target_freq, relation, &index);
+		if (unlikely(retval)) {
+			pr_err("%s: Unable to find matching freq\n", __func__);
+			return retval;
+		}
+
+		if (freq_table[index].frequency == policy->cur)
+			return 0;
+
+		retval = cpufreq_driver->target_index(policy, index);
+	}
 
 	return retval;
 }
@@ -1983,7 +2016,7 @@ int cpufreq_update_policy(unsigned int cpu)
 			pr_debug("Driver did not initialize current freq");
 			policy->cur = new_policy.cur;
 		} else {
-			if (policy->cur != new_policy.cur && cpufreq_driver->target)
+			if (policy->cur != new_policy.cur && has_target())
 				cpufreq_out_of_sync(cpu, policy->cur,
 								new_policy.cur);
 		}
@@ -2058,7 +2091,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
 		return -ENODEV;
 
 	if (!driver_data || !driver_data->verify || !driver_data->init ||
-	    ((!driver_data->setpolicy) && (!driver_data->target)))
+	    (!driver_data->setpolicy && !has_target()))
 		return -EINVAL;
 
 	pr_debug("trying to register driver %s\n", driver_data->name);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 4907eb2..ff9c8df 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -195,9 +195,11 @@ struct cpufreq_driver {
 
 	/* define one out of two */
 	int	(*setpolicy)	(struct cpufreq_policy *policy);
-	int	(*target)	(struct cpufreq_policy *policy,
+	int	(*target)	(struct cpufreq_policy *policy,	/* Deprecated */
 				 unsigned int target_freq,
 				 unsigned int relation);
+	int	(*target_index)	(struct cpufreq_policy *policy,
+				 unsigned int index);
 
 	/* should be defined, if possible */
 	unsigned int	(*get)	(unsigned int cpu);
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 02/35] cpufreq: remove CONFIG_CPU_FREQ_TABLE
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 03/35] cpufreq: acpi: Covert to light weight ->target_index() routine Viresh Kumar
                     ` (34 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

CONFIG_CPU_FREQ_TABLE will be always enabled when cpufreq framework is used, as
cpufreq core depends on it. So, we don't need this CONFIG option anymore as it
is not configurable. Remove CONFIG_CPU_FREQ_TABLE and update its users.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 arch/arm/mach-davinci/Kconfig   |  1 -
 arch/arm/mach-pxa/Kconfig       |  3 ---
 arch/arm/mach-ux500/Kconfig     |  1 -
 arch/blackfin/Kconfig           |  1 -
 arch/cris/Kconfig               |  2 --
 drivers/cpufreq/Kconfig         | 12 ------------
 drivers/cpufreq/Kconfig.arm     | 11 -----------
 drivers/cpufreq/Kconfig.powerpc |  6 ------
 drivers/cpufreq/Kconfig.x86     | 13 -------------
 drivers/cpufreq/Makefile        |  5 +----
 drivers/cpufreq/cpufreq.c       |  2 --
 drivers/thermal/Kconfig         |  1 -
 12 files changed, 1 insertion(+), 57 deletions(-)

diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index e026b19..a075b3e 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -40,7 +40,6 @@ config ARCH_DAVINCI_DA850
 	bool "DA850/OMAP-L138/AM18x based system"
 	select ARCH_DAVINCI_DA8XX
 	select ARCH_HAS_CPUFREQ
-	select CPU_FREQ_TABLE
 	select CP_INTC
 
 config ARCH_DAVINCI_DA8XX
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index a842711..96100db 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -615,14 +615,12 @@ endmenu
 config PXA25x
 	bool
 	select CPU_XSCALE
-	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA21x/25x/26x variants
 
 config PXA27x
 	bool
 	select CPU_XSCALE
-	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA27x variants
 
@@ -635,7 +633,6 @@ config CPU_PXA26x
 config PXA3xx
 	bool
 	select CPU_XSC3
-	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA3xx variants
 
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index b19b072..e6eaefa 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -34,7 +34,6 @@ config UX500_SOC_COMMON
 
 config UX500_SOC_DB8500
 	bool
-	select CPU_FREQ_TABLE if CPU_FREQ
 	select MFD_DB8500_PRCMU
 	select PINCTRL_DB8500
 	select PINCTRL_DB8540
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 3b6abc5..1ac474a 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -1430,7 +1430,6 @@ source "drivers/cpufreq/Kconfig"
 config BFIN_CPU_FREQ
 	bool
 	depends on CPU_FREQ
-	select CPU_FREQ_TABLE
 	default y
 
 config CPU_VOLTAGE
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 3201ddb..9f3c5436 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -134,13 +134,11 @@ config SVINTO_SIM
 
 config ETRAXFS
 	bool "ETRAX-FS-V32"
-	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Support CRIS V32.
 
 config CRIS_MACH_ARTPEC3
         bool "ARTPEC-3"
-	select CPU_FREQ_TABLE if CPU_FREQ
         help
           Support Axis ARTPEC-3.
 
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 2d06754..38093e2 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -2,7 +2,6 @@ menu "CPU Frequency scaling"
 
 config CPU_FREQ
 	bool "CPU Frequency scaling"
-	select CPU_FREQ_TABLE
 	help
 	  CPU Frequency scaling allows you to change the clock speed of 
 	  CPUs on the fly. This is a nice method to save power, because 
@@ -18,15 +17,11 @@ config CPU_FREQ
 
 if CPU_FREQ
 
-config CPU_FREQ_TABLE
-	tristate
-
 config CPU_FREQ_GOV_COMMON
 	bool
 
 config CPU_FREQ_STAT
 	tristate "CPU frequency translation statistics"
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This driver exports CPU frequency statistics information through sysfs
@@ -144,7 +139,6 @@ config CPU_FREQ_GOV_USERSPACE
 
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
-	select CPU_FREQ_TABLE
 	select CPU_FREQ_GOV_COMMON
 	help
 	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
@@ -188,7 +182,6 @@ config CPU_FREQ_GOV_CONSERVATIVE
 config GENERIC_CPUFREQ_CPU0
 	tristate "Generic CPU0 cpufreq driver"
 	depends on HAVE_CLK && REGULATOR && PM_OPP && OF
-	select CPU_FREQ_TABLE
 	help
 	  This adds a generic cpufreq driver for CPU0 frequency management.
 	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
@@ -224,7 +217,6 @@ depends on IA64
 
 config IA64_ACPI_CPUFREQ
 	tristate "ACPI Processor P-States driver"
-	select CPU_FREQ_TABLE
 	depends on ACPI_PROCESSOR
 	help
 	This driver adds a CPUFreq driver which utilizes the ACPI
@@ -241,7 +233,6 @@ depends on MIPS
 
 config LOONGSON2_CPUFREQ
 	tristate "Loongson2 CPUFreq Driver"
-	select CPU_FREQ_TABLE
 	help
 	  This option adds a CPUFreq driver for loongson processors which
 	  support software configurable cpu frequency.
@@ -263,7 +254,6 @@ menu "SPARC CPU frequency scaling drivers"
 depends on SPARC64
 config SPARC_US3_CPUFREQ
 	tristate "UltraSPARC-III CPU Frequency driver"
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for UltraSPARC-III processors.
 
@@ -273,7 +263,6 @@ config SPARC_US3_CPUFREQ
 
 config SPARC_US2E_CPUFREQ
 	tristate "UltraSPARC-IIe CPU Frequency driver"
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for UltraSPARC-IIe processors.
 
@@ -286,7 +275,6 @@ menu "SH CPU Frequency scaling"
 depends on SUPERH
 config SH_CPU_FREQ
 	tristate "SuperH CPU Frequency driver"
-	select CPU_FREQ_TABLE
 	help
 	  This adds the cpufreq driver for SuperH. Any CPU that supports
 	  clock rate rounding through the clock framework can use this
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de4d5d9..1bbb71e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -5,7 +5,6 @@
 config ARM_BIG_LITTLE_CPUFREQ
 	tristate "Generic ARM big LITTLE CPUfreq driver"
 	depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
-	select CPU_FREQ_TABLE
 	help
 	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
 
@@ -19,7 +18,6 @@ config ARM_DT_BL_CPUFREQ
 config ARM_EXYNOS_CPUFREQ
 	bool "SAMSUNG EXYNOS SoCs"
 	depends on ARCH_EXYNOS
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver common part for Samsung
@@ -48,7 +46,6 @@ config ARM_EXYNOS5250_CPUFREQ
 config ARM_EXYNOS5440_CPUFREQ
 	def_bool SOC_EXYNOS5440
 	depends on HAVE_CLK && PM_OPP && OF
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for Samsung EXYNOS5440
 	  SoC. The nature of exynos5440 clock controller is
@@ -73,7 +70,6 @@ config ARM_IMX6Q_CPUFREQ
 	tristate "Freescale i.MX6Q cpufreq support"
 	depends on SOC_IMX6Q
 	depends on REGULATOR_ANATOP
-	select CPU_FREQ_TABLE
 	help
 	  This adds cpufreq driver support for Freescale i.MX6Q SOC.
 
@@ -89,7 +85,6 @@ config ARM_INTEGRATOR
 
 config ARM_KIRKWOOD_CPUFREQ
 	def_bool ARCH_KIRKWOOD && OF
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for Marvell Kirkwood
 	  SoCs.
@@ -98,7 +93,6 @@ config ARM_OMAP2PLUS_CPUFREQ
 	bool "TI OMAP2+"
 	depends on ARCH_OMAP2PLUS
 	default ARCH_OMAP2PLUS
-	select CPU_FREQ_TABLE
 
 config ARM_S3C_CPUFREQ
 	bool
@@ -153,7 +147,6 @@ config ARM_S3C2412_CPUFREQ
 config ARM_S3C2416_CPUFREQ
 	bool "S3C2416 CPU Frequency scaling support"
 	depends on CPU_S3C2416
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for the Samsung S3C2416 and
 	  S3C2450 SoC. The S3C2416 supports changing the rate of the
@@ -184,7 +177,6 @@ config ARM_S3C2440_CPUFREQ
 config ARM_S3C64XX_CPUFREQ
 	bool "Samsung S3C64XX"
 	depends on CPU_S3C6410
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver for Samsung S3C6410 SoC.
@@ -194,7 +186,6 @@ config ARM_S3C64XX_CPUFREQ
 config ARM_S5PV210_CPUFREQ
 	bool "Samsung S5PV210 and S5PC110"
 	depends on CPU_S5PV210
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver for Samsung S5PV210 and
@@ -211,7 +202,6 @@ config ARM_SA1110_CPUFREQ
 config ARM_SPEAR_CPUFREQ
 	bool "SPEAr CPUFreq support"
 	depends on PLAT_SPEAR
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver support for SPEAr SOCs.
@@ -219,7 +209,6 @@ config ARM_SPEAR_CPUFREQ
 config ARM_TEGRA_CPUFREQ
 	bool "TEGRA CPUFreq support"
 	depends on ARCH_TEGRA
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver support for TEGRA SOCs.
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index 25ca9db..ca0021a 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -1,7 +1,6 @@
 config CPU_FREQ_CBE
 	tristate "CBE frequency scaling"
 	depends on CBE_RAS && PPC_CELL
-	select CPU_FREQ_TABLE
 	default m
 	help
 	  This adds the cpufreq driver for Cell BE processors.
@@ -20,7 +19,6 @@ config CPU_FREQ_CBE_PMI
 config CPU_FREQ_MAPLE
 	bool "Support for Maple 970FX Evaluation Board"
 	depends on PPC_MAPLE
-	select CPU_FREQ_TABLE
 	help
 	  This adds support for frequency switching on Maple 970FX
 	  Evaluation Board and compatible boards (IBM JS2x blades).
@@ -28,7 +26,6 @@ config CPU_FREQ_MAPLE
 config PPC_CORENET_CPUFREQ
 	tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
 	depends on PPC_E500MC && OF && COMMON_CLK
-	select CPU_FREQ_TABLE
 	select CLK_PPC_CORENET
 	help
 	  This adds the CPUFreq driver support for Freescale e500mc,
@@ -38,7 +35,6 @@ config PPC_CORENET_CPUFREQ
 config CPU_FREQ_PMAC
 	bool "Support for Apple PowerBooks"
 	depends on ADB_PMU && PPC32
-	select CPU_FREQ_TABLE
 	help
 	  This adds support for frequency switching on Apple PowerBooks,
 	  this currently includes some models of iBook & Titanium
@@ -47,7 +43,6 @@ config CPU_FREQ_PMAC
 config CPU_FREQ_PMAC64
 	bool "Support for some Apple G5s"
 	depends on PPC_PMAC && PPC64
-	select CPU_FREQ_TABLE
 	help
 	  This adds support for frequency switching on Apple iMac G5,
 	  and some of the more recent desktop G5 machines as well.
@@ -55,7 +50,6 @@ config CPU_FREQ_PMAC64
 config PPC_PASEMI_CPUFREQ
 	bool "Support for PA Semi PWRficient"
 	depends on PPC_PASEMI
-	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the support for frequency switching on PA Semi
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index e2b6eab..6897ad8 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -31,7 +31,6 @@ config X86_PCC_CPUFREQ
 
 config X86_ACPI_CPUFREQ
 	tristate "ACPI Processor P-States driver"
-	select CPU_FREQ_TABLE
 	depends on ACPI_PROCESSOR
 	help
 	  This driver adds a CPUFreq driver which utilizes the ACPI
@@ -60,7 +59,6 @@ config X86_ACPI_CPUFREQ_CPB
 
 config ELAN_CPUFREQ
 	tristate "AMD Elan SC400 and SC410"
-	select CPU_FREQ_TABLE
 	depends on MELAN
 	---help---
 	  This adds the CPUFreq driver for AMD Elan SC400 and SC410
@@ -76,7 +74,6 @@ config ELAN_CPUFREQ
 
 config SC520_CPUFREQ
 	tristate "AMD Elan SC520"
-	select CPU_FREQ_TABLE
 	depends on MELAN
 	---help---
 	  This adds the CPUFreq driver for AMD Elan SC520 processor.
@@ -88,7 +85,6 @@ config SC520_CPUFREQ
 
 config X86_POWERNOW_K6
 	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
-	select CPU_FREQ_TABLE
 	depends on X86_32
 	help
 	  This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
@@ -100,7 +96,6 @@ config X86_POWERNOW_K6
 
 config X86_POWERNOW_K7
 	tristate "AMD Mobile Athlon/Duron PowerNow!"
-	select CPU_FREQ_TABLE
 	depends on X86_32
 	help
 	  This adds the CPUFreq driver for mobile AMD K7 mobile processors.
@@ -118,7 +113,6 @@ config X86_POWERNOW_K7_ACPI
 
 config X86_POWERNOW_K8
 	tristate "AMD Opteron/Athlon64 PowerNow!"
-	select CPU_FREQ_TABLE
 	depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ
 	help
 	  This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors.
@@ -132,7 +126,6 @@ config X86_POWERNOW_K8
 config X86_AMD_FREQ_SENSITIVITY
 	tristate "AMD frequency sensitivity feedback powersave bias"
 	depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ && CPU_SUP_AMD
-	select CPU_FREQ_TABLE
 	help
 	  This adds AMD-specific powersave bias function to the ondemand
 	  governor, which allows it to make more power-conscious frequency
@@ -160,7 +153,6 @@ config X86_GX_SUSPMOD
 
 config X86_SPEEDSTEP_CENTRINO
 	tristate "Intel Enhanced SpeedStep (deprecated)"
-	select CPU_FREQ_TABLE
 	select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32
 	depends on X86_32 || (X86_64 && ACPI_PROCESSOR)
 	help
@@ -190,7 +182,6 @@ config X86_SPEEDSTEP_CENTRINO_TABLE
 
 config X86_SPEEDSTEP_ICH
 	tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
-	select CPU_FREQ_TABLE
 	depends on X86_32
 	help
 	  This adds the CPUFreq driver for certain mobile Intel Pentium III
@@ -204,7 +195,6 @@ config X86_SPEEDSTEP_ICH
 
 config X86_SPEEDSTEP_SMI
 	tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
-	select CPU_FREQ_TABLE
 	depends on X86_32
 	help
 	  This adds the CPUFreq driver for certain mobile Intel Pentium III
@@ -217,7 +207,6 @@ config X86_SPEEDSTEP_SMI
 
 config X86_P4_CLOCKMOD
 	tristate "Intel Pentium 4 clock modulation"
-	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for Intel Pentium 4 / XEON
 	  processors.  When enabled it will lower CPU temperature by skipping
@@ -259,7 +248,6 @@ config X86_LONGRUN
 
 config X86_LONGHAUL
 	tristate "VIA Cyrix III Longhaul"
-	select CPU_FREQ_TABLE
 	depends on X86_32 && ACPI_PROCESSOR
 	help
 	  This adds the CPUFreq driver for VIA Samuel/CyrixIII,
@@ -272,7 +260,6 @@ config X86_LONGHAUL
 
 config X86_E_POWERSAVER
 	tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"
-	select CPU_FREQ_TABLE
 	depends on X86_32 && ACPI_PROCESSOR
 	help
 	  This adds the CPUFreq driver for VIA C7 processors.  However, this driver
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ad5866c..b7948bb 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -1,5 +1,5 @@
 # CPUfreq core
-obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o freq_table.o
 # CPUfreq stats
 obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
 
@@ -11,9 +11,6 @@ obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
 obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
 obj-$(CONFIG_CPU_FREQ_GOV_COMMON)		+= cpufreq_governor.o
 
-# CPUfreq cross-arch helpers
-obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
-
 obj-$(CONFIG_GENERIC_CPUFREQ_CPU0)	+= cpufreq-cpu0.o
 
 ##################################################################################
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f1b0e0f..4d37306 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1130,9 +1130,7 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
 	for_each_cpu(j, policy->cpus)
 		per_cpu(cpufreq_policy_cpu, j) = cpu;
 
-#ifdef CONFIG_CPU_FREQ_TABLE
 	cpufreq_frequency_table_update_policy_cpu(policy);
-#endif
 	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
 			CPUFREQ_UPDATE_POLICY_CPU, policy);
 }
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index e988c81..6a5b948 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -69,7 +69,6 @@ config THERMAL_GOV_USER_SPACE
 config CPU_THERMAL
 	bool "generic cpu cooling support"
 	depends on CPU_FREQ
-	select CPU_FREQ_TABLE
 	help
 	  This implements the generic cpu cooling mechanism through frequency
 	  reduction. An ACPI version of this already exists
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 03/35] cpufreq: acpi: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 02/35] cpufreq: remove CONFIG_CPU_FREQ_TABLE Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 04/35] cpufreq: arm_big_little: " Viresh Kumar
                     ` (33 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/acpi-cpufreq.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index cd5badb..f69b4c8 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -424,17 +424,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
 }
 
 static int acpi_cpufreq_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq, unsigned int relation)
+			       unsigned int index)
 {
 	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
 	struct acpi_processor_performance *perf;
 	struct cpufreq_freqs freqs;
 	struct drv_cmd cmd;
-	unsigned int next_state = 0; /* Index into freq_table */
 	unsigned int next_perf_state = 0; /* Index into perf table */
 	int result = 0;
 
-	pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
+	pr_debug("acpi_cpufreq_target %d (%d)\n",
+			data->freq_table[index].frequency, policy->cpu);
 
 	if (unlikely(data == NULL ||
 	     data->acpi_data == NULL || data->freq_table == NULL)) {
@@ -442,16 +442,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
 	}
 
 	perf = data->acpi_data;
-	result = cpufreq_frequency_table_target(policy,
-						data->freq_table,
-						target_freq,
-						relation, &next_state);
-	if (unlikely(result)) {
-		result = -ENODEV;
-		goto out;
-	}
-
-	next_perf_state = data->freq_table[next_state].driver_data;
+	next_perf_state = data->freq_table[index].driver_data;
 	if (perf->state == next_perf_state) {
 		if (unlikely(data->resume)) {
 			pr_debug("Called after resume, resetting to P%d\n",
@@ -493,7 +484,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
 		cmd.mask = cpumask_of(policy->cpu);
 
 	freqs.old = perf->states[perf->state].core_frequency * 1000;
-	freqs.new = data->freq_table[next_state].frequency;
+	freqs.new = data->freq_table[index].frequency;
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	drv_write(&cmd);
@@ -919,7 +910,7 @@ static struct freq_attr *acpi_cpufreq_attr[] = {
 
 static struct cpufreq_driver acpi_cpufreq_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= acpi_cpufreq_target,
+	.target_index	= acpi_cpufreq_target,
 	.bios_limit	= acpi_processor_get_bios_limit,
 	.init		= acpi_cpufreq_cpu_init,
 	.exit		= acpi_cpufreq_cpu_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 04/35] cpufreq: arm_big_little: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (2 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 03/35] cpufreq: acpi: Covert to light weight ->target_index() routine Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 05/35] cpufreq: at32ap: " Viresh Kumar
                     ` (32 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/arm_big_little.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 7e92586..4bba5ad 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -49,28 +49,21 @@ static unsigned int bL_cpufreq_get(unsigned int cpu)
 
 /* Set clock frequency */
 static int bL_cpufreq_set_target(struct cpufreq_policy *policy,
-		unsigned int target_freq, unsigned int relation)
+		unsigned int index)
 {
 	struct cpufreq_freqs freqs;
-	u32 cpu = policy->cpu, freq_tab_idx, cur_cluster;
+	u32 cpu = policy->cpu, cur_cluster;
 	int ret = 0;
 
 	cur_cluster = cpu_to_cluster(policy->cpu);
 
 	freqs.old = bL_cpufreq_get(policy->cpu);
-
-	/* Determine valid target frequency using freq_table */
-	cpufreq_frequency_table_target(policy, freq_table[cur_cluster],
-			target_freq, relation, &freq_tab_idx);
-	freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency;
+	freqs.new = freq_table[cur_cluster][index].frequency;
 
 	pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n",
-			__func__, cpu, cur_cluster, freqs.old, target_freq,
+			__func__, cpu, cur_cluster, freqs.old, freqs.new,
 			freqs.new);
 
-	if (freqs.old == freqs.new)
-		return 0;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000);
@@ -201,7 +194,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
 	.name			= "arm-big-little",
 	.flags			= CPUFREQ_STICKY,
 	.verify			= cpufreq_generic_frequency_table_verify,
-	.target			= bL_cpufreq_set_target,
+	.target_index		= bL_cpufreq_set_target,
 	.get			= bL_cpufreq_get,
 	.init			= bL_cpufreq_init,
 	.exit			= bL_cpufreq_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 05/35] cpufreq: at32ap: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (3 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 04/35] cpufreq: arm_big_little: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-14  8:00     ` Hans-Christian Egtvedt
  2013-08-13 13:32   ` [PATCH V2 06/35] cpufreq: blackfin: " Viresh Kumar
                     ` (31 subsequent siblings)
  36 siblings, 1 reply; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/at32ap-cpufreq.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c
index 788f7e7..2e964a7 100644
--- a/drivers/cpufreq/at32ap-cpufreq.c
+++ b/drivers/cpufreq/at32ap-cpufreq.c
@@ -35,25 +35,12 @@ static unsigned int at32_get_speed(unsigned int cpu)
 static unsigned int	ref_freq;
 static unsigned long	loops_per_jiffy_ref;
 
-static int at32_set_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
+static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct cpufreq_freqs freqs;
-	long freq;
-
-	/* Convert target_freq from kHz to Hz */
-	freq = clk_round_rate(cpuclk, target_freq * 1000);
-
-	/* Check if policy->min <= new_freq <= policy->max */
-	if(freq < (policy->min * 1000) || freq > (policy->max * 1000))
-		return -EINVAL;
-
-	pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
 
 	freqs.old = at32_get_speed(0);
-	freqs.new = (freq + 500) / 1000;
-	freqs.flags = 0;
+	freqs.new = freq_table[index].frequency;
 
 	if (!ref_freq) {
 		ref_freq = freqs.old;
@@ -64,13 +51,13 @@ static int at32_set_target(struct cpufreq_policy *policy,
 	if (freqs.old < freqs.new)
 		boot_cpu_data.loops_per_jiffy = cpufreq_scale(
 				loops_per_jiffy_ref, ref_freq, freqs.new);
-	clk_set_rate(cpuclk, freq);
+	clk_set_rate(cpuclk, freqs.new * 1000);
 	if (freqs.new < freqs.old)
 		boot_cpu_data.loops_per_jiffy = cpufreq_scale(
 				loops_per_jiffy_ref, ref_freq, freqs.new);
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
-	pr_debug("cpufreq: set frequency %lu Hz\n", freq);
+	pr_debug("cpufreq: set frequency %lu Hz\n", freqs.new * 1000);
 
 	return 0;
 }
@@ -143,7 +130,7 @@ static struct cpufreq_driver at32_driver = {
 	.name		= "at32ap",
 	.init		= at32_cpufreq_driver_init,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= at32_set_target,
+	.target_index	= at32_set_target,
 	.get		= at32_get_speed,
 	.flags		= CPUFREQ_STICKY,
 };
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 06/35] cpufreq: blackfin: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (4 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 05/35] cpufreq: at32ap: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 07/35] cpufreq: cpu0: " Viresh Kumar
                     ` (30 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Steven Miao <realmz6@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/blackfin-cpufreq.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c
index 48888cf..b343c7b 100644
--- a/drivers/cpufreq/blackfin-cpufreq.c
+++ b/drivers/cpufreq/blackfin-cpufreq.c
@@ -127,14 +127,11 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new)
 }
 #endif
 
-static int bfin_target(struct cpufreq_policy *policy,
-			unsigned int target_freq, unsigned int relation)
+static int bfin_target(struct cpufreq_policy *policy, unsigned int index)
 {
 #ifndef CONFIG_BF60x
 	unsigned int plldiv;
 #endif
-	unsigned int index;
-	unsigned long cclk_hz;
 	struct cpufreq_freqs freqs;
 	static unsigned long lpj_ref;
 	static unsigned int  lpj_ref_freq;
@@ -144,17 +141,11 @@ static int bfin_target(struct cpufreq_policy *policy,
 	cycles_t cycles;
 #endif
 
-	if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq,
-				relation, &index))
-		return -EINVAL;
-
-	cclk_hz = bfin_freq_table[index].frequency;
-
 	freqs.old = bfin_getfreq_khz(0);
-	freqs.new = cclk_hz;
+	freqs.new = bfin_freq_table[index].frequency;
 
 	pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
-			cclk_hz, target_freq, freqs.old);
+			freqs.new, freqs.new, freqs.old);
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 #ifndef CONFIG_BF60x
@@ -210,7 +201,7 @@ static int __bfin_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver bfin_driver = {
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = bfin_target,
+	.target_index = bfin_target,
 	.get = bfin_getfreq_khz,
 	.init = __bfin_cpu_init,
 	.exit = cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 07/35] cpufreq: cpu0: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (5 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 06/35] cpufreq: blackfin: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 08/35] cpufreq: cris: " Viresh Kumar
                     ` (29 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq-cpu0.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index 3d24e7b..fb07a40 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -34,24 +34,14 @@ static unsigned int cpu0_get_speed(unsigned int cpu)
 	return clk_get_rate(cpu_clk) / 1000;
 }
 
-static int cpu0_set_target(struct cpufreq_policy *policy,
-			   unsigned int target_freq, unsigned int relation)
+static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct cpufreq_freqs freqs;
 	struct opp *opp;
 	unsigned long volt = 0, volt_old = 0, tol = 0;
 	long freq_Hz, freq_exact;
-	unsigned int index;
 	int ret;
 
-	ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-					     relation, &index);
-	if (ret) {
-		pr_err("failed to match target freqency %d: %d\n",
-		       target_freq, ret);
-		return ret;
-	}
-
 	freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
 	if (freq_Hz < 0)
 		freq_Hz = freq_table[index].frequency * 1000;
@@ -59,9 +49,6 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
 	freqs.new = freq_Hz / 1000;
 	freqs.old = clk_get_rate(cpu_clk) / 1000;
 
-	if (freqs.old == freqs.new)
-		return 0;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	if (cpu_reg) {
@@ -145,7 +132,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver cpu0_cpufreq_driver = {
 	.flags = CPUFREQ_STICKY,
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = cpu0_set_target,
+	.target_index = cpu0_set_target,
 	.get = cpu0_get_speed,
 	.init = cpu0_cpufreq_init,
 	.exit = cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 08/35] cpufreq: cris: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (6 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 07/35] cpufreq: cpu0: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 09/35] cpufreq: davinci: " Viresh Kumar
                     ` (28 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Mikael Starvik <starvik@axis.com>
Cc: linux-cris-kernel at axis.com
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cris-artpec3-cpufreq.c | 18 ++----------------
 drivers/cpufreq/cris-etraxfs-cpufreq.c | 17 ++---------------
 2 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c
index d26f4e4..1488277 100644
--- a/drivers/cpufreq/cris-artpec3-cpufreq.c
+++ b/drivers/cpufreq/cris-artpec3-cpufreq.c
@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
 	return clk_ctrl.pll ? 200000 : 6000;
 }
 
-static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
-		unsigned int state)
+static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
 {
 	struct cpufreq_freqs freqs;
 	reg_clkgen_rw_clk_ctrl clk_ctrl;
@@ -52,19 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
 	local_irq_enable();
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-};
-
-static int cris_freq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, cris_freq_table,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	cris_freq_set_cpu_state(policy, newstate);
 
 	return 0;
 }
@@ -82,7 +68,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver cris_freq_driver = {
 	.get	= cris_freq_get_cpu_frequency,
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= cris_freq_target,
+	.target_index = cris_freq_target,
 	.init	= cris_freq_cpu_init,
 	.exit	= cpufreq_generic_exit,
 	.name	= "cris_freq",
diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c
index d384e63..4e3e9c7 100644
--- a/drivers/cpufreq/cris-etraxfs-cpufreq.c
+++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c
@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
 	return clk_ctrl.pll ? 200000 : 6000;
 }
 
-static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
-		unsigned int state)
+static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
 {
 	struct cpufreq_freqs freqs;
 	reg_config_rw_clk_ctrl clk_ctrl;
@@ -52,18 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
 	local_irq_enable();
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-};
-
-static int cris_freq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq, unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target
-	    (policy, cris_freq_table, target_freq, relation, &newstate))
-		return -EINVAL;
-
-	cris_freq_set_cpu_state(policy, newstate);
 
 	return 0;
 }
@@ -80,7 +67,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver cris_freq_driver = {
 	.get = cris_freq_get_cpu_frequency,
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = cris_freq_target,
+	.target_index = cris_freq_target,
 	.init = cris_freq_cpu_init,
 	.exit = cpufreq_generic_exit,
 	.name = "cris_freq",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 09/35] cpufreq: davinci: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (7 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 08/35] cpufreq: cris: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 10/35] cpufreq: dbx500: " Viresh Kumar
                     ` (27 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/davinci-cpufreq.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
index 33e9460..822100b 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -68,28 +68,18 @@ static unsigned int davinci_getspeed(unsigned int cpu)
 	return clk_get_rate(cpufreq.armclk) / 1000;
 }
 
-static int davinci_target(struct cpufreq_policy *policy,
-				unsigned int target_freq, unsigned int relation)
+static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
 {
 	int ret = 0;
-	unsigned int idx;
 	struct cpufreq_freqs freqs;
 	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
 	struct clk *armclk = cpufreq.armclk;
 
 	freqs.old = davinci_getspeed(0);
-	freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
-
-	if (freqs.old == freqs.new)
-		return ret;
+	freqs.new = pdata->freq_table[idx].frequency;
 
 	dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
 
-	ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
-						freqs.new, relation, &idx);
-	if (ret)
-		return -EINVAL;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	/* if moving to higher frequency, up the voltage beforehand */
@@ -160,7 +150,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver davinci_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= davinci_verify_speed,
-	.target		= davinci_target,
+	.target_index	= davinci_target,
 	.get		= davinci_getspeed,
 	.init		= davinci_cpu_init,
 	.exit		= cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 10/35] cpufreq: dbx500: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (8 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 09/35] cpufreq: davinci: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 11/35] cpufreq: e_powersaver: " Viresh Kumar
                     ` (26 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/dbx500-cpufreq.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
index 7e2f9c0..28deaf0 100644
--- a/drivers/cpufreq/dbx500-cpufreq.c
+++ b/drivers/cpufreq/dbx500-cpufreq.c
@@ -20,23 +20,13 @@ static struct cpufreq_frequency_table *freq_table;
 static struct clk *armss_clk;
 
 static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
-				unsigned int target_freq,
-				unsigned int relation)
+				unsigned int index)
 {
 	struct cpufreq_freqs freqs;
-	unsigned int idx;
 	int ret;
 
-	/* Lookup the next frequency */
-	if (cpufreq_frequency_table_target(policy, freq_table, target_freq,
-					relation, &idx))
-		return -EINVAL;
-
 	freqs.old = policy->cur;
-	freqs.new = freq_table[idx].frequency;
-
-	if (freqs.old == freqs.new)
-		return 0;
+	freqs.new = freq_table[index].frequency;
 
 	/* pre-change notification */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
@@ -104,7 +94,7 @@ static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver dbx500_cpufreq_driver = {
 	.flags  = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS,
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = dbx500_cpufreq_target,
+	.target_index = dbx500_cpufreq_target,
 	.get    = dbx500_cpufreq_getspeed,
 	.init   = dbx500_cpufreq_init,
 	.name   = "DBX500",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 11/35] cpufreq: e_powersaver: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (9 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 10/35] cpufreq: dbx500: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 12/35] cpufreq: elanfreq: " Viresh Kumar
                     ` (25 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/e_powersaver.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index a8cbbd0..60cd576 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -168,12 +168,9 @@ postchange:
 	return err;
 }
 
-static int eps_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq,
-			       unsigned int relation)
+static int eps_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct eps_cpu_data *centaur;
-	unsigned int newstate = 0;
 	unsigned int cpu = policy->cpu;
 	unsigned int dest_state;
 	int ret;
@@ -182,16 +179,8 @@ static int eps_target(struct cpufreq_policy *policy,
 		return -ENODEV;
 	centaur = eps_cpu[cpu];
 
-	if (unlikely(cpufreq_frequency_table_target(policy,
-			&eps_cpu[cpu]->freq_table[0],
-			target_freq,
-			relation,
-			&newstate))) {
-		return -EINVAL;
-	}
-
 	/* Make frequency transition */
-	dest_state = centaur->freq_table[newstate].driver_data & 0xffff;
+	dest_state = centaur->freq_table[index].driver_data & 0xffff;
 	ret = eps_set_state(centaur, policy, dest_state);
 	if (ret)
 		printk(KERN_ERR "eps: Timeout!\n");
@@ -419,7 +408,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver eps_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= eps_target,
+	.target_index	= eps_target,
 	.init		= eps_cpu_init,
 	.exit		= eps_cpu_exit,
 	.get		= eps_get,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 12/35] cpufreq: elanfreq: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (10 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 11/35] cpufreq: e_powersaver: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 13/35] cpufreq: exynos: " Viresh Kumar
                     ` (24 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/elanfreq.c | 34 +++-------------------------------
 1 file changed, 3 insertions(+), 31 deletions(-)

diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index fe7053c..0d133a7 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -105,20 +105,8 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
 }
 
 
-/**
- *	elanfreq_set_cpu_frequency: Change the CPU core frequency
- *	@cpu: cpu number
- *	@freq: frequency in kHz
- *
- *	This function takes a frequency value and changes the CPU frequency
- *	according to this. Note that the frequency has to be checked by
- *	elanfreq_validatespeed() for correctness!
- *
- *	There is no return value.
- */
-
-static void elanfreq_set_cpu_state(struct cpufreq_policy *policy,
-		unsigned int state)
+static int elanfreq_target(struct cpufreq_policy *policy,
+			    unsigned int state)
 {
 	struct cpufreq_freqs    freqs;
 
@@ -162,25 +150,9 @@ static void elanfreq_set_cpu_state(struct cpufreq_policy *policy,
 	local_irq_enable();
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-};
-
-
-static int elanfreq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	elanfreq_set_cpu_state(policy, newstate);
 
 	return 0;
 }
-
-
 /*
  *	Module init and exit code
  */
@@ -238,7 +210,7 @@ __setup("elanfreq=", elanfreq_setup);
 static struct cpufreq_driver elanfreq_driver = {
 	.get		= elanfreq_get_cpu_frequency,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= elanfreq_target,
+	.target_index	= elanfreq_target,
 	.init		= elanfreq_cpu_init,
 	.exit		= cpufreq_generic_exit,
 	.name		= "elanfreq",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 13/35] cpufreq: exynos: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (11 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 12/35] cpufreq: elanfreq: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 14/35] cpufreq: ia64: " Viresh Kumar
                     ` (23 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/exynos-cpufreq.c     | 21 +++------------------
 drivers/cpufreq/exynos5440-cpufreq.c | 13 +++----------
 2 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 7663a96..8735b42 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -65,9 +65,6 @@ static int exynos_cpufreq_scale(unsigned int target_freq)
 	freqs.old = policy->cur;
 	freqs.new = target_freq;
 
-	if (freqs.new == freqs.old)
-		goto out;
-
 	/*
 	 * The policy max have been changed so that we cannot get proper
 	 * old_index with cpufreq_frequency_table_target(). Thus, ignore
@@ -151,13 +148,9 @@ out:
 	return ret;
 }
 
-static int exynos_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
+static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
-	unsigned int index;
-	unsigned int new_freq;
 	int ret = 0;
 
 	mutex_lock(&cpufreq_lock);
@@ -165,15 +158,7 @@ static int exynos_target(struct cpufreq_policy *policy,
 	if (frequency_locked)
 		goto out;
 
-	if (cpufreq_frequency_table_target(policy, freq_table,
-					   target_freq, relation, &index)) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	new_freq = freq_table[index].frequency;
-
-	ret = exynos_cpufreq_scale(new_freq);
+	ret = exynos_cpufreq_scale(freq_table[index].frequency);
 
 out:
 	mutex_unlock(&cpufreq_lock);
@@ -254,7 +239,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver exynos_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= exynos_target,
+	.target_index	= exynos_target,
 	.get		= exynos_getspeed,
 	.init		= exynos_cpufreq_cpu_init,
 	.exit		= cpufreq_generic_exit,
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index f139b3b..9a5ed485 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -214,21 +214,14 @@ static unsigned int exynos_getspeed(unsigned int cpu)
 	return dvfs_info->cur_frequency;
 }
 
-static int exynos_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
+static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int index, tmp;
+	unsigned int tmp;
 	int ret = 0, i;
 	struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
 
 	mutex_lock(&cpufreq_lock);
 
-	ret = cpufreq_frequency_table_target(policy, freq_table,
-					   target_freq, relation, &index);
-	if (ret)
-		goto out;
-
 	freqs.old = dvfs_info->cur_frequency;
 	freqs.new = freq_table[index].frequency;
 
@@ -333,7 +326,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver exynos_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= exynos_target,
+	.target_index	= exynos_target,
 	.get		= exynos_getspeed,
 	.init		= exynos_cpufreq_cpu_init,
 	.exit		= cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 14/35] cpufreq: ia64: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (12 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 13/35] cpufreq: exynos: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 15/35] cpufreq: imx6q: " Viresh Kumar
                     ` (22 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Tony Luck <tony.luck@intel.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/ia64-acpi-cpufreq.c | 21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)

diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c
index b958bdb..371c63d 100644
--- a/drivers/cpufreq/ia64-acpi-cpufreq.c
+++ b/drivers/cpufreq/ia64-acpi-cpufreq.c
@@ -227,26 +227,11 @@ acpi_cpufreq_get (
 static int
 acpi_cpufreq_target (
 	struct cpufreq_policy   *policy,
-	unsigned int target_freq,
-	unsigned int relation)
+	unsigned int index)
 {
-	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
-	unsigned int next_state = 0;
-	unsigned int result = 0;
-
-	pr_debug("acpi_cpufreq_setpolicy\n");
-
-	result = cpufreq_frequency_table_target(policy,
-			data->freq_table, target_freq, relation, &next_state);
-	if (result)
-		return (result);
-
-	result = processor_set_freq(data, policy, next_state);
-
-	return (result);
+	return processor_set_freq(acpi_io_data[policy->cpu], policy, index);
 }
 
-
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -380,7 +365,7 @@ acpi_cpufreq_cpu_exit (
 
 static struct cpufreq_driver acpi_cpufreq_driver = {
 	.verify 	= cpufreq_generic_frequency_table_verify,
-	.target 	= acpi_cpufreq_target,
+	.target_index	= acpi_cpufreq_target,
 	.get 		= acpi_cpufreq_get,
 	.init		= acpi_cpufreq_cpu_init,
 	.exit		= acpi_cpufreq_cpu_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 15/35] cpufreq: imx6q: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (13 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 14/35] cpufreq: ia64: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 16/35] cpufreq: kirkwood: " Viresh Kumar
                     ` (21 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/imx6q-cpufreq.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 81d1727..f6f877c 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -39,30 +39,17 @@ static unsigned int imx6q_get_speed(unsigned int cpu)
 	return clk_get_rate(arm_clk) / 1000;
 }
 
-static int imx6q_set_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq, unsigned int relation)
+static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct cpufreq_freqs freqs;
 	struct opp *opp;
 	unsigned long freq_hz, volt, volt_old;
-	unsigned int index;
 	int ret;
 
-	ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-					     relation, &index);
-	if (ret) {
-		dev_err(cpu_dev, "failed to match target frequency %d: %d\n",
-			target_freq, ret);
-		return ret;
-	}
-
 	freqs.new = freq_table[index].frequency;
 	freq_hz = freqs.new * 1000;
 	freqs.old = clk_get_rate(arm_clk) / 1000;
 
-	if (freqs.old == freqs.new)
-		return 0;
-
 	rcu_read_lock();
 	opp = opp_find_freq_ceil(cpu_dev, &freq_hz);
 	if (IS_ERR(opp)) {
@@ -187,7 +174,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver imx6q_cpufreq_driver = {
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = imx6q_set_target,
+	.target_index = imx6q_set_target,
 	.get = imx6q_get_speed,
 	.init = imx6q_cpufreq_init,
 	.exit = cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 16/35] cpufreq: kirkwood: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (14 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 15/35] cpufreq: imx6q: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 17/35] cpufreq: longhaul: " Viresh Kumar
                     ` (20 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/kirkwood-cpufreq.c | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index 9018c4d..d0d107a 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -55,8 +55,8 @@ static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
 	return kirkwood_freq_table[0].frequency;
 }
 
-static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy,
-		unsigned int index)
+static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
+			    unsigned int index)
 {
 	struct cpufreq_freqs freqs;
 	unsigned int state = kirkwood_freq_table[index].driver_data;
@@ -100,19 +100,6 @@ static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy,
 		local_irq_enable();
 	}
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-};
-
-static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int index = 0;
-
-	if (cpufreq_frequency_table_target(policy, kirkwood_freq_table,
-				target_freq, relation, &index))
-		return -EINVAL;
-
-	kirkwood_cpufreq_set_cpu_state(policy, index);
 
 	return 0;
 }
@@ -130,7 +117,7 @@ static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver kirkwood_cpufreq_driver = {
 	.get	= kirkwood_cpufreq_get_cpu_frequency,
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= kirkwood_cpufreq_target,
+	.target_index = kirkwood_cpufreq_target,
 	.init	= kirkwood_cpufreq_cpu_init,
 	.exit	= cpufreq_generic_exit,
 	.name	= "kirkwood-cpufreq",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 17/35] cpufreq: longhaul: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (15 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 16/35] cpufreq: kirkwood: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 18/35] cpufreq: loongson2: " Viresh Kumar
                     ` (19 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/longhaul.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 57d7b02..e566776 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -626,21 +626,12 @@ static void longhaul_setup_voltagescaling(void)
 
 
 static int longhaul_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq, unsigned int relation)
+			    unsigned int table_index)
 {
-	unsigned int table_index = 0;
 	unsigned int i;
 	unsigned int dir = 0;
 	u8 vid, current_vid;
 
-	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
-				relation, &table_index))
-		return -EINVAL;
-
-	/* Don't set same frequency again */
-	if (longhaul_index == table_index)
-		return 0;
-
 	if (!can_scale_voltage)
 		longhaul_setstate(policy, table_index);
 	else {
@@ -920,7 +911,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver longhaul_driver = {
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= longhaul_target,
+	.target_index = longhaul_target,
 	.get	= longhaul_get,
 	.init	= longhaul_cpu_init,
 	.exit	= cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 18/35] cpufreq: loongson2: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (16 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 17/35] cpufreq: longhaul: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 19/35] cpufreq: maple: " Viresh Kumar
                     ` (18 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: John Crispin <blogic@openwrt.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/loongson2_cpufreq.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
index ed7fbe2..009c29c 100644
--- a/drivers/cpufreq/loongson2_cpufreq.c
+++ b/drivers/cpufreq/loongson2_cpufreq.c
@@ -53,11 +53,9 @@ static unsigned int loongson2_cpufreq_get(unsigned int cpu)
  * Here we notify other drivers of the proposed change and the final change.
  */
 static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
-				     unsigned int target_freq,
-				     unsigned int relation)
+				     unsigned int index)
 {
 	unsigned int cpu = policy->cpu;
-	unsigned int newstate = 0;
 	cpumask_t cpus_allowed;
 	struct cpufreq_freqs freqs;
 	unsigned int freq;
@@ -65,26 +63,17 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
-	if (cpufreq_frequency_table_target
-	    (policy, &loongson2_clockmod_table[0], target_freq, relation,
-	     &newstate))
-		return -EINVAL;
-
 	freq =
 	    ((cpu_clock_freq / 1000) *
-	     loongson2_clockmod_table[newstate].driver_data) / 8;
-	if (freq < policy->min || freq > policy->max)
-		return -EINVAL;
+	     loongson2_clockmod_table[index].driver_data) / 8;
 
-	pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
+	pr_debug("cpufreq: requested frequency %u Hz\n",
+			loongson2_clockmod_table[index].frequency * 1000);
 
 	freqs.old = loongson2_cpufreq_get(cpu);
 	freqs.new = freq;
 	freqs.flags = 0;
 
-	if (freqs.new == freqs.old)
-		return 0;
-
 	/* notifiers */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
@@ -148,7 +137,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = {
 	.name = "loongson2",
 	.init = loongson2_cpufreq_cpu_init,
 	.verify = cpufreq_generic_frequency_table_verify,
-	.target = loongson2_cpufreq_target,
+	.target_index = loongson2_cpufreq_target,
 	.get = loongson2_cpufreq_get,
 	.exit = loongson2_cpufreq_exit,
 	.attr = cpufreq_generic_attr,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 19/35] cpufreq: maple: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (17 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 18/35] cpufreq: loongson2: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 20/35] cpufreq: omap: " Viresh Kumar
                     ` (17 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/maple-cpufreq.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c
index 7720670..1c24219 100644
--- a/drivers/cpufreq/maple-cpufreq.c
+++ b/drivers/cpufreq/maple-cpufreq.c
@@ -131,26 +131,18 @@ static int maple_scom_query_freq(void)
  */
 
 static int maple_cpufreq_target(struct cpufreq_policy *policy,
-	unsigned int target_freq, unsigned int relation)
+	unsigned int index)
 {
-	unsigned int newstate = 0;
 	struct cpufreq_freqs freqs;
 	int rc;
 
-	if (cpufreq_frequency_table_target(policy, maple_cpu_freqs,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	if (maple_pmode_cur == newstate)
-		return 0;
-
 	mutex_lock(&maple_switch_mutex);
 
 	freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency;
-	freqs.new = maple_cpu_freqs[newstate].frequency;
+	freqs.new = maple_cpu_freqs[index].frequency;
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-	rc = maple_scom_switch_freq(newstate);
+	rc = maple_scom_switch_freq(index);
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	mutex_unlock(&maple_switch_mutex);
@@ -181,7 +173,7 @@ static struct cpufreq_driver maple_cpufreq_driver = {
 	.flags		= CPUFREQ_CONST_LOOPS,
 	.init		= maple_cpufreq_cpu_init,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= maple_cpufreq_target,
+	.target_index	= maple_cpufreq_target,
 	.get		= maple_cpufreq_get_speed,
 	.attr		= cpufreq_generic_attr,
 };
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 20/35] cpufreq: omap: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (18 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 19/35] cpufreq: maple: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 21/35] cpufreq: p4: " Viresh Kumar
                     ` (16 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/omap-cpufreq.c | 31 +++----------------------------
 1 file changed, 3 insertions(+), 28 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 48020b5..69bf7d8 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -51,40 +51,15 @@ static unsigned int omap_getspeed(unsigned int cpu)
 	return rate;
 }
 
-static int omap_target(struct cpufreq_policy *policy,
-		       unsigned int target_freq,
-		       unsigned int relation)
+static int omap_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int i;
 	int r, ret = 0;
 	struct cpufreq_freqs freqs;
 	struct opp *opp;
 	unsigned long freq, volt = 0, volt_old = 0, tol = 0;
 
-	if (!freq_table) {
-		dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
-				policy->cpu);
-		return -EINVAL;
-	}
-
-	ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-			relation, &i);
-	if (ret) {
-		dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
-			__func__, policy->cpu, target_freq, ret);
-		return ret;
-	}
-	freqs.new = freq_table[i].frequency;
-	if (!freqs.new) {
-		dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
-			policy->cpu, target_freq);
-		return -EINVAL;
-	}
-
 	freqs.old = omap_getspeed(policy->cpu);
-
-	if (freqs.old == freqs.new && policy->cur == freqs.new)
-		return ret;
+	freqs.new = freq_table[index].frequency;
 
 	freq = freqs.new * 1000;
 	ret = clk_round_rate(mpu_clk, freq);
@@ -223,7 +198,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
 static struct cpufreq_driver omap_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= omap_target,
+	.target_index	= omap_target,
 	.get		= omap_getspeed,
 	.init		= omap_cpu_init,
 	.exit		= omap_cpu_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 21/35] cpufreq: p4: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (19 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 20/35] cpufreq: omap: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 22/35] cpufreq: pasemi: " Viresh Kumar
                     ` (15 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/p4-clockmod.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
index 4fe6d4c..5a6263e 100644
--- a/drivers/cpufreq/p4-clockmod.c
+++ b/drivers/cpufreq/p4-clockmod.c
@@ -105,23 +105,13 @@ static struct cpufreq_frequency_table p4clockmod_table[] = {
 };
 
 
-static int cpufreq_p4_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
+static int cpufreq_p4_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int    newstate = DC_RESV;
 	struct cpufreq_freqs freqs;
 	int i;
 
-	if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
 	freqs.old = cpufreq_p4_get(policy->cpu);
-	freqs.new = stock_freq * p4clockmod_table[newstate].driver_data / 8;
-
-	if (freqs.new == freqs.old)
-		return 0;
+	freqs.new = stock_freq * p4clockmod_table[index].driver_data / 8;
 
 	/* notifiers */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
@@ -131,7 +121,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
 	 * Developer's Manual, Volume 3
 	 */
 	for_each_cpu(i, policy->cpus)
-		cpufreq_p4_setdc(i, p4clockmod_table[newstate].driver_data);
+		cpufreq_p4_setdc(i, p4clockmod_table[index].driver_data);
 
 	/* notifiers */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
@@ -256,7 +246,7 @@ static unsigned int cpufreq_p4_get(unsigned int cpu)
 
 static struct cpufreq_driver p4clockmod_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= cpufreq_p4_target,
+	.target_index	= cpufreq_p4_target,
 	.init		= cpufreq_p4_cpu_init,
 	.exit		= cpufreq_generic_exit,
 	.get		= cpufreq_p4_get,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 22/35] cpufreq: pasemi: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (20 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 21/35] cpufreq: p4: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 23/35] cpufreq: pmac32: " Viresh Kumar
                     ` (14 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/pasemi-cpufreq.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
index 16f2508..aaee5fa 100644
--- a/drivers/cpufreq/pasemi-cpufreq.c
+++ b/drivers/cpufreq/pasemi-cpufreq.c
@@ -247,19 +247,11 @@ static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 }
 
 static int pas_cpufreq_target(struct cpufreq_policy *policy,
-			      unsigned int target_freq,
-			      unsigned int relation)
+			      unsigned int pas_astate_new)
 {
 	struct cpufreq_freqs freqs;
-	int pas_astate_new;
 	int i;
 
-	cpufreq_frequency_table_target(policy,
-				       pas_freqs,
-				       target_freq,
-				       relation,
-				       &pas_astate_new);
-
 	freqs.old = policy->cur;
 	freqs.new = pas_freqs[pas_astate_new].frequency;
 
@@ -289,7 +281,7 @@ static struct cpufreq_driver pas_cpufreq_driver = {
 	.init		= pas_cpufreq_cpu_init,
 	.exit		= pas_cpufreq_cpu_exit,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= pas_cpufreq_target,
+	.target_index	= pas_cpufreq_target,
 	.attr		= cpufreq_generic_attr,
 };
 
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 23/35] cpufreq: pmac32: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (21 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 22/35] cpufreq: pasemi: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 24/35] cpufreq: powernow: " Viresh Kumar
                     ` (13 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/pmac32-cpufreq.c | 12 +++---------
 drivers/cpufreq/pmac64-cpufreq.c | 17 ++++-------------
 2 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 3f8efd2..b1ba708 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -373,17 +373,11 @@ static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
 }
 
 static int pmac_cpufreq_target(	struct cpufreq_policy *policy,
-					unsigned int target_freq,
-					unsigned int relation)
+					unsigned int index)
 {
-	unsigned int    newstate = 0;
 	int		rc;
 
-	if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	rc = do_set_cpu_speed(policy, newstate, 1);
+	rc = do_set_cpu_speed(policy, index, 1);
 
 	ppc_proc_freq = cur_freq * 1000ul;
 	return rc;
@@ -458,7 +452,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver pmac_cpufreq_driver = {
 	.verify 	= cpufreq_generic_frequency_table_verify,
-	.target 	= pmac_cpufreq_target,
+	.target_index 	= pmac_cpufreq_target,
 	.get		= pmac_cpufreq_get_speed,
 	.init		= pmac_cpufreq_cpu_init,
 	.suspend	= pmac_cpufreq_suspend,
diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 0eb9313..7679990 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -311,27 +311,18 @@ static int g5_pfunc_query_freq(void)
  * Common interface to the cpufreq core
  */
 
-static int g5_cpufreq_target(struct cpufreq_policy *policy,
-	unsigned int target_freq, unsigned int relation)
+static int g5_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int newstate = 0;
 	struct cpufreq_freqs freqs;
 	int rc;
 
-	if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	if (g5_pmode_cur == newstate)
-		return 0;
-
 	mutex_lock(&g5_switch_mutex);
 
 	freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
-	freqs.new = g5_cpu_freqs[newstate].frequency;
+	freqs.new = g5_cpu_freqs[index].frequency;
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-	rc = g5_switch_freq(newstate);
+	rc = g5_switch_freq(index);
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	mutex_unlock(&g5_switch_mutex);
@@ -362,7 +353,7 @@ static struct cpufreq_driver g5_cpufreq_driver = {
 	.flags		= CPUFREQ_CONST_LOOPS,
 	.init		= g5_cpufreq_cpu_init,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= g5_cpufreq_target,
+	.target_index	= g5_cpufreq_target,
 	.get		= g5_cpufreq_get_speed,
 	.attr 		= cpufreq_generic_attr,
 };
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 24/35] cpufreq: powernow: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (22 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 23/35] cpufreq: pmac32: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 25/35] cpufreq: ppc: " Viresh Kumar
                     ` (12 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/powernow-k6.c | 35 +++++------------------------------
 drivers/cpufreq/powernow-k7.c | 22 ++++------------------
 drivers/cpufreq/powernow-k8.c | 24 ++++++++----------------
 3 files changed, 17 insertions(+), 64 deletions(-)

diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index ff05d28..cb19fb8 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -63,12 +63,12 @@ static int powernow_k6_get_cpu_multiplier(void)
 
 
 /**
- * powernow_k6_set_state - set the PowerNow! multiplier
+ * powernow_k6_target - set the PowerNow! multiplier
  * @best_i: clock_ratio[best_i] is the target multiplier
  *
  *   Tries to change the PowerNow! multiplier
  */
-static void powernow_k6_set_state(struct cpufreq_policy *policy,
+static int powernow_k6_target(struct cpufreq_policy *policy,
 		unsigned int best_i)
 {
 	unsigned long outvalue = 0, invalue = 0;
@@ -77,7 +77,7 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy,
 
 	if (clock_ratio[best_i].driver_data > max_multiplier) {
 		printk(KERN_ERR PFX "invalid target frequency\n");
-		return;
+		return -EINVAL;
 	}
 
 	freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
@@ -100,31 +100,6 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy,
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
-	return;
-}
-
-
-/**
- * powernow_k6_setpolicy - sets a new CPUFreq policy
- * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
- *
- * sets a new CPUFreq policy
- */
-static int powernow_k6_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq,
-			       unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	powernow_k6_set_state(policy, newstate);
-
 	return 0;
 }
 
@@ -162,7 +137,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
 	unsigned int i;
 	for (i = 0; i < 8; i++) {
 		if (i == max_multiplier)
-			powernow_k6_set_state(policy, i);
+			powernow_k6_target(policy, i);
 	}
 	cpufreq_frequency_table_put_attr(policy->cpu);
 	return 0;
@@ -177,7 +152,7 @@ static unsigned int powernow_k6_get(unsigned int cpu)
 
 static struct cpufreq_driver powernow_k6_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= powernow_k6_target,
+	.target_index	= powernow_k6_target,
 	.init		= powernow_k6_cpu_init,
 	.exit		= powernow_k6_cpu_exit,
 	.get		= powernow_k6_get,
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index 14cd98f..7c76f03 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -248,7 +248,7 @@ static void change_VID(int vid)
 }
 
 
-static void change_speed(struct cpufreq_policy *policy, unsigned int index)
+static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	u8 fid, vid;
 	struct cpufreq_freqs freqs;
@@ -291,6 +291,8 @@ static void change_speed(struct cpufreq_policy *policy, unsigned int index)
 		local_irq_enable();
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
 }
 
 
@@ -533,22 +535,6 @@ static int powernow_decode_bios(int maxfid, int startvid)
 }
 
 
-static int powernow_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate;
-
-	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
-				relation, &newstate))
-		return -EINVAL;
-
-	change_speed(policy, newstate);
-
-	return 0;
-}
-
-
 /*
  * We use the fact that the bus frequency is somehow
  * a multiple of 100000/3 khz, then we compute sgtc according
@@ -696,7 +682,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver powernow_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= powernow_target,
+	.target_index	= powernow_target,
 	.get		= powernow_get,
 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 	.bios_limit	= acpi_processor_get_bios_limit,
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 1e6f68a..80bc606 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -977,20 +977,17 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
 
 struct powernowk8_target_arg {
 	struct cpufreq_policy		*pol;
-	unsigned			targfreq;
-	unsigned			relation;
+	unsigned			newstate;
 };
 
 static long powernowk8_target_fn(void *arg)
 {
 	struct powernowk8_target_arg *pta = arg;
 	struct cpufreq_policy *pol = pta->pol;
-	unsigned targfreq = pta->targfreq;
-	unsigned relation = pta->relation;
+	unsigned newstate = pta->newstate;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	u32 checkfid;
 	u32 checkvid;
-	unsigned int newstate;
 	int ret;
 
 	if (!data)
@@ -1004,8 +1001,9 @@ static long powernowk8_target_fn(void *arg)
 		return -EIO;
 	}
 
-	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
-		pol->cpu, targfreq, pol->min, pol->max, relation);
+	pr_debug("targ: cpu %d, %d kHz, min %d, max %d\n",
+		pol->cpu, data->powernow_table[newstate].frequency, pol->min,
+		pol->max);
 
 	if (query_current_values_with_pending_wait(data))
 		return -EIO;
@@ -1021,10 +1019,6 @@ static long powernowk8_target_fn(void *arg)
 		       checkvid, data->currvid);
 	}
 
-	if (cpufreq_frequency_table_target(pol, data->powernow_table,
-				targfreq, relation, &newstate))
-		return -EIO;
-
 	mutex_lock(&fidvid_mutex);
 
 	powernow_k8_acpi_pst_values(data, newstate);
@@ -1044,11 +1038,9 @@ static long powernowk8_target_fn(void *arg)
 }
 
 /* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
-		unsigned targfreq, unsigned relation)
+static int powernowk8_target(struct cpufreq_policy *pol, unsigned index)
 {
-	struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
-					     .relation = relation };
+	struct powernowk8_target_arg pta = { .pol = pol, .newstate = index };
 
 	return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
 }
@@ -1216,7 +1208,7 @@ out:
 
 static struct cpufreq_driver cpufreq_amd64_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= powernowk8_target,
+	.target_index	= powernowk8_target,
 	.bios_limit	= acpi_processor_get_bios_limit,
 	.init		= powernowk8_cpu_init,
 	.exit		= powernowk8_cpu_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 25/35] cpufreq: ppc: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (23 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 24/35] cpufreq: powernow: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 26/35] cpufreq: pxa: " Viresh Kumar
                     ` (11 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/ppc-corenet-cpufreq.c | 15 ++++-----------
 drivers/cpufreq/ppc_cbe_cpufreq.c     | 12 ++----------
 2 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
index befd489..243a396 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -253,27 +253,20 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 }
 
 static int corenet_cpufreq_target(struct cpufreq_policy *policy,
-		unsigned int target_freq, unsigned int relation)
+		unsigned int index)
 {
 	struct cpufreq_freqs freqs;
-	unsigned int new;
 	struct clk *parent;
 	int ret;
 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
 
-	cpufreq_frequency_table_target(policy, data->table,
-			target_freq, relation, &new);
-
-	if (policy->cur == data->table[new].frequency)
-		return 0;
-
 	freqs.old = policy->cur;
-	freqs.new = data->table[new].frequency;
+	freqs.new = data->table[index].frequency;
 
 	mutex_lock(&cpufreq_lock);
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
-	parent = of_clk_get(data->parent, data->table[new].driver_data);
+	parent = of_clk_get(data->parent, data->table[index].driver_data);
 	ret = clk_set_parent(data->clk, parent);
 	if (ret)
 		freqs.new = freqs.old;
@@ -290,7 +283,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
 	.init		= corenet_cpufreq_cpu_init,
 	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= corenet_cpufreq_target,
+	.target_index	= corenet_cpufreq_target,
 	.get		= corenet_cpufreq_get_speed,
 	.attr		= cpufreq_generic_attr,
 };
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
index 38540d1..52f707d 100644
--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
@@ -129,18 +129,10 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
 }
 
 static int cbe_cpufreq_target(struct cpufreq_policy *policy,
-			      unsigned int target_freq,
-			      unsigned int relation)
+			      unsigned int cbe_pmode_new)
 {
 	int rc;
 	struct cpufreq_freqs freqs;
-	unsigned int cbe_pmode_new;
-
-	cpufreq_frequency_table_target(policy,
-				       cbe_freqs,
-				       target_freq,
-				       relation,
-				       &cbe_pmode_new);
 
 	freqs.old = policy->cur;
 	freqs.new = cbe_freqs[cbe_pmode_new].frequency;
@@ -164,7 +156,7 @@ static int cbe_cpufreq_target(struct cpufreq_policy *policy,
 
 static struct cpufreq_driver cbe_cpufreq_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= cbe_cpufreq_target,
+	.target_index	= cbe_cpufreq_target,
 	.init		= cbe_cpufreq_cpu_init,
 	.exit		= cpufreq_generic_exit,
 	.name		= "cbe-cpufreq",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 26/35] cpufreq: pxa: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (24 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 25/35] cpufreq: ppc: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 27/35] cpufreq: s3c2416: " Viresh Kumar
                     ` (10 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Eric Miao <eric.y.miao@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/pxa2xx-cpufreq.c | 13 ++-----------
 drivers/cpufreq/pxa3xx-cpufreq.c | 17 +++--------------
 2 files changed, 5 insertions(+), 25 deletions(-)

diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c
index 5a72bf3..17326e1 100644
--- a/drivers/cpufreq/pxa2xx-cpufreq.c
+++ b/drivers/cpufreq/pxa2xx-cpufreq.c
@@ -267,14 +267,11 @@ static unsigned int pxa_cpufreq_get(unsigned int cpu)
 	return get_clk_frequency_khz(0);
 }
 
-static int pxa_set_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
+static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx)
 {
 	struct cpufreq_frequency_table *pxa_freqs_table;
 	pxa_freqs_t *pxa_freq_settings;
 	struct cpufreq_freqs freqs;
-	unsigned int idx;
 	unsigned long flags;
 	unsigned int new_freq_cpu, new_freq_mem;
 	unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
@@ -283,12 +280,6 @@ static int pxa_set_target(struct cpufreq_policy *policy,
 	/* Get the current policy */
 	find_freq_tables(&pxa_freqs_table, &pxa_freq_settings);
 
-	/* Lookup the next frequency */
-	if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
-					   target_freq, relation, &idx)) {
-		return -EINVAL;
-	}
-
 	new_freq_cpu = pxa_freq_settings[idx].khz;
 	new_freq_mem = pxa_freq_settings[idx].membus;
 	freqs.old = policy->cur;
@@ -450,7 +441,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver pxa_cpufreq_driver = {
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= pxa_set_target,
+	.target_index = pxa_set_target,
 	.init	= pxa_cpufreq_init,
 	.exit	= cpufreq_generic_exit,
 	.get	= pxa_cpufreq_get,
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c
index 2837fd6..66e8cd0 100644
--- a/drivers/cpufreq/pxa3xx-cpufreq.c
+++ b/drivers/cpufreq/pxa3xx-cpufreq.c
@@ -155,24 +155,16 @@ static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
 	return pxa3xx_get_clk_frequency_khz(0);
 }
 
-static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
-			      unsigned int target_freq,
-			      unsigned int relation)
+static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct pxa3xx_freq_info *next;
 	struct cpufreq_freqs freqs;
 	unsigned long flags;
-	int idx;
 
 	if (policy->cpu != 0)
 		return -EINVAL;
 
-	/* Lookup the next frequency */
-	if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table,
-				target_freq, relation, &idx))
-		return -EINVAL;
-
-	next = &pxa3xx_freqs[idx];
+	next = &pxa3xx_freqs[index];
 
 	freqs.old = policy->cur;
 	freqs.new = next->cpufreq_mhz * 1000;
@@ -181,9 +173,6 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
 			freqs.old / 1000, freqs.new / 1000,
 			(freqs.old == freqs.new) ? " (skipped)" : "");
 
-	if (freqs.old == target_freq)
-		return 0;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	local_irq_save(flags);
@@ -224,7 +213,7 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver pxa3xx_cpufreq_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= pxa3xx_cpufreq_set,
+	.target_index	= pxa3xx_cpufreq_set,
 	.init		= pxa3xx_cpufreq_init,
 	.exit		= cpufreq_generic_exit,
 	.get		= pxa3xx_cpufreq_get,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 27/35] cpufreq: s3c2416: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (25 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 26/35] cpufreq: pxa: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 28/35] cpufreq: s3c64xx: " Viresh Kumar
                     ` (9 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/s3c2416-cpufreq.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
index 8c57f10..90efbf5 100644
--- a/drivers/cpufreq/s3c2416-cpufreq.c
+++ b/drivers/cpufreq/s3c2416-cpufreq.c
@@ -217,24 +217,15 @@ static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx)
 }
 
 static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
-				      unsigned int target_freq,
-				      unsigned int relation)
+				      unsigned int index)
 {
 	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
 	struct cpufreq_freqs freqs;
 	int idx, ret, to_dvs = 0;
-	unsigned int i;
 
 	mutex_lock(&cpufreq_lock);
 
-	pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation);
-
-	ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table,
-					     target_freq, relation, &i);
-	if (ret != 0)
-		goto out;
-
-	idx = s3c_freq->freq_table[i].driver_data;
+	idx = s3c_freq->freq_table[index].driver_data;
 
 	if (idx == SOURCE_HCLK)
 		to_dvs = 1;
@@ -256,7 +247,7 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
 	 */
 	freqs.new = (s3c_freq->is_dvs && !to_dvs)
 				? clk_get_rate(s3c_freq->hclk) / 1000
-				: s3c_freq->freq_table[i].frequency;
+				: s3c_freq->freq_table[index].frequency;
 
 	pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
 
@@ -509,7 +500,7 @@ err_hclk:
 static struct cpufreq_driver s3c2416_cpufreq_driver = {
 	.flags          = 0,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= s3c2416_cpufreq_set_target,
+	.target_index	= s3c2416_cpufreq_set_target,
 	.get		= s3c2416_cpufreq_get_speed,
 	.init		= s3c2416_cpufreq_driver_init,
 	.name		= "s3c2416",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 28/35] cpufreq: s3c64xx: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (26 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 27/35] cpufreq: s3c2416: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 29/35] cpufreq: s5pv210: " Viresh Kumar
                     ` (8 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/s3c64xx-cpufreq.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 99fbc49..72f733b 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -63,26 +63,16 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
 }
 
 static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
-				      unsigned int target_freq,
-				      unsigned int relation)
+				      unsigned int index)
 {
 	int ret;
-	unsigned int i;
 	struct cpufreq_freqs freqs;
 	struct s3c64xx_dvfs *dvfs;
 
-	ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
-					     target_freq, relation, &i);
-	if (ret != 0)
-		return ret;
-
 	freqs.old = clk_get_rate(armclk) / 1000;
-	freqs.new = s3c64xx_freq_table[i].frequency;
+	freqs.new = s3c64xx_freq_table[index].frequency;
 	freqs.flags = 0;
-	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data];
-
-	if (freqs.old == freqs.new)
-		return 0;
+	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
 
 	pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new);
 
@@ -257,7 +247,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver s3c64xx_cpufreq_driver = {
 	.flags          = 0,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= s3c64xx_cpufreq_set_target,
+	.target_index	= s3c64xx_cpufreq_set_target,
 	.get		= s3c64xx_cpufreq_get_speed,
 	.init		= s3c64xx_cpufreq_driver_init,
 	.name		= "s3c",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 29/35] cpufreq: s5pv210: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (27 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 28/35] cpufreq: s3c64xx: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 30/35] cpufreq: sa11x0: " Viresh Kumar
                     ` (7 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

This drivers wasn't as straight forward as other ones. It was doing some funny
stuff to disable driver while going into suspend mode. This part is simplified
as well to get this converted to ->target_index().

Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/s5pv210-cpufreq.c | 54 ++++++++++-----------------------------
 1 file changed, 14 insertions(+), 40 deletions(-)

diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index 0eafc52..bdffc3d 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -36,16 +36,7 @@ static DEFINE_MUTEX(set_freq_lock);
 /* Use 800MHz when entering sleep mode */
 #define SLEEP_FREQ	(800 * 1000)
 
-/*
- * relation has an additional symantics other than the standard of cpufreq
- * DISALBE_FURTHER_CPUFREQ: disable further access to target
- * ENABLE_FURTUER_CPUFREQ: enable access to target
- */
-enum cpufreq_access {
-	DISABLE_FURTHER_CPUFREQ = 0x10,
-	ENABLE_FURTHER_CPUFREQ = 0x20,
-};
-
+/* Tracks if cpu freqency can be updated anymore */
 static bool no_cpufreq_access;
 
 /*
@@ -182,12 +173,10 @@ static unsigned int s5pv210_getspeed(unsigned int cpu)
 	return clk_get_rate(cpu_clk) / 1000;
 }
 
-static int s5pv210_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
+static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	unsigned long reg;
-	unsigned int index, priv_index;
+	unsigned int priv_index;
 	unsigned int pll_changing = 0;
 	unsigned int bus_speed_changing = 0;
 	int arm_volt, int_volt;
@@ -195,9 +184,6 @@ static int s5pv210_target(struct cpufreq_policy *policy,
 
 	mutex_lock(&set_freq_lock);
 
-	if (relation & ENABLE_FURTHER_CPUFREQ)
-		no_cpufreq_access = false;
-
 	if (no_cpufreq_access) {
 #ifdef CONFIG_PM_VERBOSE
 		pr_err("%s:%d denied access to %s as it is disabled"
@@ -207,27 +193,13 @@ static int s5pv210_target(struct cpufreq_policy *policy,
 		goto exit;
 	}
 
-	if (relation & DISABLE_FURTHER_CPUFREQ)
-		no_cpufreq_access = true;
-
-	relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ);
-
 	freqs.old = s5pv210_getspeed(0);
-
-	if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
-					   target_freq, relation, &index)) {
-		ret = -EINVAL;
-		goto exit;
-	}
-
 	freqs.new = s5pv210_freq_table[index].frequency;
 
-	if (freqs.new == freqs.old)
-		goto exit;
-
 	/* Finding current running level index */
 	if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
-					   freqs.old, relation, &priv_index)) {
+					   freqs.old, CPUFREQ_RELATION_H,
+					   &priv_index)) {
 		ret = -EINVAL;
 		goto exit;
 	}
@@ -563,16 +535,18 @@ static int s5pv210_cpufreq_notifier_event(struct notifier_block *this,
 
 	switch (event) {
 	case PM_SUSPEND_PREPARE:
-		ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
-					    DISABLE_FURTHER_CPUFREQ);
+		ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
 		if (ret < 0)
 			return NOTIFY_BAD;
 
+		/* Disable updation of cpu frequency */
+		no_cpufreq_access = true;
 		return NOTIFY_OK;
 	case PM_POST_RESTORE:
 	case PM_POST_SUSPEND:
-		cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
-				      ENABLE_FURTHER_CPUFREQ);
+		/* Enable updation of cpu frequency */
+		no_cpufreq_access = false;
+		cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
 
 		return NOTIFY_OK;
 	}
@@ -585,18 +559,18 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
 {
 	int ret;
 
-	ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
-				    DISABLE_FURTHER_CPUFREQ);
+	ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
 	if (ret < 0)
 		return NOTIFY_BAD;
 
+	no_cpufreq_access = true;
 	return NOTIFY_DONE;
 }
 
 static struct cpufreq_driver s5pv210_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= s5pv210_target,
+	.target_index	= s5pv210_target,
 	.get		= s5pv210_getspeed,
 	.init		= s5pv210_cpu_init,
 	.name		= "s5pv210",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 30/35] cpufreq: sa11x0: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (28 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 29/35] cpufreq: s5pv210: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 31/35] cpufreq: sc520: " Viresh Kumar
                     ` (6 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Some existing routines are no more required and so are removed now.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 arch/arm/mach-sa1100/generic.c   | 20 --------------------
 arch/arm/mach-sa1100/generic.h   |  2 --
 drivers/cpufreq/sa1100-cpufreq.c | 24 ++++--------------------
 drivers/cpufreq/sa1110-cpufreq.c | 26 ++++----------------------
 4 files changed, 8 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index cb4b2ca..d4ea142 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -62,26 +62,6 @@ struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
 	{ .frequency = CPUFREQ_TABLE_END, },
 };
 
-/* rounds up(!)  */
-unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
-{
-	int i;
-
-	for (i = 0; i < NR_FREQS; i++)
-		if (sa11x0_freq_table[i].frequency >= khz)
-			break;
-
-	return i;
-}
-
-unsigned int sa11x0_ppcr_to_freq(unsigned int idx)
-{
-	unsigned int freq = 0;
-	if (idx < NR_FREQS)
-		freq = sa11x0_freq_table[idx].frequency;
-	return freq;
-}
-
 unsigned int sa11x0_getspeed(unsigned int cpu)
 {
 	if (cpu)
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 39d56a67..84505d5 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -22,9 +22,7 @@ extern void sa1110_mb_disable(void);
 struct cpufreq_policy;
 
 extern struct cpufreq_frequency_table sa11x0_freq_table[];
-extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
 extern unsigned int sa11x0_getspeed(unsigned int cpu);
-extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
 
 struct flash_platform_data;
 struct resource;
diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c
index 02fe8b2..7e42bce 100644
--- a/drivers/cpufreq/sa1100-cpufreq.c
+++ b/drivers/cpufreq/sa1100-cpufreq.c
@@ -177,36 +177,20 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
 	}
 }
 
-static int sa1100_target(struct cpufreq_policy *policy,
-			 unsigned int target_freq,
-			 unsigned int relation)
+static int sa1100_target(struct cpufreq_policy *policy, unsigned int ppcr)
 {
 	unsigned int cur = sa11x0_getspeed(0);
-	unsigned int new_ppcr;
 	struct cpufreq_freqs freqs;
 
-	new_ppcr = sa11x0_freq_to_ppcr(target_freq);
-	switch (relation) {
-	case CPUFREQ_RELATION_L:
-		if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
-			new_ppcr--;
-		break;
-	case CPUFREQ_RELATION_H:
-		if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
-		    (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
-			new_ppcr--;
-		break;
-	}
-
 	freqs.old = cur;
-	freqs.new = sa11x0_ppcr_to_freq(new_ppcr);
+	freqs.new = sa11x0_freq_table[ppcr].frequency;
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
 	if (freqs.new > cur)
 		sa1100_update_dram_timings(cur, freqs.new);
 
-	PPCR = new_ppcr;
+	PPCR = ppcr;
 
 	if (freqs.new < cur)
 		sa1100_update_dram_timings(cur, freqs.new);
@@ -229,7 +213,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver sa1100_driver __refdata = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= sa1100_target,
+	.target_index	= sa1100_target,
 	.get		= sa11x0_getspeed,
 	.init		= sa1100_cpu_init,
 	.name		= "sa1100",
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c
index a38d904..fb69553 100644
--- a/drivers/cpufreq/sa1110-cpufreq.c
+++ b/drivers/cpufreq/sa1110-cpufreq.c
@@ -229,34 +229,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
 /*
  * Ok, set the CPU frequency.
  */
-static int sa1110_target(struct cpufreq_policy *policy,
-			 unsigned int target_freq,
-			 unsigned int relation)
+static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr)
 {
 	struct sdram_params *sdram = &sdram_params;
 	struct cpufreq_freqs freqs;
 	struct sdram_info sd;
 	unsigned long flags;
-	unsigned int ppcr, unused;
-
-	switch (relation) {
-	case CPUFREQ_RELATION_L:
-		ppcr = sa11x0_freq_to_ppcr(target_freq);
-		if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
-			ppcr--;
-		break;
-	case CPUFREQ_RELATION_H:
-		ppcr = sa11x0_freq_to_ppcr(target_freq);
-		if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) &&
-		    (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min))
-			ppcr--;
-		break;
-	default:
-		return -EINVAL;
-	}
+	unsigned int unused;
 
 	freqs.old = sa11x0_getspeed(0);
-	freqs.new = sa11x0_ppcr_to_freq(ppcr);
+	freqs.new = sa11x0_freq_table[ppcr].frequency;
 
 	sdram_calculate_timing(&sd, freqs.new, sdram);
 
@@ -345,7 +327,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver sa1110_driver __refdata = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= sa1110_target,
+	.target_index	= sa1110_target,
 	.get		= sa11x0_getspeed,
 	.init		= sa1110_cpu_init,
 	.name		= "sa1110",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 31/35] cpufreq: sc520: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (29 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 30/35] cpufreq: sa11x0: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 32/35] cpufreq: sparc: " Viresh Kumar
                     ` (5 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/sc520_freq.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
index 8556225..cd62472 100644
--- a/drivers/cpufreq/sc520_freq.c
+++ b/drivers/cpufreq/sc520_freq.c
@@ -53,8 +53,7 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
 	}
 }
 
-static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy,
-		unsigned int state)
+static int sc520_freq_target(struct cpufreq_policy *policy, unsigned int state)
 {
 
 	struct cpufreq_freqs	freqs;
@@ -76,24 +75,10 @@ static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy,
 	local_irq_enable();
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-};
-
-static int sc520_freq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, sc520_freq_table,
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	sc520_freq_set_cpu_state(policy, newstate);
 
 	return 0;
 }
 
-
 /*
  *	Module init and exit code
  */
@@ -118,7 +103,7 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver sc520_freq_driver = {
 	.get	= sc520_freq_get_cpu_frequency,
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= sc520_freq_target,
+	.target_index = sc520_freq_target,
 	.init	= sc520_freq_cpu_init,
 	.exit	= cpufreq_generic_exit,
 	.name	= "sc520_freq",
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 32/35] cpufreq: sparc: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (30 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 31/35] cpufreq: sc520: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 33/35] cpufreq: SPEAr: " Viresh Kumar
                     ` (4 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: David S. Miller <davem@davemloft.net>
Cc: sparclinux at vger.kernel.org
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/sparc-us2e-cpufreq.c | 21 +++------------------
 drivers/cpufreq/sparc-us3-cpufreq.c  | 23 +++--------------------
 2 files changed, 6 insertions(+), 38 deletions(-)

diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c
index 291688c..3bf5b8f 100644
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -245,8 +245,7 @@ static unsigned int us2e_freq_get(unsigned int cpu)
 	return clock_tick / estar_to_divisor(estar);
 }
 
-static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy,
-		unsigned int index)
+static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	unsigned int cpu = policy->cpu;
 	unsigned long new_bits, new_freq;
@@ -277,20 +276,6 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy,
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	set_cpus_allowed_ptr(current, &cpus_allowed);
-}
-
-static int us2e_freq_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
-{
-	unsigned int new_index = 0;
-
-	if (cpufreq_frequency_table_target(policy,
-					   &us2e_freq_table[policy->cpu].table[0],
-					   target_freq, relation, &new_index))
-		return -EINVAL;
-
-	us2e_set_cpu_divider_index(policy, new_index);
 
 	return 0;
 }
@@ -325,7 +310,7 @@ static int us2e_freq_cpu_exit(struct cpufreq_policy *policy)
 {
 	if (cpufreq_us2e_driver) {
 		cpufreq_frequency_table_put_attr(policy->cpu);
-		us2e_set_cpu_divider_index(policy, 0);
+		us2e_freq_target(policy, 0);
 	}
 
 	return 0;
@@ -358,7 +343,7 @@ static int __init us2e_freq_init(void)
 
 		driver->init = us2e_freq_cpu_init;
 		driver->verify = cpufreq_generic_frequency_table_verify;
-		driver->target = us2e_freq_target;
+		driver->target_index = us2e_freq_target;
 		driver->get = us2e_freq_get;
 		driver->exit = us2e_freq_cpu_exit;
 		strcpy(driver->name, "UltraSPARC-IIe");
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c
index 9b3dbd3..2e54d55 100644
--- a/drivers/cpufreq/sparc-us3-cpufreq.c
+++ b/drivers/cpufreq/sparc-us3-cpufreq.c
@@ -93,8 +93,7 @@ static unsigned int us3_freq_get(unsigned int cpu)
 	return ret;
 }
 
-static void us3_set_cpu_divider_index(struct cpufreq_policy *policy,
-		unsigned int index)
+static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	unsigned int cpu = policy->cpu;
 	unsigned long new_bits, new_freq, reg;
@@ -136,22 +135,6 @@ static void us3_set_cpu_divider_index(struct cpufreq_policy *policy,
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	set_cpus_allowed_ptr(current, &cpus_allowed);
-}
-
-static int us3_freq_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq,
-			  unsigned int relation)
-{
-	unsigned int new_index = 0;
-
-	if (cpufreq_frequency_table_target(policy,
-					   &us3_freq_table[policy->cpu].table[0],
-					   target_freq,
-					   relation,
-					   &new_index))
-		return -EINVAL;
-
-	us3_set_cpu_divider_index(policy, new_index);
 
 	return 0;
 }
@@ -182,7 +165,7 @@ static int us3_freq_cpu_exit(struct cpufreq_policy *policy)
 {
 	if (cpufreq_us3_driver) {
 		cpufreq_frequency_table_put_attr(policy->cpu);
-		us3_set_cpu_divider_index(policy, 0);
+		us3_freq_target(policy, 0);
 	}
 
 	return 0;
@@ -219,7 +202,7 @@ static int __init us3_freq_init(void)
 
 		driver->init = us3_freq_cpu_init;
 		driver->verify = cpufreq_generic_frequency_table_verify;
-		driver->target = us3_freq_target;
+		driver->target_index = us3_freq_target;
 		driver->get = us3_freq_get;
 		driver->exit = us3_freq_cpu_exit;
 		strcpy(driver->name, "UltraSPARC-III");
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 33/35] cpufreq: SPEAr: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (31 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 32/35] cpufreq: sparc: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 34/35] cpufreq: speedstep: " Viresh Kumar
                     ` (3 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/spear-cpufreq.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index d31accc..88aa5cf 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -105,20 +105,16 @@ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq)
 }
 
 static int spear_cpufreq_target(struct cpufreq_policy *policy,
-		unsigned int target_freq, unsigned int relation)
+		unsigned int index)
 {
 	struct cpufreq_freqs freqs;
 	unsigned long newfreq;
 	struct clk *srcclk;
-	int index, ret, mult = 1;
-
-	if (cpufreq_frequency_table_target(policy, spear_cpufreq.freq_tbl,
-				target_freq, relation, &index))
-		return -EINVAL;
+	int ret, mult = 1;
 
 	freqs.old = spear_cpufreq_get(0);
-
 	newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000;
+
 	if (of_machine_is_compatible("st,spear1340")) {
 		/*
 		 * SPEAr1340 is special in the sense that due to the possibility
@@ -191,7 +187,7 @@ static struct cpufreq_driver spear_cpufreq_driver = {
 	.name		= "cpufreq-spear",
 	.flags		= CPUFREQ_STICKY,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= spear_cpufreq_target,
+	.target_index	= spear_cpufreq_target,
 	.get		= spear_cpufreq_get,
 	.init		= spear_cpufreq_init,
 	.exit		= cpufreq_generic_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 34/35] cpufreq: speedstep: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (32 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 33/35] cpufreq: SPEAr: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:32   ` [PATCH V2 35/35] cpufreq: tegra: " Viresh Kumar
                     ` (2 subsequent siblings)
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/speedstep-centrino.c | 26 +++++++-------------------
 drivers/cpufreq/speedstep-ich.c      | 24 ++++++------------------
 drivers/cpufreq/speedstep-smi.c      | 20 +++++---------------
 3 files changed, 18 insertions(+), 52 deletions(-)

diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index c7c14ae..b309774 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -422,21 +422,17 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
 /**
  * centrino_setpolicy - set a new CPUFreq policy
  * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @index: index of target frequency
  *
  * Sets a new CPUFreq policy.
  */
-static int centrino_target (struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
+static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int    newstate = 0;
 	unsigned int	msr, oldmsr = 0, h = 0, cpu = policy->cpu;
 	struct cpufreq_freqs	freqs;
 	int			retval = 0;
 	unsigned int		j, first_cpu, tmp;
+	struct cpufreq_frequency_table *op_points;
 	cpumask_var_t covered_cpus;
 
 	if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
@@ -447,16 +443,8 @@ static int centrino_target (struct cpufreq_policy *policy,
 		goto out;
 	}
 
-	if (unlikely(cpufreq_frequency_table_target(policy,
-			per_cpu(centrino_model, cpu)->op_points,
-			target_freq,
-			relation,
-			&newstate))) {
-		retval = -EINVAL;
-		goto out;
-	}
-
 	first_cpu = 1;
+	op_points = &per_cpu(centrino_model, cpu)->op_points[index];
 	for_each_cpu(j, policy->cpus) {
 		int good_cpu;
 
@@ -480,7 +468,7 @@ static int centrino_target (struct cpufreq_policy *policy,
 			break;
 		}
 
-		msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data;
+		msr = op_points->driver_data;
 
 		if (first_cpu) {
 			rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
@@ -495,7 +483,7 @@ static int centrino_target (struct cpufreq_policy *policy,
 			freqs.new = extract_clock(msr, cpu, 0);
 
 			pr_debug("target=%dkHz old=%d new=%d msr=%04x\n",
-				target_freq, freqs.old, freqs.new, msr);
+				op_points->frequency, freqs.old, freqs.new, msr);
 
 			cpufreq_notify_transition(policy, &freqs,
 					CPUFREQ_PRECHANGE);
@@ -546,7 +534,7 @@ static struct cpufreq_driver centrino_driver = {
 	.init		= centrino_cpu_init,
 	.exit		= centrino_cpu_exit,
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= centrino_target,
+	.target_index	= centrino_target,
 	.get		= get_cur_freq,
 	.attr		= cpufreq_generic_attr,
 };
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index 929a4f0..be63486 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -251,36 +251,24 @@ static unsigned int speedstep_get(unsigned int cpu)
 /**
  * speedstep_target - set a new CPUFreq policy
  * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @index: index of target frequency
  *
  * Sets a new CPUFreq policy.
  */
-static int speedstep_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
+static int speedstep_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int newstate = 0, policy_cpu;
+	unsigned int policy_cpu;
 	struct cpufreq_freqs freqs;
 
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
 	policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
 	freqs.old = speedstep_get(policy_cpu);
-	freqs.new = speedstep_freqs[newstate].frequency;
+	freqs.new = speedstep_freqs[index].frequency;
 
 	pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new);
 
-	/* no transition necessary */
-	if (freqs.old == freqs.new)
-		return 0;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
-	smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate,
+	smp_call_function_single(policy_cpu, _speedstep_set_state, &index,
 				 true);
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
@@ -343,7 +331,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 static struct cpufreq_driver speedstep_driver = {
 	.name	= "speedstep-ich",
 	.verify	= cpufreq_generic_frequency_table_verify,
-	.target	= speedstep_target,
+	.target_index = speedstep_target,
 	.init	= speedstep_cpu_init,
 	.exit	= cpufreq_generic_exit,
 	.get	= speedstep_get,
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index b3dfba0..878e64b 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -235,29 +235,19 @@ static void speedstep_set_state(unsigned int state)
 /**
  * speedstep_target - set a new CPUFreq policy
  * @policy: new policy
- * @target_freq: new freq
- * @relation:
+ * @index: index of new freq
  *
  * Sets a new CPUFreq policy/freq.
  */
-static int speedstep_target(struct cpufreq_policy *policy,
-			unsigned int target_freq, unsigned int relation)
+static int speedstep_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int newstate = 0;
 	struct cpufreq_freqs freqs;
 
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
 	freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
-	freqs.new = speedstep_freqs[newstate].frequency;
-
-	if (freqs.old == freqs.new)
-		return 0;
+	freqs.new = speedstep_freqs[index].frequency;
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-	speedstep_set_state(newstate);
+	speedstep_set_state(index);
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	return 0;
@@ -340,7 +330,7 @@ static int speedstep_resume(struct cpufreq_policy *policy)
 static struct cpufreq_driver speedstep_driver = {
 	.name		= "speedstep-smi",
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= speedstep_target,
+	.target_index	= speedstep_target,
 	.init		= speedstep_cpu_init,
 	.exit		= cpufreq_generic_exit,
 	.get		= speedstep_get,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 35/35] cpufreq: tegra: Covert to light weight ->target_index() routine
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (33 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 34/35] cpufreq: speedstep: " Viresh Kumar
@ 2013-08-13 13:32   ` Viresh Kumar
  2013-08-13 13:46   ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
  2013-08-14  5:29   ` Viresh Kumar
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts existing .target() to newly defined light weight
.target_index() routine for this driver.

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and will pass index to it.

Cc: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/tegra-cpufreq.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c
index affb294..ee2cf8f3 100644
--- a/drivers/cpufreq/tegra-cpufreq.c
+++ b/drivers/cpufreq/tegra-cpufreq.c
@@ -150,11 +150,8 @@ static unsigned long tegra_cpu_highest_speed(void)
 	return rate;
 }
 
-static int tegra_target(struct cpufreq_policy *policy,
-		       unsigned int target_freq,
-		       unsigned int relation)
+static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	unsigned int idx;
 	unsigned int freq;
 	int ret = 0;
 
@@ -165,10 +162,7 @@ static int tegra_target(struct cpufreq_policy *policy,
 		goto out;
 	}
 
-	cpufreq_frequency_table_target(policy, freq_table, target_freq,
-		relation, &idx);
-
-	freq = freq_table[idx].frequency;
+	freq = freq_table[index].frequency;
 
 	target_cpu_speed[policy->cpu] = freq;
 
@@ -234,7 +228,7 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver tegra_cpufreq_driver = {
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target		= tegra_target,
+	.target_index	= tegra_target,
 	.get		= tegra_getspeed,
 	.init		= tegra_cpu_init,
 	.exit		= tegra_cpu_exit,
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (34 preceding siblings ...)
  2013-08-13 13:32   ` [PATCH V2 35/35] cpufreq: tegra: " Viresh Kumar
@ 2013-08-13 13:46   ` Viresh Kumar
  2013-08-14  5:29   ` Viresh Kumar
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-13 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 August 2013 19:02, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Currently prototype of cpufreq_drivers target routines is:
>
> int target(struct cpufreq_policy *policy, unsigned int target_freq,
>         unsigned int relation);
>
> And most of the drivers call cpufreq_frequency_table_target() to get a valid
> index of their frequency table which is closest to the target_freq. And they
> don't use target_freq and relation after it.

I just came to know from a friend that I have written "covert" instead of
"convert" in subjects of all the patches.

Will fix it in my repo for now.

Thanks Sudeep :)

--
viresh

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

* [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
                     ` (35 preceding siblings ...)
  2013-08-13 13:46   ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
@ 2013-08-14  5:29   ` Viresh Kumar
  36 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-14  5:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 August 2013 19:02, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Currently prototype of cpufreq_drivers target routines is:
>
> int target(struct cpufreq_policy *policy, unsigned int target_freq,
>         unsigned int relation);
>
> And most of the drivers call cpufreq_frequency_table_target() to get a valid
> index of their frequency table which is closest to the target_freq. And they
> don't use target_freq and relation after it.
>
> So, it makes sense to just do this work in cpufreq core before calling
> cpufreq_frequency_table_target() and simply pass index instead. But this can be
> done only with drivers which expose their frequency table with cpufreq core. For
> others we need to stick with the old prototype of target() until those drivers
> are converted to expose frequency tables.
>
> There are 7 drivers after this patchset which still use the heavy weight
> version, i.e. target() and 44 drivers have adopted this new approach, i.e.
> target_index().
>
> Once those 7 drivers are also moved to use .target_index(), .target() will be
> removed completely.

At a quick look at the status of drivers using target_index() it looks there is
scope of more optimizations around that part..

We can actually get rid of cpufreq_notify_transition() from those cpufreq
drivers and do that in core.. And that would cut down size of ->target_index()
routines even more :)

I will give it a try soon.

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

* [PATCH V2 05/35] cpufreq: at32ap: Covert to light weight ->target_index() routine
  2013-08-13 13:32   ` [PATCH V2 05/35] cpufreq: at32ap: " Viresh Kumar
@ 2013-08-14  8:00     ` Hans-Christian Egtvedt
  0 siblings, 0 replies; 91+ messages in thread
From: Hans-Christian Egtvedt @ 2013-08-14  8:00 UTC (permalink / raw)
  To: linux-arm-kernel

Around Tue 13 Aug 2013 19:02:18 +0530 or thereabout, Viresh Kumar wrote:
> This patch converts existing .target() to newly defined light weight
> .target_index() routine for this driver.
> 
> CPUFreq core will call cpufreq_frequency_table_target() before calling this
> routine and will pass index to it.
> 
> Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>

> ---
>  drivers/cpufreq/at32ap-cpufreq.c | 23 +++++------------------
>  1 file changed, 5 insertions(+), 18 deletions(-)

<snipp diff>

-- 
mvh
Hans-Christian Egtvedt

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-13 13:32   ` [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine Viresh Kumar
@ 2013-08-18 10:41     ` amit daniel kachhap
  2013-08-19  4:37       ` Viresh Kumar
  0 siblings, 1 reply; 91+ messages in thread
From: amit daniel kachhap @ 2013-08-18 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Viresh,

On Tue, Aug 13, 2013 at 7:02 PM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Currently prototype of cpufreq_drivers target routines is:
>
> int target(struct cpufreq_policy *policy, unsigned int target_freq,
>                 unsigned int relation);
>
> And most of the drivers call cpufreq_frequency_table_target() to get a valid
> index of their frequency table which is closest to the target_freq. And they
> don't use target_freq and relation after it.
>
> So, it makes sense to just do this work in cpufreq core before calling
> cpufreq_frequency_table_target() and simply pass index instead. But this can be
> done only with drivers which expose their frequency table with cpufreq core. For
> others we need to stick with the old prototype of target() until those drivers
> are converted to expose frequency tables.
>
> This patch implements the new light weight prototype for target_index() routine.
> It looks like this:
>
> int target_index(struct cpufreq_policy *policy, unsigned int index);
This new API is fine but I have another idea.
Say During the registration of the frequency table cpufreq_policy can
be registered as SCALE_DIRECT or SCALE_STEPS. With SCALE_DIRECT flag,
valid frequency will be requested. With this flags the governor itself
can  can figure out if frequency scaling is required or not and very
few calls to __cpufreq_driver_target will happen.
But i agree that in this approach cpufreq_frequency_table_target is
still required but again it can be optimized by binary search as
currently the search is linear.

Thanks,
Amit
>
> CPUFreq core will call cpufreq_frequency_table_target() before calling this
> routine and pass index to it. Because CPUFreq core now requires to call routines
> present in freq_table.c CONFIG_CPU_FREQ_TABLE must be enabled all the time.
>
> This also marks target() interface as deprecated. So, that new drivers avoid
> using it. And
>
> Documentation is updated accordingly.
>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> Cc: Jesper Nilsson <jesper.nilsson@axis.com>
> Cc: John Crispin <blogic@openwrt.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: linux-cris-kernel at axis.com
> Cc: Mikael Starvik <starvik@axis.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Cc: sparclinux at vger.kernel.org
> Cc: Stephen Warren <swarren@nvidia.com>
> Cc: Steven Miao <realmz6@gmail.com>
> Cc: Tony Luck <tony.luck@intel.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  Documentation/cpu-freq/cpu-drivers.txt | 27 +++++++++++------
>  Documentation/cpu-freq/governors.txt   |  4 +--
>  drivers/cpufreq/Kconfig                |  1 +
>  drivers/cpufreq/cpufreq.c              | 55 +++++++++++++++++++++++++++-------
>  include/linux/cpufreq.h                |  4 ++-
>  5 files changed, 68 insertions(+), 23 deletions(-)
>
> diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
> index 40282e6..8b1a445 100644
> --- a/Documentation/cpu-freq/cpu-drivers.txt
> +++ b/Documentation/cpu-freq/cpu-drivers.txt
> @@ -23,8 +23,8 @@ Contents:
>  1.1  Initialization
>  1.2  Per-CPU Initialization
>  1.3  verify
> -1.4  target or setpolicy?
> -1.5  target
> +1.4  target/target_index or setpolicy?
> +1.5  target/target_index
>  1.6  setpolicy
>  2.   Frequency Table Helpers
>
> @@ -56,7 +56,8 @@ cpufreq_driver.init -         A pointer to the per-CPU initialization
>  cpufreq_driver.verify -                A pointer to a "verification" function.
>
>  cpufreq_driver.setpolicy _or_
> -cpufreq_driver.target -                See below on the differences.
> +cpufreq_driver.target/
> +target_index           -       See below on the differences.
>
>  And optionally
>
> @@ -66,7 +67,7 @@ cpufreq_driver.resume -               A pointer to a per-CPU resume function
>                                 which is called with interrupts disabled
>                                 and _before_ the pre-suspend frequency
>                                 and/or policy is restored by a call to
> -                               ->target or ->setpolicy.
> +                               ->target/target_index or ->setpolicy.
>
>  cpufreq_driver.attr -          A pointer to a NULL-terminated list of
>                                 "struct freq_attr" which allow to
> @@ -103,8 +104,8 @@ policy->governor            must contain the "default policy" for
>                                 this CPU. A few moments later,
>                                 cpufreq_driver.verify and either
>                                 cpufreq_driver.setpolicy or
> -                               cpufreq_driver.target is called with
> -                               these values.
> +                               cpufreq_driver.target/target_index is called
> +                               with these values.
>
>  For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
>  frequency table helpers might be helpful. See the section 2 for more information
> @@ -133,20 +134,28 @@ range) is within policy->min and policy->max. If necessary, increase
>  policy->max first, and only if this is no solution, decrease policy->min.
>
>
> -1.4 target or setpolicy?
> +1.4 target/target_index or setpolicy?
>  ----------------------------
>
>  Most cpufreq drivers or even most cpu frequency scaling algorithms
>  only allow the CPU to be set to one frequency. For these, you use the
> -->target call.
> +->target/target_index call.
>
>  Some cpufreq-capable processors switch the frequency between certain
>  limits on their own. These shall use the ->setpolicy call
>
>
> -1.4. target
> +1.4. target/target_index
>  -------------
>
> +The target_index call has two arguments: struct cpufreq_policy *policy,
> +and unsigned int index (into the exposed frequency table).
> +
> +The CPUfreq driver must set the new frequency when called here. The
> +actual frequency must be determined by freq_table[index].frequency.
> +
> +Deprecated:
> +----------
>  The target call has three arguments: struct cpufreq_policy *policy,
>  unsigned int target_frequency, unsigned int relation.
>
> diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
> index 219970b..77ec215 100644
> --- a/Documentation/cpu-freq/governors.txt
> +++ b/Documentation/cpu-freq/governors.txt
> @@ -40,7 +40,7 @@ Most cpufreq drivers (in fact, all except one, longrun) or even most
>  cpu frequency scaling algorithms only offer the CPU to be set to one
>  frequency. In order to offer dynamic frequency scaling, the cpufreq
>  core must be able to tell these drivers of a "target frequency". So
> -these specific drivers will be transformed to offer a "->target"
> +these specific drivers will be transformed to offer a "->target/target_index"
>  call instead of the existing "->setpolicy" call. For "longrun", all
>  stays the same, though.
>
> @@ -71,7 +71,7 @@ CPU can be set to switch independently         |         CPU can only be set
>                     /                          the limits of policy->{min,max}
>                    /                                \
>                   /                                  \
> -       Using the ->setpolicy call,              Using the ->target call,
> +       Using the ->setpolicy call,              Using the ->target/target_index call,
>             the limits and the                    the frequency closest
>              "policy" is set.                     to target_freq is set.
>                                                   It is assured that it
> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> index 534fcb8..2d06754 100644
> --- a/drivers/cpufreq/Kconfig
> +++ b/drivers/cpufreq/Kconfig
> @@ -2,6 +2,7 @@ menu "CPU Frequency scaling"
>
>  config CPU_FREQ
>         bool "CPU Frequency scaling"
> +       select CPU_FREQ_TABLE
>         help
>           CPU Frequency scaling allows you to change the clock speed of
>           CPUs on the fly. This is a nice method to save power, because
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 37a6874..f1b0e0f 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list);
>  static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
>  #endif
>
> +static inline bool has_target(void)
> +{
> +       return cpufreq_driver->target_index || cpufreq_driver->target;
> +}
> +
>  /*
>   * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
>   * all cpufreq/hotplug/workqueue/etc related lock issues.
> @@ -377,7 +382,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
>                         *policy = CPUFREQ_POLICY_POWERSAVE;
>                         err = 0;
>                 }
> -       } else if (cpufreq_driver->target) {
> +       } else if (has_target()) {
>                 struct cpufreq_governor *t;
>
>                 mutex_lock(&cpufreq_governor_mutex);
> @@ -539,7 +544,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
>         ssize_t i = 0;
>         struct cpufreq_governor *t;
>
> -       if (!cpufreq_driver->target) {
> +       if (!has_target()) {
>                 i += sprintf(buf, "performance powersave");
>                 goto out;
>         }
> @@ -822,7 +827,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
>                 if (ret)
>                         goto err_out_kobj_put;
>         }
> -       if (cpufreq_driver->target) {
> +       if (has_target()) {
>                 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
>                 if (ret)
>                         goto err_out_kobj_put;
> @@ -871,10 +876,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
>                                   unsigned int cpu, struct device *dev,
>                                   bool frozen)
>  {
> -       int ret = 0, has_target = !!cpufreq_driver->target;
> +       int ret = 0;
>         unsigned long flags;
>
> -       if (has_target) {
> +       if (has_target()) {
>                 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
>                 if (ret) {
>                         pr_err("%s: Failed to stop governor\n", __func__);
> @@ -893,7 +898,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
>
>         unlock_policy_rwsem_write(policy->cpu);
>
> -       if (has_target) {
> +       if (has_target()) {
>                 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
>                         (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
>                         pr_err("%s: Failed to start governor\n", __func__);
> @@ -1204,7 +1209,7 @@ static int __cpufreq_remove_dev(struct device *dev,
>                 return -EINVAL;
>         }
>
> -       if (cpufreq_driver->target) {
> +       if (has_target()) {
>                 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
>                 if (ret) {
>                         pr_err("%s: Failed to stop governor\n", __func__);
> @@ -1244,7 +1249,7 @@ static int __cpufreq_remove_dev(struct device *dev,
>
>         /* If cpu is last user of policy, free policy */
>         if (cpus == 1) {
> -               if (cpufreq_driver->target) {
> +               if (has_target()) {
>                         ret = __cpufreq_governor(policy,
>                                         CPUFREQ_GOV_POLICY_EXIT);
>                         if (ret) {
> @@ -1282,7 +1287,7 @@ static int __cpufreq_remove_dev(struct device *dev,
>                 if (!frozen)
>                         cpufreq_policy_free(policy);
>         } else {
> -               if (cpufreq_driver->target) {
> +               if (has_target()) {
>                         if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
>                                         (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
>                                 pr_err("%s: Failed to start governor\n",
> @@ -1646,11 +1651,39 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
>         pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
>                         policy->cpu, target_freq, relation, old_target_freq);
>
> +       /*
> +        * This might look like a redundant call as we are checking it again
> +        * after finding index. But it is left intentionally for cases where
> +        * exactly same freq is called again and so we can save on few function
> +        * calls.
> +        */
>         if (target_freq == policy->cur)
>                 return 0;
>
>         if (cpufreq_driver->target)
>                 retval = cpufreq_driver->target(policy, target_freq, relation);
> +       else if (cpufreq_driver->target_index) {
> +               struct cpufreq_frequency_table *freq_table;
> +               int index;
> +
> +               freq_table = cpufreq_frequency_get_table(policy->cpu);
> +               if (unlikely(!freq_table)) {
> +                       pr_err("%s: Unable to find freq_table\n", __func__);
> +                       return retval;
> +               }
> +
> +               retval = cpufreq_frequency_table_target(policy, freq_table,
> +                               target_freq, relation, &index);
> +               if (unlikely(retval)) {
> +                       pr_err("%s: Unable to find matching freq\n", __func__);
> +                       return retval;
> +               }
> +
> +               if (freq_table[index].frequency == policy->cur)
> +                       return 0;
> +
> +               retval = cpufreq_driver->target_index(policy, index);
> +       }
>
>         return retval;
>  }
> @@ -1983,7 +2016,7 @@ int cpufreq_update_policy(unsigned int cpu)
>                         pr_debug("Driver did not initialize current freq");
>                         policy->cur = new_policy.cur;
>                 } else {
> -                       if (policy->cur != new_policy.cur && cpufreq_driver->target)
> +                       if (policy->cur != new_policy.cur && has_target())
>                                 cpufreq_out_of_sync(cpu, policy->cur,
>                                                                 new_policy.cur);
>                 }
> @@ -2058,7 +2091,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
>                 return -ENODEV;
>
>         if (!driver_data || !driver_data->verify || !driver_data->init ||
> -           ((!driver_data->setpolicy) && (!driver_data->target)))
> +           (!driver_data->setpolicy && !has_target()))
>                 return -EINVAL;
>
>         pr_debug("trying to register driver %s\n", driver_data->name);
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 4907eb2..ff9c8df 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -195,9 +195,11 @@ struct cpufreq_driver {
>
>         /* define one out of two */
>         int     (*setpolicy)    (struct cpufreq_policy *policy);
> -       int     (*target)       (struct cpufreq_policy *policy,
> +       int     (*target)       (struct cpufreq_policy *policy, /* Deprecated */
>                                  unsigned int target_freq,
>                                  unsigned int relation);
> +       int     (*target_index) (struct cpufreq_policy *policy,
> +                                unsigned int index);
>
>         /* should be defined, if possible */
>         unsigned int    (*get)  (unsigned int cpu);
> --
> 1.7.12.rc2.18.g61b472e
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-18 10:41     ` amit daniel kachhap
@ 2013-08-19  4:37       ` Viresh Kumar
  2013-08-19  6:16         ` amit daniel kachhap
  0 siblings, 1 reply; 91+ messages in thread
From: Viresh Kumar @ 2013-08-19  4:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Amit,

Thanks for your feedback :)

On 18 August 2013 16:11, amit daniel kachhap <amit.daniel@samsung.com> wrote:
> This new API is fine but I have another idea.

good.

> Say During the registration of the frequency table cpufreq_policy can
> be registered as SCALE_DIRECT or SCALE_STEPS. With SCALE_DIRECT flag,
> valid frequency will be requested. With this flags the governor itself
> can  can figure out if frequency scaling is required or not and very
> few calls to __cpufreq_driver_target will happen.

Honestly speaking I couldn't get what your idea is :) ... but governor is
in no position to make this direct call to drivers.. Taking such stuff to
governors will replicate this code again.. Its better all governors call
some common part of cpufreq.c which then decides what to do..

> But i agree that in this approach cpufreq_frequency_table_target is
> still required but again it can be optimized by binary search as
> currently the search is linear.

Frequencies in this table aren't required to be in ascending order :)

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-19  4:37       ` Viresh Kumar
@ 2013-08-19  6:16         ` amit daniel kachhap
  2013-08-19  6:19           ` Viresh Kumar
  0 siblings, 1 reply; 91+ messages in thread
From: amit daniel kachhap @ 2013-08-19  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 19, 2013 at 10:07 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Hi Amit,
>
> Thanks for your feedback :)
>
> On 18 August 2013 16:11, amit daniel kachhap <amit.daniel@samsung.com> wrote:
>> This new API is fine but I have another idea.
>
> good.
>
>> Say During the registration of the frequency table cpufreq_policy can
>> be registered as SCALE_DIRECT or SCALE_STEPS. With SCALE_DIRECT flag,
>> valid frequency will be requested. With this flags the governor itself
>> can  can figure out if frequency scaling is required or not and very
>> few calls to __cpufreq_driver_target will happen.
>
> Honestly speaking I couldn't get what your idea is :) ... but governor is
> in no position to make this direct call to drivers.. Taking such stuff to
> governors will replicate this code again.. Its better all governors call
> some common part of cpufreq.c which then decides what to do..
I meant that something like 2 policies can be registered SCALE_DIRECT/STEPS.
if SCALE_DIRECT is registered than target will be called with exact
frequency. SCALE_STEPS will behave as currently happening. This way
target_index api may not be needed. But looks like Rafael and others
are fine with your approach so you can ignore this :)
>
>> But i agree that in this approach cpufreq_frequency_table_target is
>> still required but again it can be optimized by binary search as
>> currently the search is linear.
>
> Frequencies in this table aren't required to be in ascending order :)
OK right. Actually I had thought only about the case when opp library
is used to create the cpufreq table and then it creates the table in
ascending order. Anyways not all platform uses opp libraries so it is
not generic enough.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


On Mon, Aug 19, 2013 at 10:07 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Hi Amit,
>
> Thanks for your feedback :)
>
> On 18 August 2013 16:11, amit daniel kachhap <amit.daniel@samsung.com> wrote:
>> This new API is fine but I have another idea.
>
> good.
>
>> Say During the registration of the frequency table cpufreq_policy can
>> be registered as SCALE_DIRECT or SCALE_STEPS. With SCALE_DIRECT flag,
>> valid frequency will be requested. With this flags the governor itself
>> can  can figure out if frequency scaling is required or not and very
>> few calls to __cpufreq_driver_target will happen.
>
> Honestly speaking I couldn't get what your idea is :) ... but governor is
> in no position to make this direct call to drivers.. Taking such stuff to
> governors will replicate this code again.. Its better all governors call
> some common part of cpufreq.c which then decides what to do..
>
>> But i agree that in this approach cpufreq_frequency_table_target is
>> still required but again it can be optimized by binary search as
>> currently the search is linear.
>
> Frequencies in this table aren't required to be in ascending order :)
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-19  6:16         ` amit daniel kachhap
@ 2013-08-19  6:19           ` Viresh Kumar
  2013-08-19  6:46             ` amit daniel kachhap
  0 siblings, 1 reply; 91+ messages in thread
From: Viresh Kumar @ 2013-08-19  6:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 August 2013 11:46, amit daniel kachhap <amit.daniel@samsung.com> wrote:
> I meant that something like 2 policies can be registered SCALE_DIRECT/STEPS.
> if SCALE_DIRECT is registered than target will be called with exact
> frequency. SCALE_STEPS will behave as currently happening. This way
> target_index api may not be needed. But looks like Rafael and others
> are fine with your approach so you can ignore this :)


 Why wouldn't we need target_index in case of SCALE_DIRECT? All
target_index is doing now is changing platform specific registers to configure
an exact frequency reported by index..

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-19  6:19           ` Viresh Kumar
@ 2013-08-19  6:46             ` amit daniel kachhap
  2013-08-19  6:49               ` Viresh Kumar
  0 siblings, 1 reply; 91+ messages in thread
From: amit daniel kachhap @ 2013-08-19  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 19, 2013 at 11:49 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 19 August 2013 11:46, amit daniel kachhap <amit.daniel@samsung.com> wrote:
>> I meant that something like 2 policies can be registered SCALE_DIRECT/STEPS.
>> if SCALE_DIRECT is registered than target will be called with exact
>> frequency. SCALE_STEPS will behave as currently happening. This way
>> target_index api may not be needed. But looks like Rafael and others
>> are fine with your approach so you can ignore this :)
>
>
>  Why wouldn't we need target_index in case of SCALE_DIRECT? All
> target_index is doing now is changing platform specific registers to configure
> an exact frequency reported by index..

Actually target index will still be re-calculated if the platform
target driver wants to retrieve the index from the valid frequency or
directly set the valid frequency in the clock controller. So I wanted
a simpler/quicker cpufreq_frequency_table_target which just returns
the matching index from the valid frequency.



>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine
  2013-08-19  6:46             ` amit daniel kachhap
@ 2013-08-19  6:49               ` Viresh Kumar
  0 siblings, 0 replies; 91+ messages in thread
From: Viresh Kumar @ 2013-08-19  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 August 2013 12:16, amit daniel kachhap <amit.daniel@samsung.com> wrote:
> Actually target index will still be re-calculated if the platform
> target driver wants to retrieve the index from the valid frequency or
> directly set the valid frequency in the clock controller. So I wanted
> a simpler/quicker cpufreq_frequency_table_target which just returns
> the matching index from the valid frequency.

I am so sorry but I am still missing your point.

Index isn't required to be calculated by platform drivers anymore, it will be
done by cpufreq core before calling target_index()..

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

* [PATCH 0/3] mtd: gpmi: add subpage read support
       [not found] <a>
                   ` (9 preceding siblings ...)
  2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
@ 2014-01-03  3:01 ` Huang Shijie
  2014-02-21  6:51   ` Huang Shijie
  2014-03-07  7:27   ` Brian Norris
  2014-01-03  3:01 ` [PATCH 1/3] mtd: nand: add "page" argument for read_subpage hook Huang Shijie
                   ` (10 subsequent siblings)
  21 siblings, 2 replies; 91+ messages in thread
From: Huang Shijie @ 2014-01-03  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

1) Why add the subpage read support?
  The page size of the nand chip becomes larger and larger, the imx6 has to
  supports the 16K page or even bigger page. But sometimes, the upper layer only
  needs a small part of the page, such as 512 bytes or less.

  For example, ubiattach may only read 64 bytes per page.

2) We only enable the subpage read support when it meets the conditions:
   <1> the chip is imx6 (or later chips) which can supports large nand page.
   <2> the size of ECC parity is byte aligned.
       If the size of ECC parity is not byte aligned, the calling of NAND_CMD_RNDOUT
       will fail.

3) What does this patch set do?
   patch 1: add a new argument for read_subpage hook
   patch 2: do not use the mtd->writesize. 
   patch 3: This patch will fake a virtual small page for the subpage read,
            and call the gpmi_ecc_read_page() to do the real work.
            In order to fake a virtual small page, the patch changes
	    the BCH registers and the bch_geometry{}. After the subpage read
	    finished, we will restore them back.

4) Performace:
    4.1) Tested with Toshiba TC58NVG2S0F(4096 + 224) with the following command:
         #ubiattach /dev/ubi_ctrl -m 4

       The detail information of /dev/mtd4 shows below:
       --------------------------------------------------------------
       #mtdinfo /dev/mtd4
        mtd4
        Name:                           test
        Type:                           nand
        Eraseblock size:                262144 bytes, 256.0 KiB
        Amount of eraseblocks:          1856 (486539264 bytes, 464.0 MiB)
        Minimum input/output unit size: 4096 bytes
        Sub-page size:                  4096 bytes
        OOB size:                       224 bytes
        Character device major/minor:   90:8
        Bad blocks are allowed:         true
        Device is writable:             true
       --------------------------------------------------------------

    4.2) Before this patch:
       --------------------------------------------------------------
       [   94.530495] UBI: attaching mtd4 to ubi0
       [   98.928850] UBI: scanning is finished
       [   98.953594] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
       [   98.958562] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
       [   98.964076] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
       [   98.969518] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
       [   98.975128] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
       [   98.979843] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
       [   98.985878] UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 2024916145
       [   98.993635] UBI: available PEBs: 0, total reserved PEBs: 1856, PEBs reserved for bad PEB handling: 40
       [   99.001807] UBI: background thread "ubi_bgt0d" started, PID 831
       --------------------------------------------------------------
       The attach time is about 98.9 - 94.5 = 4.4s

    4.3) After this patch:
       --------------------------------------------------------------
       [  286.464906] UBI: attaching mtd4 to ubi0
       [  289.186129] UBI: scanning is finished
       [  289.211416] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
       [  289.216360] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
       [  289.221858] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
       [  289.227293] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
       [  289.232878] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
       [  289.237628] UBI: user volume: 0, internal volumes: 1, max. volumes count: 128
       [  289.243553] UBI: max/mean erase counter: 1/1, WL threshold: 4096, image sequence number: 2024916145
       [  289.251348] UBI: available PEBs: 1812, total reserved PEBs: 44, PEBs reserved for bad PEB handling: 40
       [  289.259417] UBI: background thread "ubi_bgt0d" started, PID 847
       --------------------------------------------------------------
       The attach time is about 289.18 - 286.46 = 2.7s

     4.4) The conclusion:
       We achieve (4.4 - 2.7) / 4.4 = 38.6% faster in the ubiattach.

 5) This patch depends on the following patch:
    http://lists.infradead.org/pipermail/linux-mtd/2013-December/051091.html

Huang Shijie (3):
  mtd: nand: add "page" argument for read_subpage hook
  mtd: gpmi: do not use the mtd->writesize
  mtd: gpmi: add subpage read support

 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  102 +++++++++++++++++++++++++++++++-
 drivers/mtd/nand/nand_base.c           |    7 ++-
 include/linux/mtd/nand.h               |    2 +-
 3 files changed, 105 insertions(+), 6 deletions(-)

-- 
1.7.2.rc3

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

* [PATCH 1/3] mtd: nand: add "page" argument for read_subpage hook
       [not found] <a>
                   ` (10 preceding siblings ...)
  2014-01-03  3:01 ` [PATCH 0/3] mtd: gpmi: add subpage read support Huang Shijie
@ 2014-01-03  3:01 ` Huang Shijie
  2014-01-03  3:01 ` [PATCH 2/3] mtd: gpmi: do not use the mtd->writesize Huang Shijie
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-01-03  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

Add the "page" argument for the read_subpage hook. With this argument,
the implementation of this hook could prints out more accurate information
for debugging.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/nand/nand_base.c |    7 +++++--
 include/linux/mtd/nand.h     |    2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 9b3bb3c..b2556f8 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1115,9 +1115,11 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @data_offs: offset of requested data within the page
  * @readlen: data length
  * @bufpoi: buffer to store read data
+ * @page: page number to read
  */
 static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
-			uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
+			uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
+			int page)
 {
 	int start_step, end_step, num_steps;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -1467,7 +1469,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 			else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
 				 !oob)
 				ret = chip->ecc.read_subpage(mtd, chip,
-							col, bytes, bufpoi);
+							col, bytes, bufpoi,
+							page);
 			else
 				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 							  oob_required, page);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9e6c8f9..b7a344c 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -394,7 +394,7 @@ struct nand_ecc_ctrl {
 	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
 	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
-			uint32_t offs, uint32_t len, uint8_t *buf);
+			uint32_t offs, uint32_t len, uint8_t *buf, int page);
 	int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offset, uint32_t data_len,
 			const uint8_t *data_buf, int oob_required);
-- 
1.7.2.rc3

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

* [PATCH 2/3] mtd: gpmi: do not use the mtd->writesize
       [not found] <a>
                   ` (11 preceding siblings ...)
  2014-01-03  3:01 ` [PATCH 1/3] mtd: nand: add "page" argument for read_subpage hook Huang Shijie
@ 2014-01-03  3:01 ` Huang Shijie
  2014-01-03  3:01 ` [PATCH 3/3] mtd: gpmi: add subpage read support Huang Shijie
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-01-03  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

The nfc_geo->payload_size is equal to the mtd->writesize now,
use the nfc_geo->payload_size to replace the mtd->writesize.

This patch makes preparation for the gpmi's subpage read support.
In the subpage support, the nfc_geo->payload_size maybe smaller then
the mtd->writesize.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 1908709..c92df74 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1010,7 +1010,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	int           ret;
 
 	dev_dbg(this->dev, "page number is : %d\n", page);
-	ret = read_page_prepare(this, buf, mtd->writesize,
+	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
 					this->payload_virt, this->payload_phys,
 					nfc_geo->payload_size,
 					&payload_virt, &payload_phys);
@@ -1024,7 +1024,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	/* go! */
 	ret = gpmi_read_page(this, payload_phys, auxiliary_phys);
-	read_page_end(this, buf, mtd->writesize,
+	read_page_end(this, buf, nfc_geo->payload_size,
 			this->payload_virt, this->payload_phys,
 			nfc_geo->payload_size,
 			payload_virt, payload_phys);
@@ -1079,7 +1079,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
 	}
 
-	read_page_swap_end(this, buf, mtd->writesize,
+	read_page_swap_end(this, buf, nfc_geo->payload_size,
 			this->payload_virt, this->payload_phys,
 			nfc_geo->payload_size,
 			payload_virt, payload_phys);
-- 
1.7.2.rc3

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

* [PATCH 3/3] mtd: gpmi: add subpage read support
       [not found] <a>
                   ` (12 preceding siblings ...)
  2014-01-03  3:01 ` [PATCH 2/3] mtd: gpmi: do not use the mtd->writesize Huang Shijie
@ 2014-01-03  3:01 ` Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad " Huang Shijie
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-01-03  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

1) Why add the subpage read support?
  The page size of the nand chip becomes larger and larger, the imx6 has to
  supports the 16K page or even bigger page. But sometimes, the upper layer only
  needs a small part of the page, such as 512 bytes or less.

  For example, ubiattach may only read 64 bytes per page.

2) We only enable the subpage read support when it meets the conditions:
   <1> the chip is imx6 (or later chips) which can supports large nand page.
   <2> the size of ECC parity is byte aligned.
       If the size of ECC parity is not byte aligned, the calling of NAND_CMD_RNDOUT
       will fail.

3) What does this patch do?
   This patch will fake a virtual small page for the subpage read, and call the
   gpmi_ecc_read_page() to do the real work.

   In order to fake a virtual small page, the patch changes the BCH registers and
   the bch_geometry{}. After the subpage read finished, we will restore them back.

4) Performace:
    4.1) Tested with Toshiba TC58NVG2S0F(4096 + 224) with the following command:
         #ubiattach /dev/ubi_ctrl -m 4

       The detail information of /dev/mtd4 shows below:
       --------------------------------------------------------------
       #mtdinfo /dev/mtd4
        mtd4
        Name:                           test
        Type:                           nand
        Eraseblock size:                262144 bytes, 256.0 KiB
        Amount of eraseblocks:          1856 (486539264 bytes, 464.0 MiB)
        Minimum input/output unit size: 4096 bytes
        Sub-page size:                  4096 bytes
        OOB size:                       224 bytes
        Character device major/minor:   90:8
        Bad blocks are allowed:         true
        Device is writable:             true
       --------------------------------------------------------------

    4.2) Before this patch:
       --------------------------------------------------------------
       [   94.530495] UBI: attaching mtd4 to ubi0
       [   98.928850] UBI: scanning is finished
       [   98.953594] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
       [   98.958562] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
       [   98.964076] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
       [   98.969518] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
       [   98.975128] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
       [   98.979843] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
       [   98.985878] UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 2024916145
       [   98.993635] UBI: available PEBs: 0, total reserved PEBs: 1856, PEBs reserved for bad PEB handling: 40
       [   99.001807] UBI: background thread "ubi_bgt0d" started, PID 831
       --------------------------------------------------------------
       The attach time is about 98.9 - 94.5 = 4.4s

    4.3) After this patch:
       --------------------------------------------------------------
       [  286.464906] UBI: attaching mtd4 to ubi0
       [  289.186129] UBI: scanning is finished
       [  289.211416] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
       [  289.216360] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
       [  289.221858] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
       [  289.227293] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
       [  289.232878] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
       [  289.237628] UBI: user volume: 0, internal volumes: 1, max. volumes count: 128
       [  289.243553] UBI: max/mean erase counter: 1/1, WL threshold: 4096, image sequence number: 2024916145
       [  289.251348] UBI: available PEBs: 1812, total reserved PEBs: 44, PEBs reserved for bad PEB handling: 40
       [  289.259417] UBI: background thread "ubi_bgt0d" started, PID 847
       --------------------------------------------------------------
       The attach time is about 289.18 - 286.46 = 2.7s

     4.4) The conclusion:
       We achieve (4.4 - 2.7) / 4.4 = 38.6% faster in the ubiattach.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |   96 ++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index c92df74..2ab7a9f 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -27,6 +27,7 @@
 #include <linux/of_device.h>
 #include <linux/of_mtd.h>
 #include "gpmi-nand.h"
+#include "bch-regs.h"
 
 /* Resource names for the GPMI NAND driver. */
 #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
@@ -1087,6 +1088,90 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	return max_bitflips;
 }
 
+/* Fake a virtual small page for the subpage read */
+static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+			uint32_t offs, uint32_t len, uint8_t *buf, int page)
+{
+	struct gpmi_nand_data *this = chip->priv;
+	void __iomem *bch_regs = this->resources.bch_regs;
+	struct bch_geometry old_geo = this->bch_geometry;
+	struct bch_geometry *geo = &this->bch_geometry;
+	int size = chip->ecc.size; /* ECC chunk size */
+	int meta, n, page_size;
+	u32 r1_old, r2_old, r1_new, r2_new;
+	unsigned int max_bitflips;
+	int first, last, marker_pos;
+	int ecc_parity_size;
+	int col = 0;
+
+	/* The size of ECC parity */
+	ecc_parity_size = geo->gf_len * geo->ecc_strength / 8;
+
+	/* Align it with the chunk size */
+	first = offs / size;
+	last = (offs + len - 1) / size;
+
+	/*
+	 * Find the chunk which contains the Block Marker. If this chunk is
+	 * in the range of [first, last], we have to read out the whole page.
+	 * Why? since we had swapped the data at the position of Block Marker
+	 * to the metadata which is bound with the chunk 0.
+	 */
+	marker_pos = geo->block_mark_byte_offset / size;
+	if (last >= marker_pos && first <= marker_pos) {
+		dev_dbg(this->dev, "page:%d, first:%d, last:%d, marker at:%d\n",
+				page, first, last, marker_pos);
+		return gpmi_ecc_read_page(mtd, chip, buf, 0, page);
+	}
+
+	meta = geo->metadata_size;
+	if (first) {
+		col = meta + (size + ecc_parity_size) * first;
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);
+
+		meta = 0;
+		buf = buf + first * size;
+	}
+
+	/* Save the old environment */
+	r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
+	r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+	/* change the BCH registers and bch_geometry{} */
+	n = last - first + 1;
+	page_size = meta + (size + ecc_parity_size) * n;
+
+	r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS |
+			BM_BCH_FLASH0LAYOUT0_META_SIZE);
+	r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1)
+			| BF_BCH_FLASH0LAYOUT0_META_SIZE(meta);
+	writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0);
+
+	r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE;
+	r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size);
+	writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+	geo->ecc_chunk_count = n;
+	geo->payload_size = n * size;
+	geo->page_size = page_size;
+	geo->auxiliary_status_offset = ALIGN(meta, 4);
+
+	dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n",
+		page, offs, len, col, first, n, page_size);
+
+	/* Read the subpage now */
+	this->swap_block_mark = false;
+	max_bitflips = gpmi_ecc_read_page(mtd, chip, buf, 0, page);
+
+	/* Restore */
+	writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0);
+	writel(r2_old, bch_regs + HW_BCH_FLASH0LAYOUT1);
+	this->bch_geometry = old_geo;
+	this->swap_block_mark = true;
+
+	return max_bitflips;
+}
+
 static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required)
 {
@@ -1604,6 +1689,17 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
 	ecc->layout	= &gpmi_hw_ecclayout;
 
 	/*
+	 * We only enable the subpage read when:
+	 *  (1) the chip is imx6, and
+	 *  (2) the size of the ECC parity is byte aligned.
+	 */
+	if (GPMI_IS_MX6Q(this) &&
+		((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
+		ecc->read_subpage = gpmi_ecc_read_subpage;
+		chip->options |= NAND_SUBPAGE_READ;
+	}
+
+	/*
 	 * Can we enable the extra features? such as EDO or Sync mode.
 	 *
 	 * We do not check the return value now. That's means if we fail in
-- 
1.7.2.rc3

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

* [PATCH 0/3] mtd: gpmi: add subpage read support
  2014-01-03  3:01 ` [PATCH 0/3] mtd: gpmi: add subpage read support Huang Shijie
@ 2014-02-21  6:51   ` Huang Shijie
  2014-03-07  7:27   ` Brian Norris
  1 sibling, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-02-21  6:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 03, 2014 at 11:01:39AM +0800, Huang Shijie wrote:
> 1) Why add the subpage read support?
>   The page size of the nand chip becomes larger and larger, the imx6 has to
>   supports the 16K page or even bigger page. But sometimes, the upper layer only
>   needs a small part of the page, such as 512 bytes or less.
> 
>   For example, ubiattach may only read 64 bytes per page.
> 
> 2) We only enable the subpage read support when it meets the conditions:
>    <1> the chip is imx6 (or later chips) which can supports large nand page.
>    <2> the size of ECC parity is byte aligned.
>        If the size of ECC parity is not byte aligned, the calling of NAND_CMD_RNDOUT
>        will fail.
> 
> 3) What does this patch set do?
>    patch 1: add a new argument for read_subpage hook
>    patch 2: do not use the mtd->writesize. 
>    patch 3: This patch will fake a virtual small page for the subpage read,
>             and call the gpmi_ecc_read_page() to do the real work.
>             In order to fake a virtual small page, the patch changes
> 	    the BCH registers and the bch_geometry{}. After the subpage read
> 	    finished, we will restore them back.
> 
> 4) Performace:
>     4.1) Tested with Toshiba TC58NVG2S0F(4096 + 224) with the following command:
>          #ubiattach /dev/ubi_ctrl -m 4
> 
>        The detail information of /dev/mtd4 shows below:
>        --------------------------------------------------------------
>        #mtdinfo /dev/mtd4
>         mtd4
>         Name:                           test
>         Type:                           nand
>         Eraseblock size:                262144 bytes, 256.0 KiB
>         Amount of eraseblocks:          1856 (486539264 bytes, 464.0 MiB)
>         Minimum input/output unit size: 4096 bytes
>         Sub-page size:                  4096 bytes
>         OOB size:                       224 bytes
>         Character device major/minor:   90:8
>         Bad blocks are allowed:         true
>         Device is writable:             true
>        --------------------------------------------------------------
> 
>     4.2) Before this patch:
>        --------------------------------------------------------------
>        [   94.530495] UBI: attaching mtd4 to ubi0
>        [   98.928850] UBI: scanning is finished
>        [   98.953594] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
>        [   98.958562] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
>        [   98.964076] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
>        [   98.969518] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
>        [   98.975128] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
>        [   98.979843] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
>        [   98.985878] UBI: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 2024916145
>        [   98.993635] UBI: available PEBs: 0, total reserved PEBs: 1856, PEBs reserved for bad PEB handling: 40
>        [   99.001807] UBI: background thread "ubi_bgt0d" started, PID 831
>        --------------------------------------------------------------
>        The attach time is about 98.9 - 94.5 = 4.4s
> 
>     4.3) After this patch:
>        --------------------------------------------------------------
>        [  286.464906] UBI: attaching mtd4 to ubi0
>        [  289.186129] UBI: scanning is finished
>        [  289.211416] UBI: attached mtd4 (name "test", size 464 MiB) to ubi0
>        [  289.216360] UBI: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
>        [  289.221858] UBI: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
>        [  289.227293] UBI: VID header offset: 4096 (aligned 4096), data offset: 8192
>        [  289.232878] UBI: good PEBs: 1856, bad PEBs: 0, corrupted PEBs: 0
>        [  289.237628] UBI: user volume: 0, internal volumes: 1, max. volumes count: 128
>        [  289.243553] UBI: max/mean erase counter: 1/1, WL threshold: 4096, image sequence number: 2024916145
>        [  289.251348] UBI: available PEBs: 1812, total reserved PEBs: 44, PEBs reserved for bad PEB handling: 40
>        [  289.259417] UBI: background thread "ubi_bgt0d" started, PID 847
>        --------------------------------------------------------------
>        The attach time is about 289.18 - 286.46 = 2.7s
> 
>      4.4) The conclusion:
>        We achieve (4.4 - 2.7) / 4.4 = 38.6% faster in the ubiattach.
> 
>  5) This patch depends on the following patch:
>     http://lists.infradead.org/pipermail/linux-mtd/2013-December/051091.html
> 
> Huang Shijie (3):
>   mtd: nand: add "page" argument for read_subpage hook
>   mtd: gpmi: do not use the mtd->writesize
>   mtd: gpmi: add subpage read support
> 
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  102 +++++++++++++++++++++++++++++++-
>  drivers/mtd/nand/nand_base.c           |    7 ++-
>  include/linux/mtd/nand.h               |    2 +-
>  3 files changed, 105 insertions(+), 6 deletions(-)
> 
> -- 
> 1.7.2.rc3
> 
> 
just a ping.

Best Regards
Huang Shijie

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

* [PATCH 0/3] mtd: gpmi: add subpage read support
  2014-01-03  3:01 ` [PATCH 0/3] mtd: gpmi: add subpage read support Huang Shijie
  2014-02-21  6:51   ` Huang Shijie
@ 2014-03-07  7:27   ` Brian Norris
  2014-03-07  7:32     ` Huang Shijie
  1 sibling, 1 reply; 91+ messages in thread
From: Brian Norris @ 2014-03-07  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 03, 2014 at 11:01:39AM +0800, Huang Shijie wrote:
>  5) This patch depends on the following patch:
>     http://lists.infradead.org/pipermail/linux-mtd/2013-December/051091.html

Do you have an actual dependency? I don't spot it myself. They applied
fine to my tree, and the code is logically independent.

I'm ready to push this series (but not the linked one quite yet; let me
have a look). Shout if this is incorrect.

> Huang Shijie (3):
>   mtd: nand: add "page" argument for read_subpage hook
>   mtd: gpmi: do not use the mtd->writesize
>   mtd: gpmi: add subpage read support

Thanks,
Brian

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

* [PATCH 0/3] mtd: gpmi: add subpage read support
  2014-03-07  7:27   ` Brian Norris
@ 2014-03-07  7:32     ` Huang Shijie
  2014-03-07  7:34       ` Brian Norris
  0 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-03-07  7:32 UTC (permalink / raw)
  To: linux-arm-kernel

? 2014?03?07? 15:27, Brian Norris ??:
> Do you have an actual dependency? I don't spot it myself. They applied
> fine to my tree, and the code is logically independent.
this patch set does not have any dependency.
it's independent.

thanks
Huang Shijie

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

* [PATCH 0/3] mtd: gpmi: add subpage read support
  2014-03-07  7:32     ` Huang Shijie
@ 2014-03-07  7:34       ` Brian Norris
  0 siblings, 0 replies; 91+ messages in thread
From: Brian Norris @ 2014-03-07  7:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 07, 2014 at 03:32:07PM +0800, Huang Shijie wrote:
> ? 2014?03?07? 15:27, Brian Norris ??:
> >Do you have an actual dependency? I don't spot it myself. They applied
> >fine to my tree, and the code is logically independent.
> this patch set does not have any dependency.
> it's independent.

Thanks for the confirmation. Pushed to l2-mtd.git.

Brian

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

* [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad read support
       [not found] <a>
                   ` (13 preceding siblings ...)
  2014-01-03  3:01 ` [PATCH 3/3] mtd: gpmi: add subpage read support Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

 (0) This patch set depends on the patch:
	http://lists.infradead.org/pipermail/linux-mtd/2014-April/053308.html

  
 (1) This patch set tries to add the DDR quad read support for the SPI
     NOR framework, and it also adds the DDR quad read support for FREESCALE
     quadspi controller driver.

 (2) Test this patch set with Spansion s25fl128s, the performance with mtd_speedtest.ko:
     =================================================
     mtd_speedtest: MTD device: 0
     mtd_speedtest: not NAND flash, assume page size is 512 bytes.
     mtd_speedtest: MTD device size 16777216, eraseblock size 65536, page size 512,
                    count of eraseblocks 256, pages per eraseblock 128, OOB size 0
     mtd_speedtest: testing eraseblock write speed
     mtd_speedtest: eraseblock write speed is 665 KiB/s
     mtd_speedtest: testing eraseblock read speed
     mtd_speedtest: eraseblock read speed is 49799 KiB/s
     mtd_speedtest: testing page write speed
     mtd_speedtest: page write speed is 662 KiB/s
     mtd_speedtest: testing page read speed
     mtd_speedtest: page read speed is 24236 KiB/s
     mtd_speedtest: testing 2 page write speed
     mtd_speedtest: 2 page write speed is 657 KiB/s
     mtd_speedtest: testing 2 page read speed
     mtd_speedtest: 2 page read speed is 32637 KiB/s
     mtd_speedtest: Testing erase speed
     mtd_speedtest: erase speed is 518 KiB/s
     mtd_speedtest: Testing 2x multi-block erase speed
     mtd_speedtest: 2x multi-block erase speed is 506 KiB/s
     mtd_speedtest: Testing 4x multi-block erase speed
     mtd_speedtest: 4x multi-block erase speed is 503 KiB/s
     mtd_speedtest: Testing 8x multi-block erase speed
     mtd_speedtest: 8x multi-block erase speed is 501 KiB/s
     mtd_speedtest: Testing 16x multi-block erase speed
     mtd_speedtest: 16x multi-block erase speed is 498 KiB/s
     mtd_speedtest: Testing 32x multi-block erase speed
     mtd_speedtest: 32x multi-block erase speed is 496 KiB/s
     mtd_speedtest: Testing 64x multi-block erase speed
     mtd_speedtest: 64x multi-block erase speed is 495 KiB/s
     mtd_speedtest: finished
     =================================================

  (3) Conclusion:
     The DDR quad read could be 49799 KiB/s.
     
Changlog:
  About this patch set:
     For patch 1, please see the old discusstion:
     http://lists.infradead.org/pipermail/linux-mtd/2014-April/053370.html

     For patch 2, please see the old discusstion:
     http://lists.infradead.org/pipermail/linux-mtd/2014-April/053374.html

     
Huang Shijie (7):
  mtd: spi-nor: fix the wrong dummy value
  mtd: spi-nor: add DDR quad read support
  Documentation: mtd: add a new document for SPI NOR flash
  Documentation: fsl-quadspi: update the document
  mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT
    property
  mtd: fsl-quadspi: use the information stored in spi-nor{}
  mtd: fsl-quadspi: add the DDR quad read support

 .../devicetree/bindings/mtd/fsl-quadspi.txt        |   16 +++
 .../devicetree/bindings/mtd/spi-nor-flash.txt      |    7 +
 drivers/mtd/devices/m25p80.c                       |    5 +-
 drivers/mtd/spi-nor/fsl-quadspi.c                  |  121 +++++++++++++-------
 drivers/mtd/spi-nor/spi-nor.c                      |   52 ++++++++-
 include/linux/mtd/spi-nor.h                        |    8 +-
 6 files changed, 162 insertions(+), 47 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/spi-nor-flash.txt

-- 
1.7.2.rc3

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

* [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
       [not found] <a>
                   ` (14 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad " Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 19:41   ` Marek Vasut
  2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then 8.
The dummy cycles is actually 8 for SPI fast/dual/quad read.

This patch makes preparations for the DDR quad read, it fixes the wrong dummy
value for both the spi-nor.c and m25p80.c.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/devices/m25p80.c  |    5 ++++-
 drivers/mtd/spi-nor/spi-nor.c |    2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 1557d8f..693e25f 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -128,9 +128,12 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
 	struct spi_device *spi = flash->spi;
 	struct spi_transfer t[2];
 	struct spi_message m;
-	int dummy = nor->read_dummy;
+	unsigned int dummy = nor->read_dummy;
 	int ret;
 
+	/* convert the dummy cycles to the number of byte */
+	dummy /= 8;
+
 	/* Wait till previous write/erase is done. */
 	ret = nor->wait_till_ready(nor);
 	if (ret)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index f76f3fc..1a12f81 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -77,7 +77,7 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
 	case SPI_NOR_FAST:
 	case SPI_NOR_DUAL:
 	case SPI_NOR_QUAD:
-		return 1;
+		return 8;
 	case SPI_NOR_NORMAL:
 		return 0;
 	}
-- 
1.7.2.rc3

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

* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
       [not found] <a>
                   ` (15 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 19:45   ` Marek Vasut
  2014-04-23 10:16 ` [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash Huang Shijie
                   ` (4 subsequent siblings)
  21 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the DDR quad read support by the following:

  [1] add SPI_NOR_DDR_QUAD read mode.

  [2] add DDR Quad read opcodes:
       SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D

  [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
      Currently it only works for Spansion NOR.

  [3] set the dummy with 8 for DDR quad read.
      The m25p80.c can not support the DDR quad read, the SPI NOR controller
      can set the dummy value in its driver, such as fsl-quadspi.c.

Test this patch for Spansion s25fl128s NOR flash.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/spi-nor/spi-nor.c |   50 +++++++++++++++++++++++++++++++++++++++-
 include/linux/mtd/spi-nor.h   |    8 +++++-
 2 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1a12f81..e2f69db 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
 static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
 {
 	switch (nor->flash_read) {
+	case SPI_NOR_DDR_QUAD:
+		/*
+		 * The m25p80.c can not support the DDR quad read.
+		 * We set the dummy cycles to 8 by default. If the SPI NOR
+		 * controller driver has already set it before call the
+		 * spi_nor_scan(), we just keep it as it is.
+		 */
+		if (nor->read_dummy)
+			return nor->read_dummy;
 	case SPI_NOR_FAST:
 	case SPI_NOR_DUAL:
 	case SPI_NOR_QUAD:
@@ -402,6 +411,7 @@ struct flash_info {
 #define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
 #define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
 #define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
+#define	SPI_NOR_DDR_QUAD_READ	0x80    /* Flash supports DDR Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -846,6 +856,24 @@ static int spansion_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
+static int set_ddr_quad_mode(struct spi_nor *nor, u32 jedec_id)
+{
+	int status;
+
+	switch (JEDEC_MFR(jedec_id)) {
+	case CFI_MFR_AMD: /* Spansion, actually */
+		status = spansion_quad_enable(nor);
+		if (status) {
+			dev_err(nor->dev,
+				"Spansion DDR quad-read not enabled\n");
+			return -EINVAL;
+		}
+		return status;
+	default:
+		return -EINVAL;
+	}
+}
+
 static int set_quad_mode(struct spi_nor *nor, u32 jedec_id)
 {
 	int status;
@@ -1016,8 +1044,15 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
 	if (info->flags & SPI_NOR_NO_FR)
 		nor->flash_read = SPI_NOR_NORMAL;
 
-	/* Quad/Dual-read mode takes precedence over fast/normal */
-	if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+	/* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
+	if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
+		ret = set_ddr_quad_mode(nor, info->jedec_id);
+		if (ret) {
+			dev_err(dev, "DDR quad mode not supported\n");
+			return ret;
+		}
+		nor->flash_read = SPI_NOR_DDR_QUAD;
+	} else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
 		ret = set_quad_mode(nor, info->jedec_id);
 		if (ret) {
 			dev_err(dev, "quad mode not supported\n");
@@ -1030,6 +1065,14 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
 
 	/* Default commands */
 	switch (nor->flash_read) {
+	case SPI_NOR_DDR_QUAD:
+		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { /* Spansion */
+			nor->read_opcode = SPINOR_OP_READ_1_4_4_D;
+		} else {
+			dev_err(dev, "DDR Quad Read is not supported.\n");
+			return -EINVAL;
+		}
+		break;
 	case SPI_NOR_QUAD:
 		nor->read_opcode = SPINOR_OP_READ_1_1_4;
 		break;
@@ -1057,6 +1100,9 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
 		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
 			/* Dedicated 4-byte command set */
 			switch (nor->flash_read) {
+			case SPI_NOR_DDR_QUAD:
+				nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
+				break;
 			case SPI_NOR_QUAD:
 				nor->read_opcode = SPINOR_OP_READ4_1_1_4;
 				break;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 5324184..fea7769 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -12,10 +12,11 @@
 
 /*
  * Note on opcode nomenclature: some opcodes have a format like
- * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
+ * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y, and z stand for the number
  * of I/O lines used for the opcode, address, and data (respectively). The
  * FUNCTION has an optional suffix of '4', to represent an opcode which
- * requires a 4-byte (32-bit) address.
+ * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
+ * DDR mode.
  */
 
 /* Flash opcodes. */
@@ -26,6 +27,7 @@
 #define SPINOR_OP_READ_FAST	0x0b	/* Read data bytes (high frequency) */
 #define SPINOR_OP_READ_1_1_2	0x3b	/* Read data bytes (Dual SPI) */
 #define SPINOR_OP_READ_1_1_4	0x6b	/* Read data bytes (Quad SPI) */
+#define SPINOR_OP_READ_1_4_4_D	0xed	/* Read data bytes (DDR Quad SPI) */
 #define SPINOR_OP_PP		0x02	/* Page program (up to 256 bytes) */
 #define SPINOR_OP_BE_4K		0x20	/* Erase 4KiB block */
 #define SPINOR_OP_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -40,6 +42,7 @@
 #define SPINOR_OP_READ4_FAST	0x0c	/* Read data bytes (high frequency) */
 #define SPINOR_OP_READ4_1_1_2	0x3c	/* Read data bytes (Dual SPI) */
 #define SPINOR_OP_READ4_1_1_4	0x6c	/* Read data bytes (Quad SPI) */
+#define SPINOR_OP_READ4_1_4_4_D	0xee	/* Read data bytes (DDR Quad SPI) */
 #define SPINOR_OP_PP_4B		0x12	/* Page program (up to 256 bytes) */
 #define SPINOR_OP_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
 
@@ -74,6 +77,7 @@ enum read_mode {
 	SPI_NOR_FAST,
 	SPI_NOR_DUAL,
 	SPI_NOR_QUAD,
+	SPI_NOR_DDR_QUAD,
 };
 
 /**
-- 
1.7.2.rc3

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

* [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash
       [not found] <a>
                   ` (16 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 4/7] Documentation: fsl-quadspi: update the document Huang Shijie
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

We need a DT property to store the dummy cycles for DDR Quad read.
This is a common feature for the SPI NOR flash, such as Spansion and Micron
chips.

Add this file to describe this specific SPI NOR flash features which will
be referred by the SPI NOR flash drivers.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 .../devicetree/bindings/mtd/spi-nor-flash.txt      |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/spi-nor-flash.txt

diff --git a/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
new file mode 100644
index 0000000..aba4d54
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
@@ -0,0 +1,7 @@
+This file defines some DT properties for specific SPI NOR flash features.
+The SPI NOR controller drivers may refer to this file, such as fsl-quadspi.txt
+
+Optional properties:
+  - spi-nor,ddr-quad-read-dummy: The dummy cycles used by the DDR Quad read.
+                                 Please refer to the chip's datasheet. This
+                                 property can be 4 or 6 which is less then 8.
-- 
1.7.2.rc3

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

* [PATCH v1 4/7] Documentation: fsl-quadspi: update the document
       [not found] <a>
                   ` (17 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

The patch updates the document by adding more information to describe the
DT proporties used by the Freescale Quadspi driver and the childs nodes.

For the child node for SPI NOR flash, we add the required property
("spi-max-frequency"), and refer to spi-nor-flash.txt for the optional
properties.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 .../devicetree/bindings/mtd/fsl-quadspi.txt        |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 823d134..7e1dbaf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -1,5 +1,11 @@
 * Freescale Quad Serial Peripheral Interface(QuadSPI)
 
+The QuadSPI controller acts as the SPI master. It is described with a node
+for the controller and a set of child nodes for each SPI NOR flash.
+
+Part I - The DT node for the controller:
+------------------------------
+
 Required properties:
   - compatible : Should be "fsl,vf610-qspi"
   - reg : the first contains the register location and length,
@@ -18,6 +24,16 @@ Optional properties:
 			      bus, you should enable this property.
 			      (Please check the board's schematic.)
 
+Part II - The DT nodes for each SPI NOR flash
+------------------------------
+Required properties:
+- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
+
+Optional properties:
+  Please refer to the Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
+  If you set the "spi-nor,ddr-quad-read-dummy", it means you enable the DDR
+  quad read feature for the driver.
+
 Example:
 
 qspi0: quadspi at 40044000 {
-- 
1.7.2.rc3

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

* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
       [not found] <a>
                   ` (18 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 4/7] Documentation: fsl-quadspi: update the document Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 19:48   ` Marek Vasut
  2014-04-23 10:16 ` [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{} Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support Huang Shijie
  21 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
dummy cycles for DDR quad read.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 8d659a2..15bdeb9 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	for_each_available_child_of_node(dev->of_node, np) {
 		const struct spi_device_id *id;
 		char modalias[40];
+		u32 dummy = 0;
 
 		/* skip the holes */
 		if (!has_second_chip)
@@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		if (ret < 0)
 			goto map_failed;
 
+		/* Set the dummy cycles for the DDR Quad Read */
+		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
+				&dummy);
+		if (!ret && dummy > 0 && dummy < 8)
+			nor->read_dummy = dummy;
+
 		/* set the chip address for READID */
 		fsl_qspi_set_base_addr(q, nor);
 
-- 
1.7.2.rc3

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

* [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{}
       [not found] <a>
                   ` (19 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  2014-04-23 10:16 ` [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support Huang Shijie
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

We can get the read/write/erase opcode from the spi nor framework now.
What's more is that we can get the correct dummy cycles.

This patch uses the information stored in the spi_nor{} to remove the
hardcode in the fsl_qspi_init_lut().

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c |   57 ++++++++++++------------------------
 1 files changed, 19 insertions(+), 38 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 15bdeb9..0a2901e 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -280,8 +280,10 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 {
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	struct spi_nor *nor = &q->nor[0];
+	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
 	u32 lut_base;
-	u8 cmd, addrlen, dummy;
+	u8 op, dm;
 	int i;
 
 	fsl_qspi_unlock_lut(q);
@@ -292,40 +294,29 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 
 	/* Quad Read */
 	lut_base = SEQID_QUAD_READ * 4;
-
-	if (q->nor_size <= SZ_16M) {
-		cmd = SPINOR_OP_READ_1_1_4;
-		addrlen = ADDR24BIT;
-		dummy = 8;
-	} else {
-		/* use the 4-byte address */
-		cmd = SPINOR_OP_READ_1_1_4;
-		addrlen = ADDR32BIT;
-		dummy = 8;
+	op = nor->read_opcode;
+	dm = nor->read_dummy;
+	if (nor->flash_read == SPI_NOR_QUAD) {
+		if (op == SPINOR_OP_READ_1_1_4 || op == SPINOR_OP_READ4_1_1_4) {
+			/* read mode : 1-1-4 */
+			writel(LUT0(CMD, PAD1, op) | LUT1(ADDR, PAD1, addrlen),
+				base + QUADSPI_LUT(lut_base));
+
+			writel(LUT0(DUMMY, PAD1, dm) | LUT1(READ, PAD4, rxfifo),
+				base + QUADSPI_LUT(lut_base + 1));
+		} else {
+			dev_err(nor->dev,
+				"Unsupported cmd:%.2x\n", nor->read_opcode);
+		}
 	}
 
-	writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
 	/* Write enable */
 	lut_base = SEQID_WREN * 4;
 	writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
 
 	/* Page Program */
 	lut_base = SEQID_PP * 4;
-
-	if (q->nor_size <= SZ_16M) {
-		cmd = SPINOR_OP_PP;
-		addrlen = ADDR24BIT;
-	} else {
-		/* use the 4-byte address */
-		cmd = SPINOR_OP_PP;
-		addrlen = ADDR32BIT;
-	}
-
-	writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+	writel(LUT0(CMD, PAD1, nor->program_opcode) | LUT1(ADDR, PAD1, addrlen),
 			base + QUADSPI_LUT(lut_base));
 	writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
 
@@ -336,17 +327,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 
 	/* Erase a sector */
 	lut_base = SEQID_SE * 4;
-
-	if (q->nor_size <= SZ_16M) {
-		cmd = SPINOR_OP_SE;
-		addrlen = ADDR24BIT;
-	} else {
-		/* use the 4-byte address */
-		cmd = SPINOR_OP_SE;
-		addrlen = ADDR32BIT;
-	}
-
-	writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+	writel(LUT0(CMD, PAD1, nor->erase_opcode) | LUT1(ADDR, PAD1, addrlen),
 			base + QUADSPI_LUT(lut_base));
 
 	/* Erase the whole chip */
-- 
1.7.2.rc3

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

* [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support
       [not found] <a>
                   ` (20 preceding siblings ...)
  2014-04-23 10:16 ` [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{} Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
  21 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add the DDR quad read support for the fsl-quadspi driver.

 (1) Test this patch with imx6sx-sdb board (Spansion s25fl128s)
     The clock rate is 66MHz.

 (2) The information of NOR flash:
     -----------------------------------------------
     root at imx6qdlsolo:~# mtdinfo /dev/mtd0
     mtd0
     Name:                           21e4000.qspi
     Type:                           nor
     Eraseblock size:                65536 bytes, 64.0 KiB
     Amount of eraseblocks:          256 (16777216 bytes, 16.0 MiB)
     Minimum input/output unit size: 1 byte
     Sub-page size:                  1 byte
     Character device major/minor:   90:0
     Bad blocks are allowed:         false
     Device is writable:             true
     -----------------------------------------------

 (3) Test this patch set with UBIFS & bonnie++:
     -----------------------------------------------
	ubiattach /dev/ubi_ctrl -m 0
	ubimkvol /dev/ubi0 -N test -m
	mount -t ubifs ubi0:test tmp
	bonnie++ -d tmp -u 0 -s 10 -r 5
     -----------------------------------------------

 (4) Test this patch with mtd_speedtest.ko

     root at imx6qdlsolo:~# insmod mtd_speedtest.ko dev=0
     =================================================
     mtd_speedtest: MTD device: 0
     mtd_speedtest: not NAND flash, assume page size is 512 bytes.
     mtd_speedtest: MTD device size 16777216, eraseblock size 65536, page size 512,
                    count of eraseblocks 256, pages per eraseblock 128, OOB size 0
     mtd_speedtest: testing eraseblock write speed
     mtd_speedtest: eraseblock write speed is 665 KiB/s
     mtd_speedtest: testing eraseblock read speed
     mtd_speedtest: eraseblock read speed is 49799 KiB/s
     mtd_speedtest: testing page write speed
     mtd_speedtest: page write speed is 662 KiB/s
     mtd_speedtest: testing page read speed
     mtd_speedtest: page read speed is 24236 KiB/s
     mtd_speedtest: testing 2 page write speed
     mtd_speedtest: 2 page write speed is 657 KiB/s
     mtd_speedtest: testing 2 page read speed
     mtd_speedtest: 2 page read speed is 32637 KiB/s
     mtd_speedtest: Testing erase speed
     mtd_speedtest: erase speed is 518 KiB/s
     mtd_speedtest: Testing 2x multi-block erase speed
     mtd_speedtest: 2x multi-block erase speed is 506 KiB/s
     mtd_speedtest: Testing 4x multi-block erase speed
     mtd_speedtest: 4x multi-block erase speed is 503 KiB/s
     mtd_speedtest: Testing 8x multi-block erase speed
     mtd_speedtest: 8x multi-block erase speed is 501 KiB/s
     mtd_speedtest: Testing 16x multi-block erase speed
     mtd_speedtest: 16x multi-block erase speed is 498 KiB/s
     mtd_speedtest: Testing 32x multi-block erase speed
     mtd_speedtest: 32x multi-block erase speed is 496 KiB/s
     mtd_speedtest: Testing 64x multi-block erase speed
     mtd_speedtest: 64x multi-block erase speed is 495 KiB/s
     mtd_speedtest: finished
     =================================================

  (5) Conclusion:
     The DDR quad read could be 49799 KiB/s.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c |   59 ++++++++++++++++++++++++++++++++++--
 1 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 0a2901e..fcb963f 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -29,6 +29,9 @@
 
 /* The registers */
 #define QUADSPI_MCR			0x00
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT	29
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK	\
+				(1 << MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT)
 #define QUADSPI_MCR_RESERVED_SHIFT	16
 #define QUADSPI_MCR_RESERVED_MASK	(0xF << QUADSPI_MCR_RESERVED_SHIFT)
 #define QUADSPI_MCR_MDIS_SHIFT		14
@@ -292,7 +295,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 	for (i = 0; i < QUADSPI_LUT_NUM; i++)
 		writel(0, base + QUADSPI_LUT_BASE + i * 4);
 
-	/* Quad Read */
+	/* Quad Read and DDR Quad Read*/
 	lut_base = SEQID_QUAD_READ * 4;
 	op = nor->read_opcode;
 	dm = nor->read_dummy;
@@ -308,6 +311,24 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 			dev_err(nor->dev,
 				"Unsupported cmd:%.2x\n", nor->read_opcode);
 		}
+	} else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
+		if (op == SPINOR_OP_READ_1_4_4_D ||
+			 op == SPINOR_OP_READ4_1_4_4_D) {
+			/* read mode : 1-4-4, such as Spansion s25fl128s. */
+			writel(LUT0(CMD, PAD1, op)
+				| LUT1(ADDR_DDR, PAD4, addrlen),
+				base + QUADSPI_LUT(lut_base));
+
+			writel(LUT0(MODE_DDR, PAD1, 4) | LUT1(DUMMY, PAD1, dm),
+				base + QUADSPI_LUT(lut_base + 1));
+
+			writel(LUT0(READ_DDR, PAD4, rxfifo)
+				| LUT1(JMP_ON_CS, PAD1, 0),
+				base + QUADSPI_LUT(lut_base + 2));
+		} else {
+			dev_err(nor->dev,
+				"Unsupported cmd:%.2x\n", nor->read_opcode);
+		}
 	}
 
 	/* Write enable */
@@ -369,6 +390,9 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 {
 	switch (cmd) {
+	case SPINOR_OP_READ_1_4_4_D:
+	case SPINOR_OP_READ4_1_4_4_D:
+	case SPINOR_OP_READ4_1_1_4:
 	case SPINOR_OP_READ_1_1_4:
 		return SEQID_QUAD_READ;
 	case SPINOR_OP_WREN:
@@ -558,6 +582,8 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
 static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
 {
 	void __iomem *base = q->iobase;
+	struct spi_nor *nor = &q->nor[0];
+	u32 reg, reg2;
 	int seqid;
 
 	/* AHB configuration for access buffer 0/1/2 .*/
@@ -572,9 +598,30 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
 	writel(0, base + QUADSPI_BUF2IND);
 
 	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	seqid = fsl_qspi_get_seqid(q, nor->read_opcode);
 	writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
+
+	/* enable the DDR quad read */
+	if (nor->flash_read == SPI_NOR_DDR_QUAD) {
+		reg = readl(q->iobase + QUADSPI_MCR);
+
+		/* Firstly, disable the module */
+		writel(reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+
+		/* Set the Sampling Register for DDR */
+		reg2 = readl(q->iobase + QUADSPI_SMPR);
+		reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
+		reg2 |= (2 << QUADSPI_SMPR_DDRSMP_SHIFT);
+		writel(reg2, q->iobase + QUADSPI_SMPR);
+
+		/* Enable the module again (enable the DDR too) */
+		reg |= QUADSPI_MCR_DDR_EN_MASK;
+		if (is_imx6sx_qspi(q))
+			reg |= MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK;
+
+		writel(reg, q->iobase + QUADSPI_MCR);
+	}
 }
 
 /* We use this function to do some basic init for spi_nor_scan(). */
@@ -863,6 +910,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	/* iterate the subnodes. */
 	for_each_available_child_of_node(dev->of_node, np) {
 		const struct spi_device_id *id;
+		enum read_mode mode = SPI_NOR_QUAD;
 		char modalias[40];
 		u32 dummy = 0;
 
@@ -903,13 +951,16 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		/* Set the dummy cycles for the DDR Quad Read */
 		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
 				&dummy);
-		if (!ret && dummy > 0 && dummy < 8)
+		if (!ret && dummy > 0 && dummy < 8) {
 			nor->read_dummy = dummy;
+			mode = SPI_NOR_DDR_QUAD;
+			dev_dbg(dev, "The DDR quad read dummy is %d.\n", dummy);
+		}
 
 		/* set the chip address for READID */
 		fsl_qspi_set_base_addr(q, nor);
 
-		ret = spi_nor_scan(nor, id, SPI_NOR_QUAD);
+		ret = spi_nor_scan(nor, id, mode);
 		if (ret)
 			goto map_failed;
 
-- 
1.7.2.rc3

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

* [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
  2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
@ 2014-04-23 19:41   ` Marek Vasut
  2014-04-24  4:50     ` Huang Shijie
  0 siblings, 1 reply; 91+ messages in thread
From: Marek Vasut @ 2014-04-23 19:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, April 23, 2014 at 12:16:49 PM, Huang Shijie wrote:
> For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then 8.
> The dummy cycles is actually 8 for SPI fast/dual/quad read.
> 
> This patch makes preparations for the DDR quad read, it fixes the wrong
> dummy value for both the spi-nor.c and m25p80.c.
> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>

This patch is actually V2, right ?

> ---
>  drivers/mtd/devices/m25p80.c  |    5 ++++-
>  drivers/mtd/spi-nor/spi-nor.c |    2 +-
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 1557d8f..693e25f 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -128,9 +128,12 @@ static int m25p80_read(struct spi_nor *nor, loff_t
> from, size_t len, struct spi_device *spi = flash->spi;
>  	struct spi_transfer t[2];
>  	struct spi_message m;
> -	int dummy = nor->read_dummy;
> +	unsigned int dummy = nor->read_dummy;
>  	int ret;
> 
> +	/* convert the dummy cycles to the number of byte */

'bytes', plural ...
[...]
Best regards,
Marek Vasut

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

* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
  2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
@ 2014-04-23 19:45   ` Marek Vasut
  2014-04-24  4:53     ` Huang Shijie
  0 siblings, 1 reply; 91+ messages in thread
From: Marek Vasut @ 2014-04-23 19:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, April 23, 2014 at 12:16:50 PM, Huang Shijie wrote:
> This patch adds the DDR quad read support by the following:
> 
>   [1] add SPI_NOR_DDR_QUAD read mode.
> 
>   [2] add DDR Quad read opcodes:
>        SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
> 
>   [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
>       Currently it only works for Spansion NOR.
> 
>   [3] set the dummy with 8 for DDR quad read.
>       The m25p80.c can not support the DDR quad read, the SPI NOR
> controller can set the dummy value in its driver, such as fsl-quadspi.c.
> 
> Test this patch for Spansion s25fl128s NOR flash.
> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c |   50
> +++++++++++++++++++++++++++++++++++++++- include/linux/mtd/spi-nor.h   |  
>  8 +++++-
>  2 files changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 1a12f81..e2f69db 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
>  static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>  {
>  	switch (nor->flash_read) {
> +	case SPI_NOR_DDR_QUAD:
> +		/*
> +		 * The m25p80.c can not support the DDR quad read.
> +		 * We set the dummy cycles to 8 by default. If the SPI NOR
> +		 * controller driver has already set it before call the
> +		 * spi_nor_scan(), we just keep it as it is.
> +		 */
> +		if (nor->read_dummy)
> +			return nor->read_dummy;

Can the controller set this variable to zero ?

[...]

> +static int set_ddr_quad_mode(struct spi_nor *nor, u32 jedec_id)
> +{
> +	int status;
> +
> +	switch (JEDEC_MFR(jedec_id)) {
> +	case CFI_MFR_AMD: /* Spansion, actually */
> +		status = spansion_quad_enable(nor);
> +		if (status) {
> +			dev_err(nor->dev,
> +				"Spansion DDR quad-read not enabled\n");
> +			return -EINVAL;

Can't you just return status here as well to propagate the failure?
[...]

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

* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
  2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
@ 2014-04-23 19:48   ` Marek Vasut
  2014-04-24  4:58     ` Huang Shijie
  0 siblings, 1 reply; 91+ messages in thread
From: Marek Vasut @ 2014-04-23 19:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, April 23, 2014 at 12:16:53 PM, Huang Shijie wrote:
> Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
> dummy cycles for DDR quad read.
> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2..15bdeb9 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  	for_each_available_child_of_node(dev->of_node, np) {
>  		const struct spi_device_id *id;
>  		char modalias[40];
> +		u32 dummy = 0;
> 
>  		/* skip the holes */
>  		if (!has_second_chip)
> @@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device
> *pdev) if (ret < 0)
>  			goto map_failed;
> 
> +		/* Set the dummy cycles for the DDR Quad Read */
> +		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
> +				&dummy);
> +		if (!ret && dummy > 0 && dummy < 8)
> +			nor->read_dummy = dummy;

Is there any reason for the upper limit on number of dummy cycles ?

Best regards,
Marek Vasut

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

* [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
  2014-04-23 19:41   ` Marek Vasut
@ 2014-04-24  4:50     ` Huang Shijie
  2014-04-24 13:45       ` Marek Vasut
  0 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-24  4:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 23, 2014 at 09:41:26PM +0200, Marek Vasut wrote:
> On Wednesday, April 23, 2014 at 12:16:49 PM, Huang Shijie wrote:
> > For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then 8.
> > The dummy cycles is actually 8 for SPI fast/dual/quad read.
> > 
> > This patch makes preparations for the DDR quad read, it fixes the wrong
> > dummy value for both the spi-nor.c and m25p80.c.
> > 
> > Signed-off-by: Huang Shijie <b32955@freescale.com>
> 
> This patch is actually V2, right ?
yes.

I mentioned it in the cover letter. Since other patches are the V1.
I did not change it to v2.
> 
> > ---
> >  drivers/mtd/devices/m25p80.c  |    5 ++++-
> >  drivers/mtd/spi-nor/spi-nor.c |    2 +-
> >  2 files changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> > index 1557d8f..693e25f 100644
> > --- a/drivers/mtd/devices/m25p80.c
> > +++ b/drivers/mtd/devices/m25p80.c
> > @@ -128,9 +128,12 @@ static int m25p80_read(struct spi_nor *nor, loff_t
> > from, size_t len, struct spi_device *spi = flash->spi;
> >  	struct spi_transfer t[2];
> >  	struct spi_message m;
> > -	int dummy = nor->read_dummy;
> > +	unsigned int dummy = nor->read_dummy;
> >  	int ret;
> > 
> > +	/* convert the dummy cycles to the number of byte */
> 
> 'bytes', plural ...
I will change it in the next version.

thanks.

Huang Shijie

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

* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
  2014-04-23 19:45   ` Marek Vasut
@ 2014-04-24  4:53     ` Huang Shijie
  2014-04-24 13:43       ` Marek Vasut
  0 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-24  4:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 23, 2014 at 09:45:57PM +0200, Marek Vasut wrote:
> On Wednesday, April 23, 2014 at 12:16:50 PM, Huang Shijie wrote:
> > This patch adds the DDR quad read support by the following:
> > 
> >   [1] add SPI_NOR_DDR_QUAD read mode.
> > 
> >   [2] add DDR Quad read opcodes:
> >        SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
> > 
> >   [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
> >       Currently it only works for Spansion NOR.
> > 
> >   [3] set the dummy with 8 for DDR quad read.
> >       The m25p80.c can not support the DDR quad read, the SPI NOR
> > controller can set the dummy value in its driver, such as fsl-quadspi.c.
> > 
> > Test this patch for Spansion s25fl128s NOR flash.
> > 
> > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > ---
> >  drivers/mtd/spi-nor/spi-nor.c |   50
> > +++++++++++++++++++++++++++++++++++++++- include/linux/mtd/spi-nor.h   |  
> >  8 +++++-
> >  2 files changed, 54 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> > index 1a12f81..e2f69db 100644
> > --- a/drivers/mtd/spi-nor/spi-nor.c
> > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > @@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
> >  static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
> >  {
> >  	switch (nor->flash_read) {
> > +	case SPI_NOR_DDR_QUAD:
> > +		/*
> > +		 * The m25p80.c can not support the DDR quad read.
> > +		 * We set the dummy cycles to 8 by default. If the SPI NOR
> > +		 * controller driver has already set it before call the
> > +		 * spi_nor_scan(), we just keep it as it is.
> > +		 */
> > +		if (nor->read_dummy)
> > +			return nor->read_dummy;
> 
> Can the controller set this variable to zero ?

The default value of this variable is zero.  It it meaningless to set zero.
The DDR Quad read definitely will use a non-zero dummy.
> 
> [...]
> 
> > +static int set_ddr_quad_mode(struct spi_nor *nor, u32 jedec_id)
> > +{
> > +	int status;
> > +
> > +	switch (JEDEC_MFR(jedec_id)) {
> > +	case CFI_MFR_AMD: /* Spansion, actually */
> > +		status = spansion_quad_enable(nor);
> > +		if (status) {
> > +			dev_err(nor->dev,
> > +				"Spansion DDR quad-read not enabled\n");
> > +			return -EINVAL;
> 
> Can't you just return status here as well to propagate the failure?

ok. 

thanks
Huang Shijie

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

* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
  2014-04-23 19:48   ` Marek Vasut
@ 2014-04-24  4:58     ` Huang Shijie
  2014-04-24 13:41       ` Marek Vasut
  0 siblings, 1 reply; 91+ messages in thread
From: Huang Shijie @ 2014-04-24  4:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 23, 2014 at 09:48:50PM +0200, Marek Vasut wrote:
> On Wednesday, April 23, 2014 at 12:16:53 PM, Huang Shijie wrote:
> > Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
> > dummy cycles for DDR quad read.
> > 
> > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > ---
> >  drivers/mtd/spi-nor/fsl-quadspi.c |    7 +++++++
> >  1 files changed, 7 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> > b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2..15bdeb9 100644
> > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > @@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >  	for_each_available_child_of_node(dev->of_node, np) {
> >  		const struct spi_device_id *id;
> >  		char modalias[40];
> > +		u32 dummy = 0;
> > 
> >  		/* skip the holes */
> >  		if (!has_second_chip)
> > @@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device
> > *pdev) if (ret < 0)
> >  			goto map_failed;
> > 
> > +		/* Set the dummy cycles for the DDR Quad Read */
> > +		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
> > +				&dummy);
> > +		if (!ret && dummy > 0 && dummy < 8)
> > +			nor->read_dummy = dummy;
> 
> Is there any reason for the upper limit on number of dummy cycles ?
I actually tested two kinds of NOR flash, the Spansion s25fl128s and Micron N25q256a.
The dummy cycles are all less then 8.

but i admit the upper limit here is not proper.
I can remove it in the next version.

thanks
Huang Shijie

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

* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
  2014-04-24  4:58     ` Huang Shijie
@ 2014-04-24 13:41       ` Marek Vasut
  2014-04-24 14:27         ` Huang Shijie
  0 siblings, 1 reply; 91+ messages in thread
From: Marek Vasut @ 2014-04-24 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, April 24, 2014 at 06:58:40 AM, Huang Shijie wrote:
> On Wed, Apr 23, 2014 at 09:48:50PM +0200, Marek Vasut wrote:
> > On Wednesday, April 23, 2014 at 12:16:53 PM, Huang Shijie wrote:
> > > Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
> > > dummy cycles for DDR quad read.
> > > 
> > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > > ---
> > > 
> > >  drivers/mtd/spi-nor/fsl-quadspi.c |    7 +++++++
> > >  1 files changed, 7 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> > > b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2..15bdeb9 100644
> > > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > > @@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device
> > > *pdev)
> > > 
> > >  	for_each_available_child_of_node(dev->of_node, np) {
> > >  	
> > >  		const struct spi_device_id *id;
> > >  		char modalias[40];
> > > 
> > > +		u32 dummy = 0;
> > > 
> > >  		/* skip the holes */
> > >  		if (!has_second_chip)
> > > 
> > > @@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device
> > > *pdev) if (ret < 0)
> > > 
> > >  			goto map_failed;
> > > 
> > > +		/* Set the dummy cycles for the DDR Quad Read */
> > > +		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
> > > +				&dummy);
> > > +		if (!ret && dummy > 0 && dummy < 8)
> > > +			nor->read_dummy = dummy;
> > 
> > Is there any reason for the upper limit on number of dummy cycles ?
> 
> I actually tested two kinds of NOR flash, the Spansion s25fl128s and Micron
> N25q256a. The dummy cycles are all less then 8.

I'm all for having a limit if you can justify why number 8 is the upper limit. 
If there's no justification for it, let's remove it.

Best regards,
Marek Vasut

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

* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
  2014-04-24  4:53     ` Huang Shijie
@ 2014-04-24 13:43       ` Marek Vasut
  2014-04-24 14:26         ` Huang Shijie
  0 siblings, 1 reply; 91+ messages in thread
From: Marek Vasut @ 2014-04-24 13:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, April 24, 2014 at 06:53:34 AM, Huang Shijie wrote:
> On Wed, Apr 23, 2014 at 09:45:57PM +0200, Marek Vasut wrote:
> > On Wednesday, April 23, 2014 at 12:16:50 PM, Huang Shijie wrote:
> > > This patch adds the DDR quad read support by the following:
> > >   [1] add SPI_NOR_DDR_QUAD read mode.
> > >   
> > >   [2] add DDR Quad read opcodes:
> > >        SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
> > >   
> > >   [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
> > >   
> > >       Currently it only works for Spansion NOR.
> > >   
> > >   [3] set the dummy with 8 for DDR quad read.
> > >   
> > >       The m25p80.c can not support the DDR quad read, the SPI NOR
> > > 
> > > controller can set the dummy value in its driver, such as
> > > fsl-quadspi.c.
> > > 
> > > Test this patch for Spansion s25fl128s NOR flash.
> > > 
> > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > > ---
> > > 
> > >  drivers/mtd/spi-nor/spi-nor.c |   50
> > > 
> > > +++++++++++++++++++++++++++++++++++++++- include/linux/mtd/spi-nor.h  
> > > |
> > > 
> > >  8 +++++-
> > >  2 files changed, 54 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > b/drivers/mtd/spi-nor/spi-nor.c index 1a12f81..e2f69db 100644
> > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > @@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
> > > 
> > >  static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
> > >  {
> > >  
> > >  	switch (nor->flash_read) {
> > > 
> > > +	case SPI_NOR_DDR_QUAD:
> > > +		/*
> > > +		 * The m25p80.c can not support the DDR quad read.
> > > +		 * We set the dummy cycles to 8 by default. If the SPI NOR
> > > +		 * controller driver has already set it before call the
> > > +		 * spi_nor_scan(), we just keep it as it is.
> > > +		 */
> > > +		if (nor->read_dummy)
> > > +			return nor->read_dummy;
> > 
> > Can the controller set this variable to zero ?
> 
> The default value of this variable is zero.  It it meaningless to set zero.
> The DDR Quad read definitely will use a non-zero dummy.

Can you back this by some documentation please ?

I mean, I know I am a hardass here, but please understand I'd like to understand 
the decisions that are being made.

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

* [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
  2014-04-24  4:50     ` Huang Shijie
@ 2014-04-24 13:45       ` Marek Vasut
  0 siblings, 0 replies; 91+ messages in thread
From: Marek Vasut @ 2014-04-24 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, April 24, 2014 at 06:50:29 AM, Huang Shijie wrote:
> On Wed, Apr 23, 2014 at 09:41:26PM +0200, Marek Vasut wrote:
> > On Wednesday, April 23, 2014 at 12:16:49 PM, Huang Shijie wrote:
> > > For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then
> > > 8. The dummy cycles is actually 8 for SPI fast/dual/quad read.
> > > 
> > > This patch makes preparations for the DDR quad read, it fixes the wrong
> > > dummy value for both the spi-nor.c and m25p80.c.
> > > 
> > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > 
> > This patch is actually V2, right ?
> 
> yes.
> 
> I mentioned it in the cover letter. Since other patches are the V1.
> I did not change it to v2.

So next one is V3 ;-)

Best regards,
Marek Vasut

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

* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
  2014-04-24 13:43       ` Marek Vasut
@ 2014-04-24 14:26         ` Huang Shijie
  0 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-24 14:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 24, 2014 at 03:43:51PM +0200, Marek Vasut wrote:
> On Thursday, April 24, 2014 at 06:53:34 AM, Huang Shijie wrote:
> > On Wed, Apr 23, 2014 at 09:45:57PM +0200, Marek Vasut wrote:
> > > On Wednesday, April 23, 2014 at 12:16:50 PM, Huang Shijie wrote:
> > > > This patch adds the DDR quad read support by the following:
> > > >   [1] add SPI_NOR_DDR_QUAD read mode.
> > > >   
> > > >   [2] add DDR Quad read opcodes:
> > > >        SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
> > > >   
> > > >   [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
> > > >   
> > > >       Currently it only works for Spansion NOR.
> > > >   
> > > >   [3] set the dummy with 8 for DDR quad read.
> > > >   
> > > >       The m25p80.c can not support the DDR quad read, the SPI NOR
> > > > 
> > > > controller can set the dummy value in its driver, such as
> > > > fsl-quadspi.c.
> > > > 
> > > > Test this patch for Spansion s25fl128s NOR flash.
> > > > 
> > > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > > > ---
> > > > 
> > > >  drivers/mtd/spi-nor/spi-nor.c |   50
> > > > 
> > > > +++++++++++++++++++++++++++++++++++++++- include/linux/mtd/spi-nor.h  
> > > > |
> > > > 
> > > >  8 +++++-
> > > >  2 files changed, 54 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > > b/drivers/mtd/spi-nor/spi-nor.c index 1a12f81..e2f69db 100644
> > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > > @@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
> > > > 
> > > >  static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
> > > >  {
> > > >  
> > > >  	switch (nor->flash_read) {
> > > > 
> > > > +	case SPI_NOR_DDR_QUAD:
> > > > +		/*
> > > > +		 * The m25p80.c can not support the DDR quad read.
> > > > +		 * We set the dummy cycles to 8 by default. If the SPI NOR
> > > > +		 * controller driver has already set it before call the
> > > > +		 * spi_nor_scan(), we just keep it as it is.
> > > > +		 */
> > > > +		if (nor->read_dummy)
> > > > +			return nor->read_dummy;
> > > 
> > > Can the controller set this variable to zero ?
> > 
> > The default value of this variable is zero.  It it meaningless to set zero.
> > The DDR Quad read definitely will use a non-zero dummy.
> 
> Can you back this by some documentation please ?

I can not find a document for this. :(

But i have decided to parse out the DT node in here, not in the driver.


thanks
Huang Shijie

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

* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
  2014-04-24 13:41       ` Marek Vasut
@ 2014-04-24 14:27         ` Huang Shijie
  0 siblings, 0 replies; 91+ messages in thread
From: Huang Shijie @ 2014-04-24 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 24, 2014 at 03:41:54PM +0200, Marek Vasut wrote:
> On Thursday, April 24, 2014 at 06:58:40 AM, Huang Shijie wrote:
> > On Wed, Apr 23, 2014 at 09:48:50PM +0200, Marek Vasut wrote:
> > > On Wednesday, April 23, 2014 at 12:16:53 PM, Huang Shijie wrote:
> > > > Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
> > > > dummy cycles for DDR quad read.
> > > > 
> > > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > > > ---
> > > > 
> > > >  drivers/mtd/spi-nor/fsl-quadspi.c |    7 +++++++
> > > >  1 files changed, 7 insertions(+), 0 deletions(-)
> > > > 
> > > > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> > > > b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2..15bdeb9 100644
> > > > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > > > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > > > @@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device
> > > > *pdev)
> > > > 
> > > >  	for_each_available_child_of_node(dev->of_node, np) {
> > > >  	
> > > >  		const struct spi_device_id *id;
> > > >  		char modalias[40];
> > > > 
> > > > +		u32 dummy = 0;
> > > > 
> > > >  		/* skip the holes */
> > > >  		if (!has_second_chip)
> > > > 
> > > > @@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device
> > > > *pdev) if (ret < 0)
> > > > 
> > > >  			goto map_failed;
> > > > 
> > > > +		/* Set the dummy cycles for the DDR Quad Read */
> > > > +		ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
> > > > +				&dummy);
> > > > +		if (!ret && dummy > 0 && dummy < 8)
> > > > +			nor->read_dummy = dummy;
> > > 
> > > Is there any reason for the upper limit on number of dummy cycles ?
> > 
> > I actually tested two kinds of NOR flash, the Spansion s25fl128s and Micron
> > N25q256a. The dummy cycles are all less then 8.
> 
> I'm all for having a limit if you can justify why number 8 is the upper limit. 
> If there's no justification for it, let's remove it.
ok.

thanks
Huang Shijie

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

end of thread, other threads:[~2014-04-24 14:27 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <a>
2011-11-22 15:54 ` [PATCH v7 0/3] ARM: mxs: add recording support for saif Dong Aisheng
2011-11-24  7:36   ` Shawn Guo
2011-11-24  7:46     ` Shawn Guo
2011-11-24  7:41       ` Uwe Kleine-König
2011-11-24  7:49       ` Wolfram Sang
2011-11-24  8:23         ` Shawn Guo
2011-11-24 10:46           ` Wolfram Sang
2011-11-22 15:54 ` [PATCH v7 1/3] ARM: mxs: add saif clkmux functions Dong Aisheng
2011-11-22 15:54 ` [PATCH v7 2/3] ARM: mx28evk: add platform data for saif Dong Aisheng
2011-11-22 15:54 ` [PATCH v7 3/3] ARM: mx28evk: set a initial clock rate " Dong Aisheng
2012-03-13 12:33 ` [PATCH 1/5 v4] i2c/gpio: add DT support Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 14:08   ` Wolfram Sang
2012-03-13 16:47     ` Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 19:46       ` Wolfram Sang
2012-03-15 15:56   ` [PATCH 1/5 v5] " Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 12:33 ` [PATCH 2/5 v4] ARM: at91: sam9g20 add i2c " Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 12:33 ` [PATCH 3/5 v4] ARM: at91: usb_a9g20 add DT i2c support Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 12:33 ` [PATCH 4/5 v4] ARM: at91: sam9g45 add i2c DT support Jean-Christophe PLAGNIOL-VILLARD
2012-03-13 12:33 ` [PATCH 5/5 v4] ARM: at91: sam9x5 " Jean-Christophe PLAGNIOL-VILLARD
2013-08-13 13:31 ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 01/35] cpufreq: Implement light weight ->target_index() routine Viresh Kumar
2013-08-18 10:41     ` amit daniel kachhap
2013-08-19  4:37       ` Viresh Kumar
2013-08-19  6:16         ` amit daniel kachhap
2013-08-19  6:19           ` Viresh Kumar
2013-08-19  6:46             ` amit daniel kachhap
2013-08-19  6:49               ` Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 02/35] cpufreq: remove CONFIG_CPU_FREQ_TABLE Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 03/35] cpufreq: acpi: Covert to light weight ->target_index() routine Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 04/35] cpufreq: arm_big_little: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 05/35] cpufreq: at32ap: " Viresh Kumar
2013-08-14  8:00     ` Hans-Christian Egtvedt
2013-08-13 13:32   ` [PATCH V2 06/35] cpufreq: blackfin: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 07/35] cpufreq: cpu0: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 08/35] cpufreq: cris: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 09/35] cpufreq: davinci: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 10/35] cpufreq: dbx500: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 11/35] cpufreq: e_powersaver: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 12/35] cpufreq: elanfreq: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 13/35] cpufreq: exynos: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 14/35] cpufreq: ia64: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 15/35] cpufreq: imx6q: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 16/35] cpufreq: kirkwood: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 17/35] cpufreq: longhaul: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 18/35] cpufreq: loongson2: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 19/35] cpufreq: maple: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 20/35] cpufreq: omap: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 21/35] cpufreq: p4: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 22/35] cpufreq: pasemi: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 23/35] cpufreq: pmac32: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 24/35] cpufreq: powernow: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 25/35] cpufreq: ppc: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 26/35] cpufreq: pxa: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 27/35] cpufreq: s3c2416: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 28/35] cpufreq: s3c64xx: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 29/35] cpufreq: s5pv210: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 30/35] cpufreq: sa11x0: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 31/35] cpufreq: sc520: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 32/35] cpufreq: sparc: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 33/35] cpufreq: SPEAr: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 34/35] cpufreq: speedstep: " Viresh Kumar
2013-08-13 13:32   ` [PATCH V2 35/35] cpufreq: tegra: " Viresh Kumar
2013-08-13 13:46   ` [PATCH V2 00/35] CPUFreq: Implement light weight ->target(): for 3.13 Viresh Kumar
2013-08-14  5:29   ` Viresh Kumar
2014-01-03  3:01 ` [PATCH 0/3] mtd: gpmi: add subpage read support Huang Shijie
2014-02-21  6:51   ` Huang Shijie
2014-03-07  7:27   ` Brian Norris
2014-03-07  7:32     ` Huang Shijie
2014-03-07  7:34       ` Brian Norris
2014-01-03  3:01 ` [PATCH 1/3] mtd: nand: add "page" argument for read_subpage hook Huang Shijie
2014-01-03  3:01 ` [PATCH 2/3] mtd: gpmi: do not use the mtd->writesize Huang Shijie
2014-01-03  3:01 ` [PATCH 3/3] mtd: gpmi: add subpage read support Huang Shijie
2014-04-23 10:16 ` [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad " Huang Shijie
2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
2014-04-23 19:41   ` Marek Vasut
2014-04-24  4:50     ` Huang Shijie
2014-04-24 13:45       ` Marek Vasut
2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
2014-04-23 19:45   ` Marek Vasut
2014-04-24  4:53     ` Huang Shijie
2014-04-24 13:43       ` Marek Vasut
2014-04-24 14:26         ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash Huang Shijie
2014-04-23 10:16 ` [PATCH v1 4/7] Documentation: fsl-quadspi: update the document Huang Shijie
2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
2014-04-23 19:48   ` Marek Vasut
2014-04-24  4:58     ` Huang Shijie
2014-04-24 13:41       ` Marek Vasut
2014-04-24 14:27         ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{} Huang Shijie
2014-04-23 10:16 ` [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support Huang Shijie

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).