Commit | Line | Data |
---|---|---|
a5401370 RM |
1 | /* |
2 | * BCM47XX NAND flash driver | |
3 | * | |
4 | * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | */ | |
11 | ||
12 | #include <linux/module.h> | |
13 | #include <linux/kernel.h> | |
14 | #include <linux/slab.h> | |
15 | #include <linux/platform_device.h> | |
16 | #include <linux/bcma/bcma.h> | |
17 | ||
18 | #include "bcm47xxnflash.h" | |
19 | ||
20 | MODULE_DESCRIPTION("NAND flash driver for BCMA bus"); | |
21 | MODULE_LICENSE("GPL"); | |
22 | MODULE_AUTHOR("Rafał Miłecki"); | |
23 | ||
24 | static const char *probes[] = { "bcm47xxpart", NULL }; | |
25 | ||
26 | static int bcm47xxnflash_probe(struct platform_device *pdev) | |
27 | { | |
28 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | |
29 | struct bcm47xxnflash *b47n; | |
30 | int err = 0; | |
31 | ||
32 | b47n = kzalloc(sizeof(*b47n), GFP_KERNEL); | |
33 | if (!b47n) { | |
34 | err = -ENOMEM; | |
35 | goto out; | |
36 | } | |
37 | ||
38 | b47n->nand_chip.priv = b47n; | |
39 | b47n->mtd.owner = THIS_MODULE; | |
40 | b47n->mtd.priv = &b47n->nand_chip; /* Required */ | |
41 | b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); | |
42 | ||
00940a23 RM |
43 | if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { |
44 | err = bcm47xxnflash_ops_bcm4706_init(b47n); | |
a5401370 RM |
45 | } else { |
46 | pr_err("Device not supported\n"); | |
47 | err = -ENOTSUPP; | |
48 | } | |
49 | if (err) { | |
50 | pr_err("Initialization failed: %d\n", err); | |
51 | goto err_init; | |
52 | } | |
53 | ||
54 | err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); | |
55 | if (err) { | |
56 | pr_err("Failed to register MTD device: %d\n", err); | |
57 | goto err_dev_reg; | |
58 | } | |
59 | ||
60 | return 0; | |
61 | ||
62 | err_dev_reg: | |
63 | err_init: | |
64 | kfree(b47n); | |
65 | out: | |
66 | return err; | |
67 | } | |
68 | ||
d8929942 | 69 | static int bcm47xxnflash_remove(struct platform_device *pdev) |
a5401370 RM |
70 | { |
71 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | |
72 | ||
73 | if (nflash->mtd) | |
74 | mtd_device_unregister(nflash->mtd); | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
79 | static struct platform_driver bcm47xxnflash_driver = { | |
d8929942 | 80 | .remove = bcm47xxnflash_remove, |
a5401370 RM |
81 | .driver = { |
82 | .name = "bcma_nflash", | |
83 | .owner = THIS_MODULE, | |
84 | }, | |
85 | }; | |
86 | ||
87 | static int __init bcm47xxnflash_init(void) | |
88 | { | |
89 | int err; | |
90 | ||
91 | /* | |
92 | * Platform device "bcma_nflash" exists on SoCs and is registered very | |
93 | * early, it won't be added during runtime (use platform_driver_probe). | |
94 | */ | |
95 | err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe); | |
96 | if (err) | |
97 | pr_err("Failed to register serial flash driver: %d\n", err); | |
98 | ||
99 | return err; | |
100 | } | |
101 | ||
102 | static void __exit bcm47xxnflash_exit(void) | |
103 | { | |
104 | platform_driver_unregister(&bcm47xxnflash_driver); | |
105 | } | |
106 | ||
107 | module_init(bcm47xxnflash_init); | |
108 | module_exit(bcm47xxnflash_exit); |