Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00e4e5b5 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge remote-tracking branch 'roger/for-v3.17/gpmc-omap' into omap-for-v3.17/fixes-not-urgent

parents e6f990a8 97a288ba
Loading
Loading
Loading
Loading
+37 −42
Original line number Diff line number Diff line
@@ -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",
		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;

	err = platform_device_add(pdev);
	if (err) {
		dev_err(&pdev->dev, "Unable to register NAND device\n");
		goto out_free_pdev;
	}

	return 0;

out_free_pdev:
	platform_device_put(pdev);
out_free_cs:
	gpmc_cs_free(gpmc_nand_data->cs);