2005-09-09 10:39:50 +04:00
/*
* linux / drivers / mtd / onenand / generic . c
*
* Copyright ( c ) 2005 Samsung Electronics
* Kyungmin Park < kyungmin . park @ samsung . 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 .
*
* Overview :
* This is a device driver for the OneNAND flash for generic boards .
*/
# include <linux/module.h>
# include <linux/init.h>
2006-01-08 12:02:05 +03:00
# include <linux/slab.h>
2005-12-16 05:17:29 +03:00
# include <linux/platform_device.h>
2005-09-09 10:39:50 +04:00
# include <linux/mtd/mtd.h>
# include <linux/mtd/onenand.h>
# include <linux/mtd/partitions.h>
# include <asm/io.h>
2009-09-18 23:51:44 +04:00
/*
* Note : Driver name and platform data format have been updated !
*
* This version of the driver is named " onenand-flash " and takes struct
* onenand_platform_data as platform data . The old ARM - specific version
* with the name " onenand " used to take struct flash_platform_data .
*/
# define DRIVER_NAME "onenand-flash"
2005-09-09 10:39:50 +04:00
struct onenand_info {
struct mtd_info mtd ;
struct onenand_chip onenand ;
} ;
2012-11-19 22:23:07 +04:00
static int generic_onenand_probe ( struct platform_device * pdev )
2005-09-09 10:39:50 +04:00
{
struct onenand_info * info ;
2009-09-18 23:51:44 +04:00
struct onenand_platform_data * pdata = pdev - > dev . platform_data ;
2005-09-09 10:39:50 +04:00
struct resource * res = pdev - > resource ;
2009-09-18 23:51:44 +04:00
unsigned long size = resource_size ( res ) ;
2005-09-09 10:39:50 +04:00
int err ;
2006-11-15 22:10:29 +03:00
info = kzalloc ( sizeof ( struct onenand_info ) , GFP_KERNEL ) ;
2005-09-09 10:39:50 +04:00
if ( ! info )
return - ENOMEM ;
2009-09-18 23:51:44 +04:00
if ( ! request_mem_region ( res - > start , size , dev_name ( & pdev - > dev ) ) ) {
2005-09-09 10:39:50 +04:00
err = - EBUSY ;
goto out_free_info ;
}
info - > onenand . base = ioremap ( res - > start , size ) ;
if ( ! info - > onenand . base ) {
err = - ENOMEM ;
goto out_release_mem_region ;
}
2009-09-18 23:51:44 +04:00
info - > onenand . mmcontrol = pdata ? pdata - > mmcontrol : 0 ;
2006-11-16 05:23:48 +03:00
info - > onenand . irq = platform_get_irq ( pdev , 0 ) ;
2005-09-09 10:39:50 +04:00
2009-01-06 21:44:38 +03:00
info - > mtd . name = dev_name ( & pdev - > dev ) ;
2005-09-09 10:39:50 +04:00
info - > mtd . priv = & info - > onenand ;
info - > mtd . owner = THIS_MODULE ;
if ( onenand_scan ( & info - > mtd , 1 ) ) {
err = - ENXIO ;
goto out_iounmap ;
}
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 21:24:26 +04:00
err = mtd_device_parse_register ( & info - > mtd , NULL , NULL ,
pdata ? pdata - > parts : NULL ,
pdata ? pdata - > nr_parts : 0 ) ;
2005-09-09 10:39:50 +04:00
2009-02-06 18:40:12 +03:00
platform_set_drvdata ( pdev , info ) ;
2005-09-09 10:39:50 +04:00
return 0 ;
out_iounmap :
iounmap ( info - > onenand . base ) ;
out_release_mem_region :
release_mem_region ( res - > start , size ) ;
out_free_info :
kfree ( info ) ;
return err ;
}
2012-11-19 22:26:04 +04:00
static int generic_onenand_remove ( struct platform_device * pdev )
2005-09-09 10:39:50 +04:00
{
2009-02-06 18:40:12 +03:00
struct onenand_info * info = platform_get_drvdata ( pdev ) ;
2005-09-09 10:39:50 +04:00
struct resource * res = pdev - > resource ;
2009-09-18 23:51:44 +04:00
unsigned long size = resource_size ( res ) ;
2005-09-09 10:39:50 +04:00
2009-02-06 18:40:12 +03:00
platform_set_drvdata ( pdev , NULL ) ;
2005-09-09 10:39:50 +04:00
if ( info ) {
onenand_release ( & info - > mtd ) ;
release_mem_region ( res - > start , size ) ;
iounmap ( info - > onenand . base ) ;
kfree ( info ) ;
}
return 0 ;
}
2009-02-06 18:40:12 +03:00
static struct platform_driver generic_onenand_driver = {
. driver = {
. name = DRIVER_NAME ,
. owner = THIS_MODULE ,
} ,
2005-09-09 10:39:50 +04:00
. probe = generic_onenand_probe ,
2012-11-19 22:21:24 +04:00
. remove = generic_onenand_remove ,
2005-09-09 10:39:50 +04:00
} ;
2011-11-27 16:45:03 +04:00
module_platform_driver ( generic_onenand_driver ) ;
2005-09-09 10:39:50 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Kyungmin Park <kyungmin.park@samsung.com> " ) ;
MODULE_DESCRIPTION ( " Glue layer for OneNAND flash on generic boards " ) ;
2011-11-27 16:45:03 +04:00
MODULE_ALIAS ( " platform: " DRIVER_NAME ) ;