Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 6/8] watchdog: at91sam9_wdt: add timeout-sec property binding
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

Tested on at91sam9260 board (evk-pro3).

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Cc: Andrew Victor <linux@maxim.org.za>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 Documentation/devicetree/bindings/watchdog/atmel-wdt.txt |  4 ++++
 drivers/watchdog/Kconfig                                 |  1 +
 drivers/watchdog/at91sam9_wdt.c                          | 16 +++++++++++++---
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
index 2957ebb..fcdd48f 100644
--- a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
@@ -7,9 +7,13 @@ Required properties:
 - reg: physical base address of the controller and length of memory mapped
   region.
 
+Optional properties:
+- timeout-sec: contains the watchdog timeout in seconds.
+
 Example:
 
 	watchdog at fffffd40 {
 		compatible = "atmel,at91sam9260-wdt";
 		reg = <0xfffffd40 0x10>;
+		timeout-sec = <10>;
 	};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ad1bb93..dda695f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -114,6 +114,7 @@ config AT91RM9200_WATCHDOG
 config AT91SAM9X_WATCHDOG
 	tristate "AT91SAM9X / AT91CAP9 watchdog"
 	depends on ARCH_AT91 && !ARCH_AT91RM9200
+	select WATCHDOG_CORE
 	help
 	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
 	  reboot your system when the timeout is reached.
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index dc42e44..befa369 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -57,8 +57,10 @@
 #define WDT_TIMEOUT	(HZ/2)
 
 /* User land timeout */
+#define MIN_HEARTBEAT 1
+#define MAX_HEARTBEAT 16
 #define WDT_HEARTBEAT 15
-static int heartbeat = WDT_HEARTBEAT;
+static int heartbeat = 0;
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. "
 	"(default = " __MODULE_STRING(WDT_HEARTBEAT) ")");
@@ -255,6 +257,12 @@ static struct miscdevice at91wdt_miscdev = {
 	.fops		= &at91wdt_fops,
 };
 
+static struct watchdog_device at91wdt_wdd __initdata = {
+	.timeout = WDT_HEARTBEAT,
+	.min_timeout = MIN_HEARTBEAT,
+	.max_timeout = MAX_HEARTBEAT,
+};
+
 static int __init at91wdt_probe(struct platform_device *pdev)
 {
 	struct resource	*r;
@@ -273,6 +281,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	watchdog_init_timeout(&at91wdt_wdd, heartbeat, pdev->dev.of_node);
+
 	/* Set watchdog */
 	res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));
 	if (res)
@@ -282,12 +292,12 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 	if (res)
 		return res;
 
-	at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
+	at91wdt_private.next_heartbeat = jiffies + at91wdt_wdd.timeout * HZ;
 	setup_timer(&at91wdt_private.timer, at91_ping, 0);
 	mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
 
 	pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
-		heartbeat, nowayout);
+		at91wdt_wdd.timeout, nowayout);
 
 	return 0;
 }
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 5/8] watchdog: s3c2410_wdt: add timeout-sec property binding
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

Only compile tested.

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
---
 Documentation/devicetree/bindings/watchdog/samsung-wdt.txt | 3 +++
 drivers/watchdog/s3c2410_wdt.c                             | 6 ++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
index 79ead82..451127a 100644
--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
@@ -9,3 +9,6 @@ Required properties:
 - reg : base physical address of the controller and length of memory mapped
 	region.
 - interrupts : interrupt number to the cpu.
+
+Optional properties:
+- timeout-sec : contains the watchdog timeout in seconds.
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 9245b4d..30d18a0 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -53,7 +53,7 @@
 #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME	(15)
 
 static bool nowayout	= WATCHDOG_NOWAYOUT;
-static int tmr_margin	= CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
+static int tmr_margin	= 0;
 static int tmr_atboot	= CONFIG_S3C2410_WATCHDOG_ATBOOT;
 static int soft_noboot;
 static int debug;
@@ -226,6 +226,7 @@ static struct watchdog_ops s3c2410wdt_ops = {
 static struct watchdog_device s3c2410_wdd = {
 	.info = &s3c2410_wdt_ident,
 	.ops = &s3c2410wdt_ops,
+	.timeout = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME,
 };
 
 /* interrupt handler code */
@@ -365,7 +366,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 	/* see if we can actually set the requested timer margin, and if
 	 * not, try the default value */
 
-	if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, tmr_margin)) {
+	watchdog_init_timeout(&s3c2410_wdd, tmr_margin,  pdev->dev.of_node);
+	if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout)) {
 		started = s3c2410wdt_set_heartbeat(&s3c2410_wdd,
 					CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
 
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 4/8] watchdog: pnx4008: add timeout-sec property binding
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

Only compile tested.

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Masanari Iida <standby24x7@gmail.com>
---
 Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt | 4 ++++
 drivers/watchdog/pnx4008_wdt.c                             | 7 +++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt b/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt
index 7c7f688..556d06c 100644
--- a/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt
@@ -5,9 +5,13 @@ Required properties:
 - reg: physical base address of the controller and length of memory mapped
   region.
 
+Optional properties:
+- timeout-sec: contains the watchdog timeout in seconds.
+
 Example:
 
 	watchdog at 4003C000 {
 		compatible = "nxp,pnx4008-wdt";
 		reg = <0x4003C000 0x1000>;
+		timeout-sec = <10>;
 	};
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 87722e1..152e9fb 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -142,6 +142,7 @@ static const struct watchdog_ops pnx4008_wdt_ops = {
 static struct watchdog_device pnx4008_wdd = {
 	.info = &pnx4008_wdt_ident,
 	.ops = &pnx4008_wdt_ops,
+	.timeout = DEFAULT_HEARTBEAT,
 	.min_timeout = 1,
 	.max_timeout = MAX_HEARTBEAT,
 };
@@ -151,8 +152,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
 	struct resource *r;
 	int ret = 0;
 
-	if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
-		heartbeat = DEFAULT_HEARTBEAT;
+	watchdog_init_timeout(&pnx4008_wdd, heartbeat, pdev->dev.of_node);
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	wdt_base = devm_request_and_ioremap(&pdev->dev, r);
@@ -167,7 +167,6 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
 	if (ret)
 		goto out;
 
-	pnx4008_wdd.timeout = heartbeat;
 	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
 			WDIOF_CARDRESET : 0;
 	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
@@ -181,7 +180,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
 	}
 
 	dev_info(&pdev->dev, "PNX4008 Watchdog Timer: heartbeat %d sec\n",
-			heartbeat);
+		 pnx4008_wdd.timeout);
 
 	return 0;
 
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 3/8] watchdog: orion_wdt: add timeout-sec property binding
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

Only compile tested.

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/devicetree/bindings/watchdog/marvel.txt | 5 +++++
 drivers/watchdog/orion_wdt.c                          | 8 +++-----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt
index 0b2503a..5dc8d30 100644
--- a/Documentation/devicetree/bindings/watchdog/marvel.txt
+++ b/Documentation/devicetree/bindings/watchdog/marvel.txt
@@ -5,10 +5,15 @@ Required Properties:
 - Compatibility : "marvell,orion-wdt"
 - reg		: Address of the timer registers
 
+Optional properties:
+
+- timeout-sec	: Contains the watchdog timeout in seconds
+
 Example:
 
 	wdt at 20300 {
 		compatible = "marvell,orion-wdt";
 		reg = <0x20300 0x28>;
+		timeout-sec = <10>;
 		status = "okay";
 	};
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index c20f96b..446a3e9 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -162,12 +162,10 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
 
 	wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
 
-	if ((heartbeat < 1) || (heartbeat > wdt_max_duration))
-		heartbeat = wdt_max_duration;
-
-	orion_wdt.timeout = heartbeat;
 	orion_wdt.min_timeout = 1;
+	orion_wdt.timeout = wdt_max_duration;
 	orion_wdt.max_timeout = wdt_max_duration;
+	watchdog_init_timeout(&orion_wdt, heartbeat, pdev->dev.of_node);
 
 	watchdog_set_nowayout(&orion_wdt, nowayout);
 	ret = watchdog_register_device(&orion_wdt);
@@ -177,7 +175,7 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
 	}
 
 	pr_info("Initial timeout %d sec%s\n",
-		heartbeat, nowayout ? ", nowayout" : "");
+		orion_wdt.timeout, nowayout ? ", nowayout" : "");
 	return 0;
 }
 
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 2/8] watchdog: core: dt: add support for the timeout-sec dt property
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
---
 Documentation/watchdog/watchdog-kernel-api.txt | 10 +++++++
 drivers/watchdog/watchdog_core.c               | 37 ++++++++++++++++++++++++++
 include/linux/watchdog.h                       |  3 +++
 3 files changed, 50 insertions(+)

diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 086638f..44098c2 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -212,3 +212,13 @@ driver specific data to and a pointer to the data itself.
 The watchdog_get_drvdata function allows you to retrieve driver specific data.
 The argument of this function is the watchdog device where you want to retrieve
 data from. The function returns the pointer to the driver specific data.
+
+To initialize the timeout field use the following function:
+
+extern void watchdog_init_timeout(struct watchdog_device *wdd,
+                                  unsigned int parm_timeout,
+                                  struct device_node *node);
+
+The watchdog_init_timeout function allows you to initialize the timeout field
+using the module timeout parameter or retrieving the timeout-sec property from
+the device tree.
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 3796434..37dde68 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -36,12 +36,49 @@
 #include <linux/init.h>		/* For __init/__exit/... */
 #include <linux/idr.h>		/* For ida_* macros */
 #include <linux/err.h>		/* For IS_ERR macros */
+#include <linux/of.h>		/* For of_get_timeout_sec */
 
 #include "watchdog_core.h"	/* For watchdog_dev_register/... */
 
 static DEFINE_IDA(watchdog_ida);
 static struct class *watchdog_class;
 
+static bool watchdog_is_valid_timeout(struct watchdog_device *wdd,
+				      unsigned int t)
+
+{
+	if (wdd->min_timeout < wdd->max_timeout)
+		return (wdd->min_timeout <= t) && (t <= wdd->max_timeout);
+	else
+		return (t > 0);
+}
+
+/**
+ * watchdog_init_timeout() - initialize the timeout field
+ * @parm: timeout module parameter, it takes precedence over the
+ *        timeout-sec property.
+ * @node: Retrieve the timeout-sec property only if the parm_timeout
+ *        is out of bounds.
+ */
+void watchdog_init_timeout(struct watchdog_device *wdd, unsigned int parm,
+			   struct device_node *node)
+{
+	unsigned int t = 0;
+
+	if (watchdog_is_valid_timeout(wdd, parm)) {
+		wdd->timeout = parm;
+		return;
+	}
+
+	/* try to get the timeout_sec property */
+	if (!node)
+		return;
+	of_get_timeout_sec(node, &t);
+	if (watchdog_is_valid_timeout(wdd, t))
+		wdd->timeout = t;
+}
+EXPORT_SYMBOL_GPL(watchdog_init_timeout);
+
 /**
  * watchdog_register_device() - register a watchdog device
  * @wdd: watchdog device
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index da70f0f..b8eec8d 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -175,6 +175,9 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
 }
 
 /* drivers/watchdog/core/watchdog_core.c */
+extern void watchdog_init_timeout(struct watchdog_device *wdd,
+				  unsigned int parm_timeout,
+				  struct device_node *node);
 extern int watchdog_register_device(struct watchdog_device *);
 extern void watchdog_unregister_device(struct watchdog_device *);
 
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 1/8] dt: add helper inline for retrieving timeout-sec property
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349784251-28261-1-git-send-email-fabio.porcedda@gmail.com>

The first user of this function is the watchdog framework.

Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
---
 include/linux/of.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 72843b7..5870818 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -470,4 +470,15 @@ static inline int of_property_read_u32(const struct device_node *np,
 	return of_property_read_u32_array(np, propname, out_value, 1);
 }
 
+/**
+ * of_get_timeout_sec() - Helper to read the timeout_sec property
+ * @np:		device node from which the property value is to be read.
+ * @timeout:	adress of the output value
+ */
+static inline int of_get_timeout_sec(const struct device_node *np,
+				     u32 *timeout)
+{
+	return of_property_read_u32(np, "timeout-sec", timeout);
+}
+
 #endif /* _LINUX_OF_H */
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v4 0/8] watchdog: dt: add support for the timeout-sec dt property
From: Fabio Porcedda @ 2012-10-09 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,
this patchset add the timeout-sec property to the watchdog core,
to the at91sam9_wdt driver and on all framework enabled watchdog driver
with dt support.
This patchset depends on the patchset already sent:
"[PATCH v8 0/3] watchdog: at91sam9_wdt: add device tree support"

The at91sam9_wdt is tested on evk-pr3,
the other drivers are compile tested only.


changes:
v4:
  - add of_get_timeout_sec
  - add s3c2410_wdt driver
  - split driver patch
  - fixed watchdog_init_timeout handling of min_timeout and max_timeout
v3:
  - rename watchdog_probe_dt_timeout ->  watchdog_init_timeout
  - move the watchdog_init_timeout function from inline to watchdog_core.c
  - add timeout parameter handling code to watchdog_init_timeout
  - add timeout-sec property to the pnx4008-wdt driver
  - add two small commit for fixup and cleanup
v2:
  - change "timeout" to "timeout-sec" as asked by Jean-Christophe
  - at91sam9_wdt: use the new helper function
  - at91sam9_wdt: add bounds checking
  - watchdog.h: add bounds checking


Fabio Porcedda (8):
  dt: add helper inline for retrieving timeout-sec property
  watchdog: core: dt: add support for the timeout-sec dt property
  watchdog: orion_wdt: add timeout-sec property binding
  watchdog: pnx4008: add timeout-sec property binding
  watchdog: s3c2410_wdt: add timeout-sec property binding
  watchdog: at91sam9_wdt: add timeout-sec property binding
  watchdog: orion_wdt: move the min_timeout initialization
  watchdog: WatchDog Timer Driver Core - fix comment

 .../devicetree/bindings/watchdog/atmel-wdt.txt     |  4 +++
 .../devicetree/bindings/watchdog/marvel.txt        |  5 +++
 .../devicetree/bindings/watchdog/pnx4008-wdt.txt   |  4 +++
 .../devicetree/bindings/watchdog/samsung-wdt.txt   |  3 ++
 Documentation/watchdog/watchdog-kernel-api.txt     | 10 ++++++
 drivers/watchdog/Kconfig                           |  1 +
 drivers/watchdog/at91sam9_wdt.c                    | 16 ++++++++--
 drivers/watchdog/orion_wdt.c                       | 10 +++---
 drivers/watchdog/pnx4008_wdt.c                     |  7 ++--
 drivers/watchdog/s3c2410_wdt.c                     |  6 ++--
 drivers/watchdog/watchdog_core.c                   | 37 ++++++++++++++++++++++
 include/linux/of.h                                 | 11 +++++++
 include/linux/watchdog.h                           |  5 ++-
 13 files changed, 103 insertions(+), 16 deletions(-)

-- 
1.7.11.3

^ permalink raw reply

* [PATCH 05/11] fsmc: Implement ready/busy through gpio pin
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-09 11:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> The NAND devices have a ready/busy (active low) output which is connected to the
> FSMC controller FSMC_RnB pin
> 
> The CPU can work in following two ways
> * CPU keeps waiting for a ready response and it halts until it receives a ready
>   response from NAND device. This halts the ldr instruction in between and in
>   effect holds the CPU down for a number of cycles. During this period, CPU
>   can't even service interrupts. This behavior is enabled via WAIT_ON bit of
>   FSMC controller
> * CPU merely issues the command and does not wait for response. The NAND device
>   is later probed for being ready by reading the NAND_RnB signal
> 
> Until now, WAIT_ON was enabled by default. This patch implements reading the
> device ready state through a gpio. The gpio number is passed via DT and this
> patch also adds a corresponding binding for fsmc
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |  5 ++
>  drivers/mtd/nand/fsmc_nand.c                       | 54 +++++++++++++++++++---
>  include/linux/mtd/fsmc.h                           | 11 +++++
>  3 files changed, 64 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 6a7fc43..598bca2 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -25,6 +25,11 @@ Optional properties:
>    period of hclk ie a number 4 in thold with hclk = 166MHz means that
>    thold = (1000 / 166) * 4 ns = 24.09ns
>  
> +- st,ready-busy: Should contain either of "rb-gpio" or "rb-wait". When
> +  this property is not defined, the default is to use rb-wait.
> +- st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
> +  pin number is defined in this property
> +
>  Example:
>  
>  	fsmc: flash at d1800000 {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index f3d69b3..eaffd3b 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -22,6 +22,7 @@
>  #include <linux/dma-direction.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/err.h>
> +#include <linux/gpio.h>
>  #include <linux/init.h>
>  #include <linux/module.h>
>  #include <linux/resource.h>
> @@ -32,6 +33,7 @@
>  #include <linux/mtd/nand_ecc.h>
>  #include <linux/platform_device.h>
>  #include <linux/of.h>
> +#include <linux/of_gpio.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> @@ -289,6 +291,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   * @write_dma_chan:	DMA channel for write access to NAND
>   * @dma_access_complete: Completion structure
>   *
> + * @rb_pin:		Ready/Busy data
>   * @dev_timings:	Timings to be programmed in controller
>   * @partitions:		Partition info for a NAND Flash
>   * @nr_partitions:	Total number of partition of a NAND flash
> @@ -322,6 +325,7 @@ struct fsmc_nand_data {
>  	struct completion	dma_access_complete;
>  
>  	/* Recieved from plat data */
> +	struct fsmc_rbpin	*rbpin;
>  	struct fsmc_nand_timings *dev_timings;
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
> @@ -410,12 +414,16 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
>   * This routine initializes timing parameters related to NAND memory access in
>   * FSMC registers
>   */
> -static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
> -			   uint32_t busw, struct fsmc_nand_timings *timings)
> +static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, uint32_t busw,
> +			   struct fsmc_nand_timings *timings,
> +			   struct fsmc_rbpin *rbpin)
>  {
> -	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
> +	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE;
>  	uint32_t tclr, tar, thiz, thold, twait, tset;
>  
> +	if (!rbpin || (rbpin->use_pin == FSMC_RB_WAIT))
> +		value |= FSMC_WAITON;
> +
>  	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
>  	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
>  	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> @@ -857,6 +865,14 @@ static bool filter(struct dma_chan *chan, void *slave)
>  	return true;
>  }
>  
> +static int fsmc_dev_ready(struct mtd_info *mtd)
> +{
> +	struct fsmc_nand_data *host = container_of(mtd,
> +					struct fsmc_nand_data, mtd);
> +
> +	return !!gpio_get_value(host->rbpin->gpio_pin);
> +}
> +
>  #ifdef CONFIG_OF
>  static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  					       struct device_node *np)
> @@ -870,7 +886,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  		.twait	= FSMC_TWAIT_6,
>  		.tset	= FSMC_TSET_0,
>  	};
> +	const char *rb;
>  	u32 val;
> +	enum of_gpio_flags flags;
>  
>  	/* Set default NAND width to 8 bits */
>  	pdata->width = 8;
> @@ -911,6 +929,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  				sizeof(default_timings));
>  	}
>  
> +	if (!of_property_read_string(np, "st,ready-busy", &rb) &&
> +			!strcmp(rb, "rb-gpio")) {
> +		pdata->rbpin.use_pin = FSMC_RB_GPIO;
> +		pdata->rbpin.gpio_pin =
> +			of_get_named_gpio_flags(np, "st,rb-gpios", 0, &flags);
> +	} else
> +		pdata->rbpin.use_pin = FSMC_RB_WAIT;
> +
>  	return 0;
>  }
>  #else
> @@ -1049,6 +1075,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
>  	host->dev_timings = &pdata->nand_timings;
> +	host->rbpin = &pdata->rbpin;
> +
>  	host->mode = pdata->mode;
>  	host->max_banks = pdata->max_banks;
>  
> @@ -1074,6 +1102,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	nand->select_chip = fsmc_select_chip;
>  	nand->badblockbits = 7;
>  
> +	if (host->rbpin->use_pin != FSMC_RB_WAIT)
> +		nand->dev_ready = fsmc_dev_ready;
> +
> +	if (host->rbpin->use_pin == FSMC_RB_GPIO) {
> +		ret = gpio_request(host->rbpin->gpio_pin, "fsmc-rb");
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "gpio request fail: %d\n",
> +					host->rbpin->gpio_pin);
> +			goto err_gpio_req;
> +		}
> +	}
> +
>  	if (pdata->width == FSMC_NAND_BW16)
>  		nand->options |= NAND_BUSWIDTH_16;
>  
> @@ -1107,7 +1147,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	for (bank = 0; bank < host->max_banks; bank++)
>  		fsmc_nand_setup(host->regs_va, bank,
>  				nand->options & NAND_BUSWIDTH_16,
> -				host->dev_timings);
> +				host->dev_timings, host->rbpin);
>  
>  	if (AMBA_REV_BITS(host->pid) >= 8) {
>  		nand->ecc.read_page = fsmc_read_page_hwecc;
> @@ -1211,6 +1251,9 @@ err_req_write_chnl:
>  	if (host->mode == USE_DMA_ACCESS)
>  		dma_release_channel(host->read_dma_chan);
>  err_req_read_chnl:
> +	if (host->rbpin->use_pin == FSMC_RB_GPIO)
> +		gpio_free(host->rbpin->gpio_pin);
> +err_gpio_req:
>  	clk_disable_unprepare(host->clk);
>  err_clk_prepare_enable:
>  	clk_put(host->clk);
> @@ -1260,8 +1303,7 @@ static int fsmc_nand_resume(struct device *dev)
>  		for (bank = 0; bank < host->max_banks; bank++)
>  			fsmc_nand_setup(host->regs_va, bank,
>  					host->nand.options & NAND_BUSWIDTH_16,
> -					host->dev_timings);
> -
> +					host->dev_timings, host->rbpin);
>  	}
>  	return 0;
>  }
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index 4fbdce4..eed22a1 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -130,6 +130,16 @@ struct fsmc_nand_timings {
>  	uint8_t tset;
>  };
>  
> +enum rbpin {
> +	FSMC_RB_WAIT = 0,
> +	FSMC_RB_GPIO,
> +};
> +
> +struct fsmc_rbpin {
> +	enum rbpin	use_pin;
> +	uint32_t	gpio_pin;
> +};
> +
>  enum access_mode {
>  	USE_DMA_ACCESS = 1,
>  	USE_WORD_ACCESS,
> @@ -149,6 +159,7 @@ enum access_mode {
>   */
>  struct fsmc_nand_platform_data {
>  	struct fsmc_nand_timings nand_timings;
> +	struct fsmc_rbpin	rbpin;
do more simple
	int 			rbpin;

	and set it as -EINVAL to use RB_WAIT

so in the binding if you do not specifcy a gpio or a valid one we switch to
wait

Best Regards,
J.

^ permalink raw reply

* [PATCH v4 1/3] Input: egalax_ts: get gpio from devicetree node
From: Arnd Bergmann @ 2012-10-09 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20120817003125.GA24242@S2101-09.ap.freescale.net>

On Friday 17 August 2012, Shawn Guo wrote:
> On Thu, Aug 16, 2012 at 06:47:29PM +0800, Hui Wang wrote:
> > The irq_to_gpio() is old, most platforms use GENERIC_GPIO framework
> > and don't support this API anymore.
> > 
> > The i.MX6q sabrelite platform equips an egalax touchscreen controller,
> > and this platform already transfered to GENERIC_GPIO framework, to
> > support this driver, we use a more generic way to get gpio.
> > 
> > Add a return value checking for waking up the controller in the probe
> > function, this guarantee only a workable device can pass init.
> > 
> > Signed-off-by: Hui Wang <jason77.wang@gmail.com>
> 
> Reviewed-by: Shawn Guo <shawn.guo@linaro.org>

What's the status on this patch? I'm still getting build errors from this
driver, so I guess it was never accepted for the 3.7 merge window.

	Arnd

^ permalink raw reply

* [PATCH 04/11] fsmc/nand: Accept nand timing parameters via DT
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-09 11:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Add support to accept nand timing parameters via device tree
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          | 20 ++++++++
>  drivers/mtd/nand/fsmc_nand.c                       | 59 ++++++++++++++--------
>  include/linux/mtd/fsmc.h                           |  2 +-
>  3 files changed, 59 insertions(+), 22 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 29d1a2f..6a7fc43 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -13,6 +13,18 @@ Optional properties:
>    defaults to 1 byte
>  - nand-skip-bbtscan: Indicates the the BBT scanning should be skipped
>  
> +- nand-timings-enabled: Indicates if the timing parameters are passed
> +  via DT
> +- nand-timings,tclr:
> +- nand-timings,tar:
> +- nand-timings,thiz:
> +- nand-timings,thold:
> +- nand-timings,twait:
> +- nand-timings,tset: All these timing parameters come from the actual
> +  nand device specification. Each of this represents a number of time
> +  period of hclk ie a number 4 in thold with hclk = 166MHz means that
> +  thold = (1000 / 166) * 4 ns = 24.09ns
> +
>  Example:
>  
>  	fsmc: flash at d1800000 {
> @@ -26,6 +38,14 @@ Example:
>  		st,cle-off = <0x10000>;
>  		maxbanks = <1>;
>  
> +		nand-timings-enabled;
> +		nand-timings,tclr = <1>;
> +		nand-timings,tar = <1>;
> +		nand-timings,thiz = <1>;
> +		nand-timings,thold = <4>;
> +		nand-timings,twait = <6>;
> +		nand-timings,tset = <0>;
> +
>  		bank-width = <1>;
>  		nand-skip-bbtscan;
>  
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index fc6a044..f3d69b3 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -415,27 +415,13 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
>  {
>  	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
>  	uint32_t tclr, tar, thiz, thold, twait, tset;
> -	struct fsmc_nand_timings *tims;
> -	struct fsmc_nand_timings default_timings = {
> -		.tclr	= FSMC_TCLR_1,
> -		.tar	= FSMC_TAR_1,
> -		.thiz	= FSMC_THIZ_1,
> -		.thold	= FSMC_THOLD_4,
> -		.twait	= FSMC_TWAIT_6,
> -		.tset	= FSMC_TSET_0,
> -	};
> -
> -	if (timings)
> -		tims = timings;
> -	else
> -		tims = &default_timings;
>  
> -	tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
> -	tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
> -	thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> -	thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
> -	twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
> -	tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
> +	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
> +	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
> +	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> +	thold = (timings->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
> +	twait = (timings->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
> +	tset = (timings->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
>  
>  	if (busw)
>  		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
> @@ -876,6 +862,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  					       struct device_node *np)
>  {
>  	struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	struct fsmc_nand_timings default_timings = {
> +		.tclr	= FSMC_TCLR_1,
> +		.tar	= FSMC_TAR_1,
> +		.thiz	= FSMC_THIZ_1,
> +		.thold	= FSMC_THOLD_4,
> +		.twait	= FSMC_TWAIT_6,
> +		.tset	= FSMC_TSET_0,
> +	};
>  	u32 val;
>  
>  	/* Set default NAND width to 8 bits */
> @@ -894,6 +888,29 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  		pdata->options = NAND_SKIP_BBTSCAN;
>  	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
>  
> +	if (of_property_read_bool(np, "nand-timings-enabled")) {
> +		of_property_read_u32(np, "nand-timings,tclr", &val);
> +		pdata->nand_timings.tclr = (uint8_t)val;
use a mask will be better
> +
> +		of_property_read_u32(np, "nand-timings,tar", &val);
> +		pdata->nand_timings.tar = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,thiz", &val);
> +		pdata->nand_timings.thiz = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,thold", &val);
> +		pdata->nand_timings.thold = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,twait", &val);
> +		pdata->nand_timings.twait = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,tset", &val);
> +		pdata->nand_timings.tset = (uint8_t)val;
> +	} else {
> +		memcpy(&pdata->nand_timings, &default_timings,
> +				sizeof(default_timings));
> +	}
> +
>  	return 0;
>  }
>  #else
> @@ -1031,7 +1048,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	host->partitions = pdata->partitions;
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
> -	host->dev_timings = pdata->nand_timings;
> +	host->dev_timings = &pdata->nand_timings;
>  	host->mode = pdata->mode;
>  	host->max_banks = pdata->max_banks;
>  
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index f0ab734..4fbdce4 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -148,7 +148,7 @@ enum access_mode {
>   * this may be set to NULL
>   */
>  struct fsmc_nand_platform_data {
> -	struct fsmc_nand_timings *nand_timings;
> +	struct fsmc_nand_timings nand_timings;
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
>  	unsigned int		options;
> -- 
> 1.7.11.4
> 

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Domenico Andreoli @ 2012-10-09 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50739541.2030603@wwwdotorg.org>

On Mon, Oct 08, 2012 at 09:08:49PM -0600, Stephen Warren wrote:
> On 10/06/2012 07:53 PM, Domenico Andreoli wrote:
> > BCM476x's minimal infrastructure, Kernel's great reuse.
> 
> > Index: b/arch/arm/configs/bcm476x_defconfig
> 
> > +CONFIG_DEBUG_BCM476X_UART2=y
> > +CONFIG_DEBUG_LL_INCLUDE="debug/bcm476x.S"
> > +CONFIG_UNCOMPRESS_INCLUDE="debug/bcm476x-uncompress.h"
> 
> Was this defconfig file created by "make savedefconfig ; mv defconfig
> arch/arm/configs/bcm476x_defconfig"? If you do that, I think those last
> two lines I quoted above (and many more) will be removed, since those
> values are selected by CONFIG_DEBUG_BCM476X_UART2.

Yep, knew I was a 'make help' away from this. Will fix.

Dome

^ permalink raw reply

* [PATCH 03/11] fsmc/nand: Support multiple banks connected to controller
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-09 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Support up to max_banks number of banks in fsmc driver.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
please rebase this over my patch that drop -off to resource
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |  2 ++
>  arch/arm/boot/dts/spear300.dtsi                    |  1 +
>  arch/arm/boot/dts/spear310.dtsi                    |  1 +
>  arch/arm/boot/dts/spear320.dtsi                    |  1 +
>  arch/arm/boot/dts/spear600.dtsi                    |  1 +
>  arch/arm/mach-u300/core.c                          |  1 +
>  drivers/mtd/nand/fsmc_nand.c                       | 26 +++++++++++++++-------
>  include/linux/mtd/fsmc.h                           |  2 +-
>  8 files changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index e2c663b..29d1a2f 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -6,6 +6,7 @@ Required properties:
>  - reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
>  - st,ale-off : Chip specific offset to ALE
>  - st,cle-off : Chip specific offset to CLE
> +- maxbanks: Number of banks supported by SoC
make it optionnal will simplify the binding with 1 by default and will allow
to avoid issue

>  
>  Optional properties:
>  - bank-width : Width (in bytes) of the device.  If not present, the width
> @@ -23,6 +24,7 @@ Example:
>  		reg-names = "fsmc_regs", "nand_data";
>  		st,ale-off = <0x20000>;
>  		st,cle-off = <0x10000>;
> +		maxbanks = <1>;
>  
>  		bank-width = <1>;
>  		nand-skip-bbtscan;
> diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
> index ed3627c..19e2328 100644
> --- a/arch/arm/boot/dts/spear300.dtsi
> +++ b/arch/arm/boot/dts/spear300.dtsi
> @@ -42,6 +42,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
> index 62fc4fb..0272afb3 100644
> --- a/arch/arm/boot/dts/spear310.dtsi
> +++ b/arch/arm/boot/dts/spear310.dtsi
> @@ -36,6 +36,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x10000>;
>  			st,cle-off = <0x20000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
> index 1f49d69..69fe50d 100644
> --- a/arch/arm/boot/dts/spear320.dtsi
> +++ b/arch/arm/boot/dts/spear320.dtsi
> @@ -42,6 +42,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
> index a3c36e4..6ed57c8 100644
> --- a/arch/arm/boot/dts/spear600.dtsi
> +++ b/arch/arm/boot/dts/spear600.dtsi
> @@ -71,6 +71,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
> index 03acf18..5ea9f71 100644
> --- a/arch/arm/mach-u300/core.c
> +++ b/arch/arm/mach-u300/core.c
> @@ -1546,6 +1546,7 @@ static struct fsmc_nand_platform_data nand_platform_data = {
>  	.width = FSMC_NAND_BW8,
>  	.ale_off = PLAT_NAND_ALE,
>  	.cle_off = PLAT_NAND_CLE,
> +	.max_banks = 1,
>  };
>  
>  static struct platform_device nand_device = {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index bd89580..fc6a044 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -298,6 +298,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   *			- Word access (CPU)
>   *			- None (Use driver default ie bus width specific
>   *			  CPU access)
> + * @max_banks:		Maximum number of banks supported
>   * @select_chip:	Select a particular bank
>   *
>   * @data_pa:		NAND Physical port for Data
> @@ -325,6 +326,7 @@ struct fsmc_nand_data {
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
>  	enum access_mode	mode;
> +	uint32_t		max_banks;
>  	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  
>  	/* Virtual/Physical addresses for CPU/DMA access */
> @@ -343,6 +345,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
>  
>  	host = container_of(mtd, struct fsmc_nand_data, mtd);
>  
> +	host->bank = chipnr;
>  	switch (chipnr) {
>  	case -1:
>  		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
> @@ -889,6 +892,7 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  	of_property_read_u32(np, "st,cle-off", &pdata->cle_off);
>  	if (of_get_property(np, "nand-skip-bbtscan", NULL))
>  		pdata->options = NAND_SKIP_BBTSCAN;
> +	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
>  
>  	return 0;
>  }
> @@ -915,7 +919,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	dma_cap_mask_t mask;
>  	int ret = 0;
> -	u32 pid;
> +	u32 pid, bank;
>  	int i;
>  
>  	if (np) {
> @@ -1023,13 +1027,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
>  		 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
>  
> -	host->bank = pdata->bank;
>  	host->select_chip = pdata->select_bank;
>  	host->partitions = pdata->partitions;
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
>  	host->dev_timings = pdata->nand_timings;
>  	host->mode = pdata->mode;
> +	host->max_banks = pdata->max_banks;
>  
>  	if (host->mode == USE_DMA_ACCESS)
>  		init_completion(&host->dma_access_complete);
> @@ -1083,9 +1087,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		break;
>  	}
>  
> -	fsmc_nand_setup(host->regs_va, host->bank,
> -			nand->options & NAND_BUSWIDTH_16,
> -			host->dev_timings);
> +	for (bank = 0; bank < host->max_banks; bank++)
> +		fsmc_nand_setup(host->regs_va, bank,
> +				nand->options & NAND_BUSWIDTH_16,
> +				host->dev_timings);
>  
>  	if (AMBA_REV_BITS(host->pid) >= 8) {
>  		nand->ecc.read_page = fsmc_read_page_hwecc;
> @@ -1230,11 +1235,16 @@ static int fsmc_nand_suspend(struct device *dev)
>  static int fsmc_nand_resume(struct device *dev)
>  {
>  	struct fsmc_nand_data *host = dev_get_drvdata(dev);
> +	uint32_t bank;
> +
>  	if (host) {
>  		clk_prepare_enable(host->clk);
> -		fsmc_nand_setup(host->regs_va, host->bank,
> -				host->nand.options & NAND_BUSWIDTH_16,
> -				host->dev_timings);
> +
> +		for (bank = 0; bank < host->max_banks; bank++)
> +			fsmc_nand_setup(host->regs_va, bank,
> +					host->nand.options & NAND_BUSWIDTH_16,
> +					host->dev_timings);
> +
>  	}
>  	return 0;
>  }
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index b200292..f0ab734 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -153,7 +153,7 @@ struct fsmc_nand_platform_data {
>  	unsigned int		nr_partitions;
>  	unsigned int		options;
>  	unsigned int		width;
> -	unsigned int		bank;
> +	unsigned int		max_banks;
>  
>  	/* CLE, ALE offsets */
>  	unsigned int		cle_off;
> -- 
> 1.7.11.4
> 

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Domenico Andreoli @ 2012-10-09 11:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50739074.8000001@wwwdotorg.org>

On Mon, Oct 08, 2012 at 08:48:20PM -0600, Stephen Warren wrote:
> On 10/06/2012 07:53 PM, Domenico Andreoli wrote:
> > BCM476x's minimal infrastructure, Kernel's great reuse.
> 
> > Index: b/arch/arm/boot/dts/bcm476x.dtsi
> 
> > +	chosen {
> > +		bootargs = "earlyprintk";
> > +	};
> 
> > Index: b/arch/arm/configs/bcm476x_defconfig
> 
> > +CONFIG_CMDLINE="root=/dev/mmcblk0p2 ro console=ttyAMA1,115200 rootwait init=/bin/bash"
> > +CONFIG_CMDLINE_FROM_BOOTLOADER=y
> 
> I'm not sure you need to specify a default command-line in both those
> places. I would be inclined to leave out the root= option as well; it's
> pretty specific to however the user's SD card was partitioned, so there
> could be quite some variation there I think? Oh, especially since I
> think you said there was no SD driver yet anyway?

Right, I'll drop both. Thanks.

Dome

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Domenico Andreoli @ 2012-10-09 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121008141455.324f914b@skate>

On Mon, Oct 08, 2012 at 02:14:55PM +0200, Thomas Petazzoni wrote:
> 
> On Sun, 07 Oct 2012 03:53:01 +0200, Domenico Andreoli wrote:
> 
> > Index: b/arch/arm/mach-bcm476x/Makefile.boot
> > ===================================================================
> > --- /dev/null
> > +++ b/arch/arm/mach-bcm476x/Makefile.boot
> > @@ -0,0 +1,5 @@
> > +   zreladdr-y := 0x00008000
> > +params_phys-y := 0x00000100
> > +initrd_phys-y := 0x00800000
> 
> Those params_phys-y and initrd_phys-y lines as useless as you're using
> the Device Tree.
> 
> > +#define BCM476X_PERIPH_PHYS   0x00080000
> > +#define BCM476X_PERIPH_VIRT   0xd0080000
> 
> This one should be defined with IOMEM(). Yes, you will have to add a
> cast to make it play nicely with map_desc.virtual.

Will address both of them. Thank you Thomas.

Regards,
Domenico

^ permalink raw reply

* [PATCH 02/11] fsmc/nand: Rearrange the fsmc_nand_data structure and update comments
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-09 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  drivers/mtd/nand/fsmc_nand.c | 51 ++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index e96d7d1..bd89580 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -278,52 +278,61 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   * struct fsmc_nand_data - structure for FSMC NAND device state
>   *
>   * @pid:		Part ID on the AMBA PrimeCell format
> - * @mtd:		MTD info for a NAND flash.
> - * @nand:		Chip related info for a NAND flash.
> - * @partitions:		Partition info for a NAND Flash.
> - * @nr_partitions:	Total number of partition of a NAND flash.
> - *
> - * @ecc_place:		ECC placing locations in oobfree type format.
> - * @bank:		Bank number for probed device.
> - * @clk:		Clock structure for FSMC.
> + * @mtd:		MTD info for a NAND flash
> + * @nand:		Chip related info for a NAND flash
> + * @dev:		Device structure pointer
> + * @clk:		Clock structure for FSMC
> + * @ecc_place:		ECC placing locations in oobfree type format
> + * @bank:		Bank number for probed device
>   *
>   * @read_dma_chan:	DMA channel for read access
>   * @write_dma_chan:	DMA channel for write access to NAND
>   * @dma_access_complete: Completion structure
>   *
> - * @data_pa:		NAND Physical port for Data.
> - * @data_va:		NAND port for Data.
> - * @cmd_va:		NAND port for Command.
> - * @addr_va:		NAND port for Address.
> - * @regs_va:		FSMC regs base address.
> + * @dev_timings:	Timings to be programmed in controller
> + * @partitions:		Partition info for a NAND Flash
> + * @nr_partitions:	Total number of partition of a NAND flash
> + * @mode:		Defines the NAND device access mode
> + *			Can be one of:
> + *			- DMA access
> + *			- Word access (CPU)
> + *			- None (Use driver default ie bus width specific
> + *			  CPU access)
> + * @select_chip:	Select a particular bank
> + *
> + * @data_pa:		NAND Physical port for Data
> + * @data_va:		NAND port for Data
> + * @cmd_va:		NAND port for Command
> + * @addr_va:		NAND port for Address
> + * @regs_va:		FSMC regs base address
>   */
>  struct fsmc_nand_data {
>  	u32			pid;
>  	struct mtd_info		mtd;
>  	struct nand_chip	nand;
> -	struct mtd_partition	*partitions;
> -	unsigned int		nr_partitions;
> -
> -	struct fsmc_eccplace	*ecc_place;
> -	unsigned int		bank;
>  	struct device		*dev;
> -	enum access_mode	mode;
>  	struct clk		*clk;
> +	struct fsmc_eccplace	*ecc_place;
> +	unsigned int		bank;
>  
>  	/* DMA related objects */
>  	struct dma_chan		*read_dma_chan;
>  	struct dma_chan		*write_dma_chan;
>  	struct completion	dma_access_complete;
>  
> +	/* Recieved from plat data */
>  	struct fsmc_nand_timings *dev_timings;
> +	struct mtd_partition	*partitions;
> +	unsigned int		nr_partitions;
where do you use those execpt at probe time
> +	enum access_mode	mode;
> +	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  
> +	/* Virtual/Physical addresses for CPU/DMA access */
>  	dma_addr_t		data_pa;
>  	void __iomem		*data_va;
>  	void __iomem		*cmd_va;
>  	void __iomem		*addr_va;
>  	void __iomem		*regs_va;
> -
> -	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  };
>  
>  /* Assert CS signal based on chipnr */
> -- 
> 1.7.11.4
> 

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Domenico Andreoli @ 2012-10-09 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50738DD0.5090406@wwwdotorg.org>

On Mon, Oct 08, 2012 at 08:37:04PM -0600, Stephen Warren wrote:
> On 10/07/2012 04:54 PM, Domenico Andreoli wrote:
> > On Sun, Oct 07, 2012 at 09:57:59PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >> On 03:53 Sun 07 Oct     , Domenico Andreoli wrote:
> >>> From: Domenico Andreoli <domenico.andreoli@linux.com>
> 
> >>> Index: b/arch/arm/boot/dts/bcm476x.dtsi
> 
> >>> +		vic0: interrupt-controller at 80000 {
> >>> +			compatible = "brcm,bcm476x-pl192", "arm,pl192-vic", "arm,primecell";
> >> why brcm specific compatbile?
> > 
> > Nothing breaks if I drop it. I think it's a future-proof clause, especially
> > if you consider that the devicetree could be not easy to upgrade and you
> > may need a way to differentiate the bcm476x's implementation from the
> > common one. I'm not sure it's an actual requirement with use cases.
> 
> Indeed, everything works fine right now if you drop that. However, it is
> correct practice to include a compatible value for the particular SoC
> that incorporates the IP so that if in the future some SoC-specific
> workaround is required, the compatible value needed to trigger this is
> already in all historical .dts file.

This matches with what I know but it seems anyway that in the arm,primecell
cases this is not a great concern, almost none of the dts currently in
mainline go as far as specifying the machine specific name.

> >>> Index: b/arch/arm/include/debug/bcm476x.S
> 
> >>> +#if defined(CONFIG_DEBUG_BCM476X_UART0)
> >>> +# define BCM476X_DEBUG_PHYS	0x000c0000
> >>> +# define BCM476X_DEBUG_VIRT	0xd00c0000
> >>> +#elif defined(CONFIG_DEBUG_BCM476X_UART1)
> >>> +# define BCM476X_DEBUG_PHYS	0x000c1000
> >>> +# define BCM476X_DEBUG_VIRT	0xd00c1000
> >>> +#elif defined(CONFIG_DEBUG_BCM476X_UART2)
> >>> +# define BCM476X_DEBUG_PHYS	0x000b2000
> >>> +# define BCM476X_DEBUG_VIRT	0xd00b2000
> >>> +#else
> >>> +# error Unknown BCM476x debug port
> >>> +#endif
> >>
> >> can't you detect it?
> > 
> > If I can assume that the boot loader will configure and enable only the
> > console port, I could use the first one in such state.
> > 
> > Where could I place such detection, in the maco addruart itself?
> 
> Auto-detection is not necessarily a good idea; there's no reason in
> general to believe that no future board will ever use a UART for any
> purposes other than console/debug. Being explicit is probably good.

After thinking at it a bit, I also prefer to leave the guessing out. It
can break things in non-obvious ways. I prefer a full consistent and
testable behaviour.

Thanks,
Domenico

^ permalink raw reply

* [PATCH 10/11] fsmc/nand: Add sw bch support for ecc calculation/correction
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-09 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3968b65e9aa0a81eca16ce0f20e45504da7ad7fe.1349778821.git.vipin.kumar@st.com>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |   2 +
>  drivers/mtd/nand/fsmc_nand.c                       | 156 +++++++++++++--------
>  include/linux/mtd/fsmc.h                           |   3 +
>  3 files changed, 106 insertions(+), 55 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 598bca2..dcf513b 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -30,6 +30,8 @@ Optional properties:
>  - st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
>    pin number is defined in this property
>  
> +- nand-sw-ecc: boolean indicating whether s/w ecc is supported
> +
please use the generic binding
 - nand-ecc-mode = xx
>  Example:
>  
>  	fsmc: flash at d1800000 {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index 762cf83..ff84468 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -946,6 +946,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  	} else
>  		pdata->rbpin.use_pin = FSMC_RB_WAIT;
>  
> +	if (of_property_read_bool(np, "nand-sw-ecc"))
> +		pdata->sw_ecc = true;
> +
of_get_nand_ecc_mode

>  	return 0;
>  }
>  #else
> @@ -972,6 +975,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	dma_cap_mask_t mask;
>  	int ret = 0;
>  	u32 pid, bank;
> +	uint oobeccsize, m;
>  	int i;
>  
>  	if (np) {
> @@ -1104,9 +1108,24 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	nand->cmd_ctrl = fsmc_cmd_ctrl;
>  	nand->chip_delay = 30;
>  
> -	nand->ecc.mode = NAND_ECC_HW;
> -	nand->ecc.hwctl = fsmc_enable_hwecc;
> -	nand->ecc.size = 512;
> +	if (pdata->sw_ecc) {
> +		nand->ecc.mode = NAND_ECC_SOFT_BCH;
> +		/*
> +		 * The recent devices require n-bit correctibility in x bytes.
> +		 * The values of n and x varies as below
> +		 * n - 1 to 100
> +		 * x - 512 to 1K
> +		 * TODO: For now, take x = 1K for all sw bch mathematics. Think
> +		 * of a better way to handle other device dependent
> +		 * requirements. May be it should come from board dts files
> +		 */
> +		nand->ecc.size = 1024;
> +	} else {
> +		nand->ecc.mode = NAND_ECC_HW;
> +		nand->ecc.hwctl = fsmc_enable_hwecc;
> +		nand->ecc.size = 512;
> +	}
> +
>  	nand->options = pdata->options;
>  	nand->select_chip = fsmc_select_chip;
>  	nand->badblockbits = 7;
> @@ -1165,17 +1184,19 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  				nand->options & NAND_BUSWIDTH_16,
>  				host->dev_timings, host->rbpin);
>  
> -	if (AMBA_REV_BITS(host->pid) >= 8) {
> -		nand->ecc.read_page = fsmc_read_page_hwecc;
> -		nand->ecc.calculate = fsmc_read_hwecc_ecc4;
> -		nand->ecc.correct = fsmc_bch8_correct_data;
> -		nand->ecc.bytes = 13;
> -		nand->ecc.strength = 8;
> -	} else {
> -		nand->ecc.calculate = fsmc_read_hwecc_ecc1;
> -		nand->ecc.correct = nand_correct_data;
> -		nand->ecc.bytes = 3;
> -		nand->ecc.strength = 1;
> +	if (nand->ecc.mode != NAND_ECC_SOFT_BCH) {
> +		if (AMBA_REV_BITS(host->pid) >= 8) {
> +			nand->ecc.read_page = fsmc_read_page_hwecc;
> +			nand->ecc.calculate = fsmc_read_hwecc_ecc4;
> +			nand->ecc.correct = fsmc_bch8_correct_data;
> +			nand->ecc.bytes = 13;
> +			nand->ecc.strength = 8;
> +		} else {
> +			nand->ecc.calculate = fsmc_read_hwecc_ecc1;
> +			nand->ecc.correct = nand_correct_data;
> +			nand->ecc.bytes = 3;
> +			nand->ecc.strength = 1;
> +		}
>  	}
>  
>  	/*
> @@ -1187,48 +1208,73 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		goto err_scan_ident;
>  	}
>  
> -	if (AMBA_REV_BITS(host->pid) >= 8) {
> -		switch (host->mtd.oobsize) {
> -		case 16:
> -			nand->ecc.layout = &fsmc_ecc4_16_layout;
> -			host->ecc_place = &fsmc_ecc4_sp_place;
> -			break;
> -		case 64:
> -			nand->ecc.layout = &fsmc_ecc4_64_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 128:
> -			nand->ecc.layout = &fsmc_ecc4_128_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 224:
> -			nand->ecc.layout = &fsmc_ecc4_224_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 256:
> -			nand->ecc.layout = &fsmc_ecc4_256_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		default:
> -			printk(KERN_WARNING "No oob scheme defined for "
> -			       "oobsize %d\n", mtd->oobsize);
> -			BUG();
> -		}
> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
> +		/*
> +		 * Initialize the ecc bytes and strength dynamically based on eccsize
> +		 * and writesize.
> +		 *
> +		 * Parameters @eccsize and @eccbytes are used to compute BCH parameters
> +		 * m (Galois field order) and t (error correction capability). @eccbytes
> +		 * should be equal to the number of bytes required to store m*t bits,
> +		 * where m is such that 2^m-1 > @eccsize*8.
> +		 *
> +		 * Example: to configure 4 bit correction per 512 bytes, you should pass
> +		 * @eccsize = 512  (thus, m=13 is the smallest integer such that 2^m-1 >
> +		 * 512*8) @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52
> +		 * bits)
> +		 *
> +		 * Note: 2 bytes of oob are considered reserved for bad block marking
> +		 */
> +		m = fls(1 + 8 * nand->ecc.size);
> +		oobeccsize = ((host->mtd.oobsize - 2) * \
> +				nand->ecc.size) / host->mtd.writesize;
> +		nand->ecc.bytes = (oobeccsize / m) * m;
> +		nand->ecc.strength = (nand->ecc.bytes * 8) / m;
> +		nand->ecc.layout = NULL;
>  	} else {
> -		switch (host->mtd.oobsize) {
> -		case 16:
> -			nand->ecc.layout = &fsmc_ecc1_16_layout;
> -			break;
> -		case 64:
> -			nand->ecc.layout = &fsmc_ecc1_64_layout;
> -			break;
> -		case 128:
> -			nand->ecc.layout = &fsmc_ecc1_128_layout;
> -			break;
> -		default:
> -			printk(KERN_WARNING "No oob scheme defined for "
> -			       "oobsize %d\n", mtd->oobsize);
> -			BUG();
> +		if (AMBA_REV_BITS(host->pid) >= 8) {
> +			switch (host->mtd.oobsize) {
> +			case 16:
> +				nand->ecc.layout = &fsmc_ecc4_16_layout;
> +				host->ecc_place = &fsmc_ecc4_sp_place;
> +				break;
> +			case 64:
> +				nand->ecc.layout = &fsmc_ecc4_64_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 128:
> +				nand->ecc.layout = &fsmc_ecc4_128_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 224:
> +				nand->ecc.layout = &fsmc_ecc4_224_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 256:
> +				nand->ecc.layout = &fsmc_ecc4_256_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			default:
> +				printk(KERN_WARNING "No oob scheme defined for "
> +						"oobsize %d\n", mtd->oobsize);
> +				BUG();
> +			}
> +		} else {
> +			switch (host->mtd.oobsize) {
> +			case 16:
> +				nand->ecc.layout = &fsmc_ecc1_16_layout;
> +				break;
> +			case 64:
> +				nand->ecc.layout = &fsmc_ecc1_64_layout;
> +				break;
> +			case 128:
> +				nand->ecc.layout = &fsmc_ecc1_128_layout;
> +				break;
> +			default:
> +				printk(KERN_WARNING "No oob scheme defined for "
> +						"oobsize %d\n", mtd->oobsize);
> +				BUG();
> +			}
>  		}
>  	}
>  
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index eed22a1..07eee6e 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -176,6 +176,9 @@ struct fsmc_nand_platform_data {
>  	/* priv structures for dma accesses */
>  	void			*read_dma_priv;
>  	void			*write_dma_priv;
> +
> +	/* whether s/w ecc is supported */
> +	bool			sw_ecc;
>  };
>  
>  extern int __init fsmc_nor_init(struct platform_device *pdev,
> -- 
> 1.7.11.4
> 

^ permalink raw reply

* [PATCH 6/6] ARM: EXYNOS5: SATA PHY controller driver
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds a platform driver and I2C client driver for SATA PHY controller

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 drivers/ata/Makefile          |    2 +-
 drivers/ata/sata_exynos_phy.c |  303 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 304 insertions(+), 1 deletions(-)
 create mode 100644 drivers/ata/sata_exynos_phy.c

diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 33fb2f6..769d945 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
-obj-$(CONFIG_SATA_EXYNOS)          += sata_phy.o sata_exynos.o libahci.o
+obj-$(CONFIG_SATA_EXYNOS)          += sata_phy.o sata_exynos_phy.o sata_exynos.o libahci.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/sata_exynos_phy.c b/drivers/ata/sata_exynos_phy.c
new file mode 100644
index 0000000..44861de
--- /dev/null
+++ b/drivers/ata/sata_exynos_phy.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * EXYNOS - SATA PHY controller driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/ahci_platform.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+
+#include <plat/cpu.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-sata.h>
+
+#include "sata_phy.h"
+
+#define	SATA_TIME_LIMIT		1000
+
+static struct i2c_client *i2c_client;
+
+static struct i2c_driver sataphy_i2c_driver;
+
+struct exynos_sata_phy {
+	void __iomem *mmio;
+	struct resource *mem;
+	struct clk *clk;
+};
+
+static bool sata_is_reg(void __iomem *base, u32 reg, u32 checkbit, u32 Status)
+{
+	if ((readl(base + reg) & checkbit) == Status)
+		return true;
+	else
+		return false;
+}
+
+static bool wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit,
+				u32 Status)
+{
+	u16 time_limit_cnt = 0;
+	while (!sata_is_reg(base, reg, checkbit, Status)) {
+		if (time_limit_cnt == SATA_TIME_LIMIT)
+			return false;
+		udelay(1000);
+		time_limit_cnt++;
+	}
+	return true;
+}
+
+int sataphy_init(struct sata_phy *phy)
+{
+	int ret;
+	u32 val;
+
+	/* Values to be written to enable 40 bits interface */
+	u8 buf[] = { 0x3A, 0x0B };
+
+	struct exynos_sata_phy *sata_phy;
+
+	sata_phy = (struct exynos_sata_phy *)phy->priv_data;
+
+	clk_enable(sata_phy->clk);
+
+	writel(S5P_PMU_SATA_PHY_CONTROL_EN, EXYNOS5_SATA_PHY_CONTROL);
+
+	val = 0;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_RESET);
+	val |= 0xFF;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_RESET);
+	val |= LINK_RESET;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_RESET);
+	val |= RESET_CMN_RST_N;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_PHSATA_CTRLM);
+	val &= ~PHCTRLM_REF_RATE;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_PHSATA_CTRLM);
+
+	/* High speed enable for Gen3 */
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_PHSATA_CTRLM);
+	val |= PHCTRLM_HIGH_SPEED;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_PHSATA_CTRLM);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_CTRL0);
+	val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_CTRL0);
+
+	writel(SATA_PHY_GENERATION3, sata_phy->mmio + EXYNOS5_SATA_MODE0);
+
+	ret = i2c_master_send(i2c_client, buf, sizeof(buf));
+	if (ret < 0)
+		return -EINVAL;
+
+	/* release cmu reset */
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_RESET);
+	val &= ~RESET_CMN_RST_N;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->mmio + EXYNOS5_SATA_RESET);
+	val |= RESET_CMN_RST_N;
+	writel(val, sata_phy->mmio + EXYNOS5_SATA_RESET);
+
+	if (wait_for_reg_status(sata_phy->mmio, EXYNOS5_SATA_PHSATA_STATM,
+				PHSTATM_PLL_LOCKED, 1)) {
+		return 0;
+	}
+	return -EINVAL;
+}
+
+int sataphy_shutdown(struct sata_phy *phy)
+{
+
+	struct exynos_sata_phy *sata_phy;
+
+	sata_phy = (struct exynos_sata_phy *)phy->priv_data;
+
+	clk_disable(sata_phy->clk);
+
+	return 0;
+}
+
+static int sata_i2c_probe(struct i2c_client *client,
+			  const struct i2c_device_id *i2c_id)
+{
+	i2c_client = client;
+	return 0;
+}
+
+static int __init sata_phy_probe(struct platform_device *pdev)
+{
+	struct exynos_sata_phy *sataphy;
+	struct sata_phy *phy;
+	struct resource *res;
+	int ret = 0;
+
+	phy = kzalloc(sizeof(struct sata_phy), GFP_KERNEL);
+	if (!phy) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sataphy = kzalloc(sizeof(struct exynos_sata_phy), GFP_KERNEL);
+	if (!sataphy) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Could not find IO resource\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+
+	sataphy->mem = request_mem_region(res->start, resource_size(res),
+								pdev->name);
+	if (!sataphy->mem) {
+		dev_err(&pdev->dev, "Could not request IO resource\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+
+	sataphy->mmio =
+	    ioremap(res->start, resource_size(res));
+
+	if (!sataphy->mmio) {
+		dev_err(&pdev->dev, "failed to remap IO\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	sataphy->clk = clk_get(&pdev->dev, "sata_phy");
+	if (IS_ERR(sataphy->clk)) {
+		dev_err(&pdev->dev, "failed to get clk for PHY\n");
+		ret = PTR_ERR(sataphy->clk);
+		sataphy->clk = NULL;
+		goto err3;
+	}
+
+	phy->init = sataphy_init;
+	phy->shutdown = sataphy_shutdown;
+	phy->priv_data = (void *)sataphy;
+	phy->dev = &pdev->dev;
+
+	ret = sata_add_phy(phy, SATA_PHY_GENERATION3);
+	if (ret < 0)
+		goto err4;
+
+	ret = i2c_add_driver(&sataphy_i2c_driver);
+	if (ret < 0)
+		goto err5;
+
+	platform_set_drvdata(pdev, phy);
+
+	return ret;
+
+ err5:
+	sata_remove_phy(phy);
+
+ err4:
+	clk_put(sataphy->clk);
+
+ err3:
+	iounmap(sataphy->mmio);
+
+ err2:
+	release_resource(sataphy->mem);
+
+ err1:
+	kfree(sataphy);
+
+ err0:
+	kfree(phy);
+
+ out:
+	return ret;
+}
+
+static int sata_phy_remove(struct platform_device *pdev)
+{
+	struct sata_phy *phy;
+	struct exynos_sata_phy *sataphy;
+
+	phy = platform_get_drvdata(pdev);
+
+	sataphy = (struct exynos_sata_phy *)phy->priv_data;
+	sata_remove_phy(phy);
+
+	iounmap(sataphy->mmio);
+
+	release_resource(sataphy->mem);
+
+	clk_disable(sataphy->clk);
+	clk_put(sataphy->clk);
+
+	kfree(sataphy);
+	kfree(phy);
+
+	return 0;
+}
+
+static const struct of_device_id sata_phy_of_match[] = {
+	{.compatible = "samsung,exynos-sata-phy",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, sata_phy_of_match);
+
+static const struct i2c_device_id phy_i2c_device_match[] = {
+	{"sataphy", 0},
+};
+
+MODULE_DEVICE_TABLE(of, phy_i2c_device_match);
+
+static struct platform_driver sata_phy_driver = {
+	.probe = sata_phy_probe,
+	.remove = sata_phy_remove,
+	.driver = {
+		   .name = "sata-phy",
+		   .owner = THIS_MODULE,
+		   .of_match_table = sata_phy_of_match,
+		   },
+};
+
+static struct i2c_driver sataphy_i2c_driver = {
+	.driver = {
+		   .name = "i2c-phy",
+		   .owner = THIS_MODULE,
+		   .of_match_table = phy_i2c_device_match,
+		   },
+	.probe = sata_i2c_probe,
+	.id_table = phy_i2c_device_match,
+};
+
+module_platform_driver(sata_phy_driver);
+
+MODULE_DESCRIPTION("EXYNOS SATA PHY DRIVER");
+MODULE_AUTHOR("Vasanth Ananthan, <vasanth.a@samsung.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 5/6] ARM: EYNOS5: SATA controller driver
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds a platform driver for SATA controller.

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 arch/arm/mach-exynos/include/mach/regs-pmu.h |    3 +
 drivers/ata/Makefile                         |    2 +-
 drivers/ata/sata_exynos.c                    |  274 ++++++++++++++++++++++++++
 3 files changed, 278 insertions(+), 1 deletions(-)
 create mode 100644 drivers/ata/sata_exynos.c

diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index d4e392b..3716ce8 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -367,4 +367,7 @@
 
 #define EXYNOS5_OPTION_USE_RETENTION				(1 << 4)
 
+/* Only for EXYNOS5250 */
+#define EXYNOS5_SATA_PHY_CONTROL		S5P_PMUREG(0x0724)
+
 #endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index bf3fd91..33fb2f6 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
-obj-$(CONFIG_SATA_EXYNOS)          += sata_phy.o libahci.o
+obj-$(CONFIG_SATA_EXYNOS)          += sata_phy.o sata_exynos.o libahci.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/sata_exynos.c b/drivers/ata/sata_exynos.c
new file mode 100644
index 0000000..877039e
--- /dev/null
+++ b/drivers/ata/sata_exynos.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * EXYNOS - SATA controller driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include "ahci.h"
+#include "sata_phy.h"
+
+#define SATA_FREQ	(66*1000*1000)
+
+static const struct ata_port_info ahci_port_info[] = {
+	[0] = {
+	       .flags = AHCI_FLAG_COMMON,
+	       .pio_mask = ATA_PIO4,
+	       .udma_mask = ATA_UDMA6,
+	       .port_ops = &ahci_ops,
+	       },
+};
+
+static struct scsi_host_template ahci_platform_sht = {
+	AHCI_SHT("ahci_platform"),
+};
+
+struct exynos_sata {
+	struct clk *sclk;
+	struct clk *clk;
+	struct sata_phy *phy;
+	int irq;
+};
+
+static int __init exynos_sata_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ata_port_info pi = ahci_port_info[0];
+	const struct ata_port_info *ppi[] = { &pi, NULL };
+	struct ahci_host_priv *hpriv;
+	struct exynos_sata *sata;
+	struct ata_host *host;
+	struct resource *mem;
+	int n_ports, i, ret;
+
+	sata = kzalloc(sizeof(*sata), GFP_KERNEL);
+	if (!sata) {
+		dev_err(dev, "can't alloc sata\n");
+		ret = -ENOMEM;
+		return ret;
+	}
+
+	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+	if (!hpriv) {
+		dev_err(dev, "can't alloc ahci_host_priv\n");
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	hpriv->flags |= (unsigned long)pi.private_data;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(dev, "no mmio space\n");
+		ret = -EINVAL;
+		goto err2;
+	}
+
+	sata->irq = platform_get_irq(pdev, 0);
+	if (sata->irq <= 0) {
+		dev_err(dev, "no irq\n");
+		ret = -EINVAL;
+		goto err2;
+	}
+
+	hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+	if (!hpriv->mmio) {
+		dev_err(dev, "can't map %pR\n", mem);
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	sata->sclk = clk_get(dev, "sclk_sata");
+	if (IS_ERR(sata->sclk)) {
+		dev_err(dev, "failed to get sclk_sata\n");
+		ret = PTR_ERR(sata->sclk);
+		goto err3;
+	}
+	clk_enable(sata->sclk);
+
+	clk_set_rate(sata->sclk, SATA_FREQ);
+
+	sata->clk = clk_get(dev, "sata");
+	if (IS_ERR(sata->clk)) {
+		dev_err(dev, "failed to get sata clock\n");
+		ret = PTR_ERR(sata->clk);
+		goto err4;
+	}
+	clk_enable(sata->clk);
+
+	/*  Get a gen 3 PHY controller */
+
+	sata->phy = sata_get_phy(SATA_PHY_GENERATION3);
+	if (IS_ERR(sata->phy)) {
+		dev_err(dev, "failed to get sata phy\n");
+		ret = PTR_ERR(sata->clk);
+		goto err5;
+	}
+
+	/* Initialize the controller */
+
+	ret = sata_init_phy(sata->phy);
+	if (ret)
+		goto err6;
+
+	ahci_save_initial_config(dev, hpriv, 0, 0);
+
+	/* prepare host */
+	if (hpriv->cap & HOST_CAP_NCQ)
+		pi.flags |= ATA_FLAG_NCQ;
+
+	if (hpriv->cap & HOST_CAP_PMP)
+		pi.flags |= ATA_FLAG_PMP;
+
+	ahci_set_em_messages(hpriv, &pi);
+
+	/* CAP.NP sometimes indicate the index of the last enabled
+	 * port, at other times, that of the last possible port, so
+	 * determining the maximum port number requires looking at
+	 * both CAP.NP and port_map.
+	 */
+	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
+	if (!host) {
+		ret = -ENOMEM;
+		goto err7;
+	}
+
+	host->private_data = hpriv;
+
+	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
+		host->flags |= ATA_HOST_PARALLEL_SCAN;
+	else
+		pr_info(KERN_INFO
+		       "ahci: SSS flag set, parallel bus scan disabled\n");
+
+	if (pi.flags & ATA_FLAG_EM)
+		ahci_reset_em(host);
+
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_port *ap = host->ports[i];
+
+		ata_port_desc(ap, "mmio %pR", mem);
+		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
+
+		/* set enclosure management message type */
+		if (ap->flags & ATA_FLAG_EM)
+			ap->em_message_type = hpriv->em_msg_type;
+
+		/* disabled/not-implemented port */
+		if (!(hpriv->port_map & (1 << i)))
+			ap->ops = &ata_dummy_port_ops;
+	}
+
+	ret = ahci_reset_controller(host);
+	if (ret)
+		goto err7;
+
+	ahci_init_controller(host);
+	ahci_print_info(host, "platform");
+
+	ret = ata_host_activate(host, sata->irq, ahci_interrupt, IRQF_SHARED,
+				&ahci_platform_sht);
+	if (ret)
+		goto err7;
+
+	platform_set_drvdata(pdev, sata);
+
+	return 0;
+
+ err7:
+	sata_shutdown_phy(sata->phy);
+
+ err6:
+	sata_put_phy(sata->phy);
+
+ err5:
+	clk_disable(sata->clk);
+	clk_put(sata->clk);
+
+ err4:
+	clk_disable(sata->sclk);
+	clk_put(sata->sclk);
+
+ err3:
+	iounmap(hpriv->mmio);
+
+ err2:
+	kfree(hpriv);
+
+ err1:
+	kfree(sata);
+
+	return ret;
+}
+
+static int __devexit exynos_sata_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct exynos_sata *sata = platform_get_drvdata(pdev);
+	ata_host_detach(host);
+
+	sata_shutdown_phy(sata->phy);
+	sata_put_phy(sata->phy);
+
+	clk_disable(sata->sclk);
+	clk_put(sata->sclk);
+
+	clk_disable(sata->clk);
+	clk_put(sata->clk);
+
+	kfree(sata);
+
+	return 0;
+}
+
+static const struct of_device_id ahci_of_match[] = {
+	{.compatible = "samsung,exynos-sata-ahci",},
+};
+
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
+static struct platform_driver exynos_sata_driver = {
+	.remove = exynos_sata_remove,
+	.driver = {
+		   .name = "ahci-sata",
+		   .owner = THIS_MODULE,
+		   .of_match_table = ahci_of_match,
+		   },
+};
+
+static int __init exynos_sata_init(void)
+{
+	return platform_driver_probe(&exynos_sata_driver, exynos_sata_probe);
+}
+
+module_init(exynos_sata_init);
+
+static void __exit exynos_sata_exit(void)
+{
+	platform_driver_unregister(&exynos_sata_driver);
+}
+
+module_exit(exynos_sata_exit);
+
+MODULE_DESCRIPTION("EXYNOS SATA DRIVER");
+MODULE_AUTHOR("Vasanth Ananthan, <vasanth.a@samsung.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 4/6] ARM: S3C2410: I2C driver polling mode support
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds polling mode support for i2c s3c-2410 driver.
The I2C_SATAPHY controller lacks an interrupt line but the s3c-2410 driver
is interrupt driven. Hence this support is required for functioning
of the I2C_SATAPHY controller.

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 drivers/i2c/busses/i2c-s3c2410.c |   84 +++++++++++++++++++++++++++++---------
 1 files changed, 65 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 5ae3b02..699b530 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -48,6 +48,7 @@
 #define QUIRK_S3C2440		(1 << 0)
 #define QUIRK_HDMIPHY		(1 << 1)
 #define QUIRK_NO_GPIO		(1 << 2)
+#define QUIRK_SATAPHY		(1 << 3)
 
 /* i2c controller state */
 enum s3c24xx_i2c_state {
@@ -102,10 +103,14 @@ static struct platform_device_id s3c24xx_driver_ids[] = {
 };
 MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
 
+static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat);
+
 #ifdef CONFIG_OF
 static const struct of_device_id s3c24xx_i2c_match[] = {
 	{ .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
 	{ .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
+	{ .compatible = "samsung,s3c2440-sataphy-i2c",
+	  .data = (void *)(QUIRK_S3C2440|QUIRK_SATAPHY|QUIRK_NO_GPIO) },
 	{ .compatible = "samsung,s3c2440-hdmiphy-i2c",
 	  .data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
 	{},
@@ -146,7 +151,8 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
 	if (ret)
 		i2c->msg_idx = ret;
 
-	wake_up(&i2c->wait);
+	if (!(i2c->quirks & QUIRK_SATAPHY))
+		wake_up(&i2c->wait);
 }
 
 static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
@@ -184,6 +190,21 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
 }
 
 
+static bool is_ack(struct s3c24xx_i2c *i2c)
+{
+	u32 time_out = i2c->tx_setup;
+	while (--time_out) {
+		if (readl(i2c->regs + S3C2410_IICCON)
+			& S3C2410_IICCON_IRQPEND) {
+			if (!(readl(i2c->regs + S3C2410_IICSTAT)
+				& S3C2410_IICSTAT_LASTBIT))
+				return true;
+		}
+		udelay(time_out);
+	}
+	return false;
+}
+
 /* s3c24xx_i2c_message_start
  *
  * put the start of a message onto the bus
@@ -227,6 +248,21 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
 
 	stat |= S3C2410_IICSTAT_START;
 	writel(stat, i2c->regs + S3C2410_IICSTAT);
+
+	if (i2c->quirks & QUIRK_SATAPHY) {
+
+		while ((i2c->msg_num != 0) && is_ack(i2c)) {
+
+			i2c_s3c_irq_nextbyte(i2c, stat);
+
+			stat = readl(i2c->regs + S3C2410_IICSTAT);
+			if (stat & S3C2410_IICSTAT_ARBITR)
+				dev_err(i2c->dev, "deal with arbitration loss\n");
+
+		}
+
+	}
+
 }
 
 static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
@@ -552,22 +588,27 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
 	s3c24xx_i2c_message_start(i2c, msgs);
 	spin_unlock_irq(&i2c->lock);
 
-	timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
-
 	ret = i2c->msg_idx;
 
-	/* having these next two as dev_err() makes life very
-	 * noisy when doing an i2cdetect */
+	if (!(i2c->quirks & QUIRK_SATAPHY)) {
 
-	if (timeout == 0)
-		dev_dbg(i2c->dev, "timeout\n");
-	else if (ret != num)
-		dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
+		timeout = wait_event_timeout(i2c->wait,
+				i2c->msg_num == 0, HZ * 5);
 
-	/* ensure the stop has been through the bus */
+		/* having these next two as dev_err() makes life very
+		* noisy when doing an i2cdetect */
+
+		if (timeout == 0)
+			dev_dbg(i2c->dev, "timeout\n");
+		else if (ret != num)
+			dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
+
+		/* ensure the stop has been through the bus */
+	}
 
 	dev_dbg(i2c->dev, "waiting for bus idle\n");
 
+
 	/* first, try busy waiting briefly */
 	do {
 		cpu_relax();
@@ -710,6 +751,9 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
 	if (div1 == 512)
 		iiccon |= S3C2410_IICCON_TXDIV_512;
 
+	if (i2c->quirks & QUIRK_SATAPHY)
+		iiccon |= S3C2410_IICCON_SCALE(2);
+
 	writel(iiccon, i2c->regs + S3C2410_IICCON);
 
 	if (i2c->quirks & QUIRK_S3C2440) {
@@ -1023,18 +1067,20 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 	 * ensure no current IRQs pending
 	 */
 
-	i2c->irq = ret = platform_get_irq(pdev, 0);
-	if (ret <= 0) {
-		dev_err(&pdev->dev, "cannot find IRQ\n");
-		goto err_iomap;
-	}
+	if (!(i2c->quirks & QUIRK_SATAPHY)) {
+		i2c->irq = ret = platform_get_irq(pdev, 0);
+		if (ret <= 0) {
+			dev_err(&pdev->dev, "cannot find IRQ\n");
+			goto err_iomap;
+		}
 
-	ret = request_irq(i2c->irq, s3c24xx_i2c_irq, 0,
+		ret = request_irq(i2c->irq, s3c24xx_i2c_irq, 0,
 			  dev_name(&pdev->dev), i2c);
 
-	if (ret != 0) {
-		dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
-		goto err_iomap;
+		if (ret != 0) {
+			dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
+			goto err_iomap;
+		}
 	}
 
 	ret = s3c24xx_i2c_register_cpufreq(i2c);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 3/6] DRIVERS: ATA: SATA PHY utility framework
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds SATA PHY utility framework APIs. The framework acts as an
interface between the SATA device and the PHY device. The SATA PHY device
registers itself with the framework through the APIs provided and the SATA
device finds and requests for an appropriate PHY device.

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 drivers/ata/Kconfig    |    9 ++++
 drivers/ata/Makefile   |    1 +
 drivers/ata/sata_phy.c |   99 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/ata/sata_phy.h |   44 +++++++++++++++++++++
 4 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 drivers/ata/sata_phy.c
 create mode 100644 drivers/ata/sata_phy.h

diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 27cecd3..0344b78 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -83,6 +83,15 @@ config SATA_AHCI_PLATFORM
 
 	  If unsure, say N.
 
+config SATA_EXYNOS
+	bool "Exynos SATA AHCI support"
+	depends on I2C_S3C2410
+	help
+          This option enables support for Exynos AHCI Serial ATA
+          controllers.
+
+          If unsure, say N.
+
 config SATA_FSL
 	tristate "Freescale 3.0Gbps SATA support"
 	depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index a454a13..bf3fd91 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
+obj-$(CONFIG_SATA_EXYNOS)          += sata_phy.o libahci.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/sata_phy.c b/drivers/ata/sata_phy.c
new file mode 100644
index 0000000..dbb4aa3
--- /dev/null
+++ b/drivers/ata/sata_phy.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * EXYNOS - SATA utility framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include "sata_phy.h"
+
+static LIST_HEAD(phy_list);
+static DEFINE_SPINLOCK(phy_lock);
+
+struct sata_phy *sata_get_phy(enum sata_phy_type type)
+{
+	struct sata_phy *x = NULL;
+	unsigned long flag;
+
+	spin_lock_irqsave(&phy_lock, flag);
+
+	list_for_each_entry(x, &phy_list, head) {
+		if (x->type == type) {
+			get_device(x->dev);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&phy_lock, flag);
+	return x;
+}
+EXPORT_SYMBOL(sata_get_phy);
+
+int sata_add_phy(struct sata_phy *phy, enum sata_phy_type type)
+{
+	unsigned long flag;
+	unsigned int ret = -EINVAL;
+	struct sata_phy *x;
+
+	spin_lock_irqsave(&phy_lock, flag);
+
+	if (phy) {
+
+		list_for_each_entry(x, &phy_list, head) {
+			if (x->type == type) {
+				dev_err(phy->dev, "transceiver type already exists\n");
+				goto out;
+			}
+		}
+		phy->type = type;
+		list_add_tail(&phy->head, &phy_list);
+		ret = 0;
+	}
+
+ out:
+	spin_unlock_irqrestore(&phy_lock, flag);
+	return ret;
+}
+EXPORT_SYMBOL(sata_add_phy);
+
+void sata_remove_phy(struct sata_phy *phy)
+{
+	unsigned long flag;
+	struct sata_phy *x;
+
+	spin_lock_irqsave(&phy_lock, flag);
+
+	if (phy) {
+		list_for_each_entry(x, &phy_list, head) {
+			if (x->type == phy->type)
+				list_del(&phy->head);
+		}
+	}
+
+	spin_unlock_irqrestore(&phy_lock, flag);
+}
+EXPORT_SYMBOL(sata_remove_phy);
+
+void sata_put_phy(struct sata_phy *phy)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&phy_lock, flag);
+
+	if (phy)
+		put_device(phy->dev);
+
+	spin_unlock_irqrestore(&phy_lock, flag);
+
+}
+EXPORT_SYMBOL(sata_put_phy);
diff --git a/drivers/ata/sata_phy.h b/drivers/ata/sata_phy.h
new file mode 100644
index 0000000..dc38683
--- /dev/null
+++ b/drivers/ata/sata_phy.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * EXYNOS - SATA utility framework definitions.
+ *
+ * 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.
+*/
+
+enum sata_phy_type {
+	SATA_PHY_GENERATION1,
+	SATA_PHY_GENERATION2,
+	SATA_PHY_GENERATION3,
+};
+
+struct sata_phy {
+	int (*init) (struct sata_phy *);
+	int (*shutdown) (struct sata_phy *);
+	struct device *dev;
+	void *priv_data;
+	enum sata_phy_type type;
+	struct list_head head;
+};
+
+static inline int sata_init_phy(struct sata_phy *x)
+{
+	if (x && x->init)
+		return x->init(x);
+
+	return -EINVAL;
+}
+
+static inline void sata_shutdown_phy(struct sata_phy *x)
+{
+	if (x && x->shutdown)
+		x->shutdown(x);
+}
+
+struct sata_phy *sata_get_phy(enum sata_phy_type);
+int sata_add_phy(struct sata_phy *, enum sata_phy_type);
+void sata_remove_phy(struct sata_phy *);
+void sata_put_phy(struct sata_phy *);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/6] ARM: EXYNOS5: DT Support for SATA and SATA PHY
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds Device Nodes for SATA and SATA PHY device.

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 arch/arm/boot/dts/exynos5250-smdk5250.dts |   11 +++++++++++
 arch/arm/boot/dts/exynos5250.dtsi         |   20 ++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/map.h   |    7 +++++++
 arch/arm/mach-exynos/mach-exynos5-dt.c    |    6 ++++++
 4 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 8a5e348..bb262ce 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -48,6 +48,17 @@
 		};
 	};
 
+	i2c at 121D0000 {
+		samsung,i2c-sda-delay = <100>;
+                samsung,i2c-max-bus-freq = <40000>;
+		samsung,i2c-slave-addr = <0x38>;
+
+		sataphy at 70 {
+			compatible = "samsung,i2c-phy";
+			reg = <0x38>;
+		};
+	};
+
 	i2c at 12C80000 {
 		status = "disabled";
 	};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 004aaa8..5a47a8f 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -88,6 +88,18 @@
 		interrupts = <0 54 0>;
 	};
 
+	sata at 122F0000 {
+                compatible = "samsung,exynos-sata-ahci";
+                reg = <0x122F0000 0x1ff>;
+		interrupts = <0 115 0>;
+        };
+
+        sata-phy at 12170000 {
+                compatible = "samsung,exynos-sata-phy";
+                reg = <0x12170000 0x1ff>;
+        };
+
+
 	i2c at 12C60000 {
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C60000 0x100>;
@@ -152,6 +164,13 @@
 		#size-cells = <0>;
 	};
 
+	i2c at 121D0000 {
+                compatible = "samsung,s3c2440-sataphy-i2c";
+                reg = <0x121D0000 0x100>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+        };
+
 	spi_0: spi at 12d20000 {
 		compatible = "samsung,exynos4210-spi";
 		reg = <0x12d20000 0x100>;
@@ -460,4 +479,5 @@
 			#gpio-cells = <4>;
 		};
 	};
+
 };
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c72b675..6827190 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -177,9 +177,16 @@
 #define EXYNOS4_PA_HSOTG		0x12480000
 #define EXYNOS4_PA_USB_HSPHY		0x125B0000
 
+#ifdef CONFIG_ARCH_EXYNOS4
 #define EXYNOS4_PA_SATA			0x12560000
 #define EXYNOS4_PA_SATAPHY		0x125D0000
 #define EXYNOS4_PA_SATAPHY_CTRL		0x126B0000
+#endif
+#ifdef CONFIG_ARCH_EXYNOS5
+#define EXYNOS5_PA_SATA_PHY_CTRL	0x12170000
+#define EXYNOS5_PA_SATA_PHY_I2C		0x121D0000
+#define EXYNOS5_PA_SATA_BASE		0x122F0000
+#endif
 
 #define EXYNOS4_PA_SROMC		0x12570000
 #define EXYNOS5_PA_SROMC		0x12250000
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index ef770bc..c931c6c 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -47,6 +47,12 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
 				"s3c2440-i2c.0", NULL),
 	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
 				"s3c2440-i2c.1", NULL),
+	OF_DEV_AUXDATA("samsung,exynos-sata-ahci", EXYNOS5_PA_SATA_BASE,
+				"sata_exynos", NULL),
+	OF_DEV_AUXDATA("samsung,exynos-sata-phy", EXYNOS5_PA_SATA_PHY_CTRL,
+				"sata_phy_exynos", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-sataphy-i2c", EXYNOS5_PA_SATA_PHY_I2C,
+				"sata-phy-i2c", NULL),
 	OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI0,
 				"exynos4210-spi.0", NULL),
 	OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI1,
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 1/6] ARM: EXYNOS5: Clock settings for SATA and SATA PHY
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349783332-18467-1-git-send-email-vasanthananthan@gmail.com>

This patch adds neccessary clock entries for SATA, SATA PHY and
I2C_SATAPHY

Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
 arch/arm/mach-exynos/clock-exynos5.c |   19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 774533c..4ab964e 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -599,15 +599,20 @@ static struct clk exynos5_init_clocks_off[] = {
 		.ctrlbit	= (1 << 16),
 	}, {
 		.name		= "sata",
-		.devname	= "ahci",
+		.devname	= "sata_exynos",
+		.parent         = &exynos5_clk_aclk_200.clk,
 		.enable		= exynos5_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 6),
 	}, {
 		.name		= "sata_phy",
+		.devname	= "sata_phy_exynos",
+		.parent         = &exynos5_clk_aclk_200.clk,
 		.enable		= exynos5_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 24),
 	}, {
-		.name		= "sata_phy_i2c",
+		.name		= "i2c",
+		.devname	= "sata-phy-i2c",
+		.parent         = &exynos5_clk_aclk_200.clk,
 		.enable		= exynos5_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 25),
 	}, {
@@ -1157,6 +1162,16 @@ static struct clksrc_clk exynos5_clksrcs[] = {
 		.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
 	}, {
 		.clk	= {
+			.name		= "sclk_sata",
+			.devname	= "sata_exynos",
+			.enable		= exynos5_clksrc_mask_fsys_ctrl,
+			.ctrlbit	= (1 << 24),
+		},
+		.sources = &exynos5_clkset_aclk,
+		.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 },
+		.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+	}, {
+		.clk	= {
 			.name		= "sclk_gscl_wrap",
 			.devname	= "s5p-mipi-csis.0",
 			.enable		= exynos5_clksrc_mask_gscl_ctrl,
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 0/6] Adding support for SATA in EXYNO5
From: Vasanth Ananthan @ 2012-10-09 11:48 UTC (permalink / raw)
  To: linux-arm-kernel

The following set of patches provides drivers for SATA
and SATA PHY controller and also an interface for the 
two entity to interact. 

Vasanth Ananthan (6):
  ARM: EXYNOS5: Clock settings for SATA and SATA PHY
  ARM: EXYNOS5: DT Support for SATA and SATA PHY
  DRIVERS: ATA: SATA PHY utility framework
  ARM: S3C2410: I2C driver polling mode support
  ARM: EYNOS5: SATA controller driver
  ARM: EXYNOS5: SATA PHY controller driver

 arch/arm/boot/dts/exynos5250-smdk5250.dts    |   11 +
 arch/arm/boot/dts/exynos5250.dtsi            |   20 ++
 arch/arm/mach-exynos/clock-exynos5.c         |   19 ++-
 arch/arm/mach-exynos/include/mach/map.h      |    7 +
 arch/arm/mach-exynos/include/mach/regs-pmu.h |    3 +
 arch/arm/mach-exynos/mach-exynos5-dt.c       |    6 +
 drivers/ata/Kconfig                          |    9 +
 drivers/ata/Makefile                         |    1 +
 drivers/ata/sata_exynos.c                    |  274 +++++++++++++++++++++++
 drivers/ata/sata_exynos_phy.c                |  303 ++++++++++++++++++++++++++
 drivers/ata/sata_phy.c                       |   99 +++++++++
 drivers/ata/sata_phy.h                       |   44 ++++
 drivers/i2c/busses/i2c-s3c2410.c             |   84 ++++++--
 13 files changed, 859 insertions(+), 21 deletions(-)
 create mode 100644 drivers/ata/sata_exynos.c
 create mode 100644 drivers/ata/sata_exynos_phy.c
 create mode 100644 drivers/ata/sata_phy.c
 create mode 100644 drivers/ata/sata_phy.h

-- 
1.7.5.4

^ permalink raw reply

* [PATCH 0/6] Adding support for SATA in EXYNO5
From: vasanthananthan at gmail.com @ 2012-10-09 11:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vasanth Ananthan <vasanthananthan@gmail.com>

The following set of patches provides drivers for SATA
and SATA PHY controller and also an interface for the 
two entity to interact. 

Vasanth Ananthan (6):
  ARM: EXYNOS5: Clock settings for SATA and SATA PHY
  ARM: EXYNOS5: DT Support for SATA and SATA PHY
  DRIVERS: ATA: SATA PHY utility framework
  ARM: S3C2410: I2C driver polling mode support
  ARM: EYNOS5: SATA controller driver
  ARM: EXYNOS5: SATA PHY controller driver

 arch/arm/boot/dts/exynos5250-smdk5250.dts    |   11 +
 arch/arm/boot/dts/exynos5250.dtsi            |   20 ++
 arch/arm/mach-exynos/clock-exynos5.c         |   19 ++-
 arch/arm/mach-exynos/include/mach/map.h      |    7 +
 arch/arm/mach-exynos/include/mach/regs-pmu.h |    3 +
 arch/arm/mach-exynos/mach-exynos5-dt.c       |    6 +
 drivers/ata/Kconfig                          |    9 +
 drivers/ata/Makefile                         |    1 +
 drivers/ata/sata_exynos.c                    |  274 +++++++++++++++++++++++
 drivers/ata/sata_exynos_phy.c                |  303 ++++++++++++++++++++++++++
 drivers/ata/sata_phy.c                       |   99 +++++++++
 drivers/ata/sata_phy.h                       |   44 ++++
 drivers/i2c/busses/i2c-s3c2410.c             |   84 ++++++--
 13 files changed, 859 insertions(+), 21 deletions(-)
 create mode 100644 drivers/ata/sata_exynos.c
 create mode 100644 drivers/ata/sata_exynos_phy.c
 create mode 100644 drivers/ata/sata_phy.c
 create mode 100644 drivers/ata/sata_phy.h

-- 
1.7.5.4

^ permalink raw reply


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