| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and |
|---|
| 3 | 4 | Philip Edelbrock <phil@netroedge.com> |
|---|
| 4 | 5 | |
|---|
| 5 | | - This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | | - (at your option) any later version. |
|---|
| 9 | | - |
|---|
| 10 | | - This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - GNU General Public License for more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | /* |
|---|
| .. | .. |
|---|
| 19 | 11 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 |
|---|
| 20 | 12 | ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 |
|---|
| 21 | 13 | AMD Hudson-2, ML, CZ |
|---|
| 14 | + Hygon CZ |
|---|
| 22 | 15 | SMSC Victory66 |
|---|
| 23 | 16 | |
|---|
| 24 | 17 | Note: we assume there can only be one device, with one or more |
|---|
| .. | .. |
|---|
| 79 | 72 | #define PIIX4_BLOCK_DATA 0x14 |
|---|
| 80 | 73 | |
|---|
| 81 | 74 | /* Multi-port constants */ |
|---|
| 82 | | -#define PIIX4_MAX_ADAPTERS 4 |
|---|
| 75 | +#define PIIX4_MAX_ADAPTERS 4 |
|---|
| 76 | +#define HUDSON2_MAIN_PORTS 2 /* HUDSON2, KERNCZ reserves ports 3, 4 */ |
|---|
| 83 | 77 | |
|---|
| 84 | 78 | /* SB800 constants */ |
|---|
| 85 | 79 | #define SB800_PIIX4_SMB_IDX 0xcd6 |
|---|
| .. | .. |
|---|
| 289 | 283 | PIIX4_dev->revision >= 0x41) || |
|---|
| 290 | 284 | (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && |
|---|
| 291 | 285 | PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && |
|---|
| 292 | | - PIIX4_dev->revision >= 0x49)) |
|---|
| 286 | + PIIX4_dev->revision >= 0x49) || |
|---|
| 287 | + (PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON && |
|---|
| 288 | + PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) |
|---|
| 293 | 289 | smb_en = 0x00; |
|---|
| 294 | 290 | else |
|---|
| 295 | 291 | smb_en = (aux) ? 0x28 : 0x2c; |
|---|
| .. | .. |
|---|
| 361 | 357 | piix4_smba, i2ccfg >> 4); |
|---|
| 362 | 358 | |
|---|
| 363 | 359 | /* Find which register is used for port selection */ |
|---|
| 364 | | - if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) { |
|---|
| 360 | + if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD || |
|---|
| 361 | + PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) { |
|---|
| 365 | 362 | if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || |
|---|
| 366 | 363 | (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && |
|---|
| 367 | 364 | PIIX4_dev->revision >= 0x1F)) { |
|---|
| .. | .. |
|---|
| 792 | 789 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) }, |
|---|
| 793 | 790 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) }, |
|---|
| 794 | 791 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) }, |
|---|
| 792 | + { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) }, |
|---|
| 795 | 793 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
|---|
| 796 | 794 | PCI_DEVICE_ID_SERVERWORKS_OSB4) }, |
|---|
| 797 | 795 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
|---|
| .. | .. |
|---|
| 809 | 807 | |
|---|
| 810 | 808 | static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; |
|---|
| 811 | 809 | static struct i2c_adapter *piix4_aux_adapter; |
|---|
| 810 | +static int piix4_adapter_count; |
|---|
| 812 | 811 | |
|---|
| 813 | 812 | static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, |
|---|
| 814 | 813 | bool sb800_main, u8 port, bool notify_imc, |
|---|
| 815 | | - const char *name, struct i2c_adapter **padap) |
|---|
| 814 | + u8 hw_port_nr, const char *name, |
|---|
| 815 | + struct i2c_adapter **padap) |
|---|
| 816 | 816 | { |
|---|
| 817 | 817 | struct i2c_adapter *adap; |
|---|
| 818 | 818 | struct i2c_piix4_adapdata *adapdata; |
|---|
| .. | .. |
|---|
| 844 | 844 | /* set up the sysfs linkage to our parent device */ |
|---|
| 845 | 845 | adap->dev.parent = &dev->dev; |
|---|
| 846 | 846 | |
|---|
| 847 | + if (has_acpi_companion(&dev->dev)) { |
|---|
| 848 | + acpi_preset_companion(&adap->dev, |
|---|
| 849 | + ACPI_COMPANION(&dev->dev), |
|---|
| 850 | + hw_port_nr); |
|---|
| 851 | + } |
|---|
| 852 | + |
|---|
| 847 | 853 | snprintf(adap->name, sizeof(adap->name), |
|---|
| 848 | 854 | "SMBus PIIX4 adapter%s at %04x", name, smba); |
|---|
| 849 | 855 | |
|---|
| .. | .. |
|---|
| 868 | 874 | int port; |
|---|
| 869 | 875 | int retval; |
|---|
| 870 | 876 | |
|---|
| 871 | | - for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { |
|---|
| 877 | + if (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || |
|---|
| 878 | + (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && |
|---|
| 879 | + dev->revision >= 0x1F)) { |
|---|
| 880 | + piix4_adapter_count = HUDSON2_MAIN_PORTS; |
|---|
| 881 | + } else { |
|---|
| 882 | + piix4_adapter_count = PIIX4_MAX_ADAPTERS; |
|---|
| 883 | + } |
|---|
| 884 | + |
|---|
| 885 | + for (port = 0; port < piix4_adapter_count; port++) { |
|---|
| 886 | + u8 hw_port_nr = port == 0 ? 0 : port + 1; |
|---|
| 887 | + |
|---|
| 872 | 888 | retval = piix4_add_adapter(dev, smba, true, port, notify_imc, |
|---|
| 889 | + hw_port_nr, |
|---|
| 873 | 890 | piix4_main_port_names_sb800[port], |
|---|
| 874 | 891 | &piix4_main_adapters[port]); |
|---|
| 875 | 892 | if (retval < 0) |
|---|
| .. | .. |
|---|
| 902 | 919 | if ((dev->vendor == PCI_VENDOR_ID_ATI && |
|---|
| 903 | 920 | dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && |
|---|
| 904 | 921 | dev->revision >= 0x40) || |
|---|
| 905 | | - dev->vendor == PCI_VENDOR_ID_AMD) { |
|---|
| 922 | + dev->vendor == PCI_VENDOR_ID_AMD || |
|---|
| 923 | + dev->vendor == PCI_VENDOR_ID_HYGON) { |
|---|
| 906 | 924 | bool notify_imc = false; |
|---|
| 907 | 925 | is_sb800 = true; |
|---|
| 908 | 926 | |
|---|
| 909 | | - if (dev->vendor == PCI_VENDOR_ID_AMD && |
|---|
| 927 | + if ((dev->vendor == PCI_VENDOR_ID_AMD || |
|---|
| 928 | + dev->vendor == PCI_VENDOR_ID_HYGON) && |
|---|
| 910 | 929 | dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) { |
|---|
| 911 | 930 | u8 imc; |
|---|
| 912 | 931 | |
|---|
| .. | .. |
|---|
| 938 | 957 | return retval; |
|---|
| 939 | 958 | |
|---|
| 940 | 959 | /* Try to register main SMBus adapter, give up if we can't */ |
|---|
| 941 | | - retval = piix4_add_adapter(dev, retval, false, 0, false, "", |
|---|
| 942 | | - &piix4_main_adapters[0]); |
|---|
| 960 | + retval = piix4_add_adapter(dev, retval, false, 0, false, 0, |
|---|
| 961 | + "", &piix4_main_adapters[0]); |
|---|
| 943 | 962 | if (retval < 0) |
|---|
| 944 | 963 | return retval; |
|---|
| 964 | + piix4_adapter_count = 1; |
|---|
| 945 | 965 | } |
|---|
| 946 | 966 | |
|---|
| 947 | 967 | /* Check for auxiliary SMBus on some AMD chipsets */ |
|---|
| .. | .. |
|---|
| 966 | 986 | if (retval > 0) { |
|---|
| 967 | 987 | /* Try to add the aux adapter if it exists, |
|---|
| 968 | 988 | * piix4_add_adapter will clean up if this fails */ |
|---|
| 969 | | - piix4_add_adapter(dev, retval, false, 0, false, |
|---|
| 989 | + piix4_add_adapter(dev, retval, false, 0, false, 1, |
|---|
| 970 | 990 | is_sb800 ? piix4_aux_port_name_sb800 : "", |
|---|
| 971 | 991 | &piix4_aux_adapter); |
|---|
| 972 | 992 | } |
|---|
| .. | .. |
|---|
| 989 | 1009 | |
|---|
| 990 | 1010 | static void piix4_remove(struct pci_dev *dev) |
|---|
| 991 | 1011 | { |
|---|
| 992 | | - int port = PIIX4_MAX_ADAPTERS; |
|---|
| 1012 | + int port = piix4_adapter_count; |
|---|
| 993 | 1013 | |
|---|
| 994 | 1014 | while (--port >= 0) { |
|---|
| 995 | 1015 | if (piix4_main_adapters[port]) { |
|---|
| .. | .. |
|---|
| 1013 | 1033 | |
|---|
| 1014 | 1034 | module_pci_driver(piix4_driver); |
|---|
| 1015 | 1035 | |
|---|
| 1016 | | -MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " |
|---|
| 1017 | | - "Philip Edelbrock <phil@netroedge.com>"); |
|---|
| 1036 | +MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); |
|---|
| 1037 | +MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>"); |
|---|
| 1018 | 1038 | MODULE_DESCRIPTION("PIIX4 SMBus driver"); |
|---|
| 1019 | 1039 | MODULE_LICENSE("GPL"); |
|---|