diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/earlyquirk.c | 7 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_acpi_init.c | 44 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/mips/dec/prom/init.c | 3 | ||||
-rw-r--r-- | arch/mips/sibyte/Kconfig | 22 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/bcm1250_tbprof.c | 377 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/setup.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_parse.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/83xx/mpc834x_mds.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/celleb/scc_epci.c | 82 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/feature.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 7 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/early-quirks.c | 9 |
18 files changed, 431 insertions, 182 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index e5eb97a910ed..9ea5b8ecc7e1 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -1072,7 +1072,28 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { "ASUS A7V ACPI BIOS Revision 1007"), }, }, - + { + /* + * Latest BIOS for IBM 600E (1.16) has bad pcinum + * for LPC bridge, which is needed for the PCI + * interrupt links to work. DSDT fix is in bug 5966. + * 2645, 2646 model numbers are shared with 600/600E/600X + */ + .callback = disable_acpi_irq, + .ident = "IBM Thinkpad 600 Series 2645", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2645"), + }, + }, + { + .callback = disable_acpi_irq, + .ident = "IBM Thinkpad 600 Series 2646", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2646"), + }, + }, /* * Boxes that need ACPI PCI IRQ routing and PCI scan disabled */ diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index bf86f7662d8b..a7d22d9f3d7e 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -14,11 +14,8 @@ #ifdef CONFIG_ACPI -static int nvidia_hpet_detected __initdata; - static int __init nvidia_hpet_check(struct acpi_table_header *header) { - nvidia_hpet_detected = 1; return 0; } #endif @@ -29,9 +26,7 @@ static int __init check_bridge(int vendor, int device) /* According to Nvidia all timer overrides are bogus unless HPET is enabled. */ if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { + if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " "detected. Ignoring ACPI " diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index 8c331ca6e5c9..c6216f454ffb 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -53,12 +53,15 @@ sal_ioif_init(u64 *result) } /* - * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver. - * Called for every "SGIHUB" or "SGITIO" device defined - * in the ACPI namespace. + * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback() + * for all SGIHUB and SGITIO acpi devices defined in the + * DSDT. It obtains the hubdev_info pointer from the + * ACPI vendor resource, which the PROM setup, and sets up the + * hubdev_info in the pda. */ -static int __init -sn_hubdev_add(struct acpi_device *device) + +static acpi_status __init +sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; u64 addr; @@ -67,18 +70,19 @@ sn_hubdev_add(struct acpi_device *device) int i; u64 nasid; struct acpi_resource *resource; - int ret = 0; acpi_status status; struct acpi_resource_vendor_typed *vendor; extern void sn_common_hubdev_init(struct hubdev_info *); - status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS, + status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR - "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n", - status); - return 1; + "sn_acpi_hubdev_init: acpi_get_vendor_resource() " + "(0x%x) failed for: ", status); + acpi_ns_print_node_pathname(handle, NULL); + printk("\n"); + return AE_OK; /* Continue walking namespace */ } resource = buffer.pointer; @@ -86,9 +90,10 @@ sn_hubdev_add(struct acpi_device *device) if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != sizeof(struct hubdev_info *)) { printk(KERN_ERR - "sn_hubdev_add: Invalid vendor data length: %d\n", + "sn_acpi_hubdev_init: Invalid vendor data length: %d for: ", vendor->byte_length); - ret = 1; + acpi_ns_print_node_pathname(handle, NULL); + printk("\n"); goto exit; } @@ -103,7 +108,7 @@ sn_hubdev_add(struct acpi_device *device) exit: kfree(buffer.pointer); - return ret; + return AE_OK; /* Continue walking namespace */ } /* @@ -441,14 +446,6 @@ sn_acpi_slot_fixup(struct pci_dev *dev) EXPORT_SYMBOL(sn_acpi_slot_fixup); -static struct acpi_driver acpi_sn_hubdev_driver = { - .name = "SGI HUBDEV Driver", - .ids = "SGIHUB,SGITIO", - .ops = { - .add = sn_hubdev_add, - }, -}; - /* * sn_acpi_bus_fixup - Perform SN specific setup of software structs @@ -492,7 +489,10 @@ sn_io_acpi_init(void) /* SN Altix does not follow the IOSAPIC IRQ routing model */ acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; - acpi_bus_register_driver(&acpi_sn_hubdev_driver); + /* Setup hubdev_info for all SGIHUB/SGITIO devices */ + acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL); + acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL); + status = sal_ioif_init(&result); if (status || result) panic("sal_ioif_init failed: [%lx] %s\n", diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 8571e52c2efd..bd5373d593e1 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -397,6 +397,8 @@ void __init sn_setup(char **cmdline_p) ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE); ia64_sn_set_os_feature(OSF_ACPI_ENABLE); + /* Load the new DSDT and SSDT tables into the global table list. */ + acpi_table_init(); #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) /* diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c index bf2858071f1f..a217aafe59f6 100644 --- a/arch/mips/dec/prom/init.c +++ b/arch/mips/dec/prom/init.c @@ -103,9 +103,6 @@ void __init prom_init(void) if (prom_is_rex(magic)) rex_clear_cache(); - /* Register the early console. */ - register_prom_console(); - /* Were we compiled with the right CPU option? */ #if defined(CONFIG_CPU_R3000) if ((current_cpu_data.cputype == CPU_R4000SC) || diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 67dac6204b6d..bdf24a7b5494 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -1,31 +1,35 @@ config SIBYTE_SB1250 bool select HW_HAS_PCI - select SIBYTE_HAS_LDT + select SIBYTE_ENABLE_LDT_IF_PCI select SIBYTE_SB1xxx_SOC select SYS_SUPPORTS_SMP config SIBYTE_BCM1120 bool select SIBYTE_BCM112X + select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC config SIBYTE_BCM1125 bool select HW_HAS_PCI select SIBYTE_BCM112X + select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC config SIBYTE_BCM1125H bool select HW_HAS_PCI select SIBYTE_BCM112X - select SIBYTE_HAS_LDT + select SIBYTE_ENABLE_LDT_IF_PCI + select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC config SIBYTE_BCM112X bool select SIBYTE_SB1xxx_SOC + select SIBYTE_HAS_ZBUS_PROFILING config SIBYTE_BCM1x80 bool @@ -37,6 +41,7 @@ config SIBYTE_BCM1x55 bool select HW_HAS_PCI select SIBYTE_SB1xxx_SOC + select SIBYTE_HAS_ZBUS_PROFILING select SYS_SUPPORTS_SMP config SIBYTE_SB1xxx_SOC @@ -95,8 +100,10 @@ config CPU_SB1_PASS_2 config SIBYTE_HAS_LDT bool - depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) - default y + +config SIBYTE_ENABLE_LDT_IF_PCI + bool + select SIBYTE_HAS_LDT if PCI config SIMULATION bool "Running under simulation" @@ -162,5 +169,8 @@ config SIBYTE_SB1250_PROF depends on SIBYTE_SB1xxx_SOC config SIBYTE_TBPROF - bool "Support for ZBbus profiling" - depends on SIBYTE_SB1xxx_SOC + tristate "Support for ZBbus profiling" + depends on SIBYTE_HAS_ZBUS_PROFILING + +config SIBYTE_HAS_ZBUS_PROFILING + bool diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c index 212547c57310..ea0ca131a3cf 100644 --- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c @@ -1,6 +1,4 @@ /* - * Copyright (C) 2001, 2002, 2003 Broadcom Corporation - * * 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 @@ -14,10 +12,16 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> + * Copyright (C) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle <ralf@linux-mips.org> */ -#define SBPROF_TB_DEBUG 0 +#undef DEBUG +#include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -27,24 +31,98 @@ #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/errno.h> -#include <linux/reboot.h> -#include <linux/smp_lock.h> +#include <linux/types.h> #include <linux/wait.h> -#include <asm/uaccess.h> + #include <asm/io.h> #include <asm/sibyte/sb1250.h> #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_scd.h> #include <asm/sibyte/sb1250_int.h> -#include <asm/sibyte/trace_prof.h> +#include <asm/system.h> +#include <asm/uaccess.h> -#define DEVNAME "bcm1250_tbprof" +#define SBPROF_TB_MAJOR 240 + +typedef u64 tb_sample_t[6*256]; + +enum open_status { + SB_CLOSED, + SB_OPENING, + SB_OPEN +}; + +struct sbprof_tb { + wait_queue_head_t tb_sync; + wait_queue_head_t tb_read; + struct mutex lock; + enum open_status open; + tb_sample_t *sbprof_tbbuf; + int next_tb_sample; + + volatile int tb_enable; + volatile int tb_armed; + +}; static struct sbprof_tb sbp; +#define MAX_SAMPLE_BYTES (24*1024*1024) +#define MAX_TBSAMPLE_BYTES (12*1024*1024) + +#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) +#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) +#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) + +/* ioctls */ +#define SBPROF_ZBSTART _IOW('s', 0, int) +#define SBPROF_ZBSTOP _IOW('s', 1, int) +#define SBPROF_ZBWAITFULL _IOW('s', 2, int) + +/* + * Routines for using 40-bit SCD cycle counter + * + * Client responsible for either handling interrupts or making sure + * the cycles counter never saturates, e.g., by doing + * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. + */ + +/* + * Configures SCD counter 0 to count ZCLKs starting from val; + * Configures SCD counters1,2,3 to count nothing. + * Must not be called while gathering ZBbus profiles. + */ + +#define zclk_timer_init(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "sd %0, 0x10($8);" /* write val to counter0 */ \ + "sd %1, 0($8);" /* config counter0 for zclks*/ \ + ".set pop" \ + : /* no outputs */ \ + /* enable, counter0 */ \ + : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ + : /* modifies */ "$8" ) + + +/* Reads SCD counter 0 and puts result in value + unsigned long long val; */ +#define zclk_get(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "ld %0, 0x10($8);" /* write val to counter0 */ \ + ".set pop" \ + : /* outputs */ "=r"(val) \ + : /* inputs */ \ + : /* modifies */ "$8" ) + +#define DEVNAME "bcm1250_tbprof" + #define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) -/************************************************************************ +/* * Support for ZBbus sampling using the trace buffer * * We use the SCD performance counter interrupt, caused by a Zclk counter @@ -54,30 +132,36 @@ static struct sbprof_tb sbp; * overflow. * * We map the interrupt for trace_buffer_freeze to handle it on CPU 0. - * - ************************************************************************/ + */ -static u_int64_t tb_period; +static u64 tb_period; static void arm_tb(void) { - u_int64_t scdperfcnt; - u_int64_t next = (1ULL << 40) - tb_period; - u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; - /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to - trigger start of trace. XXX vary sampling period */ + u64 scdperfcnt; + u64 next = (1ULL << 40) - tb_period; + u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; + + /* + * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger + *start of trace. XXX vary sampling period + */ __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); - /* Unfortunately, in Pass 2 we must clear all counters to knock down - a previous interrupt request. This means that bus profiling - requires ALL of the SCD perf counters. */ + + /* + * Unfortunately, in Pass 2 we must clear all counters to knock down a + * previous interrupt request. This means that bus profiling requires + * ALL of the SCD perf counters. + */ __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | - // keep counters 0,2,3 as is - M_SPC_CFG_ENABLE | // enable counting - M_SPC_CFG_CLEAR | // clear all counters - V_SPC_CFG_SRC1(1), // counter 1 counts cycles + /* keep counters 0,2,3 as is */ + M_SPC_CFG_ENABLE | /* enable counting */ + M_SPC_CFG_CLEAR | /* clear all counters */ + V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */ IOADDR(A_SCD_PERF_CNT_CFG)); __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); + /* Reset the trace buffer */ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) @@ -91,43 +175,45 @@ static void arm_tb(void) static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) { int i; - DBG(printk(DEVNAME ": tb_intr\n")); + + pr_debug(DEVNAME ": tb_intr\n"); + if (sbp.next_tb_sample < MAX_TB_SAMPLES) { /* XXX should use XKPHYS to make writes bypass L2 */ - u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; + u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; /* Read out trace */ __raw_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG)); __asm__ __volatile__ ("sync" : : : "memory"); /* Loop runs backwards because bundles are read out in reverse order */ for (i = 256 * 6; i > 0; i -= 6) { - // Subscripts decrease to put bundle in the order - // t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi + /* Subscripts decrease to put bundle in the order */ + /* t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */ p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t2 hi + /* read t2 hi */ p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t2 lo + /* read t2 lo */ p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t1 hi + /* read t1 hi */ p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t1 lo + /* read t1 lo */ p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t0 hi + /* read t0 hi */ p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - // read t0 lo + /* read t0 lo */ } if (!sbp.tb_enable) { - DBG(printk(DEVNAME ": tb_intr shutdown\n")); + pr_debug(DEVNAME ": tb_intr shutdown\n"); __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); sbp.tb_armed = 0; wake_up(&sbp.tb_sync); } else { - arm_tb(); // knock down current interrupt and get another one later + arm_tb(); /* knock down current interrupt and get another one later */ } } else { /* No more trace buffer samples */ - DBG(printk(DEVNAME ": tb_intr full\n")); + pr_debug(DEVNAME ": tb_intr full\n"); __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); sbp.tb_armed = 0; if (!sbp.tb_enable) { @@ -135,6 +221,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) } wake_up(&sbp.tb_read); } + return IRQ_HANDLED; } @@ -144,23 +231,30 @@ static irqreturn_t sbprof_pc_intr(int irq, void *dev_id) return IRQ_NONE; } -int sbprof_zbprof_start(struct file *filp) +/* + * Requires: Already called zclk_timer_init with a value that won't + * saturate 40 bits. No subsequent use of SCD performance counters + * or trace buffer. + */ + +static int sbprof_zbprof_start(struct file *filp) { - u_int64_t scdperfcnt; + u64 scdperfcnt; + int err; - if (sbp.tb_enable) + if (xchg(&sbp.tb_enable, 1)) return -EBUSY; - DBG(printk(DEVNAME ": starting\n")); + pr_debug(DEVNAME ": starting\n"); - sbp.tb_enable = 1; sbp.next_tb_sample = 0; filp->f_pos = 0; - if (request_irq - (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) { + err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, + DEVNAME " trace freeze", &sbp); + if (err) return -EBUSY; - } + /* Make sure there isn't a perf-cnt interrupt waiting */ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); /* Disable and clear counters, override SRC_1 */ @@ -168,18 +262,21 @@ int sbprof_zbprof_start(struct file *filp) M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1), IOADDR(A_SCD_PERF_CNT_CFG)); - /* We grab this interrupt to prevent others from trying to use - it, even though we don't want to service the interrupts - (they only feed into the trace-on-interrupt mechanism) */ - if (request_irq - (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { - free_irq(K_INT_TRACE_FREEZE, &sbp); - return -EBUSY; - } - - /* I need the core to mask these, but the interrupt mapper to - pass them through. I am exploiting my knowledge that - cp0_status masks out IP[5]. krw */ + /* + * We grab this interrupt to prevent others from trying to use it, even + * though we don't want to service the interrupts (they only feed into + * the trace-on-interrupt mechanism) + */ + err = request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0, + DEVNAME " scd perfcnt", &sbp); + if (err) + goto out_free_irq; + + /* + * I need the core to mask these, but the interrupt mapper to pass them + * through. I am exploiting my knowledge that cp0_status masks out + * IP[5]. krw + */ __raw_writeq(K_INT_MAP_I3, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_PERF_CNT << 3))); @@ -201,7 +298,7 @@ int sbprof_zbprof_start(struct file *filp) __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); /* Initialize Trace Event 0-7 */ - // when interrupt + /* when interrupt */ __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); @@ -212,10 +309,10 @@ int sbprof_zbprof_start(struct file *filp) __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); /* Initialize Trace Sequence 0-7 */ - // Start on event 0 (interrupt) + /* Start on event 0 (interrupt) */ __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, IOADDR(A_SCD_TRACE_SEQUENCE_0)); - // dsamp when d used | asamp when a used + /* dsamp when d used | asamp when a used */ __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | K_SCD_TRSEQ_TRIGGER_ALL, IOADDR(A_SCD_TRACE_SEQUENCE_1)); @@ -232,33 +329,41 @@ int sbprof_zbprof_start(struct file *filp) arm_tb(); - DBG(printk(DEVNAME ": done starting\n")); + pr_debug(DEVNAME ": done starting\n"); return 0; + +out_free_irq: + free_irq(K_INT_TRACE_FREEZE, &sbp); + + return err; } -int sbprof_zbprof_stop(void) +static int sbprof_zbprof_stop(void) { - DEFINE_WAIT(wait); - DBG(printk(DEVNAME ": stopping\n")); + int err; + + pr_debug(DEVNAME ": stopping\n"); if (sbp.tb_enable) { + /* + * XXXKW there is a window here where the intr handler may run, + * see the disable, and do the wake_up before this sleep + * happens. + */ + pr_debug(DEVNAME ": wait for disarm\n"); + err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed); + pr_debug(DEVNAME ": disarm complete, stat %d\n", err); + + if (err) + return err; + sbp.tb_enable = 0; - /* XXXKW there is a window here where the intr handler - may run, see the disable, and do the wake_up before - this sleep happens. */ - if (sbp.tb_armed) { - DBG(printk(DEVNAME ": wait for disarm\n")); - prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&sbp.tb_sync, &wait); - DBG(printk(DEVNAME ": disarm complete\n")); - } free_irq(K_INT_TRACE_FREEZE, &sbp); free_irq(K_INT_PERF_CNT, &sbp); } - DBG(printk(DEVNAME ": done stopping\n")); + pr_debug(DEVNAME ": done stopping\n"); return 0; } @@ -268,42 +373,45 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp) int minor; minor = iminor(inode); - if (minor != 0) { + if (minor != 0) return -ENODEV; - } - if (sbp.open) { + + if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) return -EBUSY; - } memset(&sbp, 0, sizeof(struct sbprof_tb)); + sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); - if (!sbp.sbprof_tbbuf) { + if (!sbp.sbprof_tbbuf) return -ENOMEM; - } + memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); init_waitqueue_head(&sbp.tb_sync); init_waitqueue_head(&sbp.tb_read); - sbp.open = 1; + mutex_init(&sbp.lock); + + sbp.open = SB_OPEN; return 0; } static int sbprof_tb_release(struct inode *inode, struct file *filp) { - int minor; + int minor = iminor(inode); - minor = iminor(inode); - if (minor != 0 || !sbp.open) { + if (minor != 0 || !sbp.open) return -ENODEV; - } - if (sbp.tb_armed || sbp.tb_enable) { + mutex_lock(&sbp.lock); + + if (sbp.tb_armed || sbp.tb_enable) sbprof_zbprof_stop(); - } vfree(sbp.sbprof_tbbuf); sbp.open = 0; + mutex_unlock(&sbp.lock); + return 0; } @@ -311,21 +419,35 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf, size_t size, loff_t *offp) { int cur_sample, sample_off, cur_count, sample_left; - char *src; - int count = 0; - char *dest = buf; long cur_off = *offp; + char *dest = buf; + int count = 0; + char *src; + + if (!access_ok(VERIFY_WRITE, buf, size)) + return -EFAULT; + + mutex_lock(&sbp.lock); count = 0; cur_sample = cur_off / TB_SAMPLE_SIZE; sample_off = cur_off % TB_SAMPLE_SIZE; sample_left = TB_SAMPLE_SIZE - sample_off; + while (size && (cur_sample < sbp.next_tb_sample)) { + int err; + cur_count = size < sample_left ? size : sample_left; src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); - copy_to_user(dest, src, cur_count); - DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", - cur_sample, cur_count)); + err = __copy_to_user(dest, src, cur_count); + if (err) { + *offp = cur_off + cur_count - err; + mutex_unlock(&sbp.lock); + return err; + } + + pr_debug(DEVNAME ": read from sample %d, %d bytes\n", + cur_sample, cur_count); size -= cur_count; sample_left -= cur_count; if (!sample_left) { @@ -339,37 +461,43 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf, dest += cur_count; count += cur_count; } + *offp = cur_off; + mutex_unlock(&sbp.lock); return count; } -static long sbprof_tb_ioctl(struct file *filp, - unsigned int command, - unsigned long arg) +static long sbprof_tb_ioctl(struct file *filp, unsigned int command, + unsigned long arg) { int error = 0; - lock_kernel(); switch (command) { case SBPROF_ZBSTART: + mutex_lock(&sbp.lock); error = sbprof_zbprof_start(filp); + mutex_unlock(&sbp.lock); break; + case SBPROF_ZBSTOP: + mutex_lock(&sbp.lock); error = sbprof_zbprof_stop(); + mutex_unlock(&sbp.lock); break; + case SBPROF_ZBWAITFULL: - DEFINE_WAIT(wait); - prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&sbp.tb_read, &wait); - /* XXXKW check if interrupted? */ - return put_user(TB_FULL, (int *) arg); + error = wait_event_interruptible(sbp.tb_read, TB_FULL); + if (error) + break; + + error = put_user(TB_FULL, (int *) arg); + break; + default: error = -EINVAL; break; } - unlock_kernel(); return error; } @@ -384,23 +512,60 @@ static const struct file_operations sbprof_tb_fops = { .mmap = NULL, }; +static struct class *tb_class; +static struct device *tb_dev; + static int __init sbprof_tb_init(void) { + struct device *dev; + struct class *tbc; + int err; + if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) { printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n", SBPROF_TB_MAJOR); return -EIO; } + + tbc = class_create(THIS_MODULE, "sb_tracebuffer"); + if (IS_ERR(tbc)) { + err = PTR_ERR(tbc); + goto out_chrdev; + } + + tb_class = tbc; + + dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb"); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_class; + } + tb_dev = dev; + sbp.open = 0; tb_period = zbbus_mhz * 10000LL; - printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period); + pr_info(DEVNAME ": initialized - tb_period = %lld\n", tb_period); + return 0; + +out_class: + class_destroy(tb_class); +out_chrdev: + unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); + + return err; } static void __exit sbprof_tb_cleanup(void) { + device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0)); unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); + class_destroy(tb_class); } module_init(sbprof_tb_init); module_exit(sbprof_tb_cleanup); + +MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR); +MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); +MODULE_LICENSE("GPL"); diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 1cb042eab720..87188f0f6fbe 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <linux/init.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/reboot.h> #include <linux/string.h> @@ -32,6 +33,7 @@ unsigned int soc_pass; unsigned int soc_type; unsigned int periph_rev; unsigned int zbbus_mhz; +EXPORT_SYMBOL(zbbus_mhz); static char *soc_str; static char *pass_str; diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 7ec4ac77c0fa..e4006dc087ca 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -225,6 +225,22 @@ static struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, + { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ + .pvr_mask = 0xffffffff, + .pvr_value = 0x00440100, + .cpu_name = "PPC970MP", + .cpu_features = CPU_FTRS_PPC970, + .cpu_user_features = COMMON_USER_POWER4 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, + .oprofile_cpu_type = "ppc64/970MP", + .oprofile_type = PPC_OPROFILE_POWER4, + .platform = "ppc970", + }, { /* PPC970MP */ .pvr_mask = 0xffff0000, .pvr_value = 0x00440000, diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index ea6fd552c7ea..91b443c9a488 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -916,7 +916,7 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw); static int of_irq_map_oldworld(struct device_node *device, int index, struct of_irq *out_irq) { - const u32 *ints; + const u32 *ints = NULL; int intlen; /* diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index e5d819166874..8aa9a93e2aa2 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -55,9 +55,9 @@ static int mpc834x_usb_cfg(void) struct device_node *np = NULL; int port0_is_dr = 0; - if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL) + if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL) port0_is_dr = 1; - if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL){ + if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){ if (port0_is_dr) { printk(KERN_WARNING "There is only one USB port on PB board! \n"); @@ -103,8 +103,8 @@ static int mpc834x_usb_cfg(void) return -1; /* - * if MDS board is plug into PIB board, - * force to use the PHY on MDS board + * if Processor Board is plugged into PIB board, + * force to use the PHY on Processor Board */ bcsr5 = in_8(bcsr_regs + 5); if (!(bcsr5 & BCSR5_INT_USB)) diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index eb661ccf2dab..e764c0aced88 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -47,6 +47,7 @@ config MPC85xx bool select PPC_UDBG_16550 select PPC_INDIRECT_PCI + select SERIAL_8250_SHARE_IRQ if SERIAL_8250 default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS config PPC_INDIRECT_PCI_BE diff --git a/arch/powerpc/platforms/celleb/scc_epci.c b/arch/powerpc/platforms/celleb/scc_epci.c index c11b39c3776a..fb23d53eb09c 100644 --- a/arch/powerpc/platforms/celleb/scc_epci.c +++ b/arch/powerpc/platforms/celleb/scc_epci.c @@ -43,11 +43,34 @@ #define iob() __asm__ __volatile__("eieio; sync":::"memory") +static inline volatile void __iomem *celleb_epci_get_epci_base( + struct pci_controller *hose) +{ + /* + * Note: + * Celleb epci uses cfg_addr as a base address for + * epci control registers. + */ + + return hose->cfg_addr; +} + +static inline volatile void __iomem *celleb_epci_get_epci_cfg( + struct pci_controller *hose) +{ + /* + * Note: + * Celleb epci uses cfg_data as a base address for + * configuration area for epci devices. + */ + + return hose->cfg_data; +} #if 0 /* test code for epci dummy read */ static void celleb_epci_dummy_read(struct pci_dev *dev) { - void __iomem *epci_base; + volatile void __iomem *epci_base; struct device_node *node; struct pci_controller *hose; u32 val; @@ -58,7 +81,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev) if (!hose) return; - epci_base = hose->cfg_addr; + epci_base = celleb_epci_get_epci_base(hose); val = in_be32(epci_base + SCC_EPCI_WATRP); iosync(); @@ -70,19 +93,20 @@ static void celleb_epci_dummy_read(struct pci_dev *dev) static inline void clear_and_disable_master_abort_interrupt( struct pci_controller *hose) { - void __iomem *addr; - addr = hose->cfg_addr + PCI_COMMAND; - out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); + volatile void __iomem *epci_base, *reg; + epci_base = celleb_epci_get_epci_base(hose); + reg = epci_base + PCI_COMMAND; + out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16)); } static int celleb_epci_check_abort(struct pci_controller *hose, - void __iomem *addr) + volatile void __iomem *addr) { - void __iomem *reg, *epci_base; + volatile void __iomem *reg, *epci_base; u32 val; iob(); - epci_base = hose->cfg_addr; + epci_base = celleb_epci_get_epci_base(hose); reg = epci_base + PCI_COMMAND; val = in_be32(reg); @@ -108,20 +132,21 @@ static int celleb_epci_check_abort(struct pci_controller *hose, return PCIBIOS_SUCCESSFUL; } -static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, +static volatile void __iomem *celleb_epci_make_config_addr( + struct pci_controller *hose, unsigned int devfn, int where) { - void __iomem *addr; + volatile void __iomem *addr; struct pci_bus *bus = hose->bus; if (bus->self) - addr = hose->cfg_data + + addr = celleb_epci_get_epci_cfg(hose) + (((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | (where & 0xff) | 0x01000000); else - addr = hose->cfg_data + + addr = celleb_epci_get_epci_cfg(hose) + (((devfn & 0xff) << 8) | (where & 0xff)); pr_debug("EPCI: config_addr = 0x%p\n", addr); @@ -132,7 +157,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, static int celleb_epci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { - void __iomem *addr; + volatile void __iomem *epci_base, *addr; struct device_node *node; struct pci_controller *hose; @@ -142,13 +167,14 @@ static int celleb_epci_read_config(struct pci_bus *bus, node = (struct device_node *)bus->sysdata; hose = pci_find_hose_for_OF_device(node); - if (!hose->cfg_data) + if (!celleb_epci_get_epci_cfg(hose)) return PCIBIOS_DEVICE_NOT_FOUND; if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + epci_base = celleb_epci_get_epci_base(hose); + addr = epci_base + where; switch (size) { case 1: @@ -185,7 +211,7 @@ static int celleb_epci_read_config(struct pci_bus *bus, } pr_debug("EPCI: " - "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", + "addr=0x%p, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", addr, devfn, where, size, *val); return celleb_epci_check_abort(hose, NULL); @@ -194,7 +220,7 @@ static int celleb_epci_read_config(struct pci_bus *bus, static int celleb_epci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - void __iomem *addr; + volatile void __iomem *epci_base, *addr; struct device_node *node; struct pci_controller *hose; @@ -204,13 +230,15 @@ static int celleb_epci_write_config(struct pci_bus *bus, node = (struct device_node *)bus->sysdata; hose = pci_find_hose_for_OF_device(node); - if (!hose->cfg_data) + + if (!celleb_epci_get_epci_cfg(hose)) return PCIBIOS_DEVICE_NOT_FOUND; if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + epci_base = celleb_epci_get_epci_base(hose); + addr = epci_base + where; switch (size) { case 1: @@ -258,10 +286,10 @@ struct pci_ops celleb_epci_ops = { static int __devinit celleb_epci_init(struct pci_controller *hose) { u32 val; - void __iomem *reg, *epci_base; + volatile void __iomem *reg, *epci_base; int hwres = 0; - epci_base = hose->cfg_addr; + epci_base = celleb_epci_get_epci_base(hose); /* PCI core reset(Internal bus and PCI clock) */ reg = epci_base + SCC_EPCI_CKCTRL; @@ -382,6 +410,18 @@ int __devinit celleb_setup_epci(struct device_node *node, pr_debug("PCI: celleb_setup_epci()\n"); + /* + * Note: + * Celleb epci uses cfg_addr and cfg_data member of + * pci_controller structure in irregular way. + * + * cfg_addr is used to map for control registers of + * celleb epci. + * + * cfg_data is used for configuration area of devices + * on Celleb epci buses. + */ + if (of_address_to_resource(node, 0, &r)) goto error; hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 886c522d78e9..3410bcbc9dbe 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -79,6 +79,7 @@ config LINKSTATION select MPIC select FSL_SOC select PPC_UDBG_16550 if SERIAL_8250 + select DEFAULT_UIMAGE help Select LINKSTATION if configuring for one of PPC- (MPC8241) based NAS systems from Buffalo Technology. So far only diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index c29a6a064d22..24cc50c1774a 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -810,6 +810,7 @@ core99_ata100_enable(struct device_node *node, long value) unsigned long flags; struct pci_dev *pdev = NULL; u8 pbus, pid; + int rc; if (uninorth_rev < 0x24) return -ENODEV; @@ -828,7 +829,9 @@ core99_ata100_enable(struct device_node *node, long value) pdev = pci_find_slot(pbus, pid); if (pdev == NULL) return 0; - pci_enable_device(pdev); + rc = pci_enable_device(pdev); + if (rc) + return rc; pci_set_master(pdev); } return 0; diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index f42475b27c15..6fbac308ded6 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -1191,8 +1191,11 @@ void __init pmac_pcibios_after_init(void) * -- BenH */ for_each_pci_dev(dev) { - if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) - pci_enable_device(dev); + if ((dev->class >> 16) != PCI_BASE_CLASS_STORAGE) + continue; + if (pci_enable_device(dev)) + printk(KERN_WARNING + "pci: Failed to enable %s\n", pci_name(dev)); } #endif /* CONFIG_BLK_DEV_IDE */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 0183e5fbaf46..bf299b66f3fc 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -218,7 +218,7 @@ Commands:\n\ " ss stop execution on all spus\n\ sr restore execution on stopped spus\n\ sf # dump spu fields for spu # (in hex)\n\ - sd # dump spu local store for spu # (in hex)\ + sd # dump spu local store for spu # (in hex)\n\ sdi # disassemble spu local store for spu # (in hex)\n" #endif " S print special registers\n\ diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 8047ea8c2ab2..dec587b293bf 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -30,11 +30,8 @@ static void via_bugs(void) #ifdef CONFIG_ACPI -static int nvidia_hpet_detected __initdata; - static int __init nvidia_hpet_check(struct acpi_table_header *header) { - nvidia_hpet_detected = 1; return 0; } #endif @@ -52,11 +49,7 @@ static void nvidia_bugs(void) if (acpi_use_timer_override) return; - nvidia_hpet_detected = 0; - if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) - return; - - if (nvidia_hpet_detected == 0) { + if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " "detected. Ignoring ACPI " |