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

Commit 442d1ba2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'edac-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

* 'edac-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  amd64_edac: Disable DRAM ECC injection on K8
  EDAC: Fixup scrubrate manipulation
  amd64_edac: Remove two-stage initialization
  amd64_edac: Check ECC capabilities initially
  amd64_edac: Carve out ECC-related hw settings
  amd64_edac: Remove PCI ECS enabling functions
  amd64_edac: Remove explicit Kconfig PCI dependency
  amd64_edac: Allocate driver instances dynamically
  amd64_edac: Rework printk macros
  amd64_edac: Rename CPU PCI devices
  amd64_edac: Concentrate per-family init even more
  amd64_edac: Cleanup the CPU PCI device reservation
  amd64_edac: Simplify CPU family detection
  amd64_edac: Add per-family init function
  amd64_edac: Use cached extended CPU model
  amd64_edac: Remove F11h support
parents fb5131e1 a135cef7
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -75,11 +75,11 @@ config EDAC_MCE
	bool

config EDAC_AMD64
	tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
	depends on EDAC_MM_EDAC && AMD_NB && X86_64 && PCI && EDAC_DECODE_MCE
	tristate "AMD64 (Opteron, Athlon64) K8, F10h"
	depends on EDAC_MM_EDAC && AMD_NB && X86_64 && EDAC_DECODE_MCE
	help
	  Support for error detection and correction on the AMD 64
	  Families of Memory Controllers (K8, F10h and F11h)
	  Support for error detection and correction of DRAM ECC errors on
	  the AMD64 families of memory controllers (K8 and F10h)

config EDAC_AMD64_ERROR_INJECTION
	bool "Sysfs HW Error injection facilities"
+341 −482

File changed.

Preview size limit exceeded, changes collapsed.

+39 −47
Original line number Diff line number Diff line
@@ -74,11 +74,26 @@
#include "edac_core.h"
#include "mce_amd.h"

#define amd64_printk(level, fmt, arg...) \
	edac_printk(level, "amd64", fmt, ##arg)
#define amd64_debug(fmt, arg...) \
	edac_printk(KERN_DEBUG, "amd64", fmt, ##arg)

#define amd64_mc_printk(mci, level, fmt, arg...) \
	edac_mc_chipset_printk(mci, level, "amd64", fmt, ##arg)
#define amd64_info(fmt, arg...) \
	edac_printk(KERN_INFO, "amd64", fmt, ##arg)

#define amd64_notice(fmt, arg...) \
	edac_printk(KERN_NOTICE, "amd64", fmt, ##arg)

#define amd64_warn(fmt, arg...) \
	edac_printk(KERN_WARNING, "amd64", fmt, ##arg)

#define amd64_err(fmt, arg...) \
	edac_printk(KERN_ERR, "amd64", fmt, ##arg)

#define amd64_mc_warn(mci, fmt, arg...) \
	edac_mc_chipset_printk(mci, KERN_WARNING, "amd64", fmt, ##arg)

#define amd64_mc_err(mci, fmt, arg...) \
	edac_mc_chipset_printk(mci, KERN_ERR, "amd64", fmt, ##arg)

/*
 * Throughout the comments in this code, the following terms are used:
@@ -129,11 +144,9 @@
 *         sections 3.5.4 and 3.5.5 for more information.
 */

#define EDAC_AMD64_VERSION		" Ver: 3.3.0 " __DATE__
#define EDAC_AMD64_VERSION		"v3.3.0"
#define EDAC_MOD_STR			"amd64_edac"

#define EDAC_MAX_NUMNODES		8

/* Extended Model from CPUID, for CPU Revision numbers */
#define K8_REV_D			1
#define K8_REV_E			2
@@ -322,9 +335,6 @@
#define K8_SCRCTRL			0x58

#define F10_NB_CFG_LOW			0x88
#define	F10_NB_CFG_LOW_ENABLE_EXT_CFG	BIT(14)

#define F10_NB_CFG_HIGH			0x8C

#define F10_ONLINE_SPARE		0xB0
#define F10_ONLINE_SPARE_SWAPDONE0(x)	((x) & BIT(1))
@@ -373,7 +383,6 @@ static inline int get_node_id(struct pci_dev *pdev)
enum amd64_chipset_families {
	K8_CPUS = 0,
	F10_CPUS,
	F11_CPUS,
};

/* Error injection control structure */
@@ -384,16 +393,13 @@ struct error_injection {
};

struct amd64_pvt {
	struct low_ops *ops;

	/* pci_device handles which we utilize */
	struct pci_dev *addr_f1_ctl;
	struct pci_dev *dram_f2_ctl;
	struct pci_dev *misc_f3_ctl;
	struct pci_dev *F1, *F2, *F3;

	int mc_node_id;		/* MC index of this MC node */
	int ext_model;		/* extended model value of this node */

	struct low_ops *ops;	/* pointer to per PCI Device ID func table */

	int channel_count;

	/* Raw registers */
@@ -455,27 +461,27 @@ struct amd64_pvt {
	/* place to store error injection parameters prior to issue */
	struct error_injection injection;

	/* Save old hw registers' values before we modified them */
	u32 nbctl_mcgctl_saved;		/* When true, following 2 are valid */
	u32 old_nbctl;
	/* DCT per-family scrubrate setting */
	u32 min_scrubrate;

	/* MC Type Index value: socket F vs Family 10h */
	u32 mc_type_index;
	/* family name this instance is running on */
	const char *ctl_name;

};

/*
 * per-node ECC settings descriptor
 */
struct ecc_settings {
	u32 old_nbctl;
	bool nbctl_valid;

	/* misc settings */
	struct flags {
		unsigned long cf8_extcfg:1;
		unsigned long nb_mce_enable:1;
		unsigned long nb_ecc_prev:1;
	} flags;
};

struct scrubrate {
       u32 scrubval;           /* bit pattern for scrub rate */
       u32 bandwidth;          /* bandwidth consumed (bytes/sec) */
};

extern struct scrubrate scrubrates[23];
extern const char *tt_msgs[4];
extern const char *ll_msgs[4];
extern const char *rrrr_msgs[16];
@@ -517,23 +523,10 @@ struct low_ops {

struct amd64_family_type {
	const char *ctl_name;
	u16 addr_f1_ctl;
	u16 misc_f3_ctl;
	u16 f1_id, f3_id;
	struct low_ops ops;
};

static struct amd64_family_type amd64_family_types[];

static inline const char *get_amd_family_name(int index)
{
	return amd64_family_types[index].ctl_name;
}

static inline struct low_ops *family_ops(int index)
{
	return &amd64_family_types[index].ops;
}

static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
					   u32 *val, const char *func)
{
@@ -541,7 +534,7 @@ static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,

	err = pci_read_config_dword(pdev, offset, val);
	if (err)
		amd64_printk(KERN_WARNING, "%s: error reading F%dx%x.\n",
		amd64_warn("%s: error reading F%dx%x.\n",
			   func, PCI_FUNC(pdev->devfn), offset);

	return err;
@@ -556,7 +549,6 @@ static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
 */
#define K8_MIN_SCRUB_RATE_BITS	0x0
#define F10_MIN_SCRUB_RATE_BITS	0x5
#define F11_MIN_SCRUB_RATE_BITS	0x6

int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
			     u64 *hole_offset, u64 *hole_size);
+8 −17
Original line number Diff line number Diff line
@@ -23,9 +23,7 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {

		if (value > 3) {
			amd64_printk(KERN_WARNING,
				     "%s: invalid section 0x%lx\n",
				     __func__, value);
			amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
			return -EINVAL;
		}

@@ -58,9 +56,7 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {

		if (value > 8) {
			amd64_printk(KERN_WARNING,
				     "%s: invalid word 0x%lx\n",
				     __func__, value);
			amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
			return -EINVAL;
		}

@@ -92,8 +88,7 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {

		if (value & 0xFFFF0000) {
			amd64_printk(KERN_WARNING,
				     "%s: invalid EccVector: 0x%lx\n",
			amd64_warn("%s: invalid EccVector: 0x%lx\n",
				   __func__, value);
			return -EINVAL;
		}
@@ -122,15 +117,13 @@ static ssize_t amd64_inject_read_store(struct mem_ctl_info *mci,
		/* Form value to choose 16-byte section of cacheline */
		section = F10_NB_ARRAY_DRAM_ECC |
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_ADDR, section);
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_ADDR, section);

		word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word,
						pvt->injection.bit_map);

		/* Issue 'word' and 'bit' along with the READ request */
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_DATA, word_bits);
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_DATA, word_bits);

		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);

@@ -157,15 +150,13 @@ static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci,
		/* Form value to choose 16-byte section of cacheline */
		section = F10_NB_ARRAY_DRAM_ECC |
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_ADDR, section);
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_ADDR, section);

		word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
						pvt->injection.bit_map);

		/* Issue 'word' and 'bit' along with the READ request */
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_DATA, word_bits);
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_DATA, word_bits);

		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);

+5 −4
Original line number Diff line number Diff line
@@ -818,9 +818,10 @@ static void cpc925_del_edac_devices(void)
}

/* Convert current back-ground scrub rate into byte/sec bandwith */
static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci)
{
	struct cpc925_mc_pdata *pdata = mci->pvt_info;
	int bw;
	u32 mscr;
	u8 si;

@@ -832,11 +833,11 @@ static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
	if (((mscr & MSCR_SCRUB_MOD_MASK) != MSCR_BACKGR_SCRUB) ||
	    (si == 0)) {
		cpc925_mc_printk(mci, KERN_INFO, "Scrub mode not enabled\n");
		*bw = 0;
		bw = 0;
	} else
		*bw = CPC925_SCRUB_BLOCK_SIZE * 0xFA67 / si;
		bw = CPC925_SCRUB_BLOCK_SIZE * 0xFA67 / si;

	return 0;
	return bw;
}

/* Return 0 for single channel; 1 for dual channel */
Loading