aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAaron Sierra <asierra@xes-inc.com>2012-04-20 15:14:11 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-09 11:20:09 -0400
commit887c8ec7219fc8eba78bb8f44a74c660934e9b98 (patch)
treec7f5b2d24c984a7ca57120dd057cd3cd2f6efee2 /drivers/mfd
parent16c5c023aac86228e3e94c4bf6d19708ea861a05 (diff)
watchdog: Convert iTCO_wdt driver to mfd model
This patch converts the iTCO_wdt driver to use the multi-function device driver model. It uses resources discovered by the lpc_ich driver, so that it no longer does its own PCI scanning. Signed-off-by: Aaron Sierra <asierra@xes-inc.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig3
-rw-r--r--drivers/mfd/lpc_ich.c171
2 files changed, 172 insertions, 2 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 211f5dee9b68..1e9a7d5ec919 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -785,7 +785,8 @@ config LPC_ICH
785 help 785 help
786 The LPC bridge function of the Intel ICH provides support for 786 The LPC bridge function of the Intel ICH provides support for
787 many functional units. This driver provides needed support for 787 many functional units. This driver provides needed support for
788 other drivers to control these functions, currently GPIO. 788 other drivers to control these functions, currently GPIO and
789 watchdog.
789 790
790config MFD_RDC321X 791config MFD_RDC321X
791 tristate "Support for RDC-R321x southbridge" 792 tristate "Support for RDC-R321x southbridge"
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 7e3a7b6ab022..027cc8f86132 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -65,14 +65,42 @@
65#define ACPIBASE 0x40 65#define ACPIBASE 0x40
66#define ACPIBASE_GPE_OFF 0x28 66#define ACPIBASE_GPE_OFF 0x28
67#define ACPIBASE_GPE_END 0x2f 67#define ACPIBASE_GPE_END 0x2f
68#define ACPIBASE_SMI_OFF 0x30
69#define ACPIBASE_SMI_END 0x33
70#define ACPIBASE_TCO_OFF 0x60
71#define ACPIBASE_TCO_END 0x7f
68#define ACPICTRL 0x44 72#define ACPICTRL 0x44
69 73
74#define ACPIBASE_GCS_OFF 0x3410
75#define ACPIBASE_GCS_END 0x3414
76
70#define GPIOBASE 0x48 77#define GPIOBASE 0x48
71#define GPIOCTRL 0x4C 78#define GPIOCTRL 0x4C
72 79
80#define RCBABASE 0xf0
81
82#define wdt_io_res(i) wdt_res(0, i)
83#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
84#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
85
73static int lpc_ich_acpi_save = -1; 86static int lpc_ich_acpi_save = -1;
74static int lpc_ich_gpio_save = -1; 87static int lpc_ich_gpio_save = -1;
75 88
89static struct resource wdt_ich_res[] = {
90 /* ACPI - TCO */
91 {
92 .flags = IORESOURCE_IO,
93 },
94 /* ACPI - SMI */
95 {
96 .flags = IORESOURCE_IO,
97 },
98 /* GCS */
99 {
100 .flags = IORESOURCE_MEM,
101 },
102};
103
76static struct resource gpio_ich_res[] = { 104static struct resource gpio_ich_res[] = {
77 /* GPIO */ 105 /* GPIO */
78 { 106 {
@@ -85,10 +113,17 @@ static struct resource gpio_ich_res[] = {
85}; 113};
86 114
87enum lpc_cells { 115enum lpc_cells {
88 LPC_GPIO = 0, 116 LPC_WDT = 0,
117 LPC_GPIO,
89}; 118};
90 119
91static struct mfd_cell lpc_ich_cells[] = { 120static struct mfd_cell lpc_ich_cells[] = {
121 [LPC_WDT] = {
122 .name = "iTCO_wdt",
123 .num_resources = ARRAY_SIZE(wdt_ich_res),
124 .resources = wdt_ich_res,
125 .ignore_resource_conflicts = true,
126 },
92 [LPC_GPIO] = { 127 [LPC_GPIO] = {
93 .name = "gpio_ich", 128 .name = "gpio_ich",
94 .num_resources = ARRAY_SIZE(gpio_ich_res), 129 .num_resources = ARRAY_SIZE(gpio_ich_res),
@@ -162,218 +197,276 @@ enum lpc_chipsets {
162struct lpc_ich_info lpc_chipset_info[] __devinitdata = { 197struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
163 [LPC_ICH] = { 198 [LPC_ICH] = {
164 .name = "ICH", 199 .name = "ICH",
200 .iTCO_version = 1,
165 }, 201 },
166 [LPC_ICH0] = { 202 [LPC_ICH0] = {
167 .name = "ICH0", 203 .name = "ICH0",
204 .iTCO_version = 1,
168 }, 205 },
169 [LPC_ICH2] = { 206 [LPC_ICH2] = {
170 .name = "ICH2", 207 .name = "ICH2",
208 .iTCO_version = 1,
171 }, 209 },
172 [LPC_ICH2M] = { 210 [LPC_ICH2M] = {
173 .name = "ICH2-M", 211 .name = "ICH2-M",
212 .iTCO_version = 1,
174 }, 213 },
175 [LPC_ICH3] = { 214 [LPC_ICH3] = {
176 .name = "ICH3-S", 215 .name = "ICH3-S",
216 .iTCO_version = 1,
177 }, 217 },
178 [LPC_ICH3M] = { 218 [LPC_ICH3M] = {
179 .name = "ICH3-M", 219 .name = "ICH3-M",
220 .iTCO_version = 1,
180 }, 221 },
181 [LPC_ICH4] = { 222 [LPC_ICH4] = {
182 .name = "ICH4", 223 .name = "ICH4",
224 .iTCO_version = 1,
183 }, 225 },
184 [LPC_ICH4M] = { 226 [LPC_ICH4M] = {
185 .name = "ICH4-M", 227 .name = "ICH4-M",
228 .iTCO_version = 1,
186 }, 229 },
187 [LPC_CICH] = { 230 [LPC_CICH] = {
188 .name = "C-ICH", 231 .name = "C-ICH",
232 .iTCO_version = 1,
189 }, 233 },
190 [LPC_ICH5] = { 234 [LPC_ICH5] = {
191 .name = "ICH5 or ICH5R", 235 .name = "ICH5 or ICH5R",
236 .iTCO_version = 1,
192 }, 237 },
193 [LPC_6300ESB] = { 238 [LPC_6300ESB] = {
194 .name = "6300ESB", 239 .name = "6300ESB",
240 .iTCO_version = 1,
195 }, 241 },
196 [LPC_ICH6] = { 242 [LPC_ICH6] = {
197 .name = "ICH6 or ICH6R", 243 .name = "ICH6 or ICH6R",
244 .iTCO_version = 2,
198 .gpio_version = ICH_V6_GPIO, 245 .gpio_version = ICH_V6_GPIO,
199 }, 246 },
200 [LPC_ICH6M] = { 247 [LPC_ICH6M] = {
201 .name = "ICH6-M", 248 .name = "ICH6-M",
249 .iTCO_version = 2,
202 .gpio_version = ICH_V6_GPIO, 250 .gpio_version = ICH_V6_GPIO,
203 }, 251 },
204 [LPC_ICH6W] = { 252 [LPC_ICH6W] = {
205 .name = "ICH6W or ICH6RW", 253 .name = "ICH6W or ICH6RW",
254 .iTCO_version = 2,
206 .gpio_version = ICH_V6_GPIO, 255 .gpio_version = ICH_V6_GPIO,
207 }, 256 },
208 [LPC_631XESB] = { 257 [LPC_631XESB] = {
209 .name = "631xESB/632xESB", 258 .name = "631xESB/632xESB",
259 .iTCO_version = 2,
210 .gpio_version = ICH_V6_GPIO, 260 .gpio_version = ICH_V6_GPIO,
211 }, 261 },
212 [LPC_ICH7] = { 262 [LPC_ICH7] = {
213 .name = "ICH7 or ICH7R", 263 .name = "ICH7 or ICH7R",
264 .iTCO_version = 2,
214 .gpio_version = ICH_V7_GPIO, 265 .gpio_version = ICH_V7_GPIO,
215 }, 266 },
216 [LPC_ICH7DH] = { 267 [LPC_ICH7DH] = {
217 .name = "ICH7DH", 268 .name = "ICH7DH",
269 .iTCO_version = 2,
218 .gpio_version = ICH_V7_GPIO, 270 .gpio_version = ICH_V7_GPIO,
219 }, 271 },
220 [LPC_ICH7M] = { 272 [LPC_ICH7M] = {
221 .name = "ICH7-M or ICH7-U", 273 .name = "ICH7-M or ICH7-U",
274 .iTCO_version = 2,
222 .gpio_version = ICH_V7_GPIO, 275 .gpio_version = ICH_V7_GPIO,
223 }, 276 },
224 [LPC_ICH7MDH] = { 277 [LPC_ICH7MDH] = {
225 .name = "ICH7-M DH", 278 .name = "ICH7-M DH",
279 .iTCO_version = 2,
226 .gpio_version = ICH_V7_GPIO, 280 .gpio_version = ICH_V7_GPIO,
227 }, 281 },
228 [LPC_NM10] = { 282 [LPC_NM10] = {
229 .name = "NM10", 283 .name = "NM10",
284 .iTCO_version = 2,
230 }, 285 },
231 [LPC_ICH8] = { 286 [LPC_ICH8] = {
232 .name = "ICH8 or ICH8R", 287 .name = "ICH8 or ICH8R",
288 .iTCO_version = 2,
233 .gpio_version = ICH_V7_GPIO, 289 .gpio_version = ICH_V7_GPIO,
234 }, 290 },
235 [LPC_ICH8DH] = { 291 [LPC_ICH8DH] = {
236 .name = "ICH8DH", 292 .name = "ICH8DH",
293 .iTCO_version = 2,
237 .gpio_version = ICH_V7_GPIO, 294 .gpio_version = ICH_V7_GPIO,
238 }, 295 },
239 [LPC_ICH8DO] = { 296 [LPC_ICH8DO] = {
240 .name = "ICH8DO", 297 .name = "ICH8DO",
298 .iTCO_version = 2,
241 .gpio_version = ICH_V7_GPIO, 299 .gpio_version = ICH_V7_GPIO,
242 }, 300 },
243 [LPC_ICH8M] = { 301 [LPC_ICH8M] = {
244 .name = "ICH8M", 302 .name = "ICH8M",
303 .iTCO_version = 2,
245 .gpio_version = ICH_V7_GPIO, 304 .gpio_version = ICH_V7_GPIO,
246 }, 305 },
247 [LPC_ICH8ME] = { 306 [LPC_ICH8ME] = {
248 .name = "ICH8M-E", 307 .name = "ICH8M-E",
308 .iTCO_version = 2,
249 .gpio_version = ICH_V7_GPIO, 309 .gpio_version = ICH_V7_GPIO,
250 }, 310 },
251 [LPC_ICH9] = { 311 [LPC_ICH9] = {
252 .name = "ICH9", 312 .name = "ICH9",
313 .iTCO_version = 2,
253 .gpio_version = ICH_V9_GPIO, 314 .gpio_version = ICH_V9_GPIO,
254 }, 315 },
255 [LPC_ICH9R] = { 316 [LPC_ICH9R] = {
256 .name = "ICH9R", 317 .name = "ICH9R",
318 .iTCO_version = 2,
257 .gpio_version = ICH_V9_GPIO, 319 .gpio_version = ICH_V9_GPIO,
258 }, 320 },
259 [LPC_ICH9DH] = { 321 [LPC_ICH9DH] = {
260 .name = "ICH9DH", 322 .name = "ICH9DH",
323 .iTCO_version = 2,
261 .gpio_version = ICH_V9_GPIO, 324 .gpio_version = ICH_V9_GPIO,
262 }, 325 },
263 [LPC_ICH9DO] = { 326 [LPC_ICH9DO] = {
264 .name = "ICH9DO", 327 .name = "ICH9DO",
328 .iTCO_version = 2,
265 .gpio_version = ICH_V9_GPIO, 329 .gpio_version = ICH_V9_GPIO,
266 }, 330 },
267 [LPC_ICH9M] = { 331 [LPC_ICH9M] = {
268 .name = "ICH9M", 332 .name = "ICH9M",
333 .iTCO_version = 2,
269 .gpio_version = ICH_V9_GPIO, 334 .gpio_version = ICH_V9_GPIO,
270 }, 335 },
271 [LPC_ICH9ME] = { 336 [LPC_ICH9ME] = {
272 .name = "ICH9M-E", 337 .name = "ICH9M-E",
338 .iTCO_version = 2,
273 .gpio_version = ICH_V9_GPIO, 339 .gpio_version = ICH_V9_GPIO,
274 }, 340 },
275 [LPC_ICH10] = { 341 [LPC_ICH10] = {
276 .name = "ICH10", 342 .name = "ICH10",
343 .iTCO_version = 2,
277 .gpio_version = ICH_V10CONS_GPIO, 344 .gpio_version = ICH_V10CONS_GPIO,
278 }, 345 },
279 [LPC_ICH10R] = { 346 [LPC_ICH10R] = {
280 .name = "ICH10R", 347 .name = "ICH10R",
348 .iTCO_version = 2,
281 .gpio_version = ICH_V10CONS_GPIO, 349 .gpio_version = ICH_V10CONS_GPIO,
282 }, 350 },
283 [LPC_ICH10D] = { 351 [LPC_ICH10D] = {
284 .name = "ICH10D", 352 .name = "ICH10D",
353 .iTCO_version = 2,
285 .gpio_version = ICH_V10CORP_GPIO, 354 .gpio_version = ICH_V10CORP_GPIO,
286 }, 355 },
287 [LPC_ICH10DO] = { 356 [LPC_ICH10DO] = {
288 .name = "ICH10DO", 357 .name = "ICH10DO",
358 .iTCO_version = 2,
289 .gpio_version = ICH_V10CORP_GPIO, 359 .gpio_version = ICH_V10CORP_GPIO,
290 }, 360 },
291 [LPC_PCH] = { 361 [LPC_PCH] = {
292 .name = "PCH Desktop Full Featured", 362 .name = "PCH Desktop Full Featured",
363 .iTCO_version = 2,
293 .gpio_version = ICH_V5_GPIO, 364 .gpio_version = ICH_V5_GPIO,
294 }, 365 },
295 [LPC_PCHM] = { 366 [LPC_PCHM] = {
296 .name = "PCH Mobile Full Featured", 367 .name = "PCH Mobile Full Featured",
368 .iTCO_version = 2,
297 .gpio_version = ICH_V5_GPIO, 369 .gpio_version = ICH_V5_GPIO,
298 }, 370 },
299 [LPC_P55] = { 371 [LPC_P55] = {
300 .name = "P55", 372 .name = "P55",
373 .iTCO_version = 2,
301 .gpio_version = ICH_V5_GPIO, 374 .gpio_version = ICH_V5_GPIO,
302 }, 375 },
303 [LPC_PM55] = { 376 [LPC_PM55] = {
304 .name = "PM55", 377 .name = "PM55",
378 .iTCO_version = 2,
305 .gpio_version = ICH_V5_GPIO, 379 .gpio_version = ICH_V5_GPIO,
306 }, 380 },
307 [LPC_H55] = { 381 [LPC_H55] = {
308 .name = "H55", 382 .name = "H55",
383 .iTCO_version = 2,
309 .gpio_version = ICH_V5_GPIO, 384 .gpio_version = ICH_V5_GPIO,
310 }, 385 },
311 [LPC_QM57] = { 386 [LPC_QM57] = {
312 .name = "QM57", 387 .name = "QM57",
388 .iTCO_version = 2,
313 .gpio_version = ICH_V5_GPIO, 389 .gpio_version = ICH_V5_GPIO,
314 }, 390 },
315 [LPC_H57] = { 391 [LPC_H57] = {
316 .name = "H57", 392 .name = "H57",
393 .iTCO_version = 2,
317 .gpio_version = ICH_V5_GPIO, 394 .gpio_version = ICH_V5_GPIO,
318 }, 395 },
319 [LPC_HM55] = { 396 [LPC_HM55] = {
320 .name = "HM55", 397 .name = "HM55",
398 .iTCO_version = 2,
321 .gpio_version = ICH_V5_GPIO, 399 .gpio_version = ICH_V5_GPIO,
322 }, 400 },
323 [LPC_Q57] = { 401 [LPC_Q57] = {
324 .name = "Q57", 402 .name = "Q57",
403 .iTCO_version = 2,
325 .gpio_version = ICH_V5_GPIO, 404 .gpio_version = ICH_V5_GPIO,
326 }, 405 },
327 [LPC_HM57] = { 406 [LPC_HM57] = {
328 .name = "HM57", 407 .name = "HM57",
408 .iTCO_version = 2,
329 .gpio_version = ICH_V5_GPIO, 409 .gpio_version = ICH_V5_GPIO,
330 }, 410 },
331 [LPC_PCHMSFF] = { 411 [LPC_PCHMSFF] = {
332 .name = "PCH Mobile SFF Full Featured", 412 .name = "PCH Mobile SFF Full Featured",
413 .iTCO_version = 2,
333 .gpio_version = ICH_V5_GPIO, 414 .gpio_version = ICH_V5_GPIO,
334 }, 415 },
335 [LPC_QS57] = { 416 [LPC_QS57] = {
336 .name = "QS57", 417 .name = "QS57",
418 .iTCO_version = 2,
337 .gpio_version = ICH_V5_GPIO, 419 .gpio_version = ICH_V5_GPIO,
338 }, 420 },
339 [LPC_3400] = { 421 [LPC_3400] = {
340 .name = "3400", 422 .name = "3400",
423 .iTCO_version = 2,
341 .gpio_version = ICH_V5_GPIO, 424 .gpio_version = ICH_V5_GPIO,
342 }, 425 },
343 [LPC_3420] = { 426 [LPC_3420] = {
344 .name = "3420", 427 .name = "3420",
428 .iTCO_version = 2,
345 .gpio_version = ICH_V5_GPIO, 429 .gpio_version = ICH_V5_GPIO,
346 }, 430 },
347 [LPC_3450] = { 431 [LPC_3450] = {
348 .name = "3450", 432 .name = "3450",
433 .iTCO_version = 2,
349 .gpio_version = ICH_V5_GPIO, 434 .gpio_version = ICH_V5_GPIO,
350 }, 435 },
351 [LPC_EP80579] = { 436 [LPC_EP80579] = {
352 .name = "EP80579", 437 .name = "EP80579",
438 .iTCO_version = 2,
353 }, 439 },
354 [LPC_CPT] = { 440 [LPC_CPT] = {
355 .name = "Cougar Point", 441 .name = "Cougar Point",
442 .iTCO_version = 2,
356 .gpio_version = ICH_V5_GPIO, 443 .gpio_version = ICH_V5_GPIO,
357 }, 444 },
358 [LPC_CPTD] = { 445 [LPC_CPTD] = {
359 .name = "Cougar Point Desktop", 446 .name = "Cougar Point Desktop",
447 .iTCO_version = 2,
360 .gpio_version = ICH_V5_GPIO, 448 .gpio_version = ICH_V5_GPIO,
361 }, 449 },
362 [LPC_CPTM] = { 450 [LPC_CPTM] = {
363 .name = "Cougar Point Mobile", 451 .name = "Cougar Point Mobile",
452 .iTCO_version = 2,
364 .gpio_version = ICH_V5_GPIO, 453 .gpio_version = ICH_V5_GPIO,
365 }, 454 },
366 [LPC_PBG] = { 455 [LPC_PBG] = {
367 .name = "Patsburg", 456 .name = "Patsburg",
457 .iTCO_version = 2,
368 }, 458 },
369 [LPC_DH89XXCC] = { 459 [LPC_DH89XXCC] = {
370 .name = "DH89xxCC", 460 .name = "DH89xxCC",
461 .iTCO_version = 2,
371 }, 462 },
372 [LPC_PPT] = { 463 [LPC_PPT] = {
373 .name = "Panther Point", 464 .name = "Panther Point",
465 .iTCO_version = 2,
374 }, 466 },
375 [LPC_LPT] = { 467 [LPC_LPT] = {
376 .name = "Lynx Point", 468 .name = "Lynx Point",
469 .iTCO_version = 2,
377 }, 470 },
378}; 471};
379 472
@@ -666,12 +759,88 @@ gpio_done:
666 return ret; 759 return ret;
667} 760}
668 761
762static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
763 const struct pci_device_id *id)
764{
765 u32 base_addr_cfg;
766 u32 base_addr;
767 int ret;
768 bool acpi_conflict = false;
769 struct resource *res;
770
771 /* Setup power management base register */
772 pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg);
773 base_addr = base_addr_cfg & 0x0000ff80;
774 if (!base_addr) {
775 dev_err(&dev->dev, "I/O space for ACPI uninitialized\n");
776 ret = -ENODEV;
777 goto wdt_done;
778 }
779
780 res = wdt_io_res(ICH_RES_IO_TCO);
781 res->start = base_addr + ACPIBASE_TCO_OFF;
782 res->end = base_addr + ACPIBASE_TCO_END;
783 ret = acpi_check_resource_conflict(res);
784 if (ret) {
785 acpi_conflict = true;
786 goto wdt_done;
787 }
788
789 res = wdt_io_res(ICH_RES_IO_SMI);
790 res->start = base_addr + ACPIBASE_SMI_OFF;
791 res->end = base_addr + ACPIBASE_SMI_END;
792 ret = acpi_check_resource_conflict(res);
793 if (ret) {
794 acpi_conflict = true;
795 goto wdt_done;
796 }
797 lpc_ich_enable_acpi_space(dev);
798
799 /*
800 * Get the Memory-Mapped GCS register. To get access to it
801 * we have to read RCBA from PCI Config space 0xf0 and use
802 * it as base. GCS = RCBA + ICH6_GCS(0x3410).
803 */
804 if (lpc_chipset_info[id->driver_data].iTCO_version == 2) {
805 pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
806 base_addr = base_addr_cfg & 0xffffc000;
807 if (!(base_addr_cfg & 1)) {
808 pr_err("RCBA is disabled by hardware/BIOS, "
809 "device disabled\n");
810 ret = -ENODEV;
811 goto wdt_done;
812 }
813 res = wdt_mem_res(ICH_RES_MEM_GCS);
814 res->start = base_addr + ACPIBASE_GCS_OFF;
815 res->end = base_addr + ACPIBASE_GCS_END;
816 ret = acpi_check_resource_conflict(res);
817 if (ret) {
818 acpi_conflict = true;
819 goto wdt_done;
820 }
821 }
822
823 lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id);
824 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT],
825 1, NULL, 0);
826
827wdt_done:
828 if (acpi_conflict)
829 pr_warn("Resource conflict(s) found affecting %s\n",
830 lpc_ich_cells[LPC_WDT].name);
831 return ret;
832}
833
669static int __devinit lpc_ich_probe(struct pci_dev *dev, 834static int __devinit lpc_ich_probe(struct pci_dev *dev,
670 const struct pci_device_id *id) 835 const struct pci_device_id *id)
671{ 836{
672 int ret; 837 int ret;
673 bool cell_added = false; 838 bool cell_added = false;
674 839
840 ret = lpc_ich_init_wdt(dev, id);
841 if (!ret)
842 cell_added = true;
843
675 ret = lpc_ich_init_gpio(dev, id); 844 ret = lpc_ich_init_gpio(dev, id);
676 if (!ret) 845 if (!ret)
677 cell_added = true; 846 cell_added = true;