Blame view
drivers/mfd/syscon.c
4.02 KB
87d687301 mfd: Add syscon d... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* * System Control Driver * * Copyright (C) 2012 Freescale Semiconductor, Inc. * Copyright (C) 2012 Linaro Ltd. * * Author: Dong Aisheng <dong.aisheng@linaro.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> |
75177deee mfd: syscon: Fix ... |
23 |
#include <linux/mfd/syscon.h> |
87d687301 mfd: Add syscon d... |
24 25 26 27 |
static struct platform_driver syscon_driver; struct syscon { |
87d687301 mfd: Add syscon d... |
28 29 |
struct regmap *regmap; }; |
5ab3a89a7 mfd: syscon: Add ... |
30 |
static int syscon_match_node(struct device *dev, void *data) |
87d687301 mfd: Add syscon d... |
31 |
{ |
87d687301 mfd: Add syscon d... |
32 |
struct device_node *dn = data; |
ed21465a0 mfd: syscon: Remo... |
33 |
return (dev->of_node == dn) ? 1 : 0; |
87d687301 mfd: Add syscon d... |
34 35 36 37 38 39 40 41 |
} struct regmap *syscon_node_to_regmap(struct device_node *np) { struct syscon *syscon; struct device *dev; dev = driver_find_device(&syscon_driver.driver, NULL, np, |
5ab3a89a7 mfd: syscon: Add ... |
42 |
syscon_match_node); |
87d687301 mfd: Add syscon d... |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
if (!dev) return ERR_PTR(-EPROBE_DEFER); syscon = dev_get_drvdata(dev); return syscon->regmap; } EXPORT_SYMBOL_GPL(syscon_node_to_regmap); struct regmap *syscon_regmap_lookup_by_compatible(const char *s) { struct device_node *syscon_np; struct regmap *regmap; syscon_np = of_find_compatible_node(NULL, NULL, s); if (!syscon_np) return ERR_PTR(-ENODEV); regmap = syscon_node_to_regmap(syscon_np); of_node_put(syscon_np); return regmap; } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible); |
5ab3a89a7 mfd: syscon: Add ... |
67 68 |
static int syscon_match_pdevname(struct device *dev, void *data) { |
5ab3a89a7 mfd: syscon: Add ... |
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
return !strcmp(dev_name(dev), (const char *)data); } struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) { struct device *dev; struct syscon *syscon; dev = driver_find_device(&syscon_driver.driver, NULL, (void *)s, syscon_match_pdevname); if (!dev) return ERR_PTR(-EPROBE_DEFER); syscon = dev_get_drvdata(dev); return syscon->regmap; } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname); |
87d687301 mfd: Add syscon d... |
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, const char *property) { struct device_node *syscon_np; struct regmap *regmap; syscon_np = of_parse_phandle(np, property, 0); if (!syscon_np) return ERR_PTR(-ENODEV); regmap = syscon_node_to_regmap(syscon_np); of_node_put(syscon_np); return regmap; } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle); static const struct of_device_id of_syscon_match[] = { { .compatible = "syscon", }, { }, }; static struct regmap_config syscon_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, }; |
f791be492 mfd: remove use o... |
114 |
static int syscon_probe(struct platform_device *pdev) |
87d687301 mfd: Add syscon d... |
115 116 |
{ struct device *dev = &pdev->dev; |
87d687301 mfd: Add syscon d... |
117 |
struct syscon *syscon; |
5ab3a89a7 mfd: syscon: Add ... |
118 |
struct resource *res; |
f10111cc8 mfd: syscon: Remo... |
119 |
void __iomem *base; |
87d687301 mfd: Add syscon d... |
120 |
|
5ab3a89a7 mfd: syscon: Add ... |
121 |
syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL); |
87d687301 mfd: Add syscon d... |
122 123 |
if (!syscon) return -ENOMEM; |
5ab3a89a7 mfd: syscon: Add ... |
124 125 126 |
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; |
87d687301 mfd: Add syscon d... |
127 |
|
f10111cc8 mfd: syscon: Remo... |
128 129 |
base = devm_ioremap(dev, res->start, resource_size(res)); if (!base) |
5ab3a89a7 mfd: syscon: Add ... |
130 |
return -ENOMEM; |
87d687301 mfd: Add syscon d... |
131 |
|
5ab3a89a7 mfd: syscon: Add ... |
132 |
syscon_regmap_config.max_register = res->end - res->start - 3; |
f10111cc8 mfd: syscon: Remo... |
133 |
syscon->regmap = devm_regmap_init_mmio(dev, base, |
87d687301 mfd: Add syscon d... |
134 135 136 137 138 139 |
&syscon_regmap_config); if (IS_ERR(syscon->regmap)) { dev_err(dev, "regmap init failed "); return PTR_ERR(syscon->regmap); } |
87d687301 mfd: Add syscon d... |
140 |
platform_set_drvdata(pdev, syscon); |
38d8974e3 mfd: syscon: Move... |
141 142 |
dev_dbg(dev, "regmap %pR registered ", res); |
87d687301 mfd: Add syscon d... |
143 144 145 |
return 0; } |
5ab3a89a7 mfd: syscon: Add ... |
146 147 148 149 |
static const struct platform_device_id syscon_ids[] = { { "syscon", }, { } }; |
87d687301 mfd: Add syscon d... |
150 151 152 153 154 155 156 157 |
static struct platform_driver syscon_driver = { .driver = { .name = "syscon", .owner = THIS_MODULE, .of_match_table = of_syscon_match, }, .probe = syscon_probe, |
5ab3a89a7 mfd: syscon: Add ... |
158 |
.id_table = syscon_ids, |
87d687301 mfd: Add syscon d... |
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
}; static int __init syscon_init(void) { return platform_driver_register(&syscon_driver); } postcore_initcall(syscon_init); static void __exit syscon_exit(void) { platform_driver_unregister(&syscon_driver); } module_exit(syscon_exit); MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); MODULE_DESCRIPTION("System Control driver"); MODULE_LICENSE("GPL v2"); |