oxnas: backport upstream NAND driver
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
		
							parent
							
								
									ae21033e76
								
							
						
					
					
						commit
						5cde94d9ab
					
				@ -243,8 +243,7 @@ CONFIG_MODULES_USE_ELF_REL=y
 | 
				
			|||||||
CONFIG_MTD_NAND=y
 | 
					CONFIG_MTD_NAND=y
 | 
				
			||||||
CONFIG_MTD_NAND_ECC=y
 | 
					CONFIG_MTD_NAND_ECC=y
 | 
				
			||||||
CONFIG_MTD_NAND_OXNAS=y
 | 
					CONFIG_MTD_NAND_OXNAS=y
 | 
				
			||||||
CONFIG_MTD_NAND_PLATFORM=y
 | 
					# CONFIG_MTD_SPLIT_FIRMWARE is not set
 | 
				
			||||||
CONFIG_MTD_SPLIT_FIRMWARE=y
 | 
					 | 
				
			||||||
CONFIG_MTD_UBI=y
 | 
					CONFIG_MTD_UBI=y
 | 
				
			||||||
CONFIG_MTD_UBI_BEB_LIMIT=20
 | 
					CONFIG_MTD_UBI_BEB_LIMIT=20
 | 
				
			||||||
CONFIG_MTD_UBI_BLOCK=y
 | 
					CONFIG_MTD_UBI_BLOCK=y
 | 
				
			||||||
 | 
				
			|||||||
@ -34,15 +34,6 @@
 | 
				
			|||||||
	nand@41000000 {
 | 
						nand@41000000 {
 | 
				
			||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		partition@0 {
 | 
					 | 
				
			||||||
			label = "boot";
 | 
					 | 
				
			||||||
			reg = <0x0 0x26c0000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@26c0000 {
 | 
					 | 
				
			||||||
			label = "ubi";
 | 
					 | 
				
			||||||
			reg = <0x26c0000 0xd940000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ethernet@40400000 {
 | 
						ethernet@40400000 {
 | 
				
			||||||
@ -132,3 +123,24 @@
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nandc {
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand@0 {
 | 
				
			||||||
 | 
							reg = <0>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <1>;
 | 
				
			||||||
 | 
							nand-ecc-mode = "soft";
 | 
				
			||||||
 | 
							nand-ecc-algo = "hamming";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@0 {
 | 
				
			||||||
 | 
								label = "boot";
 | 
				
			||||||
 | 
								reg = <0x00000000 0x026c0000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@26c0000 {
 | 
				
			||||||
 | 
								label = "ubi";
 | 
				
			||||||
 | 
								reg = <0x026c0000 0x0d940000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -31,37 +31,6 @@
 | 
				
			|||||||
		nr-ports = <2>;
 | 
							nr-ports = <2>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand@41000000 {
 | 
					 | 
				
			||||||
		status = "okay";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@0 {
 | 
					 | 
				
			||||||
			label = "stage1";
 | 
					 | 
				
			||||||
			reg = <0x00000000 0x00040000>;
 | 
					 | 
				
			||||||
			read-only;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@40000 {
 | 
					 | 
				
			||||||
			label = "u-boot";
 | 
					 | 
				
			||||||
			reg = <0x00040000 0x00200000>;
 | 
					 | 
				
			||||||
			read-only;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@240000 {
 | 
					 | 
				
			||||||
			label = "initrd";
 | 
					 | 
				
			||||||
			reg = <0x00240000 0x00600000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@840000 {
 | 
					 | 
				
			||||||
			label = "kernel";
 | 
					 | 
				
			||||||
			reg = <0x00840000 0x007C0000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@e00000 {
 | 
					 | 
				
			||||||
			label = "ubi";
 | 
					 | 
				
			||||||
			reg = <0x01000000 0x07000000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ethernet@40400000 {
 | 
						ethernet@40400000 {
 | 
				
			||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
		snps,phy-addr = <1>;
 | 
							snps,phy-addr = <1>;
 | 
				
			||||||
@ -163,3 +132,42 @@
 | 
				
			|||||||
		gpios = <&GPIOA 9 0>;
 | 
							gpios = <&GPIOA 9 0>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nandc {
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand@0 {
 | 
				
			||||||
 | 
							reg = <0>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <1>;
 | 
				
			||||||
 | 
							nand-ecc-mode = "soft";
 | 
				
			||||||
 | 
							nand-ecc-algo = "hamming";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@0 {
 | 
				
			||||||
 | 
								label = "stage1";
 | 
				
			||||||
 | 
								reg = <0x00000000 0x00040000>;
 | 
				
			||||||
 | 
								read-only;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@40000 {
 | 
				
			||||||
 | 
								label = "u-boot";
 | 
				
			||||||
 | 
								reg = <0x00040000 0x00200000>;
 | 
				
			||||||
 | 
								read-only;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@240000 {
 | 
				
			||||||
 | 
								label = "initrd";
 | 
				
			||||||
 | 
								reg = <0x00240000 0x00600000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@840000 {
 | 
				
			||||||
 | 
								label = "kernel";
 | 
				
			||||||
 | 
								reg = <0x00840000 0x007C0000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@e00000 {
 | 
				
			||||||
 | 
								label = "ubi";
 | 
				
			||||||
 | 
								reg = <0x01000000 0x07000000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -28,21 +28,6 @@
 | 
				
			|||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand@41000000 {
 | 
					 | 
				
			||||||
		status = "okay";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@0 {
 | 
					 | 
				
			||||||
			label = "boot";
 | 
					 | 
				
			||||||
			reg = <0x00000000 0x00e00000>;
 | 
					 | 
				
			||||||
			/*read-only;*/
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@e00000 {
 | 
					 | 
				
			||||||
			label = "ubi";
 | 
					 | 
				
			||||||
			reg = <0x00e00000 0x07200000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ethernet@40400000 {
 | 
						ethernet@40400000 {
 | 
				
			||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
@ -84,3 +69,26 @@
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nandc {
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand@0 {
 | 
				
			||||||
 | 
							reg = <0>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <1>;
 | 
				
			||||||
 | 
							nand-ecc-mode = "soft";
 | 
				
			||||||
 | 
							nand-ecc-algo = "hamming";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@0 {
 | 
				
			||||||
 | 
								label = "boot";
 | 
				
			||||||
 | 
								reg = <0x00000000 0x00e00000>;
 | 
				
			||||||
 | 
								/*read-only;*/
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@e00000 {
 | 
				
			||||||
 | 
								label = "ubi";
 | 
				
			||||||
 | 
								reg = <0x00e00000 0x07200000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -25,21 +25,6 @@
 | 
				
			|||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand@41000000 {
 | 
					 | 
				
			||||||
		status = "okay";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@0 {
 | 
					 | 
				
			||||||
			label = "boot";
 | 
					 | 
				
			||||||
			reg = <0x00000000 0x00e00000>;
 | 
					 | 
				
			||||||
			/*read-only;*/
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@e00000 {
 | 
					 | 
				
			||||||
			label = "ubi";
 | 
					 | 
				
			||||||
			reg = <0x00e00000 0x07200000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ethernet@40400000 {
 | 
						ethernet@40400000 {
 | 
				
			||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
@ -81,3 +66,26 @@
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nandc {
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand@0 {
 | 
				
			||||||
 | 
							reg = <0>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <1>;
 | 
				
			||||||
 | 
							nand-ecc-mode = "soft";
 | 
				
			||||||
 | 
							nand-ecc-algo = "hamming";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@0 {
 | 
				
			||||||
 | 
								label = "boot";
 | 
				
			||||||
 | 
								reg = <0x00000000 0x00e00000>;
 | 
				
			||||||
 | 
								/*read-only;*/
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@e00000 {
 | 
				
			||||||
 | 
								label = "ubi";
 | 
				
			||||||
 | 
								reg = <0x00e00000 0x07200000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -27,20 +27,6 @@
 | 
				
			|||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand@41000000 {
 | 
					 | 
				
			||||||
		status = "okay";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@0 {
 | 
					 | 
				
			||||||
			label = "boot";
 | 
					 | 
				
			||||||
			reg = <0x00000000 0x00e00000>;
 | 
					 | 
				
			||||||
			/*read-only;*/
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		partition@e00000 {
 | 
					 | 
				
			||||||
			label = "ubi";
 | 
					 | 
				
			||||||
			reg = <0x00e00000 0x07200000>;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ethernet@40400000 {
 | 
						ethernet@40400000 {
 | 
				
			||||||
		status = "okay";
 | 
							status = "okay";
 | 
				
			||||||
@ -91,3 +77,26 @@
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nandc {
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand@0 {
 | 
				
			||||||
 | 
							reg = <0>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <1>;
 | 
				
			||||||
 | 
							nand-ecc-mode = "soft";
 | 
				
			||||||
 | 
							nand-ecc-algo = "hamming";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@0 {
 | 
				
			||||||
 | 
								label = "boot";
 | 
				
			||||||
 | 
								reg = <0x00000000 0x00e00000>;
 | 
				
			||||||
 | 
								read-only;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							partition@e00000 {
 | 
				
			||||||
 | 
								label = "ubi";
 | 
				
			||||||
 | 
								reg = <0x00e00000 0x07200000>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -298,16 +298,15 @@
 | 
				
			|||||||
		status = "disabled";
 | 
							status = "disabled";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand@41000000 {
 | 
						nandc: nand-controller@41000000 {
 | 
				
			||||||
		compatible = "plxtech,nand-nas782x", "gen_nand";
 | 
							compatible = "oxsemi,ox820-nand";
 | 
				
			||||||
		reg = <0x41000000 0x100000>, <0x41C00000 0x20>;
 | 
							reg = <0x41000000 0x100000>;
 | 
				
			||||||
		nand-ecc-mode = "soft";
 | 
					 | 
				
			||||||
		clocks = <&stdclk 9>;
 | 
							clocks = <&stdclk 9>;
 | 
				
			||||||
		pinctrl-names = "default";
 | 
							pinctrl-names = "default";
 | 
				
			||||||
		pinctrl-0 = <&pinctrl_nand0>;
 | 
							pinctrl-0 = <&pinctrl_nand0>;
 | 
				
			||||||
		resets = <&rst 15>;
 | 
							resets = <&rst 15>;
 | 
				
			||||||
		#address-cells = <1>;
 | 
							#address-cells = <1>;
 | 
				
			||||||
		#size-cells = <1>;
 | 
							#size-cells = <0>;
 | 
				
			||||||
		status = "disabled";
 | 
							status = "disabled";
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,94 +1,211 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *  This program is free software; you can redistribute it and/or modify it
 | 
					 * Oxford Semiconductor OXNAS NAND driver
 | 
				
			||||||
 *  under the terms of the GNU General Public License version 2 as published
 | 
					
 | 
				
			||||||
 *  by the Free Software Foundation.
 | 
					 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
 | 
				
			||||||
 | 
					 * Heavily based on plat_nand.c :
 | 
				
			||||||
 | 
					 * Author: Vitaly Wool <vitalywool@gmail.com>
 | 
				
			||||||
 | 
					 * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  based on xway_nand.c
 | 
					 | 
				
			||||||
 *  Copyright © 2012 John Crispin <blogic@openwrt.org>
 | 
					 | 
				
			||||||
 *  and oxnas_nand.c "NAND glue for Oxnas platforms"
 | 
					 | 
				
			||||||
 *  written by Ma Haijun <mahaijuns@gmail.com>
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/mtd/nand.h>
 | 
					#include <linux/err.h>
 | 
				
			||||||
#include <linux/of_gpio.h>
 | 
					#include <linux/io.h>
 | 
				
			||||||
#include <linux/of_platform.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/clk.h>
 | 
					#include <linux/clk.h>
 | 
				
			||||||
#include <linux/reset.h>
 | 
					#include <linux/reset.h>
 | 
				
			||||||
 | 
					#include <linux/mtd/mtd.h>
 | 
				
			||||||
 | 
					#include <linux/mtd/nand.h>
 | 
				
			||||||
 | 
					#include <linux/mtd/partitions.h>
 | 
				
			||||||
 | 
					#include <linux/of.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* nand commands */
 | 
					/* Nand commands */
 | 
				
			||||||
#define NAND_CMD_ALE		BIT(18)
 | 
					#define OXNAS_NAND_CMD_ALE		BIT(18)
 | 
				
			||||||
#define NAND_CMD_CLE		BIT(19)
 | 
					#define OXNAS_NAND_CMD_CLE		BIT(19)
 | 
				
			||||||
#define NAND_CMD_CS		0
 | 
					 | 
				
			||||||
#define NAND_CMD_RESET		0xff
 | 
					 | 
				
			||||||
#define NAND_CMD		(NAND_CMD_CS | NAND_CMD_CLE)
 | 
					 | 
				
			||||||
#define NAND_ADDR		(NAND_CMD_CS | NAND_CMD_ALE)
 | 
					 | 
				
			||||||
#define NAND_DATA		(NAND_CMD_CS)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void oxnas_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 | 
					#define OXNAS_NAND_MAX_CHIPS	1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct oxnas_nand {
 | 
				
			||||||
 | 
						struct nand_hw_control base;
 | 
				
			||||||
 | 
						void __iomem *io_base;
 | 
				
			||||||
 | 
						struct clk *clk;
 | 
				
			||||||
 | 
						struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
 | 
				
			||||||
 | 
						unsigned long ctrl;
 | 
				
			||||||
 | 
						struct mtd_partition *partitions;
 | 
				
			||||||
 | 
						int nr_partitions;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nand_chip *this = mtd->priv;
 | 
						struct nand_chip *chip = mtd_to_nand(mtd);
 | 
				
			||||||
	unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
 | 
						struct oxnas_nand *oxnas = nand_get_controller_data(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return readb(oxnas->io_base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nand_chip *chip = mtd_to_nand(mtd);
 | 
				
			||||||
 | 
						struct oxnas_nand *oxnas = nand_get_controller_data(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ioread8_rep(oxnas->io_base, buf, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void oxnas_nand_write_buf(struct mtd_info *mtd,
 | 
				
			||||||
 | 
									 const uint8_t *buf, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nand_chip *chip = mtd_to_nand(mtd);
 | 
				
			||||||
 | 
						struct oxnas_nand *oxnas = nand_get_controller_data(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Single CS command control */
 | 
				
			||||||
 | 
					static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
 | 
				
			||||||
 | 
									unsigned int ctrl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nand_chip *chip = mtd_to_nand(mtd);
 | 
				
			||||||
 | 
						struct oxnas_nand *oxnas = nand_get_controller_data(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ctrl & NAND_CTRL_CHANGE) {
 | 
						if (ctrl & NAND_CTRL_CHANGE) {
 | 
				
			||||||
		nandaddr &= ~(NAND_CMD | NAND_ADDR);
 | 
					 | 
				
			||||||
		if (ctrl & NAND_CLE)
 | 
							if (ctrl & NAND_CLE)
 | 
				
			||||||
			nandaddr |= NAND_CMD;
 | 
								oxnas->ctrl = OXNAS_NAND_CMD_CLE;
 | 
				
			||||||
		else if (ctrl & NAND_ALE)
 | 
							else if (ctrl & NAND_ALE)
 | 
				
			||||||
			nandaddr |= NAND_ADDR;
 | 
								oxnas->ctrl = OXNAS_NAND_CMD_ALE;
 | 
				
			||||||
		this->IO_ADDR_W = (void __iomem *) nandaddr;
 | 
							else
 | 
				
			||||||
 | 
								oxnas->ctrl = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cmd != NAND_CMD_NONE)
 | 
						if (cmd != NAND_CMD_NONE)
 | 
				
			||||||
		writeb(cmd, (void __iomem *) nandaddr);
 | 
							writeb(cmd, oxnas->io_base + oxnas->ctrl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int oxnas_nand_probe(struct platform_device *pdev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* enable clock and release static block reset */
 | 
					 | 
				
			||||||
	struct clk *clk = of_clk_get(pdev->dev.of_node, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (IS_ERR(clk))
 | 
					 | 
				
			||||||
		return PTR_ERR(clk);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clk_prepare_enable(clk);
 | 
					 | 
				
			||||||
	device_reset(&pdev->dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* allow users to override the partition in DT using the cmdline */
 | 
					 | 
				
			||||||
static const char * part_probes[] = { "cmdlinepart", "ofpart", NULL };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct platform_nand_data oxnas_nand_data = {
 | 
					 | 
				
			||||||
	.chip = {
 | 
					 | 
				
			||||||
		.nr_chips		= 1,
 | 
					 | 
				
			||||||
		.chip_delay		= 30,
 | 
					 | 
				
			||||||
		.part_probe_types	= part_probes,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	.ctrl = {
 | 
					 | 
				
			||||||
		.probe		= oxnas_nand_probe,
 | 
					 | 
				
			||||||
		.cmd_ctrl	= oxnas_cmd_ctrl,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Try to find the node inside the DT. If it is available attach out
 | 
					 * Probe for the NAND device.
 | 
				
			||||||
 * platform_nand_data
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int __init oxnas_register_nand(void)
 | 
					static int oxnas_nand_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct device_node *node;
 | 
						struct device_node *np = pdev->dev.of_node;
 | 
				
			||||||
	struct platform_device *pdev;
 | 
						struct device_node *nand_np;
 | 
				
			||||||
 | 
						struct oxnas_nand *oxnas;
 | 
				
			||||||
 | 
						struct nand_chip *chip;
 | 
				
			||||||
 | 
						struct mtd_info *mtd;
 | 
				
			||||||
 | 
						struct resource *res;
 | 
				
			||||||
 | 
						int nchips = 0;
 | 
				
			||||||
 | 
						int count = 0;
 | 
				
			||||||
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node = of_find_compatible_node(NULL, NULL, "plxtech,nand-nas782x");
 | 
						/* Allocate memory for the device structure (and zero it) */
 | 
				
			||||||
	if (!node)
 | 
						oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
 | 
				
			||||||
		return -ENOENT;
 | 
								    GFP_KERNEL);
 | 
				
			||||||
	pdev = of_find_device_by_node(node);
 | 
						if (!oxnas)
 | 
				
			||||||
	if (!pdev)
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nand_hw_control_init(&oxnas->base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
				
			||||||
 | 
						oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
 | 
				
			||||||
 | 
						if (IS_ERR(oxnas->io_base))
 | 
				
			||||||
 | 
							return PTR_ERR(oxnas->io_base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oxnas->clk = devm_clk_get(&pdev->dev, NULL);
 | 
				
			||||||
 | 
						if (IS_ERR(oxnas->clk))
 | 
				
			||||||
 | 
							oxnas->clk = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Only a single chip node is supported */
 | 
				
			||||||
 | 
						count = of_get_child_count(np);
 | 
				
			||||||
 | 
						pr_info("########### count: %d\n", count);
 | 
				
			||||||
 | 
						if (count > 1)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	pdev->dev.platform_data = &oxnas_nand_data;
 | 
					
 | 
				
			||||||
	of_node_put(node);
 | 
						clk_prepare_enable(oxnas->clk);
 | 
				
			||||||
 | 
						device_reset_optional(&pdev->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for_each_child_of_node(np, nand_np) {
 | 
				
			||||||
 | 
							chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
 | 
				
			||||||
 | 
									    GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!chip)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							chip->controller = &oxnas->base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							nand_set_flash_node(chip, nand_np);
 | 
				
			||||||
 | 
							nand_set_controller_data(chip, oxnas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mtd = nand_to_mtd(chip);
 | 
				
			||||||
 | 
							mtd->dev.parent = &pdev->dev;
 | 
				
			||||||
 | 
							mtd->priv = chip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							chip->cmd_ctrl = oxnas_nand_cmd_ctrl;
 | 
				
			||||||
 | 
							chip->read_buf = oxnas_nand_read_buf;
 | 
				
			||||||
 | 
							chip->read_byte = oxnas_nand_read_byte;
 | 
				
			||||||
 | 
							chip->write_buf = oxnas_nand_write_buf;
 | 
				
			||||||
 | 
							chip->chip_delay = 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Scan to find existence of the device */
 | 
				
			||||||
 | 
							err = nand_scan(mtd, 1);
 | 
				
			||||||
 | 
							pr_info("########### nand_scan err: %d\n", err);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = mtd_device_register(mtd, NULL, 0);
 | 
				
			||||||
 | 
							pr_info("########### mtd_device_register err: %d\n", err);
 | 
				
			||||||
 | 
							if (err) {
 | 
				
			||||||
 | 
								nand_release(mtd);
 | 
				
			||||||
 | 
								return err;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							oxnas->chips[nchips] = chip;
 | 
				
			||||||
 | 
							++nchips;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_info("########### nchips: %d\n", nchips);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Exit if no chips found */
 | 
				
			||||||
 | 
						if (!nchips)
 | 
				
			||||||
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						platform_set_drvdata(pdev, oxnas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
subsys_initcall(oxnas_register_nand);
 | 
					static int oxnas_nand_remove(struct platform_device *pdev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct oxnas_nand *oxnas = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (oxnas->chips[0])
 | 
				
			||||||
 | 
							nand_release(nand_to_mtd(oxnas->chips[0]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clk_disable_unprepare(oxnas->clk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct of_device_id oxnas_nand_match[] = {
 | 
				
			||||||
 | 
						{ .compatible = "oxsemi,ox820-nand" },
 | 
				
			||||||
 | 
						{},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					MODULE_DEVICE_TABLE(of, oxnas_nand_match);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct platform_driver oxnas_nand_driver = {
 | 
				
			||||||
 | 
						.probe	= oxnas_nand_probe,
 | 
				
			||||||
 | 
						.remove	= oxnas_nand_remove,
 | 
				
			||||||
 | 
						.driver	= {
 | 
				
			||||||
 | 
							.name		= "oxnas_nand",
 | 
				
			||||||
 | 
							.of_match_table = oxnas_nand_match,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_platform_driver(oxnas_nand_driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
 | 
				
			||||||
 | 
					MODULE_DESCRIPTION("Oxnas NAND driver");
 | 
				
			||||||
 | 
					MODULE_ALIAS("platform:oxnas_nand");
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					From 410a91f6efa1c4c3c4369d1dd2c31286749dff33 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
				
			||||||
 | 
					Date: Wed, 23 Mar 2016 11:19:01 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH 073/102] of: mtd: prepare helper reading NAND ECC algo from
 | 
				
			||||||
 | 
					 DT
 | 
				
			||||||
 | 
					MIME-Version: 1.0
 | 
				
			||||||
 | 
					Content-Type: text/plain; charset=UTF-8
 | 
				
			||||||
 | 
					Content-Transfer-Encoding: 8bit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NAND subsystem is being slightly reworked to store ECC details in
 | 
				
			||||||
 | 
					separated fields. In future we'll want to add support for more DT
 | 
				
			||||||
 | 
					properties as specifying every possible setup with a single
 | 
				
			||||||
 | 
					"nand-ecc-mode" is a pretty bad idea.
 | 
				
			||||||
 | 
					To allow this let's add a helper that will support something like
 | 
				
			||||||
 | 
					"nand-ecc-algo" in future. Right now we use it for keeping backward
 | 
				
			||||||
 | 
					compatibility.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
				
			||||||
 | 
					Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					 drivers/of/of_mtd.c    |   36 ++++++++++++++++++++++++++++++++++++
 | 
				
			||||||
 | 
					 include/linux/of_mtd.h |    6 ++++++
 | 
				
			||||||
 | 
					 2 files changed, 42 insertions(+)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/drivers/of/of_mtd.c
 | 
				
			||||||
 | 
					+++ b/drivers/of/of_mtd.c
 | 
				
			||||||
 | 
					@@ -50,6 +50,42 @@ int of_get_nand_ecc_mode(struct device_n
 | 
				
			||||||
 | 
					 EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
 | 
					+ * of_get_nand_ecc_algo - Get nand ecc algorithm for given device_node
 | 
				
			||||||
 | 
					+ * @np:	Pointer to the given device_node
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * The function gets ecc algorithm and returns its enum value, or errno in error
 | 
				
			||||||
 | 
					+ * case.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+int of_get_nand_ecc_algo(struct device_node *np)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	const char *pm;
 | 
				
			||||||
 | 
					+	int err;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * TODO: Read ECC algo OF property and map it to enum nand_ecc_algo.
 | 
				
			||||||
 | 
					+	 * It's not implemented yet as currently NAND subsystem ignores
 | 
				
			||||||
 | 
					+	 * algorithm explicitly set this way. Once it's handled we should
 | 
				
			||||||
 | 
					+	 * document & support new property.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * For backward compatibility we also read "nand-ecc-mode" checking
 | 
				
			||||||
 | 
					+	 * for some obsoleted values that were specifying ECC algorithm.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	err = of_property_read_string(np, "nand-ecc-mode", &pm);
 | 
				
			||||||
 | 
					+	if (err < 0)
 | 
				
			||||||
 | 
					+		return err;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (!strcasecmp(pm, "soft"))
 | 
				
			||||||
 | 
					+		return NAND_ECC_HAMMING;
 | 
				
			||||||
 | 
					+	else if (!strcasecmp(pm, "soft_bch"))
 | 
				
			||||||
 | 
					+		return NAND_ECC_BCH;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return -ENODEV;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+EXPORT_SYMBOL_GPL(of_get_nand_ecc_algo);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+/**
 | 
				
			||||||
 | 
					  * of_get_nand_ecc_step_size - Get ECC step size associated to
 | 
				
			||||||
 | 
					  * the required ECC strength (see below).
 | 
				
			||||||
 | 
					  * @np:	Pointer to the given device_node
 | 
				
			||||||
 | 
					--- a/include/linux/of_mtd.h
 | 
				
			||||||
 | 
					+++ b/include/linux/of_mtd.h
 | 
				
			||||||
 | 
					@@ -13,6 +13,7 @@
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #include <linux/of.h>
 | 
				
			||||||
 | 
					 int of_get_nand_ecc_mode(struct device_node *np);
 | 
				
			||||||
 | 
					+int of_get_nand_ecc_algo(struct device_node *np);
 | 
				
			||||||
 | 
					 int of_get_nand_ecc_step_size(struct device_node *np);
 | 
				
			||||||
 | 
					 int of_get_nand_ecc_strength(struct device_node *np);
 | 
				
			||||||
 | 
					 int of_get_nand_bus_width(struct device_node *np);
 | 
				
			||||||
 | 
					@@ -24,6 +25,11 @@ static inline int of_get_nand_ecc_mode(s
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	return -ENOSYS;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline int of_get_nand_ecc_algo(struct device_node *np)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return -ENOSYS;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static inline int of_get_nand_ecc_step_size(struct device_node *np)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					From d45bc58dd3bdcaabc1d7d8d9b0b8dee826635cc6 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
 | 
				
			||||||
 | 
					Date: Wed, 27 Jul 2016 11:23:52 +0200
 | 
				
			||||||
 | 
					Subject: [PATCH] mtd: nand: import nand_hw_control_init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The code to initialize a struct nand_hw_control is duplicated across
 | 
				
			||||||
 | 
					several drivers. Factorize it using an inline function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
 | 
				
			||||||
 | 
					Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					 drivers/mtd/nand/bf5xx_nand.c        | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/brcmnand/brcmnand.c | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/docg4.c             | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/fsl_elbc_nand.c     | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/fsl_ifc_nand.c      | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/jz4780_nand.c       | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/nand_base.c         | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/ndfc.c              | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/pxa3xx_nand.c       | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/qcom_nandc.c        | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/s3c2410.c           | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/sunxi_nand.c        | 3 +--
 | 
				
			||||||
 | 
					 drivers/mtd/nand/txx9ndfmc.c         | 3 +--
 | 
				
			||||||
 | 
					 include/linux/mtd/nand.h             | 7 +++++++
 | 
				
			||||||
 | 
					 14 files changed, 20 insertions(+), 26 deletions(-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
 | 
				
			||||||
 | 
					index 37da423..3962f55 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/bf5xx_nand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/bf5xx_nand.c
 | 
				
			||||||
 | 
					@@ -761,8 +761,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	platform_set_drvdata(pdev, info);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	spin_lock_init(&info->controller.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&info->controller.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&info->controller);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	info->device     = &pdev->dev;
 | 
				
			||||||
 | 
					 	info->platform   = plat;
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
 | 
				
			||||||
 | 
					index 8eb2c64..82ec36b 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/brcmnand/brcmnand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
 | 
				
			||||||
 | 
					@@ -2370,8 +2370,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	init_completion(&ctrl->done);
 | 
				
			||||||
 | 
					 	init_completion(&ctrl->dma_done);
 | 
				
			||||||
 | 
					-	spin_lock_init(&ctrl->controller.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&ctrl->controller.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&ctrl->controller);
 | 
				
			||||||
 | 
					 	INIT_LIST_HEAD(&ctrl->host_list);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* NAND register range */
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
 | 
				
			||||||
 | 
					index 4731699..7af2a3c 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/docg4.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/docg4.c
 | 
				
			||||||
 | 
					@@ -1249,8 +1249,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
 | 
				
			||||||
 | 
					 	nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE;
 | 
				
			||||||
 | 
					 	nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA;
 | 
				
			||||||
 | 
					 	nand->controller = &nand->hwcontrol;
 | 
				
			||||||
 | 
					-	spin_lock_init(&nand->controller->lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&nand->controller->wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(nand->controller);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* methods */
 | 
				
			||||||
 | 
					 	nand->cmdfunc = docg4_command;
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
 | 
				
			||||||
 | 
					index 60a88f2..113f76e 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/fsl_elbc_nand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/fsl_elbc_nand.c
 | 
				
			||||||
 | 
					@@ -879,8 +879,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					 		elbc_fcm_ctrl->counter++;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-		spin_lock_init(&elbc_fcm_ctrl->controller.lock);
 | 
				
			||||||
 | 
					-		init_waitqueue_head(&elbc_fcm_ctrl->controller.wq);
 | 
				
			||||||
 | 
					+		nand_hw_control_init(&elbc_fcm_ctrl->controller);
 | 
				
			||||||
 | 
					 		fsl_lbc_ctrl_dev->nand = elbc_fcm_ctrl;
 | 
				
			||||||
 | 
					 	} else {
 | 
				
			||||||
 | 
					 		elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
 | 
				
			||||||
 | 
					index 4e9e5fd..0a177b1 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/fsl_ifc_nand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/fsl_ifc_nand.c
 | 
				
			||||||
 | 
					@@ -987,8 +987,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev)
 | 
				
			||||||
 | 
					 		ifc_nand_ctrl->addr = NULL;
 | 
				
			||||||
 | 
					 		fsl_ifc_ctrl_dev->nand = ifc_nand_ctrl;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-		spin_lock_init(&ifc_nand_ctrl->controller.lock);
 | 
				
			||||||
 | 
					-		init_waitqueue_head(&ifc_nand_ctrl->controller.wq);
 | 
				
			||||||
 | 
					+		nand_hw_control_init(&ifc_nand_ctrl->controller);
 | 
				
			||||||
 | 
					 	} else {
 | 
				
			||||||
 | 
					 		ifc_nand_ctrl = fsl_ifc_ctrl_dev->nand;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
 | 
				
			||||||
 | 
					index 77533f7..53ea796 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/nand_base.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/nand_base.c
 | 
				
			||||||
 | 
					@@ -3191,8 +3191,7 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (!chip->controller) {
 | 
				
			||||||
 | 
					 		chip->controller = &chip->hwcontrol;
 | 
				
			||||||
 | 
					-		spin_lock_init(&chip->controller->lock);
 | 
				
			||||||
 | 
					-		init_waitqueue_head(&chip->controller->wq);
 | 
				
			||||||
 | 
					+		nand_hw_control_init(chip->controller);
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
 | 
				
			||||||
 | 
					index 218c789..28e6118 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/ndfc.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/ndfc.c
 | 
				
			||||||
 | 
					@@ -218,8 +218,7 @@ static int ndfc_probe(struct platform_device *ofdev)
 | 
				
			||||||
 | 
					 	ndfc = &ndfc_ctrl[cs];
 | 
				
			||||||
 | 
					 	ndfc->chip_select = cs;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	spin_lock_init(&ndfc->ndfc_control.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&ndfc->ndfc_control.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&ndfc->ndfc_control);
 | 
				
			||||||
 | 
					 	ndfc->ofdev = ofdev;
 | 
				
			||||||
 | 
					 	dev_set_drvdata(&ofdev->dev, ndfc);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
 | 
				
			||||||
 | 
					index 436dd6d..b121bf4 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/pxa3xx_nand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/pxa3xx_nand.c
 | 
				
			||||||
 | 
					@@ -1810,8 +1810,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 | 
				
			||||||
 | 
					 		chip->cmdfunc		= nand_cmdfunc;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	spin_lock_init(&chip->controller->lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&chip->controller->wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(chip->controller);
 | 
				
			||||||
 | 
					 	info->clk = devm_clk_get(&pdev->dev, NULL);
 | 
				
			||||||
 | 
					 	if (IS_ERR(info->clk)) {
 | 
				
			||||||
 | 
					 		dev_err(&pdev->dev, "failed to get nand clock\n");
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
 | 
				
			||||||
 | 
					index d9309cf..b1734d7 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/s3c2410.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/s3c2410.c
 | 
				
			||||||
 | 
					@@ -977,8 +977,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	platform_set_drvdata(pdev, info);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	spin_lock_init(&info->controller.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&info->controller.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&info->controller);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* get the clock source and enable it */
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
 | 
				
			||||||
 | 
					index e414b31..8b5dadc 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/sunxi_nand.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/sunxi_nand.c
 | 
				
			||||||
 | 
					@@ -2175,8 +2175,7 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					 		return -ENOMEM;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	nfc->dev = dev;
 | 
				
			||||||
 | 
					-	spin_lock_init(&nfc->controller.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&nfc->controller.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&nfc->controller);
 | 
				
			||||||
 | 
					 	INIT_LIST_HEAD(&nfc->chips);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
				
			||||||
 | 
					diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
 | 
				
			||||||
 | 
					index 04d63f5..0a14fda 100644
 | 
				
			||||||
 | 
					--- a/drivers/mtd/nand/txx9ndfmc.c
 | 
				
			||||||
 | 
					+++ b/drivers/mtd/nand/txx9ndfmc.c
 | 
				
			||||||
 | 
					@@ -303,8 +303,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
 | 
				
			||||||
 | 
					 	dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
 | 
				
			||||||
 | 
					 		 (gbusclk + 500000) / 1000000, hold, spw);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	spin_lock_init(&drvdata->hw_control.lock);
 | 
				
			||||||
 | 
					-	init_waitqueue_head(&drvdata->hw_control.wq);
 | 
				
			||||||
 | 
					+	nand_hw_control_init(&drvdata->hw_control);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	platform_set_drvdata(dev, drvdata);
 | 
				
			||||||
 | 
					 	txx9ndfmc_initialize(dev);
 | 
				
			||||||
 | 
					diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
 | 
				
			||||||
 | 
					index 8dd6e01..f6a2d5e 100644
 | 
				
			||||||
 | 
					--- a/include/linux/mtd/nand.h
 | 
				
			||||||
 | 
					+++ b/include/linux/mtd/nand.h
 | 
				
			||||||
 | 
					@@ -460,6 +460,13 @@ struct nand_hw_control {
 | 
				
			||||||
 | 
					 	wait_queue_head_t wq;
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+static inline void nand_hw_control_init(struct nand_hw_control *nfc)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	nfc->active = NULL;
 | 
				
			||||||
 | 
					+	spin_lock_init(&nfc->lock);
 | 
				
			||||||
 | 
					+	init_waitqueue_head(&nfc->wq);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
 | 
					  * struct nand_ecc_ctrl - Control structure for ECC
 | 
				
			||||||
 | 
					  * @mode:	ECC mode
 | 
				
			||||||
 | 
					-- 
 | 
				
			||||||
 | 
					2.10.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,13 +1,12 @@
 | 
				
			|||||||
--- a/drivers/mtd/nand/Kconfig
 | 
					--- a/drivers/mtd/nand/Kconfig
 | 
				
			||||||
+++ b/drivers/mtd/nand/Kconfig
 | 
					+++ b/drivers/mtd/nand/Kconfig
 | 
				
			||||||
@@ -546,4 +546,12 @@ config MTD_NAND_HISI504
 | 
					@@ -546,4 +546,11 @@ config MTD_NAND_HISI504
 | 
				
			||||||
 	help
 | 
					 	help
 | 
				
			||||||
 	  Enables support for NAND controller on Hisilicon SoC Hip04.
 | 
					 	  Enables support for NAND controller on Hisilicon SoC Hip04.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
+config MTD_NAND_OXNAS
 | 
					+config MTD_NAND_OXNAS
 | 
				
			||||||
+	tristate "Support for NAND on Plxtech NAS782X SoC"
 | 
					+	tristate "Support for NAND on Plxtech NAS782X SoC"
 | 
				
			||||||
+	depends on ARCH_OXNAS
 | 
					+	depends on ARCH_OXNAS
 | 
				
			||||||
+	select MTD_NAND_PLATFORM
 | 
					 | 
				
			||||||
+	help
 | 
					+	help
 | 
				
			||||||
+	  Enables support for NAND Flash chips on Plxtech NAS782X SoCs. NAND is attached
 | 
					+	  Enables support for NAND Flash chips on Plxtech NAS782X SoCs. NAND is attached
 | 
				
			||||||
+	  to the STATIC Unit.
 | 
					+	  to the STATIC Unit.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user