Commit 97a288ba authored by Rostislav Lisovy's avatar Rostislav Lisovy Committed by Roger Quadros

ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()

GPMC controller supports up to 8 memory devices connected to it.
Since there is one statically allocated "struct platform_device
gpmc_nand_device" it is not possible to configure the system to
use more than one NAND device connected to the GPMC. This
modification makes it possible to use up to 8 NAND devices
connected to the GPMC controller.
Signed-off-by: default avatarRostislav Lisovy <lisovy@merica.cz>
Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
parent cd3de83f
...@@ -24,25 +24,6 @@ ...@@ -24,25 +24,6 @@
/* minimum size for IO mapping */ /* minimum size for IO mapping */
#define NAND_IO_SIZE 4 #define NAND_IO_SIZE 4
static struct resource gpmc_nand_resource[] = {
{
.flags = IORESOURCE_MEM,
},
{
.flags = IORESOURCE_IRQ,
},
{
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device gpmc_nand_device = {
.name = "omap2-nand",
.id = 0,
.num_resources = ARRAY_SIZE(gpmc_nand_resource),
.resource = gpmc_nand_resource,
};
static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt) static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
{ {
/* platforms which support all ECC schemes */ /* platforms which support all ECC schemes */
...@@ -93,43 +74,41 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, ...@@ -93,43 +74,41 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
{ {
int err = 0; int err = 0;
struct gpmc_settings s; struct gpmc_settings s;
struct device *dev = &gpmc_nand_device.dev; struct platform_device *pdev;
struct resource gpmc_nand_res[] = {
memset(&s, 0, sizeof(struct gpmc_settings)); { .flags = IORESOURCE_MEM, },
{ .flags = IORESOURCE_IRQ, },
{ .flags = IORESOURCE_IRQ, },
};
gpmc_nand_device.dev.platform_data = gpmc_nand_data; BUG_ON(gpmc_nand_data->cs >= GPMC_CS_NUM);
err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
(unsigned long *)&gpmc_nand_resource[0].start); (unsigned long *)&gpmc_nand_res[0].start);
if (err < 0) { if (err < 0) {
dev_err(dev, "Cannot request GPMC CS %d, error %d\n", pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
gpmc_nand_data->cs, err); gpmc_nand_data->cs, err);
return err; return err;
} }
gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
gpmc_nand_resource[0].end = gpmc_nand_resource[0].start + gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
NAND_IO_SIZE - 1; gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
gpmc_nand_resource[1].start =
gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
gpmc_nand_resource[2].start =
gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
if (gpmc_t) { if (gpmc_t) {
err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t); err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
if (err < 0) { if (err < 0) {
dev_err(dev, "Unable to set gpmc timings: %d\n", err); pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n", err);
return err; return err;
} }
} }
memset(&s, 0, sizeof(struct gpmc_settings));
if (gpmc_nand_data->of_node) if (gpmc_nand_data->of_node)
gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
else else
gpmc_set_legacy(gpmc_nand_data, &s); gpmc_set_legacy(gpmc_nand_data, &s);
s.device_nand = true; s.device_nand = true;
err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
if (err < 0) if (err < 0)
goto out_free_cs; goto out_free_cs;
...@@ -141,18 +120,34 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, ...@@ -141,18 +120,34 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) { if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
dev_err(dev, "Unsupported NAND ECC scheme selected\n"); pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
return -EINVAL; err = -EINVAL;
goto out_free_cs;
} }
err = platform_device_register(&gpmc_nand_device);
if (err < 0) { pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
dev_err(dev, "Unable to register NAND device\n"); if (pdev) {
goto out_free_cs; err = platform_device_add_resources(pdev, gpmc_nand_res,
ARRAY_SIZE(gpmc_nand_res));
if (!err)
pdev->dev.platform_data = gpmc_nand_data;
} else {
err = -ENOMEM;
}
if (err)
goto out_free_pdev;
err = platform_device_add(pdev);
if (err) {
dev_err(&pdev->dev, "Unable to register NAND device\n");
goto out_free_pdev;
} }
return 0; return 0;
out_free_pdev:
platform_device_put(pdev);
out_free_cs: out_free_cs:
gpmc_cs_free(gpmc_nand_data->cs); gpmc_cs_free(gpmc_nand_data->cs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment