aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/fsl_upm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/fsl_upm.c')
-rw-r--r--drivers/mtd/nand/fsl_upm.c100
1 files changed, 41 insertions, 59 deletions
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index d120cd8d726..4d203e84e8c 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -18,9 +18,11 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/mtd.h>
+#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/fsl_lbc.h>
#define FSL_UPM_WAIT_RUN_PATTERN 0x1
@@ -32,10 +34,7 @@ struct fsl_upm_nand {
struct mtd_info mtd;
struct nand_chip chip;
int last_ctrl;
-#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
-#endif
-
struct fsl_upm upm;
uint8_t upm_addr_offset;
uint8_t upm_cmd_offset;
@@ -48,7 +47,10 @@ struct fsl_upm_nand {
uint32_t wait_flags;
};
-#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
+static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo)
+{
+ return container_of(mtdinfo, struct fsl_upm_nand, mtd);
+}
static int fun_chip_ready(struct mtd_info *mtd)
{
@@ -112,7 +114,7 @@ static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
if (mchip_nr == -1) {
chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
- } else if (mchip_nr >= 0) {
+ } else if (mchip_nr >= 0 && mchip_nr < NAND_MAX_CHIPS) {
fun->mchip_number = mchip_nr;
chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
chip->IO_ADDR_W = chip->IO_ADDR_R;
@@ -151,15 +153,13 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
fun_wait_rnb(fun);
}
-static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
- const struct device_node *upm_np,
- const struct resource *io_res)
+static int fun_chip_init(struct fsl_upm_nand *fun,
+ const struct device_node *upm_np,
+ const struct resource *io_res)
{
int ret;
struct device_node *flash_np;
-#ifdef CONFIG_MTD_PARTITIONS
- static const char *part_types[] = { "cmdlinepart", NULL, };
-#endif
+ struct mtd_part_parser_data ppdata;
fun->chip.IO_ADDR_R = fun->io_base;
fun->chip.IO_ADDR_W = fun->io_base;
@@ -182,7 +182,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
if (!flash_np)
return -ENODEV;
- fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start,
+ fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start,
flash_np->name);
if (!fun->mtd.name) {
ret = -ENOMEM;
@@ -193,32 +193,20 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
if (ret)
goto err;
-#ifdef CONFIG_MTD_PARTITIONS
- ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
-
-#ifdef CONFIG_MTD_OF_PARTS
- if (ret == 0) {
- ret = of_mtd_parse_partitions(fun->dev, flash_np, &fun->parts);
- if (ret < 0)
- goto err;
- }
-#endif
- if (ret > 0)
- ret = add_mtd_partitions(&fun->mtd, fun->parts, ret);
- else
-#endif
- ret = add_mtd_device(&fun->mtd);
+ ppdata.of_node = flash_np;
+ ret = mtd_device_parse_register(&fun->mtd, NULL, &ppdata, NULL, 0);
err:
of_node_put(flash_np);
+ if (ret)
+ kfree(fun->mtd.name);
return ret;
}
-static int __devinit fun_probe(struct of_device *ofdev,
- const struct of_device_id *ofid)
+static int fun_probe(struct platform_device *ofdev)
{
struct fsl_upm_nand *fun;
struct resource io_res;
- const uint32_t *prop;
+ const __be32 *prop;
int rnb_gpio;
int ret;
int size;
@@ -228,7 +216,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!fun)
return -ENOMEM;
- ret = of_address_to_resource(ofdev->node, 0, &io_res);
+ ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res);
if (ret) {
dev_err(&ofdev->dev, "can't get IO base\n");
goto err1;
@@ -240,7 +228,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
goto err1;
}
- prop = of_get_property(ofdev->node, "fsl,upm-addr-offset", &size);
+ prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-offset",
+ &size);
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM address offset\n");
ret = -EINVAL;
@@ -248,7 +237,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
}
fun->upm_addr_offset = *prop;
- prop = of_get_property(ofdev->node, "fsl,upm-cmd-offset", &size);
+ prop = of_get_property(ofdev->dev.of_node, "fsl,upm-cmd-offset", &size);
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM command offset\n");
ret = -EINVAL;
@@ -256,7 +245,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
}
fun->upm_cmd_offset = *prop;
- prop = of_get_property(ofdev->node,
+ prop = of_get_property(ofdev->dev.of_node,
"fsl,upm-addr-line-cs-offsets", &size);
if (prop && (size / sizeof(uint32_t)) > 0) {
fun->mchip_count = size / sizeof(uint32_t);
@@ -265,14 +254,14 @@ static int __devinit fun_probe(struct of_device *ofdev,
goto err1;
}
for (i = 0; i < fun->mchip_count; i++)
- fun->mchip_offsets[i] = prop[i];
+ fun->mchip_offsets[i] = be32_to_cpu(prop[i]);
} else {
fun->mchip_count = 1;
}
for (i = 0; i < fun->mchip_count; i++) {
fun->rnb_gpio[i] = -1;
- rnb_gpio = of_get_gpio(ofdev->node, i);
+ rnb_gpio = of_get_gpio(ofdev->dev.of_node, i);
if (rnb_gpio >= 0) {
ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
if (ret) {
@@ -288,21 +277,21 @@ static int __devinit fun_probe(struct of_device *ofdev,
}
}
- prop = of_get_property(ofdev->node, "chip-delay", NULL);
+ prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL);
if (prop)
- fun->chip_delay = *prop;
+ fun->chip_delay = be32_to_cpup(prop);
else
fun->chip_delay = 50;
- prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+ prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size);
if (prop && size == sizeof(uint32_t))
- fun->wait_flags = *prop;
+ fun->wait_flags = be32_to_cpup(prop);
else
fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
FSL_UPM_WAIT_WRITE_BYTE;
fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
- io_res.end - io_res.start + 1);
+ resource_size(&io_res));
if (!fun->io_base) {
ret = -ENOMEM;
goto err2;
@@ -311,7 +300,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
fun->dev = &ofdev->dev;
fun->last_ctrl = NAND_CLE;
- ret = fun_chip_init(fun, ofdev->node, &io_res);
+ ret = fun_chip_init(fun, ofdev->dev.of_node, &io_res);
if (ret)
goto err2;
@@ -330,7 +319,7 @@ err1:
return ret;
}
-static int __devexit fun_remove(struct of_device *ofdev)
+static int fun_remove(struct platform_device *ofdev)
{
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
int i;
@@ -349,30 +338,23 @@ static int __devexit fun_remove(struct of_device *ofdev)
return 0;
}
-static struct of_device_id of_fun_match[] = {
+static const struct of_device_id of_fun_match[] = {
{ .compatible = "fsl,upm-nand" },
{},
};
MODULE_DEVICE_TABLE(of, of_fun_match);
-static struct of_platform_driver of_fun_driver = {
- .name = "fsl,upm-nand",
- .match_table = of_fun_match,
+static struct platform_driver of_fun_driver = {
+ .driver = {
+ .name = "fsl,upm-nand",
+ .owner = THIS_MODULE,
+ .of_match_table = of_fun_match,
+ },
.probe = fun_probe,
- .remove = __devexit_p(fun_remove),
+ .remove = fun_remove,
};
-static int __init fun_module_init(void)
-{
- return of_register_platform_driver(&of_fun_driver);
-}
-module_init(fun_module_init);
-
-static void __exit fun_module_exit(void)
-{
- of_unregister_platform_driver(&of_fun_driver);
-}
-module_exit(fun_module_exit);
+module_platform_driver(of_fun_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");