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 Original line Diff line number Diff line
@@ -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,
{
{
	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,
	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);