You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (27 commits) x86: Clean up apic.c and apic.h x86: Remove superflous goal definition of tsc_sync x86: dt: Correct local apic documentation in device tree bindings x86: dt: Cleanup local apic setup x86: dt: Fix OLPC=y/INTEL_CE=n build rtc: cmos: Add OF bindings x86: ce4100: Use OF to setup devices x86: ioapic: Add OF bindings for IO_APIC x86: dtb: Add generic bus probe x86: dtb: Add support for PCI devices backed by dtb nodes x86: dtb: Add device tree support for HPET x86: dtb: Add early parsing of IO_APIC x86: dtb: Add irq domain abstraction x86: dtb: Add a device tree for CE4100 x86: Add device tree support x86: e820: Remove conditional early mapping in parse_e820_ext x86: OLPC: Make OLPC=n build again x86: OLPC: Remove extra OLPC_OPENFIRMWARE_DT indirection x86: OLPC: Cleanup config maze completely x86: OLPC: Hide OLPC_OPENFIRMWARE config switch ... Fix up conflicts in arch/x86/platform/ce4100/ce4100.c
This commit is contained in:
@@ -104,11 +104,22 @@ struct pci_controller {
|
||||
int global_number; /* PCI domain number */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
|
||||
{
|
||||
return bus->sysdata;
|
||||
}
|
||||
|
||||
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *host;
|
||||
|
||||
if (bus->self)
|
||||
return pci_device_to_OF_node(bus->self);
|
||||
host = pci_bus_to_host(bus);
|
||||
return host ? host->dn : NULL;
|
||||
}
|
||||
|
||||
static inline int isa_vaddr_is_ioport(void __iomem *address)
|
||||
{
|
||||
/* No specific ISA handling on ppc32 at this stage, it
|
||||
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/* These are used for config access before all the PCI probing
|
||||
has been done. */
|
||||
|
||||
@@ -64,21 +64,6 @@ extern void kdump_move_device_tree(void);
|
||||
/* CPU OF node matching */
|
||||
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
|
||||
|
||||
/**
|
||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||
* @pdev: the device whose interrupt is to be resolved
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* This function resolves the PCI interrupt for a given PCI device. If a
|
||||
* device-node exists for a given pci_dev, it will use normal OF tree
|
||||
* walking. If not, it will implement standard swizzling and walk up the
|
||||
* PCI tree until an device-node is found, at which point it will finish
|
||||
* resolving using the OF tree walking.
|
||||
*/
|
||||
struct pci_dev;
|
||||
struct of_irq;
|
||||
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
@@ -2,88 +2,11 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci_regs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
struct pci_dev *ppdev;
|
||||
u32 lspec;
|
||||
u32 laddr[3];
|
||||
u8 pin;
|
||||
int rc;
|
||||
|
||||
/* Check if we have a device node, if yes, fallback to standard OF
|
||||
* parsing
|
||||
*/
|
||||
dn = pci_device_to_OF_node(pdev);
|
||||
if (dn)
|
||||
return of_irq_map_one(dn, 0, out_irq);
|
||||
|
||||
/* Ok, we don't, time to have fun. Let's start by building up an
|
||||
* interrupt spec. we assume #interrupt-cells is 1, which is standard
|
||||
* for PCI. If you do different, then don't use that routine.
|
||||
*/
|
||||
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
/* No pin, exit */
|
||||
if (pin == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Now we walk up the PCI tree */
|
||||
lspec = pin;
|
||||
for (;;) {
|
||||
/* Get the pci_dev of our parent */
|
||||
ppdev = pdev->bus->self;
|
||||
|
||||
/* Ouch, it's a host bridge... */
|
||||
if (ppdev == NULL) {
|
||||
struct pci_controller *host;
|
||||
host = pci_bus_to_host(pdev->bus);
|
||||
ppnode = host ? host->dn : NULL;
|
||||
/* No node for host bridge ? give up */
|
||||
if (ppnode == NULL)
|
||||
return -EINVAL;
|
||||
} else
|
||||
/* We found a P2P bridge, check if it has a node */
|
||||
ppnode = pci_device_to_OF_node(ppdev);
|
||||
|
||||
/* Ok, we have found a parent with a device-node, hand over to
|
||||
* the OF parsing code.
|
||||
* We build a unit address from the linux device to be used for
|
||||
* resolution. Note that we use the linux bus number which may
|
||||
* not match your firmware bus numbering.
|
||||
* Fortunately, in most cases, interrupt-map-mask doesn't
|
||||
* include the bus number as part of the matching.
|
||||
* You should still be careful about that though if you intend
|
||||
* to rely on this function (you ship a firmware that doesn't
|
||||
* create device nodes for all PCI devices).
|
||||
*/
|
||||
if (ppnode)
|
||||
break;
|
||||
|
||||
/* We can only get here if we hit a P2P bridge with no node,
|
||||
* let's do standard swizzling and try again
|
||||
*/
|
||||
lspec = pci_swizzle_interrupt_pin(pdev, lspec);
|
||||
pdev = ppdev;
|
||||
}
|
||||
|
||||
laddr[0] = (pdev->bus->number << 16)
|
||||
| (pdev->devfn << 8);
|
||||
laddr[1] = laddr[2] = 0;
|
||||
return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_pci.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
@@ -171,6 +171,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
|
||||
return bus->sysdata;
|
||||
}
|
||||
|
||||
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *host;
|
||||
|
||||
if (bus->self)
|
||||
return pci_device_to_OF_node(bus->self);
|
||||
host = pci_bus_to_host(bus);
|
||||
return host ? host->dn : NULL;
|
||||
}
|
||||
|
||||
static inline int isa_vaddr_is_ioport(void __iomem *address)
|
||||
{
|
||||
/* No specific ISA handling on ppc32 at this stage, it
|
||||
|
||||
@@ -70,21 +70,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
|
||||
#endif
|
||||
#define of_node_to_nid of_node_to_nid
|
||||
|
||||
/**
|
||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||
* @pdev: the device whose interrupt is to be resolved
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* This function resolves the PCI interrupt for a given PCI device. If a
|
||||
* device-node exists for a given pci_dev, it will use normal OF tree
|
||||
* walking. If not, it will implement standard swizzling and walk up the
|
||||
* PCI tree until an device-node is found, at which point it will finish
|
||||
* resolving using the OF tree walking.
|
||||
*/
|
||||
struct pci_dev;
|
||||
struct of_irq;
|
||||
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
|
||||
|
||||
extern void of_instantiate_rtc(void);
|
||||
|
||||
/* These includes are put at the bottom because they may contain things
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
@@ -2,95 +2,11 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci_regs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
struct pci_dev *ppdev;
|
||||
u32 lspec;
|
||||
u32 laddr[3];
|
||||
u8 pin;
|
||||
int rc;
|
||||
|
||||
/* Check if we have a device node, if yes, fallback to standard OF
|
||||
* parsing
|
||||
*/
|
||||
dn = pci_device_to_OF_node(pdev);
|
||||
if (dn) {
|
||||
rc = of_irq_map_one(dn, 0, out_irq);
|
||||
if (!rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Ok, we don't, time to have fun. Let's start by building up an
|
||||
* interrupt spec. we assume #interrupt-cells is 1, which is standard
|
||||
* for PCI. If you do different, then don't use that routine.
|
||||
*/
|
||||
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
/* No pin, exit */
|
||||
if (pin == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Now we walk up the PCI tree */
|
||||
lspec = pin;
|
||||
for (;;) {
|
||||
/* Get the pci_dev of our parent */
|
||||
ppdev = pdev->bus->self;
|
||||
|
||||
/* Ouch, it's a host bridge... */
|
||||
if (ppdev == NULL) {
|
||||
#ifdef CONFIG_PPC64
|
||||
ppnode = pci_bus_to_OF_node(pdev->bus);
|
||||
#else
|
||||
struct pci_controller *host;
|
||||
host = pci_bus_to_host(pdev->bus);
|
||||
ppnode = host ? host->dn : NULL;
|
||||
#endif
|
||||
/* No node for host bridge ? give up */
|
||||
if (ppnode == NULL)
|
||||
return -EINVAL;
|
||||
} else
|
||||
/* We found a P2P bridge, check if it has a node */
|
||||
ppnode = pci_device_to_OF_node(ppdev);
|
||||
|
||||
/* Ok, we have found a parent with a device-node, hand over to
|
||||
* the OF parsing code.
|
||||
* We build a unit address from the linux device to be used for
|
||||
* resolution. Note that we use the linux bus number which may
|
||||
* not match your firmware bus numbering.
|
||||
* Fortunately, in most cases, interrupt-map-mask doesn't include
|
||||
* the bus number as part of the matching.
|
||||
* You should still be careful about that though if you intend
|
||||
* to rely on this function (you ship a firmware that doesn't
|
||||
* create device nodes for all PCI devices).
|
||||
*/
|
||||
if (ppnode)
|
||||
break;
|
||||
|
||||
/* We can only get here if we hit a P2P bridge with no node,
|
||||
* let's do standard swizzling and try again
|
||||
*/
|
||||
lspec = pci_swizzle_interrupt_pin(pdev, lspec);
|
||||
pdev = ppdev;
|
||||
}
|
||||
|
||||
laddr[0] = (pdev->bus->number << 16)
|
||||
| (pdev->devfn << 8);
|
||||
laddr[1] = laddr[2] = 0;
|
||||
return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||
|
||||
+5
-17
@@ -386,6 +386,8 @@ config X86_INTEL_CE
|
||||
depends on X86_32
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
select X86_REBOOTFIXUPS
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
---help---
|
||||
Select for the Intel CE media processor (CE4100) SOC.
|
||||
This option compiles in support for the CE4100 SOC for settop
|
||||
@@ -2070,9 +2072,10 @@ config SCx200HR_TIMER
|
||||
|
||||
config OLPC
|
||||
bool "One Laptop Per Child support"
|
||||
depends on !X86_PAE
|
||||
select GPIOLIB
|
||||
select OLPC_OPENFIRMWARE
|
||||
depends on !X86_64 && !X86_PAE
|
||||
select OF
|
||||
select OF_PROMTREE if PROC_DEVICETREE
|
||||
---help---
|
||||
Add support for detecting the unique features of the OLPC
|
||||
XO hardware.
|
||||
@@ -2083,21 +2086,6 @@ config OLPC_XO1
|
||||
---help---
|
||||
Add support for non-essential features of the OLPC XO-1 laptop.
|
||||
|
||||
config OLPC_OPENFIRMWARE
|
||||
bool "Support for OLPC's Open Firmware"
|
||||
depends on !X86_64 && !X86_PAE
|
||||
default n
|
||||
select OF
|
||||
help
|
||||
This option adds support for the implementation of Open Firmware
|
||||
that is used on the OLPC XO-1 Children's Machine.
|
||||
If unsure, say N here.
|
||||
|
||||
config OLPC_OPENFIRMWARE_DT
|
||||
bool
|
||||
default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE
|
||||
select OF_PROMTREE
|
||||
|
||||
endif # X86_32
|
||||
|
||||
config AMD_NB
|
||||
|
||||
@@ -220,7 +220,6 @@ extern void enable_IR_x2apic(void);
|
||||
|
||||
extern int get_physical_broadcast(void);
|
||||
|
||||
extern void apic_disable(void);
|
||||
extern int lapic_get_maxlvt(void);
|
||||
extern void clear_local_APIC(void);
|
||||
extern void connect_bsp_APIC(void);
|
||||
@@ -228,7 +227,6 @@ extern void disconnect_bsp_APIC(int virt_wire_setup);
|
||||
extern void disable_local_APIC(void);
|
||||
extern void lapic_shutdown(void);
|
||||
extern int verify_local_APIC(void);
|
||||
extern void cache_APIC_registers(void);
|
||||
extern void sync_Arb_IDs(void);
|
||||
extern void init_bsp_APIC(void);
|
||||
extern void setup_local_APIC(void);
|
||||
@@ -239,8 +237,7 @@ void register_lapic_address(unsigned long address);
|
||||
extern void setup_boot_APIC_clock(void);
|
||||
extern void setup_secondary_APIC_clock(void);
|
||||
extern int APIC_init_uniprocessor(void);
|
||||
extern void enable_NMI_through_LVT0(void);
|
||||
extern int apic_force_enable(void);
|
||||
extern int apic_force_enable(unsigned long addr);
|
||||
|
||||
/*
|
||||
* On 32bit this is mach-xxx local
|
||||
@@ -261,7 +258,6 @@ static inline void lapic_shutdown(void) { }
|
||||
#define local_apic_timer_c2_ok 1
|
||||
static inline void init_apic_mappings(void) { }
|
||||
static inline void disable_local_APIC(void) { }
|
||||
static inline void apic_disable(void) { }
|
||||
# define setup_boot_APIC_clock x86_init_noop
|
||||
# define setup_secondary_APIC_clock x86_init_noop
|
||||
#endif /* !CONFIG_X86_LOCAL_APIC */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
/* setup data types */
|
||||
#define SETUP_NONE 0
|
||||
#define SETUP_E820_EXT 1
|
||||
#define SETUP_DTB 2
|
||||
|
||||
/* extensible setup data list node */
|
||||
struct setup_data {
|
||||
|
||||
@@ -96,7 +96,7 @@ extern void e820_setup_gap(void);
|
||||
extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
|
||||
unsigned long start_addr, unsigned long long end_addr);
|
||||
struct setup_data;
|
||||
extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
|
||||
extern void parse_e820_ext(struct setup_data *data);
|
||||
|
||||
#if defined(CONFIG_X86_64) || \
|
||||
(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
#include <asm/apicdef.h>
|
||||
#include <asm/irq_vectors.h>
|
||||
|
||||
/* Even though we don't support this, supply it to appease OF */
|
||||
static inline void irq_dispose_mapping(unsigned int virq) { }
|
||||
|
||||
static inline int irq_canonicalize(int irq)
|
||||
{
|
||||
return ((irq == 2) ? 9 : irq);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef __IRQ_CONTROLLER__
|
||||
#define __IRQ_CONTROLLER__
|
||||
|
||||
struct irq_domain {
|
||||
int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
|
||||
u32 *out_hwirq, u32 *out_type);
|
||||
void *priv;
|
||||
struct device_node *controller;
|
||||
struct list_head l;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define OLPC_OFW_SIG 0x2057464F /* aka "OFW " */
|
||||
|
||||
#ifdef CONFIG_OLPC_OPENFIRMWARE
|
||||
#ifdef CONFIG_OLPC
|
||||
|
||||
extern bool olpc_ofw_is_installed(void);
|
||||
|
||||
@@ -26,19 +26,15 @@ extern void setup_olpc_ofw_pgd(void);
|
||||
/* check if OFW was detected during boot */
|
||||
extern bool olpc_ofw_present(void);
|
||||
|
||||
#else /* !CONFIG_OLPC_OPENFIRMWARE */
|
||||
|
||||
static inline bool olpc_ofw_is_installed(void) { return false; }
|
||||
#else /* !CONFIG_OLPC */
|
||||
static inline void olpc_ofw_detect(void) { }
|
||||
static inline void setup_olpc_ofw_pgd(void) { }
|
||||
static inline bool olpc_ofw_present(void) { return false; }
|
||||
#endif /* !CONFIG_OLPC */
|
||||
|
||||
#endif /* !CONFIG_OLPC_OPENFIRMWARE */
|
||||
|
||||
#ifdef CONFIG_OLPC_OPENFIRMWARE_DT
|
||||
#ifdef CONFIG_OF_PROMTREE
|
||||
extern void olpc_dt_build_devicetree(void);
|
||||
#else
|
||||
static inline void olpc_dt_build_devicetree(void) { }
|
||||
#endif /* CONFIG_OLPC_OPENFIRMWARE_DT */
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_OLPC_OFW_H */
|
||||
|
||||
@@ -1 +1,69 @@
|
||||
/* dummy prom.h; here to make linux/of.h's #includes happy */
|
||||
/*
|
||||
* Definitions for Device tree / OpenFirmware handling on X86
|
||||
*
|
||||
* based on arch/powerpc/include/asm/prom.h which is
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_PROM_H
|
||||
#define _ASM_X86_PROM_H
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/irq_controller.h>
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
extern int of_ioapic;
|
||||
extern u64 initial_dtb;
|
||||
extern void add_dtb(u64 data);
|
||||
extern void x86_add_irq_domains(void);
|
||||
void __cpuinit x86_of_pci_init(void);
|
||||
void x86_dtb_init(void);
|
||||
|
||||
static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev ? pdev->dev.of_node : NULL;
|
||||
}
|
||||
|
||||
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
|
||||
{
|
||||
return pci_device_to_OF_node(bus->self);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void add_dtb(u64 data) { }
|
||||
static inline void x86_add_irq_domains(void) { }
|
||||
static inline void x86_of_pci_init(void) { }
|
||||
static inline void x86_dtb_init(void) { }
|
||||
#define of_ioapic 0
|
||||
#endif
|
||||
|
||||
extern char cmd_line[COMMAND_LINE_SIZE];
|
||||
|
||||
#define pci_address_to_pio pci_address_to_pio
|
||||
unsigned long pci_address_to_pio(phys_addr_t addr);
|
||||
|
||||
/**
|
||||
* irq_dispose_mapping - Unmap an interrupt
|
||||
* @virq: linux virq number of the interrupt to unmap
|
||||
*
|
||||
* FIXME: We really should implement proper virq handling like power,
|
||||
* but that's going to be major surgery.
|
||||
*/
|
||||
static inline void irq_dispose_mapping(unsigned int virq) { }
|
||||
|
||||
#define HAVE_ARCH_DEVTREE_FIXUPS
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif
|
||||
|
||||
@@ -83,11 +83,13 @@ struct x86_init_paging {
|
||||
* boot cpu
|
||||
* @tsc_pre_init: platform function called before TSC init
|
||||
* @timer_init: initialize the platform timer (default PIT/HPET)
|
||||
* @wallclock_init: init the wallclock device
|
||||
*/
|
||||
struct x86_init_timers {
|
||||
void (*setup_percpu_clockev)(void);
|
||||
void (*tsc_pre_init)(void);
|
||||
void (*timer_init)(void);
|
||||
void (*wallclock_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,9 +66,9 @@ obj-$(CONFIG_PCI) += early-quirks.o
|
||||
apm-y := apm_32.o
|
||||
obj-$(CONFIG_APM) += apm.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o
|
||||
obj-$(CONFIG_SMP) += smpboot.o
|
||||
obj-$(CONFIG_SMP) += tsc_sync.o
|
||||
obj-$(CONFIG_SMP) += setup_percpu.o
|
||||
obj-$(CONFIG_X86_64_SMP) += tsc_sync.o
|
||||
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
|
||||
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
|
||||
obj-y += apic/
|
||||
@@ -109,6 +109,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o
|
||||
obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
|
||||
|
||||
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
|
||||
obj-$(CONFIG_OF) += devicetree.o
|
||||
|
||||
###
|
||||
# 64 bit specific files
|
||||
|
||||
@@ -508,64 +508,12 @@ static int apbt_next_event(unsigned long delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* APB timer clock is not in sync with pclk on Langwell, which translates to
|
||||
* unreliable read value caused by sampling error. the error does not add up
|
||||
* overtime and only happens when sampling a 0 as a 1 by mistake. so the time
|
||||
* would go backwards. the following code is trying to prevent time traveling
|
||||
* backwards. little bit paranoid.
|
||||
*/
|
||||
static cycle_t apbt_read_clocksource(struct clocksource *cs)
|
||||
{
|
||||
unsigned long t0, t1, t2;
|
||||
static unsigned long last_read;
|
||||
unsigned long current_count;
|
||||
|
||||
bad_count:
|
||||
t1 = apbt_readl(phy_cs_timer_id,
|
||||
APBTMR_N_CURRENT_VALUE);
|
||||
t2 = apbt_readl(phy_cs_timer_id,
|
||||
APBTMR_N_CURRENT_VALUE);
|
||||
if (unlikely(t1 < t2)) {
|
||||
pr_debug("APBT: read current count error %lx:%lx:%lx\n",
|
||||
t1, t2, t2 - t1);
|
||||
goto bad_count;
|
||||
}
|
||||
/*
|
||||
* check against cached last read, makes sure time does not go back.
|
||||
* it could be a normal rollover but we will do tripple check anyway
|
||||
*/
|
||||
if (unlikely(t2 > last_read)) {
|
||||
/* check if we have a normal rollover */
|
||||
unsigned long raw_intr_status =
|
||||
apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
|
||||
/*
|
||||
* cs timer interrupt is masked but raw intr bit is set if
|
||||
* rollover occurs. then we read EOI reg to clear it.
|
||||
*/
|
||||
if (raw_intr_status & (1 << phy_cs_timer_id)) {
|
||||
apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
|
||||
goto out;
|
||||
}
|
||||
pr_debug("APB CS going back %lx:%lx:%lx ",
|
||||
t2, last_read, t2 - last_read);
|
||||
bad_count_x3:
|
||||
pr_debug("triple check enforced\n");
|
||||
t0 = apbt_readl(phy_cs_timer_id,
|
||||
APBTMR_N_CURRENT_VALUE);
|
||||
udelay(1);
|
||||
t1 = apbt_readl(phy_cs_timer_id,
|
||||
APBTMR_N_CURRENT_VALUE);
|
||||
udelay(1);
|
||||
t2 = apbt_readl(phy_cs_timer_id,
|
||||
APBTMR_N_CURRENT_VALUE);
|
||||
if ((t2 > t1) || (t1 > t0)) {
|
||||
printk(KERN_ERR "Error: APB CS tripple check failed\n");
|
||||
goto bad_count_x3;
|
||||
}
|
||||
}
|
||||
out:
|
||||
last_read = t2;
|
||||
return (cycle_t)~t2;
|
||||
current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE);
|
||||
return (cycle_t)~current_count;
|
||||
}
|
||||
|
||||
static int apbt_clocksource_register(void)
|
||||
|
||||
+24
-45
@@ -93,7 +93,7 @@ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID);
|
||||
*
|
||||
* +1=force-enable
|
||||
*/
|
||||
static int force_enable_local_apic;
|
||||
static int force_enable_local_apic __initdata;
|
||||
/*
|
||||
* APIC command line parameters
|
||||
*/
|
||||
@@ -163,7 +163,7 @@ early_param("nox2apic", setup_nox2apic);
|
||||
unsigned long mp_lapic_addr;
|
||||
int disable_apic;
|
||||
/* Disable local APIC timer from the kernel commandline or via dmi quirk */
|
||||
static int disable_apic_timer __cpuinitdata;
|
||||
static int disable_apic_timer __initdata;
|
||||
/* Local APIC timer works in C2 */
|
||||
int local_apic_timer_c2_ok;
|
||||
EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
|
||||
@@ -187,29 +187,8 @@ static struct resource lapic_resource = {
|
||||
|
||||
static unsigned int calibration_result;
|
||||
|
||||
static int lapic_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt);
|
||||
static void lapic_timer_setup(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt);
|
||||
static void lapic_timer_broadcast(const struct cpumask *mask);
|
||||
static void apic_pm_activate(void);
|
||||
|
||||
/*
|
||||
* The local apic timer can be used for any function which is CPU local.
|
||||
*/
|
||||
static struct clock_event_device lapic_clockevent = {
|
||||
.name = "lapic",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
|
||||
| CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
|
||||
.shift = 32,
|
||||
.set_mode = lapic_timer_setup,
|
||||
.set_next_event = lapic_next_event,
|
||||
.broadcast = lapic_timer_broadcast,
|
||||
.rating = 100,
|
||||
.irq = -1,
|
||||
};
|
||||
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
|
||||
|
||||
static unsigned long apic_phys;
|
||||
|
||||
/*
|
||||
@@ -248,7 +227,7 @@ static int modern_apic(void)
|
||||
* right after this call apic become NOOP driven
|
||||
* so apic->write/read doesn't do anything
|
||||
*/
|
||||
void apic_disable(void)
|
||||
static void __init apic_disable(void)
|
||||
{
|
||||
pr_info("APIC: switched to apic NOOP\n");
|
||||
apic = &apic_noop;
|
||||
@@ -292,23 +271,6 @@ u64 native_apic_icr_read(void)
|
||||
return icr1 | ((u64)icr2 << 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* enable_NMI_through_LVT0 - enable NMI through local vector table 0
|
||||
*/
|
||||
void __cpuinit enable_NMI_through_LVT0(void)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
/* unmask and set to NMI */
|
||||
v = APIC_DM_NMI;
|
||||
|
||||
/* Level triggered for 82489DX (32bit mode) */
|
||||
if (!lapic_is_integrated())
|
||||
v |= APIC_LVT_LEVEL_TRIGGER;
|
||||
|
||||
apic_write(APIC_LVT0, v);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/**
|
||||
* get_physical_broadcast - Get number of physical broadcast IDs
|
||||
@@ -518,6 +480,23 @@ static void lapic_timer_broadcast(const struct cpumask *mask)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The local apic timer can be used for any function which is CPU local.
|
||||
*/
|
||||
static struct clock_event_device lapic_clockevent = {
|
||||
.name = "lapic",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
|
||||
| CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
|
||||
.shift = 32,
|
||||
.set_mode = lapic_timer_setup,
|
||||
.set_next_event = lapic_next_event,
|
||||
.broadcast = lapic_timer_broadcast,
|
||||
.rating = 100,
|
||||
.irq = -1,
|
||||
};
|
||||
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
|
||||
|
||||
/*
|
||||
* Setup the local APIC timer for this CPU. Copy the initialized values
|
||||
* of the boot CPU and register the clock event in the framework.
|
||||
@@ -1560,7 +1539,7 @@ static int __init detect_init_APIC(void)
|
||||
}
|
||||
#else
|
||||
|
||||
static int apic_verify(void)
|
||||
static int __init apic_verify(void)
|
||||
{
|
||||
u32 features, h, l;
|
||||
|
||||
@@ -1585,7 +1564,7 @@ static int apic_verify(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apic_force_enable(void)
|
||||
int __init apic_force_enable(unsigned long addr)
|
||||
{
|
||||
u32 h, l;
|
||||
|
||||
@@ -1601,7 +1580,7 @@ int apic_force_enable(void)
|
||||
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
|
||||
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
|
||||
l &= ~MSR_IA32_APICBASE_BASE;
|
||||
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
|
||||
l |= MSR_IA32_APICBASE_ENABLE | addr;
|
||||
wrmsr(MSR_IA32_APICBASE, l, h);
|
||||
enabled_via_apicbase = 1;
|
||||
}
|
||||
@@ -1642,7 +1621,7 @@ static int __init detect_init_APIC(void)
|
||||
"you can enable it with \"lapic\"\n");
|
||||
return -1;
|
||||
}
|
||||
if (apic_force_enable())
|
||||
if (apic_force_enable(APIC_DEFAULT_PHYS_BASE))
|
||||
return -1;
|
||||
} else {
|
||||
if (apic_verify())
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user