aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/lpc_ich.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/lpc_ich.c')
-rw-r--r--drivers/mfd/lpc_ich.c109
1 files changed, 76 insertions, 33 deletions
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index d9d930302e98..a0cfdf980748 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -75,8 +75,10 @@
75#define ACPIBASE_GCS_OFF 0x3410 75#define ACPIBASE_GCS_OFF 0x3410
76#define ACPIBASE_GCS_END 0x3414 76#define ACPIBASE_GCS_END 0x3414
77 77
78#define GPIOBASE 0x48 78#define GPIOBASE_ICH0 0x58
79#define GPIOCTRL 0x4C 79#define GPIOCTRL_ICH0 0x5C
80#define GPIOBASE_ICH6 0x48
81#define GPIOCTRL_ICH6 0x4C
80 82
81#define RCBABASE 0xf0 83#define RCBABASE 0xf0
82 84
@@ -84,8 +86,17 @@
84#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) 86#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
85#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) 87#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
86 88
87static int lpc_ich_acpi_save = -1; 89struct lpc_ich_cfg {
88static int lpc_ich_gpio_save = -1; 90 int base;
91 int ctrl;
92 int save;
93};
94
95struct lpc_ich_priv {
96 int chipset;
97 struct lpc_ich_cfg acpi;
98 struct lpc_ich_cfg gpio;
99};
89 100
90static struct resource wdt_ich_res[] = { 101static struct resource wdt_ich_res[] = {
91 /* ACPI - TCO */ 102 /* ACPI - TCO */
@@ -661,39 +672,44 @@ MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
661 672
662static void lpc_ich_restore_config_space(struct pci_dev *dev) 673static void lpc_ich_restore_config_space(struct pci_dev *dev)
663{ 674{
664 if (lpc_ich_acpi_save >= 0) { 675 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
665 pci_write_config_byte(dev, ACPICTRL, lpc_ich_acpi_save); 676
666 lpc_ich_acpi_save = -1; 677 if (priv->acpi.save >= 0) {
678 pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save);
679 priv->acpi.save = -1;
667 } 680 }
668 681
669 if (lpc_ich_gpio_save >= 0) { 682 if (priv->gpio.save >= 0) {
670 pci_write_config_byte(dev, GPIOCTRL, lpc_ich_gpio_save); 683 pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save);
671 lpc_ich_gpio_save = -1; 684 priv->gpio.save = -1;
672 } 685 }
673} 686}
674 687
675static void lpc_ich_enable_acpi_space(struct pci_dev *dev) 688static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
676{ 689{
690 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
677 u8 reg_save; 691 u8 reg_save;
678 692
679 pci_read_config_byte(dev, ACPICTRL, &reg_save); 693 pci_read_config_byte(dev, priv->acpi.ctrl, &reg_save);
680 pci_write_config_byte(dev, ACPICTRL, reg_save | 0x10); 694 pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10);
681 lpc_ich_acpi_save = reg_save; 695 priv->acpi.save = reg_save;
682} 696}
683 697
684static void lpc_ich_enable_gpio_space(struct pci_dev *dev) 698static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
685{ 699{
700 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
686 u8 reg_save; 701 u8 reg_save;
687 702
688 pci_read_config_byte(dev, GPIOCTRL, &reg_save); 703 pci_read_config_byte(dev, priv->gpio.ctrl, &reg_save);
689 pci_write_config_byte(dev, GPIOCTRL, reg_save | 0x10); 704 pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10);
690 lpc_ich_gpio_save = reg_save; 705 priv->gpio.save = reg_save;
691} 706}
692 707
693static void lpc_ich_finalize_cell(struct mfd_cell *cell, 708static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
694 const struct pci_device_id *id)
695{ 709{
696 cell->platform_data = &lpc_chipset_info[id->driver_data]; 710 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
711
712 cell->platform_data = &lpc_chipset_info[priv->chipset];
697 cell->pdata_size = sizeof(struct lpc_ich_info); 713 cell->pdata_size = sizeof(struct lpc_ich_info);
698} 714}
699 715
@@ -721,9 +737,9 @@ static int lpc_ich_check_conflict_gpio(struct resource *res)
721 return use_gpio ? use_gpio : ret; 737 return use_gpio ? use_gpio : ret;
722} 738}
723 739
724static int lpc_ich_init_gpio(struct pci_dev *dev, 740static int lpc_ich_init_gpio(struct pci_dev *dev)
725 const struct pci_device_id *id)
726{ 741{
742 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
727 u32 base_addr_cfg; 743 u32 base_addr_cfg;
728 u32 base_addr; 744 u32 base_addr;
729 int ret; 745 int ret;
@@ -731,7 +747,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev,
731 struct resource *res; 747 struct resource *res;
732 748
733 /* Setup power management base register */ 749 /* Setup power management base register */
734 pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); 750 pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
735 base_addr = base_addr_cfg & 0x0000ff80; 751 base_addr = base_addr_cfg & 0x0000ff80;
736 if (!base_addr) { 752 if (!base_addr) {
737 dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); 753 dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -757,7 +773,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev,
757 773
758gpe0_done: 774gpe0_done:
759 /* Setup GPIO base register */ 775 /* Setup GPIO base register */
760 pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); 776 pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg);
761 base_addr = base_addr_cfg & 0x0000ff80; 777 base_addr = base_addr_cfg & 0x0000ff80;
762 if (!base_addr) { 778 if (!base_addr) {
763 dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); 779 dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
@@ -768,7 +784,7 @@ gpe0_done:
768 /* Older devices provide fewer GPIO and have a smaller resource size. */ 784 /* Older devices provide fewer GPIO and have a smaller resource size. */
769 res = &gpio_ich_res[ICH_RES_GPIO]; 785 res = &gpio_ich_res[ICH_RES_GPIO];
770 res->start = base_addr; 786 res->start = base_addr;
771 switch (lpc_chipset_info[id->driver_data].gpio_version) { 787 switch (lpc_chipset_info[priv->chipset].gpio_version) {
772 case ICH_V5_GPIO: 788 case ICH_V5_GPIO:
773 case ICH_V10CORP_GPIO: 789 case ICH_V10CORP_GPIO:
774 res->end = res->start + 128 - 1; 790 res->end = res->start + 128 - 1;
@@ -784,10 +800,10 @@ gpe0_done:
784 acpi_conflict = true; 800 acpi_conflict = true;
785 goto gpio_done; 801 goto gpio_done;
786 } 802 }
787 lpc_chipset_info[id->driver_data].use_gpio = ret; 803 lpc_chipset_info[priv->chipset].use_gpio = ret;
788 lpc_ich_enable_gpio_space(dev); 804 lpc_ich_enable_gpio_space(dev);
789 805
790 lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); 806 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]);
791 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], 807 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO],
792 1, NULL, 0, NULL); 808 1, NULL, 0, NULL);
793 809
@@ -798,16 +814,16 @@ gpio_done:
798 return ret; 814 return ret;
799} 815}
800 816
801static int lpc_ich_init_wdt(struct pci_dev *dev, 817static int lpc_ich_init_wdt(struct pci_dev *dev)
802 const struct pci_device_id *id)
803{ 818{
819 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
804 u32 base_addr_cfg; 820 u32 base_addr_cfg;
805 u32 base_addr; 821 u32 base_addr;
806 int ret; 822 int ret;
807 struct resource *res; 823 struct resource *res;
808 824
809 /* Setup power management base register */ 825 /* Setup power management base register */
810 pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); 826 pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
811 base_addr = base_addr_cfg & 0x0000ff80; 827 base_addr = base_addr_cfg & 0x0000ff80;
812 if (!base_addr) { 828 if (!base_addr) {
813 dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); 829 dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -830,7 +846,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev,
830 * we have to read RCBA from PCI Config space 0xf0 and use 846 * we have to read RCBA from PCI Config space 0xf0 and use
831 * it as base. GCS = RCBA + ICH6_GCS(0x3410). 847 * it as base. GCS = RCBA + ICH6_GCS(0x3410).
832 */ 848 */
833 if (lpc_chipset_info[id->driver_data].iTCO_version == 1) { 849 if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
834 /* Don't register iomem for TCO ver 1 */ 850 /* Don't register iomem for TCO ver 1 */
835 lpc_ich_cells[LPC_WDT].num_resources--; 851 lpc_ich_cells[LPC_WDT].num_resources--;
836 } else { 852 } else {
@@ -847,7 +863,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev,
847 res->end = base_addr + ACPIBASE_GCS_END; 863 res->end = base_addr + ACPIBASE_GCS_END;
848 } 864 }
849 865
850 lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); 866 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
851 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], 867 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT],
852 1, NULL, 0, NULL); 868 1, NULL, 0, NULL);
853 869
@@ -858,14 +874,35 @@ wdt_done:
858static int lpc_ich_probe(struct pci_dev *dev, 874static int lpc_ich_probe(struct pci_dev *dev,
859 const struct pci_device_id *id) 875 const struct pci_device_id *id)
860{ 876{
877 struct lpc_ich_priv *priv;
861 int ret; 878 int ret;
862 bool cell_added = false; 879 bool cell_added = false;
863 880
864 ret = lpc_ich_init_wdt(dev, id); 881 priv = kmalloc(GFP_KERNEL, sizeof(struct lpc_ich_priv));
882 if (!priv)
883 return -ENOMEM;
884
885 priv->chipset = id->driver_data;
886 priv->acpi.save = -1;
887 priv->acpi.base = ACPIBASE;
888 priv->acpi.ctrl = ACPICTRL;
889
890 priv->gpio.save = -1;
891 if (priv->chipset <= LPC_ICH5) {
892 priv->gpio.base = GPIOBASE_ICH0;
893 priv->gpio.ctrl = GPIOCTRL_ICH0;
894 } else {
895 priv->gpio.base = GPIOBASE_ICH6;
896 priv->gpio.ctrl = GPIOCTRL_ICH6;
897 }
898
899 pci_set_drvdata(dev, priv);
900
901 ret = lpc_ich_init_wdt(dev);
865 if (!ret) 902 if (!ret)
866 cell_added = true; 903 cell_added = true;
867 904
868 ret = lpc_ich_init_gpio(dev, id); 905 ret = lpc_ich_init_gpio(dev);
869 if (!ret) 906 if (!ret)
870 cell_added = true; 907 cell_added = true;
871 908
@@ -876,6 +913,8 @@ static int lpc_ich_probe(struct pci_dev *dev,
876 if (!cell_added) { 913 if (!cell_added) {
877 dev_warn(&dev->dev, "No MFD cells added\n"); 914 dev_warn(&dev->dev, "No MFD cells added\n");
878 lpc_ich_restore_config_space(dev); 915 lpc_ich_restore_config_space(dev);
916 pci_set_drvdata(dev, NULL);
917 kfree(priv);
879 return -ENODEV; 918 return -ENODEV;
880 } 919 }
881 920
@@ -884,8 +923,12 @@ static int lpc_ich_probe(struct pci_dev *dev,
884 923
885static void lpc_ich_remove(struct pci_dev *dev) 924static void lpc_ich_remove(struct pci_dev *dev)
886{ 925{
926 void *priv = pci_get_drvdata(dev);
927
887 mfd_remove_devices(&dev->dev); 928 mfd_remove_devices(&dev->dev);
888 lpc_ich_restore_config_space(dev); 929 lpc_ich_restore_config_space(dev);
930 pci_set_drvdata(dev, NULL);
931 kfree(priv);
889} 932}
890 933
891static struct pci_driver lpc_ich_driver = { 934static struct pci_driver lpc_ich_driver = {