Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62ff577f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull EDAC updates from Borislav Petkov:
 "A bunch of EDAC updates all over the place:

   - Support for new AMD models, along with more graceful fallback for
     unsupported hw.

   - Bunch of fixes from SUSE accumulated from bug reports

   - Misc other fixes and cleanups"

* tag 'edac_for_3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  amd64_edac: Add support for newer F16h models
  i7core_edac: Drop unused variable
  i82875p_edac: Drop redundant call to pci_get_device()
  amd8111_edac: Fix leaks in probe error paths
  e752x_edac: Drop pvt->bridge_ck
  MCE, AMD: Fix decoding module loading on unsupported hw
  i5100_edac: Remove an unneeded condition in i5100_init_csrows()
  sb_edac: Degrade log level for device registration
  amd64_edac: Fix logic to determine channel for F15 M30h processors
  edac/85xx: Remove deprecated IRQF_DISABLED
  i3200_edac: Add a missing pci_disable_device() on the exit path
  i5400_edac: Disable device when unloading module
  e752x_edac: Simplify call to pci_get_device()
parents 26f31fb9 85a8885b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
	{}
};
EXPORT_SYMBOL(amd_nb_misc_ids);
@@ -30,6 +31,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
	{}
};

+35 −3
Original line number Diff line number Diff line
@@ -1239,9 +1239,17 @@ static u8 f15_m30h_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
	if (num_dcts_intlv == 2) {
		select = (sys_addr >> 8) & 0x3;
		channel = select ? 0x3 : 0;
	} else if (num_dcts_intlv == 4)
		channel = (sys_addr >> 8) & 0x7;

	} else if (num_dcts_intlv == 4) {
		u8 intlv_addr = dct_sel_interleave_addr(pvt);
		switch (intlv_addr) {
		case 0x4:
			channel = (sys_addr >> 8) & 0x3;
			break;
		case 0x5:
			channel = (sys_addr >> 9) & 0x3;
			break;
		}
	}
	return channel;
}

@@ -1799,6 +1807,17 @@ static struct amd64_family_type family_types[] = {
			.read_dct_pci_cfg	= f10_read_dct_pci_cfg,
		}
	},
	[F16_M30H_CPUS] = {
		.ctl_name = "F16h_M30h",
		.f1_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F1,
		.f3_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F3,
		.ops = {
			.early_channel_count	= f1x_early_channel_count,
			.map_sysaddr_to_csrow	= f1x_map_sysaddr_to_csrow,
			.dbam_to_cs		= f16_dbam_to_chip_select,
			.read_dct_pci_cfg	= f10_read_dct_pci_cfg,
		}
	},
};

/*
@@ -2578,6 +2597,11 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
		break;

	case 0x16:
		if (pvt->model == 0x30) {
			fam_type = &family_types[F16_M30H_CPUS];
			pvt->ops = &family_types[F16_M30H_CPUS].ops;
			break;
		}
		fam_type	= &family_types[F16_CPUS];
		pvt->ops	= &family_types[F16_CPUS].ops;
		break;
@@ -2830,6 +2854,14 @@ static const struct pci_device_id amd64_pci_table[] = {
		.class		= 0,
		.class_mask	= 0,
	},
	{
		.vendor		= PCI_VENDOR_ID_AMD,
		.device		= PCI_DEVICE_ID_AMD_16H_M30H_NB_F2,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.class		= 0,
		.class_mask	= 0,
	},

	{0, }
};
+3 −0
Original line number Diff line number Diff line
@@ -168,6 +168,8 @@
#define PCI_DEVICE_ID_AMD_15H_NB_F2	0x1602
#define PCI_DEVICE_ID_AMD_16H_NB_F1	0x1531
#define PCI_DEVICE_ID_AMD_16H_NB_F2	0x1532
#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F1 0x1581
#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F2 0x1582

/*
 * Function 1 - Address Map
@@ -300,6 +302,7 @@ enum amd_families {
	F15_CPUS,
	F15_M30H_CPUS,
	F16_CPUS,
	F16_M30H_CPUS,
	NUM_FAMILIES,
};

+30 −14
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ static int amd8111_dev_probe(struct pci_dev *dev,
				const struct pci_device_id *id)
{
	struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
	int ret = -ENODEV;

	dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
					dev_info->err_dev, NULL);
@@ -359,16 +360,15 @@ static int amd8111_dev_probe(struct pci_dev *dev,
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, dev_info->err_dev,
			dev_info->ctl_name);
		return -ENODEV;
		goto err;
	}

	if (pci_enable_device(dev_info->dev)) {
		pci_dev_put(dev_info->dev);
		printk(KERN_ERR "failed to enable:"
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, dev_info->err_dev,
			dev_info->ctl_name);
		return -ENODEV;
		goto err_dev_put;
	}

	/*
@@ -381,8 +381,10 @@ static int amd8111_dev_probe(struct pci_dev *dev,
		edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
					   NULL, 0, 0,
					   NULL, 0, dev_info->edac_idx);
	if (!dev_info->edac_dev)
		return -ENOMEM;
	if (!dev_info->edac_dev) {
		ret = -ENOMEM;
		goto err_dev_put;
	}

	dev_info->edac_dev->pvt_info = dev_info;
	dev_info->edac_dev->dev = &dev_info->dev->dev;
@@ -399,8 +401,7 @@ static int amd8111_dev_probe(struct pci_dev *dev,
	if (edac_device_add_device(dev_info->edac_dev) > 0) {
		printk(KERN_ERR "failed to add edac_dev for %s\n",
			dev_info->ctl_name);
		edac_device_free_ctl_info(dev_info->edac_dev);
		return -ENODEV;
		goto err_edac_free_ctl;
	}

	printk(KERN_INFO "added one edac_dev on AMD8111 "
@@ -409,6 +410,13 @@ static int amd8111_dev_probe(struct pci_dev *dev,
		dev_info->ctl_name);

	return 0;

err_edac_free_ctl:
	edac_device_free_ctl_info(dev_info->edac_dev);
err_dev_put:
	pci_dev_put(dev_info->dev);
err:
	return ret;
}

static void amd8111_dev_remove(struct pci_dev *dev)
@@ -437,6 +445,7 @@ static int amd8111_pci_probe(struct pci_dev *dev,
				const struct pci_device_id *id)
{
	struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
	int ret = -ENODEV;

	pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
					pci_info->err_dev, NULL);
@@ -446,16 +455,15 @@ static int amd8111_pci_probe(struct pci_dev *dev,
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, pci_info->err_dev,
			pci_info->ctl_name);
		return -ENODEV;
		goto err;
	}

	if (pci_enable_device(pci_info->dev)) {
		pci_dev_put(pci_info->dev);
		printk(KERN_ERR "failed to enable:"
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, pci_info->err_dev,
			pci_info->ctl_name);
		return -ENODEV;
		goto err_dev_put;
	}

	/*
@@ -465,8 +473,10 @@ static int amd8111_pci_probe(struct pci_dev *dev,
	*/
	pci_info->edac_idx = edac_pci_alloc_index();
	pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
	if (!pci_info->edac_dev)
		return -ENOMEM;
	if (!pci_info->edac_dev) {
		ret = -ENOMEM;
		goto err_dev_put;
	}

	pci_info->edac_dev->pvt_info = pci_info;
	pci_info->edac_dev->dev = &pci_info->dev->dev;
@@ -483,8 +493,7 @@ static int amd8111_pci_probe(struct pci_dev *dev,
	if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
		printk(KERN_ERR "failed to add edac_pci for %s\n",
			pci_info->ctl_name);
		edac_pci_free_ctl_info(pci_info->edac_dev);
		return -ENODEV;
		goto err_edac_free_ctl;
	}

	printk(KERN_INFO "added one edac_pci on AMD8111 "
@@ -493,6 +502,13 @@ static int amd8111_pci_probe(struct pci_dev *dev,
		pci_info->ctl_name);

	return 0;

err_edac_free_ctl:
	edac_pci_free_ctl_info(pci_info->edac_dev);
err_dev_put:
	pci_dev_put(pci_info->dev);
err:
	return ret;
}

static void amd8111_pci_remove(struct pci_dev *dev)
+11 −19
Original line number Diff line number Diff line
@@ -209,7 +209,6 @@ enum e752x_chips {
 */

struct e752x_pvt {
	struct pci_dev *bridge_ck;
	struct pci_dev *dev_d0f0;
	struct pci_dev *dev_d0f1;
	u32 tolm;
@@ -891,7 +890,7 @@ static void e752x_get_error_info(struct mem_ctl_info *mci,
					info->buf_ferr);

		if (info->dram_ferr)
			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_FERR,
			pci_write_bits16(pvt->dev_d0f1, E752X_DRAM_FERR,
					 info->dram_ferr, info->dram_ferr);

		pci_write_config_dword(dev, E752X_FERR_GLOBAL,
@@ -936,7 +935,7 @@ static void e752x_get_error_info(struct mem_ctl_info *mci,
					info->buf_nerr);

		if (info->dram_nerr)
			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_NERR,
			pci_write_bits16(pvt->dev_d0f1, E752X_DRAM_NERR,
					 info->dram_nerr, info->dram_nerr);

		pci_write_config_dword(dev, E752X_NERR_GLOBAL,
@@ -1177,38 +1176,33 @@ static void e752x_init_mem_map_table(struct pci_dev *pdev,
static int e752x_get_devs(struct pci_dev *pdev, int dev_idx,
			struct e752x_pvt *pvt)
{
	struct pci_dev *dev;

	pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
				pvt->dev_info->err_dev, pvt->bridge_ck);
	pvt->dev_d0f1 = pci_get_device(PCI_VENDOR_ID_INTEL,
				pvt->dev_info->err_dev, NULL);

	if (pvt->bridge_ck == NULL) {
		pvt->bridge_ck = pci_scan_single_device(pdev->bus,
	if (pvt->dev_d0f1 == NULL) {
		pvt->dev_d0f1 = pci_scan_single_device(pdev->bus,
							PCI_DEVFN(0, 1));
		pci_dev_get(pvt->bridge_ck);
		pci_dev_get(pvt->dev_d0f1);
	}

	if (pvt->bridge_ck == NULL) {
	if (pvt->dev_d0f1 == NULL) {
		e752x_printk(KERN_ERR, "error reporting device not found:"
			"vendor %x device 0x%x (broken BIOS?)\n",
			PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
		return 1;
	}

	dev = pci_get_device(PCI_VENDOR_ID_INTEL,
	pvt->dev_d0f0 = pci_get_device(PCI_VENDOR_ID_INTEL,
				e752x_devs[dev_idx].ctl_dev,
				NULL);

	if (dev == NULL)
	if (pvt->dev_d0f0 == NULL)
		goto fail;

	pvt->dev_d0f0 = dev;
	pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);

	return 0;

fail:
	pci_dev_put(pvt->bridge_ck);
	pci_dev_put(pvt->dev_d0f1);
	return 1;
}

@@ -1385,7 +1379,6 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
fail:
	pci_dev_put(pvt->dev_d0f0);
	pci_dev_put(pvt->dev_d0f1);
	pci_dev_put(pvt->bridge_ck);
	edac_mc_free(mci);

	return -ENODEV;
@@ -1419,7 +1412,6 @@ static void e752x_remove_one(struct pci_dev *pdev)
	pvt = (struct e752x_pvt *)mci->pvt_info;
	pci_dev_put(pvt->dev_d0f0);
	pci_dev_put(pvt->dev_d0f1);
	pci_dev_put(pvt->bridge_ck);
	edac_mc_free(mci);
}

Loading