Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)     Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)     Philip Edelbrock <phil@netroedge.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)    Supports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 	Intel PIIX4, 440MX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 	AMD Hudson-2, ML, CZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 	Hygon CZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 	SMSC Victory66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)    Note: we assume there can only be one device, with one or more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)    SMBus interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)    The device can register multiple i2c_adapters (up to PIIX4_MAX_ADAPTERS).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)    For devices supporting multiple ports the i2c_adapter should provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)    an i2c_algorithm to access them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) /* PIIX4 SMBus address offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define SMBHSTSTS	(0 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define SMBHSLVSTS	(1 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define SMBHSTCNT	(2 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define SMBHSTCMD	(3 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define SMBHSTADD	(4 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define SMBHSTDAT0	(5 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define SMBHSTDAT1	(6 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define SMBBLKDAT	(7 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define SMBSLVCNT	(8 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define SMBSHDWCMD	(9 + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define SMBSLVEVT	(0xA + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define SMBSLVDAT	(0xC + piix4_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) /* count for request_region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define SMBIOSIZE	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /* PCI Address Constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define SMBBA		0x090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define SMBHSTCFG	0x0D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define SMBSLVC		0x0D3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define SMBSHDW1	0x0D4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define SMBSHDW2	0x0D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define SMBREV		0x0D6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /* Other settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define MAX_TIMEOUT	500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define  ENABLE_INT9	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) /* PIIX4 constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define PIIX4_QUICK		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define PIIX4_BYTE		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define PIIX4_BYTE_DATA		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define PIIX4_WORD_DATA		0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define PIIX4_BLOCK_DATA	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) /* Multi-port constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define PIIX4_MAX_ADAPTERS	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define HUDSON2_MAIN_PORTS	2 /* HUDSON2, KERNCZ reserves ports 3, 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) /* SB800 constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define SB800_PIIX4_SMB_IDX		0xcd6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define KERNCZ_IMC_IDX			0x3e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define KERNCZ_IMC_DATA			0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * SB800 port is selected by bits 2:1 of the smb_en register (0x2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * or the smb_sel register (0x2e), depending on bit 0 of register 0x2f.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  * Hudson-2/Bolton port is always selected by bits 2:1 of register 0x2f.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define SB800_PIIX4_PORT_IDX		0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define SB800_PIIX4_PORT_IDX_ALT	0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define SB800_PIIX4_PORT_IDX_SEL	0x2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define SB800_PIIX4_PORT_IDX_MASK	0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define SB800_PIIX4_PORT_IDX_SHIFT	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) /* On kerncz and Hudson2, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define SB800_PIIX4_PORT_IDX_KERNCZ		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define SB800_PIIX4_PORT_IDX_MASK_KERNCZ	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) /* insmod parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /* If force is set to anything different from 0, we forcibly enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)    PIIX4. DANGEROUS! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) static int force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) module_param (force, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) /* If force_addr is set to anything different from 0, we forcibly enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)    the PIIX4 at the given address. VERY DANGEROUS! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) static int force_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) module_param_hw(force_addr, int, ioport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) MODULE_PARM_DESC(force_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		 "Forcibly enable the PIIX4 at the given address. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		 "EXTREMELY DANGEROUS!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static int srvrworks_csb5_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) static struct pci_driver piix4_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) static const struct dmi_system_id piix4_dmi_blacklist[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		.ident = "Sapphire AM2RD790",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 			DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		.ident = "DFI Lanparty UT 790FX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 			DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) /* The IBM entry is in a separate table because we only check it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)    on Intel-based systems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static const struct dmi_system_id piix4_dmi_ibm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		.ident = "IBM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  * SB800 globals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static u8 piix4_port_sel_sb800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static u8 piix4_port_mask_sb800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) static u8 piix4_port_shift_sb800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	" port 0", " port 2", " port 3", " port 4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static const char *piix4_aux_port_name_sb800 = " port 1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) struct i2c_piix4_adapdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	unsigned short smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	/* SB800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	bool sb800_main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	bool notify_imc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	u8 port;		/* Port number, shifted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) static int piix4_setup(struct pci_dev *PIIX4_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		       const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	unsigned char temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	unsigned short piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	    (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		srvrworks_csb5_delay = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	/* On some motherboards, it was reported that accessing the SMBus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	   caused severe hardware problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	if (dmi_check_system(piix4_dmi_blacklist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		dev_err(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 			"Accessing the SMBus on this system is unsafe!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	/* Don't access SMBus on IBM systems which get corrupted eeproms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	if (dmi_check_system(piix4_dmi_ibm) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			"may corrupt your serial eeprom! Refusing to load "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			"module!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	/* Determine the address of the SMBus areas */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	if (force_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		piix4_smba = force_addr & 0xfff0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		force = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		piix4_smba &= 0xfff0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		if(piix4_smba == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 			dev_err(&PIIX4_dev->dev, "SMBus base address "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 				"uninitialized - upgrade BIOS or use "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 				"force_addr=0xaddr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	/* If force_addr is set, we program the new address here. Just to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	   sure, we disable the PIIX4 first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (force_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 			"new address %04x!\n", piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	} else if ((temp & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		if (force) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 			/* This should never need to be done, but has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 			 * noted that many Dell machines have the SMBus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 			 * interface on the PIIX4 disabled!? NOTE: This assumes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			 * I/O space and other allocations WERE done by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 			 * Bios!  Don't complain if your hardware does weird
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			 * things after enabling this. :') Check for Bios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 			 * updates before resorting to this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			pci_write_config_byte(PIIX4_dev, SMBHSTCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 					      temp | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			dev_notice(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 				   "WARNING: SMBus interface has been FORCEFULLY ENABLED!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			dev_err(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 				"SMBus Host Controller not enabled!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			release_region(piix4_smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	else if ((temp & 0x0E) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 			"(or code out of date)!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	dev_info(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		 "SMBus Host Controller at 0x%x, revision %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		 piix4_smba, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	return piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			     const struct pci_device_id *id, u8 aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	unsigned short piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status, port_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	u8 i2ccfg, i2ccfg_offset = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	/* SB800 and later SMBus does not support forcing address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (force || force_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		dev_err(&PIIX4_dev->dev, "SMBus does not support "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			"forcing address!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	/* Determine the address of the SMBus areas */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	     PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	     PIIX4_dev->revision >= 0x41) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	    (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	     PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	     PIIX4_dev->revision >= 0x49) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	    (PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	     PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		smb_en = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		smb_en = (aux) ? 0x28 : 0x2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		dev_err(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 			"SMB base address index region 0x%x already in use.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			SB800_PIIX4_SMB_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	outb_p(smb_en, SB800_PIIX4_SMB_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	release_region(SB800_PIIX4_SMB_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if (!smb_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		smb_en_status = smba_en_lo & 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		piix4_smba = smba_en_hi << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		if (aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			piix4_smba |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		smb_en_status = smba_en_lo & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (!smb_en_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		dev_err(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			"SMBus Host Controller not enabled!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	/* Aux SMBus does not support IRQ information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	if (aux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		dev_info(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			 "Auxiliary SMBus Host Controller at 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 			 piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		return piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	/* Request the SMBus I2C bus config region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			"0x%x already in use!\n", piix4_smba + i2ccfg_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		release_region(piix4_smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	release_region(piix4_smba + i2ccfg_offset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (i2ccfg & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	dev_info(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		 "SMBus Host Controller at 0x%x, revision %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		 piix4_smba, i2ccfg >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	/* Find which register is used for port selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	    PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		    (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		     PIIX4_dev->revision >= 0x1F)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 					  "sb800_piix4_smb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 			release_region(piix4_smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		port_sel = inb_p(SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		piix4_port_sel_sb800 = (port_sel & 0x01) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 				       SB800_PIIX4_PORT_IDX_ALT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 				       SB800_PIIX4_PORT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		release_region(SB800_PIIX4_SMB_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	dev_info(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		 "Using register 0x%02x for SMBus port selection\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		 (unsigned int)piix4_port_sel_sb800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int piix4_setup_aux(struct pci_dev *PIIX4_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			   const struct pci_device_id *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			   unsigned short base_reg_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	/* Set up auxiliary SMBus controllers found on some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	 * AMD chipsets e.g. SP5100 (SB700 derivative) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	unsigned short piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	/* Read address of auxiliary SMBus controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if ((piix4_smba & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		dev_dbg(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			"Auxiliary SMBus controller not enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	piix4_smba &= 0xfff0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	if (piix4_smba == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		dev_dbg(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			"Auxiliary SMBus base address uninitialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			"already in use!\n", piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	dev_info(&PIIX4_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		 "Auxiliary SMBus Host Controller at 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		 piix4_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	return piix4_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) static int piix4_transaction(struct i2c_adapter *piix4_adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	unsigned short piix4_smba = adapdata->smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	int timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	dev_dbg(&piix4_adapter->dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		inb_p(SMBHSTDAT1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	/* Make sure the SMBus host is ready to start transmitting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		dev_dbg(&piix4_adapter->dev, "SMBus busy (%02x). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			"Resetting...\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		outb_p(temp, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			dev_err(&piix4_adapter->dev, "Failed! (%02x)\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			dev_dbg(&piix4_adapter->dev, "Successful!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	/* start the transaction by setting bit 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		usleep_range(2000, 2100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		usleep_range(250, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	while ((++timeout < MAX_TIMEOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	       ((temp = inb_p(SMBHSTSTS)) & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		usleep_range(250, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	/* If the SMBus is still busy, we give up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	if (timeout == MAX_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		dev_err(&piix4_adapter->dev, "SMBus Timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	if (temp & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		dev_err(&piix4_adapter->dev, "Error: Failed bus transaction\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	if (temp & 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			"locked until next hard reset. (sorry!)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		/* Clock stops and slave is stuck in mid-transmission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	if (temp & 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		result = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		dev_dbg(&piix4_adapter->dev, "Error: no response!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	if (inb_p(SMBHSTSTS) != 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		outb_p(inb(SMBHSTSTS), SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		dev_err(&piix4_adapter->dev, "Failed reset at end of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			"transaction (%02x)\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	dev_dbg(&piix4_adapter->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		inb_p(SMBHSTDAT1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) /* Return negative errno on error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		 unsigned short flags, char read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		 u8 command, int size, union i2c_smbus_data * data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	unsigned short piix4_smba = adapdata->smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	case I2C_SMBUS_QUICK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		outb_p((addr << 1) | read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		size = PIIX4_QUICK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		outb_p((addr << 1) | read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 			outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		size = PIIX4_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		outb_p((addr << 1) | read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			outb_p(data->byte, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		size = PIIX4_BYTE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		outb_p((addr << 1) | read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		if (read_write == I2C_SMBUS_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			outb_p(data->word & 0xff, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		size = PIIX4_WORD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	case I2C_SMBUS_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		outb_p((addr << 1) | read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (read_write == I2C_SMBUS_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			len = data->block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			outb_p(len, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 			for (i = 1; i <= len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 				outb_p(data->block[i], SMBBLKDAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		size = PIIX4_BLOCK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	status = piix4_transaction(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	case PIIX4_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	case PIIX4_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		data->byte = inb_p(SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	case PIIX4_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	case PIIX4_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		data->block[0] = inb_p(SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		for (i = 1; i <= data->block[0]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			data->block[i] = inb_p(SMBBLKDAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) static uint8_t piix4_imc_read(uint8_t idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	outb_p(idx, KERNCZ_IMC_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	return inb_p(KERNCZ_IMC_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) static void piix4_imc_write(uint8_t idx, uint8_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	outb_p(idx, KERNCZ_IMC_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	outb_p(value, KERNCZ_IMC_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) static int piix4_imc_sleep(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	int timeout = MAX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	/* clear response register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	piix4_imc_write(0x82, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	/* request ownership flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	piix4_imc_write(0x83, 0xB4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	/* kick off IMC Mailbox command 96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	piix4_imc_write(0x80, 0x96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	while (timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		if (piix4_imc_read(0x82) == 0xfa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			release_region(KERNCZ_IMC_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	release_region(KERNCZ_IMC_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) static void piix4_imc_wakeup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	int timeout = MAX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	/* clear response register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	piix4_imc_write(0x82, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	/* release ownership flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	piix4_imc_write(0x83, 0xB5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	/* kick off IMC Mailbox command 96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	piix4_imc_write(0x80, 0x96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	while (timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		if (piix4_imc_read(0x82) == 0xfa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	release_region(KERNCZ_IMC_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  * Handles access to multiple SMBus ports on the SB800.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  * The port is selected by bits 2:1 of the smb_en register (0x2c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)  * Returns negative errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  * Note: The selected port must be returned to the initial selection to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)  * problems on certain systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		 unsigned short flags, char read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		 u8 command, int size, union i2c_smbus_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	unsigned short piix4_smba = adapdata->smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	int retries = MAX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	int smbslvcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	u8 smba_en_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	u8 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	/* Request the SMBUS semaphore, avoid conflicts with the IMC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	smbslvcnt  = inb_p(SMBSLVCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		outb_p(smbslvcnt | 0x10, SMBSLVCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		/* Check the semaphore status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		smbslvcnt  = inb_p(SMBSLVCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		if (smbslvcnt & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	} while (--retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	/* SMBus is still owned by the IMC, we give up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	if (!retries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	 * Notify the IMC (Integrated Micro Controller) if required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	 * Among other responsibilities, the IMC is in charge of monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	 * the System fans and temperature sensors, and act accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	 * All this is done through SMBus and can/will collide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	 * with our transactions if they are long (BLOCK_DATA).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	 * Therefore we need to request the ownership flag during those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	 * transactions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		ret = piix4_imc_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		case -EBUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			dev_warn(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 				 "IMC base address index region 0x%x already in use.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 				 KERNCZ_IMC_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			dev_warn(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 				 "Failed to communicate with the IMC.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		/* If IMC communication fails do not retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			dev_warn(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				 "Continuing without IMC notification.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			adapdata->notify_imc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	port = adapdata->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	if ((smba_en_lo & piix4_port_mask_sb800) != port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		       SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	retval = piix4_access(adap, addr, flags, read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			      command, size, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	/* Release the semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	outb_p(smbslvcnt | 0x20, SMBSLVCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		piix4_imc_wakeup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	release_region(SB800_PIIX4_SMB_IDX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) static u32 piix4_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	    I2C_FUNC_SMBUS_BLOCK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) static const struct i2c_algorithm smbus_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	.smbus_xfer	= piix4_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	.functionality	= piix4_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	.smbus_xfer	= piix4_access_sb800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	.functionality	= piix4_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) static const struct pci_device_id piix4_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		     PCI_DEVICE_ID_SERVERWORKS_OSB4) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		     PCI_DEVICE_ID_SERVERWORKS_CSB5) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		     PCI_DEVICE_ID_SERVERWORKS_CSB6) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		     PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		     PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) MODULE_DEVICE_TABLE (pci, piix4_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) static struct i2c_adapter *piix4_aux_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) static int piix4_adapter_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			     bool sb800_main, u8 port, bool notify_imc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			     u8 hw_port_nr, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			     struct i2c_adapter **padap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	struct i2c_adapter *adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	struct i2c_piix4_adapdata *adapdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	if (adap == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		release_region(smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	adap->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				: &smbus_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	if (adapdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		kfree(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		release_region(smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	adapdata->smba = smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	adapdata->sb800_main = sb800_main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	adapdata->port = port << piix4_port_shift_sb800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	adapdata->notify_imc = notify_imc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	/* set up the sysfs linkage to our parent device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	adap->dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	if (has_acpi_companion(&dev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		acpi_preset_companion(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				      ACPI_COMPANION(&dev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				      hw_port_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	snprintf(adap->name, sizeof(adap->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		"SMBus PIIX4 adapter%s at %04x", name, smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	i2c_set_adapdata(adap, adapdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	retval = i2c_add_adapter(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		kfree(adapdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		kfree(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		release_region(smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	*padap = adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 				    bool notify_imc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct i2c_piix4_adapdata *adapdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	    (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	     dev->revision >= 0x1F)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		piix4_adapter_count = HUDSON2_MAIN_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		piix4_adapter_count = PIIX4_MAX_ADAPTERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	for (port = 0; port < piix4_adapter_count; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		u8 hw_port_nr = port == 0 ? 0 : port + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 					   hw_port_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 					   piix4_main_port_names_sb800[port],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 					   &piix4_main_adapters[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	dev_err(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		"Error setting up SB800 adapters. Unregistering!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	while (--port >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		adapdata = i2c_get_adapdata(piix4_main_adapters[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		if (adapdata->smba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			i2c_del_adapter(piix4_main_adapters[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 			kfree(adapdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			kfree(piix4_main_adapters[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			piix4_main_adapters[port] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	bool is_sb800 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	if ((dev->vendor == PCI_VENDOR_ID_ATI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	     dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	     dev->revision >= 0x40) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	    dev->vendor == PCI_VENDOR_ID_AMD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	    dev->vendor == PCI_VENDOR_ID_HYGON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		bool notify_imc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		is_sb800 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		if ((dev->vendor == PCI_VENDOR_ID_AMD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		     dev->vendor == PCI_VENDOR_ID_HYGON) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		    dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			u8 imc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			 * Detect if IMC is active or not, this method is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			 * described on coreboot's AMD IMC notes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 						 0x40, &imc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			if (imc & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 				notify_imc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		/* base address location etc changed in SB800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		retval = piix4_setup_sb800(dev, id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		 * Try to register multiplexed main SMBus adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		 * give up if we can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		retval = piix4_add_adapters_sb800(dev, retval, notify_imc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		retval = piix4_setup(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		/* Try to register main SMBus adapter, give up if we can't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		retval = piix4_add_adapter(dev, retval, false, 0, false, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 					   "", &piix4_main_adapters[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	/* Check for auxiliary SMBus on some AMD chipsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	if (dev->vendor == PCI_VENDOR_ID_ATI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	    dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		if (dev->revision < 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			retval = piix4_setup_aux(dev, id, 0x58);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			/* SB800 added aux bus too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			retval = piix4_setup_sb800(dev, id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	if (dev->vendor == PCI_VENDOR_ID_AMD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	    (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	     dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		retval = piix4_setup_sb800(dev, id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (retval > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		/* Try to add the aux adapter if it exists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		 * piix4_add_adapter will clean up if this fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		piix4_add_adapter(dev, retval, false, 0, false, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 				  is_sb800 ? piix4_aux_port_name_sb800 : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 				  &piix4_aux_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) static void piix4_adap_remove(struct i2c_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (adapdata->smba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		i2c_del_adapter(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		if (adapdata->port == (0 << piix4_port_shift_sb800))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			release_region(adapdata->smba, SMBIOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		kfree(adapdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		kfree(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static void piix4_remove(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	int port = piix4_adapter_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	while (--port >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		if (piix4_main_adapters[port]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			piix4_adap_remove(piix4_main_adapters[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			piix4_main_adapters[port] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (piix4_aux_adapter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		piix4_adap_remove(piix4_aux_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		piix4_aux_adapter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static struct pci_driver piix4_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	.name		= "piix4_smbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	.id_table	= piix4_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	.probe		= piix4_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	.remove		= piix4_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) module_pci_driver(piix4_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) MODULE_DESCRIPTION("PIIX4 SMBus driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) MODULE_LICENSE("GPL");