brintos

brintos / linux-shallow public Read only

0
0
Text · 9.9 KiB · 28610ba Raw
359 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module4 *5 * Copyright (c) 2008 Wind River Systems, Inc.6 *7 * Authors:	Cao Qingtao <qingtao.cao@windriver.com>8 * 		Benjamin Walsh <benjamin.walsh@windriver.com>9 * 		Hu Yongqi <yongqi.hu@windriver.com>10 */11 12#include <linux/module.h>13#include <linux/init.h>14#include <linux/interrupt.h>15#include <linux/io.h>16#include <linux/bitops.h>17#include <linux/edac.h>18#include <linux/pci_ids.h>19 20#include "edac_module.h"21#include "amd8131_edac.h"22 23#define AMD8131_EDAC_REVISION	" Ver: 1.0.0"24#define AMD8131_EDAC_MOD_STR	"amd8131_edac"25 26/* Wrapper functions for accessing PCI configuration space */27static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)28{29	int ret;30 31	ret = pci_read_config_dword(dev, reg, val32);32	if (ret != 0)33		printk(KERN_ERR AMD8131_EDAC_MOD_STR34			" PCI Access Read Error at 0x%x\n", reg);35}36 37static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)38{39	int ret;40 41	ret = pci_write_config_dword(dev, reg, val32);42	if (ret != 0)43		printk(KERN_ERR AMD8131_EDAC_MOD_STR44			" PCI Access Write Error at 0x%x\n", reg);45}46 47/* Support up to two AMD8131 chipsets on a platform */48static struct amd8131_dev_info amd8131_devices[] = {49	{50	.inst = NORTH_A,51	.devfn = DEVFN_PCIX_BRIDGE_NORTH_A,52	.ctl_name = "AMD8131_PCIX_NORTH_A",53	},54	{55	.inst = NORTH_B,56	.devfn = DEVFN_PCIX_BRIDGE_NORTH_B,57	.ctl_name = "AMD8131_PCIX_NORTH_B",58	},59	{60	.inst = SOUTH_A,61	.devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,62	.ctl_name = "AMD8131_PCIX_SOUTH_A",63	},64	{65	.inst = SOUTH_B,66	.devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,67	.ctl_name = "AMD8131_PCIX_SOUTH_B",68	},69	{.inst = NO_BRIDGE,},70};71 72static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)73{74	u32 val32;75	struct pci_dev *dev = dev_info->dev;76 77	/* First clear error detection flags */78	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);79	if (val32 & MEM_LIMIT_MASK)80		edac_pci_write_dword(dev, REG_MEM_LIM, val32);81 82	/* Clear Discard Timer Timedout flag */83	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);84	if (val32 & INT_CTLR_DTS)85		edac_pci_write_dword(dev, REG_INT_CTLR, val32);86 87	/* Clear CRC Error flag on link side A */88	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);89	if (val32 & LNK_CTRL_CRCERR_A)90		edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);91 92	/* Clear CRC Error flag on link side B */93	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);94	if (val32 & LNK_CTRL_CRCERR_B)95		edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);96 97	/*98	 * Then enable all error detections.99	 *100	 * Setup Discard Timer Sync Flood Enable,101	 * System Error Enable and Parity Error Enable.102	 */103	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);104	val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;105	edac_pci_write_dword(dev, REG_INT_CTLR, val32);106 107	/* Enable overall SERR Error detection */108	edac_pci_read_dword(dev, REG_STS_CMD, &val32);109	val32 |= STS_CMD_SERREN;110	edac_pci_write_dword(dev, REG_STS_CMD, val32);111 112	/* Setup CRC Flood Enable for link side A */113	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);114	val32 |= LNK_CTRL_CRCFEN;115	edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);116 117	/* Setup CRC Flood Enable for link side B */118	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);119	val32 |= LNK_CTRL_CRCFEN;120	edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);121}122 123static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)124{125	u32 val32;126	struct pci_dev *dev = dev_info->dev;127 128	/* Disable SERR, PERR and DTSE Error detection */129	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);130	val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);131	edac_pci_write_dword(dev, REG_INT_CTLR, val32);132 133	/* Disable overall System Error detection */134	edac_pci_read_dword(dev, REG_STS_CMD, &val32);135	val32 &= ~STS_CMD_SERREN;136	edac_pci_write_dword(dev, REG_STS_CMD, val32);137 138	/* Disable CRC Sync Flood on link side A */139	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);140	val32 &= ~LNK_CTRL_CRCFEN;141	edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);142 143	/* Disable CRC Sync Flood on link side B */144	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);145	val32 &= ~LNK_CTRL_CRCFEN;146	edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);147}148 149static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)150{151	struct amd8131_dev_info *dev_info = edac_dev->pvt_info;152	struct pci_dev *dev = dev_info->dev;153	u32 val32;154 155	/* Check PCI-X Bridge Memory Base-Limit Register for errors */156	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);157	if (val32 & MEM_LIMIT_MASK) {158		printk(KERN_INFO "Error(s) in mem limit register "159			"on %s bridge\n", dev_info->ctl_name);160		printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"161			"RTA: %d, STA: %d, MDPE: %d\n",162			val32 & MEM_LIMIT_DPE,163			val32 & MEM_LIMIT_RSE,164			val32 & MEM_LIMIT_RMA,165			val32 & MEM_LIMIT_RTA,166			val32 & MEM_LIMIT_STA,167			val32 & MEM_LIMIT_MDPE);168 169		val32 |= MEM_LIMIT_MASK;170		edac_pci_write_dword(dev, REG_MEM_LIM, val32);171 172		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);173	}174 175	/* Check if Discard Timer timed out */176	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);177	if (val32 & INT_CTLR_DTS) {178		printk(KERN_INFO "Error(s) in interrupt and control register "179			"on %s bridge\n", dev_info->ctl_name);180		printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);181 182		val32 |= INT_CTLR_DTS;183		edac_pci_write_dword(dev, REG_INT_CTLR, val32);184 185		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);186	}187 188	/* Check if CRC error happens on link side A */189	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);190	if (val32 & LNK_CTRL_CRCERR_A) {191		printk(KERN_INFO "Error(s) in link conf and control register "192			"on %s bridge\n", dev_info->ctl_name);193		printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);194 195		val32 |= LNK_CTRL_CRCERR_A;196		edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);197 198		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);199	}200 201	/* Check if CRC error happens on link side B */202	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);203	if (val32 & LNK_CTRL_CRCERR_B) {204		printk(KERN_INFO "Error(s) in link conf and control register "205			"on %s bridge\n", dev_info->ctl_name);206		printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);207 208		val32 |= LNK_CTRL_CRCERR_B;209		edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);210 211		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);212	}213}214 215static struct amd8131_info amd8131_chipset = {216	.err_dev = PCI_DEVICE_ID_AMD_8131_APIC,217	.devices = amd8131_devices,218	.init = amd8131_pcix_init,219	.exit = amd8131_pcix_exit,220	.check = amd8131_pcix_check,221};222 223/*224 * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,225 * so amd8131_probe() would be called by kernel 4 times, with different226 * address of pci_dev for each of them each time.227 */228static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)229{230	struct amd8131_dev_info *dev_info;231 232	for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;233		dev_info++)234		if (dev_info->devfn == dev->devfn)235			break;236 237	if (dev_info->inst == NO_BRIDGE) /* should never happen */238		return -ENODEV;239 240	/*241	 * We can't call pci_get_device() as we are used to do because242	 * there are 4 of them but pci_dev_get() instead.243	 */244	dev_info->dev = pci_dev_get(dev);245 246	if (pci_enable_device(dev_info->dev)) {247		pci_dev_put(dev_info->dev);248		printk(KERN_ERR "failed to enable:"249			"vendor %x, device %x, devfn %x, name %s\n",250			PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,251			dev_info->devfn, dev_info->ctl_name);252		return -ENODEV;253	}254 255	/*256	 * we do not allocate extra private structure for257	 * edac_pci_ctl_info, but make use of existing258	 * one instead.259	 */260	dev_info->edac_idx = edac_pci_alloc_index();261	dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);262	if (!dev_info->edac_dev)263		return -ENOMEM;264 265	dev_info->edac_dev->pvt_info = dev_info;266	dev_info->edac_dev->dev = &dev_info->dev->dev;267	dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;268	dev_info->edac_dev->ctl_name = dev_info->ctl_name;269	dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);270 271	if (edac_op_state == EDAC_OPSTATE_POLL)272		dev_info->edac_dev->edac_check = amd8131_chipset.check;273 274	if (amd8131_chipset.init)275		amd8131_chipset.init(dev_info);276 277	if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {278		printk(KERN_ERR "failed edac_pci_add_device() for %s\n",279			dev_info->ctl_name);280		edac_pci_free_ctl_info(dev_info->edac_dev);281		return -ENODEV;282	}283 284	printk(KERN_INFO "added one device on AMD8131 "285		"vendor %x, device %x, devfn %x, name %s\n",286		PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,287		dev_info->devfn, dev_info->ctl_name);288 289	return 0;290}291 292static void amd8131_remove(struct pci_dev *dev)293{294	struct amd8131_dev_info *dev_info;295 296	for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;297		dev_info++)298		if (dev_info->devfn == dev->devfn)299			break;300 301	if (dev_info->inst == NO_BRIDGE) /* should never happen */302		return;303 304	if (dev_info->edac_dev) {305		edac_pci_del_device(dev_info->edac_dev->dev);306		edac_pci_free_ctl_info(dev_info->edac_dev);307	}308 309	if (amd8131_chipset.exit)310		amd8131_chipset.exit(dev_info);311 312	pci_dev_put(dev_info->dev);313}314 315static const struct pci_device_id amd8131_edac_pci_tbl[] = {316	{317	PCI_VEND_DEV(AMD, 8131_BRIDGE),318	.subvendor = PCI_ANY_ID,319	.subdevice = PCI_ANY_ID,320	.class = 0,321	.class_mask = 0,322	.driver_data = 0,323	},324	{325	0,326	}			/* table is NULL-terminated */327};328MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);329 330static struct pci_driver amd8131_edac_driver = {331	.name = AMD8131_EDAC_MOD_STR,332	.probe = amd8131_probe,333	.remove = amd8131_remove,334	.id_table = amd8131_edac_pci_tbl,335};336 337static int __init amd8131_edac_init(void)338{339	printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");340	printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");341 342	/* Only POLL mode supported so far */343	edac_op_state = EDAC_OPSTATE_POLL;344 345	return pci_register_driver(&amd8131_edac_driver);346}347 348static void __exit amd8131_edac_exit(void)349{350	pci_unregister_driver(&amd8131_edac_driver);351}352 353module_init(amd8131_edac_init);354module_exit(amd8131_edac_exit);355 356MODULE_LICENSE("GPL");357MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>");358MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");359