Blame view
drivers/mfd/sta2x11-mfd.c
15.5 KB
450515395 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
35bdd2909 mfd: Add driver f... |
2 |
/* |
cf090914d mfd: sta2x11: Dro... |
3 4 |
* STA2x11 mfd for GPIO, SCTL and APBREG * |
35bdd2909 mfd: Add driver f... |
5 |
* Copyright (c) 2009-2011 Wind River Systems, Inc. |
b73df6986 mfd: sta2x11-mfd:... |
6 |
* Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi) |
35bdd2909 mfd: Add driver f... |
7 8 9 |
*/ #include <linux/kernel.h> |
cf090914d mfd: sta2x11: Dro... |
10 11 |
#include <linux/init.h> #include <linux/export.h> |
35bdd2909 mfd: Add driver f... |
12 13 14 15 16 17 18 19 |
#include <linux/spinlock.h> #include <linux/errno.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/list.h> #include <linux/io.h> #include <linux/ioport.h> #include <linux/pci.h> |
35bdd2909 mfd: Add driver f... |
20 21 22 23 |
#include <linux/seq_file.h> #include <linux/platform_device.h> #include <linux/mfd/core.h> #include <linux/mfd/sta2x11-mfd.h> |
d94e25535 mfd: sta2x11-mfd:... |
24 |
#include <linux/regmap.h> |
35bdd2909 mfd: Add driver f... |
25 26 |
#include <asm/sta2x11.h> |
d94e25535 mfd: sta2x11-mfd:... |
27 28 29 30 31 32 |
static inline int __reg_within_range(unsigned int r, unsigned int start, unsigned int end) { return ((r >= start) && (r <= end)); } |
35bdd2909 mfd: Add driver f... |
33 34 35 |
/* This describes STA2X11 MFD chip for us, we may have several */ struct sta2x11_mfd { struct sta2x11_instance *instance; |
d94e25535 mfd: sta2x11-mfd:... |
36 |
struct regmap *regmap[sta2x11_n_mfd_plat_devs]; |
e885ba298 mfd: sta2x11-mfd:... |
37 |
spinlock_t lock[sta2x11_n_mfd_plat_devs]; |
35bdd2909 mfd: Add driver f... |
38 |
struct list_head list; |
1950c7164 mfd: sta2x11-mfd:... |
39 |
void __iomem *regs[sta2x11_n_mfd_plat_devs]; |
35bdd2909 mfd: Add driver f... |
40 41 42 43 44 45 46 47 48 49 50 |
}; static LIST_HEAD(sta2x11_mfd_list); /* Three functions to act on the list */ static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev) { struct sta2x11_instance *instance; struct sta2x11_mfd *mfd; if (!pdev && !list_empty(&sta2x11_mfd_list)) { |
81d30eda9 mfd: Convert rema... |
51 52 53 |
pr_warn("%s: Unspecified device, using first instance ", __func__); |
35bdd2909 mfd: Add driver f... |
54 55 56 57 58 59 60 61 62 63 64 65 66 |
return list_entry(sta2x11_mfd_list.next, struct sta2x11_mfd, list); } instance = sta2x11_get_instance(pdev); if (!instance) return NULL; list_for_each_entry(mfd, &sta2x11_mfd_list, list) { if (mfd->instance == instance) return mfd; } return NULL; } |
f791be492 mfd: remove use o... |
67 |
static int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags) |
35bdd2909 mfd: Add driver f... |
68 |
{ |
e885ba298 mfd: sta2x11-mfd:... |
69 |
int i; |
35bdd2909 mfd: Add driver f... |
70 71 72 73 74 75 76 77 78 79 80 81 |
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); struct sta2x11_instance *instance; if (mfd) return -EBUSY; instance = sta2x11_get_instance(pdev); if (!instance) return -EINVAL; mfd = kzalloc(sizeof(*mfd), flags); if (!mfd) return -ENOMEM; INIT_LIST_HEAD(&mfd->list); |
e885ba298 mfd: sta2x11-mfd:... |
82 83 |
for (i = 0; i < ARRAY_SIZE(mfd->lock); i++) spin_lock_init(&mfd->lock[i]); |
35bdd2909 mfd: Add driver f... |
84 85 86 87 |
mfd->instance = instance; list_add(&mfd->list, &sta2x11_mfd_list); return 0; } |
1950c7164 mfd: sta2x11-mfd:... |
88 89 90 |
/* This function is exported and is not expected to fail */ u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val, enum sta2x11_mfd_plat_dev index) |
35bdd2909 mfd: Add driver f... |
91 92 93 94 |
{ struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); u32 r; unsigned long flags; |
709edecd4 mfd: sta2x11: Fix... |
95 |
void __iomem *regs; |
35bdd2909 mfd: Add driver f... |
96 97 98 99 100 101 |
if (!mfd) { dev_warn(&pdev->dev, ": can't access sctl regs "); return 0; } |
709edecd4 mfd: sta2x11: Fix... |
102 103 |
regs = mfd->regs[index]; |
1950c7164 mfd: sta2x11-mfd:... |
104 |
if (!regs) { |
35bdd2909 mfd: Add driver f... |
105 106 107 108 |
dev_warn(&pdev->dev, ": system ctl not initialized "); return 0; } |
e885ba298 mfd: sta2x11-mfd:... |
109 |
spin_lock_irqsave(&mfd->lock[index], flags); |
1950c7164 mfd: sta2x11-mfd:... |
110 |
r = readl(regs + reg); |
35bdd2909 mfd: Add driver f... |
111 112 113 |
r &= ~mask; r |= val; if (mask) |
1950c7164 mfd: sta2x11-mfd:... |
114 |
writel(r, regs + reg); |
e885ba298 mfd: sta2x11-mfd:... |
115 |
spin_unlock_irqrestore(&mfd->lock[index], flags); |
35bdd2909 mfd: Add driver f... |
116 117 |
return r; } |
1950c7164 mfd: sta2x11-mfd:... |
118 |
EXPORT_SYMBOL(__sta2x11_mfd_mask); |
35bdd2909 mfd: Add driver f... |
119 |
|
29f5b5a32 mfd: sta2x11-mfd:... |
120 121 122 123 |
int sta2x11_mfd_get_regs_data(struct platform_device *dev, enum sta2x11_mfd_plat_dev index, void __iomem **regs, spinlock_t **lock) |
35bdd2909 mfd: Add driver f... |
124 |
{ |
334a41ce9 mfd: Use dev_get_... |
125 |
struct pci_dev *pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev); |
29f5b5a32 mfd: sta2x11-mfd:... |
126 |
struct sta2x11_mfd *mfd; |
35bdd2909 mfd: Add driver f... |
127 |
|
29f5b5a32 mfd: sta2x11-mfd:... |
128 129 130 131 132 133 134 135 136 137 138 139 |
if (!pdev) return -ENODEV; mfd = sta2x11_mfd_find(pdev); if (!mfd) return -ENODEV; if (index >= sta2x11_n_mfd_plat_devs) return -ENODEV; *regs = mfd->regs[index]; *lock = &mfd->lock[index]; pr_debug("%s %d *regs = %p ", __func__, __LINE__, *regs); return *regs ? 0 : -ENODEV; |
35bdd2909 mfd: Add driver f... |
140 |
} |
29f5b5a32 mfd: sta2x11-mfd:... |
141 |
EXPORT_SYMBOL(sta2x11_mfd_get_regs_data); |
35bdd2909 mfd: Add driver f... |
142 |
|
d94e25535 mfd: sta2x11-mfd:... |
143 144 145 |
/* * Special sta2x11-mfd regmap lock/unlock functions */ |
35bdd2909 mfd: Add driver f... |
146 |
|
d94e25535 mfd: sta2x11-mfd:... |
147 148 149 150 151 |
static void sta2x11_regmap_lock(void *__lock) { spinlock_t *lock = __lock; spin_lock(lock); } |
35bdd2909 mfd: Add driver f... |
152 |
|
d94e25535 mfd: sta2x11-mfd:... |
153 154 155 156 157 |
static void sta2x11_regmap_unlock(void *__lock) { spinlock_t *lock = __lock; spin_unlock(lock); } |
35bdd2909 mfd: Add driver f... |
158 |
|
dba6c1aee mfd: sta2x11-mfd:... |
159 160 161 162 |
/* OTP (one time programmable registers do not require locking */ static void sta2x11_regmap_nolock(void *__lock) { } |
d94e25535 mfd: sta2x11-mfd:... |
163 |
static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = { |
b18adafcc mfd: sta2x11-mfd:... |
164 165 166 |
[sta2x11_sctl] = STA2X11_MFD_SCTL_NAME, [sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME, [sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME, |
dba6c1aee mfd: sta2x11-mfd:... |
167 |
[sta2x11_scr] = STA2X11_MFD_SCR_NAME, |
35bdd2909 mfd: Add driver f... |
168 |
}; |
35bdd2909 mfd: Add driver f... |
169 |
|
d94e25535 mfd: sta2x11-mfd:... |
170 171 172 173 174 175 176 177 178 179 180 181 182 |
static bool sta2x11_sctl_writeable_reg(struct device *dev, unsigned int reg) { return !__reg_within_range(reg, SCTL_SCPCIECSBRST, SCTL_SCRSTSTA); } static struct regmap_config sta2x11_sctl_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, .lock = sta2x11_regmap_lock, .unlock = sta2x11_regmap_unlock, .max_register = SCTL_SCRSTSTA, .writeable_reg = sta2x11_sctl_writeable_reg, |
35bdd2909 mfd: Add driver f... |
183 |
}; |
dba6c1aee mfd: sta2x11-mfd:... |
184 185 186 187 188 |
static bool sta2x11_scr_readable_reg(struct device *dev, unsigned int reg) { return (reg == STA2X11_SECR_CR) || __reg_within_range(reg, STA2X11_SECR_FVR0, STA2X11_SECR_FVR1); } |
35bdd2909 mfd: Add driver f... |
189 |
|
dba6c1aee mfd: sta2x11-mfd:... |
190 |
static bool sta2x11_scr_writeable_reg(struct device *dev, unsigned int reg) |
35bdd2909 mfd: Add driver f... |
191 |
{ |
dba6c1aee mfd: sta2x11-mfd:... |
192 193 |
return false; } |
35bdd2909 mfd: Add driver f... |
194 |
|
dba6c1aee mfd: sta2x11-mfd:... |
195 196 197 198 199 200 201 202 203 204 |
static struct regmap_config sta2x11_scr_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, .lock = sta2x11_regmap_nolock, .unlock = sta2x11_regmap_nolock, .max_register = STA2X11_SECR_FVR1, .readable_reg = sta2x11_scr_readable_reg, .writeable_reg = sta2x11_scr_writeable_reg, }; |
35bdd2909 mfd: Add driver f... |
205 |
|
d94e25535 mfd: sta2x11-mfd:... |
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
static bool sta2x11_apbreg_readable_reg(struct device *dev, unsigned int reg) { /* Two blocks (CAN and MLB, SARAC) 0x100 bytes apart */ if (reg >= APBREG_BSR_SARAC) reg -= APBREG_BSR_SARAC; switch (reg) { case APBREG_BSR: case APBREG_PAER: case APBREG_PWAC: case APBREG_PRAC: case APBREG_PCG: case APBREG_PUR: case APBREG_EMU_PCG: return true; default: return false; } } |
35bdd2909 mfd: Add driver f... |
224 |
|
d94e25535 mfd: sta2x11-mfd:... |
225 226 227 228 229 230 231 232 |
static bool sta2x11_apbreg_writeable_reg(struct device *dev, unsigned int reg) { if (reg >= APBREG_BSR_SARAC) reg -= APBREG_BSR_SARAC; if (!sta2x11_apbreg_readable_reg(dev, reg)) return false; return reg != APBREG_PAER; } |
35bdd2909 mfd: Add driver f... |
233 |
|
d94e25535 mfd: sta2x11-mfd:... |
234 235 236 237 238 239 240 241 242 |
static struct regmap_config sta2x11_apbreg_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, .lock = sta2x11_regmap_lock, .unlock = sta2x11_regmap_unlock, .max_register = APBREG_EMU_PCG_SARAC, .readable_reg = sta2x11_apbreg_readable_reg, .writeable_reg = sta2x11_apbreg_writeable_reg, |
1950c7164 mfd: sta2x11-mfd:... |
243 |
}; |
35bdd2909 mfd: Add driver f... |
244 |
|
d94e25535 mfd: sta2x11-mfd:... |
245 246 247 248 249 250 251 252 253 254 |
static bool sta2x11_apb_soc_regs_readable_reg(struct device *dev, unsigned int reg) { return reg <= PCIE_SoC_INT_ROUTER_STATUS3_REG || __reg_within_range(reg, DMA_IP_CTRL_REG, SPARE3_RESERVED) || __reg_within_range(reg, MASTER_LOCK_REG, SYSTEM_CONFIG_STATUS_REG) || reg == MSP_CLK_CTRL_REG || __reg_within_range(reg, COMPENSATION_REG1, TEST_CTL_REG); } |
35bdd2909 mfd: Add driver f... |
255 |
|
d94e25535 mfd: sta2x11-mfd:... |
256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
static bool sta2x11_apb_soc_regs_writeable_reg(struct device *dev, unsigned int reg) { if (!sta2x11_apb_soc_regs_readable_reg(dev, reg)) return false; switch (reg) { case PCIE_COMMON_CLOCK_CONFIG_0_4_0: case SYSTEM_CONFIG_STATUS_REG: case COMPENSATION_REG1: case PCIE_SoC_INT_ROUTER_STATUS0_REG...PCIE_SoC_INT_ROUTER_STATUS3_REG: case PCIE_PM_STATUS_0_PORT_0_4...PCIE_PM_STATUS_7_0_EP4: return false; default: return true; |
35bdd2909 mfd: Add driver f... |
270 |
} |
35bdd2909 mfd: Add driver f... |
271 |
} |
d94e25535 mfd: sta2x11-mfd:... |
272 273 274 275 276 277 278 279 280 |
static struct regmap_config sta2x11_apb_soc_regs_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, .lock = sta2x11_regmap_lock, .unlock = sta2x11_regmap_unlock, .max_register = TEST_CTL_REG, .readable_reg = sta2x11_apb_soc_regs_readable_reg, .writeable_reg = sta2x11_apb_soc_regs_writeable_reg, |
1950c7164 mfd: sta2x11-mfd:... |
281 |
}; |
35bdd2909 mfd: Add driver f... |
282 |
|
d94e25535 mfd: sta2x11-mfd:... |
283 284 285 286 287 |
static struct regmap_config * sta2x11_mfd_regmap_configs[sta2x11_n_mfd_plat_devs] = { [sta2x11_sctl] = &sta2x11_sctl_regmap_config, [sta2x11_apbreg] = &sta2x11_apbreg_regmap_config, [sta2x11_apb_soc_regs] = &sta2x11_apb_soc_regs_regmap_config, |
dba6c1aee mfd: sta2x11-mfd:... |
288 |
[sta2x11_scr] = &sta2x11_scr_regmap_config, |
1950c7164 mfd: sta2x11-mfd:... |
289 |
}; |
35bdd2909 mfd: Add driver f... |
290 |
|
dba6c1aee mfd: sta2x11-mfd:... |
291 |
/* Probe for the four platform devices */ |
1950c7164 mfd: sta2x11-mfd:... |
292 293 294 |
static int sta2x11_mfd_platform_probe(struct platform_device *dev, enum sta2x11_mfd_plat_dev index) |
35bdd2909 mfd: Add driver f... |
295 296 297 298 |
{ struct pci_dev **pdev; struct sta2x11_mfd *mfd; struct resource *res; |
1950c7164 mfd: sta2x11-mfd:... |
299 |
const char *name = sta2x11_mfd_names[index]; |
d94e25535 mfd: sta2x11-mfd:... |
300 |
struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index]; |
35bdd2909 mfd: Add driver f... |
301 |
|
334a41ce9 mfd: Use dev_get_... |
302 |
pdev = dev_get_platdata(&dev->dev); |
35bdd2909 mfd: Add driver f... |
303 304 305 |
mfd = sta2x11_mfd_find(*pdev); if (!mfd) return -ENODEV; |
d94e25535 mfd: sta2x11-mfd:... |
306 307 |
if (!regmap_config) return -ENODEV; |
35bdd2909 mfd: Add driver f... |
308 309 310 311 |
res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) return -ENOMEM; |
1950c7164 mfd: sta2x11-mfd:... |
312 |
if (!request_mem_region(res->start, resource_size(res), name)) |
35bdd2909 mfd: Add driver f... |
313 |
return -EBUSY; |
1950c7164 mfd: sta2x11-mfd:... |
314 315 |
mfd->regs[index] = ioremap(res->start, resource_size(res)); if (!mfd->regs[index]) { |
35bdd2909 mfd: Add driver f... |
316 317 318 |
release_mem_region(res->start, resource_size(res)); return -ENOMEM; } |
d94e25535 mfd: sta2x11-mfd:... |
319 320 321 322 323 324 325 326 |
regmap_config->lock_arg = &mfd->lock; /* No caching, registers could be reached both via regmap and via void __iomem * */ regmap_config->cache_type = REGCACHE_NONE; mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index], regmap_config); |
ec9e4ba67 mfd: sta2x11-mfd:... |
327 |
WARN_ON(IS_ERR(mfd->regmap[index])); |
35bdd2909 mfd: Add driver f... |
328 |
|
35bdd2909 mfd: Add driver f... |
329 330 |
return 0; } |
1950c7164 mfd: sta2x11-mfd:... |
331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
static int sta2x11_sctl_probe(struct platform_device *dev) { return sta2x11_mfd_platform_probe(dev, sta2x11_sctl); } static int sta2x11_apbreg_probe(struct platform_device *dev) { return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg); } static int sta2x11_apb_soc_regs_probe(struct platform_device *dev) { return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs); } |
dba6c1aee mfd: sta2x11-mfd:... |
345 346 347 348 |
static int sta2x11_scr_probe(struct platform_device *dev) { return sta2x11_mfd_platform_probe(dev, sta2x11_scr); } |
1950c7164 mfd: sta2x11-mfd:... |
349 |
/* The three platform drivers */ |
35bdd2909 mfd: Add driver f... |
350 351 |
static struct platform_driver sta2x11_sctl_platform_driver = { .driver = { |
b18adafcc mfd: sta2x11-mfd:... |
352 |
.name = STA2X11_MFD_SCTL_NAME, |
35bdd2909 mfd: Add driver f... |
353 354 355 |
}, .probe = sta2x11_sctl_probe, }; |
35bdd2909 mfd: Add driver f... |
356 357 |
static struct platform_driver sta2x11_platform_driver = { .driver = { |
b18adafcc mfd: sta2x11-mfd:... |
358 |
.name = STA2X11_MFD_APBREG_NAME, |
35bdd2909 mfd: Add driver f... |
359 360 361 |
}, .probe = sta2x11_apbreg_probe, }; |
1950c7164 mfd: sta2x11-mfd:... |
362 363 |
static struct platform_driver sta2x11_apb_soc_regs_platform_driver = { .driver = { |
b18adafcc mfd: sta2x11-mfd:... |
364 |
.name = STA2X11_MFD_APB_SOC_REGS_NAME, |
1950c7164 mfd: sta2x11-mfd:... |
365 366 367 |
}, .probe = sta2x11_apb_soc_regs_probe, }; |
dba6c1aee mfd: sta2x11-mfd:... |
368 369 370 |
static struct platform_driver sta2x11_scr_platform_driver = { .driver = { .name = STA2X11_MFD_SCR_NAME, |
dba6c1aee mfd: sta2x11-mfd:... |
371 372 373 |
}, .probe = sta2x11_scr_probe, }; |
d91d76d84 mfd: sta2x11: Use... |
374 375 376 377 378 379 380 381 |
static struct platform_driver * const drivers[] = { &sta2x11_platform_driver, &sta2x11_sctl_platform_driver, &sta2x11_apb_soc_regs_platform_driver, &sta2x11_scr_platform_driver, }; static int __init sta2x11_drivers_init(void) |
dba6c1aee mfd: sta2x11-mfd:... |
382 |
{ |
d91d76d84 mfd: sta2x11: Use... |
383 |
return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); |
dba6c1aee mfd: sta2x11-mfd:... |
384 |
} |
35bdd2909 mfd: Add driver f... |
385 |
/* |
1950c7164 mfd: sta2x11-mfd:... |
386 |
* What follows are the PCI devices that host the above pdevs. |
35bdd2909 mfd: Add driver f... |
387 388 |
* Each logic block is 4kB and they are all consecutive: we use this info. */ |
1950c7164 mfd: sta2x11-mfd:... |
389 390 391 392 |
/* Mfd 0 device */ /* Mfd 0, Bar 0 */ enum mfd0_bar0_cells { |
35bdd2909 mfd: Add driver f... |
393 394 395 396 397 398 399 400 |
STA2X11_GPIO_0 = 0, STA2X11_GPIO_1, STA2X11_GPIO_2, STA2X11_GPIO_3, STA2X11_SCTL, STA2X11_SCR, STA2X11_TIME, }; |
1950c7164 mfd: sta2x11-mfd:... |
401 402 |
/* Mfd 0 , Bar 1 */ enum mfd0_bar1_cells { |
35bdd2909 mfd: Add driver f... |
403 404 405 406 407 408 409 |
STA2X11_APBREG = 0, }; #define CELL_4K(_name, _cell) { \ .name = _name, \ .start = _cell * 4096, .end = _cell * 4096 + 4095, \ .flags = IORESOURCE_MEM, \ } |
a73e5df16 mfd: remove use o... |
410 |
static const struct resource gpio_resources[] = { |
35bdd2909 mfd: Add driver f... |
411 |
{ |
b18adafcc mfd: sta2x11-mfd:... |
412 413 |
/* 4 consecutive cells, 1 driver */ .name = STA2X11_MFD_GPIO_NAME, |
35bdd2909 mfd: Add driver f... |
414 415 416 417 418 |
.start = 0, .end = (4 * 4096) - 1, .flags = IORESOURCE_MEM, } }; |
a73e5df16 mfd: remove use o... |
419 |
static const struct resource sctl_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
420 |
CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL), |
35bdd2909 mfd: Add driver f... |
421 |
}; |
a73e5df16 mfd: remove use o... |
422 |
static const struct resource scr_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
423 |
CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR), |
35bdd2909 mfd: Add driver f... |
424 |
}; |
a73e5df16 mfd: remove use o... |
425 |
static const struct resource time_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
426 |
CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME), |
35bdd2909 mfd: Add driver f... |
427 |
}; |
a73e5df16 mfd: remove use o... |
428 |
static const struct resource apbreg_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
429 |
CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG), |
35bdd2909 mfd: Add driver f... |
430 431 432 433 |
}; #define DEV(_name, _r) \ { .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, } |
2dfea3803 Merge tag 'mfd-3.... |
434 |
static struct mfd_cell sta2x11_mfd0_bar0[] = { |
b18adafcc mfd: sta2x11-mfd:... |
435 436 437 438 439 |
/* offset 0: we add pdata later */ DEV(STA2X11_MFD_GPIO_NAME, gpio_resources), DEV(STA2X11_MFD_SCTL_NAME, sctl_resources), DEV(STA2X11_MFD_SCR_NAME, scr_resources), DEV(STA2X11_MFD_TIME_NAME, time_resources), |
35bdd2909 mfd: Add driver f... |
440 |
}; |
2dfea3803 Merge tag 'mfd-3.... |
441 |
static struct mfd_cell sta2x11_mfd0_bar1[] = { |
b18adafcc mfd: sta2x11-mfd:... |
442 |
DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources), |
35bdd2909 mfd: Add driver f... |
443 |
}; |
1950c7164 mfd: sta2x11-mfd:... |
444 445 446 447 448 449 450 451 452 453 454 |
/* Mfd 1 devices */ /* Mfd 1, Bar 0 */ enum mfd1_bar0_cells { STA2X11_VIC = 0, }; /* Mfd 1, Bar 1 */ enum mfd1_bar1_cells { STA2X11_APB_SOC_REGS = 0, }; |
612b95cd7 Drivers: mfd: rem... |
455 |
static const struct resource vic_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
456 |
CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC), |
1950c7164 mfd: sta2x11-mfd:... |
457 |
}; |
612b95cd7 Drivers: mfd: rem... |
458 |
static const struct resource apb_soc_regs_resources[] = { |
b18adafcc mfd: sta2x11-mfd:... |
459 |
CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS), |
1950c7164 mfd: sta2x11-mfd:... |
460 |
}; |
612b95cd7 Drivers: mfd: rem... |
461 |
static struct mfd_cell sta2x11_mfd1_bar0[] = { |
b18adafcc mfd: sta2x11-mfd:... |
462 |
DEV(STA2X11_MFD_VIC_NAME, vic_resources), |
1950c7164 mfd: sta2x11-mfd:... |
463 |
}; |
612b95cd7 Drivers: mfd: rem... |
464 |
static struct mfd_cell sta2x11_mfd1_bar1[] = { |
b18adafcc mfd: sta2x11-mfd:... |
465 |
DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources), |
1950c7164 mfd: sta2x11-mfd:... |
466 |
}; |
35bdd2909 mfd: Add driver f... |
467 468 469 470 471 472 473 474 475 476 477 478 |
static int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state) { pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } static int sta2x11_mfd_resume(struct pci_dev *pdev) { int err; |
4d1d99807 mfd: sta2x11-mfd:... |
479 |
pci_set_power_state(pdev, PCI_D0); |
35bdd2909 mfd: Add driver f... |
480 481 482 483 484 485 486 |
err = pci_enable_device(pdev); if (err) return err; pci_restore_state(pdev); return 0; } |
1950c7164 mfd: sta2x11-mfd:... |
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
struct sta2x11_mfd_bar_setup_data { struct mfd_cell *cells; int ncells; }; struct sta2x11_mfd_setup_data { struct sta2x11_mfd_bar_setup_data bars[2]; }; #define STA2X11_MFD0 0 #define STA2X11_MFD1 1 static struct sta2x11_mfd_setup_data mfd_setup_data[] = { /* Mfd 0: gpio, sctl, scr, timers / apbregs */ [STA2X11_MFD0] = { .bars = { [0] = { .cells = sta2x11_mfd0_bar0, .ncells = ARRAY_SIZE(sta2x11_mfd0_bar0), }, [1] = { .cells = sta2x11_mfd0_bar1, .ncells = ARRAY_SIZE(sta2x11_mfd0_bar1), }, }, }, /* Mfd 1: vic / apb-soc-regs */ [STA2X11_MFD1] = { .bars = { [0] = { .cells = sta2x11_mfd1_bar0, .ncells = ARRAY_SIZE(sta2x11_mfd1_bar0), }, [1] = { .cells = sta2x11_mfd1_bar1, .ncells = ARRAY_SIZE(sta2x11_mfd1_bar1), }, }, }, }; |
2dfea3803 Merge tag 'mfd-3.... |
527 528 |
static void sta2x11_mfd_setup(struct pci_dev *pdev, struct sta2x11_mfd_setup_data *sd) |
1950c7164 mfd: sta2x11-mfd:... |
529 530 531 532 533 534 535 536 |
{ int i, j; for (i = 0; i < ARRAY_SIZE(sd->bars); i++) for (j = 0; j < sd->bars[i].ncells; j++) { sd->bars[i].cells[j].pdata_size = sizeof(pdev); sd->bars[i].cells[j].platform_data = &pdev; } } |
f791be492 mfd: remove use o... |
537 |
static int sta2x11_mfd_probe(struct pci_dev *pdev, |
2dfea3803 Merge tag 'mfd-3.... |
538 |
const struct pci_device_id *pci_id) |
35bdd2909 mfd: Add driver f... |
539 540 |
{ int err, i; |
1950c7164 mfd: sta2x11-mfd:... |
541 |
struct sta2x11_mfd_setup_data *setup_data; |
35bdd2909 mfd: Add driver f... |
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 |
dev_info(&pdev->dev, "%s ", __func__); err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Can't enable device. "); return err; } err = pci_enable_msi(pdev); if (err) dev_info(&pdev->dev, "Enable msi failed "); |
1950c7164 mfd: sta2x11-mfd:... |
557 558 559 |
setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ? &mfd_setup_data[STA2X11_MFD0] : &mfd_setup_data[STA2X11_MFD1]; |
35bdd2909 mfd: Add driver f... |
560 561 |
/* platform data is the pci device for all of them */ |
1950c7164 mfd: sta2x11-mfd:... |
562 |
sta2x11_mfd_setup(pdev, setup_data); |
35bdd2909 mfd: Add driver f... |
563 564 |
/* Record this pdev before mfd_add_devices: their probe looks for it */ |
8ec86a302 mfd: sta2x11-mfd:... |
565 566 |
if (!sta2x11_mfd_find(pdev)) sta2x11_mfd_add(pdev, GFP_ATOMIC); |
35bdd2909 mfd: Add driver f... |
567 |
|
1950c7164 mfd: sta2x11-mfd:... |
568 569 570 571 572 573 574 575 576 577 578 579 580 |
/* Just 2 bars for all mfd's at present */ for (i = 0; i < 2; i++) { err = mfd_add_devices(&pdev->dev, -1, setup_data->bars[i].cells, setup_data->bars[i].ncells, &pdev->resource[i], 0, NULL); if (err) { dev_err(&pdev->dev, "mfd_add_devices[%d] failed: %d ", i, err); goto err_disable; } |
35bdd2909 mfd: Add driver f... |
581 582 583 584 585 586 587 588 589 590 |
} return 0; err_disable: mfd_remove_devices(&pdev->dev); pci_disable_device(pdev); pci_disable_msi(pdev); return err; } |
36fcd06c4 mfd: Remove DEFIN... |
591 |
static const struct pci_device_id sta2x11_mfd_tbl[] = { |
35bdd2909 mfd: Add driver f... |
592 |
{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)}, |
1950c7164 mfd: sta2x11-mfd:... |
593 |
{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)}, |
35bdd2909 mfd: Add driver f... |
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 |
{0,}, }; static struct pci_driver sta2x11_mfd_driver = { .name = "sta2x11-mfd", .id_table = sta2x11_mfd_tbl, .probe = sta2x11_mfd_probe, .suspend = sta2x11_mfd_suspend, .resume = sta2x11_mfd_resume, }; static int __init sta2x11_mfd_init(void) { pr_info("%s ", __func__); return pci_register_driver(&sta2x11_mfd_driver); } /* * All of this must be ready before "normal" devices like MMCI appear. * But MFD (the pci device) can't be too early. The following choice * prepares platform drivers very early and probe the PCI device later, * but before other PCI devices. */ |
d91d76d84 mfd: sta2x11: Use... |
618 |
subsys_initcall(sta2x11_drivers_init); |
35bdd2909 mfd: Add driver f... |
619 |
rootfs_initcall(sta2x11_mfd_init); |