From: Gabor Juhos <juhosg@openwrt.org>
Date: Mon, 19 Mar 2012 15:56:59 +0000 (+0000)
Subject: ar71xx: add platform data for the RB750 NAND driver
X-Git-Tag: reboot~14479
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=8a471efe012d23a9292b4f951e6d09717595faa3;p=openwrt%2Fopenwrt.git

ar71xx: add platform data for the RB750 NAND driver

SVN-Revision: 31022
---

diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c
index 976617bb36..bcd961e1bd 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c
@@ -1,5 +1,5 @@
 /*
- *  MikroTik RouterBOARD 750 support
+ *  MikroTik RouterBOARD 750/750GL support
  *
  *  Copyright (C) 2010-2012 Gabor Juhos <juhosg@openwrt.org>
  *
@@ -59,9 +59,13 @@ static struct platform_device rb750_leds_device = {
 	}
 };
 
+static struct rb7xx_nand_platform_data rb750_nand_data;
 static struct platform_device rb750_nand_device = {
 	.name	= "rb750-nand",
 	.id	= -1,
+	.dev	= {
+		.platform_data = &rb750_nand_data,
+	}
 };
 
 int rb750_latch_change(u32 mask_clr, u32 mask_set)
@@ -113,19 +117,24 @@ unlock:
 }
 EXPORT_SYMBOL_GPL(rb750_latch_change);
 
-void rb750_nand_pins_enable(void)
+static void rb750_nand_enable_pins(void)
 {
+	rb750_latch_change(RB750_LVC573_LE, 0);
 	ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
 				  AR724X_GPIO_FUNC_SPI_EN);
 }
-EXPORT_SYMBOL_GPL(rb750_nand_pins_enable);
 
-void rb750_nand_pins_disable(void)
+static void rb750_nand_disable_pins(void)
 {
 	ath79_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
 				  AR724X_GPIO_FUNC_JTAG_DISABLE);
+	rb750_latch_change(0, RB750_LVC573_LE);
+}
+
+static void rb750_nand_latch_change(u32 clear, u32 set)
+{
+	rb750_latch_change(clear, set);
 }
-EXPORT_SYMBOL_GPL(rb750_nand_pins_disable);
 
 static void __init rb750_setup(void)
 {
@@ -147,6 +156,11 @@ static void __init rb750_setup(void)
 	ath79_register_eth(0);
 
 	platform_device_register(&rb750_leds_device);
+
+	rb750_nand_data.nce_line = RB750_NAND_NCE;
+	rb750_nand_data.enable_pins = rb750_nand_enable_pins;
+	rb750_nand_data.disable_pins = rb750_nand_disable_pins;
+	rb750_nand_data.latch_change = rb750_nand_latch_change;
 	platform_device_register(&rb750_nand_device);
 }
 
diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h
index 3e6fc50c55..9509fca71e 100644
--- a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h
+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h
@@ -43,6 +43,7 @@
 #define RB750_LED_PORT3		BIT(RB750_GPIO_LED_PORT3)
 #define RB750_LED_PORT4		BIT(RB750_GPIO_LED_PORT4)
 #define RB750_LED_PORT5		BIT(RB750_GPIO_LED_PORT5)
+#define RB750_NAND_NCE		BIT(RB750_GPIO_NAND_NCE)
 
 #define RB750_LVC573_LE		BIT(RB750_GPIO_LVC573_LE)
 
@@ -61,8 +62,14 @@ struct rb750_led_platform_data {
 	struct rb750_led_data	*leds;
 };
 
+struct rb7xx_nand_platform_data {
+	u32 nce_line;
+
+	void (*enable_pins)(void);
+	void (*disable_pins)(void);
+	void (*latch_change)(u32, u32);
+};
+
 int rb750_latch_change(u32 mask_clr, u32 mask_set);
-void rb750_nand_pins_enable(void);
-void rb750_nand_pins_disable(void);
 
 #endif /* _MACH_RB750_H */
\ No newline at end of file
diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c
index f97e6e6c69..251e182208 100644
--- a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c
+++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c
@@ -31,20 +31,24 @@
 #define RB750_NAND_NRE		BIT(RB750_GPIO_NAND_NRE)
 #define RB750_NAND_NWE		BIT(RB750_GPIO_NAND_NWE)
 #define RB750_NAND_RDY		BIT(RB750_GPIO_NAND_RDY)
-#define RB750_NAND_NCE		BIT(RB750_GPIO_NAND_NCE)
 
 #define RB750_NAND_DATA_SHIFT	1
 #define RB750_NAND_DATA_BITS	(0xff << RB750_NAND_DATA_SHIFT)
 #define RB750_NAND_INPUT_BITS	(RB750_NAND_DATA_BITS | RB750_NAND_RDY)
 #define RB750_NAND_OUTPUT_BITS	(RB750_NAND_ALE | RB750_NAND_CLE | \
-				 RB750_NAND_NRE | RB750_NAND_NWE | \
-				 RB750_NAND_NCE)
+				 RB750_NAND_NRE | RB750_NAND_NWE)
 
 struct rb750_nand_info {
 	struct nand_chip	chip;
 	struct mtd_info		mtd;
+	struct rb7xx_nand_platform_data *pdata;
 };
 
+static inline struct rb750_nand_info *mtd_to_rbinfo(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct rb750_nand_info, mtd);
+}
+
 /*
  * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  * will not be able to find the kernel that we load.
@@ -138,16 +142,12 @@ static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
 
 static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
 {
+	struct rb750_nand_info *rbinfo = mtd_to_rbinfo(mtd);
 	void __iomem *base = ath79_gpio_base;
-	u32 func;
 	u32 t;
 
-	func = __raw_readl(base + AR71XX_GPIO_REG_FUNC);
 	if (chip >= 0) {
-		/* disable latch */
-		rb750_latch_change(RB750_LVC573_LE, 0);
-
-		rb750_nand_pins_enable();
+		rbinfo->pdata->enable_pins();
 
 		/* set input mode for data lines */
 		t = __raw_readl(base + AR71XX_GPIO_REG_OE);
@@ -161,10 +161,12 @@ static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
 		(void) __raw_readl(base + AR71XX_GPIO_REG_SET);
 
 		/* activate CE line */
-		__raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_CLEAR);
+		__raw_writel(rbinfo->pdata->nce_line,
+			     base + AR71XX_GPIO_REG_CLEAR);
 	} else {
 		/* deactivate CE line */
-		__raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_SET);
+		__raw_writel(rbinfo->pdata->nce_line,
+			     base + AR71XX_GPIO_REG_SET);
 		/* flush write */
 		(void) __raw_readl(base + AR71XX_GPIO_REG_SET);
 
@@ -172,10 +174,7 @@ static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
 		__raw_writel(t | RB750_NAND_IO0 | RB750_NAND_RDY,
 			     base + AR71XX_GPIO_REG_OE);
 
-		rb750_nand_pins_disable();
-
-		/* enable latch */
-		rb750_latch_change(0, RB750_LVC573_LE);
+		rbinfo->pdata->disable_pins();
 	}
 }
 
@@ -232,7 +231,7 @@ static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
 	return rb750_nand_read_verify(NULL, len, buf);
 }
 
-static void __init rb750_nand_gpio_init(void)
+static void __init rb750_nand_gpio_init(struct rb750_nand_info *info)
 {
 	void __iomem *base = ath79_gpio_base;
 	u32 out;
@@ -253,19 +252,24 @@ static void __init rb750_nand_gpio_init(void)
 
 	/* setup output lines */
 	t = __raw_readl(base + AR71XX_GPIO_REG_OE);
-	__raw_writel(t | RB750_NAND_OUTPUT_BITS, base + AR71XX_GPIO_REG_OE);
+	t |= RB750_NAND_OUTPUT_BITS;
+	t |= info->pdata->nce_line;
+	__raw_writel(t, base + AR71XX_GPIO_REG_OE);
 
-	rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
+	info->pdata->latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
 }
 
 static int __devinit rb750_nand_probe(struct platform_device *pdev)
 {
 	struct rb750_nand_info	*info;
+	struct rb7xx_nand_platform_data *pdata;
 	int ret;
 
 	printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
 
-	rb750_nand_gpio_init();
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		return -EINVAL;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
@@ -287,8 +291,12 @@ static int __devinit rb750_nand_probe(struct platform_device *pdev)
 	info->chip.ecc.mode	= NAND_ECC_SOFT;
 	info->chip.options	|= NAND_NO_AUTOINCR;
 
+	info->pdata = pdata;
+
 	platform_set_drvdata(pdev, info);
 
+	rb750_nand_gpio_init(info);
+
 	ret = nand_scan_ident(&info->mtd, 1, NULL);
 	if (ret) {
 		ret = -ENXIO;