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

Commit ec73adba authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-fixes-for-linus' of...

Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: add X86_FEATURE_XMM4_2 definitions
  x86: fix cpufreq + sched_clock() regression
  x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3
  x86: do not enable TSC notifier if we don't need it
  x86 MCE: Fix CPU hotplug problem with multiple multicore AMD CPUs
  x86: fix: make PCI ECS for AMD CPUs hotplug capable
  x86: fix: do not run code in amd_bus.c on non-AMD CPUs
parents cc556c5c 2a61812a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = {
};

DEFINE_PER_CPU(struct sys_device, device_mce);
void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinitdata;

/* Why are there no generic functions for this? */
#define ACCESSOR(name, var, start) \
@@ -883,9 +884,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
	case CPU_ONLINE:
	case CPU_ONLINE_FROZEN:
		mce_create_device(cpu);
		if (threshold_cpu_callback)
			threshold_cpu_callback(action, cpu);
		break;
	case CPU_DEAD:
	case CPU_DEAD_FROZEN:
		if (threshold_cpu_callback)
			threshold_cpu_callback(action, cpu);
		mce_remove_device(cpu);
		break;
	}
+5 −13
Original line number Diff line number Diff line
@@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
	deallocate_threshold_block(cpu, bank);

free_out:
	kobject_del(b->kobj);
	kobject_put(b->kobj);
	kfree(b);
	per_cpu(threshold_banks, cpu)[bank] = NULL;
@@ -645,14 +646,11 @@ static void threshold_remove_device(unsigned int cpu)
}

/* get notified when a cpu comes on/off */
static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
					    unsigned long action, void *hcpu)
static void __cpuinit amd_64_threshold_cpu_callback(unsigned long action,
						     unsigned int cpu)
{
	/* cpu was unsigned int to begin with */
	unsigned int cpu = (unsigned long)hcpu;

	if (cpu >= NR_CPUS)
		goto out;
		return;

	switch (action) {
	case CPU_ONLINE:
@@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
	default:
		break;
	}
      out:
	return NOTIFY_OK;
}

static struct notifier_block threshold_cpu_notifier __cpuinitdata = {
	.notifier_call = threshold_cpu_callback,
};

static __init int threshold_init_device(void)
{
	unsigned lcpu = 0;
@@ -684,7 +676,7 @@ static __init int threshold_init_device(void)
		if (err)
			return err;
	}
	register_hotcpu_notifier(&threshold_cpu_notifier);
	threshold_cpu_callback = amd_64_threshold_cpu_callback;
	return 0;
}

+5 −1
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
			mark_tsc_unstable("cpufreq changes");
	}

	set_cyc2ns_scale(tsc_khz_ref, freq->cpu);
	set_cyc2ns_scale(tsc_khz, freq->cpu);

	return 0;
}
@@ -325,6 +325,10 @@ static struct notifier_block time_cpufreq_notifier_block = {

static int __init cpufreq_tsc(void)
{
	if (!cpu_has_tsc)
		return 0;
	if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
		return 0;
	cpufreq_register_notifier(&time_cpufreq_notifier_block,
				CPUFREQ_TRANSITION_NOTIFIER);
	return 0;
+46 −6
Original line number Diff line number Diff line
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/topology.h>
#include <linux/cpu.h>
#include "pci.h"

#ifdef CONFIG_X86_64
@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void)
	return 0;
}

postcore_initcall(early_fill_mp_bus_info);
#else  /* !CONFIG_X86_64 */

#endif
static int __init early_fill_mp_bus_info(void) { return 0; }

#endif /* !CONFIG_X86_64 */

/* common 32/64 bit code */

#define ENABLE_CF8_EXT_CFG      (1ULL << 46)

static void enable_pci_io_ecs_per_cpu(void *unused)
static void enable_pci_io_ecs(void *unused)
{
	u64 reg;
	rdmsrl(MSR_AMD64_NB_CFG, reg);
@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused)
	}
}

static int __init enable_pci_io_ecs(void)
static int __cpuinit amd_cpu_notify(struct notifier_block *self,
				    unsigned long action, void *hcpu)
{
	int cpu = (long)hcpu;
	switch(action) {
	case CPU_ONLINE:
	case CPU_ONLINE_FROZEN:
		smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
		break;
	default:
		break;
	}
	return NOTIFY_OK;
}

static struct notifier_block __cpuinitdata amd_cpu_notifier = {
	.notifier_call	= amd_cpu_notify,
};

static int __init pci_io_ecs_init(void)
{
	int cpu;

	/* assume all cpus from fam10h have IO ECS */
        if (boot_cpu_data.x86 < 0x10)
		return 0;
	on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1);

	register_cpu_notifier(&amd_cpu_notifier);
	for_each_online_cpu(cpu)
		amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
			       (void *)(long)cpu);
	pci_probe |= PCI_HAS_IO_ECS;

	return 0;
}

static int __init amd_postcore_init(void)
{
	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
		return 0;

	early_fill_mp_bus_info();
	pci_io_ecs_init();

	return 0;
}

postcore_initcall(enable_pci_io_ecs);
postcore_initcall(amd_postcore_init);
+78 −0
Original line number Diff line number Diff line
@@ -31,8 +31,11 @@
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>

#include <asm/pat.h>
#include <asm/hpet.h>
#include <asm/io_apic.h>

#include "pci.h"

@@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res,
}
EXPORT_SYMBOL(pcibios_align_resource);

static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
{
	unsigned long base;
	unsigned long size;
	int i;

	base = res->start;
	size = (res->start == 0 && res->end == res->start) ? 0 :
		 (res->end - res->start + 1);

	if (!base || !size)
		return 0;

#ifdef CONFIG_HPET_TIMER
	/* for hpet */
	if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
		dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
				 base, base + size - 1);
		return 1;
	}
#endif

#ifdef CONFIG_X86_IO_APIC
	for (i = 0; i < nr_ioapics; i++) {
		unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;

		if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
			dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
					 base, base + size - 1);
			return 1;
		}
	}
#endif

#ifdef CONFIG_PCI_MMCONFIG
	for (i = 0; i < pci_mmcfg_config_num; i++) {
		unsigned long addr;

		addr = pci_mmcfg_config[i].address;
		if (base == addr && (res->flags & IORESOURCE_MEM)) {
			dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
					 base, base + size - 1);
			return 1;
		}
	}
#endif

	return 0;
}

static int check_platform(struct pci_dev *dev, struct resource *res)
{
	struct resource *root = NULL;

	/*
	 * forcibly insert it into the
	 * resource tree
	 */
	if (res->flags & IORESOURCE_MEM)
		root = &iomem_resource;
	else if (res->flags & IORESOURCE_IO)
		root = &ioport_resource;

	if (root && check_res_with_valid(dev, res)) {
		insert_resource(root, res);

		return 1;
	}

	return 0;
}
/*
 *  Handle resources of PCI devices.  If the world were perfect, we could
 *  just allocate all the resource regions and do nothing more.  It isn't.
@@ -128,6 +202,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
				pr = pci_find_parent_resource(dev, r);
				if (!r->start || !pr ||
				    request_resource(pr, r) < 0) {
					if (check_platform(dev, r))
						continue;
					dev_err(&dev->dev, "BAR %d: can't "
						"allocate resource\n", idx);
					/*
@@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass)
					r->flags, disabled, pass);
				pr = pci_find_parent_resource(dev, r);
				if (!pr || request_resource(pr, r) < 0) {
					if (check_platform(dev, r))
						continue;
					dev_err(&dev->dev, "BAR %d: can't "
						"allocate resource\n", idx);
					/* We'll assign a new address later */
Loading