From: Roger Quadros <rogerq@ti.com>
To: Rostislav Lisovy <lisovy@gmail.com>,
Kevin Hilman <khilman@deeprootsystems.com>,
Tony Lindgren <tony@atomide.com>,
Russell King <linux@arm.linux.org.uk>,
linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: Pekon Gupta <pekon@ti.com>, Michal Vokac <vokac.m@gmail.com>,
Michal Sojka <sojkam1@fel.cvut.cz>,
Rostislav Lisovy <lisovy@merica.cz>
Subject: Re: [PATCH] ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()
Date: Fri, 11 Jul 2014 15:02:52 +0300 [thread overview]
Message-ID: <53BFD26C.6080609@ti.com> (raw)
In-Reply-To: <53BD3A56.9050302@ti.com>
On 07/09/2014 03:49 PM, Roger Quadros wrote:
> Hi Rostislav,
>
> On 06/04/2014 05:24 PM, Rostislav Lisovy wrote:
>> 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: Rostislav Lisovy <lisovy@merica.cz>
>> ---
>>
>> Tested on custom AM335x board with two different NAND chips
>> (128 + 256 MiB) using GPMC configuration in FDT -- behaves
>> correctly.
>>
>>
>> arch/arm/mach-omap2/gpmc-nand.c | 79 +++++++++++++++++++----------------------
>> 1 file changed, 37 insertions(+), 42 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
>> index 4349e82..c5481a8 100644
>> --- a/arch/arm/mach-omap2/gpmc-nand.c
>> +++ b/arch/arm/mach-omap2/gpmc-nand.c
>> @@ -24,25 +24,6 @@
>> /* minimum size for IO mapping */
>> #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)
>> {
>> /* platforms which support all ECC schemes */
>> @@ -93,43 +74,41 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>> {
>> int err = 0;
>> struct gpmc_settings s;
>> - struct device *dev = &gpmc_nand_device.dev;
>> -
>> - memset(&s, 0, sizeof(struct gpmc_settings));
>> + struct platform_device *pdev;
>> + struct resource gpmc_nand_res[] = {
>> + { .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,
>> - (unsigned long *)&gpmc_nand_resource[0].start);
>> + (unsigned long *)&gpmc_nand_res[0].start);
>> if (err < 0) {
>> - dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
>> - gpmc_nand_data->cs, err);
>> + pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
>> + gpmc_nand_data->cs, err);
>> return err;
>> }
>> -
>> - gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
>> - NAND_IO_SIZE - 1;
>> -
>> - 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);
>> + gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
>> + gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
>> + gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
>>
>> if (gpmc_t) {
>> err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
>> 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;
>> }
>> }
>>
>> + memset(&s, 0, sizeof(struct gpmc_settings));
>> if (gpmc_nand_data->of_node)
>> gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
>> else
>> gpmc_set_legacy(gpmc_nand_data, &s);
>>
>> s.device_nand = true;
>> -
>> err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
>> if (err < 0)
>> goto out_free_cs;
>> @@ -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);
>>
>> if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
>> - dev_err(dev, "Unsupported NAND ECC scheme selected\n");
>> - return -EINVAL;
>> + pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
>> + err = -EINVAL;
>> + goto out_free_cs;
>> }
>>
>> - err = platform_device_register(&gpmc_nand_device);
>> - if (err < 0) {
>> - dev_err(dev, "Unable to register NAND device\n");
>> - goto out_free_cs;
>> +
>> + pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
>> + if (pdev) {
>> + 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;
>
> There is a slight problem here. If platform_device_alloc() fails,
> we must jump to 'out_free_cs' and not 'out_free_pdev'.
Nevermind. It shouldn't be a problem as platform_device_put() checks for NULL pdev.
cheers,
-roger
WARNING: multiple messages have this Message-ID (diff)
From: rogerq@ti.com (Roger Quadros)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()
Date: Fri, 11 Jul 2014 15:02:52 +0300 [thread overview]
Message-ID: <53BFD26C.6080609@ti.com> (raw)
In-Reply-To: <53BD3A56.9050302@ti.com>
On 07/09/2014 03:49 PM, Roger Quadros wrote:
> Hi Rostislav,
>
> On 06/04/2014 05:24 PM, Rostislav Lisovy wrote:
>> 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: Rostislav Lisovy <lisovy@merica.cz>
>> ---
>>
>> Tested on custom AM335x board with two different NAND chips
>> (128 + 256 MiB) using GPMC configuration in FDT -- behaves
>> correctly.
>>
>>
>> arch/arm/mach-omap2/gpmc-nand.c | 79 +++++++++++++++++++----------------------
>> 1 file changed, 37 insertions(+), 42 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
>> index 4349e82..c5481a8 100644
>> --- a/arch/arm/mach-omap2/gpmc-nand.c
>> +++ b/arch/arm/mach-omap2/gpmc-nand.c
>> @@ -24,25 +24,6 @@
>> /* minimum size for IO mapping */
>> #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)
>> {
>> /* platforms which support all ECC schemes */
>> @@ -93,43 +74,41 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>> {
>> int err = 0;
>> struct gpmc_settings s;
>> - struct device *dev = &gpmc_nand_device.dev;
>> -
>> - memset(&s, 0, sizeof(struct gpmc_settings));
>> + struct platform_device *pdev;
>> + struct resource gpmc_nand_res[] = {
>> + { .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,
>> - (unsigned long *)&gpmc_nand_resource[0].start);
>> + (unsigned long *)&gpmc_nand_res[0].start);
>> if (err < 0) {
>> - dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
>> - gpmc_nand_data->cs, err);
>> + pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
>> + gpmc_nand_data->cs, err);
>> return err;
>> }
>> -
>> - gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
>> - NAND_IO_SIZE - 1;
>> -
>> - 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);
>> + gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
>> + gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
>> + gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
>>
>> if (gpmc_t) {
>> err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
>> 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;
>> }
>> }
>>
>> + memset(&s, 0, sizeof(struct gpmc_settings));
>> if (gpmc_nand_data->of_node)
>> gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
>> else
>> gpmc_set_legacy(gpmc_nand_data, &s);
>>
>> s.device_nand = true;
>> -
>> err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
>> if (err < 0)
>> goto out_free_cs;
>> @@ -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);
>>
>> if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
>> - dev_err(dev, "Unsupported NAND ECC scheme selected\n");
>> - return -EINVAL;
>> + pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
>> + err = -EINVAL;
>> + goto out_free_cs;
>> }
>>
>> - err = platform_device_register(&gpmc_nand_device);
>> - if (err < 0) {
>> - dev_err(dev, "Unable to register NAND device\n");
>> - goto out_free_cs;
>> +
>> + pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
>> + if (pdev) {
>> + 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;
>
> There is a slight problem here. If platform_device_alloc() fails,
> we must jump to 'out_free_cs' and not 'out_free_pdev'.
Nevermind. It shouldn't be a problem as platform_device_put() checks for NULL pdev.
cheers,
-roger
WARNING: multiple messages have this Message-ID (diff)
From: Roger Quadros <rogerq@ti.com>
To: Rostislav Lisovy <lisovy@gmail.com>,
Kevin Hilman <khilman@deeprootsystems.com>,
Tony Lindgren <tony@atomide.com>,
Russell King <linux@arm.linux.org.uk>,
<linux-omap@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>
Cc: Pekon Gupta <pekon@ti.com>, Michal Vokac <vokac.m@gmail.com>,
Michal Sojka <sojkam1@fel.cvut.cz>,
Rostislav Lisovy <lisovy@merica.cz>
Subject: Re: [PATCH] ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()
Date: Fri, 11 Jul 2014 15:02:52 +0300 [thread overview]
Message-ID: <53BFD26C.6080609@ti.com> (raw)
In-Reply-To: <53BD3A56.9050302@ti.com>
On 07/09/2014 03:49 PM, Roger Quadros wrote:
> Hi Rostislav,
>
> On 06/04/2014 05:24 PM, Rostislav Lisovy wrote:
>> 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: Rostislav Lisovy <lisovy@merica.cz>
>> ---
>>
>> Tested on custom AM335x board with two different NAND chips
>> (128 + 256 MiB) using GPMC configuration in FDT -- behaves
>> correctly.
>>
>>
>> arch/arm/mach-omap2/gpmc-nand.c | 79 +++++++++++++++++++----------------------
>> 1 file changed, 37 insertions(+), 42 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
>> index 4349e82..c5481a8 100644
>> --- a/arch/arm/mach-omap2/gpmc-nand.c
>> +++ b/arch/arm/mach-omap2/gpmc-nand.c
>> @@ -24,25 +24,6 @@
>> /* minimum size for IO mapping */
>> #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)
>> {
>> /* platforms which support all ECC schemes */
>> @@ -93,43 +74,41 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>> {
>> int err = 0;
>> struct gpmc_settings s;
>> - struct device *dev = &gpmc_nand_device.dev;
>> -
>> - memset(&s, 0, sizeof(struct gpmc_settings));
>> + struct platform_device *pdev;
>> + struct resource gpmc_nand_res[] = {
>> + { .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,
>> - (unsigned long *)&gpmc_nand_resource[0].start);
>> + (unsigned long *)&gpmc_nand_res[0].start);
>> if (err < 0) {
>> - dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
>> - gpmc_nand_data->cs, err);
>> + pr_err("omap2-gpmc: Cannot request GPMC CS %d, error %d\n",
>> + gpmc_nand_data->cs, err);
>> return err;
>> }
>> -
>> - gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
>> - NAND_IO_SIZE - 1;
>> -
>> - 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);
>> + gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
>> + gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
>> + gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
>>
>> if (gpmc_t) {
>> err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
>> 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;
>> }
>> }
>>
>> + memset(&s, 0, sizeof(struct gpmc_settings));
>> if (gpmc_nand_data->of_node)
>> gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
>> else
>> gpmc_set_legacy(gpmc_nand_data, &s);
>>
>> s.device_nand = true;
>> -
>> err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
>> if (err < 0)
>> goto out_free_cs;
>> @@ -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);
>>
>> if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
>> - dev_err(dev, "Unsupported NAND ECC scheme selected\n");
>> - return -EINVAL;
>> + pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
>> + err = -EINVAL;
>> + goto out_free_cs;
>> }
>>
>> - err = platform_device_register(&gpmc_nand_device);
>> - if (err < 0) {
>> - dev_err(dev, "Unable to register NAND device\n");
>> - goto out_free_cs;
>> +
>> + pdev = platform_device_alloc("omap2-nand", gpmc_nand_data->cs);
>> + if (pdev) {
>> + 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;
>
> There is a slight problem here. If platform_device_alloc() fails,
> we must jump to 'out_free_cs' and not 'out_free_pdev'.
Nevermind. It shouldn't be a problem as platform_device_put() checks for NULL pdev.
cheers,
-roger
next prev parent reply other threads:[~2014-07-11 12:02 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-04 14:24 [PATCH] ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc() Rostislav Lisovy
2014-06-04 14:24 ` Rostislav Lisovy
2014-07-09 12:49 ` Roger Quadros
2014-07-09 12:49 ` Roger Quadros
2014-07-09 12:49 ` Roger Quadros
2014-07-11 12:02 ` Roger Quadros [this message]
2014-07-11 12:02 ` Roger Quadros
2014-07-11 12:02 ` Roger Quadros
2014-07-11 13:45 ` Roger Quadros
2014-07-11 13:45 ` Roger Quadros
2014-07-11 13:45 ` Roger Quadros
2014-07-15 7:25 ` Tony Lindgren
2014-07-15 7:25 ` Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53BFD26C.6080609@ti.com \
--to=rogerq@ti.com \
--cc=khilman@deeprootsystems.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=lisovy@gmail.com \
--cc=lisovy@merica.cz \
--cc=pekon@ti.com \
--cc=sojkam1@fel.cvut.cz \
--cc=tony@atomide.com \
--cc=vokac.m@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.