aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/lpc_ich.c
diff options
context:
space:
mode:
authorAaron Sierra <asierra@xes-inc.com>2013-01-24 15:52:39 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2013-02-13 18:22:52 -0500
commit01560f6bb958b821ceec98590a7147d610a62625 (patch)
tree56a8aedbbe9d8f266e4d8a8405aa3dee79c36f3e /drivers/mfd/lpc_ich.c
parentfbc6ae363e5e589a28135c051a2ff835e6236d5f (diff)
mfd: lpc_ich: Fix gpio base and control offsets
In ICH5 and earlier the GPIOBASE and GPIOCTRL registers are found at offsets 0x58 and 0x5C, respectively. This patch allows GPIO access to properly be enabled (and disabled) for these chipsets. Signed-off-by: Agócs Pál <agocs.pal.86@gmail.com> Signed-off-by: Aaron Sierra <asierra@xes-inc.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
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 = {