.. | .. |
---|
| 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"); |
---|