denali_dt.c 3.1 KB
Newer Older
D
Dinh Nguyen 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * NAND Flash Controller Device Driver for DT
 *
 * Copyright © 2011, Picochip.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include "denali.h"

struct denali_dt {
	struct denali_nand_info	denali;
	struct clk		*clk;
};

32
struct denali_dt_data {
33
	unsigned int revision;
34 35 36
	unsigned int caps;
};

37 38 39
static const struct denali_dt_data denali_socfpga_data = {
	.caps = DENALI_CAP_HW_ECC_FIXUP,
};
D
Dinh Nguyen 已提交
40

41 42 43 44 45 46 47
static const struct of_device_id denali_nand_dt_ids[] = {
	{
		.compatible = "altr,socfpga-denali-nand",
		.data = &denali_socfpga_data,
	},
	{ /* sentinel */ }
};
D
Dinh Nguyen 已提交
48 49
MODULE_DEVICE_TABLE(of, denali_nand_dt_ids);

50
static int denali_dt_probe(struct platform_device *pdev)
D
Dinh Nguyen 已提交
51
{
52
	struct resource *res;
D
Dinh Nguyen 已提交
53
	struct denali_dt *dt;
54
	const struct denali_dt_data *data;
D
Dinh Nguyen 已提交
55 56 57
	struct denali_nand_info *denali;
	int ret;

58
	dt = devm_kzalloc(&pdev->dev, sizeof(*dt), GFP_KERNEL);
D
Dinh Nguyen 已提交
59 60 61 62
	if (!dt)
		return -ENOMEM;
	denali = &dt->denali;

63
	data = of_device_get_match_data(&pdev->dev);
64 65
	if (data) {
		denali->revision = data->revision;
66
		denali->caps = data->caps;
67
	}
68

D
Dinh Nguyen 已提交
69
	denali->platform = DT;
70 71
	denali->dev = &pdev->dev;
	denali->irq = platform_get_irq(pdev, 0);
D
Dinh Nguyen 已提交
72
	if (denali->irq < 0) {
73
		dev_err(&pdev->dev, "no irq defined\n");
74
		return denali->irq;
D
Dinh Nguyen 已提交
75 76
	}

77 78
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "denali_reg");
	denali->flash_reg = devm_ioremap_resource(&pdev->dev, res);
79 80
	if (IS_ERR(denali->flash_reg))
		return PTR_ERR(denali->flash_reg);
D
Dinh Nguyen 已提交
81

82 83
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
	denali->flash_mem = devm_ioremap_resource(&pdev->dev, res);
84 85
	if (IS_ERR(denali->flash_mem))
		return PTR_ERR(denali->flash_mem);
D
Dinh Nguyen 已提交
86

87
	dt->clk = devm_clk_get(&pdev->dev, NULL);
D
Dinh Nguyen 已提交
88
	if (IS_ERR(dt->clk)) {
89
		dev_err(&pdev->dev, "no clk available\n");
D
Dinh Nguyen 已提交
90 91 92 93 94 95 96 97
		return PTR_ERR(dt->clk);
	}
	clk_prepare_enable(dt->clk);

	ret = denali_init(denali);
	if (ret)
		goto out_disable_clk;

98
	platform_set_drvdata(pdev, dt);
D
Dinh Nguyen 已提交
99 100 101 102 103 104 105 106
	return 0;

out_disable_clk:
	clk_disable_unprepare(dt->clk);

	return ret;
}

107
static int denali_dt_remove(struct platform_device *pdev)
D
Dinh Nguyen 已提交
108
{
109
	struct denali_dt *dt = platform_get_drvdata(pdev);
D
Dinh Nguyen 已提交
110 111

	denali_remove(&dt->denali);
112
	clk_disable_unprepare(dt->clk);
D
Dinh Nguyen 已提交
113 114 115 116 117 118

	return 0;
}

static struct platform_driver denali_dt_driver = {
	.probe		= denali_dt_probe,
B
Bill Pemberton 已提交
119
	.remove		= denali_dt_remove,
D
Dinh Nguyen 已提交
120 121
	.driver		= {
		.name	= "denali-nand-dt",
122
		.of_match_table	= denali_nand_dt_ids,
D
Dinh Nguyen 已提交
123 124 125
	},
};

126
module_platform_driver(denali_dt_driver);
D
Dinh Nguyen 已提交
127 128 129 130

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamie Iles");
MODULE_DESCRIPTION("DT driver for Denali NAND controller");