55 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
58 #include <linux/kernel.h>
59 #include <linux/module.h>
60 #include <linux/errno.h>
62 #include <linux/pci.h>
67 #define ACPIBASE_GPE_OFF 0x28
68 #define ACPIBASE_GPE_END 0x2f
69 #define ACPIBASE_SMI_OFF 0x30
70 #define ACPIBASE_SMI_END 0x33
71 #define ACPIBASE_TCO_OFF 0x60
72 #define ACPIBASE_TCO_END 0x7f
75 #define ACPIBASE_GCS_OFF 0x3410
76 #define ACPIBASE_GCS_END 0x3414
83 #define wdt_io_res(i) wdt_res(0, i)
84 #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
85 #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
87 static int lpc_ich_acpi_save = -1;
88 static int lpc_ich_gpio_save = -1;
90 static struct resource wdt_ich_res[] = {
105 static struct resource gpio_ich_res[] = {
121 static struct mfd_cell lpc_ich_cells[] = {
125 .resources = wdt_ich_res,
126 .ignore_resource_conflicts =
true,
131 .resources = gpio_ich_res,
132 .ignore_resource_conflicts =
true,
237 .name =
"ICH5 or ICH5R",
245 .name =
"ICH6 or ICH6R",
255 .name =
"ICH6W or ICH6RW",
260 .name =
"631xESB/632xESB",
265 .name =
"ICH7 or ICH7R",
275 .name =
"ICH7-M or ICH7-U",
289 .name =
"ICH8 or ICH8R",
364 .name =
"PCH Desktop Full Featured",
369 .name =
"PCH Mobile Full Featured",
414 .name =
"PCH Mobile SFF Full Featured",
443 .name =
"Cougar Point",
448 .name =
"Cougar Point Desktop",
453 .name =
"Cougar Point Mobile",
466 .name =
"Panther Point",
470 .name =
"Lynx Point",
474 .name =
"Lynx Point_LP",
662 static void lpc_ich_restore_config_space(
struct pci_dev *
dev)
664 if (lpc_ich_acpi_save >= 0) {
665 pci_write_config_byte(dev,
ACPICTRL, lpc_ich_acpi_save);
666 lpc_ich_acpi_save = -1;
669 if (lpc_ich_gpio_save >= 0) {
670 pci_write_config_byte(dev,
GPIOCTRL, lpc_ich_gpio_save);
671 lpc_ich_gpio_save = -1;
679 pci_read_config_byte(dev,
ACPICTRL, ®_save);
680 pci_write_config_byte(dev,
ACPICTRL, reg_save | 0x10);
681 lpc_ich_acpi_save = reg_save;
688 pci_read_config_byte(dev,
GPIOCTRL, ®_save);
689 pci_write_config_byte(dev,
GPIOCTRL, reg_save | 0x10);
690 lpc_ich_gpio_save = reg_save;
710 if (resource_size(res) >= 0x50 &&
721 return use_gpio ? use_gpio :
ret;
730 bool acpi_conflict =
false;
734 pci_read_config_dword(dev,
ACPIBASE, &base_addr_cfg);
735 base_addr = base_addr_cfg & 0x0000ff80;
737 dev_err(&dev->
dev,
"I/O space for ACPI uninitialized\n");
753 acpi_conflict =
true;
755 lpc_ich_enable_acpi_space(dev);
760 pci_read_config_dword(dev,
GPIOBASE, &base_addr_cfg);
761 base_addr = base_addr_cfg & 0x0000ff80;
763 dev_err(&dev->
dev,
"I/O space for GPIO uninitialized\n");
770 res->
start = base_addr;
771 switch (lpc_chipset_info[id->
driver_data].gpio_version) {
781 ret = lpc_ich_check_conflict_gpio(res);
784 acpi_conflict =
true;
787 lpc_chipset_info[
id->driver_data].use_gpio =
ret;
788 lpc_ich_enable_gpio_space(dev);
790 lpc_ich_finalize_cell(&lpc_ich_cells[
LPC_GPIO],
id);
796 pr_warn(
"Resource conflict(s) found affecting %s\n",
810 pci_read_config_dword(dev,
ACPIBASE, &base_addr_cfg);
811 base_addr = base_addr_cfg & 0x0000ff80;
813 dev_err(&dev->
dev,
"I/O space for ACPI uninitialized\n");
826 lpc_ich_enable_acpi_space(dev);
833 if (lpc_chipset_info[id->
driver_data].iTCO_version == 2) {
834 pci_read_config_dword(dev,
RCBABASE, &base_addr_cfg);
835 base_addr = base_addr_cfg & 0xffffc000;
836 if (!(base_addr_cfg & 1)) {
837 pr_err(
"RCBA is disabled by hardware/BIOS, "
838 "device disabled\n");
847 lpc_ich_finalize_cell(&lpc_ich_cells[
LPC_WDT],
id);
859 bool cell_added =
false;
861 ret = lpc_ich_init_wdt(dev,
id);
865 ret = lpc_ich_init_gpio(dev,
id);
874 lpc_ich_restore_config_space(dev);
884 lpc_ich_restore_config_space(dev);
889 .id_table = lpc_ich_ids,
890 .probe = lpc_ich_probe,
894 static int __init lpc_ich_init(
void)
896 return pci_register_driver(&lpc_ich_driver);
899 static void __exit lpc_ich_exit(
void)