aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel/sn1
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn/kernel/sn1')
-rw-r--r--arch/ia64/sn/kernel/sn1/Makefile45
-rw-r--r--arch/ia64/sn/kernel/sn1/cache.c81
-rw-r--r--arch/ia64/sn/kernel/sn1/error.c187
-rw-r--r--arch/ia64/sn/kernel/sn1/iomv.c65
-rw-r--r--arch/ia64/sn/kernel/sn1/sn1_smp.c476
-rw-r--r--arch/ia64/sn/kernel/sn1/synergy.c533
6 files changed, 0 insertions, 1387 deletions
diff --git a/arch/ia64/sn/kernel/sn1/Makefile b/arch/ia64/sn/kernel/sn1/Makefile
deleted file mode 100644
index 65261dc37f5d2..0000000000000
--- a/arch/ia64/sn/kernel/sn1/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# arch/ia64/sn/kernel/sn1/Makefile
-#
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License
-# as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it would be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Further, this software is distributed without any warranty that it is
-# free of the rightful claim of any third person regarding infringement
-# or the like. Any license provided herein, whether implied or
-# otherwise, applies only to this software file. Patent licenses, if
-# any, provided herein do not apply to combinations of this program with
-# other software, or any other product whatsoever.
-#
-# You should have received a copy of the GNU General Public
-# License along with this program; if not, write the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
-# Mountain View, CA 94043, or:
-#
-# http://www.sgi.com
-#
-# For further information regarding this notice, see:
-#
-# http://oss.sgi.com/projects/GenInfo/NoticeExplan
-#
-
-
-EXTRA_CFLAGS := -DLITTLE_ENDIAN
-
-.S.s:
- $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
-.S.o:
- $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-
-O_TARGET = sn1.o
-
-obj-y = cache.o error.o iomv.o synergy.o sn1_smp.o
diff --git a/arch/ia64/sn/kernel/sn1/cache.c b/arch/ia64/sn/kernel/sn1/cache.c
deleted file mode 100644
index c0894b03fca09..0000000000000
--- a/arch/ia64/sn/kernel/sn1/cache.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/delay.h>
-
-#ifndef MB
-#define MB (1024*1024)
-#endif
-
-/*
- * Lock for protecting SYN_TAG_DISABLE_WAY.
- * Consider making this a per-FSB lock.
- */
-static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
-
-/**
- * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4)
- * @flush_addr: identity mapped region 7 address to start flushing
- * @bytes: number of bytes to flush
- *
- * Flush a range of addresses from all caches including L4. All addresses
- * fully or partially contained within @flush_addr to @flush_addr + @bytes
- * are flushed from the all caches.
- */
-void
-sn_flush_all_caches(long flush_addr, long bytes)
-{
- ulong addr, baddr, eaddr, bitbucket;
- int way, alias;
-
- /*
- * Because of the way synergy implements "fc", this flushes the
- * data from all caches on all cpus & L4's on OTHER FSBs. It also
- * flushes both cpus on the local FSB. It does NOT flush it from
- * the local FSB.
- */
- flush_icache_range(flush_addr, flush_addr+bytes);
-
- /*
- * Memory DIMMs are a minimum of 256MB and start on 256MB
- * boundaries. Convert the start address to an address
- * that is between +0MB & +128 of the same DIMM.
- * Then add 8MB to skip the uncached MinState areas if the address
- * is on the master node.
- */
- if (bytes > SYNERGY_L4_BYTES_PER_WAY)
- bytes = SYNERGY_L4_BYTES_PER_WAY;
- baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB);
- eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1);
- baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1);
-
- /*
- * Now flush the local synergy.
- */
- spin_lock(&flush_lock);
- for(way=0; way<SYNERGY_L4_WAYS; way++) {
- WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0xffL ^ (1L<<way));
- mb();
- for(alias=0; alias < 9; alias++)
- for(addr=baddr; addr<eaddr; addr+=SYNERGY_BLOCK_SIZE)
- bitbucket = *(volatile ulong *)(addr+alias*8*MB);
- mb();
- }
- WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0);
- spin_unlock(&flush_lock);
-
-}
-
-
diff --git a/arch/ia64/sn/kernel/sn1/error.c b/arch/ia64/sn/kernel/sn1/error.c
deleted file mode 100644
index 16b68ae0012b4..0000000000000
--- a/arch/ia64/sn/kernel/sn1/error.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * SN1 Platform specific error Support
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-
-/**
- * snia_error_intr_handler - handle SN specific error interrupts
- * @irq: error interrupt received
- * @devid: device causing the interrupt
- * @pt_regs: saved register state
- *
- * This routine is called when certain interrupts occur on SN systems.
- * It will either recover from the situations that caused the interrupt
- * or panic.
- */
-void
-snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs)
-{
- unsigned long long intpend_val;
- unsigned long long bit;
-
- switch (irq) {
- case SGI_UART_IRQ:
- /*
- * This isn't really an error interrupt. We're just
- * here because we have to do something with them.
- * This is probably wrong, and this code will be
- * removed.
- */
- intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
- if ( (bit = ~(1L<<GFX_INTR_A)) ==
- (intpend_val & ~(1L<<GFX_INTR_A)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- if ( (bit = ~(1L<<GFX_INTR_B)) ==
- (intpend_val & ~(1L<<GFX_INTR_B)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- if ( (bit = ~(1L<<PG_MIG_INTR)) ==
- (intpend_val & ~(1L<<PG_MIG_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- if ( (bit = ~(1L<<UART_INTR)) ==
- (intpend_val & ~(1L<<UART_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- if ( (bit = ~(1L<<CC_PEND_A)) ==
- (intpend_val & ~(1L<<CC_PEND_A)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- if ( (bit = ~(1L<<CC_PEND_B)) ==
- (intpend_val & ~(1L<<CC_PEND_B)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- return;
- }
- printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
- return;
- case SGI_HUB_ERROR_IRQ:
- /*
- * These are mostly error interrupts of various
- * sorts. We need to do more than panic here, but
- * what the heck, this is bring up.
- */
- intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
-
- if ( (bit = ~(1L<<XB_ERROR)) ==
- (intpend_val & ~(1L<<XB_ERROR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<LB_ERROR)) ==
- (intpend_val & ~(1L<<LB_ERROR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<NACK_INT_A)) ==
- (intpend_val & ~(1L<<NACK_INT_A)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<NACK_INT_B)) ==
- (intpend_val & ~(1L<<NACK_INT_B)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
- (intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
- (intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
- (intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
- (intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
- (intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
- (intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
- LOCAL_HUB_CLR_INTR(bit);
- panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
- smp_processor_id(),
- cpuid_to_cnodeid(smp_processor_id()));
- }
- printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
- return;
- default:
- printk("Received invalid irq in snia_error_intr_handler()\n");
- }
-}
diff --git a/arch/ia64/sn/kernel/sn1/iomv.c b/arch/ia64/sn/kernel/sn1/iomv.c
deleted file mode 100644
index 04bd87614c90c..0000000000000
--- a/arch/ia64/sn/kernel/sn1/iomv.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/sn/simulator.h>
-#include <asm/delay.h>
-#include <asm/sn/pda.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64. This routine will convert a port number into a valid
- * SN i/o address. Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
- if (!IS_RUNNING_ON_SIMULATOR()) {
- return( (void *) (port | __IA64_UNCACHED_OFFSET));
- } else {
- unsigned long io_base;
- unsigned long addr;
-
- /*
- * word align port, but need more than 10 bits
- * for accessing registers in bedrock local block
- * (so we don't do port&0xfff)
- */
- if ((port >= 0x1f0 && port <= 0x1f7) ||
- port == 0x3f6 || port == 0x3f7) {
- io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
- addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
- } else {
- addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
- }
- return(void *) addr;
- }
-}
-
-/**
- * sn1_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to
- * I/O space. This ensures that subsequent writes to I/O space arrive after
- * all previous writes. For most ia64 platforms, this is a simple
- * 'mf.a' instruction. For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear.
- */
-void
-sn1_mmiob (void)
-{
- (volatile unsigned long) (*pda.bedrock_rev_id);
- while (!(volatile unsigned long) (*pda.pio_write_status_addr))
- udelay(5);
-}
diff --git a/arch/ia64/sn/kernel/sn1/sn1_smp.c b/arch/ia64/sn/kernel/sn1/sn1_smp.c
deleted file mode 100644
index e24f97eba6576..0000000000000
--- a/arch/ia64/sn/kernel/sn1/sn1_smp.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * SN1 Platform specific SMP Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mmzone.h>
-
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/hw_irq.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
- union {
- struct {
- unsigned long start;
- unsigned long end;
- unsigned long nbits;
- unsigned int rid;
- atomic_t unfinished_count;
- } ptc;
- char pad[SMP_CACHE_BYTES];
- };
-} ptc_params_t;
-
-#define NUMPTC 512
-
-static ptc_params_t ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t *ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t *ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0; /* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-/*
- * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We don't want to start
- * cpus unless we know their cache domain.
- */
-#ifdef PTC_NOTYET
-sn_sapicid_info_t sn_sapicid_info[NR_CPUS];
-#endif
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers). Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better
- * until I get some statistics on a running system. At a minimum, we should only
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
- do {
- __asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
- start += (1UL << nbits);
- } while (start < end);
- ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
- unsigned long start, end, nbits;
- unsigned int rid, saved_rid;
- int cpu = smp_processor_id();
- int result;
- ptc_params_t *ptcParams;
-
- ptcParams = ptcParamsNextByCpu[cpu*16];
- if (ptcParams == ptcParamsEmpty)
- return;
-
- do {
- start = ptcParams->ptc.start;
- saved_rid = (unsigned int) ia64_get_rr(start);
- end = ptcParams->ptc.end;
- nbits = ptcParams->ptc.nbits;
- rid = ptcParams->ptc.rid;
-
- if (saved_rid != rid) {
- ia64_set_rr(start, (unsigned long)rid);
- ia64_srlz_d();
- }
-
- sn1_ptc_l_range(start, end, nbits);
-
- if (saved_rid != rid)
- ia64_set_rr(start, (unsigned long)saved_rid);
-
- ia64_srlz_i();
-
- result = atomic_dec(&ptcParams->ptc.unfinished_count);
-#ifdef PTCDEBUG
- {
- int i = ptcParams-&ptcParamArray[0];
- ptcParamsResults[cpu][i] = (char) result;
- ptcParamsCounts[cpu][i]++;
- }
-#endif /* PTCDEBUG */
-
- if (++ptcParams == &ptcParamArray[NUMPTC])
- ptcParams = &ptcParamArray[0];
-
- } while (ptcParams != ptcParamsEmpty);
-
- ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
- ptc_params_t *params;
- ptc_params_t *next;
- unsigned long irqflags;
-#ifdef PTCDEBUG
- ptc_params_t *nextnext;
- int backlog = 0;
-#endif
-
- if (smp_num_cpus == 1) {
- sn1_ptc_l_range(start, end, nbits);
- return;
- }
-
- if (in_interrupt()) {
- /*
- * If at interrupt level and cannot get spinlock,
- * then do something useful by flushing own tlbflush queue
- * so as to avoid a possible deadlock.
- */
- while (!spin_trylock(&ptcParamsLock)) {
- local_irq_save(irqflags);
- sn1_received_flush_tlb();
- local_irq_restore(irqflags);
- udelay(10); /* take it easier on the bus */
- }
- } else {
- spin_lock(&ptcParamsLock);
- }
-
- if (!ptcInit) {
- int cpu;
- ptcInit = 1;
- memset(ptcParamArray, 0, sizeof(ptcParamArray));
- ptcParamsEmpty = &ptcParamArray[0];
- for (cpu=0; cpu<NR_CPUS; cpu++)
- ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
- memset(ptcBacklog, 0, sizeof(ptcBacklog));
- memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
- memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif /* PTCDEBUG */
- }
-
- params = (ptc_params_t *) ptcParamsEmpty;
- next = (ptc_params_t *) ptcParamsEmpty + 1;
- if (next == &ptcParamArray[NUMPTC])
- next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
- nextnext = next + 1;
- if (nextnext == &ptcParamArray[NUMPTC])
- nextnext = &ptcParamArray[0];
-
- if (ptcCountBacklog) {
- /* quick count of backlog */
- ptc_params_t *ptr;
-
- /* check the current pointer to the beginning */
- ptr = params;
- while(--ptr >= &ptcParamArray[0]) {
- if (atomic_read(&ptr->ptc.unfinished_count) == 0)
- break;
- ++backlog;
- }
-
- if (backlog) {
- /* check the end of the array */
- ptr = &ptcParamArray[NUMPTC];
- while (--ptr > params) {
- if (atomic_read(&ptr->ptc.unfinished_count) == 0)
- break;
- ++backlog;
- }
- }
- ptcBacklog[backlog]++;
- }
-#endif /* PTCDEBUG */
-
- /* wait for the next entry to clear...should be rare */
- if (atomic_read(&next->ptc.unfinished_count) > 0) {
-#ifdef PTCDEBUG
- ptcParamsAllBusy++;
-
- if (atomic_read(&nextnext->ptc.unfinished_count) == 0) {
- if (atomic_read(&next->ptc.unfinished_count) > 0) {
- panic("\nnonzero next zero nextnext %lx %lx\n",
- (long)next, (long)nextnext);
- }
- }
-#endif
-
- /* it could be this cpu that is behind */
- local_irq_save(irqflags);
- sn1_received_flush_tlb();
- local_irq_restore(irqflags);
-
- /* now we know it's not this cpu, so just wait */
- while (atomic_read(&next->ptc.unfinished_count) > 0) {
- barrier();
- }
- }
-
- params->ptc.start = start;
- params->ptc.end = end;
- params->ptc.nbits = nbits;
- params->ptc.rid = (unsigned int) ia64_get_rr(start);
- atomic_set(&params->ptc.unfinished_count, smp_num_cpus);
-
- /* The atomic_set above can hit memory *after* the update
- * to ptcParamsEmpty below, which opens a timing window
- * that other cpus can squeeze into!
- */
- mb();
-
- /* everything is ready to process:
- * -- global lock is held
- * -- new entry + 1 is free
- * -- new entry is set up
- * so now:
- * -- update the global next pointer
- * -- unlock the global lock
- * -- send IPI to notify other cpus
- * -- process the data ourselves
- */
- ptcParamsEmpty = next;
- spin_unlock(&ptcParamsLock);
- smp_send_flush_tlb();
-
- local_irq_save(irqflags);
- sn1_received_flush_tlb();
- local_irq_restore(irqflags);
-
- /* Currently we don't think global TLB purges need to be atomic.
- * All CPUs get sent IPIs, so if they haven't done the purge,
- * they're busy with interrupts that are at the IPI level, which is
- * priority 15. We're asserting that any code at that level
- * shouldn't be using user TLB entries. To change this to wait
- * for all the flushes to complete, enable the following code.
- */
-#if defined(SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE) || defined(BUS_INT_WAR)
- /* this code is not tested */
- /* wait for the flush to complete */
- while (atomic_read(&params->ptc.unfinished_count) > 0)
- barrier();
-#endif
-}
-
-/**
- * sn_send_IPI_phys - send an IPI to a Nasid and slice
- * @physid: physical cpuid to receive the interrupt.
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @physid
- *
- * @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn_send_IPI_phys(long physid, int vector, int delivery_mode)
-{
- long *p;
- long nasid, slice;
-
- static int off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
-
-#ifdef BUS_INT_WAR
- if (vector != ap_wakeup_vector) {
- return;
- }
-#endif
-
- nasid = cpu_physical_id_to_nasid(physid);
- slice = cpu_physical_id_to_slice(physid);
-
- p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
-
- mb();
- *p = (delivery_mode << 8) | (vector & 0xff);
-}
-
-
-/**
- * sn1_send_IPI - send an IPI to a processor
- * @cpuid: target of the IPI
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- * @redirect: redirect the IPI?
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @cpuid. @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
- long physid;
-
- physid = cpu_physical_id(cpuid);
-
- sn_send_IPI_phys(physid, vector, delivery_mode);
-}
-#ifdef CONFIG_SMP
-
-#ifdef PTC_NOTYET
-static void __init
-process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
-{
- ia64_sal_ptc_domain_proc_entry_t *pe;
- int i, sapicid, cpuid;
-
- pe = __va(di->proc_list);
- for (i=0; i<di->proc_count; i++, pe++) {
- sapicid = id_eid_to_sapicid(pe->id, pe->eid);
- cpuid = cpu_logical_id(sapicid);
- sn_sapicid_info[cpuid].domain = domain;
- sn_sapicid_info[cpuid].sapicid = sapicid;
- }
-}
-
-
-static void __init
-process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
-{
- ia64_sal_ptc_domain_info_t *di;
- int i;
-
- di = __va(ptc->domain_info);
- for (i=0; i<ptc->num_domains; i++, di++) {
- process_sal_ptc_domain_info(di, i);
- }
-}
-#endif /* PTC_NOTYET */
-
-/**
- * init_sn1_smp_config - setup PTC domains per processor
- */
-void __init
-init_sn1_smp_config(void)
-{
- if (!ia64_ptc_domain_info) {
- printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
- smp_num_cpus = 1;
- return;
- }
-
-#ifdef PTC_NOTYET
- memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
- process_sal_desc_ptc(ia64_ptc_domain_info);
-#endif
-}
-
-#else /* CONFIG_SMP */
-
-void __init
-init_sn1_smp_config(void)
-{
-
-#ifdef PTC_NOTYET
- sn_sapicid_info[0].sapicid = hard_smp_processor_id();
-#endif
-}
-
-#endif /* CONFIG_SMP */
diff --git a/arch/ia64/sn/kernel/sn1/synergy.c b/arch/ia64/sn/kernel/sn1/synergy.c
deleted file mode 100644
index df31731bc73b9..0000000000000
--- a/arch/ia64/sn/kernel/sn1/synergy.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * SN1 Platform specific synergy Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/sn/sndrv.h>
-
-int bit_pos_to_irq(int bit);
-void setclear_mask_b(int irq, int cpuid, int set);
-void setclear_mask_a(int irq, int cpuid, int set);
-void * kmalloc(size_t size, int flags);
-
-static int synergy_perf_initialized = 0;
-
-void
-synergy_intr_alloc(int bit, int cpuid) {
- return;
-}
-
-int
-synergy_intr_connect(int bit,
- int cpuid)
-{
- int irq;
- unsigned is_b;
-
- irq = bit_pos_to_irq(bit);
-
- is_b = (cpuid_to_slice(cpuid)) & 1;
- if (is_b) {
- setclear_mask_b(irq,cpuid,1);
- setclear_mask_a(irq,cpuid, 0);
- } else {
- setclear_mask_a(irq, cpuid, 1);
- setclear_mask_b(irq, cpuid, 0);
- }
- return 0;
-}
-void
-setclear_mask_a(int irq, int cpuid, int set)
-{
- int synergy;
- int nasid;
- int reg_num;
- unsigned long mask;
- unsigned long addr;
- unsigned long reg;
- unsigned long val;
- int my_cnode, my_synergy;
- int target_cnode, target_synergy;
-
- /*
- * Perform some idiot checks ..
- */
- if ( (irq < 0) || (irq > 255) ||
- (cpuid < 0) || (cpuid > 512) ) {
- printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
- return;
- }
-
- target_cnode = cpuid_to_cnodeid(cpuid);
- target_synergy = cpuid_to_synergy(cpuid);
- my_cnode = cpuid_to_cnodeid(smp_processor_id());
- my_synergy = cpuid_to_synergy(smp_processor_id());
-
- reg_num = irq / 64;
- mask = 1;
- mask <<= (irq % 64);
- switch (reg_num) {
- case 0:
- reg = VEC_MASK0A;
- addr = VEC_MASK0A_ADDR;
- break;
- case 1:
- reg = VEC_MASK1A;
- addr = VEC_MASK1A_ADDR;
- break;
- case 2:
- reg = VEC_MASK2A;
- addr = VEC_MASK2A_ADDR;
- break;
- case 3:
- reg = VEC_MASK3A;
- addr = VEC_MASK3A_ADDR;
- break;
- default:
- reg = addr = 0;
- break;
- }
- if (my_cnode == target_cnode && my_synergy == target_synergy) {
- // local synergy
- val = READ_LOCAL_SYNERGY_REG(addr);
- if (set) {
- val |= mask;
- } else {
- val &= ~mask;
- }
- WRITE_LOCAL_SYNERGY_REG(addr, val);
- val = READ_LOCAL_SYNERGY_REG(addr);
- } else { /* remote synergy */
- synergy = cpuid_to_synergy(cpuid);
- nasid = cpuid_to_nasid(cpuid);
- val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
- if (set) {
- val |= mask;
- } else {
- val &= ~mask;
- }
- REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
- }
-}
-
-void
-setclear_mask_b(int irq, int cpuid, int set)
-{
- int synergy;
- int nasid;
- int reg_num;
- unsigned long mask;
- unsigned long addr;
- unsigned long reg;
- unsigned long val;
- int my_cnode, my_synergy;
- int target_cnode, target_synergy;
-
- /*
- * Perform some idiot checks ..
- */
- if ( (irq < 0) || (irq > 255) ||
- (cpuid < 0) || (cpuid > 512) ) {
- printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
- return;
- }
-
- target_cnode = cpuid_to_cnodeid(cpuid);
- target_synergy = cpuid_to_synergy(cpuid);
- my_cnode = cpuid_to_cnodeid(smp_processor_id());
- my_synergy = cpuid_to_synergy(smp_processor_id());
-
- reg_num = irq / 64;
- mask = 1;
- mask <<= (irq % 64);
- switch (reg_num) {
- case 0:
- reg = VEC_MASK0B;
- addr = VEC_MASK0B_ADDR;
- break;
- case 1:
- reg = VEC_MASK1B;
- addr = VEC_MASK1B_ADDR;
- break;
- case 2:
- reg = VEC_MASK2B;
- addr = VEC_MASK2B_ADDR;
- break;
- case 3:
- reg = VEC_MASK3B;
- addr = VEC_MASK3B_ADDR;
- break;
- default:
- reg = addr = 0;
- break;
- }
- if (my_cnode == target_cnode && my_synergy == target_synergy) {
- // local synergy
- val = READ_LOCAL_SYNERGY_REG(addr);
- if (set) {
- val |= mask;
- } else {
- val &= ~mask;
- }
- WRITE_LOCAL_SYNERGY_REG(addr, val);
- val = READ_LOCAL_SYNERGY_REG(addr);
- } else { /* remote synergy */
- synergy = cpuid_to_synergy(cpuid);
- nasid = cpuid_to_nasid(cpuid);
- val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
- if (set) {
- val |= mask;
- } else {
- val &= ~mask;
- }
- REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
- }
-}
-
-/*
- * Synergy perf stats. Multiplexed via timer_interrupt.
- */
-
-static int
-synergy_perf_append(uint64_t modesel)
-{
- int cnode;
- nodepda_t *npdap;
- synergy_perf_t *p;
- int checked = 0;
- int err = 0;
- unsigned long flags;
-
- /* bit 45 is enable */
- modesel |= (1UL << 45);
-
- for (cnode=0; cnode < numnodes; cnode++) {
- /* for each node, insert a new synergy_perf entry */
- if ((npdap = NODEPDA(cnode)) == NULL) {
- printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda);
- continue;
- }
-
- if (npdap->synergy_perf_enabled) {
- /* user must disable counting to append new events */
- err = -EBUSY;
- break;
- }
-
- if (!checked && npdap->synergy_perf_data != NULL) {
- checked = 1;
- for (p = npdap->synergy_perf_first; ;) {
- if (p->modesel == modesel)
- return 0; /* event already registered */
- if ((p = p->next) == npdap->synergy_perf_first)
- break;
- }
- }
-
- /* XX use kmem_alloc_node() when it is implemented */
- p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
- if ((((uint64_t)p) & 7UL) != 0)
- BUG(); /* bad alignment */
- if (p == NULL) {
- err = -ENOMEM;
- break;
- }
- else {
- memset(p, 0, sizeof(synergy_perf_t));
- p->modesel = modesel;
-
- spin_lock_irqsave(&npdap->synergy_perf_lock, flags);
- if (npdap->synergy_perf_data == NULL) {
- /* circular list */
- p->next = p;
- npdap->synergy_perf_first = p;
- npdap->synergy_perf_data = p;
- }
- else {
- p->next = npdap->synergy_perf_data->next;
- npdap->synergy_perf_data->next = p;
- }
- spin_unlock_irqrestore(&npdap->synergy_perf_lock, flags);
- }
- }
-
- return err;
-}
-
-static void
-synergy_perf_set_freq(int freq)
-{
- int cnode;
- nodepda_t *npdap;
-
- for (cnode=0; cnode < numnodes; cnode++) {
- if ((npdap = NODEPDA(cnode)) != NULL)
- npdap->synergy_perf_freq = freq;
- }
-}
-
-static void
-synergy_perf_set_enable(int enable)
-{
- int cnode;
- nodepda_t *npdap;
-
- for (cnode=0; cnode < numnodes; cnode++) {
- if ((npdap = NODEPDA(cnode)) != NULL)
- npdap->synergy_perf_enabled = enable;
- }
- printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis");
-}
-
-static int
-synergy_perf_size(nodepda_t *npdap)
-{
- synergy_perf_t *p;
- int n;
-
- if (npdap->synergy_perf_enabled == 0) {
- /* no stats to return */
- return 0;
- }
-
- spin_lock_irq(&npdap->synergy_perf_lock);
- for (n=0, p = npdap->synergy_perf_first; p;) {
- n++;
- p = p->next;
- if (p == npdap->synergy_perf_first)
- break;
- }
- spin_unlock_irq(&npdap->synergy_perf_lock);
-
- /* bytes == n pairs of {event,counter} */
- return n * 2 * sizeof(uint64_t);
-}
-
-static int
-synergy_perf_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int cnode;
- nodepda_t *npdap;
- synergy_perf_t *p;
- int intarg;
- int fsb;
- uint64_t longarg;
- uint64_t *stats;
- int n;
- devfs_handle_t d;
- arbitrary_info_t info;
-
- if ((d = devfs_get_handle_from_inode(inode)) == NULL)
- return -ENODEV;
- info = hwgraph_fastinfo_get(d);
-
- cnode = SYNERGY_PERF_INFO_CNODE(info);
- fsb = SYNERGY_PERF_INFO_FSB(info);
- npdap = NODEPDA(cnode);
-
- switch (cmd) {
- case SNDRV_GET_SYNERGY_VERSION:
- /* return int, version of data structure for SNDRV_GET_SYNERGYINFO */
- intarg = 1; /* version 1 */
- if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
- return -EFAULT;
- break;
-
- case SNDRV_GET_INFOSIZE:
- /* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */
- intarg = synergy_perf_size(npdap);
- if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
- return -EFAULT;
- break;
-
- case SNDRV_GET_SYNERGYINFO:
- /* return array of event/value pairs, this node only */
- if ((intarg = synergy_perf_size(npdap)) <= 0)
- return -ENODATA;
- if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- spin_lock_irq(&npdap->synergy_perf_lock);
- for (n=0, p = npdap->synergy_perf_first; p;) {
- stats[n++] = p->modesel;
- if (p->intervals > 0)
- stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals;
- else
- stats[n++] = 0;
- p = p->next;
- if (p == npdap->synergy_perf_first)
- break;
- }
- spin_unlock_irq(&npdap->synergy_perf_lock);
-
- if (copy_to_user((void *)arg, stats, intarg)) {
- kfree(stats);
- return -EFAULT;
- }
-
- kfree(stats);
- break;
-
- case SNDRV_SYNERGY_APPEND:
- /* reads 64bit event, append synergy perf event to all nodes */
- if (copy_from_user(&longarg, (void *)arg, sizeof(longarg)))
- return -EFAULT;
- return synergy_perf_append(longarg);
- break;
-
- case SNDRV_GET_SYNERGY_STATUS:
- /* return int, 1 if enabled else 0 */
- intarg = npdap->synergy_perf_enabled;
- if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
- return -EFAULT;
- break;
-
- case SNDRV_SYNERGY_ENABLE:
- /* read int, if true enable counting else disable */
- if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
- return -EFAULT;
- synergy_perf_set_enable(intarg);
- break;
-
- case SNDRV_SYNERGY_FREQ:
- /* read int, set jiffies per update */
- if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
- return -EFAULT;
- if (intarg < 0 || intarg >= HZ)
- return -EINVAL;
- synergy_perf_set_freq(intarg);
- break;
-
- default:
- printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb);
- return -EINVAL;
- }
- return(0);
-}
-
-struct file_operations synergy_mon_fops = {
- .ioctl = synergy_perf_ioctl,
-};
-
-void
-synergy_perf_update(int cpu)
-{
- nasid_t nasid;
- cnodeid_t cnode;
- struct nodepda_s *npdap;
-
- /*
- * synergy_perf_initialized is set by synergy_perf_init()
- * which is called last thing by sn_mp_setup(), i.e. well
- * after nodepda has been initialized.
- */
- if (!synergy_perf_initialized)
- return;
-
- cnode = cpuid_to_cnodeid(cpu);
- npdap = NODEPDA(cnode);
-
- if (npdap == NULL || cnode < 0 || cnode >= numnodes)
- /* this should not happen: still in early io init */
- return;
-
-#if 0
- /* use this to check nodepda initialization */
- if (((uint64_t)npdap) & 0x7) {
- printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap);
- BUG();
- }
-#endif
-
- if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) {
- /* Not enabled, or no events to monitor */
- return;
- }
-
- if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
- /* don't multiplex on every timer interrupt */
- return;
- }
-
- /*
- * Read registers for last interval and increment counters.
- * Hold the per-node synergy_perf_lock so concurrent readers get
- * consistent values.
- */
- spin_lock_irq(&npdap->synergy_perf_lock);
-
- nasid = cpuid_to_nasid(cpu);
- npdap->synergy_active_intervals++;
- npdap->synergy_perf_data->intervals++;
- npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals;
-
- npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
- REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
-
- npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
- REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
-
- /* skip to next in circular list */
- npdap->synergy_perf_data = npdap->synergy_perf_data->next;
-
- spin_unlock_irq(&npdap->synergy_perf_lock);
-
- /* set the counter 0 selection modes for both A and B */
- REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
- REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
-
- /* and reset the counter registers to zero */
- REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
- REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
-}
-
-void
-synergy_perf_init(void)
-{
- printk("synergy_perf_init(), counting is initially disabled\n");
- synergy_perf_initialized++;
-}