blob: b1e67406d36761c160cc6ea23f03cb5c4e6871aa [file] [log] [blame]
Lee Jonesd90db4a2014-03-20 09:20:33 +00001/*
2 * st_spi_fsm.c - ST Fast Sequence Mode (FSM) Serial Flash Controller
3 *
4 * Author: Angus Clark <angus.clark@st.com>
5 *
6 * Copyright (C) 2010-2014 STicroelectronics Limited
7 *
8 * JEDEC probe based on drivers/mtd/devices/m25p80.c
9 *
10 * This code is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h>
19#include <linux/sched.h>
20#include <linux/delay.h>
21#include <linux/io.h>
22#include <linux/of.h>
23
24struct stfsm {
25 struct device *dev;
26 void __iomem *base;
27 struct resource *region;
28 struct mtd_info mtd;
29 struct mutex lock;
30};
31
32static int stfsm_probe(struct platform_device *pdev)
33{
34 struct device_node *np = pdev->dev.of_node;
35 struct resource *res;
36 struct stfsm *fsm;
37
38 if (!np) {
39 dev_err(&pdev->dev, "No DT found\n");
40 return -EINVAL;
41 }
42
43 fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL);
44 if (!fsm)
45 return -ENOMEM;
46
47 fsm->dev = &pdev->dev;
48
49 platform_set_drvdata(pdev, fsm);
50
51 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
52 if (!res) {
53 dev_err(&pdev->dev, "Resource not found\n");
54 return -ENODEV;
55 }
56
57 fsm->base = devm_ioremap_resource(&pdev->dev, res);
58 if (IS_ERR(fsm->base)) {
59 dev_err(&pdev->dev,
60 "Failed to reserve memory region %pR\n", res);
61 return PTR_ERR(fsm->base);
62 }
63
64 mutex_init(&fsm->lock);
65
66 fsm->mtd.dev.parent = &pdev->dev;
67 fsm->mtd.type = MTD_NORFLASH;
68 fsm->mtd.writesize = 4;
69 fsm->mtd.writebufsize = fsm->mtd.writesize;
70 fsm->mtd.flags = MTD_CAP_NORFLASH;
71
72 return mtd_device_parse_register(&fsm->mtd, NULL, NULL, NULL, 0);
73}
74
75static int stfsm_remove(struct platform_device *pdev)
76{
77 struct stfsm *fsm = platform_get_drvdata(pdev);
78 int err;
79
80 err = mtd_device_unregister(&fsm->mtd);
81 if (err)
82 return err;
83
84 return 0;
85}
86
87static struct of_device_id stfsm_match[] = {
88 { .compatible = "st,spi-fsm", },
89 {},
90};
91MODULE_DEVICE_TABLE(of, stfsm_match);
92
93static struct platform_driver stfsm_driver = {
94 .probe = stfsm_probe,
95 .remove = stfsm_remove,
96 .driver = {
97 .name = "st-spi-fsm",
98 .owner = THIS_MODULE,
99 .of_match_table = stfsm_match,
100 },
101};
102module_platform_driver(stfsm_driver);
103
104MODULE_AUTHOR("Angus Clark <angus.clark@st.com>");
105MODULE_DESCRIPTION("ST SPI FSM driver");
106MODULE_LICENSE("GPL");