2007-05-06 19:31:18 +04:00
/*
* Generic NAND driver
*
* Author : Vitaly Wool < vitalywool @ gmail . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
*/
2014-01-03 11:16:28 +09:00
# include <linux/err.h>
2007-05-06 19:31:18 +04:00
# include <linux/io.h>
# include <linux/module.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/mtd/mtd.h>
# include <linux/mtd/nand.h>
# include <linux/mtd/partitions.h>
struct plat_nand_data {
struct nand_chip chip ;
void __iomem * io_base ;
} ;
/*
* Probe for the NAND device .
*/
2012-11-19 13:23:07 -05:00
static int plat_nand_probe ( struct platform_device * pdev )
2007-05-06 19:31:18 +04:00
{
2013-07-30 17:18:33 +09:00
struct platform_nand_data * pdata = dev_get_platdata ( & pdev - > dev ) ;
2007-05-06 19:31:18 +04:00
struct plat_nand_data * data ;
2015-12-10 09:00:19 +01:00
struct mtd_info * mtd ;
2009-10-19 19:45:29 -04:00
struct resource * res ;
2012-03-28 11:13:05 -07:00
const char * * part_types ;
2009-10-19 19:45:29 -04:00
int err = 0 ;
2012-07-22 08:59:57 +02:00
if ( ! pdata ) {
dev_err ( & pdev - > dev , " platform_nand_data is missing \n " ) ;
return - EINVAL ;
}
2010-08-12 03:53:55 +01:00
if ( pdata - > chip . nr_chips < 1 ) {
dev_err ( & pdev - > dev , " invalid number of chips specified \n " ) ;
return - EINVAL ;
}
2007-05-06 19:31:18 +04:00
/* Allocate memory for the device structure (and zero it) */
2014-01-03 11:16:28 +09:00
data = devm_kzalloc ( & pdev - > dev , sizeof ( struct plat_nand_data ) ,
GFP_KERNEL ) ;
2014-01-03 11:17:29 +09:00
if ( ! data )
2007-05-06 19:31:18 +04:00
return - ENOMEM ;
2014-01-07 21:38:12 +08:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2014-01-03 11:16:28 +09:00
data - > io_base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( data - > io_base ) )
return PTR_ERR ( data - > io_base ) ;
2007-05-06 19:31:18 +04:00
2015-10-30 20:33:25 -07:00
nand_set_flash_node ( & data - > chip , pdev - > dev . of_node ) ;
2015-12-10 09:00:19 +01:00
mtd = nand_to_mtd ( & data - > chip ) ;
mtd - > dev . parent = & pdev - > dev ;
2007-05-06 19:31:18 +04:00
data - > chip . IO_ADDR_R = data - > io_base ;
data - > chip . IO_ADDR_W = data - > io_base ;
data - > chip . cmd_ctrl = pdata - > ctrl . cmd_ctrl ;
data - > chip . dev_ready = pdata - > ctrl . dev_ready ;
data - > chip . select_chip = pdata - > ctrl . select_chip ;
2009-05-11 19:28:01 +01:00
data - > chip . write_buf = pdata - > ctrl . write_buf ;
data - > chip . read_buf = pdata - > ctrl . read_buf ;
2012-04-30 19:30:47 +02:00
data - > chip . read_byte = pdata - > ctrl . read_byte ;
2007-05-06 19:31:18 +04:00
data - > chip . chip_delay = pdata - > chip . chip_delay ;
data - > chip . options | = pdata - > chip . options ;
2011-05-31 16:31:22 -07:00
data - > chip . bbt_options | = pdata - > chip . bbt_options ;
2007-05-06 19:31:18 +04:00
data - > chip . ecc . hwctl = pdata - > ctrl . hwcontrol ;
data - > chip . ecc . mode = NAND_ECC_SOFT ;
2016-04-08 12:23:50 +02:00
data - > chip . ecc . algo = NAND_ECC_HAMMING ;
2007-05-06 19:31:18 +04:00
platform_set_drvdata ( pdev , data ) ;
2009-05-12 13:46:58 -07:00
/* Handle any platform specific setup */
if ( pdata - > ctrl . probe ) {
2009-10-19 19:45:29 -04:00
err = pdata - > ctrl . probe ( pdev ) ;
if ( err )
2009-05-12 13:46:58 -07:00
goto out ;
}
2011-03-30 22:57:33 -03:00
/* Scan to find existence of the device */
2016-11-04 19:42:57 +09:00
err = nand_scan ( mtd , pdata - > chip . nr_chips ) ;
if ( err )
2007-05-06 19:31:18 +04:00
goto out ;
2015-05-18 16:15:24 -07:00
part_types = pdata - > chip . part_probe_types ;
2012-03-28 11:13:05 -07:00
2015-12-10 09:00:19 +01:00
err = mtd_device_parse_register ( mtd , part_types , NULL ,
mtd: do not use plain 0 as NULL
The first 3 arguments of 'mtd_device_parse_register()' are pointers,
but many callers pass '0' instead of 'NULL'. Fix this globally. Thanks
to coccinelle for making it easy to do with the following semantic patch:
@@
expression mtd, types, parser_data, parts, nr_parts;
@@
(
-mtd_device_parse_register(mtd, 0, parser_data, parts, nr_parts)
+mtd_device_parse_register(mtd, NULL, parser_data, parts, nr_parts)
|
-mtd_device_parse_register(mtd, types, 0, parts, nr_parts)
+mtd_device_parse_register(mtd, types, NULL, parts, nr_parts)
|
-mtd_device_parse_register(mtd, types, parser_data, 0, nr_parts)
+mtd_device_parse_register(mtd, types, parser_data, NULL, nr_parts)
)
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2012-03-09 19:24:26 +02:00
pdata - > chip . partitions ,
pdata - > chip . nr_partitions ) ;
2007-05-06 19:31:18 +04:00
2009-10-19 19:45:29 -04:00
if ( ! err )
return err ;
2007-05-06 19:31:18 +04:00
2015-12-10 09:00:19 +01:00
nand_release ( mtd ) ;
2007-05-06 19:31:18 +04:00
out :
2009-05-12 13:46:58 -07:00
if ( pdata - > ctrl . remove )
pdata - > ctrl . remove ( pdev ) ;
2009-10-19 19:45:29 -04:00
return err ;
2007-05-06 19:31:18 +04:00
}
/*
* Remove a NAND device .
*/
2012-11-19 13:26:04 -05:00
static int plat_nand_remove ( struct platform_device * pdev )
2007-05-06 19:31:18 +04:00
{
struct plat_nand_data * data = platform_get_drvdata ( pdev ) ;
2013-07-30 17:18:33 +09:00
struct platform_nand_data * pdata = dev_get_platdata ( & pdev - > dev ) ;
2007-05-06 19:31:18 +04:00
2015-12-10 09:00:19 +01:00
nand_release ( nand_to_mtd ( & data - > chip ) ) ;
2009-05-12 13:46:58 -07:00
if ( pdata - > ctrl . remove )
pdata - > ctrl . remove ( pdev ) ;
2007-05-06 19:31:18 +04:00
return 0 ;
}
2012-04-30 19:30:46 +02:00
static const struct of_device_id plat_nand_match [ ] = {
{ . compatible = " gen_nand " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , plat_nand_match ) ;
2007-05-06 19:31:18 +04:00
static struct platform_driver plat_nand_driver = {
2012-04-30 19:30:46 +02:00
. probe = plat_nand_probe ,
2012-11-19 13:21:24 -05:00
. remove = plat_nand_remove ,
2012-04-30 19:30:46 +02:00
. driver = {
. name = " gen_nand " ,
. of_match_table = plat_nand_match ,
2007-05-06 19:31:18 +04:00
} ,
} ;
2011-11-27 20:45:03 +08:00
module_platform_driver ( plat_nand_driver ) ;
2007-05-06 19:31:18 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Vitaly Wool " ) ;
MODULE_DESCRIPTION ( " Simple generic NAND driver " ) ;
2008-04-18 13:44:27 -07:00
MODULE_ALIAS ( " platform:gen_nand " ) ;