diff options
Diffstat (limited to 'drivers/mfd/lpc_ich.c')
-rw-r--r-- | drivers/mfd/lpc_ich.c | 151 |
1 files changed, 108 insertions, 43 deletions
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index be93fa261ded..3f10ea3f45d1 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -58,7 +58,6 @@ | |||
58 | 58 | ||
59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
60 | 60 | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
63 | #include <linux/module.h> | 62 | #include <linux/module.h> |
64 | #include <linux/errno.h> | 63 | #include <linux/errno.h> |
@@ -72,9 +71,11 @@ | |||
72 | #define ACPIBASE_GPE_END 0x2f | 71 | #define ACPIBASE_GPE_END 0x2f |
73 | #define ACPIBASE_SMI_OFF 0x30 | 72 | #define ACPIBASE_SMI_OFF 0x30 |
74 | #define ACPIBASE_SMI_END 0x33 | 73 | #define ACPIBASE_SMI_END 0x33 |
74 | #define ACPIBASE_PMC_OFF 0x08 | ||
75 | #define ACPIBASE_PMC_END 0x0c | ||
75 | #define ACPIBASE_TCO_OFF 0x60 | 76 | #define ACPIBASE_TCO_OFF 0x60 |
76 | #define ACPIBASE_TCO_END 0x7f | 77 | #define ACPIBASE_TCO_END 0x7f |
77 | #define ACPICTRL 0x44 | 78 | #define ACPICTRL_PMCBASE 0x44 |
78 | 79 | ||
79 | #define ACPIBASE_GCS_OFF 0x3410 | 80 | #define ACPIBASE_GCS_OFF 0x3410 |
80 | #define ACPIBASE_GCS_END 0x3414 | 81 | #define ACPIBASE_GCS_END 0x3414 |
@@ -90,16 +91,17 @@ | |||
90 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) | 91 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) |
91 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) | 92 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) |
92 | 93 | ||
93 | struct lpc_ich_cfg { | ||
94 | int base; | ||
95 | int ctrl; | ||
96 | int save; | ||
97 | }; | ||
98 | |||
99 | struct lpc_ich_priv { | 94 | struct lpc_ich_priv { |
100 | int chipset; | 95 | int chipset; |
101 | struct lpc_ich_cfg acpi; | 96 | |
102 | struct lpc_ich_cfg gpio; | 97 | int abase; /* ACPI base */ |
98 | int actrl_pbase; /* ACPI control or PMC base */ | ||
99 | int gbase; /* GPIO base */ | ||
100 | int gctrl; /* GPIO control */ | ||
101 | |||
102 | int abase_save; /* Cached ACPI base value */ | ||
103 | int actrl_pbase_save; /* Cached ACPI control or PMC base value */ | ||
104 | int gctrl_save; /* Cached GPIO control value */ | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static struct resource wdt_ich_res[] = { | 107 | static struct resource wdt_ich_res[] = { |
@@ -111,7 +113,7 @@ static struct resource wdt_ich_res[] = { | |||
111 | { | 113 | { |
112 | .flags = IORESOURCE_IO, | 114 | .flags = IORESOURCE_IO, |
113 | }, | 115 | }, |
114 | /* GCS */ | 116 | /* GCS or PMC */ |
115 | { | 117 | { |
116 | .flags = IORESOURCE_MEM, | 118 | .flags = IORESOURCE_MEM, |
117 | }, | 119 | }, |
@@ -211,6 +213,7 @@ enum lpc_chipsets { | |||
211 | LPC_LPT_LP, /* Lynx Point-LP */ | 213 | LPC_LPT_LP, /* Lynx Point-LP */ |
212 | LPC_WBG, /* Wellsburg */ | 214 | LPC_WBG, /* Wellsburg */ |
213 | LPC_AVN, /* Avoton SoC */ | 215 | LPC_AVN, /* Avoton SoC */ |
216 | LPC_BAYTRAIL, /* Bay Trail SoC */ | ||
214 | LPC_COLETO, /* Coleto Creek */ | 217 | LPC_COLETO, /* Coleto Creek */ |
215 | LPC_WPT_LP, /* Wildcat Point-LP */ | 218 | LPC_WPT_LP, /* Wildcat Point-LP */ |
216 | }; | 219 | }; |
@@ -303,6 +306,7 @@ static struct lpc_ich_info lpc_chipset_info[] = { | |||
303 | [LPC_NM10] = { | 306 | [LPC_NM10] = { |
304 | .name = "NM10", | 307 | .name = "NM10", |
305 | .iTCO_version = 2, | 308 | .iTCO_version = 2, |
309 | .gpio_version = ICH_V7_GPIO, | ||
306 | }, | 310 | }, |
307 | [LPC_ICH8] = { | 311 | [LPC_ICH8] = { |
308 | .name = "ICH8 or ICH8R", | 312 | .name = "ICH8 or ICH8R", |
@@ -499,7 +503,12 @@ static struct lpc_ich_info lpc_chipset_info[] = { | |||
499 | }, | 503 | }, |
500 | [LPC_AVN] = { | 504 | [LPC_AVN] = { |
501 | .name = "Avoton SoC", | 505 | .name = "Avoton SoC", |
502 | .iTCO_version = 1, | 506 | .iTCO_version = 3, |
507 | .gpio_version = AVOTON_GPIO, | ||
508 | }, | ||
509 | [LPC_BAYTRAIL] = { | ||
510 | .name = "Bay Trail SoC", | ||
511 | .iTCO_version = 3, | ||
503 | }, | 512 | }, |
504 | [LPC_COLETO] = { | 513 | [LPC_COLETO] = { |
505 | .name = "Coleto Creek", | 514 | .name = "Coleto Creek", |
@@ -726,6 +735,7 @@ static const struct pci_device_id lpc_ich_ids[] = { | |||
726 | { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, | 735 | { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, |
727 | { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, | 736 | { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, |
728 | { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, | 737 | { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, |
738 | { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, | ||
729 | { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, | 739 | { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, |
730 | { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, | 740 | { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, |
731 | { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, | 741 | { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, |
@@ -742,14 +752,20 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev) | |||
742 | { | 752 | { |
743 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 753 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
744 | 754 | ||
745 | if (priv->acpi.save >= 0) { | 755 | if (priv->abase_save >= 0) { |
746 | pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save); | 756 | pci_write_config_byte(dev, priv->abase, priv->abase_save); |
747 | priv->acpi.save = -1; | 757 | priv->abase_save = -1; |
758 | } | ||
759 | |||
760 | if (priv->actrl_pbase_save >= 0) { | ||
761 | pci_write_config_byte(dev, priv->actrl_pbase, | ||
762 | priv->actrl_pbase_save); | ||
763 | priv->actrl_pbase_save = -1; | ||
748 | } | 764 | } |
749 | 765 | ||
750 | if (priv->gpio.save >= 0) { | 766 | if (priv->gctrl_save >= 0) { |
751 | pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save); | 767 | pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); |
752 | priv->gpio.save = -1; | 768 | priv->gctrl_save = -1; |
753 | } | 769 | } |
754 | } | 770 | } |
755 | 771 | ||
@@ -758,9 +774,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev) | |||
758 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 774 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
759 | u8 reg_save; | 775 | u8 reg_save; |
760 | 776 | ||
761 | pci_read_config_byte(dev, priv->acpi.ctrl, ®_save); | 777 | switch (lpc_chipset_info[priv->chipset].iTCO_version) { |
762 | pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10); | 778 | case 3: |
763 | priv->acpi.save = reg_save; | 779 | /* |
780 | * Some chipsets (eg Avoton) enable the ACPI space in the | ||
781 | * ACPI BASE register. | ||
782 | */ | ||
783 | pci_read_config_byte(dev, priv->abase, ®_save); | ||
784 | pci_write_config_byte(dev, priv->abase, reg_save | 0x2); | ||
785 | priv->abase_save = reg_save; | ||
786 | break; | ||
787 | default: | ||
788 | /* | ||
789 | * Most chipsets enable the ACPI space in the ACPI control | ||
790 | * register. | ||
791 | */ | ||
792 | pci_read_config_byte(dev, priv->actrl_pbase, ®_save); | ||
793 | pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); | ||
794 | priv->actrl_pbase_save = reg_save; | ||
795 | break; | ||
796 | } | ||
764 | } | 797 | } |
765 | 798 | ||
766 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) | 799 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) |
@@ -768,9 +801,20 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev) | |||
768 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 801 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
769 | u8 reg_save; | 802 | u8 reg_save; |
770 | 803 | ||
771 | pci_read_config_byte(dev, priv->gpio.ctrl, ®_save); | 804 | pci_read_config_byte(dev, priv->gctrl, ®_save); |
772 | pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10); | 805 | pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); |
773 | priv->gpio.save = reg_save; | 806 | priv->gctrl_save = reg_save; |
807 | } | ||
808 | |||
809 | static void lpc_ich_enable_pmc_space(struct pci_dev *dev) | ||
810 | { | ||
811 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
812 | u8 reg_save; | ||
813 | |||
814 | pci_read_config_byte(dev, priv->actrl_pbase, ®_save); | ||
815 | pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); | ||
816 | |||
817 | priv->actrl_pbase_save = reg_save; | ||
774 | } | 818 | } |
775 | 819 | ||
776 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) | 820 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) |
@@ -815,7 +859,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) | |||
815 | struct resource *res; | 859 | struct resource *res; |
816 | 860 | ||
817 | /* Setup power management base register */ | 861 | /* Setup power management base register */ |
818 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); | 862 | pci_read_config_dword(dev, priv->abase, &base_addr_cfg); |
819 | base_addr = base_addr_cfg & 0x0000ff80; | 863 | base_addr = base_addr_cfg & 0x0000ff80; |
820 | if (!base_addr) { | 864 | if (!base_addr) { |
821 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 865 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -841,7 +885,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) | |||
841 | 885 | ||
842 | gpe0_done: | 886 | gpe0_done: |
843 | /* Setup GPIO base register */ | 887 | /* Setup GPIO base register */ |
844 | pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg); | 888 | pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); |
845 | base_addr = base_addr_cfg & 0x0000ff80; | 889 | base_addr = base_addr_cfg & 0x0000ff80; |
846 | if (!base_addr) { | 890 | if (!base_addr) { |
847 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); | 891 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); |
@@ -891,7 +935,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
891 | struct resource *res; | 935 | struct resource *res; |
892 | 936 | ||
893 | /* Setup power management base register */ | 937 | /* Setup power management base register */ |
894 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); | 938 | pci_read_config_dword(dev, priv->abase, &base_addr_cfg); |
895 | base_addr = base_addr_cfg & 0x0000ff80; | 939 | base_addr = base_addr_cfg & 0x0000ff80; |
896 | if (!base_addr) { | 940 | if (!base_addr) { |
897 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 941 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -910,14 +954,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
910 | lpc_ich_enable_acpi_space(dev); | 954 | lpc_ich_enable_acpi_space(dev); |
911 | 955 | ||
912 | /* | 956 | /* |
957 | * iTCO v2: | ||
913 | * Get the Memory-Mapped GCS register. To get access to it | 958 | * Get the Memory-Mapped GCS register. To get access to it |
914 | * we have to read RCBA from PCI Config space 0xf0 and use | 959 | * we have to read RCBA from PCI Config space 0xf0 and use |
915 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). | 960 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). |
961 | * | ||
962 | * iTCO v3: | ||
963 | * Get the Power Management Configuration register. To get access | ||
964 | * to it we have to read the PMC BASE from config space and address | ||
965 | * the register at offset 0x8. | ||
916 | */ | 966 | */ |
917 | if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { | 967 | if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { |
918 | /* Don't register iomem for TCO ver 1 */ | 968 | /* Don't register iomem for TCO ver 1 */ |
919 | lpc_ich_cells[LPC_WDT].num_resources--; | 969 | lpc_ich_cells[LPC_WDT].num_resources--; |
920 | } else { | 970 | } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { |
921 | pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); | 971 | pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); |
922 | base_addr = base_addr_cfg & 0xffffc000; | 972 | base_addr = base_addr_cfg & 0xffffc000; |
923 | if (!(base_addr_cfg & 1)) { | 973 | if (!(base_addr_cfg & 1)) { |
@@ -926,9 +976,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
926 | ret = -ENODEV; | 976 | ret = -ENODEV; |
927 | goto wdt_done; | 977 | goto wdt_done; |
928 | } | 978 | } |
929 | res = wdt_mem_res(ICH_RES_MEM_GCS); | 979 | res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); |
930 | res->start = base_addr + ACPIBASE_GCS_OFF; | 980 | res->start = base_addr + ACPIBASE_GCS_OFF; |
931 | res->end = base_addr + ACPIBASE_GCS_END; | 981 | res->end = base_addr + ACPIBASE_GCS_END; |
982 | } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { | ||
983 | lpc_ich_enable_pmc_space(dev); | ||
984 | pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); | ||
985 | base_addr = base_addr_cfg & 0xfffffe00; | ||
986 | |||
987 | res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); | ||
988 | res->start = base_addr + ACPIBASE_PMC_OFF; | ||
989 | res->end = base_addr + ACPIBASE_PMC_END; | ||
932 | } | 990 | } |
933 | 991 | ||
934 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); | 992 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); |
@@ -952,28 +1010,35 @@ static int lpc_ich_probe(struct pci_dev *dev, | |||
952 | return -ENOMEM; | 1010 | return -ENOMEM; |
953 | 1011 | ||
954 | priv->chipset = id->driver_data; | 1012 | priv->chipset = id->driver_data; |
955 | priv->acpi.save = -1; | ||
956 | priv->acpi.base = ACPIBASE; | ||
957 | priv->acpi.ctrl = ACPICTRL; | ||
958 | 1013 | ||
959 | priv->gpio.save = -1; | 1014 | priv->actrl_pbase_save = -1; |
1015 | priv->abase_save = -1; | ||
1016 | |||
1017 | priv->abase = ACPIBASE; | ||
1018 | priv->actrl_pbase = ACPICTRL_PMCBASE; | ||
1019 | |||
1020 | priv->gctrl_save = -1; | ||
960 | if (priv->chipset <= LPC_ICH5) { | 1021 | if (priv->chipset <= LPC_ICH5) { |
961 | priv->gpio.base = GPIOBASE_ICH0; | 1022 | priv->gbase = GPIOBASE_ICH0; |
962 | priv->gpio.ctrl = GPIOCTRL_ICH0; | 1023 | priv->gctrl = GPIOCTRL_ICH0; |
963 | } else { | 1024 | } else { |
964 | priv->gpio.base = GPIOBASE_ICH6; | 1025 | priv->gbase = GPIOBASE_ICH6; |
965 | priv->gpio.ctrl = GPIOCTRL_ICH6; | 1026 | priv->gctrl = GPIOCTRL_ICH6; |
966 | } | 1027 | } |
967 | 1028 | ||
968 | pci_set_drvdata(dev, priv); | 1029 | pci_set_drvdata(dev, priv); |
969 | 1030 | ||
970 | ret = lpc_ich_init_wdt(dev); | 1031 | if (lpc_chipset_info[priv->chipset].iTCO_version) { |
971 | if (!ret) | 1032 | ret = lpc_ich_init_wdt(dev); |
972 | cell_added = true; | 1033 | if (!ret) |
1034 | cell_added = true; | ||
1035 | } | ||
973 | 1036 | ||
974 | ret = lpc_ich_init_gpio(dev); | 1037 | if (lpc_chipset_info[priv->chipset].gpio_version) { |
975 | if (!ret) | 1038 | ret = lpc_ich_init_gpio(dev); |
976 | cell_added = true; | 1039 | if (!ret) |
1040 | cell_added = true; | ||
1041 | } | ||
977 | 1042 | ||
978 | /* | 1043 | /* |
979 | * We only care if at least one or none of the cells registered | 1044 | * We only care if at least one or none of the cells registered |