From 13ffe5f82ac23303e6c21ac842269bb4a48a6473 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 03:48:14 -0700 Subject: [ARM] Timer cleanup Signed-off-by: Deepak Saxena --- include/asm-arm/arch-adifcc/time.h | 9 - include/asm-arm/arch-cl7500/time.h | 43 ----- include/asm-arm/arch-ebsa110/time.h | 118 ------------ include/asm-arm/arch-ebsa285/time.h | 287 ----------------------------- include/asm-arm/arch-epxa10db/time.h | 60 ------ include/asm-arm/arch-integrator/platform.h | 4 + include/asm-arm/arch-ixp4xx/platform.h | 1 + include/asm-arm/arch-lh7a40x/time.h | 53 ------ include/asm-arm/arch-omap/time.h | 212 --------------------- include/asm-arm/arch-pxa/time.h | 105 ----------- include/asm-arm/arch-rpc/time.h | 37 ---- include/asm-arm/arch-s3c2410/time.h | 173 ----------------- include/asm-arm/arch-sa1100/time.h | 111 ----------- include/asm-arm/arch-shark/time.h | 39 ---- include/asm-arm/arch-tbox/time.h | 39 ---- include/asm-arm/mach/arch.h | 5 + 16 files changed, 10 insertions(+), 1286 deletions(-) delete mode 100644 include/asm-arm/arch-adifcc/time.h delete mode 100644 include/asm-arm/arch-cl7500/time.h delete mode 100644 include/asm-arm/arch-ebsa110/time.h delete mode 100644 include/asm-arm/arch-ebsa285/time.h delete mode 100644 include/asm-arm/arch-epxa10db/time.h delete mode 100644 include/asm-arm/arch-lh7a40x/time.h delete mode 100644 include/asm-arm/arch-omap/time.h delete mode 100644 include/asm-arm/arch-pxa/time.h delete mode 100644 include/asm-arm/arch-rpc/time.h delete mode 100644 include/asm-arm/arch-s3c2410/time.h delete mode 100644 include/asm-arm/arch-sa1100/time.h delete mode 100644 include/asm-arm/arch-shark/time.h delete mode 100644 include/asm-arm/arch-tbox/time.h (limited to 'include') diff --git a/include/asm-arm/arch-adifcc/time.h b/include/asm-arm/arch-adifcc/time.h deleted file mode 100644 index 2237ef006e71..000000000000 --- a/include/asm-arm/arch-adifcc/time.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/time.h - * - */ - -/* - * No on board timer, implementation @ arch/arm/kernel/xscale-time.c - */ - diff --git a/include/asm-arm/arch-cl7500/time.h b/include/asm-arm/arch-cl7500/time.h deleted file mode 100644 index e5e5be510265..000000000000 --- a/include/asm-arm/arch-cl7500/time.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/include/asm-arm/arch-cl7500/time.h - * - * Copyright (c) 1996-2000 Russell King. - * - * Changelog: - * 24-Sep-1996 RMK Created - * 10-Oct-1996 RMK Brought up to date with arch-sa110eval - * 04-Dec-1997 RMK Updated for new arch/arm/time.c - */ - -extern void ioctime_init(void); - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - do_timer(regs); - do_set_rtc(); - do_profile(regs); - - { - /* Twinkle the lights. */ - static int count, state = 0xff00; - if (count-- == 0) { - state ^= 0x100; - count = 25; - *((volatile unsigned int *)LED_ADDRESS) = state; - } - } - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt. - */ -void __init time_init(void) -{ - ioctime_init(); - - timer_irq.handler = timer_interrupt; - - setup_irq(IRQ_TIMER, &timer_irq); -} diff --git a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h deleted file mode 100644 index c482e372b012..000000000000 --- a/include/asm-arm/arch-ebsa110/time.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/time.h - * - * Copyright (C) 1996,1997,1998 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * No real time clock on the evalulation board! - * - * Changelog: - * 10-Oct-1996 RMK Created - * 04-Dec-1997 RMK Updated for new arch/arm/kernel/time.c - * 07-Aug-1998 RMK Updated for arch/arm/kernel/leds.c - * 28-Dec-1998 APH Made leds code optional - */ - -#include -#include - -extern unsigned long (*gettimeoffset)(void); - -#define PIT_CTRL (PIT_BASE + 0x0d) -#define PIT_T2 (PIT_BASE + 0x09) -#define PIT_T1 (PIT_BASE + 0x05) -#define PIT_T0 (PIT_BASE + 0x01) - -/* - * This is the rate at which your MCLK signal toggles (in Hz) - * This was measured on a 10 digit frequency counter sampling - * over 1 second. - */ -#define MCLK 47894000 - -/* - * This is the rate at which the PIT timers get clocked - */ -#define CLKBY7 (MCLK / 7) - -/* - * This is the counter value. We tick at 200Hz on this platform. - */ -#define COUNT ((CLKBY7 + (HZ / 2)) / HZ) - -/* - * Get the time offset from the system PIT. Note that if we have missed an - * interrupt, then the PIT counter will roll over (ie, be negative). - * This actually works out to be convenient. - */ -static unsigned long ebsa110_gettimeoffset(void) -{ - unsigned long offset, count; - - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - /* - * If count > COUNT, make the number negative. - */ - if (count > COUNT) - count |= 0xffff0000; - - offset = COUNT; - offset -= count; - - /* - * `offset' is in units of timer counts. Convert - * offset to units of microseconds. - */ - offset = offset * (1000000 / HZ) / COUNT; - - return offset; -} - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 count; - - /* latch and read timer 1 */ - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - count += COUNT; - - __raw_writeb(count & 0xff, PIT_T1); - __raw_writeb(count >> 8, PIT_T1); - - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt. - */ -void __init time_init(void) -{ - /* - * Timer 1, mode 2, LSB/MSB - */ - __raw_writeb(0x70, PIT_CTRL); - __raw_writeb(COUNT & 0xff, PIT_T1); - __raw_writeb(COUNT >> 8, PIT_T1); - - gettimeoffset = ebsa110_gettimeoffset; - - timer_irq.handler = timer_interrupt; - - setup_irq(IRQ_EBSA110_TIMER0, &timer_irq); -} - - diff --git a/include/asm-arm/arch-ebsa285/time.h b/include/asm-arm/arch-ebsa285/time.h deleted file mode 100644 index f651eeb655be..000000000000 --- a/include/asm-arm/arch-ebsa285/time.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa285/time.h - * - * Copyright (C) 1998 Russell King. - * Copyright (C) 1998 Phil Blundell - * - * CATS has a real-time clock, though the evaluation board doesn't. - * - * Changelog: - * 21-Mar-1998 RMK Created - * 27-Aug-1998 PJB CATS support - * 28-Dec-1998 APH Made leds optional - * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder - * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in - */ - -#define RTC_PORT(x) (rtc_base+(x)) -#define RTC_ALWAYS_BCD 0 - -#include -#include - -#include -#include -#include - -static int rtc_base; - -#define mSEC_10_from_14 ((14318180 + 100) / 200) - -static unsigned long isa_gettimeoffset(void) -{ - int count; - - static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; - - /* timer count may underflow right here */ - outb_p(0x00, 0x43); /* latch the count ASAP */ - - count = inb_p(0x40); /* read the latched count */ - - /* - * We do this guaranteed double memory access instead of a _p - * postfix in the previous port access. Wheee, hackady hack - */ - jiffies_t = jiffies; - - count |= inb_p(0x40) << 8; - - /* Detect timer underflows. If we haven't had a timer tick since - the last time we were called, and time is apparently going - backwards, the counter must have wrapped during this routine. */ - if ((jiffies_t == jiffies_p) && (count > count_p)) - count -= (mSEC_10_from_14/6); - else - jiffies_p = jiffies_t; - - count_p = count; - - count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000); - count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); - - return count; -} - -static irqreturn_t -isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - if (machine_is_netwinder()) - do_leds(); - - do_timer(regs); - do_set_rtc(); - do_profile(regs); - - return IRQ_HANDLED; -} - -static unsigned long __init get_isa_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - int i; - - // check to see if the RTC makes sense..... - if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) - return mktime(1970, 1, 1, 0, 0, 0); - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - if ((year += 1900) < 1970) - year += 100; - return mktime(year, mon, day, hour, min, sec); -} - -static int -set_isa_cmos_time(void) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - unsigned long nowtime = xtime.tv_sec; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else - retval = -1; - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - - -static unsigned long timer1_latch; - -static unsigned long timer1_gettimeoffset (void) -{ - unsigned long value = timer1_latch - *CSR_TIMER1_VALUE; - - return ((tick_nsec / 1000) * value) / timer1_latch; -} - -static irqreturn_t -timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - *CSR_TIMER1_CLR = 0; - - /* Do the LEDs things */ - do_leds(); - do_timer(regs); - do_set_rtc(); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt. - */ -void __init time_init(void) -{ - int irq; - - if (machine_is_co285() || - machine_is_personal_server()) - /* - * Add-in 21285s shouldn't access the RTC - */ - rtc_base = 0; - else - rtc_base = 0x70; - - if (rtc_base) { - int reg_d, reg_b; - - /* - * Probe for the RTC. - */ - reg_d = CMOS_READ(RTC_REG_D); - - /* - * make sure the divider is set - */ - CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); - - /* - * Set control reg B - * (24 hour mode, update enabled) - */ - reg_b = CMOS_READ(RTC_REG_B) & 0x7f; - reg_b |= 2; - CMOS_WRITE(reg_b, RTC_REG_B); - - if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && - CMOS_READ(RTC_REG_B) == reg_b) { - struct timespec tv; - - /* - * We have a RTC. Check the battery - */ - if ((reg_d & 0x80) == 0) - printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); - - tv.tv_nsec = 0; - tv.tv_sec = get_isa_cmos_time(); - do_settimeofday(&tv); - set_rtc = set_isa_cmos_time; - } else - rtc_base = 0; - } - - if (machine_is_ebsa285() || - machine_is_co285() || - machine_is_personal_server()) { - gettimeoffset = timer1_gettimeoffset; - - timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ); - - *CSR_TIMER1_CLR = 0; - *CSR_TIMER1_LOAD = timer1_latch; - *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; - - timer_irq.handler = timer1_interrupt; - irq = IRQ_TIMER1; - } else { - /* enable PIT timer */ - /* set for periodic (4) and LSB/MSB write (0x30) */ - outb(0x34, 0x43); - outb((mSEC_10_from_14/6) & 0xFF, 0x40); - outb((mSEC_10_from_14/6) >> 8, 0x40); - - gettimeoffset = isa_gettimeoffset; - timer_irq.handler = isa_timer_interrupt; - irq = IRQ_ISA_TIMER; - } - setup_irq(irq, &timer_irq); -} diff --git a/include/asm-arm/arch-epxa10db/time.h b/include/asm-arm/arch-epxa10db/time.h deleted file mode 100644 index 749770b83e9a..000000000000 --- a/include/asm-arm/arch-epxa10db/time.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * linux/include/asm-arm/arch-epxa10db/time.h - * - * Copyright (C) 2001 Altera 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 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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 - */ -#include -#include -#include -#define TIMER00_TYPE (volatile unsigned int*) -#include - - -/* - * IRQ handler for the timer - */ -static irqreturn_t -excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - - // ...clear the interrupt - *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK; - - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init time_init(void) -{ - timer_irq.handler = excalibur_timer_interrupt; - - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMER0, &timer_irq); - - /* Start the timer */ - *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200); - *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1; - *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK; -} diff --git a/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h index 6b67e41669f4..09ec7902f4bf 100644 --- a/include/asm-arm/arch-integrator/platform.h +++ b/include/asm-arm/arch-integrator/platform.h @@ -457,6 +457,10 @@ #define mSEC_25 (mSEC_1 * 25) #define SEC_1 (mSEC_1 * 1000) +#ifndef __ASSEMBLY__ +extern void integrator_time_init(unsigned long, unsigned int); +#endif + #define INTEGRATOR_CSR_BASE 0x10000000 #define INTEGRATOR_CSR_SIZE 0x10000000 diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h index 52c1c445c536..b8ea57968d4a 100644 --- a/include/asm-arm/arch-ixp4xx/platform.h +++ b/include/asm-arm/arch-ixp4xx/platform.h @@ -58,6 +58,7 @@ struct ixp4xx_i2c_pins { */ extern void ixp4xx_map_io(void); extern void ixp4xx_init_irq(void); +extern void ixp4xx_init_time(void); extern void ixp4xx_pci_preinit(void); struct pci_sys_data; extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); diff --git a/include/asm-arm/arch-lh7a40x/time.h b/include/asm-arm/arch-lh7a40x/time.h deleted file mode 100644 index 5f1cf4f9b2c7..000000000000 --- a/include/asm-arm/arch-lh7a40x/time.h +++ /dev/null @@ -1,53 +0,0 @@ -/* include/asm-arm/arch-lh7a40x/time.h - * - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#if HZ < 100 -# define TIMER_CONTROL TIMER_CONTROL1 -# define TIMER_LOAD TIMER_LOAD1 -# define TIMER_CONSTANT (508469/HZ) -# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC | TIMER_C_508KHZ) -# define TIMER_EOI TIMER_EOI1 -# define TIMER_IRQ IRQ_T1UI -#else -# define TIMER_CONTROL TIMER_CONTROL3 -# define TIMER_LOAD TIMER_LOAD3 -# define TIMER_CONSTANT (3686400/HZ) -# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC) -# define TIMER_EOI TIMER_EOI3 -# define TIMER_IRQ IRQ_T3UI -#endif - -static irqreturn_t -lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - TIMER_EOI = 0; - do_profile (regs); - do_leds(); - do_set_rtc(); - do_timer (regs); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - /* Stop/disable all timers */ - TIMER_CONTROL1 = 0; - TIMER_CONTROL2 = 0; - TIMER_CONTROL3 = 0; - - timer_irq.handler = lh7a40x_timer_interrupt; - timer_irq.flags |= SA_INTERRUPT; - setup_irq (TIMER_IRQ, &timer_irq); - - TIMER_LOAD = TIMER_CONSTANT; - TIMER_CONTROL = TIMER_MODE; -} - diff --git a/include/asm-arm/arch-omap/time.h b/include/asm-arm/arch-omap/time.h deleted file mode 100644 index 9e3cc951ebb4..000000000000 --- a/include/asm-arm/arch-omap/time.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/time.h - * - * 32kHz timer definition - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: Greg Lonnon - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#if !defined(__ASM_ARCH_OMAP_TIME_H) -#define __ASM_ARCH_OMAP_TIME_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __instrument -#define __instrument -#define __noinstrument __attribute__ ((no_instrument_function)) -#endif - -typedef struct { - u32 cntl; /* CNTL_TIMER, R/W */ - u32 load_tim; /* LOAD_TIM, W */ - u32 read_tim; /* READ_TIM, R */ -} mputimer_regs_t; - -#define mputimer_base(n) \ - ((volatile mputimer_regs_t*)IO_ADDRESS(OMAP_MPUTIMER_BASE + \ - (n)*OMAP_MPUTIMER_OFF)) - -static inline unsigned long timer32k_read(int reg) { - unsigned long val; - val = omap_readw(reg + OMAP_32kHz_TIMER_BASE); - return val; -} -static inline void timer32k_write(int reg,int val) { - omap_writew(val, reg + OMAP_32kHz_TIMER_BASE); -} - -/* - * How long is the timer interval? 100 HZ, right... - * IRQ rate = (TVR + 1) / 32768 seconds - * TVR = 32768 * IRQ_RATE -1 - * IRQ_RATE = 1/100 - * TVR = 326 - */ -#define TIMER32k_PERIOD 326 -//#define TIMER32k_PERIOD 0x7ff - -static inline void start_timer32k(void) { - timer32k_write(TIMER32k_CR, - TIMER32k_TSS | TIMER32k_TRB | - TIMER32k_INT | TIMER32k_ARL); -} - -#ifdef CONFIG_MACH_OMAP_PERSEUS2 -/* - * After programming PTV with 0 and setting the MPUTIM_CLOCK_ENABLE - * (external clock enable) bit, the timer count rate is 6.5 MHz (13 - * MHZ input/2). !! The divider by 2 is undocumented !! - */ -#define MPUTICKS_PER_SEC (13000000/2) -#else -/* - * After programming PTV with 0, the timer count rate is 6 MHz. - * WARNING! this must be an even number, or machinecycles_to_usecs - * below will break. - */ -#define MPUTICKS_PER_SEC (12000000/2) -#endif - -static int mputimer_started[3] = {0,0,0}; - -static inline void __noinstrument start_mputimer(int n, - unsigned long load_val) -{ - volatile mputimer_regs_t* timer = mputimer_base(n); - - mputimer_started[n] = 0; - timer->cntl = MPUTIM_CLOCK_ENABLE; - udelay(1); - - timer->load_tim = load_val; - udelay(1); - timer->cntl = (MPUTIM_CLOCK_ENABLE | MPUTIM_AR | MPUTIM_ST); - mputimer_started[n] = 1; -} - -static inline unsigned long __noinstrument -read_mputimer(int n) -{ - volatile mputimer_regs_t* timer = mputimer_base(n); - return (mputimer_started[n] ? timer->read_tim : 0); -} - -void __noinstrument start_mputimer1(unsigned long load_val) -{ - start_mputimer(0, load_val); -} -void __noinstrument start_mputimer2(unsigned long load_val) -{ - start_mputimer(1, load_val); -} -void __noinstrument start_mputimer3(unsigned long load_val) -{ - start_mputimer(2, load_val); -} - -unsigned long __noinstrument read_mputimer1(void) -{ - return read_mputimer(0); -} -unsigned long __noinstrument read_mputimer2(void) -{ - return read_mputimer(1); -} -unsigned long __noinstrument read_mputimer3(void) -{ - return read_mputimer(2); -} - -unsigned long __noinstrument do_getmachinecycles(void) -{ - return 0 - read_mputimer(0); -} - -unsigned long __noinstrument machinecycles_to_usecs(unsigned long mputicks) -{ - /* Round up to nearest usec */ - return ((mputicks * 1000) / (MPUTICKS_PER_SEC / 2 / 1000) + 1) >> 1; -} - -/* - * This marks the time of the last system timer interrupt - * that was *processed by the ISR* (timer 2). - */ -static unsigned long systimer_mark; - -static unsigned long omap1510_gettimeoffset(void) -{ - /* Return elapsed usecs since last system timer ISR */ - return machinecycles_to_usecs(do_getmachinecycles() - systimer_mark); -} - -static irqreturn_t -omap1510_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned long now, ilatency; - - /* - * Mark the time at which the timer interrupt ocurred using - * timer1. We need to remove interrupt latency, which we can - * retrieve from the current system timer2 counter. Both the - * offset timer1 and the system timer2 are counting at 6MHz, - * so we're ok. - */ - now = 0 - read_mputimer1(); - ilatency = MPUTICKS_PER_SEC / 100 - read_mputimer2(); - systimer_mark = now - ilatency; - - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - /* Since we don't call request_irq, we must init the structure */ - gettimeoffset = omap1510_gettimeoffset; - - timer_irq.handler = omap1510_timer_interrupt; - timer_irq.flags = SA_INTERRUPT; -#ifdef OMAP1510_USE_32KHZ_TIMER - timer32k_write(TIMER32k_CR, 0x0); - timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD); - setup_irq(INT_OS_32kHz_TIMER, &timer_irq); - start_timer32k(); -#else - setup_irq(INT_TIMER2, &timer_irq); - start_mputimer2(MPUTICKS_PER_SEC / 100 - 1); -#endif -} - -#endif diff --git a/include/asm-arm/arch-pxa/time.h b/include/asm-arm/arch-pxa/time.h deleted file mode 100644 index bc9437a8c38d..000000000000 --- a/include/asm-arm/arch-pxa/time.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * linux/include/asm-arm/arch-pxa/time.h - * - * Author: Nicolas Pitre - * Created: Jun 15, 2001 - * Copyright: MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - -static inline unsigned long pxa_get_rtc_time(void) -{ - return RCNR; -} - -static int pxa_set_rtc(void) -{ - unsigned long current_time = xtime.tv_sec; - - if (RTSR & RTSR_ALE) { - /* make sure not to forward the clock over an alarm */ - unsigned long alarm = RTAR; - if (current_time >= alarm && alarm >= RCNR) - return -ERESTARTSYS; - } - RCNR = current_time; - return 0; -} - -/* IRQs are disabled before entering here from do_gettimeofday() */ -static unsigned long pxa_gettimeoffset (void) -{ - long ticks_to_match, elapsed, usec; - - /* Get ticks before next timer match */ - ticks_to_match = OSMR0 - OSCR; - - /* We need elapsed ticks since last match */ - elapsed = LATCH - ticks_to_match; - - /* don't get fooled by the workaround in pxa_timer_interrupt() */ - if (elapsed <= 0) - return 0; - - /* Now convert them to usec */ - usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; - - return usec; -} - -static irqreturn_t -pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - int next_match; - - do_profile(regs); - - /* Loop until we get ahead of the free running timer. - * This ensures an exact clock tick count and time accuracy. - * IRQs are disabled inside the loop to ensure coherence between - * lost_ticks (updated in do_timer()) and the match reg value, so we - * can use do_gettimeofday() from interrupt handlers. - * - * HACK ALERT: it seems that the PXA timer regs aren't updated right - * away in all cases when a write occurs. We therefore compare with - * 8 instead of 0 in the while() condition below to avoid missing a - * match if OSCR has already reached the next OSMR value. - * Experience has shown that up to 6 ticks are needed to work around - * this problem, but let's use 8 to be conservative. Note that this - * affect things only when the timer IRQ has been delayed by nearly - * exactly one tick period which should be a pretty rare event. - */ - do { - do_leds(); - do_set_rtc(); - do_timer(regs); - OSSR = OSSR_M0; /* Clear match on timer 0 */ - next_match = (OSMR0 += LATCH); - } while( (signed long)(next_match - OSCR) <= 8 ); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - struct timespec tv; - - gettimeoffset = pxa_gettimeoffset; - set_rtc = pxa_set_rtc; - - tv.tv_nsec = 0; - tv.tv_sec = pxa_get_rtc_time(); - do_settimeofday(&tv); - - timer_irq.handler = pxa_timer_interrupt; - OSMR0 = 0; /* set initial match at 0 */ - OSSR = 0xf; /* clear status on all timers */ - setup_irq(IRQ_OST0, &timer_irq); - OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer, force first match */ -} - diff --git a/include/asm-arm/arch-rpc/time.h b/include/asm-arm/arch-rpc/time.h deleted file mode 100644 index 1df6a12cd0e3..000000000000 --- a/include/asm-arm/arch-rpc/time.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/include/asm-arm/arch-rpc/time.h - * - * Copyright (C) 1996-2000 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * 24-Sep-1996 RMK Created - * 10-Oct-1996 RMK Brought up to date with arch-sa110eval - * 04-Dec-1997 RMK Updated for new arch/arm/time.c - */ -extern void ioctime_init(void); - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - do_timer(regs); - do_set_rtc(); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt. - */ -void __init time_init(void) -{ - ioctime_init(); - - timer_irq.handler = timer_interrupt; - - setup_irq(IRQ_TIMER, &timer_irq); -} diff --git a/include/asm-arm/arch-s3c2410/time.h b/include/asm-arm/arch-s3c2410/time.h deleted file mode 100644 index 8aab3438a992..000000000000 --- a/include/asm-arm/arch-s3c2410/time.h +++ /dev/null @@ -1,173 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/time.h - * - * Copyright (C) 2003 Simtec Electronics - * Ben Dooks, - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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 - */ - -#include -#include -#include - -#include -#include -#include - -extern unsigned long (*gettimeoffset)(void); - -static unsigned long timer_startval; -static unsigned long timer_ticks_usec; - -#ifdef CONFIG_S3C2410_RTC -extern void s3c2410_rtc_check(); -#endif - -/* with an 12MHz clock, we get 12 ticks per-usec - */ - - -/*** - * Returns microsecond since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - * IRQs are disabled before entering here from do_gettimeofday() - */ -static unsigned long s3c2410_gettimeoffset (void) -{ - unsigned long tdone; - unsigned long usec; - - /* work out how many ticks have gone since last timer interrupt */ - - tdone = timer_startval - __raw_readl(S3C2410_TCNTO(4)); - - /* currently, tcnt is in 12MHz units, but this may change - * for non-bast machines... - */ - - usec = tdone / timer_ticks_usec; - - return usec; -} - - -/* - * IRQ handler for the timer - */ -static irqreturn_t -s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - do_leds(); - do_timer(regs); - - do_set_rtc(); - //s3c2410_rtc_check(); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt, and return the current time in seconds. - */ - -/* currently we only use timer4, as it is the only timer which has no - * other function that can be exploited externally -*/ - -void __init time_init (void) -{ - unsigned long tcon; - unsigned long tcnt; - unsigned long tcfg1; - unsigned long tcfg0; - - gettimeoffset = s3c2410_gettimeoffset; - timer_irq.handler = s3c2410_timer_interrupt; - - tcnt = 0xffff; /* default value for tcnt */ - - /* read the current timer configuration bits */ - - tcon = __raw_readl(S3C2410_TCON); - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg0 = __raw_readl(S3C2410_TCFG0); - - /* configure the system for whichever machine is in use */ - - if (machine_is_bast() || machine_is_vr1000()) { - timer_ticks_usec = 12; /* timer is at 12MHz */ - tcnt = (timer_ticks_usec * (1000*1000)) / HZ; - } - - /* for the h1940, we use the pclk from the core to generate - * the timer values. since 67.5MHz is not a value we can directly - * generate the timer value from, we need to pre-scale and - * divied before using it. - * - * overall divsior to get 200Hz is 337500 - * we can fit tcnt if we pre-scale by 6, producing a tick rate - * of 11.25MHz, and a tcnt of 56250. - */ - - if (machine_is_h1940() || machine_is_smdk2410() ) { - timer_ticks_usec = s3c2410_pclk / (1000*1000); - timer_ticks_usec /= 6; - - tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; - tcfg1 |= S3C2410_TCFG1_MUX4_DIV2; - - tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; - tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT; - - tcnt = (s3c2410_pclk / 6) / HZ; - } - - - printk("setup_timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx\n", - tcon, tcnt, tcfg0, tcfg1); - - /* check to see if timer is within 16bit range... */ - if (tcnt > 0xffff) { - panic("setup_timer: HZ is too small, cannot configure timer!"); - return; - } - - __raw_writel(tcfg1, S3C2410_TCFG1); - __raw_writel(tcfg0, S3C2410_TCFG0); - - timer_startval = tcnt; - __raw_writel(tcnt, S3C2410_TCNTB(4)); - - /* ensure timer is stopped... */ - - tcon &= ~(7<<20); - tcon |= S3C2410_TCON_T4RELOAD; - tcon |= S3C2410_TCON_T4MANUALUPD; - - __raw_writel(tcon, S3C2410_TCON); - __raw_writel(tcnt, S3C2410_TCNTB(4)); - __raw_writel(tcnt, S3C2410_TCMPB(4)); - - setup_irq(IRQ_TIMER4, &timer_irq); - - /* start the timer running */ - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; - __raw_writel(tcon, S3C2410_TCON); -} - - - diff --git a/include/asm-arm/arch-sa1100/time.h b/include/asm-arm/arch-sa1100/time.h deleted file mode 100644 index d962626154dd..000000000000 --- a/include/asm-arm/arch-sa1100/time.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * linux/include/asm-arm/arch-sa1100/time.h - * - * Copyright (C) 1998 Deborah Wallach. - * Twiddles (C) 1999 Hugo Fiennes - * - * 2000/03/29 (C) Nicolas Pitre - * Rewritten: big cleanup, much simpler, better HZ accuracy. - * - */ - - -#define RTC_DEF_DIVIDER (32768 - 1) -#define RTC_DEF_TRIM 0 - -static unsigned long __init sa1100_get_rtc_time(void) -{ - /* - * According to the manual we should be able to let RTTR be zero - * and then a default diviser for a 32.768KHz clock is used. - * Apparently this doesn't work, at least for my SA1110 rev 5. - * If the clock divider is uninitialized then reset it to the - * default value to get the 1Hz clock. - */ - if (RTTR == 0) { - RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); - printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n"); - /* The current RTC value probably doesn't make sense either */ - RCNR = 0; - return 0; - } - return RCNR; -} - -static int sa1100_set_rtc(void) -{ - unsigned long current_time = xtime.tv_sec; - - if (RTSR & RTSR_ALE) { - /* make sure not to forward the clock over an alarm */ - unsigned long alarm = RTAR; - if (current_time >= alarm && alarm >= RCNR) - return -ERESTARTSYS; - } - RCNR = current_time; - return 0; -} - -/* IRQs are disabled before entering here from do_gettimeofday() */ -static unsigned long sa1100_gettimeoffset (void) -{ - unsigned long ticks_to_match, elapsed, usec; - - /* Get ticks before next timer match */ - ticks_to_match = OSMR0 - OSCR; - - /* We need elapsed ticks since last match */ - elapsed = LATCH - ticks_to_match; - - /* Now convert them to usec */ - usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; - - return usec; -} - -/* - * We will be entered with IRQs enabled. - * - * Loop until we get ahead of the free running timer. - * This ensures an exact clock tick count and time accuracy. - * IRQs are disabled inside the loop to ensure coherence between - * lost_ticks (updated in do_timer()) and the match reg value, so we - * can use do_gettimeofday() from interrupt handlers. - */ -static irqreturn_t -sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int next_match; - - do { - do_leds(); - do_timer(regs); - OSSR = OSSR_M0; /* Clear match on timer 0 */ - next_match = (OSMR0 += LATCH); - do_set_rtc(); - } while ((signed long)(next_match - OSCR) <= 0); - - do_profile(regs); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - struct timespec tv; - - gettimeoffset = sa1100_gettimeoffset; - set_rtc = sa1100_set_rtc; - - tv.tv_nsec = 0; - tv.tv_sec = sa1100_get_rtc_time(); - do_settimeofday(&tv); - - timer_irq.handler = sa1100_timer_interrupt; - OSMR0 = 0; /* set initial match at 0 */ - OSSR = 0xf; /* clear status on all timers */ - setup_irq(IRQ_OST0, &timer_irq); - OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer, force first match */ -} - diff --git a/include/asm-arm/arch-shark/time.h b/include/asm-arm/arch-shark/time.h deleted file mode 100644 index 66e45254a628..000000000000 --- a/include/asm-arm/arch-shark/time.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/include/asm-arm/arch-shark/time.h - * - * by Alexander Schulz - * - * derived from include/asm-arm/arch-ebsa110/time.h - * Copyright (c) 1996,1997,1998 Russell King. - */ - -#include -#include - -#define IRQ_TIMER 0 -#define HZ_TIME ((1193180 + HZ/2) / HZ) - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init time_init(void) -{ - unsigned long flags; - - outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */ - outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ - outb(HZ_TIME >> 8, 0x40); - - timer_irq.handler = timer_interrupt; - setup_irq(IRQ_TIMER, &timer_irq); -} diff --git a/include/asm-arm/arch-tbox/time.h b/include/asm-arm/arch-tbox/time.h deleted file mode 100644 index 461787189e1e..000000000000 --- a/include/asm-arm/arch-tbox/time.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/include/asm-arm/arch-tbox/time.h - * - * Copyright (c) 1997, 1999 Phil Blundell. - * Copyright (c) 2000 FutureTV Labs Ltd - * - * Tbox has no real-time clock -- we get millisecond ticks to update - * our soft copy. - */ - -/* - * 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. - */ - -#include -#include - -#define update_rtc() - -static irqreturn_t -timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) -{ - /* Clear irq */ - __raw_writel(1, FPGA1CONT + 0xc); - __raw_writel(0, FPGA1CONT + 0xc); - - do_timer(regs); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - timer_irq.handler = timer_interrupt; - setup_irq(IRQ_TIMER, &timer_irq); -} diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index d751faf725de..7841941c0e25 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -45,6 +45,8 @@ struct machine_desc { struct meminfo *); void (*map_io)(void);/* IO mapping function */ void (*init_irq)(void); + void (*init_time)(void); + void (*gettimeoffset)(void); void (*init_machine)(void); }; @@ -87,6 +89,9 @@ const struct machine_desc __mach_desc_##_type \ #define INITIRQ(_func) \ .init_irq = _func, +#define INITTIME(_func) \ + .init_time = _func, + #define INIT_MACHINE(_func) \ .init_machine = _func, -- cgit v1.2.3 From 04b928363634a28ff931f064488351da038f2493 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 04:16:01 -0700 Subject: [ARM] Remove bogus gettimeoffset ptr from machine_desc struct. This was accidently added during the timer code cleanup. Signed-off-by: Deepak Saxena --- include/asm-arm/mach/arch.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index 7841941c0e25..37ae74796331 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -46,7 +46,6 @@ struct machine_desc { void (*map_io)(void);/* IO mapping function */ void (*init_irq)(void); void (*init_time)(void); - void (*gettimeoffset)(void); void (*init_machine)(void); }; -- cgit v1.2.3 From 65f8e7460d289df22f91f8b15801d5681d6dbbc7 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 04:38:14 -0700 Subject: [ARM] Delete include/asm-arm/arch-nexuspci/time.h Signed-off-by: Deepak Saxena --- include/asm-arm/arch-nexuspci/time.h | 62 ------------------------------------ 1 file changed, 62 deletions(-) delete mode 100644 include/asm-arm/arch-nexuspci/time.h (limited to 'include') diff --git a/include/asm-arm/arch-nexuspci/time.h b/include/asm-arm/arch-nexuspci/time.h deleted file mode 100644 index c0fd0cdc9cb0..000000000000 --- a/include/asm-arm/arch-nexuspci/time.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * linux/include/asm-arm/arch-nexuspci/time.h - * - * Copyright (c) 1997, 1998, 1999, 2000 FutureTV Labs Ltd. - * - * The FTV PCI card has no real-time clock. We get timer ticks from the - * SCC chip. - */ - -/* - * 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. - */ - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - static int count = 25; - unsigned char stat = __raw_readb(DUART_BASE + 0x14); - if (!(stat & 0x10)) - return; /* Not for us */ - - /* Reset counter */ - __raw_writeb(0x90, DUART_BASE + 8); - - if (--count == 0) { - static int state = 1; - state ^= 1; - __raw_writeb(0x1a + state, INTCONT_BASE); - __raw_writeb(0x18 + state, INTCONT_BASE); - count = 50; - } - - /* Wait for slow rise time */ - __raw_readb(DUART_BASE + 0x14); - __raw_readb(DUART_BASE + 0x14); - __raw_readb(DUART_BASE + 0x14); - __raw_readb(DUART_BASE + 0x14); - __raw_readb(DUART_BASE + 0x14); - __raw_readb(DUART_BASE + 0x14); - - do_timer(regs); - - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - int tick = 3686400 / 16 / 2 / 100; - - __raw_writeb(tick & 0xff, DUART_BASE + 0x1c); - __raw_writeb(tick >> 8, DUART_BASE + 0x18); - __raw_writeb(0x80, DUART_BASE + 8); - __raw_writeb(0x10, DUART_BASE + 0x14); - - timer_irq.handler = timer_interrupt; - timer_irq.flags = SA_SHIRQ; - - setup_irq(IRQ_TIMER, &timer_irq); -} -- cgit v1.2.3 From d1e1909659c468219aee7547f58ebc631bbd4423 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 04:42:18 -0700 Subject: [ARM] Delete include/asm-arm/arch-iop3xx/time.h Signed-off-by: Deepak Saxena --- include/asm-arm/arch-iop3xx/time.h | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 include/asm-arm/arch-iop3xx/time.h (limited to 'include') diff --git a/include/asm-arm/arch-iop3xx/time.h b/include/asm-arm/arch-iop3xx/time.h deleted file mode 100644 index b58ac84f954e..000000000000 --- a/include/asm-arm/arch-iop3xx/time.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop80310/time.h - * - * Author: Nicolas Pitre - * Copyright: (C) 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -- cgit v1.2.3 From f20ebfbaf07c164e83c6000ead7169839fde6085 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 04:45:01 -0700 Subject: [ARM] Delete include/asm-arm/arch-ixp4xx/time.h Signed-off-by: Deepak Saxena --- include/asm-arm/arch-ixp4xx/time.h | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 include/asm-arm/arch-ixp4xx/time.h (limited to 'include') diff --git a/include/asm-arm/arch-ixp4xx/time.h b/include/asm-arm/arch-ixp4xx/time.h deleted file mode 100644 index e79f4acbe7b3..000000000000 --- a/include/asm-arm/arch-ixp4xx/time.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * linux/include/asm-arm/arch-ixp4xx/time.h - * - * We implement timer code in arch/arm/mach-ixp4xx/time.c - * - */ - -- cgit v1.2.3 From 237b1524ef4a23008076a36258bdb06f5bd7453f Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 05:00:23 -0700 Subject: [ARM] Delete include/asm-arm/arch-versatile/time.h Signed-off-by: Deepak Saxena --- include/asm-arm/arch-versatile/time.h | 158 ---------------------------------- 1 file changed, 158 deletions(-) delete mode 100644 include/asm-arm/arch-versatile/time.h (limited to 'include') diff --git a/include/asm-arm/arch-versatile/time.h b/include/asm-arm/arch-versatile/time.h deleted file mode 100644 index 7d97d9565a4b..000000000000 --- a/include/asm-arm/arch-versatile/time.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * linux/include/asm-arm/arch-versatile/time.h - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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 - */ -#include -#include - -/* - * Where is the timer (VA)? - */ -#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE) -#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20) -#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE) -#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20) -#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE) - -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ -#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_CTRL 0x80 /* Enable */ -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - -extern unsigned long (*gettimeoffset)(void); - -/* - * Returns number of ms since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -static unsigned long versatile_gettimeoffset(void) -{ - volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; - unsigned long ticks1, ticks2, status; - - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = timer0->TimerValue & 0xffff; - do { - ticks1 = ticks2; - status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); - ticks2 = timer0->TimerValue & 0xffff; - } while (ticks2 > ticks1); - - /* - * Number of ticks since last interrupt. - */ - ticks1 = TIMER_RELOAD - ticks2; - - /* - * Interrupt pending? If so, we've reloaded once already. - * - * FIXME: Need to check this is effectively timer 0 that expires - */ - if (status & IRQMASK_TIMERINT0_1) - ticks1 += TIMER_RELOAD; - - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - - // ...clear the interrupt - timer0->TimerClear = 1; - - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init time_init(void) -{ - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; - - /* - * set clock frequency: - * VERSATILE_REFCLK is 32KHz - * VERSATILE_TIMCLK is 1MHz - */ - *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= - ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); - - timer_irq.handler = versatile_timer_interrupt; - - /* - * Initialise to a known state (all timers off) - */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - timer3->TimerControl = 0; - - timer0->TimerLoad = TIMER_RELOAD; - timer0->TimerValue = TIMER_RELOAD; - timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ - - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT0_1, &timer_irq); - gettimeoffset = versatile_gettimeoffset; -} -- cgit v1.2.3 From 9ab6f3220efd4b4d11ba7d9fafdc6ce7b0707981 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Tue, 15 Jun 2004 05:32:48 -0700 Subject: [ARM] Add include/asm-arm/mach/time.h for shared timer definitions Signed-off-by: Deepak Saxena --- include/asm-arm/mach/time.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/asm-arm/mach/time.h (limited to 'include') diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h new file mode 100644 index 000000000000..a473e6dfc878 --- /dev/null +++ b/include/asm-arm/mach/time.h @@ -0,0 +1,24 @@ +/* + * linux/include/asm-arm/mach/time.h + * + * Copyright (C) 2004 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_MACH_TIME_H +#define __ASM_ARM_MACH_TIME_H + +extern void (*init_arch_time)(void); + +void do_set_rtc(void); + +void do_profile(struct pt_regs *); + +void do_leds(void); + +extern int (*set_rtc)(void); +extern unsigned long(*gettimeoffset)(void); + +#endif -- cgit v1.2.3 From 4e54c4816bfe51c145382d272b19c2ae41e9e36f Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 15 Jun 2004 06:37:41 -0700 Subject: [NET]: Add tc extensions infrastructure. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 + include/linux/pkt_cls.h | 171 +++++++- include/linux/pkt_sched.h | 1 + include/linux/rtnetlink.h | 17 + include/linux/skbuff.h | 10 +- include/net/pkt_act.h | 286 ++++++++++++++ include/net/pkt_cls.h | 32 +- include/net/pkt_sched.h | 80 +++- net/core/dev.c | 81 ++++ net/core/rtnetlink.c | 6 +- net/core/skbuff.c | 23 ++ net/ethernet/eth.c | 3 + net/sched/Kconfig | 35 +- net/sched/Makefile | 4 +- net/sched/act_api.c | 978 ++++++++++++++++++++++++++++++++++++++++++++++ net/sched/cls_api.c | 23 +- net/sched/cls_fw.c | 177 ++++++++- net/sched/cls_route.c | 6 +- net/sched/cls_rsvp.h | 6 +- net/sched/cls_tcindex.c | 4 +- net/sched/cls_u32.c | 187 ++++++++- net/sched/police.c | 330 +++++++++++++++- net/sched/sch_ingress.c | 72 +++- net/sched/sch_prio.c | 72 +++- 24 files changed, 2539 insertions(+), 67 deletions(-) create mode 100644 include/net/pkt_act.h create mode 100644 net/sched/act_api.c (limited to 'include') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a55f97a34035..6402659e2e6a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -366,6 +366,8 @@ struct net_device struct Qdisc *qdisc_ingress; unsigned long tx_queue_len; /* Max frames per queue allowed */ + /* ingress path synchronizer */ + spinlock_t ingress_lock; /* hard_start_xmit synchronizer */ spinlock_t xmit_lock; /* cpu id of processor entered to hard_start_xmit or -1, diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index f54111f9d14c..74daa67e81c9 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -1,14 +1,130 @@ #ifndef __LINUX_PKT_CLS_H #define __LINUX_PKT_CLS_H +/* I think i could have done better macros ; for now this is stolen from + * some arch/mips code - jhs +*/ +#define _TC_MAKE32(x) ((x)) + +#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) +#define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n)) +#define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n)) +#define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n)) + +/* verdict bit breakdown + * +bit 0: when set -> this packet has been munged already + +bit 1: when set -> It is ok to munge this packet + +bit 2,3,4,5: Reclassify counter - sort of reverse TTL - if exceeded +assume loop + +bit 6,7: Where this packet was last seen +0: Above the transmit example at the socket level +1: on the Ingress +2: on the Egress + +bit 8: when set --> Request not to classify on ingress. + +bits 9,10,11: redirect counter - redirect TTL. Loop avoidance + + * + * */ + +#define TC_MUNGED _TC_MAKEMASK1(0) +#define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED)) +#define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED) + +#define TC_OK2MUNGE _TC_MAKEMASK1(1) +#define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE)) +#define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE) + +#define S_TC_VERD _TC_MAKE32(2) +#define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD) +#define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD) +#define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD) +#define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD)) + +#define S_TC_FROM _TC_MAKE32(6) +#define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM) +#define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM) +#define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM) +#define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM)) +#define AT_STACK 0x0 +#define AT_INGRESS 0x1 +#define AT_EGRESS 0x2 + +#define TC_NCLS _TC_MAKEMASK1(8) +#define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS)) +#define CLR_TC_NCLS(v) ( v & ~TC_NCLS) + +#define S_TC_RTTL _TC_MAKE32(9) +#define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL) +#define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL) +#define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL) +#define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL)) + +#define S_TC_AT _TC_MAKE32(12) +#define M_TC_AT _TC_MAKEMASK(2,S_TC_AT) +#define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT) +#define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT) +#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) + +/* Action types */ +enum +{ + TCA_ACT_UNSPEC=0, + TCA_ACT_KIND=1, + TCA_ACT_OPTIONS=2, + TCA_ACT_INDEX=3, + TCA_ACT_POLICE=4, + /* other actions go here */ + __TCA_ACT_MAX=255 +}; + +#define TCA_ACT_MAX __TCA_ACT_MAX +#define TCA_OLD_COMPAT (TCA_ACT_MAX+1) +#define TCA_ACT_MAX_PRIO 32 +#define TCA_ACT_BIND 1 +#define TCA_ACT_NOBIND 0 +#define TCA_ACT_UNBIND 1 +#define TCA_ACT_NOUNBIND 0 +#define TCA_ACT_REPLACE 1 +#define TCA_ACT_NOREPLACE 0 +#define MAX_REC_LOOP 4 +#define MAX_RED_LOOP 4 + +#define TC_ACT_UNSPEC (-1) +#define TC_ACT_OK 0 +#define TC_ACT_RECLASSIFY 1 +#define TC_ACT_SHOT 2 +#define TC_ACT_PIPE 3 +#define TC_ACT_STOLEN 4 +#define TC_ACT_QUEUED 5 +#define TC_ACT_REPEAT 6 +#define TC_ACT_JUMP 0x10000000 + struct tc_police { __u32 index; +#ifdef CONFIG_NET_CLS_ACT + int refcnt; + int bindcnt; +#endif +/* Turned off because it requires new tc + * to work (for now maintain ABI) + * +#ifdef CONFIG_NET_CLS_ACT + __u32 capab; +#endif +*/ int action; -#define TC_POLICE_UNSPEC (-1) -#define TC_POLICE_OK 0 -#define TC_POLICE_RECLASSIFY 1 -#define TC_POLICE_SHOT 2 +#define TC_POLICE_UNSPEC TC_ACT_UNSPEC +#define TC_POLICE_OK TC_ACT_OK +#define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY +#define TC_POLICE_SHOT TC_ACT_SHOT +#define TC_POLICE_PIPE TC_ACT_PIPE __u32 limit; __u32 burst; @@ -17,6 +133,26 @@ struct tc_police struct tc_ratespec peakrate; }; +struct tcf_t +{ + __u32 install; + __u32 lastuse; + __u32 expires; +}; + +struct tc_cnt +{ + int refcnt; + int bindcnt; +}; + +#define tc_gen \ + __u32 index; \ + __u32 capab; \ + int action; \ + int refcnt; \ + int bindcnt + enum { TCA_POLICE_UNSPEC, @@ -25,8 +161,8 @@ enum TCA_POLICE_PEAKRATE, TCA_POLICE_AVRATE, TCA_POLICE_RESULT, -#define TCA_POLICE_RESULT TCA_POLICE_RESULT __TCA_POLICE_MAX +#define TCA_POLICE_RESULT TCA_POLICE_RESULT }; #define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1) @@ -50,6 +186,12 @@ enum TCA_U32_DIVISOR, TCA_U32_SEL, TCA_U32_POLICE, +#ifdef CONFIG_NET_CLS_ACT + TCA_U32_ACT, +#endif +#ifdef CONFIG_NET_CLS_IND + TCA_U32_INDEV, +#endif __TCA_U32_MAX }; @@ -61,6 +203,9 @@ struct tc_u32_key __u32 val; int off; int offmask; +#ifdef CONFIG_CLS_U32_PERF + unsigned long kcnt; +#endif }; struct tc_u32_sel @@ -68,6 +213,7 @@ struct tc_u32_sel unsigned char flags; unsigned char offshift; unsigned char nkeys; + unsigned char fshift; /* fold shift */ __u16 offmask; __u16 off; @@ -75,7 +221,10 @@ struct tc_u32_sel short hoff; __u32 hmask; - +#ifdef CONFIG_CLS_U32_PERF + unsigned long rcnt; + unsigned long rhit; +#endif struct tc_u32_key keys[0]; }; @@ -102,7 +251,7 @@ enum __TCA_RSVP_MAX }; -#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1) +#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 ) struct tc_rsvp_gpi { @@ -143,6 +292,12 @@ enum TCA_FW_UNSPEC, TCA_FW_CLASSID, TCA_FW_POLICE, +#ifdef CONFIG_NET_CLS_IND + TCA_FW_INDEV, +#endif +#ifdef CONFIG_NET_CLS_ACT + TCA_FW_ACT, +#endif __TCA_FW_MAX }; @@ -162,6 +317,6 @@ enum __TCA_TCINDEX_MAX }; -#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1) +#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1) #endif diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index a3d6b59af515..437cf3206e0e 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -37,6 +37,7 @@ struct tc_stats __u32 bps; /* Current flow byte rate */ __u32 pps; /* Current flow packet rate */ __u32 qlen; + __u32 reqs; /* number of requeues happened */ __u32 backlog; #ifdef __KERNEL__ spinlock_t *lock; diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 4b3a0b5d44b6..366eae3b4fc3 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -44,6 +44,10 @@ #define RTM_DELTFILTER (RTM_BASE+29) #define RTM_GETTFILTER (RTM_BASE+30) +#define RTM_NEWACTION (RTM_BASE+32) +#define RTM_DELACTION (RTM_BASE+33) +#define RTM_GETACTION (RTM_BASE+34) + #define RTM_NEWPREFIX (RTM_BASE+36) #define RTM_GETPREFIX (RTM_BASE+38) @@ -639,6 +643,7 @@ enum TCA_STATS, TCA_XSTATS, TCA_RATE, + TCA_FCNT, __TCA_MAX }; @@ -673,6 +678,18 @@ enum #define RTMGRP_IPV6_PREFIX 0x20000 +/* TC action piece */ +struct tcamsg +{ + unsigned char tca_family; + unsigned char tca__pad1; + unsigned short tca__pad2; +}; +#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) +#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) +#define TCA_ACT_TAB 1 /* attr type must be >=1 */ +#define TCAA_MAX 1 + /* End of information exported to user level */ #ifdef __KERNEL__ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7bf6501a9024..dcadb7781b9d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -155,6 +155,7 @@ struct skb_shared_info { * @sk: Socket we are owned by * @stamp: Time we arrived * @dev: Device we arrived on/are leaving by + * @input_dev: Device we arrived on * @real_dev: The real device we are using * @h: Transport layer header * @nh: Network layer header @@ -197,6 +198,7 @@ struct sk_buff { struct sock *sk; struct timeval stamp; struct net_device *dev; + struct net_device *input_dev; struct net_device *real_dev; union { @@ -262,9 +264,15 @@ struct sk_buff { } private; #endif #ifdef CONFIG_NET_SCHED - __u32 tc_index; /* traffic control index */ + __u32 tc_index; /* traffic control index */ +#ifdef CONFIG_NET_CLS_ACT + __u32 tc_verd; /* traffic control verdict */ + __u32 tc_classid; /* traffic control classid */ + #endif + #endif + /* These elements must be at the end, see alloc_skb() for details. */ unsigned int truesize; atomic_t users; diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h new file mode 100644 index 000000000000..390b82aea577 --- /dev/null +++ b/include/net/pkt_act.h @@ -0,0 +1,286 @@ +#ifndef __NET_PKT_ACT_H +#define __NET_PKT_ACT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define tca_st(val) (struct tcf_##val *) +#define PRIV(a,name) ( tca_st(name) (a)->priv) + +#if 0 /* control */ +#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) +#else +#define DPRINTK(format,args...) +#endif + +#if 0 /* data */ +#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args) +#else +#define D2PRINTK(format,args...) +#endif + +static __inline__ unsigned +tcf_hash(u32 index) +{ + return index & MY_TAB_MASK; +} + +/* probably move this from being inline + * and put into act_generic +*/ +static inline void +tcf_hash_destroy(struct tcf_st *p) +{ + unsigned h = tcf_hash(p->index); + struct tcf_st **p1p; + + for (p1p = &tcf_ht[h]; *p1p; p1p = &(*p1p)->next) { + if (*p1p == p) { + write_lock_bh(&tcf_t_lock); + *p1p = p->next; + write_unlock_bh(&tcf_t_lock); +#ifdef CONFIG_NET_ESTIMATOR + qdisc_kill_estimator(&p->stats); +#endif + kfree(p); + return; + } + } + BUG_TRAP(0); +} + +static inline void +tcf_hash_release(struct tcf_st *p, int bind ) +{ + if (p) { + if (bind) { + p->bindcnt--; + } + p->refcnt--; + if (p->refcnt > 0) + MOD_DEC_USE_COUNT; + if(p->bindcnt <=0 && p->refcnt <= 0) { + tcf_hash_destroy(p); + } + } +} + +static __inline__ int +tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, + struct tc_action *a) +{ + struct tcf_st *p; + int err =0, index = -1,i= 0, s_i = 0, n_i = 0; + struct rtattr *r ; + + read_lock(&tcf_t_lock); + + s_i = cb->args[0]; + + for (i = 0; i < MY_TAB_SIZE; i++) { + p = tcf_ht[tcf_hash(i)]; + + for (; p; p = p->next) { + index++; + if (index < s_i) + continue; + a->priv = p; + a->order = n_i; + r = (struct rtattr*) skb->tail; + RTA_PUT(skb, a->order, 0, NULL); + err = tcf_action_dump_1(skb, a, 0, 0); + if (0 > err) { + index--; + skb_trim(skb, (u8*)r - skb->data); + goto done; + } + r->rta_len = skb->tail - (u8*)r; + n_i++; + if (n_i >= TCA_ACT_MAX_PRIO) { + printk("Jamal Dump Exceeded batch limit\n"); + goto done; + } + } + } +done: + read_unlock(&tcf_t_lock); + if (n_i) + cb->args[0] += n_i; + return n_i; + +rtattr_failure: + skb_trim(skb, (u8*)r - skb->data); + goto done; +} + +static __inline__ int +tcf_del_walker(struct sk_buff *skb, struct tc_action *a) +{ + struct tcf_st *p, *s_p; + struct rtattr *r ; + int i= 0, n_i = 0; + + r = (struct rtattr*) skb->tail; + RTA_PUT(skb, a->order, 0, NULL); + RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + for (i = 0; i < MY_TAB_SIZE; i++) { + p = tcf_ht[tcf_hash(i)]; + + while (p != NULL) { + s_p = p->next; + printk("tcf_del_walker deleting ..\n"); + tcf_hash_release(p, 0); + n_i++; + p = s_p; + } + } + RTA_PUT(skb, TCA_FCNT, 4, &n_i); + r->rta_len = skb->tail - (u8*)r; + + return n_i; +rtattr_failure: + skb_trim(skb, (u8*)r - skb->data); + return -EINVAL; +} + +static __inline__ int +tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, + struct tc_action *a) +{ + if (type == RTM_DELACTION) { + return tcf_del_walker(skb,a); + } else if (type == RTM_GETACTION) { + return tcf_dump_walker(skb,cb,a); + } else { + printk("tcf_generic_walker: unknown action %d\n",type); + return -EINVAL; + } +} + +static __inline__ struct tcf_st * +tcf_hash_lookup(u32 index) +{ + struct tcf_st *p; + + read_lock(&tcf_t_lock); + for (p = tcf_ht[tcf_hash(index)]; p; p = p->next) { + if (p->index == index) + break; + } + read_unlock(&tcf_t_lock); + return p; +} + +static __inline__ u32 +tcf_hash_new_index(void) +{ + do { + if (++idx_gen == 0) + idx_gen = 1; + } while (tcf_hash_lookup(idx_gen)); + + return idx_gen; +} + + +static inline int +tcf_hash_search(struct tc_action *a, u32 index) +{ + struct tcf_st *p = tcf_hash_lookup(index); + + if (p != NULL) { + a->priv = p; + return 1; + } else { + return 0; + } +} + +#ifdef CONFIG_NET_ACT_INIT +static inline struct tcf_st * +tcf_hash_check(struct tc_st *parm, struct tc_action *a, int ovr, int bind) +{ + struct tcf_st *p = NULL; + if (parm->index && (p = tcf_hash_lookup(parm->index)) != NULL) { + spin_lock(&p->lock); + if (bind) { + p->bindcnt++; + p->refcnt++; + } + spin_unlock(&p->lock); + a->priv = (void *) p; + } + return p; +} + +static inline struct tcf_st * +tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind) +{ + unsigned h; + struct tcf_st *p = NULL; + + p = kmalloc(size, GFP_KERNEL); + if (p == NULL) + return p; + + memset(p, 0, size); + p->refcnt = 1; + + if (bind) { + p->bindcnt = 1; + } + + MOD_INC_USE_COUNT; + spin_lock_init(&p->lock); + p->stats.lock = &p->lock; + p->index = parm->index ? : tcf_hash_new_index(); + p->tm.install = jiffies; + p->tm.lastuse = jiffies; +#ifdef CONFIG_NET_ESTIMATOR + if (est) { + qdisc_new_estimator(&p->stats, est); + } +#endif + h = tcf_hash(p->index); + write_lock_bh(&tcf_t_lock); + p->next = tcf_ht[h]; + tcf_ht[h] = p; + write_unlock_bh(&tcf_t_lock); + + a->priv = (void *) p; + return p; +} + +static inline struct tcf_st * +tcf_hash_init(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind) +{ + struct tcf_st *p; + p = tcf_hash_check (parm,a,ovr,bind); + if (NULL == p) { + return tcf_hash_create(parm, est, a, size, ovr, bind); + } +} + +#endif + +#endif diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index ca07367721df..4de3ea73ca5d 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -71,12 +71,38 @@ static inline int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, struct { int err = 0; u32 protocol = skb->protocol; +#ifdef CONFIG_NET_CLS_ACT + struct tcf_proto *otp = tp; +reclassify: +#endif + protocol = skb->protocol; for ( ; tp; tp = tp->next) { if ((tp->protocol == protocol || - tp->protocol == __constant_htons(ETH_P_ALL)) && - (err = tp->classify(skb, tp, res)) >= 0) + tp->protocol == __constant_htons(ETH_P_ALL)) && + (err = tp->classify(skb, tp, res)) >= 0) { +#ifdef CONFIG_NET_CLS_ACT + if ( TC_ACT_RECLASSIFY == err) { + __u32 verd = (__u32) G_TC_VERD(skb->tc_verd); + tp = otp; + + if (MAX_REC_LOOP < verd++) { + printk("rule prio %d protocol %02x reclassify is buggy packet dropped\n",tp->prio&0xffff, ntohs(tp->protocol)); + return TC_ACT_SHOT; + } + skb->tc_verd = SET_TC_VERD(skb->tc_verd,verd); + goto reclassify; + } else { + if (skb->tc_verd) + skb->tc_verd = SET_TC_VERD(skb->tc_verd,0); + return err; + } +#else + return err; +#endif + } + } return -1; } @@ -90,6 +116,8 @@ static inline void tcf_destroy(struct tcf_proto *tp) extern int register_tcf_proto_ops(struct tcf_proto_ops *ops); extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); +extern int ing_filter(struct sk_buff *skb); + diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 80661d855fd8..eb6c344ddd95 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -12,11 +12,14 @@ #include #include #include +#include +#include #ifdef CONFIG_X86_TSC #include #endif + struct rtattr; struct Qdisc; @@ -390,14 +393,15 @@ struct tcf_police { struct tcf_police *next; int refcnt; +#ifdef CONFIG_NET_CLS_ACT + int bindcnt; +#endif u32 index; - int action; int result; u32 ewma_rate; u32 burst; u32 mtu; - u32 toks; u32 ptoks; psched_time_t t_c; @@ -408,16 +412,84 @@ struct tcf_police struct tc_stats stats; }; +#ifdef CONFIG_NET_CLS_ACT + +#define tca_gen(name) \ +struct tcf_##name *next; \ + u32 index; \ + int refcnt; \ + int bindcnt; \ + u32 capab; \ + int action; \ + struct tcf_t tm; \ + struct tc_stats stats; \ + spinlock_t lock + + +struct tc_action +{ + void *priv; + struct tc_action_ops *ops; + __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ + __u32 order; + struct tc_action *next; +}; + +#define TCA_CAP_NONE 0 +struct tc_action_ops +{ + struct tc_action_ops *next; + char kind[IFNAMSIZ]; + __u32 type; /* TBD to match kind */ + __u32 capab; /* capabilities includes 4 bit version */ + int (*act)(struct sk_buff **, struct tc_action *); + int (*get_stats)(struct sk_buff *, struct tc_action *); + int (*dump)(struct sk_buff *, struct tc_action *,int , int); + void (*cleanup)(struct tc_action *, int bind); + int (*lookup)(struct tc_action *, u32 ); + int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); + int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); +}; + +extern int tcf_register_action(struct tc_action_ops *a); +extern int tcf_unregister_action(struct tc_action_ops *a); +extern void tcf_action_destroy(struct tc_action *a, int bind); +extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a); +extern int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind); +extern int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind); +extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int); +extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); +extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); +extern int tcf_action_copy_stats (struct sk_buff *,struct tc_action *); +extern int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *,int , int ); +extern int tcf_act_police_dump(struct sk_buff *, struct tc_action *, int, int); +extern int tcf_act_police(struct sk_buff **skb, struct tc_action *a); +#endif + +extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st); extern void tcf_police_destroy(struct tcf_police *p); extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); -extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); -static inline void tcf_police_release(struct tcf_police *p) +static inline void tcf_police_release(struct tcf_police *p, int bind) { +#ifdef CONFIG_NET_CLS_ACT + if (p) { + if (bind) { + p->bindcnt--; + } + p->refcnt--; + if (p->refcnt > 0) + MOD_DEC_USE_COUNT; + if (p->refcnt <= 0 && !p->bindcnt) + tcf_police_destroy(p); + } +#else if (p && --p->refcnt == 0) tcf_police_destroy(p); + +#endif } extern struct Qdisc noop_qdisc; diff --git a/net/core/dev.c b/net/core/dev.c index fb20e1047f27..e3ef7d5884ff 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1351,6 +1351,9 @@ int dev_queue_xmit(struct sk_buff *skb) /* Grab device queue */ spin_lock_bh(&dev->queue_lock); q = dev->qdisc; +#ifdef CONFIG_NET_CLS_ACT + skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); +#endif if (q->enqueue) { rc = q->enqueue(skb, q); @@ -1731,6 +1734,48 @@ static inline int __handle_bridge(struct sk_buff *skb, return 0; } + +#ifdef CONFIG_NET_CLS_ACT +/* TODO: Maybe we should just force sch_ingress to be compiled in + * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions + * a compare and 2 stores extra right now if we dont have it on + * but have CONFIG_NET_CLS_ACT + * NOTE: This doesnt stop any functionality; if you dont have + * the ingress scheduler, you just cant add policies on ingress. + * + */ +int ing_filter(struct sk_buff *skb) +{ + struct Qdisc *q; + struct net_device *dev = skb->dev; + int result = TC_ACT_OK; + + if (dev->qdisc_ingress) { + __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd); + if (MAX_RED_LOOP < ttl++) { + printk("Redir loop detected Dropping packet (%s->%s)\n", + skb->input_dev?skb->input_dev->name:"??",skb->dev->name); + return TC_ACT_SHOT; + } + + skb->tc_verd = SET_TC_RTTL(skb->tc_verd,ttl); + + skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); + if (NULL == skb->input_dev) { + skb->input_dev = skb->dev; + printk("ing_filter: fixed %s out %s\n",skb->input_dev->name,skb->dev->name); + } + spin_lock(&dev->ingress_lock); + if ((q = dev->qdisc_ingress) != NULL) + result = q->enqueue(skb, q); + spin_unlock(&dev->ingress_lock); + + } + + return result; +} +#endif + int netif_receive_skb(struct sk_buff *skb) { struct packet_type *ptype, *pt_prev; @@ -1762,6 +1807,13 @@ int netif_receive_skb(struct sk_buff *skb) skb->mac_len = skb->nh.raw - skb->mac.raw; pt_prev = NULL; +#ifdef CONFIG_NET_CLS_ACT + if (skb->tc_verd & TC_NCLS) { + skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); + goto ncls; + } + #endif + rcu_read_lock(); list_for_each_entry_rcu(ptype, &ptype_all, list) { if (!ptype->dev || ptype->dev == skb->dev) { @@ -1771,6 +1823,26 @@ int netif_receive_skb(struct sk_buff *skb) } } +#ifdef CONFIG_NET_CLS_ACT + if (pt_prev) { + atomic_inc(&skb->users); + ret = pt_prev->func(skb, skb->dev, pt_prev); + pt_prev = NULL; /* noone else should process this after*/ + } else { + skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); + } + + ret = ing_filter(skb); + + if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) { + kfree_skb(skb); + goto out; + } + + skb->tc_verd = 0; +ncls: +#endif + handle_diverter(skb); if (__handle_bridge(skb, &pt_prev, &ret)) @@ -2824,6 +2896,10 @@ int register_netdevice(struct net_device *dev) spin_lock_init(&dev->queue_lock); spin_lock_init(&dev->xmit_lock); dev->xmit_lock_owner = -1; +#ifdef CONFIG_NET_CLS_ACT + spin_lock_init(&dev->ingress_lock); +#endif + #ifdef CONFIG_NET_FASTROUTE dev->fastpath_lock = RW_LOCK_UNLOCKED; #endif @@ -3358,4 +3434,9 @@ EXPORT_SYMBOL(netdev_fastroute); EXPORT_SYMBOL(netdev_fastroute_obstacles); #endif +#ifdef CONFIG_NET_CLS_ACT +EXPORT_SYMBOL(ing_filter); +#endif + + EXPORT_PER_CPU_SYMBOL(softnet_data); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 26e3577c0ec3..e652d8fbaa60 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -93,7 +93,8 @@ static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = NLMSG_LENGTH(sizeof(struct rtmsg)), NLMSG_LENGTH(sizeof(struct tcmsg)), NLMSG_LENGTH(sizeof(struct tcmsg)), - NLMSG_LENGTH(sizeof(struct tcmsg)) + NLMSG_LENGTH(sizeof(struct tcmsg)), + NLMSG_LENGTH(sizeof(struct tcamsg)) }; static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = @@ -105,7 +106,8 @@ static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = RTA_MAX, TCA_MAX, TCA_MAX, - TCA_MAX + TCA_MAX, + TCAA_MAX }; void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7d72cdb49a57..03a64d3ae6c2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -49,6 +49,9 @@ #include #include #include +#ifdef CONFIG_NET_CLS_ACT +#include +#endif #include #include #include @@ -241,6 +244,15 @@ void __kfree_skb(struct sk_buff *skb) nf_bridge_put(skb->nf_bridge); #endif #endif +/* XXX: IS this still necessary? - JHS */ +#ifdef CONFIG_NET_SCHED + skb->tc_index = 0; +#ifdef CONFIG_NET_CLS_ACT + skb->tc_verd = 0; + skb->tc_classid = 0; +#endif +#endif + kfree_skbmem(skb); } @@ -312,6 +324,14 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) #endif #ifdef CONFIG_NET_SCHED C(tc_index); +#ifdef CONFIG_NET_CLS_ACT + n->tc_verd = SET_TC_VERD(skb->tc_verd,0); + n->tc_verd = CLR_TC_OK2MUNGE(skb->tc_verd); + n->tc_verd = CLR_TC_MUNGED(skb->tc_verd); + C(input_dev); + C(tc_classid); +#endif + #endif C(truesize); atomic_set(&n->users, 1); @@ -366,6 +386,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) #endif #endif #ifdef CONFIG_NET_SCHED +#ifdef CONFIG_NET_CLS_ACT + new->tc_verd = old->tc_verd; +#endif new->tc_index = old->tc_index; #endif atomic_set(&new->users, 1); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 4b3fa0084cd5..9569f3a80f86 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -164,6 +164,9 @@ unsigned short eth_type_trans(struct sk_buff *skb, struct net_device *dev) skb->mac.raw=skb->data; skb_pull(skb,ETH_HLEN); eth= skb->mac.ethernet; +#ifdef CONFIG_NET_CLS_ACT + skb->input_dev = dev; +#endif if(*eth->h_dest&1) { diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 8931426e0243..481b8ad2b84c 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -177,7 +177,7 @@ config NET_SCH_DELAY config NET_SCH_INGRESS tristate "Ingress Qdisc" - depends on NET_SCHED && NETFILTER + depends on NET_SCHED help If you say Y here, you will be able to police incoming bandwidth and drop packets when this bandwidth exceeds your desired rate. @@ -274,6 +274,22 @@ config NET_CLS_U32 To compile this code as a module, choose M here: the module will be called cls_u32. +config CLS_U32_PERF + bool " U32 classifier perfomance counters" + depends on NET_CLS_U32 + help + gathers stats that could be used to tune u32 classifier perfomance. + Requires a new iproute2 + +config NET_CLS_IND + bool "classify input device (slows things u32/fw) " + depends on NET_CLS_U32 || NET_CLS_FW + help + This option will be killed eventually when a + metadata action appears because it slows things a little + Available only for u32 and fw classifiers. + Requires a new iproute2 + config NET_CLS_RSVP tristate "Special RSVP classifier" depends on NET_CLS && NET_QOS @@ -303,9 +319,24 @@ config NET_CLS_RSVP6 To compile this code as a module, choose M here: the module will be called cls_rsvp6. +config NET_CLS_ACT + bool ' Packet ACTION ' + depends on NET_CLS && NET_QOS + ---help--- + This option requires you have a new iproute2. It enables + tc extensions which can be used with tc classifiers. + Only the u32 and fw classifiers are supported at the moment. + +config NET_ACT_POLICE + tristate ' Policing Actions' + depends on NET_CLS_ACT + ---help--- + If you are using a newer iproute2 select this one, otherwise use one + NET_CLS_POLICE below + config NET_CLS_POLICE bool "Traffic policing (needed for in/egress)" - depends on NET_CLS && NET_QOS + depends on NET_CLS && NET_QOS && !NET_ACT_POLICE help Say Y to support traffic policing (bandwidth limits). Needed for ingress and egress rate limiting. diff --git a/net/sched/Makefile b/net/sched/Makefile index af4a4f284d3a..89d838fc7e77 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -7,7 +7,9 @@ obj-y := sch_generic.o obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o obj-$(CONFIG_NET_ESTIMATOR) += estimator.o obj-$(CONFIG_NET_CLS) += cls_api.o -obj-$(CONFIG_NET_CLS_POLICE) += police.o +obj-$(CONFIG_NET_CLS_ACT) += act_api.o +obj-$(CONFIG_NET_ACT_POLICE) += police.o +obj-$(CONFIG_NET_CLS_POLICE) += police.o obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o obj-$(CONFIG_NET_SCH_CSZ) += sch_csz.o diff --git a/net/sched/act_api.c b/net/sched/act_api.c new file mode 100644 index 000000000000..a0ba2f6363e9 --- /dev/null +++ b/net/sched/act_api.c @@ -0,0 +1,978 @@ +/* + * net/sched/act_api.c Packet action API. + * + * 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. + * + * Author: Jamal Hadi Salim + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if 1 /* control */ +#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) +#else +#define DPRINTK(format,args...) +#endif + +static struct tc_action_ops *act_base = NULL; +static rwlock_t act_mod_lock = RW_LOCK_UNLOCKED; + +int tcf_register_action(struct tc_action_ops *act) +{ + struct tc_action_ops *a, **ap; + + write_lock(&act_mod_lock); + for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) { + if (strcmp(act->kind, a->kind) == 0) { + write_unlock(&act_mod_lock); + return -EEXIST; + } + } + act->next = NULL; + *ap = act; + + write_unlock(&act_mod_lock); + + return 0; +} + +int tcf_unregister_action(struct tc_action_ops *act) +{ + struct tc_action_ops *a, **ap; + int err = -ENOENT; + + write_lock(&act_mod_lock); + for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) + if(a == act) + break; + + if (a) { + *ap = a->next; + a->next = NULL; + err = 0; + } + write_unlock(&act_mod_lock); + return err; +} + +/* lookup by name */ +struct tc_action_ops *tc_lookup_action_n(char *kind) +{ + + struct tc_action_ops *a = NULL; + + if (kind) { + read_lock(&act_mod_lock); + for (a = act_base; a; a = a->next) { + if (strcmp(kind,a->kind) == 0) + break; + } + read_unlock(&act_mod_lock); + } + + return a; +} + +/* lookup by rtattr */ +struct tc_action_ops *tc_lookup_action(struct rtattr *kind) +{ + + struct tc_action_ops *a = NULL; + + if (kind) { + read_lock(&act_mod_lock); + for (a = act_base; a; a = a->next) { + + if (strcmp((char*)RTA_DATA(kind),a->kind) == 0) + break; + } + read_unlock(&act_mod_lock); + } + + return a; +} + +/* lookup by id */ +struct tc_action_ops *tc_lookup_action_id(u32 type) +{ + struct tc_action_ops *a = NULL; + + if (type) { + read_lock(&act_mod_lock); + for (a = act_base; a; a = a->next) { + if (a->type == type) + break; + } + read_unlock(&act_mod_lock); + } + + return a; +} + +int tcf_action_exec(struct sk_buff *skb,struct tc_action *act) +{ + + struct tc_action *a; + int ret = -1; + + if (skb->tc_verd & TC_NCLS) { + skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); + DPRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",skb,skb->input_dev?skb->input_dev->name:"xxx",skb->dev->name); + return TC_ACT_OK; + } + while ((a = act) != NULL) { +repeat: + if (a->ops && a->ops->act) { + ret = a->ops->act(&skb,a); + if (TC_MUNGED & skb->tc_verd) { + /* copied already, allow trampling */ + skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); + skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); + } + + if (ret != TC_ACT_PIPE) + goto exec_done; + if (ret == TC_ACT_REPEAT) + goto repeat; /* we need a ttl - JHS */ + + } + act = a->next; + } + +exec_done: + + return ret; +} + +void tcf_action_destroy(struct tc_action *act, int bind) +{ + struct tc_action *a; + + for (a = act; act; a = act) { + if (a && a->ops && a->ops->cleanup) { + DPRINTK("tcf_action_destroy destroying %p next %p\n", a,a->next?a->next:NULL); + act = act->next; + a->ops->cleanup(a, bind); + a->ops = NULL; + kfree(a); + } else { /*FIXME: Remove later - catch insertion bugs*/ + printk("tcf_action_destroy: BUG? destroying NULL ops \n"); + if (a) { + act = act->next; + kfree(a); + } else { + printk("tcf_action_destroy: BUG? destroying NULL action! \n"); + break; + } + } + } +} + +int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) +{ + int err = -EINVAL; + + + if ( (NULL == a) || (NULL == a->ops) + || (NULL == a->ops->dump) ) + return err; + return a->ops->dump(skb, a, bind, ref); + +} + + +int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) +{ + int err = -EINVAL; + unsigned char *b = skb->tail; + struct rtattr *r; + + + if ( (NULL == a) || (NULL == a->ops) + || (NULL == a->ops->dump) || (NULL == a->ops->kind)) + return err; + + + RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + if (tcf_action_copy_stats(skb,a)) + goto rtattr_failure; + r = (struct rtattr*) skb->tail; + RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { + r->rta_len = skb->tail - (u8*)r; + return err; + } + + +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; + +} + +int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) +{ + struct tc_action *a; + int err = -EINVAL; + unsigned char *b = skb->tail; + struct rtattr *r ; + + while ((a = act) != NULL) { + r = (struct rtattr*) skb->tail; + act = a->next; + RTA_PUT(skb, a->order, 0, NULL); + err = tcf_action_dump_1(skb, a, bind, ref); + if (0 > err) + goto rtattr_failure; + + r->rta_len = skb->tail - (u8*)r; + } + + return 0; + +rtattr_failure: + skb_trim(skb, b - skb->data); + return -err; + +} + +int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr, int bind ) +{ + struct tc_action_ops *a_o; + char act_name[4 + IFNAMSIZ + 1]; + struct rtattr *tb[TCA_ACT_MAX+1]; + struct rtattr *kind = NULL; + + int err = -EINVAL; + + + if (NULL == name) { + if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) + goto err_out; + kind = tb[TCA_ACT_KIND-1]; + if (NULL != kind) { + sprintf(act_name, "%s", (char*)RTA_DATA(kind)); + if (RTA_PAYLOAD(kind) >= IFNAMSIZ) { + printk(" Action %s bad\n", (char*)RTA_DATA(kind)); + goto err_out; + } + + } else { + printk("Action bad kind\n"); + goto err_out; + } + a_o = tc_lookup_action(kind); + } else { + sprintf(act_name, "%s", name); + DPRINTK("tcf_action_init_1: finding %s\n",act_name); + a_o = tc_lookup_action_n(name); + } +#ifdef CONFIG_KMOD + if (NULL == a_o) { + DPRINTK("tcf_action_init_1: trying to load module %s\n",act_name); + request_module (act_name); + a_o = tc_lookup_action_n(act_name); + } + +#endif + if (NULL == a_o) { + printk("failed to find %s\n",act_name); + goto err_out; + } + + if (NULL == a) { + goto err_out; + } + + /* backward compatibility for policer */ + if (NULL == name) { + err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind); + if (0 > err ) { + return -EINVAL; + } + } else { + err = a_o->init(rta, est, a, ovr, bind); + if (0 > err ) { + return -EINVAL; + } + } + + DPRINTK("tcf_action_init_1: sucess %s\n",act_name); + + a->ops = a_o; + + return 0; +err_out: + return err; +} + +int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr , int bind) +{ + struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; + int i; + struct tc_action *act = a, *a_s = a; + + int err = -EINVAL; + + if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) + return err; + + for (i=0; i < TCA_ACT_MAX_PRIO ; i++) { + if (tb[i]) { + if (NULL == act) { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) { + err = -ENOMEM; + goto bad_ret; + } + memset(act, 0,sizeof(*act)); + } + act->next = NULL; + if (0 > tcf_action_init_1(tb[i],est,act,name,ovr,bind)) { + printk("Error processing action order %d\n",i); + return err; + } + + act->order = i+1; + if (a_s != act) { + a_s->next = act; + a_s = act; + } + act = NULL; + } + + } + + return 0; +bad_ret: + tcf_action_destroy(a, bind); + return err; +} + +int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a) +{ +#ifdef CONFIG_KMOD + /* place holder */ +#endif + + if (NULL == a->ops || NULL == a->ops->get_stats) + return 1; + + return a->ops->get_stats(skb,a); +} + + +static int +tca_get_fill(struct sk_buff *skb, struct tc_action *a, + u32 pid, u32 seq, unsigned flags, int event, int bind, int ref) +{ + struct tcamsg *t; + struct nlmsghdr *nlh; + unsigned char *b = skb->tail; + struct rtattr *x; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t)); + nlh->nlmsg_flags = flags; + t = NLMSG_DATA(nlh); + t->tca_family = AF_UNSPEC; + + x = (struct rtattr*) skb->tail; + RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + + if (0 > tcf_action_dump(skb, a, bind, ref)) { + goto rtattr_failure; + } + + x->rta_len = skb->tail - (u8*)x; + + nlh->nlmsg_len = skb->tail - b; + return skb->len; + +rtattr_failure: +nlmsg_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +static int act_get_notify(u32 pid, struct nlmsghdr *n, + struct tc_action *a, int event) +{ + struct sk_buff *skb; + + int err = 0; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + err = netlink_unicast(rtnl,skb, pid, MSG_DONTWAIT); + if (err > 0) + err = 0; + return err; +} + +int tcf_action_get_1(struct rtattr *rta, struct tc_action *a, struct nlmsghdr *n, u32 pid) +{ + struct tc_action_ops *a_o; + char act_name[4 + IFNAMSIZ + 1]; + struct rtattr *tb[TCA_ACT_MAX+1]; + struct rtattr *kind = NULL; + int index; + + int err = -EINVAL; + + if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) + goto err_out; + + + kind = tb[TCA_ACT_KIND-1]; + if (NULL != kind) { + sprintf(act_name, "%s", (char*)RTA_DATA(kind)); + if (RTA_PAYLOAD(kind) >= IFNAMSIZ) { + printk("tcf_action_get_1: action %s bad\n", (char*)RTA_DATA(kind)); + goto err_out; + } + + } else { + printk("tcf_action_get_1: action bad kind\n"); + goto err_out; + } + + if (tb[TCA_ACT_INDEX - 1]) { + index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]); + } else { + printk("tcf_action_get_1: index not received\n"); + goto err_out; + } + + a_o = tc_lookup_action(kind); +#ifdef CONFIG_KMOD + if (NULL == a_o) { + request_module (act_name); + a_o = tc_lookup_action_n(act_name); + } + +#endif + if (NULL == a_o) { + printk("failed to find %s\n",act_name); + goto err_out; + } + + if (NULL == a) { + goto err_out; + } + + a->ops = a_o; + + if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) + return -EINVAL; + + return 0; +err_out: + return err; +} + +void cleanup_a (struct tc_action *act) +{ + struct tc_action *a; + + for (a = act; act; a = act) { + if (a) { + act = act->next; + a->ops = NULL; + a->priv = NULL; + kfree(a); + } else { + printk("cleanup_a: BUG? empty action\n"); + } + } +} + +struct tc_action_ops *get_ao(struct rtattr *kind, struct tc_action *a) +{ + char act_name[4 + IFNAMSIZ + 1]; + struct tc_action_ops *a_o = NULL; + + if (NULL != kind) { + sprintf(act_name, "%s", (char*)RTA_DATA(kind)); + if (RTA_PAYLOAD(kind) >= IFNAMSIZ) { + printk("get_ao: action %s bad\n", (char*)RTA_DATA(kind)); + return NULL; + } + + } else { + printk("get_ao: action bad kind\n"); + return NULL; + } + + a_o = tc_lookup_action(kind); +#ifdef CONFIG_KMOD + if (NULL == a_o) { + DPRINTK("get_ao: trying to load module %s\n",act_name); + request_module (act_name); + a_o = tc_lookup_action_n(act_name); + } +#endif + + if (NULL == a_o) { + printk("get_ao: failed to find %s\n",act_name); + return NULL; + } + + a->ops = a_o; + return a_o; +} + +struct tc_action *create_a(int i) +{ + struct tc_action *act = NULL; + + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) { /* grrr .. */ + printk("create_a: failed to alloc! \n"); + return NULL; + } + + memset(act, 0,sizeof(*act)); + + act->order = i; + + return act; +} + +int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) +{ + struct sk_buff *skb; + unsigned char *b; + struct nlmsghdr *nlh; + struct tcamsg *t; + struct rtattr *x; + struct rtattr *tb[TCA_ACT_MAX+1]; + struct rtattr *kind = NULL; + struct tc_action *a = create_a(0); + int err = -EINVAL; + + if (NULL == a) { + printk("tca_action_flush: couldnt create tc_action\n"); + return err; + } + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) { + printk("tca_action_flush: failed skb alloc\n"); + kfree(a); + return -ENOBUFS; + } + + b = (unsigned char *)skb->tail; + + if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) { + goto err_out; + } + + kind = tb[TCA_ACT_KIND-1]; + if (NULL == get_ao(kind, a)) { + goto err_out; + } + + nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof (*t)); + t = NLMSG_DATA(nlh); + t->tca_family = AF_UNSPEC; + + x = (struct rtattr *) skb->tail; + RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + + err = a->ops->walk(skb, NULL, RTM_DELACTION, a); + if (0 > err ) { + goto rtattr_failure; + } + + x->rta_len = skb->tail - (u8 *) x; + + nlh->nlmsg_len = skb->tail - b; + nlh->nlmsg_flags |= NLM_F_ROOT; + kfree(a); + err = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + if (err > 0) + return 0; + + return err; + + +rtattr_failure: +nlmsg_failure: +err_out: + kfree_skb(skb); + kfree(a); + return err; +} + +int tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event ) +{ + + int s = 0; + int i, ret = 0; + struct tc_action *act = NULL; + struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; + struct tc_action *a = NULL, *a_s = NULL; + + if (event != RTM_GETACTION && event != RTM_DELACTION) + ret = -EINVAL; + + if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) { + ret = -EINVAL; + goto nlmsg_failure; + } + + if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { + if (NULL != tb[0] && NULL == tb[1]) { + return tca_action_flush(tb[0],n,pid); + } + } + + for (i=0; i < TCA_ACT_MAX_PRIO ; i++) { + + if (NULL == tb[i]) + break; + + act = create_a(i+1); + if (NULL != a && a != act) { + a->next = act; + a = act; + } else { + a = act; + } + + if (!s) { + s = 1; + a_s = a; + } + + ret = tcf_action_get_1(tb[i],act,n,pid); + if (ret < 0) { + printk("tcf_action_get: failed to get! \n"); + ret = -EINVAL; + goto rtattr_failure; + } + + } + + + if (RTM_GETACTION == event) { + ret = act_get_notify(pid, n, a_s, event); + } else { /* delete */ + + struct sk_buff *skb; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOBUFS; + goto nlmsg_failure; + } + + if (tca_get_fill(skb, a_s, pid, n->nlmsg_seq, 0, event, 0 , 1) <= 0) { + kfree_skb(skb); + ret = -EINVAL; + goto nlmsg_failure; + } + + /* now do the delete */ + tcf_action_destroy(a_s, 0); + + ret = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + if (ret > 0) + return 0; + return ret; + } +rtattr_failure: +nlmsg_failure: + cleanup_a(a_s); + return ret; +} + + +int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, unsigned flags) +{ + struct tcamsg *t; + struct nlmsghdr *nlh; + struct sk_buff *skb; + struct rtattr *x; + unsigned char *b; + + + int err = 0; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + b = (unsigned char *)skb->tail; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t)); + nlh->nlmsg_flags = flags; + t = NLMSG_DATA(nlh); + t->tca_family = AF_UNSPEC; + + x = (struct rtattr*) skb->tail; + RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + + if (0 > tcf_action_dump(skb, a, 0, 0)) { + goto rtattr_failure; + } + + x->rta_len = skb->tail - (u8*)x; + + nlh->nlmsg_len = skb->tail - b; + NETLINK_CB(skb).dst_groups = RTMGRP_TC; + + err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO); + if (err > 0) + err = 0; + + return err; + +rtattr_failure: +nlmsg_failure: + skb_trim(skb, b - skb->data); + return -1; +} + + +int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr ) +{ + int ret = 0; + struct tc_action *act = NULL; + struct tc_action *a = NULL; + u32 seq = n->nlmsg_seq; + + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + + ret = tcf_action_init(rta, NULL,act,NULL,ovr,0); + /* NOTE: We have an all-or-none model + * This means that of any of the actions fail + * to update then all are undone. + * */ + if (0 > ret) { + tcf_action_destroy(act, 0); + goto done; + } + + /* dump then free all the actions after update; inserted policy + * stays intact + * */ + ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); + for (a = act; act; a = act) { + if (a) { + act = act->next; + a->ops = NULL; + a->priv = NULL; + kfree(a); + } else { + printk("tcf_action_add: BUG? empty action\n"); + } + } +done: + + return ret; +} + +static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) +{ + struct rtattr **tca = arg; + u32 pid = skb ? NETLINK_CB(skb).pid : 0; + + int ret = 0, ovr = 0; + + if (NULL == tca[TCA_ACT_TAB-1]) { + printk("tc_ctl_action: received NO action attribs\n"); + return -EINVAL; + } + + /* n->nlmsg_flags&NLM_F_CREATE + * */ + switch (n->nlmsg_type) { + case RTM_NEWACTION: + /* we are going to assume all other flags + * imply create only if it doesnt exist + * Note that CREATE | EXCL implies that + * but since we want avoid ambiguity (eg when flags + * is zero) then just set this + */ + if (n->nlmsg_flags&NLM_F_REPLACE) { + ovr = 1; + } + ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr); + break; + case RTM_DELACTION: + ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_DELACTION); + break; + case RTM_GETACTION: + ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_GETACTION); + break; + default: + printk(" Unknown cmd was detected\n"); + break; + } + + return ret; +} + +char * +find_dump_kind(struct nlmsghdr *n) +{ + struct rtattr *tb1, *tb2[TCA_ACT_MAX_PRIO+1]; + struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; + struct rtattr *rta[TCAA_MAX + 1]; + struct rtattr *kind = NULL; + int min_len = NLMSG_LENGTH(sizeof (struct tcamsg)); + + int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len); + struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len); + + if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0) + return NULL; + tb1 = rta[TCA_ACT_TAB - 1]; + if (NULL == tb1) { + return NULL; + } + + if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0) + return NULL; + if (NULL == tb[0]) + return NULL; + + if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), RTA_PAYLOAD(tb[0]))<0) + return NULL; + kind = tb2[TCA_ACT_KIND-1]; + + return (char *) RTA_DATA(kind); +} + +static int +tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct nlmsghdr *nlh; + unsigned char *b = skb->tail; + struct rtattr *x; + struct tc_action_ops *a_o; + struct tc_action a; + int ret = 0; + + struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); + char *kind = find_dump_kind(cb->nlh); + if (NULL == kind) { + printk("tc_dump_action: action bad kind\n"); + return 0; + } + + a_o = tc_lookup_action_n(kind); + +#ifdef CONFIG_KMOD + if (NULL == a_o) { + DPRINTK("tc_dump_action: trying to load module %s\n", kind); + request_module(kind); + a_o = tc_lookup_action_n(kind); + } +#endif + if (NULL == a_o) { + printk("failed to find %s\n", kind); + return 0; + } + + memset(&a,0,sizeof(struct tc_action)); + a.ops = a_o; + + if (NULL == a_o->walk) { + printk("tc_dump_action: %s !capable of dumping table\n",kind); + goto rtattr_failure; + } + + nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, cb->nlh->nlmsg_type, sizeof (*t)); + t = NLMSG_DATA(nlh); + t->tca_family = AF_UNSPEC; + + x = (struct rtattr *) skb->tail; + RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + + ret = a_o->walk(skb, cb, RTM_GETACTION, &a); + if (0 > ret ) { + goto rtattr_failure; + } + + if (ret > 0) { + x->rta_len = skb->tail - (u8 *) x; + ret = skb->len; + } else { + skb_trim(skb, (u8*)x - skb->data); + } + + nlh->nlmsg_len = skb->tail - b; + if (NETLINK_CB(cb->skb).pid && ret) + nlh->nlmsg_flags |= NLM_F_MULTI; + return skb->len; + +rtattr_failure: +nlmsg_failure: + skb_trim(skb, b - skb->data); + return skb->len; +} + +static int __init tc_action_init(void) +{ + struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC]; + + if (link_p) { + link_p[RTM_NEWACTION-RTM_BASE].doit = tc_ctl_action; + link_p[RTM_DELACTION-RTM_BASE].doit = tc_ctl_action; + link_p[RTM_GETACTION-RTM_BASE].doit = tc_ctl_action; + link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action; + } + + printk("TC classifier action (bugs to netdev@oss.sgi.com cc hadi@cyberus.ca)\n"); + return 0; +} + +subsys_initcall(tc_action_init); + +EXPORT_SYMBOL(tcf_register_action); +EXPORT_SYMBOL(tcf_unregister_action); +EXPORT_SYMBOL(tcf_action_init_1); +EXPORT_SYMBOL(tcf_action_init); +EXPORT_SYMBOL(tcf_action_destroy); +EXPORT_SYMBOL(tcf_action_exec); +EXPORT_SYMBOL(tcf_action_copy_stats); +EXPORT_SYMBOL(tcf_action_dump); +EXPORT_SYMBOL(tcf_action_dump_1); +EXPORT_SYMBOL(tcf_action_dump_old); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index a48b75d54fb9..5d034cc0d874 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -11,6 +11,7 @@ * Changes: * * Eduardo J. Blanco :990222: kmod support + * */ #include @@ -36,6 +37,12 @@ #include #include +#if 0 /* control */ +#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) +#else +#define DPRINTK(format,args...) +#endif + /* The list of all installed classifier types */ static struct tcf_proto_ops *tcf_proto_base; @@ -132,7 +139,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) struct tcf_proto_ops *tp_ops; struct Qdisc_class_ops *cops; unsigned long cl = 0; - unsigned long fh; + unsigned long fh, fh_s; int err; if (prio == 0) { @@ -238,7 +245,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) } else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind)) goto errout; - fh = tp->ops->get(tp, t->tcm_handle); + fh_s = fh = tp->ops->get(tp, t->tcm_handle); if (fh == 0) { if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { @@ -247,6 +254,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) *back = tp->next; spin_unlock_bh(&dev->queue_lock); write_unlock(&qdisc_tree_lock); + tfilter_notify(skb, n, tp, fh_s, RTM_DELTFILTER); tcf_destroy(tp); err = 0; goto errout; @@ -264,6 +272,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) break; case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); + if (err == 0) + tfilter_notify(skb, n, tp, fh_s, RTM_DELTFILTER); goto errout; case RTM_GETTFILTER: err = tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); @@ -298,11 +308,14 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, tcm->tcm_family = AF_UNSPEC; tcm->tcm_ifindex = tp->q->dev->ifindex; tcm->tcm_parent = tp->classid; - tcm->tcm_handle = 0; tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); RTA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind); - if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) - goto rtattr_failure; + tcm->tcm_handle = fh; + if (RTM_DELTFILTER != event) { + tcm->tcm_handle = 0; + if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) + goto rtattr_failure; + } nlh->nlmsg_len = skb->tail - b; return skb->len; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 5b614b63aa66..6e0baf28e5ab 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -11,6 +11,11 @@ * Changes: * Karlis Peisenieks : 990415 : fw_walk off by one * Karlis Peisenieks : 990415 : fw_delete killed all the filter (and kernel). + * Alex : 2004xxyy: Added Action extension + * + * JHS: We should remove the CONFIG_NET_CLS_IND from here + * eventually when the meta match extension is made available + * */ #include @@ -50,9 +55,16 @@ struct fw_filter struct fw_filter *next; u32 id; struct tcf_result res; +#ifdef CONFIG_NET_CLS_ACT + struct tc_action *action; +#ifdef CONFIG_NET_CLS_IND + char indev[IFNAMSIZ]; +#endif +#else #ifdef CONFIG_NET_CLS_POLICE struct tcf_police *police; #endif +#endif }; static __inline__ int fw_hash(u32 handle) @@ -77,9 +89,28 @@ static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp, for (f=head->ht[fw_hash(id)]; f; f=f->next) { if (f->id == id) { *res = f->res; +#ifdef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NET_CLS_IND + if (0 != f->indev[0]) { + if (NULL == skb->input_dev) { + continue; + } else { + if (0 != strcmp(f->indev, skb->input_dev->name)) { + continue; + } + } + } +#endif + if (f->action) { + int pol_res = tcf_action_exec(skb, f->action); + if (pol_res >= 0) + return pol_res; + } else +#else #ifdef CONFIG_NET_CLS_POLICE if (f->police) return tcf_police(skb, f->police); +#endif #endif return 0; } @@ -136,9 +167,16 @@ static void fw_destroy(struct tcf_proto *tp) if ((cl = __cls_set_class(&f->res.class, 0)) != 0) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); +#ifdef CONFIG_NET_CLS_ACT + if (f->action) { + tcf_action_destroy(f->action,TCA_ACT_UNBIND); + } +#else #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); +#endif #endif + kfree(f); } } @@ -164,8 +202,14 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg) if ((cl = cls_set_class(tp, &f->res.class, 0)) != 0) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); +#ifdef CONFIG_NET_CLS_ACT + if (f->action) { + tcf_action_destroy(f->action,TCA_ACT_UNBIND); + } +#else #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); +#endif #endif kfree(f); return 0; @@ -185,6 +229,11 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_FW_MAX]; int err; +#ifdef CONFIG_NET_CLS_ACT + struct tc_action *act = NULL; + int ret; +#endif + if (!opt) return handle ? -EINVAL : 0; @@ -206,6 +255,58 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (cl) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); } +#ifdef CONFIG_NET_CLS_ACT + if (tb[TCA_FW_POLICE-1]) { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + + memset(act,0,sizeof(*act)); + ret = tcf_action_init_1(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1] ,act,"police",TCA_ACT_NOREPLACE,TCA_ACT_BIND); + if (0 > ret){ + tcf_action_destroy(act,TCA_ACT_UNBIND); + return ret; + } + act->type = TCA_OLD_COMPAT; + + sch_tree_lock(tp->q); + act = xchg(&f->action, act); + sch_tree_unlock(tp->q); + + tcf_action_destroy(act,TCA_ACT_UNBIND); + + } + + if(tb[TCA_FW_ACT-1]) { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + memset(act,0,sizeof(*act)); + ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL, TCA_ACT_NOREPLACE,TCA_ACT_BIND); + if (0 > ret) { + tcf_action_destroy(act,TCA_ACT_UNBIND); + return ret; + } + + sch_tree_lock(tp->q); + act = xchg(&f->action, act); + sch_tree_unlock(tp->q); + + tcf_action_destroy(act,TCA_ACT_UNBIND); + } +#ifdef CONFIG_NET_CLS_IND + if(tb[TCA_FW_INDEV-1]) { + struct rtattr *idev = tb[TCA_FW_INDEV-1]; + if (RTA_PAYLOAD(idev) >= IFNAMSIZ) { + printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev)); + err = -EINVAL; + goto errout; + } + memset(f->indev,0,IFNAMSIZ); + sprintf(f->indev, "%s", (char*)RTA_DATA(idev)); + } +#endif +#else /* only POLICE defined */ #ifdef CONFIG_NET_CLS_POLICE if (tb[TCA_FW_POLICE-1]) { struct tcf_police *police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]); @@ -214,8 +315,9 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, police = xchg(&f->police, police); tcf_tree_unlock(tp); - tcf_police_release(police); + tcf_police_release(police,TCA_ACT_UNBIND); } +#endif #endif return 0; } @@ -249,9 +351,36 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid)); } +#ifdef CONFIG_NET_CLS_ACT + if(tb[TCA_FW_ACT-1]) { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + memset(act,0,sizeof(*act)); + ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL,TCA_ACT_NOREPLACE,TCA_ACT_BIND); + if (0 > ret) { + tcf_action_destroy(act,TCA_ACT_UNBIND); + return ret; + } + f->action= act; + } +#ifdef CONFIG_NET_CLS_IND + if(tb[TCA_FW_INDEV-1]) { + struct rtattr *idev = tb[TCA_FW_INDEV-1]; + if (RTA_PAYLOAD(idev) >= IFNAMSIZ) { + printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev)); + err = -EINVAL; + goto errout; + } + memset(f->indev,0,IFNAMSIZ); + sprintf(f->indev, "%s", (char*)RTA_DATA(idev)); + } +#endif +#else #ifdef CONFIG_NET_CLS_POLICE if (tb[TCA_FW_POLICE-1]) f->police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]); +#endif #endif f->next = head->ht[fw_hash(handle)]; @@ -309,8 +438,12 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, t->tcm_handle = f->id; if (!f->res.classid +#ifdef CONFIG_NET_CLS_ACT + && !f->action +#else #ifdef CONFIG_NET_CLS_POLICE && !f->police +#endif #endif ) return skb->len; @@ -320,6 +453,36 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, if (f->res.classid) RTA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid); +#ifdef CONFIG_NET_CLS_ACT + /* again for backward compatible mode - we want + * to work with both old and new modes of entering + * tc data even if iproute2 was newer - jhs + */ + if (f->action) { + struct rtattr * p_rta = (struct rtattr*)skb->tail; + + if (f->action->type != TCA_OLD_COMPAT) { + RTA_PUT(skb, TCA_FW_ACT, 0, NULL); + if (tcf_action_dump(skb,f->action,0,0) < 0) { + goto rtattr_failure; + } + } else { + RTA_PUT(skb, TCA_FW_POLICE, 0, NULL); + if (tcf_action_dump_old(skb,f->action,0,0) < 0) { + goto rtattr_failure; + } + } + + p_rta->rta_len = skb->tail - (u8*)p_rta; + } +#ifdef CONFIG_NET_CLS_IND + if(strlen(f->indev)) { + struct rtattr * p_rta = (struct rtattr*)skb->tail; + RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev); + p_rta->rta_len = skb->tail - (u8*)p_rta; + } +#endif +#else #ifdef CONFIG_NET_CLS_POLICE if (f->police) { struct rtattr * p_rta = (struct rtattr*)skb->tail; @@ -331,14 +494,22 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, p_rta->rta_len = skb->tail - (u8*)p_rta; } +#endif #endif rta->rta_len = skb->tail - b; +#ifdef CONFIG_NET_CLS_ACT + if (f->action && f->action->type == TCA_OLD_COMPAT) { + if (tcf_action_copy_stats(skb,f->action)) + goto rtattr_failure; + } +#else #ifdef CONFIG_NET_CLS_POLICE if (f->police) { if (qdisc_copy_stats(skb, &f->police->stats)) goto rtattr_failure; } +#endif #endif return skb->len; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 4c09012edbce..d4dada10e6ef 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -297,7 +297,7 @@ static void route4_destroy(struct tcf_proto *tp) if ((cl = __cls_set_class(&f->res.class, 0)) != 0) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); #endif kfree(f); } @@ -336,7 +336,7 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); #endif kfree(f); @@ -398,7 +398,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, police = xchg(&f->police, police); tcf_tree_unlock(tp); - tcf_police_release(police); + tcf_police_release(police,TCA_ACT_UNBIND); } #endif return 0; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 85e028d84757..8ebaa2787d9a 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -278,7 +278,7 @@ static void rsvp_destroy(struct tcf_proto *tp) if ((cl = __cls_set_class(&f->res.class, 0)) != 0) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); #endif kfree(f); } @@ -310,7 +310,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police); + tcf_police_release(f->police,TCA_ACT_UNBIND); #endif kfree(f); @@ -452,7 +452,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, police = xchg(&f->police, police); tcf_tree_unlock(tp); - tcf_police_release(police); + tcf_police_release(police,TCA_ACT_UNBIND); } #endif return 0; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index adbc77dd2318..c696fcf8f166 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -190,7 +190,7 @@ found: if (cl) tp->q->ops->cl_ops->unbind_tcf(tp->q,cl); #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(r->police); + tcf_police_release(r->police, TCA_ACT_UNBIND); #endif if (f) kfree(f); @@ -333,7 +333,7 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle, tcf_tree_lock(tp); police = xchg(&r->police,police); tcf_tree_unlock(tp); - tcf_police_release(police); + tcf_police_release(police,TCA_ACT_UNBIND); } #endif if (r != &new_filter_result) diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 938d88744b63..7ea20b622fc8 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -23,6 +23,10 @@ * It is especially useful for link sharing combined with QoS; * pure RSVP doesn't need such a general approach and can use * much simpler (and faster) schemes, sort of cls_rsvp.c. + * + * JHS: We should remove the CONFIG_NET_CLS_IND from here + * eventually when the meta match extension is made available + * */ #include @@ -58,8 +62,15 @@ struct tc_u_knode struct tc_u_knode *next; u32 handle; struct tc_u_hnode *ht_up; +#ifdef CONFIG_NET_CLS_ACT + struct tc_action *action; +#ifdef CONFIG_NET_CLS_IND + char indev[IFNAMSIZ]; +#endif +#else #ifdef CONFIG_NET_CLS_POLICE struct tcf_police *police; +#endif #endif struct tcf_result res; struct tc_u_hnode *ht_down; @@ -90,10 +101,12 @@ static struct tc_u_common *u32_list; static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel) { - unsigned h = key & sel->hmask; + unsigned h = (key & sel->hmask)>>sel->fshift; + /* h ^= h>>16; h ^= h>>8; + */ return h; } @@ -119,22 +132,61 @@ next_knode: if (n) { struct tc_u32_key *key = n->sel.keys; +#ifdef CONFIG_CLS_U32_PERF + n->sel.rcnt +=1; +#endif for (i = n->sel.nkeys; i>0; i--, key++) { + if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { n = n->next; goto next_knode; } +#ifdef CONFIG_CLS_U32_PERF + key->kcnt +=1; +#endif } if (n->ht_down == NULL) { check_terminal: if (n->sel.flags&TC_U32_TERMINAL) { + *res = n->res; +#ifdef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NET_CLS_IND + /* yes, i know it sucks but the feature is + ** optional dammit! - JHS */ + if (0 != n->indev[0]) { + if (NULL == skb->input_dev) { + n = n->next; + goto next_knode; + } else { + if (0 != strcmp(n->indev, skb->input_dev->name)) { + n = n->next; + goto next_knode; + } + } + } +#endif +#ifdef CONFIG_CLS_U32_PERF + n->sel.rhit +=1; +#endif + if (n->action) { + int pol_res = tcf_action_exec(skb, n->action); + if (skb->tc_classid > 0) { + res->classid = skb->tc_classid; + skb->tc_classid = 0; + } + + if (pol_res >= 0) + return pol_res; + } else +#else #ifdef CONFIG_NET_CLS_POLICE if (n->police) { int pol_res = tcf_police(skb, n->police); if (pol_res >= 0) return pol_res; } else +#endif #endif return 0; } @@ -298,8 +350,14 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n) if ((cl = __cls_set_class(&n->res.class, 0)) != 0) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); +#ifdef CONFIG_NET_CLS_ACT + if (n->action) { + tcf_action_destroy(n->action, TCA_ACT_UNBIND); + } +#else #ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(n->police); + tcf_police_release(n->police, TCA_ACT_UNBIND); +#endif #endif if (n->ht_down) n->ht_down->refcnt--; @@ -438,6 +496,10 @@ static int u32_set_parms(struct Qdisc *q, unsigned long base, struct tc_u_knode *n, struct rtattr **tb, struct rtattr *est) { +#ifdef CONFIG_NET_CLS_ACT + struct tc_action *act = NULL; + int ret; +#endif if (tb[TCA_U32_LINK-1]) { u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]); struct tc_u_hnode *ht_down = NULL; @@ -470,17 +532,73 @@ static int u32_set_parms(struct Qdisc *q, unsigned long base, if (cl) q->ops->cl_ops->unbind_tcf(q, cl); } +#ifdef CONFIG_NET_CLS_ACT + /*backward compatibility */ + if (tb[TCA_U32_POLICE-1]) + { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + + memset(act,0,sizeof(*act)); + ret = tcf_action_init_1(tb[TCA_U32_POLICE-1], est,act,"police", TCA_ACT_NOREPLACE, TCA_ACT_BIND); + if (0 > ret){ + tcf_action_destroy(act, TCA_ACT_UNBIND); + return ret; + } + act->type = TCA_OLD_COMPAT; + + sch_tree_lock(q); + act = xchg(&n->action, act); + sch_tree_unlock(q); + + tcf_action_destroy(act, TCA_ACT_UNBIND); + + } + + if(tb[TCA_U32_ACT-1]) { + act = kmalloc(sizeof(*act),GFP_KERNEL); + if (NULL == act) + return -ENOMEM; + memset(act,0,sizeof(*act)); + ret = tcf_action_init(tb[TCA_U32_ACT-1], est,act,NULL,TCA_ACT_NOREPLACE, TCA_ACT_BIND); + if (0 > ret) { + tcf_action_destroy(act, TCA_ACT_UNBIND); + return ret; + } + + sch_tree_lock(q); + act = xchg(&n->action, act); + sch_tree_unlock(q); + + tcf_action_destroy(act, TCA_ACT_UNBIND); + } + +#ifdef CONFIG_NET_CLS_IND + n->indev[0] = 0; + if(tb[TCA_U32_INDEV-1]) { + struct rtattr *input_dev = tb[TCA_U32_INDEV-1]; + if (RTA_PAYLOAD(input_dev) >= IFNAMSIZ) { + printk("cls_u32: bad indev name %s\n",(char*)RTA_DATA(input_dev)); + /* should we clear state first? */ + return -EINVAL; + } + sprintf(n->indev, "%s", (char*)RTA_DATA(input_dev)); + } +#endif + +#else #ifdef CONFIG_NET_CLS_POLICE if (tb[TCA_U32_POLICE-1]) { struct tcf_police *police = tcf_police_locate(tb[TCA_U32_POLICE-1], est); - sch_tree_lock(q); police = xchg(&n->police, police); sch_tree_unlock(q); - - tcf_police_release(police); + tcf_police_release(police, TCA_ACT_UNBIND); } #endif +#endif + return 0; } @@ -656,26 +774,79 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid); if (n->ht_down) RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); +#ifdef CONFIG_CLS_U32_PERF2 + printk("fh %x cnt %lu hit %lu\n",n->handle,n->sel.rcnt,n->sel.rhit); + n->sel.rcnt = n->sel.rhit = 0; + /* dump key cnt */ + { + int i = 0; + struct tc_u32_key *key = n->sel.keys; + for (i = n->sel.nkeys; i>0; i--, key++) { + printk("\t key%d success %lu\n",i,key->kcnt); + key->cnt = 0; + } + } + +#endif +#ifdef CONFIG_NET_CLS_ACT + /* again for backward compatible mode - we want + * to work with both old and new modes of entering + * tc data even if iproute2 was newer - jhs + */ + if (n->action) { + struct rtattr * p_rta = (struct rtattr*)skb->tail; + + if (n->action->type != TCA_OLD_COMPAT) { + RTA_PUT(skb, TCA_U32_ACT, 0, NULL); + if (tcf_action_dump(skb,n->action, 0, 0) < 0) { + goto rtattr_failure; + } + } else { + RTA_PUT(skb, TCA_U32_POLICE, 0, NULL); + if (tcf_action_dump_old(skb,n->action,0,0) < 0) { + goto rtattr_failure; + } + } + + p_rta->rta_len = skb->tail - (u8*)p_rta; + } +#ifdef CONFIG_NET_CLS_IND + if(strlen(n->indev)) { + struct rtattr * p_rta = (struct rtattr*)skb->tail; + RTA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev); + p_rta->rta_len = skb->tail - (u8*)p_rta; + } +#endif + +#else #ifdef CONFIG_NET_CLS_POLICE if (n->police) { struct rtattr * p_rta = (struct rtattr*)skb->tail; - RTA_PUT(skb, TCA_U32_POLICE, 0, NULL); - + if (tcf_police_dump(skb, n->police) < 0) goto rtattr_failure; p_rta->rta_len = skb->tail - (u8*)p_rta; + } +#endif #endif } rta->rta_len = skb->tail - b; +#ifdef CONFIG_NET_CLS_ACT + if (TC_U32_KEY(n->handle) && n->action && n->action->type == TCA_OLD_COMPAT) { + if (tcf_action_copy_stats(skb,n->action)) + goto rtattr_failure; + } +#else #ifdef CONFIG_NET_CLS_POLICE if (TC_U32_KEY(n->handle) && n->police) { - if (qdisc_copy_stats(skb, &n->police->stats)) + if (qdisc_copy_stats(skb,&n->police->stats)) goto rtattr_failure; } +#endif #endif return skb->len; diff --git a/net/sched/police.c b/net/sched/police.c index e92a07620ffd..14ccbae43858 100644 --- a/net/sched/police.c +++ b/net/sched/police.c @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, + * J Hadi Salim (action changes) */ #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -33,9 +35,13 @@ #define L2T(p,L) ((p)->R_tab->data[(L)>>(p)->R_tab->rate.cell_log]) #define L2T_P(p,L) ((p)->P_tab->data[(L)>>(p)->P_tab->rate.cell_log]) +#define PRIV(a) ((struct tcf_police *) (a)->priv) +/* use generic hash table */ +#define MY_TAB_SIZE 16 +#define MY_TAB_MASK 15 static u32 idx_gen; -static struct tcf_police *tcf_police_ht[16]; +static struct tcf_police *tcf_police_ht[MY_TAB_SIZE]; /* Policer hash table lock */ static rwlock_t police_lock = RW_LOCK_UNLOCKED; @@ -59,6 +65,68 @@ static __inline__ struct tcf_police * tcf_police_lookup(u32 index) return p; } +#ifdef CONFIG_NET_CLS_ACT +static __inline__ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) +{ + struct tcf_police *p; + int err =0, index = -1,i= 0, s_i = 0, n_i = 0; + struct rtattr *r ; + + read_lock(&police_lock); + + s_i = cb->args[0]; + + for (i = 0; i < MY_TAB_SIZE; i++) { + p = tcf_police_ht[tcf_police_hash(i)]; + + for (; p; p = p->next) { + index++; + if (index < s_i) + continue; + a->priv = p; + a->order = index; + r = (struct rtattr*) skb->tail; + RTA_PUT(skb, a->order, 0, NULL); + if (type == RTM_DELACTION) + err = tcf_action_dump_1(skb, a, 0, 1); + else + err = tcf_action_dump_1(skb, a, 0, 0); + if (0 > err) { + index--; + skb_trim(skb, (u8*)r - skb->data); + goto done; + } + r->rta_len = skb->tail - (u8*)r; + n_i++; + } + } +done: + read_unlock(&police_lock); + if (n_i) + cb->args[0] += n_i; + return n_i; + +rtattr_failure: + skb_trim(skb, (u8*)r - skb->data); + goto done; +} + +static inline int +tcf_hash_search(struct tc_action *a, u32 index) +{ + struct tcf_police *p = tcf_police_lookup(index); + + if (p != NULL) { + a->priv = p; + return 1; + } else { + return 0; + } +} + + +#endif + static __inline__ u32 tcf_police_new_index(void) { do { @@ -94,6 +162,264 @@ void tcf_police_destroy(struct tcf_police *p) BUG_TRAP(0); } +#ifdef CONFIG_NET_CLS_ACT +int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *a, int ovr, int bind) +{ + unsigned h; + struct rtattr *tb[TCA_POLICE_MAX]; + struct tc_police *parm; + struct tcf_police *p; + + if (NULL == a) { + if (net_ratelimit()) + printk("BUG: tcf_police_locate called with NULL params\n"); + return -1; + } + + if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) + return -1; + + if (tb[TCA_POLICE_TBF-1] == NULL) + return -1; + + parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); + + if (parm->index && (p = tcf_police_lookup(parm->index)) != NULL) { + a->priv = (void *)p; + spin_lock(&p->lock); + if (bind) { + p->bindcnt += 1; + p->refcnt += 1; + } + if (ovr) { + goto override; + } + spin_unlock(&p->lock); + return 1; + } + + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return -1; + + memset(p, 0, sizeof(*p)); + MOD_INC_USE_COUNT; + p->refcnt = 1; + spin_lock_init(&p->lock); + p->stats.lock = &p->lock; + if (bind) + p->bindcnt = 1; +override: + if (parm->rate.rate) { + if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL) + goto failure; + if (parm->peakrate.rate && + (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL) + goto failure; + } + if (tb[TCA_POLICE_RESULT-1]) + p->result = *(int*)RTA_DATA(tb[TCA_POLICE_RESULT-1]); +#ifdef CONFIG_NET_ESTIMATOR + if (tb[TCA_POLICE_AVRATE-1]) + p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]); +#endif + p->toks = p->burst = parm->burst; + p->mtu = parm->mtu; + if (p->mtu == 0) { + p->mtu = ~0; + if (p->R_tab) + p->mtu = 255<R_tab->rate.cell_log; + } + if (p->P_tab) + p->ptoks = L2T_P(p, p->mtu); + p->action = parm->action; + + if (ovr) { + spin_unlock(&p->lock); + return 1; + } + PSCHED_GET_TIME(p->t_c); + p->index = parm->index ? : tcf_police_new_index(); +#ifdef CONFIG_NET_ESTIMATOR + if (est) + qdisc_new_estimator(&p->stats, est); +#endif + h = tcf_police_hash(p->index); + write_lock_bh(&police_lock); + p->next = tcf_police_ht[h]; + tcf_police_ht[h] = p; + write_unlock_bh(&police_lock); + + MOD_INC_USE_COUNT; + a->priv = (void *)p; + return 1; + +failure: + if (p->R_tab) + qdisc_put_rtab(p->R_tab); + if (ovr) + spin_unlock(&p->lock); + kfree(p); + return -1; +} + +void tcf_act_police_cleanup(struct tc_action *a, int bind) +{ + struct tcf_police *p; + p = PRIV(a); + if (NULL != p) + tcf_police_release(p, bind); +} + +int tcf_act_police_stats(struct sk_buff *skb, struct tc_action *a) +{ + struct tcf_police *p; + p = PRIV(a); + if (NULL != p) + return qdisc_copy_stats(skb, &p->stats); + + return 1; +} + +int tcf_act_police(struct sk_buff **pskb, struct tc_action *a) +{ + psched_time_t now; + struct sk_buff *skb = *pskb; + struct tcf_police *p; + long toks; + long ptoks = 0; + + p = PRIV(a); + + if (NULL == p) { + printk("BUG: tcf_police called with NULL params\n"); + return -1; + } + + spin_lock(&p->lock); + + p->stats.bytes += skb->len; + p->stats.packets++; + +#ifdef CONFIG_NET_ESTIMATOR + if (p->ewma_rate && p->stats.bps >= p->ewma_rate) { + p->stats.overlimits++; + spin_unlock(&p->lock); + return p->action; + } +#endif + + if (skb->len <= p->mtu) { + if (p->R_tab == NULL) { + spin_unlock(&p->lock); + return p->result; + } + + PSCHED_GET_TIME(now); + + toks = PSCHED_TDIFF_SAFE(now, p->t_c, p->burst, 0); + + if (p->P_tab) { + ptoks = toks + p->ptoks; + if (ptoks > (long)L2T_P(p, p->mtu)) + ptoks = (long)L2T_P(p, p->mtu); + ptoks -= L2T_P(p, skb->len); + } + toks += p->toks; + if (toks > (long)p->burst) + toks = p->burst; + toks -= L2T(p, skb->len); + + if ((toks|ptoks) >= 0) { + p->t_c = now; + p->toks = toks; + p->ptoks = ptoks; + spin_unlock(&p->lock); + return p->result; + } + } + + p->stats.overlimits++; + spin_unlock(&p->lock); + return p->action; +} + +int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) +{ + unsigned char *b = skb->tail; + struct tc_police opt; + struct tcf_police *p; + + p = PRIV(a); + if (NULL == p) { + printk("BUG: tcf_police_dump called with NULL params\n"); + goto rtattr_failure; + } + + opt.index = p->index; + opt.action = p->action; + opt.mtu = p->mtu; + opt.burst = p->burst; + opt.refcnt = p->refcnt - ref; + opt.bindcnt = p->bindcnt - bind; + if (p->R_tab) + opt.rate = p->R_tab->rate; + else + memset(&opt.rate, 0, sizeof(opt.rate)); + if (p->P_tab) + opt.peakrate = p->P_tab->rate; + else + memset(&opt.peakrate, 0, sizeof(opt.peakrate)); + RTA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); + if (p->result) + RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int), &p->result); +#ifdef CONFIG_NET_ESTIMATOR + if (p->ewma_rate) + RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &p->ewma_rate); +#endif + return skb->len; + +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +MODULE_AUTHOR("Alexey Kuznetsov"); +MODULE_DESCRIPTION("Policing actions"); +MODULE_LICENSE("GPL"); + + +struct tc_action_ops act_police_ops = { + NULL, + "police", + TCA_ACT_POLICE, + TCA_CAP_NONE, + tcf_act_police, + tcf_act_police_stats, + tcf_act_police_dump, + tcf_act_police_cleanup, + tcf_hash_search, + tcf_act_police_locate, + tcf_generic_walker +}; + +static int __init +police_init_module(void) +{ + return tcf_register_action(&act_police_ops); +} + +static void __exit +police_cleanup_module(void) +{ + tcf_unregister_action(&act_police_ops); +} + +module_init(police_init_module); +module_exit(police_cleanup_module); + +#endif + struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) { unsigned h; @@ -111,6 +437,7 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) if (parm->index && (p = tcf_police_lookup(parm->index)) != NULL) { p->refcnt++; + MOD_INC_USE_COUNT; return p; } @@ -156,6 +483,7 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) p->next = tcf_police_ht[h]; tcf_police_ht[h] = p; write_unlock_bh(&police_lock); + MOD_INC_USE_COUNT; return p; failure: diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 37eb5df8f304..3ec741a3b44a 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -45,7 +45,11 @@ /* Thanks to Doron Oz for this hack */ +#ifndef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NETFILTER static int nf_registered; +#endif +#endif struct ingress_qdisc_data { struct Qdisc *q; @@ -146,27 +150,52 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) * Unlike normal "enqueue" functions, ingress_enqueue returns a * firewall FW_* code. */ -#ifdef CONFIG_NET_CLS_POLICE +#ifdef CONFIG_NET_CLS_ACT + sch->stats.packets++; + sch->stats.bytes += skb->len; switch (result) { - case TC_POLICE_SHOT: - result = NF_DROP; + case TC_ACT_SHOT: + result = TC_ACT_SHOT; sch->stats.drops++; break; + case TC_ACT_STOLEN: + case TC_ACT_QUEUED: + result = TC_ACT_STOLEN; + break; + case TC_ACT_RECLASSIFY: + case TC_ACT_OK: + case TC_ACT_UNSPEC: + default: + skb->tc_index = TC_H_MIN(res.classid); + result = TC_ACT_OK; + break; + }; +/* backward compat */ +#else +#ifdef CONFIG_NET_CLS_POLICE + switch (result) { + case TC_POLICE_SHOT: + result = NF_DROP; + sch->stats.drops++; + break; case TC_POLICE_RECLASSIFY: /* DSCP remarking here ? */ case TC_POLICE_OK: case TC_POLICE_UNSPEC: default: - sch->stats.packets++; - sch->stats.bytes += skb->len; - result = NF_ACCEPT; - break; + sch->stats.packets++; + sch->stats.bytes += skb->len; + result = NF_ACCEPT; + break; }; + #else + D2PRINTK("Overriding result to ACCEPT\n"); + result = NF_ACCEPT; sch->stats.packets++; sch->stats.bytes += skb->len; +#endif #endif - skb->tc_index = TC_H_MIN(res.classid); return result; } @@ -199,6 +228,8 @@ static unsigned int ingress_drop(struct Qdisc *sch) return 0; } +#ifndef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NETFILTER static unsigned int ing_hook(unsigned int hook, struct sk_buff **pskb, const struct net_device *indev, @@ -240,10 +271,29 @@ static struct nf_hook_ops ing_ops = { .priority = NF_IP_PRI_FILTER + 1, }; +#endif +#endif + int ingress_init(struct Qdisc *sch,struct rtattr *opt) { struct ingress_qdisc_data *p = PRIV(sch); +/* Make sure either netfilter or preferably CLS_ACT is +* compiled in */ +#ifndef CONFIG_NET_CLS_ACT +#ifndef CONFIG_NETFILTER + printk("You MUST compile classifier actions into the kernel\n"); + goto error; +#else + printk("Ingress scheduler: Classifier actions prefered over netfilter\n"); +#endif +#endif + + if (NULL == p) + goto error; + +#ifndef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NETFILTER if (!nf_registered) { if (nf_register_hook(&ing_ops) < 0) { printk("ingress qdisc registration error \n"); @@ -251,6 +301,8 @@ int ingress_init(struct Qdisc *sch,struct rtattr *opt) } nf_registered++; } +#endif +#endif DPRINTK("ingress_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt); memset(p, 0, sizeof(*p)); @@ -364,8 +416,12 @@ static int __init ingress_module_init(void) static void __exit ingress_module_exit(void) { unregister_qdisc(&ingress_qdisc_ops); +#ifndef CONFIG_NET_CLS_ACT +#ifdef CONFIG_NETFILTER if (nf_registered) nf_unregister_hook(&ing_ops); +#endif +#endif } module_init(ingress_module_init) module_exit(ingress_module_exit) diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index f8eafc507644..52a4c2e28272 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -47,60 +47,104 @@ struct prio_sched_data }; -static __inline__ unsigned prio_classify(struct sk_buff *skb, struct Qdisc *sch) +struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) { struct prio_sched_data *q = (struct prio_sched_data *)sch->data; struct tcf_result res; u32 band; + int result = 0; band = skb->priority; + if (TC_H_MAJ(skb->priority) != sch->handle) { +#ifdef CONFIG_NET_CLS_ACT + *r = result = tc_classify(skb, q->filter_list, &res); + + switch (result) { + case TC_ACT_SHOT: + case TC_ACT_STOLEN: + case TC_ACT_QUEUED: + kfree_skb(skb); + return NULL; + case TC_ACT_RECLASSIFY: + case TC_ACT_OK: + case TC_ACT_UNSPEC: + default: + break; + }; + + if (!q->filter_list ) { +#else if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) { +#endif if (TC_H_MAJ(band)) band = 0; - return q->prio2band[band&TC_PRIO_MAX]; + return q->queues[q->prio2band[band&TC_PRIO_MAX]]; } band = res.classid; } band = TC_H_MIN(band) - 1; - return band < q->bands ? band : q->prio2band[0]; + if (band > q->bands) + return q->queues[q->prio2band[0]]; + + return q->queues[band]; } static int prio_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; struct Qdisc *qdisc; int ret; - qdisc = q->queues[prio_classify(skb, sch)]; + /* moving these up here changes things from before + * packets counted now include everything that was ever + * seen + */ + sch->stats.bytes += skb->len; + sch->stats.packets++; + qdisc = prio_classify(skb, sch, &ret); + if (NULL == qdisc) + goto dropped; if ((ret = qdisc->enqueue(skb, qdisc)) == 0) { - sch->stats.bytes += skb->len; - sch->stats.packets++; sch->q.qlen++; - return 0; + return NET_XMIT_SUCCESS; } - sch->stats.drops++; - return ret; + +dropped: +#ifdef CONFIG_NET_CLS_ACT + if (TC_ACT_SHOT == ret || NET_XMIT_DROP == ret) { +#endif + sch->stats.drops++; + return NET_XMIT_DROP; +#ifdef CONFIG_NET_CLS_ACT + } else { + sch->stats.overlimits++; /* abuse, but noone uses it */ + return NET_XMIT_BYPASS; /* we dont want to confuse TCP */ + } +#endif } static int prio_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + //struct prio_sched_data *q = (struct prio_sched_data *)sch->data; struct Qdisc *qdisc; - int ret; + int ret = NET_XMIT_DROP; - qdisc = q->queues[prio_classify(skb, sch)]; + sch->stats.reqs++; + qdisc = prio_classify(skb, sch, &ret); + if (qdisc == NULL) + goto dropped; if ((ret = qdisc->ops->requeue(skb, qdisc)) == 0) { sch->q.qlen++; return 0; } +dropped: sch->stats.drops++; - return ret; + return NET_XMIT_DROP; } -- cgit v1.2.3 From d0b53c036d6fd4cab93bd52c56e4e2bd6d39af92 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Thu, 17 Jun 2004 00:21:35 -0700 Subject: [ARM] Consolidate various ARM timer fns. into single timer_tick() call. Signed-off-by: Deepak Saxena --- arch/arm/kernel/time.c | 24 ++++++++++++++++-------- arch/arm/mach-clps711x/time.c | 4 +--- arch/arm/mach-clps7500/core.c | 5 ++--- arch/arm/mach-ebsa110/core.c | 4 +--- arch/arm/mach-epxa10db/time.c | 4 +--- arch/arm/mach-footbridge/time.c | 13 ++----------- arch/arm/mach-integrator/time.c | 4 +--- arch/arm/mach-iop3xx/iop321-time.c | 2 +- arch/arm/mach-ixp4xx/common.c | 2 +- arch/arm/mach-lh7a40x/time.c | 5 +---- arch/arm/mach-omap/time.c | 4 +--- arch/arm/mach-pxa/time.c | 6 +----- arch/arm/mach-rpc/riscpc.c | 4 +--- arch/arm/mach-s3c2410/time.c | 7 +------ arch/arm/mach-sa1100/time.c | 6 +----- arch/arm/mach-shark/core.c | 4 +--- arch/arm/mach-versatile/core.c | 4 +--- include/asm-arm/mach/time.h | 8 ++------ 18 files changed, 36 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index f8c164e94733..efcb44a9e6ab 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -52,15 +52,11 @@ EXPORT_SYMBOL(rtc_lock); /* change this if you have some constant time drift */ #define USECS_PER_JIFFY (1000000/HZ) -static int dummy_set_rtc(void) -{ - return 0; -} /* * hook for setting the RTC's idea of the current time. */ -int (*set_rtc)(void) = dummy_set_rtc; +int (*set_rtc)(void); static unsigned long dummy_gettimeoffset(void) { @@ -86,7 +82,7 @@ unsigned long long __attribute__((weak)) sched_clock(void) /* * Handle kernel profile stuff... */ -void do_profile(struct pt_regs *regs) +static inline void do_profile(struct pt_regs *regs) { profile_hook(regs); @@ -116,7 +112,7 @@ static unsigned long next_rtc_update; * called as close as possible to 500 ms before the new second * starts. */ -void do_set_rtc(void) +static inline void do_set_rtc(void) { if (time_status & STA_UNSYNC || set_rtc == NULL) return; @@ -240,7 +236,8 @@ device_initcall(leds_init); EXPORT_SYMBOL(leds_event); #endif -void do_leds(void) +#ifdef CONFIG_LEDS_TIMER +static inline void do_leds(void) { static unsigned int count = 50; @@ -249,6 +246,9 @@ void do_leds(void) leds_event(led_timer); } } +#else +#define do_leds() +#endif void do_gettimeofday(struct timeval *tv) { @@ -315,6 +315,14 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); +void timer_tick(struct pt_regs *regs) +{ + do_profile(regs); + do_leds(); + do_set_rtc(); + do_timer(regs); +} + void (*init_arch_time)(void); void __init time_init(void) diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c index 9c732d18ddc0..58da84effd5e 100644 --- a/arch/arm/mach-clps711x/time.c +++ b/arch/arm/mach-clps711x/time.c @@ -49,9 +49,7 @@ static unsigned long clps711x_gettimeoffset(void) static irqreturn_t p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 2214f739768a..ee1a3192ad7b 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -271,10 +271,9 @@ extern void ioctime_init(void); static irqreturn_t clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_timer(regs); - do_set_rtc(); - do_profile(regs); + timer_tick(regs); + /* Why not using do_leds interface?? */ { /* Twinkle the lights. */ static int count, state = 0xff00; diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index eddce7348095..6f20b86a69c4 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -160,9 +160,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) __raw_writeb(count & 0xff, PIT_T1); __raw_writeb(count >> 8, PIT_T1); - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c index 1b3766a46069..7d72a433dad7 100644 --- a/arch/arm/mach-epxa10db/time.c +++ b/arch/arm/mach-epxa10db/time.c @@ -47,9 +47,7 @@ epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) // ...clear the interrupt *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK; - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c index c32dd9a5c9b9..d4b9c9f87fff 100644 --- a/arch/arm/mach-footbridge/time.c +++ b/arch/arm/mach-footbridge/time.c @@ -83,12 +83,7 @@ static unsigned long isa_gettimeoffset(void) static irqreturn_t isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (machine_is_netwinder()) - do_leds(); - - do_timer(regs); - do_set_rtc(); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } @@ -206,11 +201,7 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { *CSR_TIMER1_CLR = 0; - /* Do the LEDs things */ - do_leds(); - do_timer(regs); - do_set_rtc(); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index d791f1e41896..e12bcf814d95 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c @@ -139,9 +139,7 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) // ...clear the interrupt timer1->TimerClear = 1; - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c index 3af8823cda37..be36c70690b1 100644 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ b/arch/arm/mach-iop3xx/iop321-time.c @@ -63,7 +63,7 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - do_timer(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 986f2d43db28..a4edbe0eb909 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -228,7 +228,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs * Catch up with the real idea of time */ do { - do_timer(regs); + timer_tick(regs); last_jiffy_time += LATCH; } while((*IXP4XX_OSTS - last_jiffy_time) > LATCH); diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c index 52c20c3bf248..61ada24c78a7 100644 --- a/arch/arm/mach-lh7a40x/time.c +++ b/arch/arm/mach-lh7a40x/time.c @@ -41,10 +41,7 @@ static irqreturn_t lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { TIMER_EOI = 0; - do_profile (regs); - do_leds(); - do_set_rtc(); - do_timer (regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index 57e9bd3a0579..d62e22614394 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -183,9 +183,7 @@ omap_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ilatency = MPUTICKS_PER_SEC / 100 - read_mputimer2(); systimer_mark = now - ilatency; - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 432f65db19b7..7e89235632f8 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -74,8 +74,6 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int next_match; - do_profile(regs); - /* Loop until we get ahead of the free running timer. * This ensures an exact clock tick count and time accuracy. * IRQs are disabled inside the loop to ensure coherence between @@ -92,9 +90,7 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * exactly one tick period which should be a pretty rare event. */ do { - do_leds(); - do_set_rtc(); - do_timer(regs); + timer_tick(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); } while( (signed long)(next_match - OSCR) <= 8 ); diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 7dae14b39103..d5a1a3af216c 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -88,9 +88,7 @@ void __init rpc_map_io(void) static irqreturn_t rpc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_timer(regs); - do_set_rtc(); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index e86250e69b65..62d89d98c423 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -74,12 +74,7 @@ static unsigned long s3c2410_gettimeoffset (void) static irqreturn_t s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_leds(); - do_timer(regs); - - do_set_rtc(); - //s3c2410_rtc_check(); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index caff78e1c61f..e58463b02e67 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -78,15 +78,11 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) unsigned int next_match; do { - do_leds(); - do_timer(regs); + timer_tick(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); - do_set_rtc(); } while ((signed long)(next_match - OSCR) <= 0); - do_profile(regs); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index 28504c990829..e4ae688899c1 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -35,9 +35,7 @@ static void __init shark_map_io(void) static irqreturn_t shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 27b4b95f2508..a2f88df44ab9 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -606,9 +606,7 @@ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_re // ...clear the interrupt timer0->TimerClear = 1; - do_leds(); - do_timer(regs); - do_profile(regs); + timer_tick(regs); return IRQ_HANDLED; } diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index a473e6dfc878..edb6fcc6a200 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h @@ -12,13 +12,9 @@ extern void (*init_arch_time)(void); -void do_set_rtc(void); - -void do_profile(struct pt_regs *); - -void do_leds(void); - extern int (*set_rtc)(void); extern unsigned long(*gettimeoffset)(void); +void timer_tick(struct pt_regs *); + #endif -- cgit v1.2.3 From f0b3c84e7da94fd7a174bba885d3bb26090683f5 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Thu, 17 Jun 2004 01:41:52 -0700 Subject: [ARM] Remove ADIFCC machine type The code is completely out of date, I am no longer maintaining it, and nobdy has volunteered to do so; therefore, I am killing it. Signed-off-by: Deepak Saxena --- arch/arm/Kconfig | 3 - arch/arm/Makefile | 1 - arch/arm/boot/Makefile | 2 - arch/arm/boot/compressed/head-xscale.S | 3 - arch/arm/configs/adi_evb_defconfig | 678 ------------------------------- arch/arm/kernel/debug.S | 26 -- arch/arm/kernel/entry-armv.S | 2 +- arch/arm/mach-adifcc/Makefile | 11 - arch/arm/mach-adifcc/arch.c | 32 -- arch/arm/mach-adifcc/irq.c | 61 --- arch/arm/mach-adifcc/mm.c | 23 -- arch/arm/mm/Kconfig | 2 +- include/asm-arm/arch-adifcc/adi_evb.h | 19 - include/asm-arm/arch-adifcc/dma.h | 18 - include/asm-arm/arch-adifcc/hardware.h | 27 -- include/asm-arm/arch-adifcc/io.h | 22 - include/asm-arm/arch-adifcc/irqs.h | 20 - include/asm-arm/arch-adifcc/memory.h | 27 -- include/asm-arm/arch-adifcc/param.h | 3 - include/asm-arm/arch-adifcc/serial.h | 34 -- include/asm-arm/arch-adifcc/system.h | 28 -- include/asm-arm/arch-adifcc/timex.h | 10 - include/asm-arm/arch-adifcc/uncompress.h | 35 -- include/asm-arm/arch-adifcc/vmalloc.h | 15 - 24 files changed, 2 insertions(+), 1100 deletions(-) delete mode 100644 arch/arm/configs/adi_evb_defconfig delete mode 100644 arch/arm/mach-adifcc/Makefile delete mode 100644 arch/arm/mach-adifcc/arch.c delete mode 100644 arch/arm/mach-adifcc/irq.c delete mode 100644 arch/arm/mach-adifcc/mm.c delete mode 100644 include/asm-arm/arch-adifcc/adi_evb.h delete mode 100644 include/asm-arm/arch-adifcc/dma.h delete mode 100644 include/asm-arm/arch-adifcc/hardware.h delete mode 100644 include/asm-arm/arch-adifcc/io.h delete mode 100644 include/asm-arm/arch-adifcc/irqs.h delete mode 100644 include/asm-arm/arch-adifcc/memory.h delete mode 100644 include/asm-arm/arch-adifcc/param.h delete mode 100644 include/asm-arm/arch-adifcc/serial.h delete mode 100644 include/asm-arm/arch-adifcc/system.h delete mode 100644 include/asm-arm/arch-adifcc/timex.h delete mode 100644 include/asm-arm/arch-adifcc/uncompress.h delete mode 100644 include/asm-arm/arch-adifcc/vmalloc.h (limited to 'include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 21e8c8c42903..08241dfd49c6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -72,9 +72,6 @@ choice prompt "ARM system type" default ARCH_RPC -config ARCH_ADIFCC - bool "ADIFCC-based" - config ARCH_CLPS7500 bool "Cirrus-CL-PS7500FE" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 85eeb2b1e1cd..e6d43f3eccf4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -91,7 +91,6 @@ textaddr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 machine-$(CONFIG_ARCH_IOP3XX) := iop3xx - machine-$(CONFIG_ARCH_ADIFCC) := adifcc machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_S3C2410) := s3c2410 diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 72be85c543ed..8c42a9132ce3 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -49,8 +49,6 @@ initrd_phys-$(CONFIG_ARCH_SA1100) := 0xc0800000 zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000 zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000 params_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100 - zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000 -params_phys-$(CONFIG_ARCH_ADIFCC) := 0xc0000100 zreladdr-$(CONFIG_ARCH_IXP4XX) := 0x00008000 params-phys-$(CONFIG_ARCH_IXP4XX) := 0x00000100 zreladdr-$(CONFIG_ARCH_OMAP) := 0x10008000 diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index e6656d4ef5c8..f9194499e863 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -66,7 +66,4 @@ __XScale_start: mov r7, #MACH_TYPE_IQ80310 #endif -#ifdef CONFIG_ARCH_ADI_EVB - mov r7, #MACH_TYPE_ADI_EVB -#endif diff --git a/arch/arm/configs/adi_evb_defconfig b/arch/arm/configs/adi_evb_defconfig deleted file mode 100644 index bae486663bb4..000000000000 --- a/arch/arm/configs/adi_evb_defconfig +++ /dev/null @@ -1,678 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_ARM=y -# CONFIG_EISA is not set -# CONFIG_SBUS is not set -# CONFIG_MCA is not set -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_GENERIC_BUST_SPINLOCK is not set -# CONFIG_GENERIC_ISA_DMA is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -# CONFIG_OBSOLETE is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set - -# -# System Type -# -CONFIG_ARCH_ADIFCC=y -# CONFIG_ARCH_ARCA5K is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP310 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SHARK is not set - -# -# Archimedes/A5000 Implementations -# -# CONFIG_ARCH_ARC is not set -# CONFIG_ARCH_A5K is not set - -# -# Footbridge Implementations -# -# CONFIG_ARCH_CATS is not set -# CONFIG_ARCH_PERSONAL_SERVER is not set -# CONFIG_ARCH_EBSA285_ADDIN is not set -# CONFIG_ARCH_EBSA285_HOST is not set -# CONFIG_ARCH_NETWINDER is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_ASSABET_NEPONSET is not set -# CONFIG_SA1100_ADSBITSY is not set -# CONFIG_SA1100_BRUTUS is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_H3600 is not set -# CONFIG_SA1100_EXTENEX1 is not set -# CONFIG_SA1100_FLEXANET is not set -# CONFIG_SA1100_FREEBIRD is not set -# CONFIG_SA1100_GRAPHICSCLIENT is not set -# CONFIG_SA1100_GRAPHICSMASTER is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HUW_WEBPANEL is not set -# CONFIG_SA1100_ITSY is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_NANOENGINE is not set -# CONFIG_SA1100_OMNIMETER is not set -# CONFIG_SA1100_PANGOLIN is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHERMAN is not set -# CONFIG_SA1100_SIMPAD is not set -# CONFIG_SA1100_PFS168 is not set -# CONFIG_SA1100_VICTOR is not set -# CONFIG_SA1100_XP860 is not set -# CONFIG_SA1100_YOPY is not set -# CONFIG_SA1100_USB is not set -# CONFIG_SA1100_USB_NETLINK is not set -# CONFIG_SA1100_USB_CHAR is not set - -# -# CLPS711X/EP721X Implementations -# -# CONFIG_ARCH_CDB89712 is not set -# CONFIG_ARCH_CLEP7312 is not set -# CONFIG_ARCH_EDB7211 is not set -# CONFIG_ARCH_P720T is not set -# CONFIG_ARCH_EP7211 is not set -# CONFIG_ARCH_EP7212 is not set -CONFIG_ARCH_ADI_EVB=y -CONFIG_XSCALE_PMU_TIMER=y -# CONFIG_ARCH_ACORN is not set -# CONFIG_FOOTBRIDGE is not set -# CONFIG_FOOTBRIDGE_HOST is not set -# CONFIG_FOOTBRIDGE_ADDIN is not set -CONFIG_CPU_32=y -# CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -# CONFIG_CPU_32v4 is not set -# CONFIG_CPU_ARM610 is not set -# CONFIG_CPU_ARM710 is not set -# CONFIG_CPU_ARM720T is not set -# CONFIG_CPU_ARM920T is not set -# CONFIG_CPU_ARM926T is not set -# CONFIG_CPU_ARM1020 is not set -# CONFIG_CPU_SA110 is not set -# CONFIG_CPU_SA1100 is not set -CONFIG_CPU_32v4=y -CONFIG_CPU_XSCALE=y -CONFIG_ARM_THUMB=y -# CONFIG_XSCALE_TOOLS is not set -CONFIG_XSCALE_WRITE_ALLOC=y -CONFIG_XSCALE_PMU=y -CONFIG_ARM_THUMB=y -# CONFIG_DISCONTIGMEM is not set - -# -# General setup -# -# CONFIG_PCI is not set -# CONFIG_ISA is not set -# CONFIG_ISA_DMA is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_NET=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_FASTFPE is not set -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set -# CONFIG_ARTHUR is not set -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1 mem=32M initrd=0xc0800000,3M" -CONFIG_ALIGNMENT_TRAP=y - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_BOOTLDR_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_NORA is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_CDB89712 is not set -# CONFIG_MTD_SA1100 is not set -# CONFIG_MTD_DC21285 is not set -# CONFIG_MTD_IQ80310 is not set -CONFIG_MTD_ADI_EVB=y -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -# CONFIG_PACKET is not set -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_ARM_AM79C961A is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_AMBA is not set -# CONFIG_SERIAL_AMBA_CONSOLE is not set -# CONFIG_SERIAL_CLPS711X is not set -# CONFIG_SERIAL_CLPS711X_CONSOLE is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set -# CONFIG_SERIAL_UART00 is not set -# CONFIG_SERIAL_UART00_CONSOLE is not set -# CONFIG_SERIAL_SA1100 is not set -# CONFIG_SERIAL_SA1100_CONSOLE is not set -# CONFIG_SERIAL_8250 is not set -# CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_HUB6 is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# L3 serial bus support -# -# CONFIG_L3 is not set -# CONFIG_L3_ALGOBIT is not set -# CONFIG_L3_BIT_SA1100_GPIO is not set -# CONFIG_L3_SA1111 is not set -# CONFIG_BIT_SA1100_GPIO is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Multimedia Capabilities Port drivers -# -# CONFIG_MCP is not set -# CONFIG_MCP_SA1100 is not set -# CONFIG_MCP_UCB1200 is not set -# CONFIG_MCP_UCB1200_AUDIO is not set -# CONFIG_MCP_UCB1200_TS is not set - -# -# USB support -# -# CONFIG_USB is not set -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set -# CONFIG_USB_OHCI_SA1111 is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set - -# -# Kernel hacking -# -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_NO_PGT_CACHE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_DC21285_PORT is not set -# CONFIG_DEBUG_CLPS711X_UART2 is not set diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 2ae6eae420e4..0b3b9ab5b41d 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -439,32 +439,6 @@ #endif .endm -#elif defined(CONFIG_ARCH_ADI_EVB) - - .macro addruart,rx - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - mov \rx, #0x00400000 @ physical base address - orrne \rx, \rx, #0xff000000 @ virtual base - .endm - - .macro senduart,rd,rx - strb \rd, [\rx] - .endm - - .macro busyuart,rd,rx -1002: ldrb \rd, [\rx, #0x5] - and \rd, \rd, #0x60 - teq \rd, #0x60 - bne 1002b - .endm - - .macro waituart,rd,rx -1001: ldrb \rd, [\rx, #0x6] - tst \rd, #0x10 - beq 1001b - .endm - #elif defined(CONFIG_ARCH_IXP4XX) .macro addruart,rx diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 8af6251f3c3a..c43df2218298 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -561,7 +561,7 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm -#elif defined(CONFIG_ARCH_IOP310) || defined(CONFIG_ARCH_ADIFCC) +#elif defined(CONFIG_ARCH_IOP310) .macro disable_fiq .endm diff --git a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile deleted file mode 100644 index d8c1959e9483..000000000000 --- a/arch/arm/mach-adifcc/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := arch.o irq.o mm.o -obj-m := -obj-n := -obj- := - diff --git a/arch/arm/mach-adifcc/arch.c b/arch/arm/mach-adifcc/arch.c deleted file mode 100644 index bfc59556d9da..000000000000 --- a/arch/arm/mach-adifcc/arch.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * linux/arch/arm/mach-adifcc/arch.c - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -extern void adifcc_map_io(void); -extern void adifcc_init_irq(void); - -#ifdef CONFIG_ARCH_ADI_EVB -MACHINE_START(ADI_EVB, "ADI 80200FCC Evaluation Board") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xc0000000, 0x00400000, 0xff400000) - MAPIO(adifcc_map_io) - INITIRQ(adifcc_init_irq) -MACHINE_END -#endif - diff --git a/arch/arm/mach-adifcc/irq.c b/arch/arm/mach-adifcc/irq.c deleted file mode 100644 index 4163c602dc2f..000000000000 --- a/arch/arm/mach-adifcc/irq.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * linux/arch/arm/mach-xscale/irq.c - * - * Author: Deepak Saxena - * Copyright: (C) 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Based on IOP80310 code. Currently there's nothing more than the - * 80200 on chip interrupts. That'll change once the hardware adds - * support for PCI though. - */ -#include -#include - -#include -#include -#include - -static void xs80200_irq_mask (unsigned int irq) -{ - long INTCTL; - asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL)); - switch (irq) { - case IRQ_XS80200_BCU: INTCTL &= ~(1<<3); break; - case IRQ_XS80200_PMU: INTCTL &= ~(1<<2); break; - case IRQ_XS80200_EXTIRQ: INTCTL &= ~(1<<1); break; - case IRQ_XS80200_EXTFIQ: INTCTL &= ~(1<<0); break; - } - asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL)); -} - -static void xs80200_irq_unmask (unsigned int irq) -{ - long INTCTL; - asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL)); - switch (irq) { - case IRQ_XS80200_BCU: INTCTL |= (1<<3); break; - case IRQ_XS80200_PMU: INTCTL |= (1<<2); break; - case IRQ_XS80200_EXTIRQ: INTCTL |= (1<<1); break; - case IRQ_XS80200_EXTFIQ: INTCTL |= (1<<0); break; - } - asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL)); -} - -void __init adifcc_init_irq(void) -{ - int i; - - for (i = 0; i < NR_XS80200_IRQS; i++) { - irq_desc[i].valid = 1; - irq_desc[i].probe_ok = 0; - irq_desc[i].mask_ack = xs80200_irq_mask; - irq_desc[i].mask = xs80200_irq_mask; - irq_desc[i].unmask = xs80200_irq_unmask; - } -} - - diff --git a/arch/arm/mach-adifcc/mm.c b/arch/arm/mach-adifcc/mm.c deleted file mode 100644 index a81a9794ff10..000000000000 --- a/arch/arm/mach-adifcc/mm.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/arch/arm/mach-xscale/mm.c - */ -#include -#include -#include - -#include -#include -#include - -#include - - -static struct map_desc adifcc_io_desc[] __initdata = { - /* on-board devices */ - { 0xff400000, 0x00400000, 0x00300000, MT_DEVICE } -}; - -void __init adifcc_map_io(void) -{ - iotable_init(adifcc_io_desc, ARRAY_SIZE(adifcc_io_desc)); -} diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ba32817ad59f..545a548b1f69 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -220,7 +220,7 @@ config CPU_SA1100 # XScale config CPU_XSCALE bool - depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA || ARCH_IXP4XX + depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX default y select CPU_32v5 select CPU_ABRT_EV5T diff --git a/include/asm-arm/arch-adifcc/adi_evb.h b/include/asm-arm/arch-adifcc/adi_evb.h deleted file mode 100644 index f4b74c6fcf9a..000000000000 --- a/include/asm-arm/arch-adifcc/adi_evb.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * linux/include/asm/arch-80200fcc/adi_evb.h - * - * ADI 80200FCC evaluation board definitions - * - * Author: Deepak Saxena - * - * Copyright (C) 2001 MontaVista Software Inc. - * - * 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. - */ - -#define ADI_EVB__RAMBASE 0xa0000000 -#define ADI_EVB__UART 0x00400000 /* UART */ -#define ADI_EVB_7SEG_1 0x00500000 /* 7-Segment */ - diff --git a/include/asm-arm/arch-adifcc/dma.h b/include/asm-arm/arch-adifcc/dma.h deleted file mode 100644 index 19aa1dbc3be7..000000000000 --- a/include/asm-arm/arch-adifcc/dma.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * linux/include/asm-arm/arch-80200fcc/dma.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -#define MAX_DMA_ADDRESS 0xffffffff - -/* No DMA */ -#define MAX_DMA_CHANNELS 0 - -#endif /* _ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-adifcc/hardware.h b/include/asm-arm/arch-adifcc/hardware.h deleted file mode 100644 index 9eeb3cb507da..000000000000 --- a/include/asm-arm/arch-adifcc/hardware.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/hardware.h - * - * Hardware definitions for ADI based systems - * - * Author: Deepak Saxena - * - * Copyright (C) 2000-2001 MontaVista Software Inc. - * - * 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_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include - -#define PCIO_BASE 0 - -#if defined(CONFIG_ARCH_ADI_EVB) -#include "adi_evb.h" -#endif - -#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-adifcc/io.h b/include/asm-arm/arch-adifcc/io.h deleted file mode 100644 index bdcaec08bddf..000000000000 --- a/include/asm-arm/arch-adifcc/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/io.h - * - * Author: Deepak Saxena - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) (PCIO_BASE + (a)) -#define __mem_pci(a) ((unsigned long)(a)) -#define __mem_isa(a) ((unsigned long)(a)) - -#endif diff --git a/include/asm-arm/arch-adifcc/irqs.h b/include/asm-arm/arch-adifcc/irqs.h deleted file mode 100644 index b559ca79ef80..000000000000 --- a/include/asm-arm/arch-adifcc/irqs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/include/asm-arm/arch-80200fcc/irqs.h - * - * Author: Deepak Saxena - * Copyright: (C) 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define IRQ_XS80200_BCU 0 /* Bus Control Unit */ -#define IRQ_XS80200_PMU 1 /* Performance Monitoring Unit */ -#define IRQ_XS80200_EXTIRQ 2 /* external IRQ signal */ -#define IRQ_XS80200_EXTFIQ 3 /* external IRQ signal */ - -#define NR_XS80200_IRQS 4 -#define NR_IRQS NR_XS80200_IRQS - -#define IRQ_XSCALE_PMU IRQ_XS80200_PMU diff --git a/include/asm-arm/arch-adifcc/memory.h b/include/asm-arm/arch-adifcc/memory.h deleted file mode 100644 index b76187d8d42b..000000000000 --- a/include/asm-arm/arch-adifcc/memory.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/memory.h - * - * Copyright (c) 2001 MontaVista Software, Inc. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PHYS_OFFSET (0xC0000000UL) - -/* - * Virtual view <-> DMA view memory address translations - * virt_to_bus: Used to translate the virtual address to an - * address suitable to be passed to set_dma_addr - * bus_to_virt: Used to convert an address for DMA operations - * to an address that the kernel can use. - * - * These are dummies for now. - */ -#define __virt_to_bus(x) __virt_to_phys(x) -#define __bus_to_virt(x) __phys_to_virt(x) - -#endif diff --git a/include/asm-arm/arch-adifcc/param.h b/include/asm-arm/arch-adifcc/param.h deleted file mode 100644 index b1a410eff447..000000000000 --- a/include/asm-arm/arch-adifcc/param.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/param.h - */ diff --git a/include/asm-arm/arch-adifcc/serial.h b/include/asm-arm/arch-adifcc/serial.h deleted file mode 100644 index ce4e87699c91..000000000000 --- a/include/asm-arm/arch-adifcc/serial.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * include/asm-arm/arch-adifcc/serial.h - * - * Author: Deepak Saxena - * - * Copyright (c) 2001 MontaVista Software, Inc. - */ -#include - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD ( 1852000 / 16 ) - -/* Standard COM flags */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - -#ifdef CONFIG_ARCH_ADI_EVB - -/* - * One serial port, int goes to FIQ, so we run in polled mode - */ -#define STD_SERIAL_PORT_DEFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0xff400000, 0, STD_COM_FLAGS } /* ttyS0 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif - diff --git a/include/asm-arm/arch-adifcc/system.h b/include/asm-arm/arch-adifcc/system.h deleted file mode 100644 index 4bffbdc294a0..000000000000 --- a/include/asm-arm/arch-adifcc/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -static inline void arch_idle(void) -{ -#if 0 - cpu_do_idle(); -#endif -} - - -static inline void arch_reset(char mode) -{ - if ( 1 && mode == 's') { - /* Jump into ROM at address 0 */ - cpu_reset(0); - } else { - /* Use on-chip reset capability */ - } -} - diff --git a/include/asm-arm/arch-adifcc/timex.h b/include/asm-arm/arch-adifcc/timex.h deleted file mode 100644 index d994c8abecd5..000000000000 --- a/include/asm-arm/arch-adifcc/timex.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/timex.h - * - * XScale architecture timex specifications - */ - -/* This is for a timer based on the XS80200's PMU counter */ - -#define CLOCK_TICK_RATE 600000000 /* Underlying HZ */ - diff --git a/include/asm-arm/arch-adifcc/uncompress.h b/include/asm-arm/arch-adifcc/uncompress.h deleted file mode 100644 index 792b4e17aa86..000000000000 --- a/include/asm-arm/arch-adifcc/uncompress.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/uncompress.h - * - * Author: Deepak Saxena - * - * Copyright (c) 2001 MontaVista Software, Inc. - * - */ - -#define UART_BASE ((volatile unsigned char *)0x00400000) - -static __inline__ void putc(char c) -{ - while ((UART_BASE[5] & 0x60) != 0x60); - UART_BASE[0] = c; -} - -/* - * This does not append a newline - */ -static void puts(const char *s) -{ - while (*s) { - putc(*s); - if (*s == '\n') - putc('\r'); - s++; - } -} - -/* - * nothing to do - */ -#define arch_decomp_setup() -#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-adifcc/vmalloc.h b/include/asm-arm/arch-adifcc/vmalloc.h deleted file mode 100644 index d45b27e1ad0e..000000000000 --- a/include/asm-arm/arch-adifcc/vmalloc.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * linux/include/asm-arm/arch-adifcc/vmalloc.h - */ - -/* - * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -#define VMALLOC_OFFSET (8*1024*1024) -#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_END (0xe8000000) -- cgit v1.2.3 From a99a281c3dbc66a1bf7ebeb0654f2f4efe1f7eab Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Jun 2004 23:26:48 +0100 Subject: [PCMCIA] 03-memwin Eliminate win->base and win->size elements from window_t. window_t contains struct pccard_mem_map, which contains a copy of these (sys_start, sys_stop) in a slightly different form. --- drivers/pcmcia/cs.c | 10 ++++------ include/pcmcia/ss.h | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 06462389ac7a..e25cf7f777e4 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -1549,7 +1549,7 @@ int pcmcia_release_window(window_handle_t win) /* Release system memory */ if(!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(win->base, win->size); + release_mem_region(win->ctl.sys_start, win->ctl.sys_stop - win->ctl.sys_start + 1); win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -1871,14 +1871,14 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->index = w; win->handle = *handle; win->sock = s; - win->base = req->Base; - win->size = req->Size; + win->ctl.sys_start = req->Base; if (!(s->features & SS_CAP_STATIC_MAP) && - find_mem_region(&win->base, win->size, align, + find_mem_region(&win->ctl.sys_start, req->Size, align, (req->Attributes & WIN_MAP_BELOW_1MB), (*handle)->dev_info, s)) return CS_IN_USE; + win->ctl.sys_stop = win->ctl.sys_start + req->Size - 1; (*handle)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ @@ -1893,8 +1893,6 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->ctl.flags |= MAP_16BIT; if (req->Attributes & WIN_USE_WAIT) win->ctl.flags |= MAP_USE_WAIT; - win->ctl.sys_start = win->base; - win->ctl.sys_stop = win->base + win->size-1; win->ctl.card_start = 0; if (s->ops->set_mem_map(s, &win->ctl) != 0) return CS_BAD_ARGS; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index c45bed63166c..510d75155c57 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -154,8 +154,6 @@ typedef struct window_t { u_short index; client_handle_t handle; struct pcmcia_socket *sock; - u_long base; - u_long size; pccard_mem_map ctl; } window_t; -- cgit v1.2.3 From d51d5d95df511761ed5493df34aa8c2a7e33e900 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sun, 20 Jun 2004 00:18:46 -0700 Subject: [NET]: Fix module refcounting of TC actions. --- include/linux/pkt_cls.h | 27 ++++++++++++------ include/linux/pkt_sched.h | 6 ++++ include/net/pkt_act.h | 14 +++++----- include/net/pkt_sched.h | 15 ++++++---- net/sched/Kconfig | 12 +++++--- net/sched/act_api.c | 70 ++++++++++++++++++++++++++++++++++++----------- net/sched/cls_u32.c | 25 ++++++++--------- net/sched/police.c | 27 ++++++++++-------- net/sched/sch_prio.c | 3 +- 9 files changed, 133 insertions(+), 66 deletions(-) (limited to 'include') diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 74daa67e81c9..06e4e728d4fc 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -71,16 +71,14 @@ bits 9,10,11: redirect counter - redirect TTL. Loop avoidance #define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT) #define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) -/* Action types */ +/* Action attributes */ enum { - TCA_ACT_UNSPEC=0, - TCA_ACT_KIND=1, - TCA_ACT_OPTIONS=2, - TCA_ACT_INDEX=3, - TCA_ACT_POLICE=4, - /* other actions go here */ - __TCA_ACT_MAX=255 + TCA_ACT_UNSPEC, + TCA_ACT_KIND, + TCA_ACT_OPTIONS, + TCA_ACT_INDEX, + __TCA_ACT_MAX }; #define TCA_ACT_MAX __TCA_ACT_MAX @@ -105,6 +103,17 @@ enum #define TC_ACT_REPEAT 6 #define TC_ACT_JUMP 0x10000000 +/* Action type identifiers*/ +enum +{ + TCA_ID_UNSPEC=0, + TCA_ID_POLICE=1, + /* other actions go here */ + __TCA_ID_MAX=255 +}; + +#define TCA_ID_MAX __TCA_ID_MAX + struct tc_police { __u32 index; @@ -213,7 +222,9 @@ struct tc_u32_sel unsigned char flags; unsigned char offshift; unsigned char nkeys; +#ifdef fix_u32_bug unsigned char fshift; /* fold shift */ +#endif __u16 offmask; __u16 off; diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 437cf3206e0e..86f98b500fa6 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -37,7 +37,13 @@ struct tc_stats __u32 bps; /* Current flow byte rate */ __u32 pps; /* Current flow packet rate */ __u32 qlen; +#ifdef CONFIG_NET_CLS_ACT +/* eventually remove the define here; adding this(useful) +field at least fixes the 8 byte layout problems we +have with MIPS and PPC because we have a u64 +*/ __u32 reqs; /* number of requeues happened */ +#endif __u32 backlog; #ifdef __KERNEL__ spinlock_t *lock; diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h index 390b82aea577..9f37ac40f1a0 100644 --- a/include/net/pkt_act.h +++ b/include/net/pkt_act.h @@ -69,20 +69,21 @@ tcf_hash_destroy(struct tcf_st *p) BUG_TRAP(0); } -static inline void +static inline int tcf_hash_release(struct tcf_st *p, int bind ) { + int ret = 0; if (p) { if (bind) { p->bindcnt--; } p->refcnt--; - if (p->refcnt > 0) - MOD_DEC_USE_COUNT; if(p->bindcnt <=0 && p->refcnt <= 0) { tcf_hash_destroy(p); + ret = 1; } } + return ret; } static __inline__ int @@ -117,7 +118,6 @@ tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, r->rta_len = skb->tail - (u8*)r; n_i++; if (n_i >= TCA_ACT_MAX_PRIO) { - printk("Jamal Dump Exceeded batch limit\n"); goto done; } } @@ -148,8 +148,9 @@ tcf_del_walker(struct sk_buff *skb, struct tc_action *a) while (p != NULL) { s_p = p->next; - printk("tcf_del_walker deleting ..\n"); - tcf_hash_release(p, 0); + if (ACT_P_DELETED == tcf_hash_release(p, 0)) { + module_put(a->ops->owner); + } n_i++; p = s_p; } @@ -250,7 +251,6 @@ tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int p->bindcnt = 1; } - MOD_INC_USE_COUNT; spin_lock_init(&p->lock); p->stats.lock = &p->lock; p->index = parm->index ? : tcf_hash_new_index(); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index eb6c344ddd95..f0d5fc3b66cc 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -414,6 +414,8 @@ struct tcf_police #ifdef CONFIG_NET_CLS_ACT +#define ACT_P_CREATED 1 +#define ACT_P_DELETED 1 #define tca_gen(name) \ struct tcf_##name *next; \ u32 index; \ @@ -442,10 +444,11 @@ struct tc_action_ops char kind[IFNAMSIZ]; __u32 type; /* TBD to match kind */ __u32 capab; /* capabilities includes 4 bit version */ + struct module *owner; int (*act)(struct sk_buff **, struct tc_action *); int (*get_stats)(struct sk_buff *, struct tc_action *); int (*dump)(struct sk_buff *, struct tc_action *,int , int); - void (*cleanup)(struct tc_action *, int bind); + int (*cleanup)(struct tc_action *, int bind); int (*lookup)(struct tc_action *, u32 ); int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); @@ -472,24 +475,26 @@ extern void tcf_police_destroy(struct tcf_police *p); extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); -static inline void tcf_police_release(struct tcf_police *p, int bind) +static inline int tcf_police_release(struct tcf_police *p, int bind) { + int ret = 0; #ifdef CONFIG_NET_CLS_ACT if (p) { if (bind) { p->bindcnt--; } p->refcnt--; - if (p->refcnt > 0) - MOD_DEC_USE_COUNT; - if (p->refcnt <= 0 && !p->bindcnt) + if (p->refcnt <= 0 && !p->bindcnt) { tcf_police_destroy(p); + ret = 1; + } } #else if (p && --p->refcnt == 0) tcf_police_destroy(p); #endif + return ret; } extern struct Qdisc noop_qdisc; diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 481b8ad2b84c..924e9f2dcee7 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -280,6 +280,7 @@ config CLS_U32_PERF help gathers stats that could be used to tune u32 classifier perfomance. Requires a new iproute2 + You MUST NOT turn this on if you dont have an update iproute2. config NET_CLS_IND bool "classify input device (slows things u32/fw) " @@ -289,6 +290,7 @@ config NET_CLS_IND metadata action appears because it slows things a little Available only for u32 and fw classifiers. Requires a new iproute2 + You MUST NOT turn this on if you dont have an update iproute2. config NET_CLS_RSVP tristate "Special RSVP classifier" @@ -321,22 +323,24 @@ config NET_CLS_RSVP6 config NET_CLS_ACT bool ' Packet ACTION ' - depends on NET_CLS && NET_QOS + depends on EXPERIMENTAL && NET_CLS && NET_QOS ---help--- This option requires you have a new iproute2. It enables tc extensions which can be used with tc classifiers. Only the u32 and fw classifiers are supported at the moment. + You MUST NOT turn this on if you dont have an update iproute2. config NET_ACT_POLICE tristate ' Policing Actions' - depends on NET_CLS_ACT + depends on NET_CLS_ACT ---help--- If you are using a newer iproute2 select this one, otherwise use one - NET_CLS_POLICE below + below to select a policer. + You MUST NOT turn this on if you dont have an update iproute2. config NET_CLS_POLICE bool "Traffic policing (needed for in/egress)" - depends on NET_CLS && NET_QOS && !NET_ACT_POLICE + depends on NET_CLS && NET_QOS && NET_ACT_POLICE!=y && NET_ACT_POLICE!=m help Say Y to support traffic policing (bandwidth limits). Needed for ingress and egress rate limiting. diff --git a/net/sched/act_api.c b/net/sched/act_api.c index a0ba2f6363e9..91076dc78b5d 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -48,11 +48,12 @@ int tcf_register_action(struct tc_action_ops *act) write_lock(&act_mod_lock); for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) { - if (strcmp(act->kind, a->kind) == 0) { + if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { write_unlock(&act_mod_lock); return -EEXIST; } } + act->next = NULL; *ap = act; @@ -89,8 +90,13 @@ struct tc_action_ops *tc_lookup_action_n(char *kind) if (kind) { read_lock(&act_mod_lock); for (a = act_base; a; a = a->next) { - if (strcmp(kind,a->kind) == 0) + if (strcmp(kind,a->kind) == 0) { + if (!try_module_get(a->owner)) { + read_unlock(&act_mod_lock); + return NULL; + } break; + } } read_unlock(&act_mod_lock); } @@ -108,8 +114,13 @@ struct tc_action_ops *tc_lookup_action(struct rtattr *kind) read_lock(&act_mod_lock); for (a = act_base; a; a = a->next) { - if (strcmp((char*)RTA_DATA(kind),a->kind) == 0) + if (strcmp((char*)RTA_DATA(kind),a->kind) == 0){ + if (!try_module_get(a->owner)) { + read_unlock(&act_mod_lock); + return NULL; + } break; + } } read_unlock(&act_mod_lock); } @@ -125,8 +136,13 @@ struct tc_action_ops *tc_lookup_action_id(u32 type) if (type) { read_lock(&act_mod_lock); for (a = act_base; a; a = a->next) { - if (a->type == type) + if (a->type == type) { + if (!try_module_get(a->owner)) { + read_unlock(&act_mod_lock); + return NULL; + } break; + } } read_unlock(&act_mod_lock); } @@ -177,7 +193,10 @@ void tcf_action_destroy(struct tc_action *act, int bind) if (a && a->ops && a->ops->cleanup) { DPRINTK("tcf_action_destroy destroying %p next %p\n", a,a->next?a->next:NULL); act = act->next; - a->ops->cleanup(a, bind); + if (ACT_P_DELETED == a->ops->cleanup(a, bind)) { + module_put(a->ops->owner); + } + a->ops = NULL; kfree(a); } else { /*FIXME: Remove later - catch insertion bugs*/ @@ -270,7 +289,6 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action * int err = -EINVAL; - if (NULL == name) { if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) goto err_out; @@ -306,27 +324,37 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action * } if (NULL == a) { - goto err_out; + goto err_mod; } /* backward compatibility for policer */ if (NULL == name) { err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind); if (0 > err ) { - return -EINVAL; + err = -EINVAL; + goto err_mod; } } else { err = a_o->init(rta, est, a, ovr, bind); if (0 > err ) { - return -EINVAL; + err = -EINVAL; + goto err_mod; } } - DPRINTK("tcf_action_init_1: sucess %s\n",act_name); - + /* module count goes up only when brand new policy is created + if it exists and is only bound to in a_o->init() then + ACT_P_CREATED is not returned (a zero is). + */ + if (ACT_P_CREATED != err) { + module_put(a_o->owner); + } a->ops = a_o; + DPRINTK("tcf_action_init_1: successfull %s \n",act_name); return 0; +err_mod: + module_put(a_o->owner); err_out: return err; } @@ -350,7 +378,7 @@ int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, err = -ENOMEM; goto bad_ret; } - memset(act, 0,sizeof(*act)); + memset(act, 0,sizeof(*act)); } act->next = NULL; if (0 > tcf_action_init_1(tb[i],est,act,name,ovr,bind)) { @@ -489,15 +517,21 @@ int tcf_action_get_1(struct rtattr *rta, struct tc_action *a, struct nlmsghdr *n } if (NULL == a) { - goto err_out; + goto err_mod; } a->ops = a_o; - if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) - return -EINVAL; + if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) { + a->ops = NULL; + err = -EINVAL; + goto err_mod; + } + module_put(a_o->owner); return 0; +err_mod: + module_put(a_o->owner); err_out: return err; } @@ -621,6 +655,7 @@ int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh->nlmsg_len = skb->tail - b; nlh->nlmsg_flags |= NLM_F_ROOT; + module_put(a->ops->owner); kfree(a); err = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); if (err > 0) @@ -630,6 +665,7 @@ int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) rtattr_failure: + module_put(a->ops->owner); nlmsg_failure: err_out: kfree_skb(skb); @@ -852,7 +888,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) char * find_dump_kind(struct nlmsghdr *n) { - struct rtattr *tb1, *tb2[TCA_ACT_MAX_PRIO+1]; + struct rtattr *tb1, *tb2[TCA_ACT_MAX+1]; struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; struct rtattr *rta[TCAA_MAX + 1]; struct rtattr *kind = NULL; @@ -941,10 +977,12 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) nlh->nlmsg_len = skb->tail - b; if (NETLINK_CB(cb->skb).pid && ret) nlh->nlmsg_flags |= NLM_F_MULTI; + module_put(a_o->owner); return skb->len; rtattr_failure: nlmsg_failure: + module_put(a_o->owner); skb_trim(skb, b - skb->data); return skb->len; } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7ea20b622fc8..24620274d6b8 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -101,12 +101,14 @@ static struct tc_u_common *u32_list; static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel) { +#ifdef fix_u32_bug unsigned h = (key & sel->hmask)>>sel->fshift; +#else + unsigned h = (key & sel->hmask); - /* h ^= h>>16; h ^= h>>8; - */ +#endif return h; } @@ -684,6 +686,14 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, return -EINVAL; s = RTA_DATA(tb[TCA_U32_SEL-1]); + +#ifdef CONFIG_CLS_U32_PERF + if (RTA_PAYLOAD(tb[TCA_U32_SEL-1]) < + (s->nkeys*sizeof(struct tc_u32_key)) + sizeof(struct tc_u32_sel)) { + printk("Please upgrade your iproute2 tools or compile proper options in!\n"); + return -EINVAL; +} +#endif n = kmalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); if (n == NULL) return -ENOBUFS; @@ -775,18 +785,7 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, if (n->ht_down) RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); #ifdef CONFIG_CLS_U32_PERF2 - printk("fh %x cnt %lu hit %lu\n",n->handle,n->sel.rcnt,n->sel.rhit); n->sel.rcnt = n->sel.rhit = 0; - /* dump key cnt */ - { - int i = 0; - struct tc_u32_key *key = n->sel.keys; - for (i = n->sel.nkeys; i>0; i--, key++) { - printk("\t key%d success %lu\n",i,key->kcnt); - key->cnt = 0; - } - } - #endif #ifdef CONFIG_NET_CLS_ACT /* again for backward compatible mode - we want diff --git a/net/sched/police.c b/net/sched/police.c index 14ccbae43858..2556651b7366 100644 --- a/net/sched/police.c +++ b/net/sched/police.c @@ -166,6 +166,7 @@ void tcf_police_destroy(struct tcf_police *p) int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *a, int ovr, int bind) { unsigned h; + int ret = 0; struct rtattr *tb[TCA_POLICE_MAX]; struct tc_police *parm; struct tcf_police *p; @@ -195,7 +196,7 @@ int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_actio goto override; } spin_unlock(&p->lock); - return 1; + return ret; } p = kmalloc(sizeof(*p), GFP_KERNEL); @@ -203,7 +204,7 @@ int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_actio return -1; memset(p, 0, sizeof(*p)); - MOD_INC_USE_COUNT; + ret = 1; p->refcnt = 1; spin_lock_init(&p->lock); p->stats.lock = &p->lock; @@ -211,11 +212,13 @@ int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_actio p->bindcnt = 1; override: if (parm->rate.rate) { - if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL) + if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL) { goto failure; + } if (parm->peakrate.rate && - (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL) + (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL) { goto failure; + } } if (tb[TCA_POLICE_RESULT-1]) p->result = *(int*)RTA_DATA(tb[TCA_POLICE_RESULT-1]); @@ -236,7 +239,7 @@ override: if (ovr) { spin_unlock(&p->lock); - return 1; + return ret; } PSCHED_GET_TIME(p->t_c); p->index = parm->index ? : tcf_police_new_index(); @@ -250,9 +253,8 @@ override: tcf_police_ht[h] = p; write_unlock_bh(&police_lock); - MOD_INC_USE_COUNT; a->priv = (void *)p; - return 1; + return ret; failure: if (p->R_tab) @@ -263,12 +265,14 @@ failure: return -1; } -void tcf_act_police_cleanup(struct tc_action *a, int bind) +int tcf_act_police_cleanup(struct tc_action *a, int bind) { struct tcf_police *p; p = PRIV(a); if (NULL != p) - tcf_police_release(p, bind); + return tcf_police_release(p, bind); + + return 0; } int tcf_act_police_stats(struct sk_buff *skb, struct tc_action *a) @@ -392,8 +396,9 @@ MODULE_LICENSE("GPL"); struct tc_action_ops act_police_ops = { NULL, "police", - TCA_ACT_POLICE, + TCA_ID_POLICE, TCA_CAP_NONE, + THIS_MODULE, tcf_act_police, tcf_act_police_stats, tcf_act_police_dump, @@ -437,7 +442,6 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) if (parm->index && (p = tcf_police_lookup(parm->index)) != NULL) { p->refcnt++; - MOD_INC_USE_COUNT; return p; } @@ -483,7 +487,6 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) p->next = tcf_police_ht[h]; tcf_police_ht[h] = p; write_unlock_bh(&police_lock); - MOD_INC_USE_COUNT; return p; failure: diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 52a4c2e28272..fa6741d96a27 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -129,11 +129,12 @@ dropped: static int prio_requeue(struct sk_buff *skb, struct Qdisc* sch) { - //struct prio_sched_data *q = (struct prio_sched_data *)sch->data; struct Qdisc *qdisc; int ret = NET_XMIT_DROP; +#ifdef CONFIG_NET_CLS_ACT sch->stats.reqs++; +#endif qdisc = prio_classify(skb, sch, &ret); if (qdisc == NULL) goto dropped; -- cgit v1.2.3 From ba5d92231e4cdea031a85e91aefca3e14c12ae8e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 20 Jun 2004 03:40:34 -0700 Subject: [SPARC64]: bug.h needs compiler.h Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/asm-sparc64/bug.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h index bdaba5ccc11e..bfac1afa9983 100644 --- a/include/asm-sparc64/bug.h +++ b/include/asm-sparc64/bug.h @@ -3,6 +3,8 @@ #ifndef _SPARC64_BUG_H #define _SPARC64_BUG_H +#include + #ifdef CONFIG_DEBUG_BUGVERBOSE extern void do_BUG(const char *file, int line); #define BUG() do { \ -- cgit v1.2.3 From 3beb5b3948aaf0d09956039f9e4414566465b7f9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 20 Jun 2004 17:33:23 -0300 Subject: [NET] generalise wait_for_tcp_connect This will be used by the poor cousins, look, for instance, at x25_wait_for_connection_establishment :-) Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/tcp.h | 2 -- include/net/sock.h | 4 ++++ net/core/sock.c | 1 + net/core/stream.c | 37 +++++++++++++++++++++++++++++++++++++ net/ipv4/tcp.c | 43 ++++--------------------------------------- net/ipv4/tcp_input.c | 2 +- 6 files changed, 47 insertions(+), 42 deletions(-) (limited to 'include') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 39e2d22619dc..f807f0507815 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -371,8 +371,6 @@ struct tcp_opt { struct open_request *accept_queue; struct open_request *accept_queue_tail; - int write_pending; /* A write to socket waits to start. */ - unsigned int keepalive_time; /* time before keep alive takes place */ unsigned int keepalive_intvl; /* time interval between keep alive probes */ int linger2; diff --git a/include/net/sock.h b/include/net/sock.h index 0ee6ccddca40..0a7546a9957c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -167,6 +167,7 @@ struct sock_common { * @sk_socket - Identd and reporting IO signals * @sk_user_data - RPC layer private data * @sk_owner - module that owns this socket + * @sk_write_pending - a write to stream socket waits to start * @sk_state_change - callback to indicate change in the state of the sock * @sk_data_ready - callback to indicate there is data to be processed * @sk_write_space - callback to indicate there is bf sending space available @@ -247,6 +248,7 @@ struct sock { struct socket *sk_socket; void *sk_user_data; struct module *sk_owner; + int sk_write_pending; void *sk_security; void (*sk_state_change)(struct sock *sk); void (*sk_data_ready)(struct sock *sk, int bytes); @@ -458,6 +460,8 @@ do { if (!(__sk)->sk_backlog.tail) { \ rc; \ }) +extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); + extern int sk_wait_data(struct sock *sk, long *timeo); /* IP protocol blocks we attach to sockets. diff --git a/net/core/sock.c b/net/core/sock.c index 289f5824e97c..cc84b85f5b0f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1176,6 +1176,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_peercred.pid = 0; sk->sk_peercred.uid = -1; sk->sk_peercred.gid = -1; + sk->sk_write_pending = 0; sk->sk_rcvlowat = 1; sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; diff --git a/net/core/stream.c b/net/core/stream.c index 24a6f72a0594..04330ba71e03 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -39,3 +40,39 @@ void sk_stream_write_space(struct sock *sk) } EXPORT_SYMBOL(sk_stream_write_space); + +/** + * sk_stream_wait_connect - Wait for a socket to get into the connected state + * @sk - sock to wait on + * @timeo_p - for how long to wait + * + * Must be called with the socket locked. + */ +int sk_stream_wait_connect(struct sock *sk, long *timeo_p) +{ + struct task_struct *tsk = current; + DEFINE_WAIT(wait); + + while (1) { + if (sk->sk_err) + return sock_error(sk); + if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) + return -EPIPE; + if (!*timeo_p) + return -EAGAIN; + if (signal_pending(tsk)) + return sock_intr_errno(*timeo_p); + + prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); + sk->sk_write_pending++; + if (sk_wait_event(sk, timeo_p, + !((1 << sk->sk_state) & + ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)))) + break; + finish_wait(sk->sk_sleep, &wait); + sk->sk_write_pending--; + } + return 0; +} + +EXPORT_SYMBOL(sk_stream_wait_connect); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 476716f4bc30..30b04f122ecd 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -636,46 +636,11 @@ static void tcp_listen_stop (struct sock *sk) BUG_TRAP(!sk->sk_ack_backlog); } -/* - * Wait for a socket to get into the connected state - * - * Note: Must be called with the socket locked. - */ -static int wait_for_tcp_connect(struct sock *sk, int flags, long *timeo_p) -{ - struct tcp_opt *tp = tcp_sk(sk); - struct task_struct *tsk = current; - DEFINE_WAIT(wait); - - while ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { - if (sk->sk_err) - return sock_error(sk); - if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) - return -EPIPE; - if (!*timeo_p) - return -EAGAIN; - if (signal_pending(tsk)) - return sock_intr_errno(*timeo_p); - - prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); - tp->write_pending++; - - release_sock(sk); - *timeo_p = schedule_timeout(*timeo_p); - lock_sock(sk); - - finish_wait(sk->sk_sleep, &wait); - tp->write_pending--; - } - return 0; -} - /* * Wait for more memory for a socket */ static int wait_for_tcp_memory(struct sock *sk, long *timeo) { - struct tcp_opt *tp = tcp_sk(sk); int err = 0; long vm_wait = 0; long current_timeo = *timeo; @@ -700,12 +665,12 @@ static int wait_for_tcp_memory(struct sock *sk, long *timeo) break; set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); - tp->write_pending++; + sk->sk_write_pending++; release_sock(sk); if (!sk_stream_memory_free(sk) || vm_wait) current_timeo = schedule_timeout(current_timeo); lock_sock(sk); - tp->write_pending--; + sk->sk_write_pending--; if (vm_wait) { vm_wait -= current_timeo; @@ -812,7 +777,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse /* Wait for a connection to finish. */ if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) - if ((err = wait_for_tcp_connect(sk, 0, &timeo)) != 0) + if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) goto out_err; clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); @@ -965,7 +930,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* Wait for a connection to finish. */ if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) - if ((err = wait_for_tcp_connect(sk, flags, &timeo)) != 0) + if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) goto out_err; /* This should be in poll */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 708005f0d0b0..e310b09964fd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4474,7 +4474,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, sk_wake_async(sk, 0, POLL_OUT); } - if (tp->write_pending || tp->defer_accept || tp->ack.pingpong) { + if (sk->sk_write_pending || tp->defer_accept || tp->ack.pingpong) { /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * -- cgit v1.2.3 From 16a9e6dc86af9a6ca6935d13884ec4f2ecd9ac55 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 20 Jun 2004 17:47:17 -0300 Subject: [NET] introduce sk_stream_wait_close, from tcp code Will be used by the poor cousins. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 1 + net/core/stream.c | 28 ++++++++++++++++++++++++++++ net/ipv4/tcp.c | 28 +--------------------------- 3 files changed, 30 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 0a7546a9957c..e5bc2560bc2e 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -461,6 +461,7 @@ do { if (!(__sk)->sk_backlog.tail) { \ }) extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); +extern void sk_stream_wait_close(struct sock *sk, long timeo_p); extern int sk_wait_data(struct sock *sk, long *timeo); diff --git a/net/core/stream.c b/net/core/stream.c index 04330ba71e03..8f5a63532ef8 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -76,3 +76,31 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) } EXPORT_SYMBOL(sk_stream_wait_connect); + +/** + * sk_stream_closing - Return 1 if we still have things to send in our buffers. + * @sk - socket to verify + */ +static inline int sk_stream_closing(struct sock *sk) +{ + return (1 << sk->sk_state) & + (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK); +} + +void sk_stream_wait_close(struct sock *sk, long timeout) +{ + if (timeout) { + DEFINE_WAIT(wait); + + do { + prepare_to_wait(sk->sk_sleep, &wait, + TASK_INTERRUPTIBLE); + if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk))) + break; + } while (!signal_pending(current) && timeout); + + finish_wait(sk->sk_sleep, &wait); + } +} + +EXPORT_SYMBOL(sk_stream_wait_close); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 30b04f122ecd..fec54474867b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1712,17 +1712,6 @@ void tcp_shutdown(struct sock *sk, int how) } } - -/* - * Return 1 if we still have things to send in our buffers. - */ - -static inline int closing(struct sock *sk) -{ - return (1 << sk->sk_state) & - (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK); -} - static __inline__ void tcp_kill_sk_queues(struct sock *sk) { /* First the read buffer. */ @@ -1865,22 +1854,7 @@ void tcp_close(struct sock *sk, long timeout) tcp_send_fin(sk); } - if (timeout) { - struct task_struct *tsk = current; - DEFINE_WAIT(wait); - - do { - prepare_to_wait(sk->sk_sleep, &wait, - TASK_INTERRUPTIBLE); - if (!closing(sk)) - break; - release_sock(sk); - timeout = schedule_timeout(timeout); - lock_sock(sk); - } while (!signal_pending(tsk) && timeout); - - finish_wait(sk->sk_sleep, &wait); - } + sk_stream_wait_close(sk, timeout); adjudge_to_death: /* It is the last release_sock in its life. It will remove backlog. */ -- cgit v1.2.3 From ce2ae3b7fa0285b0af84e1aeeb4450ea3862289f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 20 Jun 2004 17:57:54 -0300 Subject: [NET] generalise wait_for_tcp_memory Renaming it to sk_stream_wait_memory Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 1 + net/core/stream.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ net/ipv4/tcp.c | 65 ++---------------------------------------------------- net/sctp/socket.c | 2 +- 4 files changed, 67 insertions(+), 64 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index e5bc2560bc2e..54a494a657fc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -461,6 +461,7 @@ do { if (!(__sk)->sk_backlog.tail) { \ }) extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); +extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p); extern void sk_stream_wait_close(struct sock *sk, long timeo_p); extern int sk_wait_data(struct sock *sk, long *timeo); diff --git a/net/core/stream.c b/net/core/stream.c index 8f5a63532ef8..eaeea6843b0a 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -104,3 +104,66 @@ void sk_stream_wait_close(struct sock *sk, long timeout) } EXPORT_SYMBOL(sk_stream_wait_close); + +/** + * sk_stream_wait_memory - Wait for more memory for a socket + * @sk - socket to wait for memory + * @timeo_p - for how long + */ +int sk_stream_wait_memory(struct sock *sk, long *timeo_p) +{ + int err = 0; + long vm_wait = 0; + long current_timeo = *timeo_p; + DEFINE_WAIT(wait); + + if (sk_stream_memory_free(sk)) + current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2; + + while (1) { + set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); + + prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); + + if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) + goto do_error; + if (!*timeo_p) + goto do_nonblock; + if (signal_pending(current)) + goto do_interrupted; + clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); + if (sk_stream_memory_free(sk) && !vm_wait) + break; + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; + sk_wait_event(sk, ¤t_timeo, sk_stream_memory_free(sk) && + vm_wait); + sk->sk_write_pending--; + + if (vm_wait) { + vm_wait -= current_timeo; + current_timeo = *timeo_p; + if (current_timeo != MAX_SCHEDULE_TIMEOUT && + (current_timeo -= vm_wait) < 0) + current_timeo = 0; + vm_wait = 0; + } + *timeo_p = current_timeo; + } +out: + finish_wait(sk->sk_sleep, &wait); + return err; + +do_error: + err = -EPIPE; + goto out; +do_nonblock: + err = -EAGAIN; + goto out; +do_interrupted: + err = sock_intr_errno(*timeo_p); + goto out; +} + +EXPORT_SYMBOL(sk_stream_wait_memory); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index fec54474867b..ba5cb0beb71d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -636,67 +636,6 @@ static void tcp_listen_stop (struct sock *sk) BUG_TRAP(!sk->sk_ack_backlog); } -/* - * Wait for more memory for a socket - */ -static int wait_for_tcp_memory(struct sock *sk, long *timeo) -{ - int err = 0; - long vm_wait = 0; - long current_timeo = *timeo; - DEFINE_WAIT(wait); - - if (sk_stream_memory_free(sk)) - current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2; - - for (;;) { - set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); - - prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); - - if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) - goto do_error; - if (!*timeo) - goto do_nonblock; - if (signal_pending(current)) - goto do_interrupted; - clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); - if (sk_stream_memory_free(sk) && !vm_wait) - break; - - set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); - sk->sk_write_pending++; - release_sock(sk); - if (!sk_stream_memory_free(sk) || vm_wait) - current_timeo = schedule_timeout(current_timeo); - lock_sock(sk); - sk->sk_write_pending--; - - if (vm_wait) { - vm_wait -= current_timeo; - current_timeo = *timeo; - if (current_timeo != MAX_SCHEDULE_TIMEOUT && - (current_timeo -= vm_wait) < 0) - current_timeo = 0; - vm_wait = 0; - } - *timeo = current_timeo; - } -out: - finish_wait(sk->sk_sleep, &wait); - return err; - -do_error: - err = -EPIPE; - goto out; -do_nonblock: - err = -EAGAIN; - goto out; -do_interrupted: - err = sock_intr_errno(*timeo); - goto out; -} - static inline void fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size) { @@ -854,7 +793,7 @@ wait_for_memory: if (copied) tcp_push(sk, tp, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); - if ((err = wait_for_tcp_memory(sk, &timeo)) != 0) + if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); @@ -1097,7 +1036,7 @@ wait_for_memory: if (copied) tcp_push(sk, tp, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); - if ((err = wait_for_tcp_memory(sk, &timeo)) != 0) + if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 491b510b0782..d1b683952499 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -990,7 +990,7 @@ static int sctp_error(struct sock *sk, int flags, int err) * Note: This function could use a rewrite especially when explicit * connect support comes in. */ -/* BUG: We do not implement the equivalent of wait_for_tcp_memory(). */ +/* BUG: We do not implement the equivalent of sk_stream_wait_memory(). */ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *); -- cgit v1.2.3 From 9c40518616528e33801f34d6ac22b8b3d7ad4dd6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Jun 2004 23:53:25 +0100 Subject: [PCMCIA] 04-memres Make find_mem_region() return a struct resource. We preserve pccard_mem_map's sys_start and sys_stop elements for the moment since socket drivers are relying on this information for setting up their windows. --- drivers/pcmcia/cistpl.c | 24 +++++++++++++----------- drivers/pcmcia/cs.c | 30 +++++++++++++++++++----------- drivers/pcmcia/cs_internal.h | 2 +- drivers/pcmcia/i82092.c | 4 ++-- drivers/pcmcia/i82365.c | 4 ++-- drivers/pcmcia/pd6729.c | 4 ++-- drivers/pcmcia/rsrc_mgr.c | 18 ++++++++++-------- drivers/pcmcia/tcic.c | 4 ++-- drivers/pcmcia/yenta_socket.c | 4 ++-- include/pcmcia/ss.h | 1 + 10 files changed, 54 insertions(+), 41 deletions(-) (limited to 'include') diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 2892e5adc98c..b78d41a3c840 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -85,13 +85,15 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ void release_cis_mem(struct pcmcia_socket *s) { - if (s->cis_mem.sys_start != 0) { + if (s->cis_mem.flags & MAP_ACTIVE) { s->cis_mem.flags &= ~MAP_ACTIVE; s->ops->set_mem_map(s, &s->cis_mem); - if (!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(s->cis_mem.sys_start, s->map_size); + if (s->cis_mem.res) { + release_resource(s->cis_mem.res); + kfree(s->cis_mem.res); + s->cis_mem.res = NULL; + } iounmap(s->cis_virt); - s->cis_mem.sys_start = 0; s->cis_virt = NULL; } } @@ -105,16 +107,16 @@ static unsigned char * set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) { pccard_mem_map *mem = &s->cis_mem; - if (!(s->features & SS_CAP_STATIC_MAP) && - mem->sys_start == 0) { - mem->sys_start = 0; - if (find_mem_region(&mem->sys_start, s->map_size, - s->map_size, 0, "card services", s)) { + if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { + mem->res = find_mem_region(0, s->map_size, s->map_size, 0, + "card services", s); + if (mem->res == NULL) { printk(KERN_NOTICE "cs: unable to map card memory!\n"); return NULL; } - mem->sys_stop = mem->sys_start+s->map_size-1; - s->cis_virt = ioremap(mem->sys_start, s->map_size); + mem->sys_start = mem->res->start; + mem->sys_stop = mem->res->end; + s->cis_virt = ioremap(mem->res->start, s->map_size); } mem->card_start = card_offset; mem->flags = flags; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index e25cf7f777e4..44bfe71c70cf 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -1100,8 +1100,8 @@ int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req) if (w == MAX_WIN) return CS_NO_MORE_ITEMS; win = &s->win[w]; - req->Base = win->ctl.sys_start; - req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1; + req->Base = win->ctl.res->start; + req->Size = win->ctl.res->end - win->ctl.res->start + 1; req->AccessSpeed = win->ctl.speed; req->Attributes = 0; if (win->ctl.flags & MAP_ATTRIB) @@ -1548,8 +1548,11 @@ int pcmcia_release_window(window_handle_t win) s->state &= ~SOCKET_WIN_REQ(win->index); /* Release system memory */ - if(!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(win->ctl.sys_start, win->ctl.sys_stop - win->ctl.sys_start + 1); + if (win->ctl.res) { + release_resource(win->ctl.res); + kfree(win->ctl.res); + win->ctl.res = NULL; + } win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -1871,14 +1874,19 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->index = w; win->handle = *handle; win->sock = s; - win->ctl.sys_start = req->Base; - if (!(s->features & SS_CAP_STATIC_MAP) && - find_mem_region(&win->ctl.sys_start, req->Size, align, - (req->Attributes & WIN_MAP_BELOW_1MB), - (*handle)->dev_info, s)) - return CS_IN_USE; - win->ctl.sys_stop = win->ctl.sys_start + req->Size - 1; + if (!(s->features & SS_CAP_STATIC_MAP)) { + win->ctl.res = find_mem_region(req->Base, req->Size, align, + (req->Attributes & WIN_MAP_BELOW_1MB), + (*handle)->dev_info, s); + if (!win->ctl.res) + return CS_IN_USE; + win->ctl.sys_start = win->ctl.res->start; + win->ctl.sys_stop = win->ctl.res->end; + } else { + win->ctl.sys_start = req->Base; + win->ctl.sys_stop = req->Base + req->Size - 1; + } (*handle)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index e73efb05c93e..88396d87be21 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -185,7 +185,7 @@ struct resource *find_io_region(unsigned long base, int num, unsigned long align char *name, struct pcmcia_socket *s); int adjust_io_region(struct resource *res, unsigned long r_start, unsigned long r_end, struct pcmcia_socket *s); -int find_mem_region(u_long *base, u_long num, u_long align, +struct resource *find_mem_region(u_long base, u_long num, u_long align, int low, char *name, struct pcmcia_socket *s); int try_irq(u_int Attributes, int irq, int specific); void undo_irq(u_int Attributes, int irq); diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 69125c3b3257..3115eb3bc7f1 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -420,12 +420,12 @@ static void set_bridge_state(int sock) static int i82092aa_init(struct pcmcia_socket *sock) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; enter("i82092aa_init"); - mem.sys_stop = 0x0fff; for (i = 0; i < 2; i++) { io.map = i; i82092aa_set_io_map(sock, &io); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 120569b1f12e..9e20b68aa49b 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1308,10 +1308,10 @@ static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) static int pcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; pcic_set_io_map(s, &io); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index e92d63a67c43..694e13f43aac 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -563,10 +563,10 @@ static int pd6729_suspend(struct pcmcia_socket *sock) static int pd6729_init(struct pcmcia_socket *sock) { int i; + struct resource res = { .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff }; - mem.sys_stop = 0x0fff; pd6729_set_socket(sock, &dead_socket); for (i = 0; i < 2; i++) { io.map = i; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index d4e0a88f3cb6..5a246dddb95d 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -303,6 +303,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in s->cis_mem.sys_start = res->start; s->cis_mem.sys_stop = res->end; + s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { ret = pcmcia_validate_cis(s->clients, info); @@ -313,6 +314,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in } s->cis_mem.sys_start = 0; s->cis_mem.sys_stop = 0; + s->cis_mem.res = NULL; if ((ret != 0) || (info->Chains == 0)) return 0; return 1; @@ -332,6 +334,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res) map.speed = 0; map.sys_start = res->start; map.sys_stop = res->end; + map.res = res; map.card_start = 0; s->ops->set_mem_map(s, &map); @@ -661,8 +664,8 @@ struct resource *find_io_region(unsigned long base, int num, return res; } -int find_mem_region(u_long *base, u_long num, u_long align, - int low, char *name, struct pcmcia_socket *s) +struct resource *find_mem_region(u_long base, u_long num, u_long align, + int low, char *name, struct pcmcia_socket *s) { struct resource *res = make_resource(0, num, IORESOURCE_MEM, name); struct pcmcia_align_data data; @@ -672,16 +675,16 @@ int find_mem_region(u_long *base, u_long num, u_long align, low = low || !(s->features & SS_CAP_PAGE_REGS); data.mask = align - 1; - data.offset = *base & data.mask; + data.offset = base & data.mask; data.map = &mem_db; for (i = 0; i < 2; i++) { if (low) { max = 0x100000UL; - min = *base < max ? *base : 0; + min = base < max ? base : 0; } else { max = ~0UL; - min = 0x100000UL + *base; + min = 0x100000UL + base; } down(&rsrc_sem); @@ -702,10 +705,9 @@ int find_mem_region(u_long *base, u_long num, u_long align, if (ret != 0) { kfree(res); - } else { - *base = res->start; + res = NULL; } - return ret; + return res; } /*====================================================================== diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 367222170f07..f3b38e96dcdc 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -868,10 +868,10 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m static int tcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; tcic_set_io_map(s, &io); diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 767b2c1a23b4..ae3b05c2b706 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -445,10 +445,10 @@ static void yenta_interrupt_wrapper(unsigned long data) static void yenta_clear_maps(struct yenta_socket *socket) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; - mem.sys_stop = 0x0fff; yenta_set_socket(&socket->socket, &dead_socket); for (i = 0; i < 2; i++) { io.map = i; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 510d75155c57..4df622f6da47 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -105,6 +105,7 @@ typedef struct pccard_mem_map { u_short speed; u_long sys_start, sys_stop; u_int card_start; + struct resource *res; } pccard_mem_map; typedef struct cb_bridge_map { -- cgit v1.2.3 From 30962905aa5bfcd061496ff9f6dc22006dfd4c09 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 21 Jun 2004 00:28:23 -0700 Subject: [NETFILTER]: Fix non-existant config option for IP_NF_ASSERT, fix some broken assertions Signed-off-by: Patrick McHardy Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_conntrack.h | 2 +- net/ipv4/netfilter/ip_conntrack_core.c | 4 +--- net/ipv4/netfilter/ip_nat_core.c | 5 +++-- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 26d7f3a11fd7..1974f162f5a0 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -103,7 +103,7 @@ union ip_conntrack_nat_help { #include #include -#ifdef CONFIG_NF_DEBUG +#ifdef CONFIG_NETFILTER_DEBUG #define IP_NF_ASSERT(x) \ do { \ if (!(x)) \ diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 1f47e9bbc4eb..35b7e8f3330d 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -174,13 +174,12 @@ static void destroy_expect(struct ip_conntrack_expect *exp) { DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); - IP_NF_ASSERT(atomic_read(&exp->use)); + IP_NF_ASSERT(atomic_read(&exp->use) == 0); IP_NF_ASSERT(!timer_pending(&exp->timeout)); kfree(exp); } - inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) { IP_NF_ASSERT(exp); @@ -716,7 +715,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", conntrack, expected); /* Welcome, Mr. Bond. We've been expecting you... */ - IP_NF_ASSERT(master_ct(conntrack)); __set_bit(IPS_EXPECTED_BIT, &conntrack->status); conntrack->master = expected; expected->sibling = conntrack; diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 3e5ca975459d..40116b9850d1 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -528,6 +528,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, MUST_BE_WRITE_LOCKED(&ip_nat_lock); IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_POST_ROUTING + || hooknum == NF_IP_LOCAL_IN || hooknum == NF_IP_LOCAL_OUT); IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS); IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); @@ -899,10 +900,10 @@ icmp_reply_translation(struct sk_buff **pskb, /* Must be RELATED */ IP_NF_ASSERT((*pskb)->nfct - - (struct ip_conntrack *)(*pskb)->nfct->master + - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos == IP_CT_RELATED || (*pskb)->nfct - - (struct ip_conntrack *)(*pskb)->nfct->master + - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos == IP_CT_RELATED+IP_CT_IS_REPLY); /* Redirects on non-null nats must be dropped, else they'll -- cgit v1.2.3 From 02c83c2e15de9b2a06275388f0b288a2af92ad3e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 21 Jun 2004 00:34:20 -0700 Subject: [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields Signed-off-by: Patrick McHardy Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/skbuff.h | 15 ++++++++++++--- net/ipv4/ip_gre.c | 16 ++-------------- net/ipv4/ip_input.c | 6 +----- net/ipv4/ipip.c | 16 ++-------------- net/ipv4/ipmr.c | 15 +++------------ net/ipv4/netfilter/ipt_REJECT.c | 6 +----- net/ipv6/ip6_tunnel.c | 8 +------- net/ipv6/sit.c | 16 ++-------------- 8 files changed, 24 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 1b33d607f276..f47163e84760 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1109,6 +1109,14 @@ static inline void nf_conntrack_get(struct nf_ct_info *nfct) if (nfct) atomic_inc(&nfct->master->use); } +static inline void nf_reset(struct sk_buff *skb) +{ + nf_conntrack_put(skb->nfct); + skb->nfct = NULL; +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif +} #ifdef CONFIG_BRIDGE_NETFILTER static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) @@ -1121,9 +1129,10 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) if (nf_bridge) atomic_inc(&nf_bridge->use); } -#endif - -#endif +#endif /* CONFIG_BRIDGE_NETFILTER */ +#else /* CONFIG_NETFILTER */ +static inline void nf_reset(struct sk_buff *skb) {} +#endif /* CONFIG_NETFILTER */ #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4a227f51b2c1..0c2f8ca5ae83 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -643,13 +643,7 @@ int ipgre_rcv(struct sk_buff *skb) skb->dev = tunnel->dev; dst_release(skb->dst); skb->dst = NULL; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); ipgre_ecn_decapsulate(iph, skb); netif_rx(skb); read_unlock(&ipgre_lock); @@ -877,13 +871,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } } -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); IPTUNNEL_XMIT(); tunnel->recursion--; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2f71ed5cfcc9..5b473004fab9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -202,17 +202,13 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) #ifdef CONFIG_NETFILTER_DEBUG nf_debug_ip_local_deliver(skb); - skb->nf_debug = 0; #endif /*CONFIG_NETFILTER_DEBUG*/ __skb_pull(skb, ihl); -#ifdef CONFIG_NETFILTER /* Free reference early: we don't need it any more, and it may hold ip_conntrack module loaded indefinitely. */ - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#endif /*CONFIG_NETFILTER*/ + nf_reset(skb); /* Point into the IP datagram, just past the header. */ skb->h.raw = skb->data; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 757b1d3f6aa2..98ba22404ac3 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -497,13 +497,7 @@ static int ipip_rcv(struct sk_buff *skb) skb->dev = tunnel->dev; dst_release(skb->dst); skb->dst = NULL; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); ipip_ecn_decapsulate(iph, skb); netif_rx(skb); read_unlock(&ipip_lock); @@ -648,13 +642,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if ((iph->ttl = tiph->ttl) == 0) iph->ttl = old_iph->ttl; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); IPTUNNEL_XMIT(); tunnel->recursion--; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index a25e56077072..3aecdcf5e085 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1105,10 +1105,7 @@ static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr) skb->h.ipiph = skb->nh.iph; skb->nh.iph = iph; memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#endif + nf_reset(skb); } static inline int ipmr_forward_finish(struct sk_buff *skb) @@ -1461,10 +1458,7 @@ int pim_rcv_v1(struct sk_buff * skb) skb->dst = NULL; ((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len; ((struct net_device_stats*)reg_dev->priv)->rx_packets++; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#endif + nf_reset(skb); netif_rx(skb); dev_put(reg_dev); return 0; @@ -1520,10 +1514,7 @@ static int pim_rcv(struct sk_buff * skb) ((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len; ((struct net_device_stats*)reg_dev->priv)->rx_packets++; skb->dst = NULL; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#endif + nf_reset(skb); netif_rx(skb); dev_put(reg_dev); return 0; diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index f6183f968b2b..b8018cb023ff 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -142,12 +142,8 @@ static void send_reset(struct sk_buff *oldskb, int hook) nskb->dst = &rt->u.dst; /* This packet will not be the same as the other: clear nf fields */ - nf_conntrack_put(nskb->nfct); - nskb->nfct = NULL; + nf_reset(nskb); nskb->nfcache = 0; -#ifdef CONFIG_NETFILTER_DEBUG - nskb->nf_debug = 0; -#endif nskb->nfmark = 0; #ifdef CONFIG_BRIDGE_NETFILTER nf_bridge_put(nskb->nf_bridge); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9e5677dd45a2..0c8db0391a78 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -722,13 +722,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ipv6h->nexthdr = proto; ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src); ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst); -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); pkt_len = skb->len; err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2fac873fdd3d..2958bb9c76fe 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -388,13 +388,7 @@ static int ipip6_rcv(struct sk_buff *skb) skb->dev = tunnel->dev; dst_release(skb->dst); skb->dst = NULL; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); ipip6_ecn_decapsulate(iph, skb); netif_rx(skb); read_unlock(&ipip6_lock); @@ -580,13 +574,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if ((iph->ttl = tiph->ttl) == 0) iph->ttl = iph6->hop_limit; -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); IPTUNNEL_XMIT(); tunnel->recursion--; -- cgit v1.2.3 From fd4daaf7b32473367b25c2936d2cc71eb72e1e72 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 21 Jun 2004 00:36:31 -0700 Subject: [NETFILTER]: Add addrtype match Signed-off-by: Patrick McHardy Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ipt_addrtype.h | 11 +++++ net/ipv4/netfilter/Kconfig | 10 ++++ net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/ipt_addrtype.c | 77 +++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 include/linux/netfilter_ipv4/ipt_addrtype.h create mode 100644 net/ipv4/netfilter/ipt_addrtype.c (limited to 'include') diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h new file mode 100644 index 000000000000..166ed01a8122 --- /dev/null +++ b/include/linux/netfilter_ipv4/ipt_addrtype.h @@ -0,0 +1,11 @@ +#ifndef _IPT_ADDRTYPE_H +#define _IPT_ADDRTYPE_H + +struct ipt_addrtype_info { + u_int16_t source; /* source-type mask */ + u_int16_t dest; /* dest-type mask */ + u_int32_t invert_source; + u_int32_t invert_dest; +}; + +#endif diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index f5a5110f97da..5e9b01f74c30 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -603,5 +603,15 @@ config IP_NF_RAW . If unsure, say `N'. help +config IP_NF_MATCH_ADDRTYPE + tristate 'address type match support' + depends on IP_NF_IPTABLES + help + This option allows you to match what routing thinks of an address, + eg. UNICAST, LOCAL, BROADCAST, ... + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + endmenu diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 52bedf2d7c62..5893bc654ab0 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o +obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c new file mode 100644 index 000000000000..7392ba6bd23f --- /dev/null +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -0,0 +1,77 @@ +/* + * iptables module to match inet_addr_type() of an ip. + * + * Copyright (c) 2004 Patrick McHardy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Patrick McHardy "); +MODULE_DESCRIPTION("iptables addrtype match"); + +static inline int match_type(u_int32_t addr, u_int16_t mask) +{ + return !!(mask & (1 << inet_addr_type(addr))); +} + +static int match(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const void *matchinfo, + int offset, int *hotdrop) +{ + const struct ipt_addrtype_info *info = matchinfo; + const struct iphdr *iph = skb->nh.iph; + int ret = 1; + + if (info->source) + ret &= match_type(iph->saddr, info->source)^info->invert_source; + if (info->dest) + ret &= match_type(iph->daddr, info->dest)^info->invert_dest; + + return ret; +} + +static int checkentry(const char *tablename, const struct ipt_ip *ip, + void *matchinfo, unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) { + printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.", + matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info))); + return 0; + } + + return 1; +} + +static struct ipt_match addrtype_match = { + .name = "addrtype", + .match = match, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&addrtype_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&addrtype_match); +} + +module_init(init); +module_exit(fini); -- cgit v1.2.3 From e07d39a4fe747af843ca8ec76edc5531cc2fa551 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 21 Jun 2004 00:38:44 -0700 Subject: [NETFILTER]: Add realm match Signed-off-by: Patrick McHardy Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ipt_realm.h | 10 +++++ net/ipv4/netfilter/Kconfig | 14 ++++++ net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/ipt_realm.c | 76 ++++++++++++++++++++++++++++++++ net/sched/Kconfig | 4 +- 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 include/linux/netfilter_ipv4/ipt_realm.h create mode 100644 net/ipv4/netfilter/ipt_realm.c (limited to 'include') diff --git a/include/linux/netfilter_ipv4/ipt_realm.h b/include/linux/netfilter_ipv4/ipt_realm.h new file mode 100644 index 000000000000..a4d6698723ac --- /dev/null +++ b/include/linux/netfilter_ipv4/ipt_realm.h @@ -0,0 +1,10 @@ +#ifndef _IPT_REALM_H +#define _IPT_REALM_H + +struct ipt_realm_info { + u_int32_t id; + u_int32_t mask; + u_int8_t invert; +}; + +#endif /* _IPT_REALM_H */ diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 5e9b01f74c30..eaf79408bc03 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -613,5 +613,19 @@ config IP_NF_MATCH_ADDRTYPE If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say `N'. +config IP_NF_MATCH_REALM + tristate 'realm match support' + depends on IP_NF_IPTABLES + select NET_CLS_ROUTE + help + This option adds a `realm' match, which allows you to use the realm + key from the routing subsytem inside iptables. + + This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option + in tc world. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + endmenu diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 5893bc654ab0..bdb23fde133f 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o diff --git a/net/ipv4/netfilter/ipt_realm.c b/net/ipv4/netfilter/ipt_realm.c new file mode 100644 index 000000000000..54a6897ebaa6 --- /dev/null +++ b/net/ipv4/netfilter/ipt_realm.c @@ -0,0 +1,76 @@ +/* IP tables module for matching the routing realm + * + * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ + * + * (C) 2003 by Sampsa Ranta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Sampsa Ranta "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("iptables realm match"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + const struct ipt_realm_info *info = matchinfo; + struct dst_entry *dst = skb->dst; + + return (info->id == (dst->tclassid & info->mask)) ^ info->invert; +} + +static int check(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (hook_mask + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | + (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " + "LOCAL_IN or FORWARD.\n"); + return 0; + } + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { + printk("ipt_realm: invalid matchsize.\n"); + return 0; + } + return 1; +} + +static struct ipt_match realm_match = { + .name = "realm", + .match = match, + .checkentry = check, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&realm_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&realm_match); +} + +module_init(init); +module_exit(fini); diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 8931426e0243..293655830d98 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -242,6 +242,7 @@ config NET_CLS_TCINDEX config NET_CLS_ROUTE4 tristate "Routing table based classifier" depends on NET_CLS + select NET_CLS_ROUTE help If you say Y here, you will be able to classify outgoing packets according to the route table entry they matched. If unsure, say Y. @@ -251,8 +252,7 @@ config NET_CLS_ROUTE4 config NET_CLS_ROUTE bool - depends on NET_CLS_ROUTE4 - default y + default n config NET_CLS_FW tristate "Firewall based classifier" -- cgit v1.2.3 From a47b157e456fecc7bc09dead9ef3e1733ebdfc56 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Jun 2004 07:14:12 -0300 Subject: [NET] generalise tcp_set_owner_r and tcp_rfree Will be used by the poor cousins Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 10 ++++++++++ include/net/tcp.h | 10 ---------- net/core/stream.c | 10 ++++++++++ net/ipv4/tcp.c | 8 -------- net/ipv4/tcp_input.c | 8 ++++---- 5 files changed, 24 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 54a494a657fc..60f8c869b5bd 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -436,6 +436,16 @@ static inline int sk_stream_memory_free(struct sock *sk) return sk->sk_wmem_queued < sk->sk_sndbuf; } +extern void sk_stream_rfree(struct sk_buff *skb); + +static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk) +{ + skb->sk = sk; + skb->destructor = sk_stream_rfree; + atomic_add(skb->truesize, &sk->sk_rmem_alloc); + sk->sk_forward_alloc -= skb->truesize; +} + /* The per-socket spinlock must be held here. */ #define sk_add_backlog(__sk, __skb) \ do { if (!(__sk)->sk_backlog.tail) { \ diff --git a/include/net/tcp.h b/include/net/tcp.h index 3a323cd1e79f..aaef4bf548be 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1955,16 +1955,6 @@ static inline void tcp_writequeue_purge(struct sock *sk) tcp_mem_reclaim(sk); } -extern void tcp_rfree(struct sk_buff *skb); - -static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk) -{ - skb->sk = sk; - skb->destructor = tcp_rfree; - atomic_add(skb->truesize, &sk->sk_rmem_alloc); - sk->sk_forward_alloc -= skb->truesize; -} - extern void tcp_listen_wlock(void); /* - We may sleep inside this lock. diff --git a/net/core/stream.c b/net/core/stream.c index eaeea6843b0a..d5357897830a 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -167,3 +167,13 @@ do_interrupted: } EXPORT_SYMBOL(sk_stream_wait_memory); + +void sk_stream_rfree(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + + atomic_sub(skb->truesize, &sk->sk_rmem_alloc); + sk->sk_forward_alloc += skb->truesize; +} + +EXPORT_SYMBOL(sk_stream_rfree); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ba5cb0beb71d..77525aa5274e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -360,14 +360,6 @@ void __tcp_mem_reclaim(struct sock *sk) } } -void tcp_rfree(struct sk_buff *skb) -{ - struct sock *sk = skb->sk; - - atomic_sub(skb->truesize, &sk->sk_rmem_alloc); - sk->sk_forward_alloc += skb->truesize; -} - /* * LISTEN is a special case for poll.. */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e310b09964fd..d0ad5def4629 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3453,7 +3453,7 @@ queue_and_out: if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) goto drop; } - tcp_set_owner_r(skb, sk); + sk_stream_set_owner_r(skb, sk); __skb_queue_tail(&sk->sk_receive_queue, skb); } tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; @@ -3534,7 +3534,7 @@ drop: SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); - tcp_set_owner_r(skb, sk); + sk_stream_set_owner_r(skb, sk); if (!skb_peek(&tp->out_of_order_queue)) { /* Initial out of order segment, build 1 SACK. */ @@ -3673,7 +3673,7 @@ tcp_collapse(struct sock *sk, struct sk_buff *head, memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start; __skb_insert(nskb, skb->prev, skb, skb->list); - tcp_set_owner_r(nskb, sk); + sk_stream_set_owner_r(nskb, sk); /* Copy data, releasing collapsed skbs. */ while (copy > 0) { @@ -4234,7 +4234,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, /* Bulk data transfer: receiver */ __skb_pull(skb,tcp_header_len); __skb_queue_tail(&sk->sk_receive_queue, skb); - tcp_set_owner_r(skb, sk); + sk_stream_set_owner_r(skb, sk); tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; } -- cgit v1.2.3 From 217a7b206acd141ad300694d5719ea12258d725d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Jun 2004 17:01:24 -0300 Subject: [NET] generalise tcp_error, renaming it to sk_stream_error Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 1 + net/core/stream.c | 11 +++++++++++ net/ipv4/tcp.c | 13 ++----------- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 60f8c869b5bd..c87a90d7ca25 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -473,6 +473,7 @@ do { if (!(__sk)->sk_backlog.tail) { \ extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p); extern void sk_stream_wait_close(struct sock *sk, long timeo_p); +extern int sk_stream_error(struct sock *sk, int flags, int err); extern int sk_wait_data(struct sock *sk, long *timeo); diff --git a/net/core/stream.c b/net/core/stream.c index d5357897830a..d00c8d90565f 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -177,3 +177,14 @@ void sk_stream_rfree(struct sk_buff *skb) } EXPORT_SYMBOL(sk_stream_rfree); + +int sk_stream_error(struct sock *sk, int flags, int err) +{ + if (err == -EPIPE) + err = sock_error(sk) ? : -EPIPE; + if (err == -EPIPE && !(flags & MSG_NOSIGNAL)) + send_sig(SIGPIPE, current, 0); + return err; +} + +EXPORT_SYMBOL(sk_stream_error); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 77525aa5274e..00743ca43f4d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -688,15 +688,6 @@ static inline void tcp_push(struct sock *sk, struct tcp_opt *tp, int flags, } } -static int tcp_error(struct sock *sk, int flags, int err) -{ - if (err == -EPIPE) - err = sock_error(sk) ? : -EPIPE; - if (err == -EPIPE && !(flags & MSG_NOSIGNAL)) - send_sig(SIGPIPE, current, 0); - return err; -} - static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags) { @@ -800,7 +791,7 @@ do_error: if (copied) goto out; out_err: - return tcp_error(sk, flags, err); + return sk_stream_error(sk, flags, err); } ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, @@ -1054,7 +1045,7 @@ do_error: if (copied) goto out; out_err: - err = tcp_error(sk, flags, err); + err = sk_stream_error(sk, flags, err); TCP_CHECK_TIMER(sk); release_sock(sk); return err; -- cgit v1.2.3 From dd87b025bb0e23ca603b5603f9b93c74ac8ceb65 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Jun 2004 18:46:47 -0300 Subject: [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb Will be used by the poor cousins Signed-of-by: Arnaldo Carvalho de Melo --- include/linux/tcp.h | 2 +- include/net/sock.h | 11 +++++++++++ include/net/tcp.h | 10 +--------- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_input.c | 10 ++++------ net/ipv4/tcp_output.c | 4 ++-- 6 files changed, 20 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index f807f0507815..17b7902ff760 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -262,8 +262,8 @@ struct tcp_opt { __u32 frto_highmark; /* snd_nxt when RTO occurred */ __u8 unused_pad; - __u8 queue_shrunk; /* Write queue has been shrunk recently.*/ __u8 defer_accept; /* User waits for some data after accept() */ + /* one byte hole, try to pack */ /* RTT measurement */ __u8 backoff; /* backoff */ diff --git a/include/net/sock.h b/include/net/sock.h index c87a90d7ca25..16011c87f20b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -168,6 +168,7 @@ struct sock_common { * @sk_user_data - RPC layer private data * @sk_owner - module that owns this socket * @sk_write_pending - a write to stream socket waits to start + * @sk_queue_shrunk - write queue has been shrunk recently * @sk_state_change - callback to indicate change in the state of the sock * @sk_data_ready - callback to indicate there is data to be processed * @sk_write_space - callback to indicate there is bf sending space available @@ -250,6 +251,8 @@ struct sock { struct module *sk_owner; int sk_write_pending; void *sk_security; + __u8 sk_queue_shrunk; + /* three bytes hole, try to pack */ void (*sk_state_change)(struct sock *sk); void (*sk_data_ready)(struct sock *sk, int bytes); void (*sk_write_space)(struct sock *sk); @@ -446,6 +449,14 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk) sk->sk_forward_alloc -= skb->truesize; } +static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) +{ + sk->sk_queue_shrunk = 1; + sk->sk_wmem_queued -= skb->truesize; + sk->sk_forward_alloc += skb->truesize; + __kfree_skb(skb); +} + /* The per-socket spinlock must be held here. */ #define sk_add_backlog(__sk, __skb) \ do { if (!(__sk)->sk_backlog.tail) { \ diff --git a/include/net/tcp.h b/include/net/tcp.h index aaef4bf548be..5ce69af04dd4 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1876,14 +1876,6 @@ static __inline__ void tcp_openreq_init(struct open_request *req, #define TCP_MEM_QUANTUM ((int)PAGE_SIZE) -static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb) -{ - tcp_sk(sk)->queue_shrunk = 1; - sk->sk_wmem_queued -= skb->truesize; - sk->sk_forward_alloc += skb->truesize; - __kfree_skb(skb); -} - extern void __tcp_mem_reclaim(struct sock *sk); extern int tcp_mem_schedule(struct sock *sk, int size, int kind); @@ -1951,7 +1943,7 @@ static inline void tcp_writequeue_purge(struct sock *sk) struct sk_buff *skb; while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) - tcp_free_skb(sk, skb); + sk_stream_free_skb(sk, skb); tcp_mem_reclaim(sk); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 00743ca43f4d..71404e1a9e63 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1038,7 +1038,7 @@ do_fault: if (tp->send_head == skb) tp->send_head = NULL; __skb_unlink(skb, skb->list); - tcp_free_skb(sk, skb); + sk_stream_free_skb(sk, skb); } do_error: diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d0ad5def4629..40f31f3b569c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2368,7 +2368,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) tp->fackets_out--; tp->packets_out--; __skb_unlink(skb, skb->list); - tcp_free_skb(sk, skb); + sk_stream_free_skb(sk, skb); } if (acked&FLAG_ACKED) { @@ -3829,7 +3829,7 @@ void tcp_cwnd_application_limited(struct sock *sk) /* When incoming ACK allowed to free some skb from write_queue, - * we remember this event in flag tp->queue_shrunk and wake up socket + * we remember this event in flag sk->sk_queue_shrunk and wake up socket * on the exit from tcp input handler. * * PROBLEM: sndbuf expansion does not work well with largesend. @@ -3857,10 +3857,8 @@ static void tcp_new_space(struct sock *sk) static inline void tcp_check_space(struct sock *sk) { - struct tcp_opt *tp = tcp_sk(sk); - - if (tp->queue_shrunk) { - tp->queue_shrunk = 0; + if (sk->sk_queue_shrunk) { + sk->sk_queue_shrunk = 0; if (sk->sk_socket && test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) tcp_new_space(sk); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ad0c2ac89a1a..20dd3b7e3ec5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -763,7 +763,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m */ if (tp->fackets_out) tp->fackets_out--; - tcp_free_skb(sk, next_skb); + sk_stream_free_skb(sk, next_skb); tp->packets_out--; } } @@ -1104,7 +1104,7 @@ int tcp_send_synack(struct sock *sk) return -ENOMEM; __skb_unlink(skb, &sk->sk_write_queue); __skb_queue_head(&sk->sk_write_queue, nskb); - tcp_free_skb(sk, skb); + sk_stream_free_skb(sk, skb); sk_charge_skb(sk, nskb); skb = nskb; } -- cgit v1.2.3 From 6511d74e8502c38b02bbbdaa38004fa53d2745e8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Jun 2004 19:20:08 -0300 Subject: [NET] generalise tcp_moderate_sndbuf Renaming it to sk_stream_moderate_sndbuf, further patches will move all the tcp memory pressure handling support into net/core/stream.c to make them usable by the poor cousins, starting with LLC. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 8 ++++++++ include/net/tcp.h | 12 ++---------- net/ipv4/tcp.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 16011c87f20b..f34406db9442 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1095,6 +1095,14 @@ static inline void sk_wake_async(struct sock *sk, int how, int band) #define SOCK_MIN_SNDBUF 2048 #define SOCK_MIN_RCVBUF 256 +static inline void sk_stream_moderate_sndbuf(struct sock *sk) +{ + if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { + sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2); + sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF); + } +} + /* * Default write policy as shown to user space via poll/select/SIGIO */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 5ce69af04dd4..904f0cd12da9 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1893,14 +1893,6 @@ static inline void tcp_enter_memory_pressure(void) } } -static inline void tcp_moderate_sndbuf(struct sock *sk) -{ - if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { - sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2); - sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF); - } -} - static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) { struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp); @@ -1915,7 +1907,7 @@ static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, __kfree_skb(skb); } else { tcp_enter_memory_pressure(); - tcp_moderate_sndbuf(sk); + sk_stream_moderate_sndbuf(sk); } return NULL; } @@ -1934,7 +1926,7 @@ static inline struct page * tcp_alloc_page(struct sock *sk) return page; } tcp_enter_memory_pressure(); - tcp_moderate_sndbuf(sk); + sk_stream_moderate_sndbuf(sk); return NULL; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 71404e1a9e63..201713493659 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -333,7 +333,7 @@ int tcp_mem_schedule(struct sock *sk, int size, int kind) suppress_allocation: if (!kind) { - tcp_moderate_sndbuf(sk); + sk_stream_moderate_sndbuf(sk); /* Fail only if socket is _under_ its sndbuf. * In this case we cannot block, so that we have to fail. -- cgit v1.2.3 From a09a83869eeaed66b44bb8e82944efacd9533310 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Jun 2004 21:52:32 -0300 Subject: [NET] move send_head from tcp private area to struct sock The poor cousins also need this, LLC will be the first to use it. Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/tcp.h | 1 - include/net/sock.h | 8 ++++++++ include/net/tcp.h | 17 +++++------------ net/core/sock.c | 2 ++ net/ipv4/tcp.c | 20 ++++++++++---------- net/ipv4/tcp_input.c | 25 ++++++++++++------------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 36 +++++++++++++++++++----------------- net/ipv4/tcp_timer.c | 4 ++-- 9 files changed, 59 insertions(+), 56 deletions(-) (limited to 'include') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 17b7902ff760..d95f58a553b0 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -297,7 +297,6 @@ struct tcp_opt { struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */ - struct sk_buff *send_head; /* Front of stuff to transmit */ __u32 rcv_wnd; /* Current receiver window */ __u32 rcv_wup; /* rcv_nxt on last window update sent */ diff --git a/include/net/sock.h b/include/net/sock.h index f34406db9442..0398823e18ed 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -167,6 +167,7 @@ struct sock_common { * @sk_socket - Identd and reporting IO signals * @sk_user_data - RPC layer private data * @sk_owner - module that owns this socket + * @sk_send_head - front of stuff to transmit * @sk_write_pending - a write to stream socket waits to start * @sk_queue_shrunk - write queue has been shrunk recently * @sk_state_change - callback to indicate change in the state of the sock @@ -248,6 +249,7 @@ struct sock { struct timeval sk_stamp; struct socket *sk_socket; void *sk_user_data; + struct sk_buff *sk_send_head; struct module *sk_owner; int sk_write_pending; void *sk_security; @@ -1103,6 +1105,12 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) } } +#define sk_stream_for_retrans_queue(skb, sk) \ + for (skb = (sk)->sk_write_queue.next; \ + (skb != (sk)->sk_send_head) && \ + (skb != (struct sk_buff *)&(sk)->sk_write_queue); \ + skb = skb->next) + /* * Default write policy as shown to user space via poll/select/SIGIO */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 904f0cd12da9..22a62d58c24d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1186,13 +1186,6 @@ struct tcp_skb_cb { #define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) -#define for_retrans_queue(skb, sk, tp) \ - for (skb = (sk)->sk_write_queue.next; \ - (skb != (tp)->send_head) && \ - (skb != (struct sk_buff *)&(sk)->sk_write_queue); \ - skb=skb->next) - - #include /* This determines how many packets are "in the network" to the best @@ -1400,7 +1393,7 @@ tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int n tcp_minshall_check(tp)))); } -/* This checks if the data bearing packet SKB (usually tp->send_head) +/* This checks if the data bearing packet SKB (usually sk->sk_send_head) * should be put on the wire right now. */ static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb, @@ -1457,7 +1450,7 @@ static __inline__ void __tcp_push_pending_frames(struct sock *sk, unsigned cur_mss, int nonagle) { - struct sk_buff *skb = tp->send_head; + struct sk_buff *skb = sk->sk_send_head; if (skb) { if (!tcp_skb_is_last(sk, skb)) @@ -1477,7 +1470,7 @@ static __inline__ void tcp_push_pending_frames(struct sock *sk, static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp) { - struct sk_buff *skb = tp->send_head; + struct sk_buff *skb = sk->sk_send_head; return (skb && tcp_snd_test(tp, skb, tcp_current_mss(sk, 1), @@ -2023,8 +2016,8 @@ static inline int tcp_use_frto(const struct sock *sk) * unsent new data, and the advertised window should allow * sending it. */ - return (sysctl_tcp_frto && tp->send_head && - !after(TCP_SKB_CB(tp->send_head)->end_seq, + return (sysctl_tcp_frto && sk->sk_send_head && + !after(TCP_SKB_CB(sk->sk_send_head)->end_seq, tp->snd_una + tp->snd_wnd)); } diff --git a/net/core/sock.c b/net/core/sock.c index cc84b85f5b0f..992c2ab34c7a 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1147,6 +1147,8 @@ void sock_init_data(struct socket *sock, struct sock *sk) skb_queue_head_init(&sk->sk_write_queue); skb_queue_head_init(&sk->sk_error_queue); + sk->sk_send_head = NULL; + init_timer(&sk->sk_timer); sk->sk_allocation = GFP_KERNEL; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 201713493659..bc1394f67919 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -659,8 +659,8 @@ static inline void skb_entail(struct sock *sk, struct tcp_opt *tp, TCP_SKB_CB(skb)->sacked = 0; __skb_queue_tail(&sk->sk_write_queue, skb); sk_charge_skb(sk, skb); - if (!tp->send_head) - tp->send_head = skb; + if (!sk->sk_send_head) + sk->sk_send_head = skb; else if (tp->nonagle&TCP_NAGLE_PUSH) tp->nonagle &= ~TCP_NAGLE_PUSH; } @@ -678,7 +678,7 @@ static inline void tcp_mark_urg(struct tcp_opt *tp, int flags, static inline void tcp_push(struct sock *sk, struct tcp_opt *tp, int flags, int mss_now, int nonagle) { - if (tp->send_head) { + if (sk->sk_send_head) { struct sk_buff *skb = sk->sk_write_queue.prev; if (!(flags & MSG_MORE) || forced_push(tp)) tcp_mark_push(tp, skb); @@ -718,7 +718,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse int offset = poffset % PAGE_SIZE; int size = min_t(size_t, psize, PAGE_SIZE - offset); - if (!tp->send_head || (copy = mss_now - skb->len) <= 0) { + if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; @@ -766,7 +766,7 @@ new_segment: if (forced_push(tp)) { tcp_mark_push(tp, skb); __tcp_push_pending_frames(sk, tp, mss_now, TCP_NAGLE_PUSH); - } else if (skb == tp->send_head) + } else if (skb == sk->sk_send_head) tcp_push_one(sk, mss_now); continue; @@ -880,7 +880,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, skb = sk->sk_write_queue.prev; - if (!tp->send_head || + if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { new_segment: @@ -1009,7 +1009,7 @@ new_segment: if (forced_push(tp)) { tcp_mark_push(tp, skb); __tcp_push_pending_frames(sk, tp, mss_now, TCP_NAGLE_PUSH); - } else if (skb == tp->send_head) + } else if (skb == sk->sk_send_head) tcp_push_one(sk, mss_now); continue; @@ -1035,8 +1035,8 @@ out: do_fault: if (!skb->len) { - if (tp->send_head == skb) - tp->send_head = NULL; + if (sk->sk_send_head == skb) + sk->sk_send_head = NULL; __skb_unlink(skb, skb->list); sk_stream_free_skb(sk, skb); } @@ -1907,7 +1907,7 @@ int tcp_disconnect(struct sock *sk, int flags) tcp_set_ca_state(tp, TCP_CA_Open); tcp_clear_retrans(tp); tcp_delack_init(tp); - tp->send_head = NULL; + sk->sk_send_head = NULL; tp->saw_tstamp = 0; tcp_sack_reset(tp); __sk_dst_reset(sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 40f31f3b569c..5ac9ec2ad579 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1001,7 +1001,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (after(end_seq, tp->high_seq)) flag |= FLAG_DATA_LOST; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { u8 sacked = TCP_SKB_CB(skb)->sacked; int in_sack; @@ -1105,7 +1105,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (lost_retrans && tp->ca_state == TCP_CA_Recovery) { struct sk_buff *skb; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { if (after(TCP_SKB_CB(skb)->seq, lost_retrans)) break; if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) @@ -1171,7 +1171,7 @@ void tcp_enter_frto(struct sock *sk) tp->undo_marker = tp->snd_una; tp->undo_retrans = 0; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_RETRANS; } tcp_sync_left_out(tp); @@ -1194,7 +1194,7 @@ static void tcp_enter_frto_loss(struct sock *sk) tp->lost_out = 0; tp->fackets_out = 0; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { cnt++; TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) { @@ -1267,7 +1267,7 @@ void tcp_enter_loss(struct sock *sk, int how) if (!how) tp->undo_marker = tp->snd_una; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { cnt++; if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS) tp->undo_marker = 0; @@ -1510,7 +1510,7 @@ tcp_mark_head_lost(struct sock *sk, struct tcp_opt *tp, int packets, u32 high_se BUG_TRAP(cnt <= tp->packets_out); - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { if (--cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq)) break; if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { @@ -1542,7 +1542,7 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_opt *tp) if (tcp_head_timedout(sk, tp)) { struct sk_buff *skb; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { if (tcp_skb_timedout(tp, skb) && !(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; @@ -1711,7 +1711,7 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp) { if (tcp_may_undo(tp)) { struct sk_buff *skb; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; } DBGUNDO(sk, tp, "partial loss"); @@ -2320,7 +2320,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) int acked = 0; __s32 seq_rtt = -1; - while ((skb = skb_peek(&sk->sk_write_queue)) && skb != tp->send_head) { + while ((skb = skb_peek(&sk->sk_write_queue)) && skb != sk->sk_send_head) { struct tcp_skb_cb *scb = TCP_SKB_CB(skb); __u8 sacked = scb->sacked; @@ -2408,7 +2408,7 @@ static void tcp_ack_probe(struct sock *sk) /* Was it a usable window open? */ - if (!after(TCP_SKB_CB(tp->send_head)->end_seq, + if (!after(TCP_SKB_CB(sk->sk_send_head)->end_seq, tp->snd_una + tp->snd_wnd)) { tp->backoff = 0; tcp_clear_xmit_timer(sk, TCP_TIME_PROBE0); @@ -2849,7 +2849,7 @@ no_queue: * being used to time the probes, and is probably far higher than * it needs to be for normal retransmission. */ - if (tp->send_head) + if (sk->sk_send_head) tcp_ack_probe(sk); return 1; @@ -3877,8 +3877,7 @@ static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) static __inline__ void tcp_data_snd_check(struct sock *sk) { - struct tcp_opt *tp = tcp_sk(sk); - struct sk_buff *skb = tp->send_head; + struct sk_buff *skb = sk->sk_send_head; if (skb != NULL) __tcp_data_snd_check(sk, skb); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 3af98bd3ff3e..dacd76e33133 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -718,6 +718,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, sock_reset_flag(newsk, SOCK_DONE); newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; + newsk->sk_send_head = NULL; newsk->sk_callback_lock = RW_LOCK_UNLOCKED; skb_queue_head_init(&newsk->sk_error_queue); newsk->sk_write_space = sk_stream_write_space; @@ -775,7 +776,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, tcp_set_ca_state(newtp, TCP_CA_Open); tcp_init_xmit_timers(newsk); skb_queue_head_init(&newtp->out_of_order_queue); - newtp->send_head = NULL; newtp->rcv_wup = req->rcv_isn + 1; newtp->write_seq = req->snt_isn + 1; newtp->pushed_seq = newtp->write_seq; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 20dd3b7e3ec5..7d6eca0cd01e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -48,9 +48,9 @@ int sysctl_tcp_retrans_collapse = 1; static __inline__ void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) { - tp->send_head = skb->next; - if (tp->send_head == (struct sk_buff *)&sk->sk_write_queue) - tp->send_head = NULL; + sk->sk_send_head = skb->next; + if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue) + sk->sk_send_head = NULL; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; if (tp->packets_out++ == 0) tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); @@ -329,8 +329,8 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) sk_charge_skb(sk, skb); /* Queue it, remembering where we must start sending. */ - if (tp->send_head == NULL) - tp->send_head = skb; + if (sk->sk_send_head == NULL) + sk->sk_send_head = skb; } /* Send _single_ skb sitting at the send head. This function requires @@ -339,13 +339,13 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) void tcp_push_one(struct sock *sk, unsigned cur_mss) { struct tcp_opt *tp = tcp_sk(sk); - struct sk_buff *skb = tp->send_head; + struct sk_buff *skb = sk->sk_send_head; if (tcp_snd_test(tp, skb, cur_mss, TCP_NAGLE_PUSH)) { /* Send it out now. */ TCP_SKB_CB(skb)->when = tcp_time_stamp; if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) { - tp->send_head = NULL; + sk->sk_send_head = NULL; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; if (tp->packets_out++ == 0) tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); @@ -572,8 +572,10 @@ int tcp_write_xmit(struct sock *sk, int nonagle) */ mss_now = tcp_current_mss(sk, 1); - while((skb = tp->send_head) && - tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb) ? nonagle : TCP_NAGLE_PUSH)) { + while ((skb = sk->sk_send_head) && + tcp_snd_test(tp, skb, mss_now, + tcp_skb_is_last(sk, skb) ? nonagle : + TCP_NAGLE_PUSH)) { if (skb->len > mss_now) { if (tcp_fragment(sk, skb, mss_now)) break; @@ -593,7 +595,7 @@ int tcp_write_xmit(struct sock *sk, int nonagle) return 0; } - return !tp->packets_out && tp->send_head; + return !tp->packets_out && sk->sk_send_head; } return 0; } @@ -779,7 +781,7 @@ void tcp_simple_retransmit(struct sock *sk) unsigned int mss = tcp_current_mss(sk, 0); int lost = 0; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { if (skb->len > mss && !(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) { if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) { @@ -865,7 +867,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) /* Collapse two adjacent packets if worthwhile and we can. */ if(!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) && (skb->len < (cur_mss >> 1)) && - (skb->next != tp->send_head) && + (skb->next != sk->sk_send_head) && (skb->next != (struct sk_buff *)&sk->sk_write_queue) && (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) && (sysctl_tcp_retrans_collapse != 0)) @@ -940,7 +942,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) /* First pass: retransmit lost packets. */ if (packet_cnt) { - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { __u8 sacked = TCP_SKB_CB(skb)->sacked; if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) @@ -988,7 +990,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) packet_cnt = 0; - for_retrans_queue(skb, sk, tp) { + sk_stream_for_retrans_queue(skb, sk) { if(++packet_cnt > tp->fackets_out) break; @@ -1025,7 +1027,7 @@ void tcp_send_fin(struct sock *sk) */ mss_now = tcp_current_mss(sk, 1); - if(tp->send_head != NULL) { + if (sk->sk_send_head != NULL) { TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN; TCP_SKB_CB(skb)->end_seq++; tp->write_seq++; @@ -1404,7 +1406,7 @@ int tcp_write_wakeup(struct sock *sk) struct tcp_opt *tp = tcp_sk(sk); struct sk_buff *skb; - if ((skb = tp->send_head) != NULL && + if ((skb = sk->sk_send_head) != NULL && before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)) { int err; int mss = tcp_current_mss(sk, 0); @@ -1458,7 +1460,7 @@ void tcp_send_probe0(struct sock *sk) err = tcp_write_wakeup(sk); - if (tp->packets_out || !tp->send_head) { + if (tp->packets_out || !sk->sk_send_head) { /* Cancel probe timer, if it is not required. */ tp->probes_out = 0; tp->backoff = 0; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index cab2678b1958..44615198e6a1 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -269,7 +269,7 @@ static void tcp_probe_timer(struct sock *sk) struct tcp_opt *tp = tcp_sk(sk); int max_probes; - if (tp->packets_out || !tp->send_head) { + if (tp->packets_out || !sk->sk_send_head) { tp->probes_out = 0; return; } @@ -606,7 +606,7 @@ static void tcp_keepalive_timer (unsigned long data) elapsed = keepalive_time_when(tp); /* It is alive without keepalive 8) */ - if (tp->packets_out || tp->send_head) + if (tp->packets_out || sk->sk_send_head) goto resched; elapsed = tcp_time_stamp - tp->rcv_tstamp; -- cgit v1.2.3 From 61266d5f8b5b08ff99b767a50cb24d72f96b5a64 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 21 Jun 2004 23:54:22 -0700 Subject: [IPSEC]: In ESP, do not put scatterlist array on stack. Put it in per-esp data instead. Noticed by Linus. Signed-off-by: David S. Miller --- include/net/esp.h | 5 +++++ net/ipv4/esp4.c | 16 ++++++---------- net/ipv6/esp6.c | 16 ++++++---------- 3 files changed, 17 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/net/esp.h b/include/net/esp.h index a513d14522ee..90cd94fad7d9 100644 --- a/include/net/esp.h +++ b/include/net/esp.h @@ -2,9 +2,14 @@ #define _NET_ESP_H #include +#include + +#define ESP_NUM_FAST_SG 4 struct esp_data { + struct scatterlist sgbuf[ESP_NUM_FAST_SG]; + /* Confidentiality */ struct { u8 *key; /* Key */ diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index acecd602a2c8..2cd91612ed63 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -11,8 +11,6 @@ #include #include -#define MAX_SG_ONSTACK 4 - /* decapsulation data for use when post-processing */ struct esp_decap_data { xfrm_address_t saddr; @@ -185,17 +183,16 @@ int esp_output(struct sk_buff **pskb) crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); do { - struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags]; - struct scatterlist *sg = sgbuf; + struct scatterlist *sg = &esp->sgbuf[0]; - if (unlikely(nfrags > MAX_SG_ONSTACK)) { + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); if (!sg) goto error; } skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen); crypto_cipher_encrypt(tfm, sg, sg, clen); - if (unlikely(sg != sgbuf)) + if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); } while (0); @@ -283,19 +280,18 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu { u8 nexthdr[2]; - struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags]; - struct scatterlist *sg = sgbuf; + struct scatterlist *sg = &esp->sgbuf[0]; u8 workbuf[60]; int padlen; - if (unlikely(nfrags > MAX_SG_ONSTACK)) { + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); if (!sg) goto out; } skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); - if (unlikely(sg != sgbuf)) + if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index fb2720697d96..8682cf13402a 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -38,8 +38,6 @@ #include #include -#define MAX_SG_ONSTACK 4 - int esp6_output(struct sk_buff **pskb) { int err; @@ -151,17 +149,16 @@ int esp6_output(struct sk_buff **pskb) crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); do { - struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags]; - struct scatterlist *sg = sgbuf; + struct scatterlist *sg = &esp->sgbuf[0]; - if (unlikely(nfrags > MAX_SG_ONSTACK)) { + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); if (!sg) goto error; } skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen); crypto_cipher_encrypt(tfm, sg, sg, clen); - if (unlikely(sg != sgbuf)) + if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); } while (0); @@ -259,12 +256,11 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b { u8 nexthdr[2]; - struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags]; - struct scatterlist *sg = sgbuf; + struct scatterlist *sg = &esp->sgbuf[0]; u8 padlen; u8 *prevhdr; - if (unlikely(nfrags > MAX_SG_ONSTACK)) { + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); if (!sg) { ret = -ENOMEM; @@ -273,7 +269,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b } skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); - if (unlikely(sg != sgbuf)) + if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) -- cgit v1.2.3 From 23990425b56fd29f4142d309abfc9b33e16e94d7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:57:48 -0700 Subject: [PATCH] PCI: remove duplicate in pci_ids.h Get rid of duplicate entry, one is in the middle of the file with duplicate at the end Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 45d805ddeb9e..31617253cdcb 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2272,6 +2272,3 @@ #define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 #define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 - -#define PCI_VENDOR_ID_HINT 0x3388 -#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 -- cgit v1.2.3 From c911ba686e4496dc7ece5544d683e31db746aef0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:58:27 -0700 Subject: [PATCH] PCI: fix out of order entry in pci_ids.h The last entry in pci_ids.h is out of order, someone wasn't reading the comment to keep it sorted. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 31617253cdcb..80879404d80c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1769,6 +1769,12 @@ #define PCI_DEVICE_ID_CCD_B00C 0xb00c #define PCI_DEVICE_ID_CCD_B100 0xb100 +#define PCI_VENDOR_ID_MICROGATE 0x13c0 +#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 +#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 +#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 +#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 + #define PCI_VENDOR_ID_3WARE 0x13C1 #define PCI_DEVICE_ID_3WARE_1000 0x1000 #define PCI_DEVICE_ID_3WARE_7000 0x1001 @@ -2266,9 +2272,3 @@ #define PCI_DEVICE_ID_ARK_STING 0xa091 #define PCI_DEVICE_ID_ARK_STINGARK 0xa099 #define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 - -#define PCI_VENDOR_ID_MICROGATE 0x13c0 -#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 -#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 -#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 -#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 -- cgit v1.2.3 From b0316bada5735d62b854e471f1b1f501625e086f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:59:02 -0700 Subject: [PATCH] PCI: add id's for sk98 driver Redoing the sk98 driver to correct pci model. These are (most of) the entries it uses. Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 80879404d80c..e03556883a77 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -967,12 +967,14 @@ #define PCI_VENDOR_ID_3COM 0x10b7 #define PCI_DEVICE_ID_3COM_3C985 0x0001 +#define PCI_DEVICE_ID_3COM_3C940 0x1700 #define PCI_DEVICE_ID_3COM_3C339 0x3390 #define PCI_DEVICE_ID_3COM_3C359 0x3590 #define PCI_DEVICE_ID_3COM_3C590 0x5900 #define PCI_DEVICE_ID_3COM_3C595TX 0x5950 #define PCI_DEVICE_ID_3COM_3C595T4 0x5951 #define PCI_DEVICE_ID_3COM_3C595MII 0x5952 +#define PCI_DEVICE_ID_3COM_3C940B 0x80eb #define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 #define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 #define PCI_DEVICE_ID_3COM_3C905TX 0x9050 @@ -1420,6 +1422,9 @@ #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 +#define PCI_VENDOR_ID_DLINK 0x1186 +#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 + #define PCI_VENDOR_ID_ARTOP 0x1191 #define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 #define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 @@ -1735,6 +1740,9 @@ #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 +#define PCI_VENDOR_ID_CNET 0x1371 +#define PCI_DEVICE_ID_CNET_GIGACARD 0x434e + #define PCI_VENDOR_ID_LMC 0x1376 #define PCI_DEVICE_ID_LMC_HSSI 0x0003 #define PCI_DEVICE_ID_LMC_DS3 0x0004 @@ -1919,6 +1927,10 @@ #define PCI_DEVICE_ID_FARSITE_TE1 0x1610 #define PCI_DEVICE_ID_FARSITE_TE1C 0x1612 +#define PCI_VENDOR_ID_LINKSYS 0x1737 +#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 +#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 + #define PCI_VENDOR_ID_ALTIMA 0x173b #define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 #define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9 -- cgit v1.2.3 From c51fd78e40195663177a27690246658a48f4ff06 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 03:04:54 -0700 Subject: [NET]: rtentry->rt_dev is __user. The device entry in the route ioctl's needs annotation. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/route.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/route.h b/include/linux/route.h index e670dbac51ea..f7ed35d5e653 100644 --- a/include/linux/route.h +++ b/include/linux/route.h @@ -24,7 +24,7 @@ #define _LINUX_ROUTE_H #include - +#include /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ struct rtentry @@ -38,7 +38,7 @@ struct rtentry unsigned long rt_pad3; void *rt_pad4; short rt_metric; /* +1 for binary compatibility! */ - char *rt_dev; /* forcing the device at add */ + char __user *rt_dev; /* forcing the device at add */ unsigned long rt_mtu; /* per route MTU/Window */ #ifndef __KERNEL__ #define rt_mss rt_mtu /* Compatibility :-( */ -- cgit v1.2.3 From 296cf45d024d126cd7976a663ff8533648d97184 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 03:06:32 -0700 Subject: [IPV4]: ip_rt_ioctl argument is user pointer. The function ip_rt_ioctl expects a pointer to a user route structure, so define it that way and cast as appropriate. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/route.h | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/fib_frontend.c | 2 +- net/ipv4/ipconfig.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/net/route.h b/include/net/route.h index 0e7210e6d194..a5e9c575ea3e 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -129,7 +129,7 @@ extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned inet_addr_type(u32 addr); extern void ip_rt_multicast_event(struct in_device *); -extern int ip_rt_ioctl(unsigned int cmd, void *arg); +extern int ip_rt_ioctl(unsigned int cmd, void __user *arg); extern void ip_rt_get_source(u8 *src, struct rtable *rt); extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f6c27fc4f05c..caa8632509b5 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -848,7 +848,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCADDRT: case SIOCDELRT: case SIOCRTMSG: - err = ip_rt_ioctl(cmd, (void *)arg); + err = ip_rt_ioctl(cmd, (void __user *)arg); break; case SIOCDARP: case SIOCGARP: diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index fc4e9f8e6bb7..f5b008a9d7d0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -235,7 +235,7 @@ e_inval: * Handle IP routing ioctl calls. These are used to manipulate the routing tables */ -int ip_rt_ioctl(unsigned int cmd, void *arg) +int ip_rt_ioctl(unsigned int cmd, void __user *arg) { int err; struct kern_rta rta; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index a5322adb2be8..19833d69dab8 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -272,7 +272,7 @@ static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg) mm_segment_t oldfs = get_fs(); set_fs(get_ds()); - res = devinet_ioctl(cmd, arg); + res = devinet_ioctl(cmd, (struct ifreq __user *) arg); set_fs(oldfs); return res; } @@ -283,7 +283,7 @@ static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg) mm_segment_t oldfs = get_fs(); set_fs(get_ds()); - res = ip_rt_ioctl(cmd, arg); + res = ip_rt_ioctl(cmd, (void __user *) arg); set_fs(oldfs); return res; } -- cgit v1.2.3 From 694b677ff8b68d1a5b6692795615f6d118e96873 Mon Sep 17 00:00:00 2001 From: Marc Singer Date: Wed, 23 Jun 2004 02:44:18 +0100 Subject: [ARM PATCH] 1913/1: lh7a40x #3 (1/2) serial Patch from Marc Singer Serial console and port driver for the LH7a40x CPUs. The only change made since the last patch was to change the PORT_ID (again). This patch superceeds two serial driver patches. --- drivers/serial/Kconfig | 23 ++ drivers/serial/Makefile | 1 + drivers/serial/serial_lh7a40x.c | 708 ++++++++++++++++++++++++++++++++++++++++ include/linux/serial_core.h | 3 + 4 files changed, 735 insertions(+) create mode 100644 drivers/serial/serial_lh7a40x.c (limited to 'include') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e5ce98eb0378..cb005e5a5bca 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -603,5 +603,28 @@ config SERIAL_PMACZILOG_CONSOLE on your PowerMac as the console, you can do so by answering Y to this option. +config SERIAL_LH7A40X + tristate "Sharp LH7A40X embedded UART support" + depends on ARM && ARCH_LH7A40X + select SERIAL_CORE + help + This enables support for the three on-board UARTs of the + Sharp LH7A40X series CPUs. Choose Y or M. + +config SERIAL_LH7A40X_CONSOLE + bool "Support for connsole on Sharp LH7A40X serial port" + depends on SERIAL_LH7A40X=y + select SERIAL_CORE_CONSOLE + help + Say Y here if you wish to use one of the serial ports as the + system console--the system console is the device which + receives all kernel messages and warnings and which allows + logins in single user mode. + + Even if you say Y here, the currently visible framebuffer console + (/dev/tty0) will still be used as the default system console, but + you can alter that using a kernel command line, for example + "console=ttyAM1". + endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index c2eb159d8b43..ceacc99d8cd1 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_68360) += 68360serial.o obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_V850E_UART) += v850e_uart.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o +obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c new file mode 100644 index 000000000000..d863368e45e2 --- /dev/null +++ b/drivers/serial/serial_lh7a40x.c @@ -0,0 +1,708 @@ +/* drivers/serial/serial_lh7a40x.c + * + * Copyright (C) 2004 Coastal Environmental Systems + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +/* Driver for Sharp LH7A40X embedded serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd. + * + * --- + * + * This driver supports the embedded UARTs of the Sharp LH7A40X series + * CPUs. While similar to the 16550 and other UART chips, there is + * nothing close to register compatibility. Moreover, some of the + * modem control lines are not available, either in the chip or they + * are lacking in the board-level implementation. + * + * - Use of SIRDIS + * For simplicity, we disable the IR functions of any UART whenever + * we enable it. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include + +#include + +#define DEV_MAJOR 204 +#define DEV_MINOR 16 +#define DEV_NR 3 + +#define ISR_LOOP_LIMIT 256 + +#define UR(p,o) _UR ((p)->membase, o) +#define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o)))) +#define BIT_CLR(p,o,m) UR(p,o) = UR(p,o) & (~(unsigned int)m) +#define BIT_SET(p,o,m) UR(p,o) = UR(p,o) | ( (unsigned int)m) + +#define UART_REG_SIZE 32 + +#define UARTEN (0x01) /* UART enable */ +#define SIRDIS (0x02) /* Serial IR disable (UART1 only) */ + +#define RxEmpty (0x10) +#define TxEmpty (0x80) +#define TxFull (0x20) +#define nRxRdy RxEmpty +#define nTxRdy TxFull +#define TxBusy (0x08) + +#define RxBreak (0x0800) +#define RxOverrunError (0x0400) +#define RxParityError (0x0200) +#define RxFramingError (0x0100) +#define RxError (RxBreak | RxOverrunError | RxParityError | RxFramingError) + +#define DCD (0x04) +#define DSR (0x02) +#define CTS (0x01) + +#define RxInt (0x01) +#define TxInt (0x02) +#define ModemInt (0x04) +#define RxTimeoutInt (0x08) + +#define MSEOI (0x10) + +#define WLEN_8 (0x60) +#define WLEN_7 (0x40) +#define WLEN_6 (0x20) +#define WLEN_5 (0x00) +#define WLEN (0x60) /* Mask for all word-length bits */ +#define STP2 (0x08) +#define PEN (0x02) /* Parity Enable */ +#define EPS (0x04) /* Even Parity Set */ +#define FEN (0x10) /* FIFO Enable */ +#define BRK (0x01) /* Send Break */ + + +struct uart_port_lh7a40x { + struct uart_port port; + unsigned int statusPrev; /* Most recently read modem status */ +}; + +static void lh7a40xuart_stop_tx (struct uart_port* port, unsigned int tty_stop) +{ + BIT_CLR (port, UART_R_INTEN, TxInt); +} + +static void lh7a40xuart_start_tx (struct uart_port* port, + unsigned int tty_start) +{ + BIT_SET (port, UART_R_INTEN, TxInt); + + /* *** FIXME: do I need to check for startup of the + transmitter? The old driver did, but AMBA + doesn't . */ +} + +static void lh7a40xuart_stop_rx (struct uart_port* port) +{ + BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); +} + +static void lh7a40xuart_enable_ms (struct uart_port* port) +{ + BIT_SET (port, UART_R_INTEN, ModemInt); +} + +static void +#ifdef SUPPORT_SYSRQ +lh7a40xuart_rx_chars (struct uart_port* port, struct pt_regs* regs) +#else +lh7a40xuart_rx_chars (struct uart_port* port) +#endif +{ + struct tty_struct* tty = port->info->tty; + int cbRxMax = 256; /* (Gross) limit on receive */ + unsigned int data; /* Received data and status */ + + while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.work.func((void*)tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + printk(KERN_WARNING "TTY_DONT_FLIP set\n"); + return; + } + } + + data = UR (port, UART_R_DATA); + + *tty->flip.char_buf_ptr = (unsigned char) data; + *tty->flip.flag_buf_ptr = TTY_NORMAL; + ++port->icount.rx; + + if (data & RxError) { /* Quick check, short-circuit */ + if (data & RxBreak) { + data &= ~(RxFramingError | RxParityError); + ++port->icount.brk; + if (uart_handle_break (port)) + continue; + } + else if (data & RxParityError) + ++port->icount.parity; + else if (data & RxFramingError) + ++port->icount.frame; + if (data & RxOverrunError) + ++port->icount.overrun; + + /* Mask by termios, leave Rx'd byte */ + data &= port->read_status_mask | 0xff; + + if (data & RxBreak) + *tty->flip.flag_buf_ptr = TTY_BREAK; + else if (data & RxParityError) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (data & RxFramingError) + *tty->flip.flag_buf_ptr = TTY_FRAME; + } + + if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) + continue; + + if ((data & port->ignore_status_mask) == 0) { + ++tty->flip.flag_buf_ptr; + ++tty->flip.char_buf_ptr; + ++tty->flip.count; + } + if ((data & RxOverrunError) + && tty->flip.count < TTY_FLIPBUF_SIZE) { + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + *tty->flip.char_buf_ptr++ = 0; + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + ++tty->flip.count; + } + } + tty_flip_buffer_push (tty); + return; +} + +static void lh7a40xuart_tx_chars (struct uart_port* port) +{ + struct circ_buf* xmit = &port->info->xmit; + int cbTxMax = port->fifosize; + + if (port->x_char) { + UR (port, UART_R_DATA) = port->x_char; + ++port->icount.tx; + port->x_char = 0; + return; + } + if (uart_circ_empty (xmit) || uart_tx_stopped (port)) { + lh7a40xuart_stop_tx (port, 0); + return; + } + + /* Unlike the AMBA UART, the lh7a40x UART does not guarantee + that at least half of the FIFO is empty. Instead, we check + status for every character. Using the AMBA method causes + the transmitter to drop characters. */ + + do { + UR (port, UART_R_DATA) = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + ++port->icount.tx; + if (uart_circ_empty(xmit)) + break; + } while (!(UR (port, UART_R_STATUS) & nTxRdy) + && cbTxMax--); + + if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS) + uart_write_wakeup (port); + + if (uart_circ_empty (xmit)) + lh7a40xuart_stop_tx (port, 0); +} + +static void lh7a40xuart_modem_status (struct uart_port* port) +{ + unsigned int status = UR (port, UART_R_STATUS); + unsigned int delta + = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev; + + BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */ + + if (!delta) /* Only happens if we missed 2 transitions */ + return; + + ((struct uart_port_lh7a40x*) port)->statusPrev = status; + + if (delta & DCD) + uart_handle_dcd_change (port, status & DCD); + + if (delta & DSR) + ++port->icount.dsr; + + if (delta & CTS) + uart_handle_cts_change (port, status & CTS); + + wake_up_interruptible (&port->info->delta_msr_wait); +} + +static irqreturn_t lh7a40xuart_int (int irq, void* dev_id, + struct pt_regs* regs) +{ + struct uart_port* port = dev_id; + unsigned int cLoopLimit = ISR_LOOP_LIMIT; + unsigned int isr = UR (port, UART_R_ISR); + + + do { + if (isr & (RxInt | RxTimeoutInt)) +#ifdef SUPPORT_SYSRQ + lh7a40xuart_rx_chars(port, regs); +#else + lh7a40xuart_rx_chars(port); +#endif + if (isr & ModemInt) + lh7a40xuart_modem_status (port); + if (isr & TxInt) + lh7a40xuart_tx_chars (port); + + if (--cLoopLimit == 0) + break; + + isr = UR (port, UART_R_ISR); + } while (isr & (RxInt | TxInt | RxTimeoutInt)); + + return IRQ_HANDLED; +} + +static unsigned int lh7a40xuart_tx_empty (struct uart_port* port) +{ + return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0; +} + +static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port) +{ + unsigned int result = 0; + unsigned int status = UR (port, UART_R_STATUS); + + if (status & DCD) + result |= TIOCM_CAR; + if (status & DSR) + result |= TIOCM_DSR; + if (status & CTS) + result |= TIOCM_CTS; + + return result; +} + +static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl) +{ + /* None of the ports supports DTR. UART1 supports RTS through GPIO. */ + /* Note, kernel appears to be setting DTR and RTS on console. */ + + /* *** FIXME: this deserves more work. There's some work in + tracing all of the IO pins. */ +#if 0 + if( port->mapbase == UART1_PHYS) { + gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS); + + if (mctrl & TIOCM_RTS) + gpio->pbdr &= ~GPIOB_UART1_RTS; + else + gpio->pbdr |= GPIOB_UART1_RTS; + } +#endif +} + +static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state) +{ + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + if (break_state == -1) + BIT_SET (port, UART_R_FCON, BRK); /* Assert break */ + else + BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */ + spin_unlock_irqrestore(&port->lock, flags); +} + +static int lh7a40xuart_startup (struct uart_port* port) +{ + int retval; + + retval = request_irq (port->irq, lh7a40xuart_int, 0, + "serial_lh7a40x", port); + if (retval) + return retval; + + /* Initial modem control-line settings */ + ((struct uart_port_lh7a40x*) port)->statusPrev + = UR (port, UART_R_STATUS); + + /* There is presently no configuration option to enable IR. + Thus, we always disable it. */ + + BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); + BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); + + return 0; +} + +static void lh7a40xuart_shutdown (struct uart_port* port) +{ + free_irq (port->irq, port); + BIT_CLR (port, UART_R_FCON, BRK | FEN); + BIT_CLR (port, UART_R_CON, UARTEN); +} + +static void lh7a40xuart_set_termios (struct uart_port* port, + struct termios* termios, + struct termios* old) +{ + unsigned int con; + unsigned int inten; + unsigned int fcon; + unsigned long flags; + unsigned int baud; + unsigned int quot; + + baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16); + quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */ + + switch (termios->c_cflag & CSIZE) { + case CS5: + fcon = WLEN_5; + break; + case CS6: + fcon = WLEN_6; + break; + case CS7: + fcon = WLEN_7; + break; + case CS8: + default: + fcon = WLEN_8; + break; + } + if (termios->c_cflag & CSTOPB) + fcon |= STP2; + if (termios->c_cflag & PARENB) { + fcon |= PEN; + if (!(termios->c_cflag & PARODD)) + fcon |= EPS; + } + if (port->fifosize > 1) + fcon |= FEN; + + spin_lock_irqsave (&port->lock, flags); + + uart_update_timeout (port, termios->c_cflag, baud); + + port->read_status_mask = RxOverrunError; + if (termios->c_iflag & INPCK) + port->read_status_mask |= RxFramingError | RxParityError; + if (termios->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= RxBreak; + + /* Figure mask for status we ignore */ + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= RxFramingError | RxParityError; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= RxBreak; + /* Ignore overrun when ignorning parity */ + /* *** FIXME: is this in the right place? */ + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= RxOverrunError; + } + + /* Ignore all receive errors when receive disabled */ + if ((termios->c_cflag & CREAD) == 0) + port->ignore_status_mask |= RxError; + + con = UR (port, UART_R_CON); + inten = (UR (port, UART_R_INTEN) & ~ModemInt); + + if (UART_ENABLE_MS (port, termios->c_cflag)) + inten |= ModemInt; + + BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */ + UR (port, UART_R_INTEN) = 0; /* Disable interrupts */ + UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */ + UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */ + UR (port, UART_R_INTEN) = inten; /* Enable interrupts */ + UR (port, UART_R_CON) = con; /* Restore UART mode */ + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char* lh7a40xuart_type (struct uart_port* port) +{ + return port->type == PORT_LH7A40X ? "LH7A40X" : NULL; +} + +static void lh7a40xuart_release_port (struct uart_port* port) +{ + release_mem_region (port->mapbase, UART_REG_SIZE); +} + +static int lh7a40xuart_request_port (struct uart_port* port) +{ + return request_mem_region (port->mapbase, UART_REG_SIZE, + "serial_lh7a40x") != NULL + ? 0 : -EBUSY; +} + +static void lh7a40xuart_config_port (struct uart_port* port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_LH7A40X; + lh7a40xuart_request_port (port); + } +} + +static int lh7a40xuart_verify_port (struct uart_port* port, + struct serial_struct* ser) +{ + int ret = 0; + + if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + ret = -EINVAL; + if (ser->baud_base < 9600) /* *** FIXME: is this true? */ + ret = -EINVAL; + return ret; +} + +static struct uart_ops lh7a40x_uart_ops = { + .tx_empty = lh7a40xuart_tx_empty, + .set_mctrl = lh7a40xuart_set_mctrl, + .get_mctrl = lh7a40xuart_get_mctrl, + .stop_tx = lh7a40xuart_stop_tx, + .start_tx = lh7a40xuart_start_tx, + .stop_rx = lh7a40xuart_stop_rx, + .enable_ms = lh7a40xuart_enable_ms, + .break_ctl = lh7a40xuart_break_ctl, + .startup = lh7a40xuart_startup, + .shutdown = lh7a40xuart_shutdown, + .set_termios = lh7a40xuart_set_termios, + .type = lh7a40xuart_type, + .release_port = lh7a40xuart_release_port, + .request_port = lh7a40xuart_request_port, + .config_port = lh7a40xuart_config_port, + .verify_port = lh7a40xuart_verify_port, +}; + +static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { + { + .port = { + .membase = (void*) io_p2v (UART1_PHYS), + .mapbase = UART1_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART1INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + }, + { + .port = { + .membase = (void*) io_p2v (UART2_PHYS), + .mapbase = UART2_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART2INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + }, + { + .port = { + .membase = (void*) io_p2v (UART3_PHYS), + .mapbase = UART3_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART3INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + }, +}; + +#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE +# define LH7A40X_CONSOLE NULL +#else +# define LH7A40X_CONSOLE &lh7a40x_console + + +static void lh7a40xuart_console_write (struct console* co, + const char* s, + unsigned int count) +{ + struct uart_port* port = &lh7a40x_ports[co->index].port; + unsigned int con = UR (port, UART_R_CON); + unsigned int inten = UR (port, UART_R_INTEN); + + + UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ + BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ + + for (; count-- > 0; ++s) { + while (UR (port, UART_R_STATUS) & nTxRdy) + ; + UR (port, UART_R_DATA) = *s; + if (*s == '\n') { + while ((UR (port, UART_R_STATUS) & TxBusy)) + ; + UR (port, UART_R_DATA) = '\r'; + } + } + + /* Wait until all characters are sent */ + while (UR (port, UART_R_STATUS) & TxBusy) + ; + + /* Restore control and interrupt mask */ + UR (port, UART_R_CON) = con; + UR (port, UART_R_INTEN) = inten; +} + +static void __init lh7a40xuart_console_get_options (struct uart_port* port, + int* baud, + int* parity, + int* bits) +{ + if (UR (port, UART_R_CON) & UARTEN) { + unsigned int fcon = UR (port, UART_R_FCON); + unsigned int quot = UR (port, UART_R_BRCON) + 1; + + switch (fcon & (PEN | EPS)) { + default: *parity = 'n'; break; + case PEN: *parity = 'o'; break; + case PEN | EPS: *parity = 'e'; break; + } + + switch (fcon & WLEN) { + default: + case WLEN_8: *bits = 8; break; + case WLEN_7: *bits = 7; break; + case WLEN_6: *bits = 6; break; + case WLEN_5: *bits = 5; break; + } + + *baud = port->uartclk/(16*quot); + } +} + +static int __init lh7a40xuart_console_setup (struct console* co, char* options) +{ + struct uart_port* port; + int baud = 38400; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index >= DEV_NR) /* Bounds check on device number */ + co->index = 0; + port = &lh7a40x_ports[co->index].port; + + if (options) + uart_parse_options (options, &baud, &parity, &bits, &flow); + else + lh7a40xuart_console_get_options (port, &baud, &parity, &bits); + + return uart_set_options (port, co, baud, parity, bits, flow); +} + +extern struct uart_driver lh7a40x_reg; +static struct console lh7a40x_console = { + .name = "ttyAM", + .write = lh7a40xuart_console_write, + .device = uart_console_device, + .setup = lh7a40xuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &lh7a40x_reg, +}; + +static int __init lh7a40xuart_console_init(void) +{ + register_console (&lh7a40x_console); + return 0; +} + +console_initcall (lh7a40xuart_console_init); + +#endif + +static struct uart_driver lh7a40x_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyAM", + .dev_name = "ttyAM", + .major = DEV_MAJOR, + .minor = DEV_MINOR, + .nr = DEV_NR, + .cons = LH7A40X_CONSOLE, +}; + +static int __init lh7a40xuart_init(void) +{ + int ret; + + printk (KERN_INFO "serial: LH7A40X serial driver\n"); + + ret = uart_register_driver (&lh7a40x_reg); + + if (ret == 0) { + int i; + + for (i = 0; i < DEV_NR; i++) + uart_add_one_port (&lh7a40x_reg, + &lh7a40x_ports[i].port); + } + return ret; +} + +static void __exit lh7a40xuart_exit(void) +{ + int i; + + for (i = 0; i < DEV_NR; i++) + uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port); + + uart_unregister_driver (&lh7a40x_reg); +} + +module_init (lh7a40xuart_init); +module_exit (lh7a40xuart_exit); + +MODULE_AUTHOR ("Marc Singer"); +MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver"); +MODULE_LICENSE ("GPL"); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f79c67d6f281..c653647073f1 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -80,6 +80,9 @@ /* SGI IP22 aka Indy / Challenge S / Indigo 2 */ #define PORT_IP22ZILOG 56 +/* Sharp LH7a40x -- an ARM9 SoC series */ +#define PORT_LH7A40X 57 + #ifdef __KERNEL__ #include -- cgit v1.2.3 From 14881d2b19e687b2788d131ac54e9e7ee338c45c Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 22 Jun 2004 16:55:39 +0100 Subject: [ARM] Move cpu_switch_mm() and cpu_get_pgd() to asm/proc-fns.h --- include/asm-arm/cpu-multi32.h | 17 +---------------- include/asm-arm/cpu-single.h | 21 ++------------------- include/asm-arm/proc-fns.h | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h index 00f936197ad9..ff48022e4720 100644 --- a/include/asm-arm/cpu-multi32.h +++ b/include/asm-arm/cpu-multi32.h @@ -7,9 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef __ASSEMBLY__ - -#include #include struct mm_struct; @@ -64,16 +61,4 @@ extern struct processor { #define cpu_do_idle() processor._do_idle() #define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz) #define cpu_set_pte(ptep, pte) processor.set_pte(ptep, pte) - -#define cpu_switch_mm(pgd,mm) processor.switch_mm(__virt_to_phys((unsigned long)(pgd)),mm) - -#define cpu_get_pgd() \ - ({ \ - unsigned long pg; \ - __asm__("mrc p15, 0, %0, c2, c0, 0" \ - : "=r" (pg) : : "cc"); \ - pg &= ~0x3fff; \ - (pgd_t *)phys_to_virt(pg); \ - }) - -#endif +#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm) diff --git a/include/asm-arm/cpu-single.h b/include/asm-arm/cpu-single.h index cc213ad7167f..b5ec5d54665d 100644 --- a/include/asm-arm/cpu-single.h +++ b/include/asm-arm/cpu-single.h @@ -27,12 +27,9 @@ #define cpu_reset __cpu_fn(CPU_NAME,_reset) #define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle) #define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area) -#define cpu__switch_mm __cpu_fn(CPU_NAME,_switch_mm) +#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm) #define cpu_set_pte __cpu_fn(CPU_NAME,_set_pte) -#ifndef __ASSEMBLY__ - -#include #include struct mm_struct; @@ -42,20 +39,6 @@ extern void cpu_proc_init(void); extern void cpu_proc_fin(void); extern int cpu_do_idle(void); extern void cpu_dcache_clean_area(void *, int); -extern void cpu__switch_mm(unsigned long pgd_phys, struct mm_struct *mm); +extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); extern void cpu_set_pte(pte_t *ptep, pte_t pte); - extern volatile void cpu_reset(unsigned long addr); - -#define cpu_switch_mm(pgd,mm) cpu__switch_mm(__virt_to_phys((unsigned long)(pgd)),mm) - -#define cpu_get_pgd() \ - ({ \ - unsigned long pg; \ - __asm__("mrc p15, 0, %0, c2, c0, 0" \ - : "=r" (pg) : : "cc"); \ - pg &= ~0x3fff; \ - (pgd_t *)phys_to_virt(pg); \ - }) - -#endif diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 9599c6e2f55a..7bef2bf6be51 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -148,11 +148,27 @@ # endif #endif +#ifndef __ASSEMBLY__ + #ifndef MULTI_CPU #include "asm/cpu-single.h" #else #include "asm/cpu-multi32.h" #endif +#include + +#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) + +#define cpu_get_pgd() \ + ({ \ + unsigned long pg; \ + __asm__("mrc p15, 0, %0, c2, c0, 0" \ + : "=r" (pg) : : "cc"); \ + pg &= ~0x3fff; \ + (pgd_t *)phys_to_virt(pg); \ + }) + +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* __ASM_PROCFNS_H */ -- cgit v1.2.3 From 797b051552940428abeeb75820720d47c7640527 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 23 Jun 2004 03:07:38 +0100 Subject: [ARM PATCH] 1940/1: asm-arm/checksum.h - missing include Patch from David Vrabel Missing include (cf. include/asm-i386/checksum.h) in include/asm-arm/checksum.h. --- include/asm-arm/checksum.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h index daa0f4e0abbf..f82f595c75af 100644 --- a/include/asm-arm/checksum.h +++ b/include/asm-arm/checksum.h @@ -9,6 +9,8 @@ #ifndef __ASM_ARM_CHECKSUM_H #define __ASM_ARM_CHECKSUM_H +#include + /* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) -- cgit v1.2.3 From 48c1a5733d9a55cca607a762c65c88096b329bbc Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 22 Jun 2004 12:42:16 -0400 Subject: [libata sata_sil] Re-fix mod15write bug Certain early SATA drives have problems with write requests whose length satisfy the equation "sectors % 15 == 1", on the SiI 3112. Other drives, and other SiI controllers, are not affected. The fix for this problem is to avoid such requests, in one of three ways, for the affect drive+controller combos: 1) Limit all writes to 15 sectors 2) Use block layer features to avoid creating requests whose length satisfies the above equation. 3) When a request satisfies the above equation, split the request into two writes, neither of which satisfies the equation. I chose fix #1, the most simple to implement. After discussion with Silicon Image and others regarding the impact of this fix, I have decided to remain with fix #1, and will not be implementing a "better fix". This means that the affected SATA drives will see decreased performance, but set of affected drives is small and will never grow larger. Further, the complexity of implementing solution #2 or solution #3 is rather large. When implementing lba48 'large request' support, I unintentionally broke the fix for these affected drives. Kudos to Ricky Beam for noticing this. This change restores the fix, by adding a flag ATA_DFLAG_LOCK_SECTORS to indicate that the max_sectors value set by the low-level driver should never be changed. --- drivers/scsi/libata-scsi.c | 3 ++- drivers/scsi/sata_sil.c | 1 + include/linux/libata.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index fed311e81c50..1c24c0eefe0e 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -182,7 +182,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev) * 65534 when Jens Axboe's patch for dynamically * determining max_sectors is merged. */ - if (dev->flags & ATA_DFLAG_LBA48) { + if ((dev->flags & ATA_DFLAG_LBA48) && + ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { sdev->host->max_sectors = 2048; blk_queue_max_sectors(sdev->request_queue, 2048); } diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 49ce4d02c1fd..12043e8f84cb 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -302,6 +302,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) ap->id, dev->devno); ap->host->max_sectors = 15; ap->host->hostt->max_sectors = 15; + dev->flags |= ATA_DFLAG_LOCK_SECTORS; return; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 787f3583729a..a40286d08e23 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -91,6 +91,7 @@ enum { ATA_DFLAG_MASTER = (1 << 2), /* is device 0? */ ATA_DFLAG_WCACHE = (1 << 3), /* has write cache we can * (hopefully) flush? */ + ATA_DFLAG_LOCK_SECTORS = (1 << 4), /* don't adjust max_sectors */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ -- cgit v1.2.3 From b62102f692b387f5d3cd2e6d4b8c4bfecdd08c2d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 22 Jun 2004 05:51:29 -0700 Subject: [PATCH] ppc32: Cleanups & warning fixes of traps.c This cleans up arch/ppc/kernel/traps.c and vecemu.c to use the same formatting style for all functions, and fixes 2 warnings in the altivec floating point emulation code. No functional change. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- arch/ppc/kernel/traps.c | 53 +++++++++++++++------------------------------ arch/ppc/kernel/vecemu.c | 3 +-- include/asm-ppc/processor.h | 2 ++ 3 files changed, 21 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index ebe93fe949b8..d72c35081da2 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -103,8 +103,7 @@ void die(const char * str, struct pt_regs * fp, long err) do_exit(err); } -void -_exception(int signr, struct pt_regs *regs, int code, unsigned long addr) +void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) { siginfo_t info; @@ -200,8 +199,7 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -void -MachineCheckException(struct pt_regs *regs) +void MachineCheckException(struct pt_regs *regs) { unsigned long reason = get_mc_reason(regs); @@ -329,8 +327,7 @@ MachineCheckException(struct pt_regs *regs) die("machine check", regs, SIGBUS); } -void -SMIException(struct pt_regs *regs) +void SMIException(struct pt_regs *regs) { debugger(regs); #if !(defined(CONFIG_XMON) || defined(CONFIG_KGDB)) @@ -339,24 +336,21 @@ SMIException(struct pt_regs *regs) #endif } -void -UnknownException(struct pt_regs *regs) +void UnknownException(struct pt_regs *regs) { printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); _exception(SIGTRAP, regs, 0, 0); } -void -InstructionBreakpoint(struct pt_regs *regs) +void InstructionBreakpoint(struct pt_regs *regs) { if (debugger_iabr_match(regs)) return; _exception(SIGTRAP, regs, TRAP_BRKPT, 0); } -void -RunModeException(struct pt_regs *regs) +void RunModeException(struct pt_regs *regs) { _exception(SIGTRAP, regs, 0, 0); } @@ -374,8 +368,7 @@ RunModeException(struct pt_regs *regs) #define INST_MFSPR_PVR 0x7c1f42a6 #define INST_MFSPR_PVR_MASK 0xfc1fffff -static int -emulate_instruction(struct pt_regs *regs) +static int emulate_instruction(struct pt_regs *regs) { u32 instword; u32 rd; @@ -438,8 +431,7 @@ static struct bug_entry *find_bug(unsigned long bugaddr) return module_find_bug(bugaddr); } -int -check_bug_trap(struct pt_regs *regs) +int check_bug_trap(struct pt_regs *regs) { struct bug_entry *bug; unsigned long addr; @@ -476,8 +468,7 @@ check_bug_trap(struct pt_regs *regs) return 0; } -void -ProgramCheckException(struct pt_regs *regs) +void ProgramCheckException(struct pt_regs *regs) { unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); @@ -550,8 +541,7 @@ ProgramCheckException(struct pt_regs *regs) _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); } -void -SingleStepException(struct pt_regs *regs) +void SingleStepException(struct pt_regs *regs) { regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ if (debugger_sstep(regs)) @@ -559,8 +549,7 @@ SingleStepException(struct pt_regs *regs) _exception(SIGTRAP, regs, TRAP_TRACE, 0); } -void -AlignmentException(struct pt_regs *regs) +void AlignmentException(struct pt_regs *regs) { int fixed; @@ -580,8 +569,7 @@ AlignmentException(struct pt_regs *regs) _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } -void -StackOverflow(struct pt_regs *regs) +void StackOverflow(struct pt_regs *regs) { printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", current, regs->gpr[1]); @@ -598,8 +586,7 @@ void nonrecoverable_exception(struct pt_regs *regs) die("nonrecoverable exception", regs, SIGKILL); } -void -trace_syscall(struct pt_regs *regs) +void trace_syscall(struct pt_regs *regs) { printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], @@ -607,8 +594,7 @@ trace_syscall(struct pt_regs *regs) } #ifdef CONFIG_8xx -void -SoftwareEmulation(struct pt_regs *regs) +void SoftwareEmulation(struct pt_regs *regs) { extern int do_mathemu(struct pt_regs *); extern int Soft_emulate_8xx(struct pt_regs *); @@ -660,8 +646,7 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status) #endif /* CONFIG_4xx || CONFIG_BOOKE */ #if !defined(CONFIG_TAU_INT) -void -TAUException(struct pt_regs *regs) +void TAUException(struct pt_regs *regs) { printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); @@ -683,14 +668,13 @@ void AltivecUnavailException(struct pt_regs *regs) /* The kernel has executed an altivec instruction without first enabling altivec. Whinge but let it do it. */ if (++kernel_altivec_count < 10) - printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%x)\n", + printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", current, regs->nip); regs->msr |= MSR_VEC; } #ifdef CONFIG_ALTIVEC -void -AltivecAssistException(struct pt_regs *regs) +void AltivecAssistException(struct pt_regs *regs) { int err; @@ -734,8 +718,7 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address, #endif /* CONFIG_FSL_BOOKE */ #ifdef CONFIG_SPE -void -SPEFloatingPointException(struct pt_regs *regs) +void SPEFloatingPointException(struct pt_regs *regs) { unsigned long spefscr; int fpexc_mode; diff --git a/arch/ppc/kernel/vecemu.c b/arch/ppc/kernel/vecemu.c index 1430ef59279c..2411a1cbc638 100644 --- a/arch/ppc/kernel/vecemu.c +++ b/arch/ppc/kernel/vecemu.c @@ -256,8 +256,7 @@ static unsigned int rfin(unsigned int x) return (x + half) & ~(0x7fffff >> exp); } -int -emulate_altivec(struct pt_regs *regs) +int emulate_altivec(struct pt_regs *regs) { unsigned int instr, i; unsigned int va, vb, vc, vd; diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index fe7a94383a1d..63fc68e784c5 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -197,6 +197,8 @@ extern inline void prefetchw(const void *x) #define spin_lock_prefetch(x) prefetchw(x) +extern int emulate_altivec(struct pt_regs *regs); + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_PPC_PROCESSOR_H */ -- cgit v1.2.3 From ca216b8acd734682fa53d5c447bb891fa466308d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 22 Jun 2004 05:51:52 -0700 Subject: [PATCH] ppc32: Support for new Apple laptop models This adds support for newer Apple laptop models. It adds the basic identification for the new motherboards and the cpufreq support for models using the new 7447A CPU from Motorola. This is mostly the work of John Steele Scott with some bits from Sebastian Henschel and some rework by myself. Please apply, Signed-off-by: John Steele Scott Signed-off-by: Sebastian Henschel Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- arch/ppc/kernel/misc.S | 18 +++ arch/ppc/platforms/pmac_cpufreq.c | 311 +++++++++++++++++++++++--------------- arch/ppc/platforms/pmac_feature.c | 32 ++++ include/asm-ppc/pmac_feature.h | 6 + include/asm-ppc/reg.h | 1 + include/asm-ppc/uninorth.h | 6 + 6 files changed, 256 insertions(+), 118 deletions(-) (limited to 'include') diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 38cd36d6cbe9..873199e435f6 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -253,6 +253,24 @@ _GLOBAL(low_choose_750fx_pll) mtmsr r7 blr +_GLOBAL(low_choose_7447a_dfs) + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Calc new HID1 value */ + mfspr r4,SPRN_HID1 + insrwi r4,r3,1,9 /* insert parameter into bit 9 */ + sync + mtspr SPRN_HID1,r4 + sync + isync + + /* Return */ + mtmsr r7 + blr + #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */ /* void local_save_flags_ptr(unsigned long *flags) */ diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 2c8cec2723ad..b26c7e158792 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c @@ -1,7 +1,8 @@ /* * arch/ppc/platforms/pmac_cpufreq.c * - * Copyright (C) 2002 - 2003 Benjamin Herrenschmidt + * Copyright (C) 2002 - 2004 Benjamin Herrenschmidt + * Copyright (C) 2004 John Steele Scott * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -47,6 +48,7 @@ #warning "WARNING, CPUFREQ not recommended on SMP kernels" #endif +extern void low_choose_7447a_dfs(int dfs); extern void low_choose_750fx_pll(int pll); extern void low_sleep_handler(void); extern void openpic_suspend(struct sys_device *sysdev, u32 state); @@ -54,18 +56,27 @@ extern void openpic_resume(struct sys_device *sysdev); extern void enable_kernel_altivec(void); extern void enable_kernel_fp(void); +/* + * Currently, PowerMac cpufreq supports only high & low frequencies + * that are set by the firmware + */ static unsigned int low_freq; static unsigned int hi_freq; static unsigned int cur_freq; -/* Clean that up some day ... use a func ptr or at least an enum... */ -static int cpufreq_uses_pmu; -static int cpufreq_uses_gpios; +/* + * Different models uses different mecanisms to switch the frequency + */ +static int (*set_speed_proc)(int low_speed); +/* + * Some definitions used by the various speedprocs + */ static u32 voltage_gpio; static u32 frequency_gpio; static u32 slew_done_gpio; + #define PMAC_CPU_LOW_SPEED 1 #define PMAC_CPU_HIGH_SPEED 0 @@ -123,9 +134,39 @@ static int __pmac cpu_750fx_cpu_speed(int low_speed) return 0; } +/* Switch CPU speed using DFS */ +static int __pmac dfs_set_cpu_speed(int low_speed) +{ + if (low_speed == 0) { + /* ramping up, set voltage first */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/1000); + } else { + /* ramping down, enable aack delay first */ + pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 1, 0); + } + + /* set frequency */ + low_choose_7447a_dfs(low_speed); + + if (low_speed == 1) { + /* ramping down, set voltage last */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/1000); + } else { + /* ramping up, disable aack delay last */ + pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 0, 0); + } + + return 0; +} + + /* Switch CPU speed using slewing GPIOs */ -static int __pmac gpios_set_cpu_speed(unsigned int low_speed) +static int __pmac gpios_set_cpu_speed(int low_speed) { int gpio; @@ -138,7 +179,8 @@ static int __pmac gpios_set_cpu_speed(unsigned int low_speed) } /* Set frequency */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, low_speed ? 0x04 : 0x05); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, + low_speed ? 0x04 : 0x05); udelay(200); do { set_current_state(TASK_UNINTERRUPTIBLE); @@ -163,7 +205,7 @@ static int __pmac gpios_set_cpu_speed(unsigned int low_speed) /* Switch CPU speed under PMU control */ -static int __pmac pmu_set_cpu_speed(unsigned int low_speed) +static int __pmac pmu_set_cpu_speed(int low_speed) { struct adb_request req; unsigned long save_l2cr; @@ -269,12 +311,7 @@ static int __pmac do_set_cpu_speed(int speed_mode) return 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - if (cpufreq_uses_pmu) - rc = pmu_set_cpu_speed(speed_mode); - else if (cpufreq_uses_gpios) - rc = gpios_set_cpu_speed(speed_mode); - else - rc = cpu_750fx_cpu_speed(speed_mode); + set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; @@ -338,20 +375,137 @@ static struct cpufreq_driver pmac_cpufreq_driver = { }; +static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np = of_find_node_by_name(NULL, + "voltage-gpio"); + struct device_node *freq_gpio_np = of_find_node_by_name(NULL, + "frequency-gpio"); + struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, + "slewing-done"); + u32 *value; + + /* + * Check to see if it's GPIO driven or PMU only + * + * The way we extract the GPIO address is slightly hackish, but it + * works well enough for now. We need to abstract the whole GPIO + * stuff sooner or later anyway + */ + + if (volt_gpio_np) + voltage_gpio = read_gpio(volt_gpio_np); + if (freq_gpio_np) + frequency_gpio = read_gpio(freq_gpio_np); + if (slew_done_gpio_np) + slew_done_gpio = read_gpio(slew_done_gpio_np); + + /* If we use the frequency GPIOs, calculate the min/max speeds based + * on the bus frequencies + */ + if (frequency_gpio && slew_done_gpio) { + int lenp, rc; + u32 *freqs, *ratio; + + freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); + lenp /= sizeof(u32); + if (freqs == NULL || lenp != 2) { + printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); + return 1; + } + ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); + if (ratio == NULL) { + printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); + return 1; + } + + /* Get the min/max bus frequencies */ + low_freq = min(freqs[0], freqs[1]); + hi_freq = max(freqs[0], freqs[1]); + + /* Grrrr.. It _seems_ that the device-tree is lying on the low bus + * frequency, it claims it to be around 84Mhz on some models while + * it appears to be approx. 101Mhz on all. Let's hack around here... + * fortunately, we don't need to be too precise + */ + if (low_freq < 98000000) + low_freq = 101000000; + + /* Convert those to CPU core clocks */ + low_freq = (low_freq * (*ratio)) / 2000; + hi_freq = (hi_freq * (*ratio)) / 2000; + + /* Now we get the frequencies, we read the GPIO to see what is out current + * speed + */ + rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); + cur_freq = (rc & 0x01) ? hi_freq : low_freq; + + set_speed_proc = gpios_set_cpu_speed; + return 1; + } + + /* If we use the PMU, look for the min & max frequencies in the + * device-tree + */ + value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); + if (!value) + return 1; + low_freq = (*value) / 1000; + /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree + * here */ + if (low_freq < 100000) + low_freq *= 10; + + value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); + if (!value) + return 1; + hi_freq = (*value) / 1000; + set_speed_proc = pmu_set_cpu_speed; + + return 0; +} + +static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np; + + /* OF only reports the high frequency */ + hi_freq = cur_freq; + low_freq = cur_freq/2; + if (mfspr(HID1) & HID1_DFS) + cur_freq = low_freq; + else + cur_freq = hi_freq; + + volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); + if (!volt_gpio_np){ + printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); + return 1; + } + + u32 *reg = (u32 *)get_property(volt_gpio_np, "reg", NULL); + voltage_gpio = *reg; + set_speed_proc = dfs_set_cpu_speed; + + return 0; +} + /* Currently, we support the following machines: * * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz) * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz) + * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz) * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) * - iBook2 500 (PMU based, 400Mhz & 500Mhz) * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) - * - Recent MacRISC3 machines + * - Recent MacRISC3 laptops + * - iBook G4s and PowerBook G4s with 7447A CPUs */ static int __init pmac_cpufreq_setup(void) { struct device_node *cpunode; u32 *value; - int has_freq_ctl = 0; if (strstr(cmd_line, "nocpufreq")) return 0; @@ -367,113 +521,36 @@ static int __init pmac_cpufreq_setup(void) goto out; cur_freq = (*value) / 1000; - /* Check for newer machines */ - if (machine_is_compatible("PowerBook3,4") || - machine_is_compatible("PowerBook3,5") || - machine_is_compatible("MacRISC3")) { - struct device_node *volt_gpio_np = of_find_node_by_name(NULL, "voltage-gpio"); - struct device_node *freq_gpio_np = of_find_node_by_name(NULL, "frequency-gpio"); - struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, "slewing-done"); - - /* - * Check to see if it's GPIO driven or PMU only - * - * The way we extract the GPIO address is slightly hackish, but it - * works well enough for now. We need to abstract the whole GPIO - * stuff sooner or later anyway - */ - - if (volt_gpio_np) - voltage_gpio = read_gpio(volt_gpio_np); - if (freq_gpio_np) - frequency_gpio = read_gpio(freq_gpio_np); - if (slew_done_gpio_np) - slew_done_gpio = read_gpio(slew_done_gpio_np); - - /* If we use the frequency GPIOs, calculate the min/max speeds based - * on the bus frequencies - */ - if (frequency_gpio && slew_done_gpio) { - int lenp, rc; - u32 *freqs, *ratio; - - freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); - lenp /= sizeof(u32); - if (freqs == NULL || lenp != 2) { - printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); - goto out; - } - ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); - if (ratio == NULL) { - printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); - goto out; - } - - /* Get the min/max bus frequencies */ - low_freq = min(freqs[0], freqs[1]); - hi_freq = max(freqs[0], freqs[1]); - - /* Grrrr.. It _seems_ that the device-tree is lying on the low bus - * frequency, it claims it to be around 84Mhz on some models while - * it appears to be approx. 101Mhz on all. Let's hack around here... - * fortunately, we don't need to be too precise - */ - if (low_freq < 98000000) - low_freq = 101000000; - - /* Convert those to CPU core clocks */ - low_freq = (low_freq * (*ratio)) / 2000; - hi_freq = (hi_freq * (*ratio)) / 2000; - - /* Now we get the frequencies, we read the GPIO to see what is out current - * speed - */ - rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); - cur_freq = (rc & 0x01) ? hi_freq : low_freq; - - has_freq_ctl = 1; - cpufreq_uses_gpios = 1; - goto out; - } - - /* If we use the PMU, look for the min & max frequencies in the - * device-tree - */ - value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); - if (!value) - goto out; - low_freq = (*value) / 1000; - /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree - * here */ - if (low_freq < 100000) - low_freq *= 10; - - value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); - if (!value) - goto out; - hi_freq = (*value) / 1000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; - } + /* Check for 7447A based iBook G4 or PowerBook */ + if (machine_is_compatible("PowerBook6,5") || + machine_is_compatible("PowerBook6,4") || + machine_is_compatible("PowerBook5,5") || + machine_is_compatible("PowerBook5,4")) { + pmac_cpufreq_init_7447A(cpunode); + /* Check for other MacRISC3 machines */ + } else if (machine_is_compatible("PowerBook3,4") || + machine_is_compatible("PowerBook3,5") || + machine_is_compatible("MacRISC3")) { + pmac_cpufreq_init_MacRISC3(cpunode); /* Else check for iBook2 500 */ - else if (machine_is_compatible("PowerBook4,1")) { + } else if (machine_is_compatible("PowerBook4,1")) { /* We only know about 500Mhz model */ if (cur_freq < 450000 || cur_freq > 550000) goto out; hi_freq = cur_freq; low_freq = 400000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; + set_speed_proc = pmu_set_cpu_speed; } - /* Else check for TiPb 500 */ + /* Else check for TiPb 400 & 500 */ else if (machine_is_compatible("PowerBook3,2")) { - /* We only know about 500Mhz model */ - if (cur_freq < 450000 || cur_freq > 550000) + /* We only know about the 400 MHz and the 500Mhz model + * they both have 300 MHz as low frequency + */ + if (cur_freq < 350000 || cur_freq > 550000) goto out; hi_freq = cur_freq; low_freq = 300000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; + set_speed_proc = pmu_set_cpu_speed; } /* Else check for 750FX */ else if (PVR_VER(mfspr(PVR)) == 0x7000) { @@ -483,21 +560,19 @@ static int __init pmac_cpufreq_setup(void) value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); if (!value) goto out; - low_freq = (*value) / 1000; - cpufreq_uses_pmu = 0; - has_freq_ctl = 1; + low_freq = (*value) / 1000; + set_speed_proc = cpu_750fx_cpu_speed; } out: - if (!has_freq_ctl) + if (set_speed_proc == NULL) return -ENODEV; pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq; pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq; printk(KERN_INFO "Registering PowerMac CPU frequency driver\n"); - printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz, switch method: %s\n", - low_freq/1000, hi_freq/1000, cur_freq/1000, - cpufreq_uses_pmu ? "PMU" : (cpufreq_uses_gpios ? "GPIOs" : "CPU")); + printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n", + low_freq/1000, hi_freq/1000, cur_freq/1000); return cpufreq_register_driver(&pmac_cpufreq_driver); } diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c index abd06fc82a34..35714de243b8 100644 --- a/arch/ppc/platforms/pmac_feature.c +++ b/arch/ppc/platforms/pmac_feature.c @@ -1282,6 +1282,25 @@ core99_firewire_cable_power(struct device_node* node, long param, long value) return 0; } +static long __pmac +intrepid_aack_delay_enable(struct device_node* node, long param, long value) +{ + unsigned long flags; + + if (uninorth_rev < 0xd2) + return -ENODEV; + + LOCK(flags); + if (param) + UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + else + UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + UNLOCK(flags); + + return 0; +} + + #endif /* CONFIG_POWER4 */ static long __pmac @@ -1914,6 +1933,7 @@ static struct feature_table_entry intrepid_features[] __pmacdata = { { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, { PMAC_FTR_READ_GPIO, core99_read_gpio }, { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable }, { 0, NULL } }; @@ -2116,6 +2136,14 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, + { "PowerBook5,4", "PowerBook G4 15\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, + { "PowerBook5,5", "PowerBook G4 17\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, { "PowerBook6,1", "PowerBook G4 12\"", PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, @@ -2128,6 +2156,10 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, + { "PowerBook6,4", "PowerBook G4 12\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, { "PowerBook6,5", "iBook G4", PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h index 11065e368382..ee15e9c59aa2 100644 --- a/include/asm-ppc/pmac_feature.h +++ b/include/asm-ppc/pmac_feature.h @@ -273,6 +273,12 @@ static inline long pmac_call_feature(int selector, struct device_node* node, */ #define PMAC_FTR_ENABLE_MPIC PMAC_FTR_DEF(19) +/* PMAC_FTR_AACK_DELAY_ENABLE (NULL, int enable, 0) + * + * Enable/disable the AACK delay on the northbridge for systems using DFS + */ +#define PMAC_FTR_AACK_DELAY_ENABLE PMAC_FTR_DEF(20) + /* Don't use those directly, they are for the sake of pmac_setup.c */ extern long pmac_do_feature_call(unsigned int selector, ...); diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h index f02ec3cf65ec..15c93af4079a 100644 --- a/include/asm-ppc/reg.h +++ b/include/asm-ppc/reg.h @@ -174,6 +174,7 @@ #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ #define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */ +#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */ #define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */ #define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */ #define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */ diff --git a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h index eeff122f365b..2cf025936edf 100644 --- a/include/asm-ppc/uninorth.h +++ b/include/asm-ppc/uninorth.h @@ -142,6 +142,12 @@ */ #define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000 +/* This register controls AACK delay, which is set when 2004 iBook/PowerBook + * is in low speed mode. + */ +#define UNI_N_AACK_DELAY 0x0100 +#define UNI_N_AACK_DELAY_ENABLE 0x00000001 + /* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */ -- cgit v1.2.3 From 7a08473bfee8b94befd7b38333d747290668848a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 22 Jun 2004 05:52:14 -0700 Subject: [PATCH] Handle altivec assist exception properly This is the PPC64 counterpart of the PPC32 Altivec assist exception handler that went in recently. On PPC64 machines with Altivec (i.e. machines that use the PPC970 chip, such as the G5 powermac), the altivec floating-point instructions can operate in two modes: one where denormalized inputs or outputs are truncated to zero, and one where they aren't. In the latter mode the processor can take an exception when it encounters denormalized floating-point inputs or outputs rather than dealing with them in hardware. This patch adds code to deal properly with the exception, by emulating the instruction that caused the exception. Previously the kernel just switched the altivec unit into the truncate-to-zero mode, which works but is a bit gross. Fortunately there are only a limited set of altivec instructions which can generate the assist exception, so we don't have to emulate the whole altivec instruction set. Note that Altivec is Motorola's name for the PowerPC vector/SIMD instructions; IBM calls the same thing VMX, and currently only IBM makes 64-bit PowerPC CPU chips. Nevertheless, I have used the term Altivec in the PPC64 code for consistency with the PPC32 code. Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/Makefile | 2 + arch/ppc64/kernel/traps.c | 34 ++++- arch/ppc64/kernel/vecemu.c | 346 +++++++++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/vector.S | 172 ++++++++++++++++++++++ include/asm-ppc64/system.h | 1 + 5 files changed, 553 insertions(+), 2 deletions(-) create mode 100644 arch/ppc64/kernel/vecemu.c create mode 100644 arch/ppc64/kernel/vector.S (limited to 'include') diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index c36dd89a4e3b..fda27888edd3 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -56,4 +56,6 @@ ifdef CONFIG_SMP obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o endif +obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o + CFLAGS_ioctl32.o += -Ifs/ diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index 593319735e5e..4de4982f58f3 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c @@ -544,9 +544,39 @@ AlignmentException(struct pt_regs *regs) void AltivecAssistException(struct pt_regs *regs) { + int err; + siginfo_t info; + + if (!user_mode(regs)) { + printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" + " at %lx\n", regs->nip); + die("Kernel VMX/Altivec assist exception", regs, SIGILL); + } + flush_altivec_to_thread(current); - /* XXX quick hack for now: set the non-Java bit in the VSCR */ - current->thread.vscr.u[3] |= 0x10000; + + err = emulate_altivec(regs); + if (err == 0) { + regs->nip += 4; /* skip emulated instruction */ + emulate_single_step(regs); + return; + } + + if (err == -EFAULT) { + /* got an error reading the instruction */ + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *) regs->nip; + force_sig_info(SIGSEGV, &info, current); + } else { + /* didn't recognize the instruction */ + /* XXX quick hack for now: set the non-Java bit in the VSCR */ + if (printk_ratelimit()) + printk(KERN_ERR "Unrecognized altivec instruction " + "in %s at %lx\n", current->comm, regs->nip); + current->thread.vscr.u[3] |= 0x10000; + } } #endif /* CONFIG_ALTIVEC */ diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c new file mode 100644 index 000000000000..1430ef59279c --- /dev/null +++ b/arch/ppc64/kernel/vecemu.c @@ -0,0 +1,346 @@ +/* + * Routines to emulate some Altivec/VMX instructions, specifically + * those that can trap when given denormalized operands in Java mode. + */ +#include +#include +#include +#include +#include +#include + +/* Functions in vector.S */ +extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b); +extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b); +extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); +extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); +extern void vrefp(vector128 *dst, vector128 *src); +extern void vrsqrtefp(vector128 *dst, vector128 *src); +extern void vexptep(vector128 *dst, vector128 *src); + +static unsigned int exp2s[8] = { + 0x800000, + 0x8b95c2, + 0x9837f0, + 0xa5fed7, + 0xb504f3, + 0xc5672a, + 0xd744fd, + 0xeac0c7 +}; + +/* + * Computes an estimate of 2^x. The `s' argument is the 32-bit + * single-precision floating-point representation of x. + */ +static unsigned int eexp2(unsigned int s) +{ + int exp, pwr; + unsigned int mant, frac; + + /* extract exponent field from input */ + exp = ((s >> 23) & 0xff) - 127; + if (exp > 7) { + /* check for NaN input */ + if (exp == 128 && (s & 0x7fffff) != 0) + return s | 0x400000; /* return QNaN */ + /* 2^-big = 0, 2^+big = +Inf */ + return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */ + } + if (exp < -23) + return 0x3f800000; /* 1.0 */ + + /* convert to fixed point integer in 9.23 representation */ + pwr = (s & 0x7fffff) | 0x800000; + if (exp > 0) + pwr <<= exp; + else + pwr >>= -exp; + if (s & 0x80000000) + pwr = -pwr; + + /* extract integer part, which becomes exponent part of result */ + exp = (pwr >> 23) + 126; + if (exp >= 254) + return 0x7f800000; + if (exp < -23) + return 0; + + /* table lookup on top 3 bits of fraction to get mantissa */ + mant = exp2s[(pwr >> 20) & 7]; + + /* linear interpolation using remaining 20 bits of fraction */ + asm("mulhwu %0,%1,%2" : "=r" (frac) + : "r" (pwr << 12), "r" (0x172b83ff)); + asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant)); + mant += frac; + + if (exp >= 0) + return mant + (exp << 23); + + /* denormalized result */ + exp = -exp; + mant += 1 << (exp - 1); + return mant >> exp; +} + +/* + * Computes an estimate of log_2(x). The `s' argument is the 32-bit + * single-precision floating-point representation of x. + */ +static unsigned int elog2(unsigned int s) +{ + int exp, mant, lz, frac; + + exp = s & 0x7f800000; + mant = s & 0x7fffff; + if (exp == 0x7f800000) { /* Inf or NaN */ + if (mant != 0) + s |= 0x400000; /* turn NaN into QNaN */ + return s; + } + if ((exp | mant) == 0) /* +0 or -0 */ + return 0xff800000; /* return -Inf */ + + if (exp == 0) { + /* denormalized */ + asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant)); + mant <<= lz - 8; + exp = (-118 - lz) << 23; + } else { + mant |= 0x800000; + exp -= 127 << 23; + } + + if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */ + exp |= 0x400000; /* 0.5 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */ + } + if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */ + exp |= 0x200000; /* 0.25 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */ + } + if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */ + exp |= 0x100000; /* 0.125 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */ + } + if (mant > 0x800000) { /* 1.0 * 2^23 */ + /* calculate (mant - 1) * 1.381097463 */ + /* 1.381097463 == 0.125 / (2^0.125 - 1) */ + asm("mulhwu %0,%1,%2" : "=r" (frac) + : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a)); + exp += frac; + } + s = exp & 0x80000000; + if (exp != 0) { + if (s) + exp = -exp; + asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp)); + lz = 8 - lz; + if (lz > 0) + exp >>= lz; + else if (lz < 0) + exp <<= -lz; + s += ((lz + 126) << 23) + exp; + } + return s; +} + +#define VSCR_SAT 1 + +static int ctsxs(unsigned int x, int scale, unsigned int *vscrp) +{ + int exp, mant; + + exp = (x >> 23) & 0xff; + mant = x & 0x7fffff; + if (exp == 255 && mant != 0) + return 0; /* NaN -> 0 */ + exp = exp - 127 + scale; + if (exp < 0) + return 0; /* round towards zero */ + if (exp >= 31) { + /* saturate, unless the result would be -2^31 */ + if (x + (scale << 23) != 0xcf000000) + *vscrp |= VSCR_SAT; + return (x & 0x80000000)? 0x80000000: 0x7fffffff; + } + mant |= 0x800000; + mant = (mant << 7) >> (30 - exp); + return (x & 0x80000000)? -mant: mant; +} + +static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp) +{ + int exp; + unsigned int mant; + + exp = (x >> 23) & 0xff; + mant = x & 0x7fffff; + if (exp == 255 && mant != 0) + return 0; /* NaN -> 0 */ + exp = exp - 127 + scale; + if (exp < 0) + return 0; /* round towards zero */ + if (x & 0x80000000) { + /* negative => saturate to 0 */ + *vscrp |= VSCR_SAT; + return 0; + } + if (exp >= 32) { + /* saturate */ + *vscrp |= VSCR_SAT; + return 0xffffffff; + } + mant |= 0x800000; + mant = (mant << 8) >> (31 - exp); + return mant; +} + +/* Round to floating integer, towards 0 */ +static unsigned int rfiz(unsigned int x) +{ + int exp; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if (exp < 0) + return x & 0x80000000; /* |x| < 1.0 rounds to 0 */ + return x & ~(0x7fffff >> exp); +} + +/* Round to floating integer, towards +/- Inf */ +static unsigned int rfii(unsigned int x) +{ + int exp, mask; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if ((x & 0x7fffffff) == 0) + return x; /* +/-0 -> +/-0 */ + if (exp < 0) + /* 0 < |x| < 1.0 rounds to +/- 1.0 */ + return (x & 0x80000000) | 0x3f800000; + mask = 0x7fffff >> exp; + /* mantissa overflows into exponent - that's OK, + it can't overflow into the sign bit */ + return (x + mask) & ~mask; +} + +/* Round to floating integer, to nearest */ +static unsigned int rfin(unsigned int x) +{ + int exp, half; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if (exp < -1) + return x & 0x80000000; /* |x| < 0.5 -> +/-0 */ + if (exp == -1) + /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */ + return (x & 0x80000000) | 0x3f800000; + half = 0x400000 >> exp; + /* add 0.5 to the magnitude and chop off the fraction bits */ + return (x + half) & ~(0x7fffff >> exp); +} + +int +emulate_altivec(struct pt_regs *regs) +{ + unsigned int instr, i; + unsigned int va, vb, vc, vd; + vector128 *vrs; + + if (get_user(instr, (unsigned int *) regs->nip)) + return -EFAULT; + if ((instr >> 26) != 4) + return -EINVAL; /* not an altivec instruction */ + vd = (instr >> 21) & 0x1f; + va = (instr >> 16) & 0x1f; + vb = (instr >> 11) & 0x1f; + vc = (instr >> 6) & 0x1f; + + vrs = current->thread.vr; + switch (instr & 0x3f) { + case 10: + switch (vc) { + case 0: /* vaddfp */ + vaddfp(&vrs[vd], &vrs[va], &vrs[vb]); + break; + case 1: /* vsubfp */ + vsubfp(&vrs[vd], &vrs[va], &vrs[vb]); + break; + case 4: /* vrefp */ + vrefp(&vrs[vd], &vrs[vb]); + break; + case 5: /* vrsqrtefp */ + vrsqrtefp(&vrs[vd], &vrs[vb]); + break; + case 6: /* vexptefp */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = eexp2(vrs[vb].u[i]); + break; + case 7: /* vlogefp */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = elog2(vrs[vb].u[i]); + break; + case 8: /* vrfin */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = rfin(vrs[vb].u[i]); + break; + case 9: /* vrfiz */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = rfiz(vrs[vb].u[i]); + break; + case 10: /* vrfip */ + for (i = 0; i < 4; ++i) { + u32 x = vrs[vb].u[i]; + x = (x & 0x80000000)? rfiz(x): rfii(x); + vrs[vd].u[i] = x; + } + break; + case 11: /* vrfim */ + for (i = 0; i < 4; ++i) { + u32 x = vrs[vb].u[i]; + x = (x & 0x80000000)? rfii(x): rfiz(x); + vrs[vd].u[i] = x; + } + break; + case 14: /* vctuxs */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, + ¤t->thread.vscr.u[3]); + break; + case 15: /* vctsxs */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, + ¤t->thread.vscr.u[3]); + break; + default: + return -EINVAL; + } + break; + case 46: /* vmaddfp */ + vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); + break; + case 47: /* vnmsubfp */ + vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); + break; + default: + return -EINVAL; + } + + return 0; +} diff --git a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S new file mode 100644 index 000000000000..940cd7287346 --- /dev/null +++ b/arch/ppc64/kernel/vector.S @@ -0,0 +1,172 @@ +#include +#include + +/* + * The routines below are in assembler so we can closely control the + * usage of floating-point registers. These routines must be called + * with preempt disabled. + */ + .section ".toc","aw" +fpzero: + .tc FD_0_0[TC],0 +fpone: + .tc FD_3ff00000_0[TC],0x3ff0000000000000 /* 1.0 */ +fphalf: + .tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */ + + .text +/* + * Internal routine to enable floating point and set FPSCR to 0. + * Don't call it from C; it doesn't use the normal calling convention. + */ +fpenable: + mfmsr r10 + ori r11,r10,MSR_FP + mtmsr r11 + isync + stfd fr31,-8(r1) + stfd fr0,-16(r1) + stfd fr1,-24(r1) + mffs fr31 + lfd fr1,fpzero@toc(r2) + mtfsf 0xff,fr1 + blr + +fpdisable: + mtlr r12 + mtfsf 0xff,fr31 + lfd fr1,-24(r1) + lfd fr0,-16(r1) + lfd fr31,-8(r1) + mtmsr r10 + isync + blr + +/* + * Vector add, floating point. + */ +_GLOBAL(vaddfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fadds fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector subtract, floating point. + */ +_GLOBAL(vsubfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fsubs fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector multiply and add, floating point. + */ +_GLOBAL(vmaddfp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fmadds fr0,fr0,fr1,fr2 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,-32(r1) + b fpdisable + +/* + * Vector negative multiply and subtract, floating point. + */ +_GLOBAL(vnmsubfp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fnmsubs fr0,fr0,fr1,fr2 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,-32(r1) + b fpdisable + +/* + * Vector reciprocal estimate. We just compute 1.0/x. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrefp) + mflr r12 + bl fpenable + li r0,4 + lfd fr1,fpone@toc(r2) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + fdivs fr0,fr1,fr0 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector reciprocal square-root estimate, floating point. + * We use the frsqrte instruction for the initial estimate followed + * by 2 iterations of Newton-Raphson to get sufficient accuracy. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrsqrtefp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + stfd fr3,-40(r1) + stfd fr4,-48(r1) + stfd fr5,-56(r1) + li r0,4 + lfd fr4,fpone@toc(r2) + lfd fr5,fphalf@toc(r2) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + frsqrte fr1,fr0 /* r = frsqrte(s) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + stfsx fr1,r3,r6 + addi r6,r6,4 + bdnz 1b + lfd fr5,-56(r1) + lfd fr4,-48(r1) + lfd fr3,-40(r1) + lfd fr2,-32(r1) + b fpdisable diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 67ac484a14cd..06ecd1bb285d 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -116,6 +116,7 @@ extern void enable_kernel_fp(void); extern void giveup_altivec(struct task_struct *); extern void disable_kernel_altivec(void); extern void enable_kernel_altivec(void); +extern int emulate_altivec(struct pt_regs *); extern void cvt_fd(float *from, double *to, unsigned long *fpscr); extern void cvt_df(double *from, float *to, unsigned long *fpscr); -- cgit v1.2.3 From 0d072115e0b16d89f9844d0a03ee5a181e4486ae Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 11:51:20 -0300 Subject: [NET] Move sndmsg_page and sndmsg_off to struct sock Yeah, the poor cousins will use this as well :-) --- include/linux/ip.h | 2 -- include/net/sock.h | 6 +++++- net/core/sock.c | 11 +++++++++++ net/ipv4/ip_output.c | 16 ++++++++-------- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_ipv4.c | 4 ---- net/ipv6/ip6_output.c | 16 ++++++++-------- net/ipv6/tcp_ipv6.c | 4 ---- 8 files changed, 34 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/include/linux/ip.h b/include/linux/ip.h index ab799b48b485..12d504ef8df0 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -129,8 +129,6 @@ struct inet_opt { int mc_index; /* Multicast device index */ __u32 mc_addr; struct ip_mc_socklist *mc_list; /* Group array */ - struct page *sndmsg_page; /* Cached page for sendmsg */ - u32 sndmsg_off; /* Cached offset for sendmsg */ /* * Following members are used to retain the infomation to build * an ip header on each ip fragmentation while the socket is corked. diff --git a/include/net/sock.h b/include/net/sock.h index 0398823e18ed..fe293dc84da9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -167,6 +167,8 @@ struct sock_common { * @sk_socket - Identd and reporting IO signals * @sk_user_data - RPC layer private data * @sk_owner - module that owns this socket + * @sk_sndmsg_page - cached page for sendmsg + * @sk_sndmsg_off - cached offset for sendmsg * @sk_send_head - front of stuff to transmit * @sk_write_pending - a write to stream socket waits to start * @sk_queue_shrunk - write queue has been shrunk recently @@ -249,8 +251,10 @@ struct sock { struct timeval sk_stamp; struct socket *sk_socket; void *sk_user_data; - struct sk_buff *sk_send_head; struct module *sk_owner; + struct page *sk_sndmsg_page; + __u32 sk_sndmsg_off; + struct sk_buff *sk_send_head; int sk_write_pending; void *sk_security; __u8 sk_queue_shrunk; diff --git a/net/core/sock.c b/net/core/sock.c index 992c2ab34c7a..089972f623ab 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -650,6 +650,14 @@ void sk_free(struct sock *sk) printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); + /* + * If sendmsg cached page exists, toss it. + */ + if (sk->sk_sndmsg_page) { + __free_page(sk->sk_sndmsg_page); + sk->sk_sndmsg_page = NULL; + } + security_sk_free(sk); kmem_cache_free(sk->sk_slab, sk); module_put(owner); @@ -1175,6 +1183,9 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_error_report = sock_def_error_report; sk->sk_destruct = sock_def_destruct; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; + sk->sk_peercred.pid = 0; sk->sk_peercred.uid = -1; sk->sk_peercred.gid = -1; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 34a4a3feccb7..2e04043e0e2d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -766,8 +766,8 @@ int ip_append_data(struct sock *sk, inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst); inet->cork.rt = rt; inet->cork.length = 0; - inet->sndmsg_page = NULL; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; if ((exthdrlen = rt->u.dst.header_len) != 0) { length += exthdrlen; transhdrlen += exthdrlen; @@ -915,8 +915,8 @@ alloc_new_skb: } else { int i = skb_shinfo(skb)->nr_frags; skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; - struct page *page = inet->sndmsg_page; - int off = inet->sndmsg_off; + struct page *page = sk->sk_sndmsg_page; + int off = sk->sk_sndmsg_off; unsigned int left; if (page && (left = PAGE_SIZE - off) > 0) { @@ -928,7 +928,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, inet->sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if (i < MAX_SKB_FRAGS) { @@ -939,8 +939,8 @@ alloc_new_skb: err = -ENOMEM; goto error; } - inet->sndmsg_page = page; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; skb_fill_page_desc(skb, i, page, 0, 0); frag = &skb_shinfo(skb)->frags[i]; @@ -954,7 +954,7 @@ alloc_new_skb: err = -EFAULT; goto error; } - inet->sndmsg_off += copy; + sk->sk_sndmsg_off += copy; frag->size += copy; skb->len += copy; skb->data_len += copy; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index bc1394f67919..34afc2863953 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -816,8 +816,8 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, return res; } -#define TCP_PAGE(sk) (inet_sk(sk)->sndmsg_page) -#define TCP_OFF(sk) (inet_sk(sk)->sndmsg_off) +#define TCP_PAGE(sk) (sk->sk_sndmsg_page) +#define TCP_OFF(sk) (sk->sk_sndmsg_off) static inline int select_size(struct sock *sk, struct tcp_opt *tp) { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a487ef203e52..956a9c44af40 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2113,10 +2113,6 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - /* If sendmsg cached page exists, toss it. */ - if (inet_sk(sk)->sndmsg_page) - __free_page(inet_sk(sk)->sndmsg_page); - atomic_dec(&tcp_sockets_allocated); return 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b9e7b26c5c29..c0b2003787b1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -854,8 +854,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse np->cork.hop_limit = hlimit; inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst); inet->cork.length = 0; - inet->sndmsg_page = NULL; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0); length += exthdrlen; transhdrlen += exthdrlen; @@ -971,8 +971,8 @@ alloc_new_skb: } else { int i = skb_shinfo(skb)->nr_frags; skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; - struct page *page = inet->sndmsg_page; - int off = inet->sndmsg_off; + struct page *page = sk->sk_sndmsg_page; + int off = sk->sk_sndmsg_off; unsigned int left; if (page && (left = PAGE_SIZE - off) > 0) { @@ -984,7 +984,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, inet->sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if(i < MAX_SKB_FRAGS) { @@ -995,8 +995,8 @@ alloc_new_skb: err = -ENOMEM; goto error; } - inet->sndmsg_page = page; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; skb_fill_page_desc(skb, i, page, 0, 0); frag = &skb_shinfo(skb)->frags[i]; @@ -1010,7 +1010,7 @@ alloc_new_skb: err = -EFAULT; goto error; } - inet->sndmsg_off += copy; + sk->sk_sndmsg_off += copy; frag->size += copy; skb->len += copy; skb->data_len += copy; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c41ddd55f958..ed89f41ddb78 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1911,10 +1911,6 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - /* If sendmsg cached page exists, toss it. */ - if (inet->sndmsg_page != NULL) - __free_page(inet->sndmsg_page); - atomic_dec(&tcp_sockets_allocated); return inet6_destroy_sock(sk); -- cgit v1.2.3 From 8a99b8d40d08d7d3ddb01e6cb5fbe6d94102543d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 13:32:50 -0300 Subject: [NET] rename struct inet_protocol to net_protocol The poor cousins will also have registration routines, etc. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/protocol.h | 11 +++++------ net/ipv4/af_inet.c | 8 ++++---- net/ipv4/ah4.c | 2 +- net/ipv4/esp4.c | 2 +- net/ipv4/icmp.c | 2 +- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_input.c | 2 +- net/ipv4/ipcomp.c | 2 +- net/ipv4/ipmr.c | 4 ++-- net/ipv4/protocol.c | 6 +++--- net/ipv4/xfrm4_tunnel.c | 2 +- net/ipv6/sit.c | 2 +- net/sctp/protocol.c | 2 +- 13 files changed, 23 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/net/protocol.h b/include/net/protocol.h index f67327486a9c..357691f6a45f 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -34,8 +34,7 @@ /* This is used to register protocols. */ -struct inet_protocol -{ +struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int no_policy; @@ -78,15 +77,15 @@ struct inet_protosw { #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ -extern struct inet_protocol *inet_protocol_base; -extern struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +extern struct net_protocol *inet_protocol_base; +extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; #endif -extern int inet_add_protocol(struct inet_protocol *prot, unsigned char num); -extern int inet_del_protocol(struct inet_protocol *prot, unsigned char num); +extern int inet_add_protocol(struct net_protocol *prot, unsigned char num); +extern int inet_del_protocol(struct net_protocol *prot, unsigned char num); extern void inet_register_protosw(struct inet_protosw *p); extern void inet_unregister_protosw(struct inet_protosw *p); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8b14637aa8a2..f6c27fc4f05c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1041,24 +1041,24 @@ void inet_unregister_protosw(struct inet_protosw *p) } #ifdef CONFIG_IP_MULTICAST -static struct inet_protocol igmp_protocol = { +static struct net_protocol igmp_protocol = { .handler = igmp_rcv, }; #endif -static struct inet_protocol tcp_protocol = { +static struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, .no_policy = 1, }; -static struct inet_protocol udp_protocol = { +static struct net_protocol udp_protocol = { .handler = udp_rcv, .err_handler = udp_err, .no_policy = 1, }; -static struct inet_protocol icmp_protocol = { +static struct net_protocol icmp_protocol = { .handler = icmp_rcv, }; diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 0d62398f71a6..e2cee0788c78 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -340,7 +340,7 @@ static struct xfrm_type ah_type = .output = ah_output }; -static struct inet_protocol ah4_protocol = { +static struct net_protocol ah4_protocol = { .handler = xfrm4_rcv, .err_handler = ah4_err, .no_policy = 1, diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 4755e0dcc90d..4e678c4aabf8 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -594,7 +594,7 @@ static struct xfrm_type esp_type = .output = esp_output }; -static struct inet_protocol esp4_protocol = { +static struct net_protocol esp4_protocol = { .handler = xfrm4_rcv, .err_handler = esp4_err, .no_policy = 1, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index f3b54930368c..efcd23dd37b9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -592,7 +592,7 @@ static void icmp_unreach(struct sk_buff *skb) struct iphdr *iph; struct icmphdr *icmph; int hash, protocol; - struct inet_protocol *ipprot; + struct net_protocol *ipprot; struct sock *raw_sk; u32 info = 0; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4a227f51b2c1..4cd7e8b57624 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1240,7 +1240,7 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev) } -static struct inet_protocol ipgre_protocol = { +static struct net_protocol ipgre_protocol = { .handler = ipgre_rcv, .err_handler = ipgre_err, }; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2f71ed5cfcc9..b72ea4961f15 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -223,7 +223,7 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) int protocol = skb->nh.iph->protocol; int hash; struct sock *raw_sk; - struct inet_protocol *ipprot; + struct net_protocol *ipprot; resubmit: hash = protocol & (MAX_INET_PROTOS - 1); diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index e20c7e43b215..9e04df880d3c 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -405,7 +405,7 @@ static struct xfrm_type ipcomp_type = { .output = ipcomp_output }; -static struct inet_protocol ipcomp4_protocol = { +static struct net_protocol ipcomp4_protocol = { .handler = xfrm4_rcv, .err_handler = ipcomp4_err, .no_policy = 1, diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index a25e56077072..b1fdb95e0d00 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -109,7 +109,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm); -static struct inet_protocol pim_protocol; +static struct net_protocol pim_protocol; static struct timer_list ipmr_expire_timer; @@ -1876,7 +1876,7 @@ static struct file_operations ipmr_mfc_fops = { #endif #ifdef CONFIG_IP_PIMSM_V2 -static struct inet_protocol pim_protocol = { +static struct net_protocol pim_protocol = { .handler = pim_rcv, }; #endif diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index a98eb5250d9a..a8b4bdc27ec4 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -48,14 +48,14 @@ #include #include -struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +struct net_protocol *inet_protos[MAX_INET_PROTOS]; static spinlock_t inet_proto_lock = SPIN_LOCK_UNLOCKED; /* * Add a protocol handler to the hash tables */ -int inet_add_protocol(struct inet_protocol *prot, unsigned char protocol) +int inet_add_protocol(struct net_protocol *prot, unsigned char protocol) { int hash, ret; @@ -77,7 +77,7 @@ int inet_add_protocol(struct inet_protocol *prot, unsigned char protocol) * Remove a protocol from the hash tables. */ -int inet_del_protocol(struct inet_protocol *prot, unsigned char protocol) +int inet_del_protocol(struct net_protocol *prot, unsigned char protocol) { int hash, ret; diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 3c9d4aaa21be..5a7ed8e13d63 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -167,7 +167,7 @@ static struct xfrm_type ipip_type = { .output = ipip_output }; -static struct inet_protocol ipip_protocol = { +static struct net_protocol ipip_protocol = { .handler = ipip_rcv, .err_handler = ipip_err, .no_policy = 1, diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2fac873fdd3d..67d0361f51d1 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -800,7 +800,7 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev) return 0; } -static struct inet_protocol sit_protocol = { +static struct net_protocol sit_protocol = { .handler = ipip6_rcv, .err_handler = ipip6_err, }; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index fbc958a75ea4..f2abbf48a7d3 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -875,7 +875,7 @@ static struct inet_protosw sctp_stream_protosw = { }; /* Register with IP layer. */ -static struct inet_protocol sctp_protocol = { +static struct net_protocol sctp_protocol = { .handler = sctp_rcv, .err_handler = sctp_v4_err, .no_policy = 1, -- cgit v1.2.3 From fb5f695cabd362c1c5dc8be38593bb389533e20b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 14:04:46 -0300 Subject: [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc Also remove an unused inet_opt variable from ipv6 code. Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/skbuff.h | 12 +++++++----- net/ipv4/tcp.c | 14 ++------------ net/ipv6/tcp_ipv6.c | 1 - 3 files changed, 9 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cc44268a6e83..2d9ee25fb08f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -664,13 +664,15 @@ static inline int skb_pagelen(const struct sk_buff *skb) return len + skb_headlen(skb); } -static inline void skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size) +static inline void skb_fill_page_desc(struct sk_buff *skb, int i, + struct page *page, int off, int size) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - frag->page = page; - frag->page_offset = off; - frag->size = size; - skb_shinfo(skb)->nr_frags = i+1; + + frag->page = page; + frag->page_offset = off; + frag->size = size; + skb_shinfo(skb)->nr_frags = i + 1; } #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 34afc2863953..e9a5843f6902 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -628,16 +628,6 @@ static void tcp_listen_stop (struct sock *sk) BUG_TRAP(!sk->sk_ack_backlog); } -static inline void fill_page_desc(struct sk_buff *skb, int i, - struct page *page, int off, int size) -{ - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - frag->page = page; - frag->page_offset = off; - frag->size = size; - skb_shinfo(skb)->nr_frags = i + 1; -} - static inline void tcp_mark_push(struct tcp_opt *tp, struct sk_buff *skb) { TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; @@ -740,7 +730,7 @@ new_segment: skb_shinfo(skb)->frags[i - 1].size += copy; } else if (i < MAX_SKB_FRAGS) { get_page(page); - fill_page_desc(skb, i, page, offset, copy); + skb_fill_page_desc(skb, i, page, offset, copy); } else { tcp_mark_push(tp, skb); goto new_segment; @@ -980,7 +970,7 @@ new_segment: skb_shinfo(skb)->frags[i - 1].size += copy; } else { - fill_page_desc(skb, i, page, off, copy); + skb_fill_page_desc(skb, i, page, off, copy); if (TCP_PAGE(sk)) { get_page(page); } else if (off + copy < PAGE_SIZE) { diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ed89f41ddb78..db58adc22c59 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1894,7 +1894,6 @@ static int tcp_v6_init_sock(struct sock *sk) static int tcp_v6_destroy_sock(struct sock *sk) { struct tcp_opt *tp = tcp_sk(sk); - struct inet_opt *inet = inet_sk(sk); tcp_clear_xmit_timers(sk); -- cgit v1.2.3 From 3ac2a2d46ecd8c21f58ed2c67995d6a6c0e65806 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 19:20:40 -0300 Subject: [NET] Generalise tcp memory pressure handling Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 34 +++++++++++- include/net/tcp.h | 32 ++--------- net/core/stream.c | 97 +++++++++++++++++++++++++++++++++ net/ipv4/proc.c | 4 +- net/ipv4/sysctl_net_ipv4.c | 12 ++--- net/ipv4/tcp.c | 131 ++++++--------------------------------------- net/ipv4/tcp_input.c | 34 ++++++------ net/ipv4/tcp_ipv4.c | 45 ++++++++-------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 2 +- net/ipv4/tcp_timer.c | 12 ++--- net/ipv6/tcp_ipv6.c | 8 +-- 12 files changed, 210 insertions(+), 203 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index fe293dc84da9..23f72934b180 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -491,10 +491,11 @@ extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p); extern void sk_stream_wait_close(struct sock *sk, long timeo_p); extern int sk_stream_error(struct sock *sk, int flags, int err); +extern void sk_stream_kill_queues(struct sock *sk); extern int sk_wait_data(struct sock *sk, long *timeo); -/* IP protocol blocks we attach to sockets. +/* Networking protocol blocks we attach to sockets. * socket layer -> transport layer interface * transport -> network interface is defined by struct inet_proto */ @@ -538,6 +539,21 @@ struct proto { void (*unhash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); + /* Memory pressure */ + void (*enter_memory_pressure)(void); + atomic_t memory_allocated; /* Current allocated memory. */ + atomic_t sockets_allocated; /* Current number of sockets. */ + /* + * Pressure flag: try to collapse. + * Technical note: it is used by multiple contexts non atomically. + * All the sk_stream_mem_schedule() is of this nature: accounting + * is strict, actions are advisory and have some latency. + */ + int memory_pressure; + int sysctl_mem[3]; + int sysctl_wmem[3]; + int sysctl_rmem[3]; + char name[32]; struct { @@ -628,6 +644,22 @@ static inline struct inode *SOCK_INODE(struct socket *socket) return &container_of(socket, struct socket_alloc, socket)->vfs_inode; } +extern void __sk_stream_mem_reclaim(struct sock *sk); +extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind); + +#define SK_STREAM_MEM_QUANTUM ((int)PAGE_SIZE) + +static inline int sk_stream_pages(int amt) +{ + return (amt + SK_STREAM_MEM_QUANTUM - 1) / SK_STREAM_MEM_QUANTUM; +} + +static inline void sk_stream_mem_reclaim(struct sock *sk) +{ + if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) + __sk_stream_mem_reclaim(sk); +} + /* Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it * from under us. It essentially blocks any incoming diff --git a/include/net/tcp.h b/include/net/tcp.h index 22a62d58c24d..8e2a7739136a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -594,9 +594,6 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; -extern int sysctl_tcp_mem[3]; -extern int sysctl_tcp_wmem[3]; -extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_tw_reuse; @@ -614,10 +611,6 @@ extern int sysctl_tcp_bic_low_window; extern int sysctl_tcp_default_win_scale; extern int sysctl_tcp_moderate_rcvbuf; -extern atomic_t tcp_memory_allocated; -extern atomic_t tcp_sockets_allocated; -extern int tcp_memory_pressure; - struct open_request; struct or_calltable { @@ -1867,24 +1860,7 @@ static __inline__ void tcp_openreq_init(struct open_request *req, req->rmt_port = skb->h.th->source; } -#define TCP_MEM_QUANTUM ((int)PAGE_SIZE) - -extern void __tcp_mem_reclaim(struct sock *sk); -extern int tcp_mem_schedule(struct sock *sk, int size, int kind); - -static inline void tcp_mem_reclaim(struct sock *sk) -{ - if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM) - __tcp_mem_reclaim(sk); -} - -static inline void tcp_enter_memory_pressure(void) -{ - if (!tcp_memory_pressure) { - NET_INC_STATS(TCPMemoryPressures); - tcp_memory_pressure = 1; - } -} +extern void tcp_enter_memory_pressure(void); static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) { @@ -1893,7 +1869,7 @@ static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, if (skb) { skb->truesize += mem; if (sk->sk_forward_alloc >= (int)skb->truesize || - tcp_mem_schedule(sk, skb->truesize, 0)) { + sk_stream_mem_schedule(sk, skb->truesize, 0)) { skb_reserve(skb, MAX_TCP_HEADER); return skb; } @@ -1913,7 +1889,7 @@ static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) static inline struct page * tcp_alloc_page(struct sock *sk) { if (sk->sk_forward_alloc >= (int)PAGE_SIZE || - tcp_mem_schedule(sk, PAGE_SIZE, 0)) { + sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) { struct page *page = alloc_pages(sk->sk_allocation, 0); if (page) return page; @@ -1929,7 +1905,7 @@ static inline void tcp_writequeue_purge(struct sock *sk) while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_stream_free_skb(sk, skb); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } extern void tcp_listen_wlock(void); diff --git a/net/core/stream.c b/net/core/stream.c index d00c8d90565f..1d9c8b932fa1 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -188,3 +188,100 @@ int sk_stream_error(struct sock *sk, int flags, int err) } EXPORT_SYMBOL(sk_stream_error); + +void __sk_stream_mem_reclaim(struct sock *sk) +{ + if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) { + atomic_sub(sk->sk_forward_alloc / SK_STREAM_MEM_QUANTUM, + &sk->sk_prot->memory_allocated); + sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1; + if (sk->sk_prot->memory_pressure && + (atomic_read(&sk->sk_prot->memory_allocated) < + sk->sk_prot->sysctl_mem[0])) + sk->sk_prot->memory_pressure = 0; + } +} + +EXPORT_SYMBOL(__sk_stream_mem_reclaim); + +int sk_stream_mem_schedule(struct sock *sk, int size, int kind) +{ + int amt = sk_stream_pages(size); + + sk->sk_forward_alloc += amt * SK_STREAM_MEM_QUANTUM; + atomic_add(amt, &sk->sk_prot->memory_allocated); + + /* Under limit. */ + if (atomic_read(&sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { + if (sk->sk_prot->memory_pressure) + sk->sk_prot->memory_pressure = 0; + return 1; + } + + /* Over hard limit. */ + if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { + sk->sk_prot->enter_memory_pressure(); + goto suppress_allocation; + } + + /* Under pressure. */ + if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) + sk->sk_prot->enter_memory_pressure(); + + if (kind) { + if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_prot->sysctl_rmem[0]) + return 1; + } else if (sk->sk_wmem_queued < sk->sk_prot->sysctl_wmem[0]) + return 1; + + if (!sk->sk_prot->memory_pressure || + sk->sk_prot->sysctl_mem[2] > atomic_read(&sk->sk_prot->sockets_allocated) * + sk_stream_pages(sk->sk_wmem_queued + + atomic_read(&sk->sk_rmem_alloc) + + sk->sk_forward_alloc)) + return 1; + +suppress_allocation: + + if (!kind) { + sk_stream_moderate_sndbuf(sk); + + /* Fail only if socket is _under_ its sndbuf. + * In this case we cannot block, so that we have to fail. + */ + if (sk->sk_wmem_queued + size >= sk->sk_sndbuf) + return 1; + } + + /* Alas. Undo changes. */ + sk->sk_forward_alloc -= amt * SK_STREAM_MEM_QUANTUM; + atomic_sub(amt, &sk->sk_prot->memory_allocated); + return 0; +} + +EXPORT_SYMBOL(sk_stream_mem_schedule); + +void sk_stream_kill_queues(struct sock *sk) +{ + /* First the read buffer. */ + __skb_queue_purge(&sk->sk_receive_queue); + + /* Next, the error queue. */ + __skb_queue_purge(&sk->sk_error_queue); + + /* Next, the write queue. */ + BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); + + /* Account for returned memory. */ + sk_stream_mem_reclaim(sk); + + BUG_TRAP(!sk->sk_wmem_queued); + BUG_TRAP(!sk->sk_forward_alloc); + + /* It is _impossible_ for the backlog to contain anything + * when we get here. All user references to this socket + * have gone away, only the net layer knows can touch it. + */ +} + +EXPORT_SYMBOL(sk_stream_kill_queues); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index be47cbec57be..35164af84e34 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -65,8 +65,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) socket_seq_show(seq); seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count), - tcp_tw_count, atomic_read(&tcp_sockets_allocated), - atomic_read(&tcp_memory_allocated)); + tcp_tw_count, atomic_read(&tcp_prot.sockets_allocated), + atomic_read(&tcp_prot.memory_allocated)); seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues, diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 6b0b74430e28..81c31a3b10b3 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -508,24 +508,24 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_TCP_MEM, .procname = "tcp_mem", - .data = &sysctl_tcp_mem, - .maxlen = sizeof(sysctl_tcp_mem), + .data = &tcp_prot.sysctl_mem, + .maxlen = sizeof(tcp_prot.sysctl_mem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_WMEM, .procname = "tcp_wmem", - .data = &sysctl_tcp_wmem, - .maxlen = sizeof(sysctl_tcp_wmem), + .data = &tcp_prot.sysctl_wmem, + .maxlen = sizeof(tcp_prot.sysctl_wmem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_RMEM, .procname = "tcp_rmem", - .data = &sysctl_tcp_rmem, - .maxlen = sizeof(sysctl_tcp_rmem), + .data = &tcp_prot.sysctl_rmem, + .maxlen = sizeof(tcp_prot.sysctl_rmem), .mode = 0644, .proc_handler = &proc_dointvec }, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e9a5843f6902..dffead725c64 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -278,85 +278,11 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); int sysctl_tcp_default_win_scale; -int sysctl_tcp_mem[3]; -int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; -int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; - -atomic_t tcp_memory_allocated; /* Current allocated memory. */ -atomic_t tcp_sockets_allocated; /* Current number of TCP sockets. */ - -/* Pressure flag: try to collapse. - * Technical note: it is used by multiple contexts non atomically. - * All the tcp_mem_schedule() is of this nature: accounting - * is strict, actions are advisory and have some latency. */ -int tcp_memory_pressure; - -#define TCP_PAGES(amt) (((amt) + TCP_MEM_QUANTUM - 1) / TCP_MEM_QUANTUM) - -int tcp_mem_schedule(struct sock *sk, int size, int kind) -{ - int amt = TCP_PAGES(size); - - sk->sk_forward_alloc += amt * TCP_MEM_QUANTUM; - atomic_add(amt, &tcp_memory_allocated); - - /* Under limit. */ - if (atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { - if (tcp_memory_pressure) - tcp_memory_pressure = 0; - return 1; - } - - /* Over hard limit. */ - if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) { - tcp_enter_memory_pressure(); - goto suppress_allocation; - } - - /* Under pressure. */ - if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[1]) - tcp_enter_memory_pressure(); - - if (kind) { - if (atomic_read(&sk->sk_rmem_alloc) < sysctl_tcp_rmem[0]) - return 1; - } else if (sk->sk_wmem_queued < sysctl_tcp_wmem[0]) - return 1; - - if (!tcp_memory_pressure || - sysctl_tcp_mem[2] > atomic_read(&tcp_sockets_allocated) * - TCP_PAGES(sk->sk_wmem_queued + - atomic_read(&sk->sk_rmem_alloc) + - sk->sk_forward_alloc)) - return 1; - -suppress_allocation: - - if (!kind) { - sk_stream_moderate_sndbuf(sk); - - /* Fail only if socket is _under_ its sndbuf. - * In this case we cannot block, so that we have to fail. - */ - if (sk->sk_wmem_queued + size >= sk->sk_sndbuf) - return 1; - } - - /* Alas. Undo changes. */ - sk->sk_forward_alloc -= amt * TCP_MEM_QUANTUM; - atomic_sub(amt, &tcp_memory_allocated); - return 0; -} - -void __tcp_mem_reclaim(struct sock *sk) +void tcp_enter_memory_pressure(void) { - if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM) { - atomic_sub(sk->sk_forward_alloc / TCP_MEM_QUANTUM, - &tcp_memory_allocated); - sk->sk_forward_alloc &= TCP_MEM_QUANTUM - 1; - if (tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) - tcp_memory_pressure = 0; + if (!tcp_prot.memory_pressure) { + NET_INC_STATS(TCPMemoryPressures); + tcp_prot.memory_pressure = 1; } } @@ -1624,29 +1550,6 @@ void tcp_shutdown(struct sock *sk, int how) } } -static __inline__ void tcp_kill_sk_queues(struct sock *sk) -{ - /* First the read buffer. */ - __skb_queue_purge(&sk->sk_receive_queue); - - /* Next, the error queue. */ - __skb_queue_purge(&sk->sk_error_queue); - - /* Next, the write queue. */ - BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); - - /* Account for returned memory. */ - tcp_mem_reclaim(sk); - - BUG_TRAP(!sk->sk_wmem_queued); - BUG_TRAP(!sk->sk_forward_alloc); - - /* It is _impossible_ for the backlog to contain anything - * when we get here. All user references to this socket - * have gone away, only the net layer knows can touch it. - */ -} - /* * At this point, there should be no process reference to this * socket, and thus no user references at all. Therefore we @@ -1674,7 +1577,7 @@ void tcp_destroy_sock(struct sock *sk) sk->sk_prot->destroy(sk); - tcp_kill_sk_queues(sk); + sk_stream_kill_queues(sk); xfrm_sk_free_policy(sk); @@ -1717,7 +1620,7 @@ void tcp_close(struct sock *sk, long timeout) __kfree_skb(skb); } - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); /* As outlined in draft-ietf-tcpimpl-prob-03.txt, section * 3.10, we send a RST here because data was lost. To @@ -1816,10 +1719,10 @@ adjudge_to_death: } } if (sk->sk_state != TCP_CLOSE) { - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "TCP: too many of orphaned " "sockets\n"); @@ -2366,15 +2269,15 @@ void __init tcp_init(void) } tcp_port_rover = sysctl_local_port_range[0] - 1; - sysctl_tcp_mem[0] = 768 << order; - sysctl_tcp_mem[1] = 1024 << order; - sysctl_tcp_mem[2] = 1536 << order; + tcp_prot.sysctl_mem[0] = 768 << order; + tcp_prot.sysctl_mem[1] = 1024 << order; + tcp_prot.sysctl_mem[2] = 1536 << order; if (order < 3) { - sysctl_tcp_wmem[2] = 64 * 1024; - sysctl_tcp_rmem[0] = PAGE_SIZE; - sysctl_tcp_rmem[1] = 43689; - sysctl_tcp_rmem[2] = 2 * 43689; + tcp_prot.sysctl_wmem[2] = 64 * 1024; + tcp_prot.sysctl_rmem[0] = PAGE_SIZE; + tcp_prot.sysctl_rmem[1] = 43689; + tcp_prot.sysctl_rmem[2] = 2 * 43689; } printk(KERN_INFO "TCP: Hash tables configured " @@ -2384,9 +2287,6 @@ void __init tcp_init(void) tcpdiag_init(); } -EXPORT_SYMBOL(__tcp_mem_reclaim); -EXPORT_SYMBOL(sysctl_tcp_rmem); -EXPORT_SYMBOL(sysctl_tcp_wmem); EXPORT_SYMBOL(tcp_accept); EXPORT_SYMBOL(tcp_close); EXPORT_SYMBOL(tcp_close_state); @@ -2402,6 +2302,5 @@ EXPORT_SYMBOL(tcp_sendmsg); EXPORT_SYMBOL(tcp_sendpage); EXPORT_SYMBOL(tcp_setsockopt); EXPORT_SYMBOL(tcp_shutdown); -EXPORT_SYMBOL(tcp_sockets_allocated); EXPORT_SYMBOL(tcp_statistics); EXPORT_SYMBOL(tcp_timewait_cachep); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5ac9ec2ad579..eb20c5d98163 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -207,7 +207,7 @@ static void tcp_fixup_sndbuf(struct sock *sk) sizeof(struct sk_buff); if (sk->sk_sndbuf < 3 * sndmem) - sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); + sk->sk_sndbuf = min(3 * sndmem, tcp_prot.sysctl_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -259,7 +259,7 @@ tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) /* Check #1 */ if (tp->rcv_ssthresh < tp->window_clamp && (int)tp->rcv_ssthresh < tcp_space(sk) && - !tcp_memory_pressure) { + !tcp_prot.memory_pressure) { int incr; /* Check #2. Increase window, if skb with such overhead @@ -291,7 +291,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) while (tcp_win_from_space(rcvmem) < tp->advmss) rcvmem += 128; if (sk->sk_rcvbuf < 4 * rcvmem) - sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]); + sk->sk_rcvbuf = min(4 * rcvmem, tcp_prot.sysctl_rmem[2]); } /* 4. Try to fixup all. It is made iimediately after connection enters @@ -347,12 +347,12 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) * do not clamp window. Try to expand rcvbuf instead. */ if (ofo_win) { - if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && + if (sk->sk_rcvbuf < tcp_prot.sysctl_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) + !tcp_prot.memory_pressure && + atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), - sysctl_tcp_rmem[2]); + tcp_prot.sysctl_rmem[2]); } if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { app_win += ofo_win; @@ -473,7 +473,7 @@ void tcp_rcv_space_adjust(struct sock *sk) rcvmem = (tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff)); space *= rcvmem; - space = min(space, sysctl_tcp_rmem[2]); + space = min(space, tcp_prot.sysctl_rmem[2]); if (space > sk->sk_rcvbuf) sk->sk_rcvbuf = space; } @@ -527,7 +527,7 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_b * restart window, so that we send ACKs quickly. */ tcp_incr_quickack(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } } tp->ack.lrcvtime = now; @@ -3158,7 +3158,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) __skb_queue_purge(&tp->out_of_order_queue); if (tp->sack_ok) tcp_sack_reset(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); @@ -3393,7 +3393,7 @@ static void tcp_ofo_queue(struct sock *sk) static inline int tcp_rmem_schedule(struct sock *sk, struct sk_buff *skb) { return (int)skb->truesize <= sk->sk_forward_alloc || - tcp_mem_schedule(sk, skb->truesize, 1); + sk_stream_mem_schedule(sk, skb->truesize, 1); } static int tcp_prune_queue(struct sock *sk); @@ -3760,14 +3760,14 @@ static int tcp_prune_queue(struct sock *sk) if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) tcp_clamp_window(sk, tp); - else if (tcp_memory_pressure) + else if (tcp_prot.memory_pressure) tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); tcp_collapse_ofo_queue(sk); tcp_collapse(sk, sk->sk_receive_queue.next, (struct sk_buff*)&sk->sk_receive_queue, tp->copied_seq, tp->rcv_nxt); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) return 0; @@ -3788,7 +3788,7 @@ static int tcp_prune_queue(struct sock *sk) */ if (tp->sack_ok) tcp_sack_reset(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) @@ -3840,15 +3840,15 @@ static void tcp_new_space(struct sock *sk) if (tp->packets_out < tp->snd_cwnd && !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + !tcp_prot.memory_pressure && + atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) { int sndmem = max_t(u32, tp->mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); sndmem *= 2*demanded; if (sndmem > sk->sk_sndbuf) - sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); + sk->sk_sndbuf = min(sndmem, tcp_prot.sysctl_wmem[2]); tp->snd_cwnd_stamp = tcp_time_stamp; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 956a9c44af40..828920f7b552 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2086,10 +2086,10 @@ static int tcp_v4_init_sock(struct sock *sk) tp->af_specific = &ipv4_specific; - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; + sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; + sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); return 0; } @@ -2113,7 +2113,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_sockets_allocated); + atomic_dec(&tcp_prot.sockets_allocated); return 0; } @@ -2582,23 +2582,26 @@ void tcp4_proc_exit(void) #endif /* CONFIG_PROC_FS */ struct proto tcp_prot = { - .name = "TCP", - .close = tcp_close, - .connect = tcp_v4_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v4_init_sock, - .destroy = tcp_v4_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v4_do_rcv, - .hash = tcp_v4_hash, - .unhash = tcp_unhash, - .get_port = tcp_v4_get_port, + .name = "TCP", + .close = tcp_close, + .connect = tcp_v4_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v4_init_sock, + .destroy = tcp_v4_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v4_do_rcv, + .hash = tcp_v4_hash, + .unhash = tcp_unhash, + .get_port = tcp_v4_get_port, + .enter_memory_pressure = tcp_enter_memory_pressure, + .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, + .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, }; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index dacd76e33133..4f36e164eb07 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -801,7 +801,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); #endif - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); if (sock_flag(newsk, SOCK_KEEPOPEN)) tcp_reset_keepalive_timer(newsk, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7d6eca0cd01e..e78461bdbf3b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -672,7 +672,7 @@ u32 __tcp_select_window(struct sock *sk) if (free_space < full_space/2) { tp->ack.quick = 0; - if (tcp_memory_pressure) + if (tcp_prot.memory_pressure) tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); if (free_space < mss) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 44615198e6a1..876f9f410277 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -113,7 +113,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) if (orphans >= sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "Out of socket memory\n"); @@ -217,7 +217,7 @@ static void tcp_delack_timer(unsigned long data) goto out_unlock; } - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (sk->sk_state == TCP_CLOSE || !(tp->ack.pending & TCP_ACK_TIMER)) goto out; @@ -257,8 +257,8 @@ static void tcp_delack_timer(unsigned long data) TCP_CHECK_TIMER(sk); out: - if (tcp_memory_pressure) - tcp_mem_reclaim(sk); + if (tcp_prot.memory_pressure) + sk_stream_mem_reclaim(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); @@ -448,7 +448,7 @@ static void tcp_write_timer(unsigned long data) TCP_CHECK_TIMER(sk); out: - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); @@ -633,7 +633,7 @@ static void tcp_keepalive_timer (unsigned long data) } TCP_CHECK_TIMER(sk); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); resched: tcp_reset_keepalive_timer (sk, elapsed); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index db58adc22c59..99d6ccefd17f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1883,10 +1883,10 @@ static int tcp_v6_init_sock(struct sock *sk) sk->sk_write_space = sk_stream_write_space; sk->sk_use_write_queue = 1; - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; + sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; + sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); return 0; } @@ -1910,7 +1910,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_sockets_allocated); + atomic_dec(&tcp_prot.sockets_allocated); return inet6_destroy_sock(sk); } -- cgit v1.2.3 From fdf12225556ebee8cb881414f98ce228b4d096ce Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 23 Jun 2004 12:03:17 -0300 Subject: [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} Only new requirement was to add a max_header field to struct sock sk_prot member. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/net/tcp.h | 46 ------------------------------------------ net/ipv4/tcp.c | 12 +++++------ net/ipv4/tcp_input.c | 16 ++++++--------- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv4/tcp_output.c | 2 +- net/ipv6/tcp_ipv6.c | 3 ++- 7 files changed, 73 insertions(+), 65 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 23f72934b180..809a3c687c1c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -553,6 +553,7 @@ struct proto { int sysctl_mem[3]; int sysctl_wmem[3]; int sysctl_rmem[3]; + int max_header; char name[32]; @@ -660,6 +661,21 @@ static inline void sk_stream_mem_reclaim(struct sock *sk) __sk_stream_mem_reclaim(sk); } +static inline void sk_stream_writequeue_purge(struct sock *sk) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) + sk_stream_free_skb(sk, skb); + sk_stream_mem_reclaim(sk); +} + +static inline int sk_stream_rmem_schedule(struct sock *sk, struct sk_buff *skb) +{ + return (int)skb->truesize <= sk->sk_forward_alloc || + sk_stream_mem_schedule(sk, skb->truesize, 1); +} + /* Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it * from under us. It essentially blocks any incoming @@ -1141,6 +1157,46 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) } } +static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, + int size, int mem, int gfp) +{ + struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp); + + if (skb) { + skb->truesize += mem; + if (sk->sk_forward_alloc >= (int)skb->truesize || + sk_stream_mem_schedule(sk, skb->truesize, 0)) { + skb_reserve(skb, sk->sk_prot->max_header); + return skb; + } + __kfree_skb(skb); + } else { + sk->sk_prot->enter_memory_pressure(); + sk_stream_moderate_sndbuf(sk); + } + return NULL; +} + +static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk, + int size, int gfp) +{ + return sk_stream_alloc_pskb(sk, size, 0, gfp); +} + +static inline struct page *sk_stream_alloc_page(struct sock *sk) +{ + struct page *page = NULL; + + if (sk->sk_forward_alloc >= (int)PAGE_SIZE || + sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) + page = alloc_pages(sk->sk_allocation, 0); + else { + sk->sk_prot->enter_memory_pressure(); + sk_stream_moderate_sndbuf(sk); + } + return page; +} + #define sk_stream_for_retrans_queue(skb, sk) \ for (skb = (sk)->sk_write_queue.next; \ (skb != (sk)->sk_send_head) && \ diff --git a/include/net/tcp.h b/include/net/tcp.h index 8e2a7739136a..626a0803e452 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1862,52 +1862,6 @@ static __inline__ void tcp_openreq_init(struct open_request *req, extern void tcp_enter_memory_pressure(void); -static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) -{ - struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp); - - if (skb) { - skb->truesize += mem; - if (sk->sk_forward_alloc >= (int)skb->truesize || - sk_stream_mem_schedule(sk, skb->truesize, 0)) { - skb_reserve(skb, MAX_TCP_HEADER); - return skb; - } - __kfree_skb(skb); - } else { - tcp_enter_memory_pressure(); - sk_stream_moderate_sndbuf(sk); - } - return NULL; -} - -static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) -{ - return tcp_alloc_pskb(sk, size, 0, gfp); -} - -static inline struct page * tcp_alloc_page(struct sock *sk) -{ - if (sk->sk_forward_alloc >= (int)PAGE_SIZE || - sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) { - struct page *page = alloc_pages(sk->sk_allocation, 0); - if (page) - return page; - } - tcp_enter_memory_pressure(); - sk_stream_moderate_sndbuf(sk); - return NULL; -} - -static inline void tcp_writequeue_purge(struct sock *sk) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) - sk_stream_free_skb(sk, skb); - sk_stream_mem_reclaim(sk); -} - extern void tcp_listen_wlock(void); /* - We may sleep inside this lock. diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index dffead725c64..554de667bfee 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -639,8 +639,8 @@ new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; - skb = tcp_alloc_pskb(sk, 0, tp->mss_cache, - sk->sk_allocation); + skb = sk_stream_alloc_pskb(sk, 0, tp->mss_cache, + sk->sk_allocation); if (!skb) goto wait_for_memory; @@ -806,8 +806,8 @@ new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; - skb = tcp_alloc_pskb(sk, select_size(sk, tp), - 0, sk->sk_allocation); + skb = sk_stream_alloc_pskb(sk, select_size(sk, tp), + 0, sk->sk_allocation); if (!skb) goto wait_for_memory; @@ -868,7 +868,7 @@ new_segment: if (!page) { /* Allocate new cache page. */ - if (!(page = tcp_alloc_page(sk))) + if (!(page = sk_stream_alloc_page(sk))) goto wait_for_memory; off = 0; } @@ -1778,7 +1778,7 @@ int tcp_disconnect(struct sock *sk, int flags) tcp_clear_xmit_timers(sk); __skb_queue_purge(&sk->sk_receive_queue); - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); __skb_queue_purge(&tp->out_of_order_queue); inet->dport = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eb20c5d98163..235ecbbd7a77 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3390,12 +3390,6 @@ static void tcp_ofo_queue(struct sock *sk) } } -static inline int tcp_rmem_schedule(struct sock *sk, struct sk_buff *skb) -{ - return (int)skb->truesize <= sk->sk_forward_alloc || - sk_stream_mem_schedule(sk, skb->truesize, 1); -} - static int tcp_prune_queue(struct sock *sk); static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) @@ -3449,8 +3443,9 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) queue_and_out: if (eaten < 0 && (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !tcp_rmem_schedule(sk, skb))) { - if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + !sk_stream_rmem_schedule(sk, skb))) { + if (tcp_prune_queue(sk) < 0 || + !sk_stream_rmem_schedule(sk, skb)) goto drop; } sk_stream_set_owner_r(skb, sk); @@ -3522,8 +3517,9 @@ drop: TCP_ECN_check_ce(tp, skb); if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !tcp_rmem_schedule(sk, skb)) { - if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + !sk_stream_rmem_schedule(sk, skb)) { + if (tcp_prune_queue(sk) < 0 || + !sk_stream_rmem_schedule(sk, skb)) goto drop; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 828920f7b552..1f18e6aab18b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2101,7 +2101,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) tcp_clear_xmit_timers(sk); /* Cleanup up the write buffer. */ - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); /* Cleans up our, hopefully empty, out_of_order_queue. */ __skb_queue_purge(&tp->out_of_order_queue); @@ -2602,6 +2602,7 @@ struct proto tcp_prot = { .enter_memory_pressure = tcp_enter_memory_pressure, .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, + .max_header = MAX_TCP_HEADER, }; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e78461bdbf3b..b6203742f97f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -372,7 +372,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) return -ENOMEM; /* Get a new skb... force flag on. */ - buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC); + buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); if (buff == NULL) return -ENOMEM; /* We'll just try again later. */ sk_charge_skb(sk, buff); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 99d6ccefd17f..a1b6dfb0193c 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1898,7 +1898,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) tcp_clear_xmit_timers(sk); /* Cleanup up the write buffer. */ - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); /* Cleans up our, hopefully empty, out_of_order_queue. */ __skb_queue_purge(&tp->out_of_order_queue); @@ -2096,6 +2096,7 @@ struct proto tcpv6_prot = { .hash = tcp_v6_hash, .unhash = tcp_unhash, .get_port = tcp_v6_get_port, + .max_header = MAX_TCP_HEADER, }; static struct inet6_protocol tcpv6_protocol = { -- cgit v1.2.3 From 50bde7d0f69bbdf0b90baf198620bb838eb5cc74 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 23 Jun 2004 20:01:15 -0300 Subject: [NET] make the struct proto entries related to memory pressure be pointers This is needed because tcpv6_prot has to point to the same place tcp_prot points, as they share the same accounting variables. This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, thanks David! Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/sock.h | 12 +++++------ include/net/tcp.h | 7 +++++++ net/core/stream.c | 26 +++++++++++------------ net/ipv4/proc.c | 4 ++-- net/ipv4/sysctl_net_ipv4.c | 12 +++++------ net/ipv4/tcp.c | 46 ++++++++++++++++++++++++++++++++--------- net/ipv4/tcp_input.c | 16 +++++++-------- net/ipv4/tcp_ipv4.c | 16 +++++++++------ net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_timer.c | 2 +- net/ipv6/tcp_ipv6.c | 51 ++++++++++++++++++++++++++-------------------- 11 files changed, 119 insertions(+), 75 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 809a3c687c1c..9da91b9be903 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -541,18 +541,18 @@ struct proto { /* Memory pressure */ void (*enter_memory_pressure)(void); - atomic_t memory_allocated; /* Current allocated memory. */ - atomic_t sockets_allocated; /* Current number of sockets. */ + atomic_t *memory_allocated; /* Current allocated memory. */ + atomic_t *sockets_allocated; /* Current number of sockets. */ /* * Pressure flag: try to collapse. * Technical note: it is used by multiple contexts non atomically. * All the sk_stream_mem_schedule() is of this nature: accounting * is strict, actions are advisory and have some latency. */ - int memory_pressure; - int sysctl_mem[3]; - int sysctl_wmem[3]; - int sysctl_rmem[3]; + int *memory_pressure; + int *sysctl_mem; + int *sysctl_wmem; + int *sysctl_rmem; int max_header; char name[32]; diff --git a/include/net/tcp.h b/include/net/tcp.h index 626a0803e452..3f4c524de3e2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -594,6 +594,9 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; +extern int sysctl_tcp_mem[3]; +extern int sysctl_tcp_wmem[3]; +extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_tw_reuse; @@ -611,6 +614,10 @@ extern int sysctl_tcp_bic_low_window; extern int sysctl_tcp_default_win_scale; extern int sysctl_tcp_moderate_rcvbuf; +extern atomic_t tcp_memory_allocated; +extern atomic_t tcp_sockets_allocated; +extern int tcp_memory_pressure; + struct open_request; struct or_calltable { diff --git a/net/core/stream.c b/net/core/stream.c index 1d9c8b932fa1..1e27a57b5a97 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -193,12 +193,12 @@ void __sk_stream_mem_reclaim(struct sock *sk) { if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) { atomic_sub(sk->sk_forward_alloc / SK_STREAM_MEM_QUANTUM, - &sk->sk_prot->memory_allocated); + sk->sk_prot->memory_allocated); sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1; - if (sk->sk_prot->memory_pressure && - (atomic_read(&sk->sk_prot->memory_allocated) < + if (*sk->sk_prot->memory_pressure && + (atomic_read(sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0])) - sk->sk_prot->memory_pressure = 0; + *sk->sk_prot->memory_pressure = 0; } } @@ -209,23 +209,23 @@ int sk_stream_mem_schedule(struct sock *sk, int size, int kind) int amt = sk_stream_pages(size); sk->sk_forward_alloc += amt * SK_STREAM_MEM_QUANTUM; - atomic_add(amt, &sk->sk_prot->memory_allocated); + atomic_add(amt, sk->sk_prot->memory_allocated); /* Under limit. */ - if (atomic_read(&sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { - if (sk->sk_prot->memory_pressure) - sk->sk_prot->memory_pressure = 0; + if (atomic_read(sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { + if (*sk->sk_prot->memory_pressure) + *sk->sk_prot->memory_pressure = 0; return 1; } /* Over hard limit. */ - if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { + if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { sk->sk_prot->enter_memory_pressure(); goto suppress_allocation; } /* Under pressure. */ - if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) + if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) sk->sk_prot->enter_memory_pressure(); if (kind) { @@ -234,8 +234,8 @@ int sk_stream_mem_schedule(struct sock *sk, int size, int kind) } else if (sk->sk_wmem_queued < sk->sk_prot->sysctl_wmem[0]) return 1; - if (!sk->sk_prot->memory_pressure || - sk->sk_prot->sysctl_mem[2] > atomic_read(&sk->sk_prot->sockets_allocated) * + if (!*sk->sk_prot->memory_pressure || + sk->sk_prot->sysctl_mem[2] > atomic_read(sk->sk_prot->sockets_allocated) * sk_stream_pages(sk->sk_wmem_queued + atomic_read(&sk->sk_rmem_alloc) + sk->sk_forward_alloc)) @@ -255,7 +255,7 @@ suppress_allocation: /* Alas. Undo changes. */ sk->sk_forward_alloc -= amt * SK_STREAM_MEM_QUANTUM; - atomic_sub(amt, &sk->sk_prot->memory_allocated); + atomic_sub(amt, sk->sk_prot->memory_allocated); return 0; } diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 35164af84e34..be47cbec57be 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -65,8 +65,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) socket_seq_show(seq); seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count), - tcp_tw_count, atomic_read(&tcp_prot.sockets_allocated), - atomic_read(&tcp_prot.memory_allocated)); + tcp_tw_count, atomic_read(&tcp_sockets_allocated), + atomic_read(&tcp_memory_allocated)); seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues, diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 81c31a3b10b3..6b0b74430e28 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -508,24 +508,24 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_TCP_MEM, .procname = "tcp_mem", - .data = &tcp_prot.sysctl_mem, - .maxlen = sizeof(tcp_prot.sysctl_mem), + .data = &sysctl_tcp_mem, + .maxlen = sizeof(sysctl_tcp_mem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_WMEM, .procname = "tcp_wmem", - .data = &tcp_prot.sysctl_wmem, - .maxlen = sizeof(tcp_prot.sysctl_wmem), + .data = &sysctl_tcp_wmem, + .maxlen = sizeof(sysctl_tcp_wmem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_RMEM, .procname = "tcp_rmem", - .data = &tcp_prot.sysctl_rmem, - .maxlen = sizeof(tcp_prot.sysctl_rmem), + .data = &sysctl_tcp_rmem, + .maxlen = sizeof(sysctl_tcp_rmem), .mode = 0644, .proc_handler = &proc_dointvec }, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 554de667bfee..33ca080f8727 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -278,14 +278,40 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); int sysctl_tcp_default_win_scale; +int sysctl_tcp_mem[3]; +int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; +int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; + +EXPORT_SYMBOL(sysctl_tcp_mem); +EXPORT_SYMBOL(sysctl_tcp_rmem); +EXPORT_SYMBOL(sysctl_tcp_wmem); + +atomic_t tcp_memory_allocated; /* Current allocated memory. */ +atomic_t tcp_sockets_allocated; /* Current number of TCP sockets. */ + +EXPORT_SYMBOL(tcp_memory_allocated); +EXPORT_SYMBOL(tcp_sockets_allocated); + +/* + * Pressure flag: try to collapse. + * Technical note: it is used by multiple contexts non atomically. + * All the sk_stream_mem_schedule() is of this nature: accounting + * is strict, actions are advisory and have some latency. + */ +int tcp_memory_pressure; + +EXPORT_SYMBOL(tcp_memory_pressure); + void tcp_enter_memory_pressure(void) { - if (!tcp_prot.memory_pressure) { + if (!tcp_memory_pressure) { NET_INC_STATS(TCPMemoryPressures); - tcp_prot.memory_pressure = 1; + tcp_memory_pressure = 1; } } +EXPORT_SYMBOL(tcp_enter_memory_pressure); + /* * LISTEN is a special case for poll.. */ @@ -1722,7 +1748,7 @@ adjudge_to_death: sk_stream_mem_reclaim(sk); if (atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "TCP: too many of orphaned " "sockets\n"); @@ -2269,15 +2295,15 @@ void __init tcp_init(void) } tcp_port_rover = sysctl_local_port_range[0] - 1; - tcp_prot.sysctl_mem[0] = 768 << order; - tcp_prot.sysctl_mem[1] = 1024 << order; - tcp_prot.sysctl_mem[2] = 1536 << order; + sysctl_tcp_mem[0] = 768 << order; + sysctl_tcp_mem[1] = 1024 << order; + sysctl_tcp_mem[2] = 1536 << order; if (order < 3) { - tcp_prot.sysctl_wmem[2] = 64 * 1024; - tcp_prot.sysctl_rmem[0] = PAGE_SIZE; - tcp_prot.sysctl_rmem[1] = 43689; - tcp_prot.sysctl_rmem[2] = 2 * 43689; + sysctl_tcp_wmem[2] = 64 * 1024; + sysctl_tcp_rmem[0] = PAGE_SIZE; + sysctl_tcp_rmem[1] = 43689; + sysctl_tcp_rmem[2] = 2 * 43689; } printk(KERN_INFO "TCP: Hash tables configured " diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 235ecbbd7a77..69dcc9f123bf 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -207,7 +207,7 @@ static void tcp_fixup_sndbuf(struct sock *sk) sizeof(struct sk_buff); if (sk->sk_sndbuf < 3 * sndmem) - sk->sk_sndbuf = min(3 * sndmem, tcp_prot.sysctl_wmem[2]); + sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -291,7 +291,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) while (tcp_win_from_space(rcvmem) < tp->advmss) rcvmem += 128; if (sk->sk_rcvbuf < 4 * rcvmem) - sk->sk_rcvbuf = min(4 * rcvmem, tcp_prot.sysctl_rmem[2]); + sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]); } /* 4. Try to fixup all. It is made iimediately after connection enters @@ -347,12 +347,12 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) * do not clamp window. Try to expand rcvbuf instead. */ if (ofo_win) { - if (sk->sk_rcvbuf < tcp_prot.sysctl_rmem[2] && + if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !tcp_prot.memory_pressure && - atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), - tcp_prot.sysctl_rmem[2]); + sysctl_tcp_rmem[2]); } if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { app_win += ofo_win; @@ -473,7 +473,7 @@ void tcp_rcv_space_adjust(struct sock *sk) rcvmem = (tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff)); space *= rcvmem; - space = min(space, tcp_prot.sysctl_rmem[2]); + space = min(space, sysctl_tcp_rmem[2]); if (space > sk->sk_rcvbuf) sk->sk_rcvbuf = space; } @@ -3837,14 +3837,14 @@ static void tcp_new_space(struct sock *sk) if (tp->packets_out < tp->snd_cwnd && !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && !tcp_prot.memory_pressure && - atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) { + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { int sndmem = max_t(u32, tp->mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); sndmem *= 2*demanded; if (sndmem > sk->sk_sndbuf) - sk->sk_sndbuf = min(sndmem, tcp_prot.sysctl_wmem[2]); + sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); tp->snd_cwnd_stamp = tcp_time_stamp; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1f18e6aab18b..35ca34b6b052 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2086,10 +2086,10 @@ static int tcp_v4_init_sock(struct sock *sk) tp->af_specific = &ipv4_specific; - sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; - sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; + sk->sk_sndbuf = sysctl_tcp_wmem[1]; + sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); return 0; } @@ -2113,7 +2113,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_prot.sockets_allocated); + atomic_dec(&tcp_sockets_allocated); return 0; } @@ -2600,8 +2600,12 @@ struct proto tcp_prot = { .unhash = tcp_unhash, .get_port = tcp_v4_get_port, .enter_memory_pressure = tcp_enter_memory_pressure, - .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, - .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, + .sockets_allocated = &tcp_sockets_allocated, + .memory_allocated = &tcp_memory_allocated, + .memory_pressure = &tcp_memory_pressure, + .sysctl_mem = sysctl_tcp_mem, + .sysctl_wmem = sysctl_tcp_wmem, + .sysctl_rmem = sysctl_tcp_rmem, .max_header = MAX_TCP_HEADER, }; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 4f36e164eb07..dacd76e33133 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -801,7 +801,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); #endif - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); if (sock_flag(newsk, SOCK_KEEPOPEN)) tcp_reset_keepalive_timer(newsk, diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 876f9f410277..840f621886c8 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -113,7 +113,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) if (orphans >= sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "Out of socket memory\n"); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a1b6dfb0193c..d2855de92260 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1883,10 +1883,10 @@ static int tcp_v6_init_sock(struct sock *sk) sk->sk_write_space = sk_stream_write_space; sk->sk_use_write_queue = 1; - sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; - sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; + sk->sk_sndbuf = sysctl_tcp_wmem[1]; + sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); return 0; } @@ -1910,7 +1910,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_prot.sockets_allocated); + atomic_dec(&tcp_sockets_allocated); return inet6_destroy_sock(sk); } @@ -2079,24 +2079,31 @@ void tcp6_proc_exit(void) #endif struct proto tcpv6_prot = { - .name = "TCPv6", - .close = tcp_close, - .connect = tcp_v6_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v6_init_sock, - .destroy = tcp_v6_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v6_do_rcv, - .hash = tcp_v6_hash, - .unhash = tcp_unhash, - .get_port = tcp_v6_get_port, - .max_header = MAX_TCP_HEADER, + .name = "TCPv6", + .close = tcp_close, + .connect = tcp_v6_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v6_init_sock, + .destroy = tcp_v6_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v6_do_rcv, + .hash = tcp_v6_hash, + .unhash = tcp_unhash, + .get_port = tcp_v6_get_port, + .enter_memory_pressure = tcp_enter_memory_pressure, + .sockets_allocated = &tcp_sockets_allocated, + .memory_allocated = &tcp_memory_allocated, + .memory_pressure = &tcp_memory_pressure, + .sysctl_mem = sysctl_tcp_mem, + .sysctl_wmem = sysctl_tcp_wmem, + .sysctl_rmem = sysctl_tcp_rmem, + .max_header = MAX_TCP_HEADER, }; static struct inet6_protocol tcpv6_protocol = { -- cgit v1.2.3 From 36f9f2094996483001457fb02398d4b7eae170bd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:48:56 -0700 Subject: [PATCH] Allow i386 to reenable interrupts on lock contention From: Zwane Mwaikambo Following up on Keith's code, I adapted the i386 code to allow enabling interrupts during contested locks depending on previous interrupt enable status. Obviously there will be a text increase (only for non CONFIG_SPINLINE case), although it doesn't seem so bad, there will be an increased exit latency when we attempt a lock acquisition after spinning due to the extra instructions. How much this will affect performance I'm not sure yet as I haven't had time to micro bench. text data bss dec hex filename 2628024 921731 0 3549755 362a3b vmlinux-after 2621369 921731 0 3543100 36103c vmlinux-before 2618313 919222 0 3537535 35fa7f vmlinux-spinline The code has been stress tested on a 16x NUMAQ (courtesy OSDL). Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-i386/spinlock.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 8bd4f23a562e..d6dbfd469565 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -42,7 +42,6 @@ typedef struct { #define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0) #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) #define spin_lock_string \ "\n1:\t" \ @@ -56,6 +55,23 @@ typedef struct { "jmp 1b\n" \ LOCK_SECTION_END +#define spin_lock_string_flags \ + "\n1:\t" \ + "lock ; decb %0\n\t" \ + "js 2f\n\t" \ + LOCK_SECTION_START("") \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 3f\n\t" \ + "sti\n\t" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "cli\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END + /* * This works. Despite all the confusion. * (except on PPro SMP or if we are using OOSTORE) @@ -126,6 +142,20 @@ here: :"=m" (lock->lock) : : "memory"); } +static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) +{ +#ifdef CONFIG_DEBUG_SPINLOCK + __label__ here; +here: + if (unlikely(lock->magic != SPINLOCK_MAGIC)) { + printk("eip: %p\n", &&here); + BUG(); + } +#endif + __asm__ __volatile__( + spin_lock_string_flags + :"=m" (lock->lock) : "r" (flags) : "memory"); +} /* * Read-write spinlocks, allowing multiple readers -- cgit v1.2.3 From b884e83821944633fb02295fd0470398090ac782 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:21 -0700 Subject: [PATCH] Move saved_command_line to init/main.c From: Rusty Russell Currently every arch declares its own char saved_command_line[]. Make sure every arch defines COMMAND_LINE_SIZE in asm/setup.h, and declare saved_command_line in linux/init.h (init/main.c contains the definition). Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/setup.c | 1 - arch/arm/kernel/setup.c | 1 - arch/arm26/kernel/setup.c | 1 - arch/cris/kernel/setup.c | 3 -- arch/h8300/kernel/setup.c | 4 +-- arch/i386/boot/compressed/misc.c | 31 +++++++++---------- arch/i386/kernel/setup.c | 1 - arch/ia64/kernel/setup.c | 4 --- arch/m68k/kernel/setup.c | 1 - arch/m68k/q40/config.c | 1 - arch/m68knommu/kernel/setup.c | 4 +-- arch/mips/kernel/setup.c | 1 - arch/parisc/kernel/setup.c | 2 -- arch/ppc/kernel/setup.c | 1 - arch/ppc/platforms/lopec_setup.c | 1 - arch/ppc/platforms/pmac_setup.c | 2 -- arch/ppc/platforms/pplus.c | 2 -- arch/ppc/platforms/prep_setup.c | 1 - arch/ppc64/kernel/head.S | 3 +- arch/ppc64/kernel/setup.c | 1 - arch/s390/kernel/setup.c | 1 - arch/sh/kernel/setup.c | 2 -- arch/sparc/kernel/setup.c | 3 +- arch/sparc/kernel/sparc_ksyms.c | 2 +- arch/sparc64/kernel/setup.c | 3 +- arch/sparc64/kernel/sparc64_ksyms.c | 2 +- arch/um/kernel/user_util.c | 1 - arch/v850/kernel/setup.c | 4 +-- arch/x86_64/kernel/setup.c | 1 - drivers/sbus/char/openprom.c | 1 - fs/proc/kcore.c | 3 +- fs/proc/proc_misc.c | 1 - include/asm-alpha/setup.h | 6 ++++ include/asm-alpha/system.h | 1 - include/asm-cris/setup.h | 3 ++ include/asm-h8300/setup.h | 7 ++++- include/asm-i386/param.h | 1 + include/asm-ia64/setup.h | 6 ++++ include/asm-m68k/setup.h | 1 + include/asm-m68knommu/setup.h | 4 +++ include/asm-mips/bootinfo.h | 3 +- include/asm-mips/setup.h | 8 +++++ include/asm-parisc/setup.h | 12 +++----- include/asm-ppc/machdep.h | 1 - include/asm-ppc/setup.h | 3 ++ include/asm-ppc64/machdep.h | 3 +- include/asm-ppc64/setup.h | 2 +- include/asm-sh/setup.h | 8 +++++ include/asm-sparc/setup.h | 1 + include/asm-sparc64/setup.h | 1 + include/asm-um/setup.h | 6 ++++ include/asm-v850/setup.h | 6 ++++ include/asm-x86_64/bootsetup.h | 1 - include/asm-x86_64/setup.h | 6 +--- include/linux/init.h | 22 ++++++++++---- init/main.c | 60 +++++++++++++++++++++++++++++++++++-- 56 files changed, 172 insertions(+), 90 deletions(-) create mode 100644 include/asm-alpha/setup.h create mode 100644 include/asm-ia64/setup.h create mode 100644 include/asm-mips/setup.h create mode 100644 include/asm-sh/setup.h create mode 100644 include/asm-um/setup.h create mode 100644 include/asm-v850/setup.h (limited to 'include') diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 1dff8e6c9881..4e93fe9cc6b6 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -122,7 +122,6 @@ static void get_sysnames(unsigned long, unsigned long, unsigned long, static void determine_cpu_caches (unsigned int); static char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; /* * The format of "screen_info" is strange, and due to early diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d159659677b0..835010c55597 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -97,7 +97,6 @@ unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c index afb7db526bd3..e02d41867a72 100644 --- a/arch/arm26/kernel/setup.c +++ b/arch/arm26/kernel/setup.c @@ -76,7 +76,6 @@ struct processor processor; unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 95a9f4408075..f95b82503281 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -29,10 +29,7 @@ unsigned char aux_device_present; extern int root_mountflags; extern char _etext, _edata, _end; -#define COMMAND_LINE_SIZE 256 - static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; extern const unsigned long text_start, edata; /* set by the linker script */ extern unsigned long dram_start, dram_end; diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index bf5822c5659e..0d9e932372d3 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,7 @@ unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 200ac3efd01f..fa67045234a3 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -87,12 +87,11 @@ static void gzip_release(void **); */ static unsigned char *real_mode; /* Pointer to real-mode data */ -#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) +#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) +#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) -#define EDID_INFO (*(struct edid_info *)(real_mode+0x440)) +#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern char input_data[]; extern int input_len; @@ -174,8 +173,8 @@ static void putstr(const char *s) int x,y,pos; char c; - x = SCREEN_INFO.orig_x; - y = SCREEN_INFO.orig_y; + x = RM_SCREEN_INFO.orig_x; + y = RM_SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { @@ -196,8 +195,8 @@ static void putstr(const char *s) } } - SCREEN_INFO.orig_x = x; - SCREEN_INFO.orig_y = y; + RM_SCREEN_INFO.orig_x = x; + RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); @@ -306,9 +305,9 @@ struct { static void setup_normal_output_buffer(void) { #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < 1024) error("Less than 2MB of memory"); + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif output_data = (char *)0x100000; /* Points to 1M */ free_mem_end_ptr = (long)real_mode; @@ -323,9 +322,11 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) { high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < + (3*1024)) + error("Less than 4MB of memory"); #endif mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX @@ -358,7 +359,7 @@ asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; - if (SCREEN_INFO.orig_video_mode == 7) { + if (RM_SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { @@ -366,8 +367,8 @@ asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) vidport = 0x3d4; } - lines = SCREEN_INFO.orig_video_lines; - cols = SCREEN_INFO.orig_video_cols; + lines = RM_SCREEN_INFO.orig_video_lines; + cols = RM_SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index fc466fb4488a..c077386a4568 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -127,7 +127,6 @@ unsigned long saved_videomode; #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE]; - char saved_command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index aa2cb4fc3e54..3f4dc188995b 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -88,10 +88,6 @@ unsigned char aux_device_present = 0xaa; /* XXX remove this when legacy I unsigned long ia64_max_iommu_merge_mask = ~0UL; EXPORT_SYMBOL(ia64_max_iommu_merge_mask); -#define COMMAND_LINE_SIZE 512 - -char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */ - /* * We use a special marker for the end of memory and it uses the extra (+1) slot */ diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 2ede4125bd13..7680eabc3337 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -62,7 +62,6 @@ struct mem_info m68k_memory[NUM_MEMINFO]; static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; -char saved_command_line[CL_SIZE]; char m68k_debug_device[6] = ""; diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 1f8977e7948e..90d82d961abe 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -64,7 +64,6 @@ void q40_set_vectors (void); extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); -extern char *saved_command_line; extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, unsigned int count); diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index bd6a4a89f65f..bb680024f1d7 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,7 @@ unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* setup some dummy routines */ static void dummy_waitbut(void) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a1336d16c57e..8a5acf174730 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -71,7 +71,6 @@ EXPORT_SYMBOL(mips_machgroup); struct boot_mem_map boot_mem_map; static char command_line[CL_SIZE]; - char saved_command_line[CL_SIZE]; char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE; /* diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 820adb178f70..98b6f4c2cf6f 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -45,8 +45,6 @@ #include #include -#define COMMAND_LINE_SIZE 1024 -char saved_command_line[COMMAND_LINE_SIZE]; char command_line[COMMAND_LINE_SIZE]; /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 18a2f147d412..a46602e33b80 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -54,7 +54,6 @@ extern void ppc6xx_idle(void); extern void power4_idle(void); extern boot_infos_t *boot_infos; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; struct ide_machdep_calls ppc_ide_md; char *sysmap; diff --git a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c index c231f67d73c6..d675b76a9838 100644 --- a/arch/ppc/platforms/lopec_setup.c +++ b/arch/ppc/platforms/lopec_setup.c @@ -33,7 +33,6 @@ #include #include -extern char saved_command_line[]; extern void lopec_find_bridges(void); /* diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index d89cfe2ae765..b05cee1f7216 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -103,8 +103,6 @@ int has_l2cache = 0; static int current_root_goodness = -1; -extern char saved_command_line[]; - extern int pmac_newworld; #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c index 6fc3ca978728..673641ff4bf5 100644 --- a/arch/ppc/platforms/pplus.c +++ b/arch/ppc/platforms/pplus.c @@ -48,8 +48,6 @@ TODC_ALLOC(); -extern char saved_command_line[]; - extern void pplus_setup_hose(void); extern void pplus_set_VIA_IDE_native(void); diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 7c3623bcce39..4362597e191e 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -76,7 +76,6 @@ extern void rs_nvram_write_val(int addr, extern void ibm_prep_init(void); extern void prep_find_bridges(void); -extern char saved_command_line[]; int _prep_type; diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 83601a8b05f4..0f0f276607de 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -2222,4 +2223,4 @@ stab_array: */ .globl cmd_line cmd_line: - .space 512 /* COMMAND_LINE_SIZE */ + .space COMMAND_LINE_SIZE diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index f13739566fa9..aec2d763e9f9 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -82,7 +82,6 @@ unsigned long decr_overclock_proc0_set = 0; int powersave_nap; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d549ad5c2724..8b4c40d8f7bf 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -76,7 +76,6 @@ extern int _text,_etext, _edata, _end; #include static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; static struct resource code_resource = { "Kernel code", 0x100000, 0 }; static struct resource data_resource = { "Kernel data", 0, 0 }; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 574ac24f8e51..3c1b4c799e62 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -85,14 +85,12 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name); #define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -#define COMMAND_LINE_SIZE 256 #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f }, diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index e4558e7f0df7..ba8a2fab320e 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -244,8 +244,7 @@ extern unsigned short ram_flags; extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; enum sparc_cpu sparc_cpu_model; struct tt_entry *sparc_ttable; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 601c97a31dd0..fdaacfa478c7 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -74,7 +75,6 @@ extern void *__memscan_zero(void *, size_t); extern void *__memscan_generic(void *, int, size_t); extern int __memcmp(const void *, const void *, __kernel_size_t); extern int __strncmp(const char *, const char *, __kernel_size_t); -extern char saved_command_line[]; extern void bcopy (const char *, char *, int); extern int __ashrdi3(int, int); diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 3d097a4bb2c3..f463ca2e61c8 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -451,8 +451,7 @@ extern unsigned short ram_flags; extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 909a13aeb1d8..888d540a1672 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -76,7 +77,6 @@ extern int __memcmp(const void *, const void *, __kernel_size_t); extern int __strncmp(const char *, const char *, __kernel_size_t); extern __kernel_size_t __strlen(const char *); extern __kernel_size_t strlen(const char *); -extern char saved_command_line[]; extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index a953a08c1a14..9e4fbae93617 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c @@ -34,7 +34,6 @@ #define COMMAND_LINE_SIZE _POSIX_ARG_MAX /* Changed in linux_main and setup_arch, which run before SMP is started */ -char saved_command_line[COMMAND_LINE_SIZE] = { 0 }; char command_line[COMMAND_LINE_SIZE] = { 0 }; void add_arg(char *cmd_line, char *arg) diff --git a/arch/v850/kernel/setup.c b/arch/v850/kernel/setup.c index 960802a756ae..49675035cf9d 100644 --- a/arch/v850/kernel/setup.c +++ b/arch/v850/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -40,8 +41,7 @@ extern char _root_fs_image_start __attribute__ ((__weak__)); extern char _root_fs_image_end __attribute__ ((__weak__)); -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* Memory not used by the kernel. */ static unsigned long total_ram_pages; diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 094949f96ace..84417fc01841 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -100,7 +100,6 @@ extern int root_mountflags; extern char _text, _etext, _edata, _end; char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY | IORESOURCE_IO }, diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index c140f63b366b..82bfa900c619 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -149,7 +149,6 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, char buffer[OPROMMAXPARAM+1], *buf; struct openpromio *opp; int bufsize, len, error = 0; - extern char saved_command_line[]; static int cnt; if (cmd == OPROMSETOPT) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 1f55db799b51..3b1f58300d36 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -84,8 +85,6 @@ kclist_del(void *addr) return 0; } -extern char saved_command_line[]; - static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) { size_t try, size; diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index a46bd705e93b..415d6ee489b4 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -518,7 +518,6 @@ static int filesystems_read_proc(char *page, char **start, off_t off, static int cmdline_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - extern char saved_command_line[]; int len; len = sprintf(page, "%s\n", saved_command_line); diff --git a/include/asm-alpha/setup.h b/include/asm-alpha/setup.h new file mode 100644 index 000000000000..2e023a4aa317 --- /dev/null +++ b/include/asm-alpha/setup.h @@ -0,0 +1,6 @@ +#ifndef __ALPHA_SETUP_H +#define __ALPHA_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index 606a0553c688..1e5ac92d2073 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -43,7 +43,6 @@ */ #define PARAM ZERO_PGE #define COMMAND_LINE ((char*)(PARAM + 0x0000)) -#define COMMAND_LINE_SIZE 256 #define INITRD_START (*(unsigned long *) (PARAM+0x100)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x108)) diff --git a/include/asm-cris/setup.h b/include/asm-cris/setup.h index 832c197edf48..b90728652d1a 100644 --- a/include/asm-cris/setup.h +++ b/include/asm-cris/setup.h @@ -1,3 +1,6 @@ #ifndef _CRIS_SETUP_H #define _CRIS_SETUP_H + +#define COMMAND_LINE_SIZE 256 + #endif diff --git a/include/asm-h8300/setup.h b/include/asm-h8300/setup.h index 4fc416e80bef..e2c600e96733 100644 --- a/include/asm-h8300/setup.h +++ b/include/asm-h8300/setup.h @@ -1 +1,6 @@ -/* Nothing do */ +#ifndef __H8300_SETUP_H +#define __H8300_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h index e0a47502836d..b6440526e42a 100644 --- a/include/asm-i386/param.h +++ b/include/asm-i386/param.h @@ -18,5 +18,6 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#define COMMAND_LINE_SIZE 256 #endif diff --git a/include/asm-ia64/setup.h b/include/asm-ia64/setup.h new file mode 100644 index 000000000000..ea29b57affcb --- /dev/null +++ b/include/asm-ia64/setup.h @@ -0,0 +1,6 @@ +#ifndef __IA64_SETUP_H +#define __IA64_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h index 47b4627ef846..ce2762822a2b 100644 --- a/include/asm-m68k/setup.h +++ b/include/asm-m68k/setup.h @@ -357,6 +357,7 @@ extern int m68k_is040or060; #define NUM_MEMINFO 4 #define CL_SIZE 256 +#define COMMAND_LINE_SIZE CL_SIZE #ifndef __ASSEMBLY__ extern int m68k_num_memory; /* # of memory blocks found (and used) */ diff --git a/include/asm-m68knommu/setup.h b/include/asm-m68knommu/setup.h index ff4565ead5d7..d2b0fcce41b2 100644 --- a/include/asm-m68knommu/setup.h +++ b/include/asm-m68knommu/setup.h @@ -1 +1,5 @@ #include + +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE 512 diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index aacab4d6ebf6..c9c257c201eb 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -12,6 +12,7 @@ #define _ASM_BOOTINFO_H #include +#include /* * The MACH_GROUP_ IDs are the equivalent to PCI vendor IDs; the remaining @@ -209,7 +210,7 @@ #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ -#define CL_SIZE (256) +#define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); diff --git a/include/asm-mips/setup.h b/include/asm-mips/setup.h new file mode 100644 index 000000000000..737fa4a6912e --- /dev/null +++ b/include/asm-mips/setup.h @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#ifndef _MIPS_SETUP_H +#define _MIPS_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif /* __SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-parisc/setup.h b/include/asm-parisc/setup.h index ae25cc4275d3..7da2e5b8747e 100644 --- a/include/asm-parisc/setup.h +++ b/include/asm-parisc/setup.h @@ -1,10 +1,6 @@ -/* - * Just a place holder. We don't want to have to test x86 before - * we include stuff - */ +#ifndef _PARISC_SETUP_H +#define _PARISC_SETUP_H -#ifndef _i386_SETUP_H -#define _i386_SETUP_H +#define COMMAND_LINE_SIZE 1024 - -#endif /* _i386_SETUP_H */ +#endif /* _PARISC_SETUP_H */ diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 4ace72fc4e7b..fca154980c17 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -106,7 +106,6 @@ struct machdep_calls { }; extern struct machdep_calls ppc_md; -#define COMMAND_LINE_SIZE 512 extern char cmd_line[COMMAND_LINE_SIZE]; extern void setup_pci_ptrs(void); diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h index cd458c4f1642..d2d19ee103df 100644 --- a/include/asm-ppc/setup.h +++ b/include/asm-ppc/setup.h @@ -6,6 +6,9 @@ #define m68k_memory memory #include +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE 512 #endif /* _PPC_SETUP_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index bb961a029fae..f0b00cc458c7 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -11,6 +11,7 @@ #include #include +#include #include struct pt_regs; @@ -112,9 +113,7 @@ struct machdep_calls { }; extern struct machdep_calls ppc_md; -#define COMMAND_LINE_SIZE 512 extern char cmd_line[COMMAND_LINE_SIZE]; -extern char saved_command_line[COMMAND_LINE_SIZE]; /* Functions to produce codes on the leds. * The SRC code should be unique for the message category and should diff --git a/include/asm-ppc64/setup.h b/include/asm-ppc64/setup.h index d6e62d15a5dd..b257b8348c73 100644 --- a/include/asm-ppc64/setup.h +++ b/include/asm-ppc64/setup.h @@ -1,6 +1,6 @@ #ifndef _PPC_SETUP_H #define _PPC_SETUP_H -/* This is a place holder include */ +#define COMMAND_LINE_SIZE 512 #endif /* _PPC_SETUP_H */ diff --git a/include/asm-sh/setup.h b/include/asm-sh/setup.h new file mode 100644 index 000000000000..d19de7c8df4e --- /dev/null +++ b/include/asm-sh/setup.h @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#ifndef _SH_SETUP_H +#define _SH_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif /* _SH_SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-sparc/setup.h b/include/asm-sparc/setup.h index d8aaa7205345..b3af958a2ad2 100644 --- a/include/asm-sparc/setup.h +++ b/include/asm-sparc/setup.h @@ -5,5 +5,6 @@ #ifndef _SPARC_SETUP_H #define _SPARC_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif /* _SPARC_SETUP_H */ diff --git a/include/asm-sparc64/setup.h b/include/asm-sparc64/setup.h index 97ae5d456702..b356ee2cda92 100644 --- a/include/asm-sparc64/setup.h +++ b/include/asm-sparc64/setup.h @@ -5,5 +5,6 @@ #ifndef _SPARC64_SETUP_H #define _SPARC64_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif /* _SPARC64_SETUP_H */ diff --git a/include/asm-um/setup.h b/include/asm-um/setup.h new file mode 100644 index 000000000000..e5787bb80e79 --- /dev/null +++ b/include/asm-um/setup.h @@ -0,0 +1,6 @@ +#ifndef SETUP_H_INCLUDED +#define SETUP_H_INCLUDED + +#define COMMAND_LINE_SIZE 512 + +#endif /* SETUP_H_INCLUDED */ diff --git a/include/asm-v850/setup.h b/include/asm-v850/setup.h new file mode 100644 index 000000000000..c48a9b97d05b --- /dev/null +++ b/include/asm-v850/setup.h @@ -0,0 +1,6 @@ +#ifndef _V850_SETUP_H +#define _V850_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif /* __SETUP_H */ diff --git a/include/asm-x86_64/bootsetup.h b/include/asm-x86_64/bootsetup.h index ee1557748b0e..8fe68a93b798 100644 --- a/include/asm-x86_64/bootsetup.h +++ b/include/asm-x86_64/bootsetup.h @@ -30,7 +30,6 @@ extern char x86_boot_params[2048]; #define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) #define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE saved_command_line -#define COMMAND_LINE_SIZE 256 #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 diff --git a/include/asm-x86_64/setup.h b/include/asm-x86_64/setup.h index 7079a136ca8e..985d4e3c79da 100644 --- a/include/asm-x86_64/setup.h +++ b/include/asm-x86_64/setup.h @@ -1,10 +1,6 @@ -/* - * Just a place holder. We don't want to have to test x86 before - * we include stuff - */ - #ifndef _x8664_SETUP_H #define _x8664_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif diff --git a/include/linux/init.h b/include/linux/init.h index 45069e275b3d..641657ebe067 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -3,6 +3,7 @@ #include #include +#include /* These macros are used to mark some functions or * initialized data (doesn't apply to uninitialized data) @@ -66,6 +67,9 @@ typedef void (*exitcall_t)(void); extern initcall_t __con_initcall_start, __con_initcall_end; extern initcall_t __security_initcall_start, __security_initcall_end; + +/* Defined in init/main.c */ +extern char saved_command_line[COMMAND_LINE_SIZE]; #endif #ifndef MODULE @@ -107,25 +111,33 @@ extern initcall_t __security_initcall_start, __security_initcall_end; struct obs_kernel_param { const char *str; int (*setup_func)(char *); + int early; }; -/* OBSOLETE: see moduleparam.h for the right way. */ -#define __setup_param(str, unique_id, fn) \ +/* Only for really core code. See moduleparam.h for the normal way. */ +#define __setup_param(str, unique_id, fn, early) \ static char __setup_str_##unique_id[] __initdata = str; \ static struct obs_kernel_param __setup_##unique_id \ __attribute_used__ \ __attribute__((__section__(".init.setup"))) \ - = { __setup_str_##unique_id, fn } + = { __setup_str_##unique_id, fn, early } #define __setup_null_param(str, unique_id) \ - __setup_param(str, unique_id, NULL) + __setup_param(str, unique_id, NULL, 0) #define __setup(str, fn) \ - __setup_param(str, fn, fn) + __setup_param(str, fn, fn, 0) #define __obsolete_setup(str) \ __setup_null_param(str, __LINE__) +/* NOTE: fn is as per module_param, not __setup! Emits warning if fn + * returns non-zero. */ +#define early_param(str, fn) \ + __setup_param(str, fn, fn, 1) + +/* Relies on saved_command_line being set */ +void __init parse_early_param(void); #endif /* __ASSEMBLY__ */ /** diff --git a/init/main.c b/init/main.c index 1e58b66b2144..4d99b928aeb4 100644 --- a/init/main.c +++ b/init/main.c @@ -111,6 +111,9 @@ extern void time_init(void); void (*late_time_init)(void); extern void softirq_init(void); +/* Untouched command line (eg. for /proc) saved by arch-specific code. */ +char saved_command_line[COMMAND_LINE_SIZE]; + static char *execute_command; /* Setup configured maximum number of CPUs to activate */ @@ -157,8 +160,14 @@ static int __init obsolete_checksetup(char *line) do { int n = strlen(p->str); if (!strncmp(line, p->str, n)) { - if (!p->setup_func) { - printk(KERN_WARNING "Parameter %s is obsolete, ignored\n", p->str); + if (p->early) { + /* Already done in parse_early_param? (Needs + * exact match on param part) */ + if (line[n] == '\0' || line[n] == '=') + return 1; + } else if (!p->setup_func) { + printk(KERN_WARNING "Parameter %s is obsolete," + " ignored\n", p->str); return 1; } else if (p->setup_func(line + n)) return 1; @@ -393,6 +402,38 @@ static void noinline rest_init(void) cpu_idle(); } +/* Check for early params. */ +static int __init do_early_param(char *param, char *val) +{ + struct obs_kernel_param *p; + extern struct obs_kernel_param __setup_start, __setup_end; + + for (p = &__setup_start; p < &__setup_end; p++) { + if (p->early && strcmp(param, p->str) == 0) { + if (p->setup_func(val) != 0) + printk(KERN_WARNING + "Malformed early option '%s'\n", param); + } + } + /* We accept everything at this stage. */ + return 0; +} + +/* Arch code calls this early on, or if not, just before other parsing. */ +void __init parse_early_param(void) +{ + static __initdata int done = 0; + static __initdata char tmp_cmdline[COMMAND_LINE_SIZE]; + + if (done) + return; + + /* All fall through to do_early_param. */ + strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE); + parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); + done = 1; +} + /* * Activate the first processor. */ @@ -400,7 +441,6 @@ static void noinline rest_init(void) asmlinkage void __init start_kernel(void) { char * command_line; - extern char saved_command_line[]; extern struct kernel_param __start___param[], __stop___param[]; /* * Interrupts are still disabled. Do necessary setups, then @@ -428,6 +468,7 @@ asmlinkage void __init start_kernel(void) build_all_zonelists(); page_alloc_init(); printk("Kernel command line: %s\n", saved_command_line); + parse_early_param(); parse_args("Booting kernel", command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); @@ -676,3 +717,16 @@ static int init(void * unused) panic("No init found. Try passing init= option to kernel."); } + +static int early_param_test(char *rest) +{ + printk("early_parm_test: %s\n", rest ?: "(null)"); + return rest ? 0 : -EINVAL; +} +early_param("testsetup", early_param_test); +static int early_setup_test(char *rest) +{ + printk("early_setup_test: %s\n", rest ?: "(null)"); + return 0; +} +__setup("testsetup_long", early_setup_test); -- cgit v1.2.3 From 5c60169a01af712b0b1aa1f5db3fcb8776b22d9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:33 -0700 Subject: [PATCH] rcu lock update: Add per-cpu batch counter From: Manfred Spraul Below is the one of my patches from my rcu lock update. Jack Steiner tested the first one on a 512p and it resolved the rcu cache line trashing. All were tested on osdl with STP. Step one for reducing cacheline trashing within rcupdate.c: The current code uses the rcu_cpu_mask bitmap both for keeping track of the cpus that haven't gone through a quiescent state and for checking if a cpu should look for quiescent states. The bitmap is frequently changed and the check is done by polling - together this causes cache line trashing. If it's cheaper to access a (mostly) read-only cacheline than a cacheline that is frequently dirtied, then it's possible to reduce the trashing by splitting the rcu_cpu_mask bitmap into two cachelines: The patch adds a generation counter and moves it into a separate cacheline. This allows to removes all accesses to rcu_cpumask (in the read-write cacheline) from rcu_pending and at least 50% of the accesses from rcu_check_quiescent_state. rcu_pending and all but one call per cpu to rcu_check_quiescent_state access the read-only cacheline. Probably not enough for 512p, but it's a start, just for 128 byte more memory use, without slowing down rcu grace periods. Obviously the read-only cacheline is not really read-only: it's written once per grace period to indicate that a new grace period is running. Tests on an 8-way Pentium III with reaim showed some improvement: oprofile hits: Reference: http://khack.osdl.org/stp/293075/ Hits % 23741 0.0994 rcu_pending 19057 0.0798 rcu_check_quiescent_state 6530 0.0273 rcu_check_callbacks Patched: http://khack.osdl.org/stp/293076/ 8291 0.0579 rcu_pending 5475 0.0382 rcu_check_quiescent_state 3604 0.0252 rcu_check_callbacks The total runtime differs between both runs, thus the % number must be compared: Around 50% faster. I've uninlined rcu_pending for the test. Tested with reaim and kernbench. Description: - per-cpu quiescbatch and qs_pending fields introduced: quiescbatch contains the number of the last quiescent period that the cpu has seen and qs_pending is set if the cpu has not yet reported the quiescent state for the current period. With these two fields a cpu can test if it should report a quiescent state without having to look at the frequently written rcu_cpu_mask bitmap. - curbatch split into two fields: rcu_ctrlblk.batch.completed and rcu_ctrlblk.batch.cur. This makes it possible to figure out if a grace period is running (completed != cur) without accessing the rcu_cpu_mask bitmap. - rcu_ctrlblk.maxbatch removed and replaced with a true/false next_pending flag: next_pending=1 means that another grace period should be started immediately after the end of the current period. Previously, this was achieved by maxbatch: curbatch==maxbatch means don't start, curbatch!= maxbatch means start. A flag improves the readability: The only possible values for maxbatch were curbatch and curbatch+1. - rcu_ctrlblk split into two cachelines for better performance. - common code from rcu_offline_cpu and rcu_check_quiescent_state merged into cpu_quiet. - rcu_offline_cpu: replace spin_lock_irq with spin_lock_bh, there are no accesses from irq context (and there are accesses to the spinlock with enabled interrupts from tasklet context). - rcu_restart_cpu introduced, s390 should call it after changing nohz: Theoretically the global batch counter could wrap around and end up at RCU_quiescbatch(cpu). Then the cpu would not look for a quiescent state and rcu would lock up. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 48 +++++++++++----- kernel/rcupdate.c | 142 +++++++++++++++++++++++++++++------------------ 2 files changed, 122 insertions(+), 68 deletions(-) (limited to 'include') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 58048abd7446..f9981251d542 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -65,11 +65,18 @@ struct rcu_head { /* Control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk { - spinlock_t mutex; /* Guard this struct */ - long curbatch; /* Current batch number. */ - long maxbatch; /* Max requested batch number. */ - cpumask_t rcu_cpu_mask; /* CPUs that need to switch in order */ - /* for current batch to proceed. */ + /* "const" members: only changed when starting/ending a grace period */ + struct { + long cur; /* Current batch number. */ + long completed; /* Number of the last completed batch */ + } batch ____cacheline_maxaligned_in_smp; + /* remaining members: bookkeeping of the progress of the grace period */ + struct { + spinlock_t mutex; /* Guard this struct */ + int next_pending; /* Is the next batch already waiting? */ + cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ + /* in order for current batch to proceed. */ + } state ____cacheline_maxaligned_in_smp; }; /* Is batch a before batch b ? */ @@ -90,9 +97,14 @@ static inline int rcu_batch_after(long a, long b) * curlist - current batch for which quiescent cycle started if any */ struct rcu_data { + /* 1) quiescent state handling : */ + long quiescbatch; /* Batch # for grace period */ long qsctr; /* User-mode/idle loop etc. */ long last_qsctr; /* value of qsctr at beginning */ /* of rcu grace period */ + int qs_pending; /* core waits for quiesc state */ + + /* 2) batch handling */ long batch; /* Batch # for current RCU batch */ struct list_head nxtlist; struct list_head curlist; @@ -101,24 +113,31 @@ struct rcu_data { DECLARE_PER_CPU(struct rcu_data, rcu_data); extern struct rcu_ctrlblk rcu_ctrlblk; +#define RCU_quiescbatch(cpu) (per_cpu(rcu_data, (cpu)).quiescbatch) #define RCU_qsctr(cpu) (per_cpu(rcu_data, (cpu)).qsctr) #define RCU_last_qsctr(cpu) (per_cpu(rcu_data, (cpu)).last_qsctr) +#define RCU_qs_pending(cpu) (per_cpu(rcu_data, (cpu)).qs_pending) #define RCU_batch(cpu) (per_cpu(rcu_data, (cpu)).batch) #define RCU_nxtlist(cpu) (per_cpu(rcu_data, (cpu)).nxtlist) #define RCU_curlist(cpu) (per_cpu(rcu_data, (cpu)).curlist) -#define RCU_QSCTR_INVALID 0 - static inline int rcu_pending(int cpu) { - if ((!list_empty(&RCU_curlist(cpu)) && - rcu_batch_before(RCU_batch(cpu), rcu_ctrlblk.curbatch)) || - (list_empty(&RCU_curlist(cpu)) && - !list_empty(&RCU_nxtlist(cpu))) || - cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) + /* This cpu has pending rcu entries and the grace period + * for them has completed. + */ + if (!list_empty(&RCU_curlist(cpu)) && + !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) + return 1; + /* This cpu has no pending entries, but there are new entries */ + if (list_empty(&RCU_curlist(cpu)) && + !list_empty(&RCU_nxtlist(cpu))) + return 1; + /* The rcu core waits for a quiescent state from the cpu */ + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur || RCU_qs_pending(cpu)) return 1; - else - return 0; + /* nothing to do */ + return 0; } #define rcu_read_lock() preempt_disable() @@ -126,6 +145,7 @@ static inline int rcu_pending(int cpu) extern void rcu_init(void); extern void rcu_check_callbacks(int cpu, int user); +extern void rcu_restart_cpu(int cpu); /* Exported interfaces */ extern void FASTCALL(call_rcu(struct rcu_head *head, diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 13a1b5a5825f..d665d001e030 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,8 +47,8 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .mutex = SPIN_LOCK_UNLOCKED, .curbatch = 1, - .maxbatch = 1, .rcu_cpu_mask = CPU_MASK_NONE }; + { .batch = { .cur = -300, .completed = -300 }, + .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; /* Fake initialization required by compiler */ @@ -96,26 +96,60 @@ static void rcu_do_batch(struct list_head *list) } } +/* + * Grace period handling: + * The grace period handling consists out of two steps: + * - A new grace period is started. + * This is done by rcu_start_batch. The start is not broadcasted to + * all cpus, they must pick this up by comparing rcu_ctrlblk.batch.cur with + * RCU_quiescbatch(cpu). All cpus are recorded in the + * rcu_ctrlblk.state.rcu_cpu_mask bitmap. + * - All cpus must go through a quiescent state. + * Since the start of the grace period is not broadcasted, at least two + * calls to rcu_check_quiescent_state are required: + * The first call just notices that a new grace period is running. The + * following calls check if there was a quiescent state since the beginning + * of the grace period. If so, it updates rcu_ctrlblk.state.rcu_cpu_mask. If + * the bitmap is empty, then the grace period is completed. + * rcu_check_quiescent_state calls rcu_start_batch(0) to start the next grace + * period (if necessary). + */ /* * Register a new batch of callbacks, and start it up if there is currently no * active batch and the batch to be registered has not already occurred. - * Caller must hold the rcu_ctrlblk lock. + * Caller must hold the rcu_ctrlblk.state lock. */ -static void rcu_start_batch(long newbatch) +static void rcu_start_batch(int next_pending) { cpumask_t active; - if (rcu_batch_before(rcu_ctrlblk.maxbatch, newbatch)) { - rcu_ctrlblk.maxbatch = newbatch; + if (next_pending) + rcu_ctrlblk.state.next_pending = 1; + + if (rcu_ctrlblk.state.next_pending && + rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { + rcu_ctrlblk.state.next_pending = 0; + /* Can't change, since spin lock held. */ + active = nohz_cpu_mask; + cpus_complement(active); + cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); + rcu_ctrlblk.batch.cur++; } - if (rcu_batch_before(rcu_ctrlblk.maxbatch, rcu_ctrlblk.curbatch) || - !cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) { - return; +} + +/* + * cpu went through a quiescent state since the beginning of the grace period. + * Clear it from the cpu mask and complete the grace period if it was the last + * cpu. Start another grace period if someone has further entries pending + */ +static void cpu_quiet(int cpu) +{ + cpu_clear(cpu, rcu_ctrlblk.state.rcu_cpu_mask); + if (cpus_empty(rcu_ctrlblk.state.rcu_cpu_mask)) { + /* batch completed ! */ + rcu_ctrlblk.batch.completed = rcu_ctrlblk.batch.cur; + rcu_start_batch(0); } - /* Can't change, since spin lock held. */ - active = nohz_cpu_mask; - cpus_complement(active); - cpus_and(rcu_ctrlblk.rcu_cpu_mask, cpu_online_map, active); } /* @@ -127,7 +161,19 @@ static void rcu_check_quiescent_state(void) { int cpu = smp_processor_id(); - if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur) { + /* new grace period: record qsctr value. */ + RCU_qs_pending(cpu) = 1; + RCU_last_qsctr(cpu) = RCU_qsctr(cpu); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.cur; + return; + } + + /* Grace period already completed for this cpu? + * qs_pending is checked instead of the actual bitmap to avoid + * cacheline trashing. + */ + if (!RCU_qs_pending(cpu)) return; /* @@ -135,27 +181,19 @@ static void rcu_check_quiescent_state(void) * we may miss one quiescent state of that CPU. That is * tolerable. So no need to disable interrupts. */ - if (RCU_last_qsctr(cpu) == RCU_QSCTR_INVALID) { - RCU_last_qsctr(cpu) = RCU_qsctr(cpu); - return; - } if (RCU_qsctr(cpu) == RCU_last_qsctr(cpu)) return; + RCU_qs_pending(cpu) = 0; - spin_lock(&rcu_ctrlblk.mutex); - if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) - goto out_unlock; - - cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); - RCU_last_qsctr(cpu) = RCU_QSCTR_INVALID; - if (!cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) - goto out_unlock; - - rcu_ctrlblk.curbatch++; - rcu_start_batch(rcu_ctrlblk.maxbatch); + spin_lock(&rcu_ctrlblk.state.mutex); + /* + * RCU_quiescbatch/batch.cur and the cpu bitmap can come out of sync + * during cpu startup. Ignore the quiescent state. + */ + if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.batch.cur)) + cpu_quiet(cpu); -out_unlock: - spin_unlock(&rcu_ctrlblk.mutex); + spin_unlock(&rcu_ctrlblk.state.mutex); } @@ -185,25 +223,11 @@ static void rcu_offline_cpu(int cpu) * we can block indefinitely waiting for it, so flush * it here */ - spin_lock_irq(&rcu_ctrlblk.mutex); - if (cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) - goto unlock; - - cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); - if (cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) { - rcu_ctrlblk.curbatch++; - /* We may avoid calling start batch if - * we are starting the batch only - * because of the DEAD CPU (the current - * CPU will start a new batch anyway for - * the callbacks we will move to current CPU). - * However, we will avoid this optimisation - * for now. - */ - rcu_start_batch(rcu_ctrlblk.maxbatch); - } + spin_lock_bh(&rcu_ctrlblk.state.mutex); + if (rcu_ctrlblk.batch.cur != rcu_ctrlblk.batch.completed) + cpu_quiet(cpu); unlock: - spin_unlock_irq(&rcu_ctrlblk.mutex); + spin_unlock_bh(&rcu_ctrlblk.state.mutex); rcu_move_batch(&RCU_curlist(cpu)); rcu_move_batch(&RCU_nxtlist(cpu)); @@ -213,6 +237,14 @@ unlock: #endif +void rcu_restart_cpu(int cpu) +{ + spin_lock_bh(&rcu_ctrlblk.state.mutex); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_qs_pending(cpu) = 0; + spin_unlock_bh(&rcu_ctrlblk.state.mutex); +} + /* * This does the RCU processing work from tasklet context. */ @@ -222,7 +254,7 @@ static void rcu_process_callbacks(unsigned long unused) LIST_HEAD(list); if (!list_empty(&RCU_curlist(cpu)) && - rcu_batch_after(rcu_ctrlblk.curbatch, RCU_batch(cpu))) { + !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) { __list_splice(&RCU_curlist(cpu), &list); INIT_LIST_HEAD(&RCU_curlist(cpu)); } @@ -236,10 +268,10 @@ static void rcu_process_callbacks(unsigned long unused) /* * start the next batch of callbacks */ - spin_lock(&rcu_ctrlblk.mutex); - RCU_batch(cpu) = rcu_ctrlblk.curbatch + 1; - rcu_start_batch(RCU_batch(cpu)); - spin_unlock(&rcu_ctrlblk.mutex); + spin_lock(&rcu_ctrlblk.state.mutex); + RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; + rcu_start_batch(1); + spin_unlock(&rcu_ctrlblk.state.mutex); } else { local_irq_enable(); } @@ -263,6 +295,8 @@ static void __devinit rcu_online_cpu(int cpu) tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); INIT_LIST_HEAD(&RCU_curlist(cpu)); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_qs_pending(cpu) = 0; } static int __devinit rcu_cpu_notify(struct notifier_block *self, -- cgit v1.2.3 From 720e8a63908eb18aad1721c1429e89fbf7cf0ca6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:44 -0700 Subject: [PATCH] rcu lock update: Use a sequence lock for starting batches From: Manfred Spraul Step two for reducing cacheline trashing within rcupdate.c: rcu_process_callbacks always acquires rcu_ctrlblk.state.mutex and calls rcu_start_batch, even if the batch is already running or already scheduled to run. This can be avoided with a sequence lock: A sequence lock allows to read the current batch number and next_pending atomically. If next_pending is already set, then there is no need to acquire the global mutex. This means that for each grace period, there will be - one write access to the rcu_ctrlblk.batch cacheline - lots of read accesses to rcu_ctrlblk.batch (3-10*cpus_online()). Behavior similar to the jiffies cacheline, shouldn't be a problem. - cpus_online()+1 write accesses to rcu_ctrlblk.state, all of them starting with spin_lock(&rcu_ctrlblk.state.mutex). For large enough cpus_online() this will be a problem, but all except two of the spin_lock calls only protect the rcu_cpu_mask bitmap, thus a hierarchical bitmap would allow to split the write accesses to multiple cachelines. Tested on an 8-way with reaim. Unfortunately it probably won't help with Jack Steiner's 'ls' test since in this test only one cpu generates rcu entries. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 6 +++++- kernel/rcupdate.c | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index f9981251d542..883fc03ed4ef 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -41,6 +41,7 @@ #include #include #include +#include /** * struct rcu_head - callback structure for use with RCU @@ -69,11 +70,14 @@ struct rcu_ctrlblk { struct { long cur; /* Current batch number. */ long completed; /* Number of the last completed batch */ + int next_pending; /* Is the next batch already waiting? */ + seqcount_t lock; /* for atomically reading cur and */ + /* next_pending. Spinlock not used, */ + /* protected by state.mutex */ } batch ____cacheline_maxaligned_in_smp; /* remaining members: bookkeeping of the progress of the grace period */ struct { spinlock_t mutex; /* Guard this struct */ - int next_pending; /* Is the next batch already waiting? */ cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ /* in order for current batch to proceed. */ } state ____cacheline_maxaligned_in_smp; diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index d665d001e030..dc1ac448d07c 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,7 +47,7 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .batch = { .cur = -300, .completed = -300 }, + { .batch = { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }, .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; @@ -124,16 +124,18 @@ static void rcu_start_batch(int next_pending) cpumask_t active; if (next_pending) - rcu_ctrlblk.state.next_pending = 1; + rcu_ctrlblk.batch.next_pending = 1; - if (rcu_ctrlblk.state.next_pending && + if (rcu_ctrlblk.batch.next_pending && rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { - rcu_ctrlblk.state.next_pending = 0; /* Can't change, since spin lock held. */ active = nohz_cpu_mask; cpus_complement(active); cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); + write_seqcount_begin(&rcu_ctrlblk.batch.lock); + rcu_ctrlblk.batch.next_pending = 0; rcu_ctrlblk.batch.cur++; + write_seqcount_end(&rcu_ctrlblk.batch.lock); } } @@ -261,6 +263,8 @@ static void rcu_process_callbacks(unsigned long unused) local_irq_disable(); if (!list_empty(&RCU_nxtlist(cpu)) && list_empty(&RCU_curlist(cpu))) { + int next_pending, seq; + __list_splice(&RCU_nxtlist(cpu), &RCU_curlist(cpu)); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); local_irq_enable(); @@ -268,10 +272,19 @@ static void rcu_process_callbacks(unsigned long unused) /* * start the next batch of callbacks */ - spin_lock(&rcu_ctrlblk.state.mutex); - RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; - rcu_start_batch(1); - spin_unlock(&rcu_ctrlblk.state.mutex); + do { + seq = read_seqcount_begin(&rcu_ctrlblk.batch.lock); + /* determine batch number */ + RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; + next_pending = rcu_ctrlblk.batch.next_pending; + } while (read_seqcount_retry(&rcu_ctrlblk.batch.lock, seq)); + + if (!next_pending) { + /* and start it/schedule start if it's a new batch */ + spin_lock(&rcu_ctrlblk.state.mutex); + rcu_start_batch(1); + spin_unlock(&rcu_ctrlblk.state.mutex); + } } else { local_irq_enable(); } -- cgit v1.2.3 From 72914d307d2ab4630212644a46cf75746d04440d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:55 -0700 Subject: [PATCH] rcu lock update: Code move & cleanup From: Manfred Spraul Step three for reducing cacheline trashing within rcupdate.c: Cleanup and code move from to kernel/rcupdate.c: Remove internal details from the header file. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 27 +++++----------- kernel/rcupdate.c | 81 +++++++++++++++++++++++++++--------------------- 2 files changed, 53 insertions(+), 55 deletions(-) (limited to 'include') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 883fc03ed4ef..967b2d47014b 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -64,24 +64,13 @@ struct rcu_head { -/* Control variables for rcupdate callback mechanism. */ +/* Global control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk { - /* "const" members: only changed when starting/ending a grace period */ - struct { - long cur; /* Current batch number. */ - long completed; /* Number of the last completed batch */ - int next_pending; /* Is the next batch already waiting? */ - seqcount_t lock; /* for atomically reading cur and */ - /* next_pending. Spinlock not used, */ - /* protected by state.mutex */ - } batch ____cacheline_maxaligned_in_smp; - /* remaining members: bookkeeping of the progress of the grace period */ - struct { - spinlock_t mutex; /* Guard this struct */ - cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ - /* in order for current batch to proceed. */ - } state ____cacheline_maxaligned_in_smp; -}; + long cur; /* Current batch number. */ + long completed; /* Number of the last completed batch */ + int next_pending; /* Is the next batch already waiting? */ + seqcount_t lock; /* For atomic reads of cur and next_pending. */ +} ____cacheline_maxaligned_in_smp; /* Is batch a before batch b ? */ static inline int rcu_batch_before(long a, long b) @@ -131,14 +120,14 @@ static inline int rcu_pending(int cpu) * for them has completed. */ if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) + !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) return 1; /* This cpu has no pending entries, but there are new entries */ if (list_empty(&RCU_curlist(cpu)) && !list_empty(&RCU_nxtlist(cpu))) return 1; /* The rcu core waits for a quiescent state from the cpu */ - if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur || RCU_qs_pending(cpu)) + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur || RCU_qs_pending(cpu)) return 1; /* nothing to do */ return 0; diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index dc1ac448d07c..0e13bdbb9fd7 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,8 +47,17 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .batch = { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }, - .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; + { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }; + +/* Bookkeeping of the progress of the grace period */ +struct { + spinlock_t mutex; /* Guard this struct and writes to rcu_ctrlblk */ + cpumask_t rcu_cpu_mask; /* CPUs that need to switch in order */ + /* for current batch to proceed. */ +} rcu_state ____cacheline_maxaligned_in_smp = + {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE }; + + DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; /* Fake initialization required by compiler */ @@ -101,15 +110,15 @@ static void rcu_do_batch(struct list_head *list) * The grace period handling consists out of two steps: * - A new grace period is started. * This is done by rcu_start_batch. The start is not broadcasted to - * all cpus, they must pick this up by comparing rcu_ctrlblk.batch.cur with + * all cpus, they must pick this up by comparing rcu_ctrlblk.cur with * RCU_quiescbatch(cpu). All cpus are recorded in the - * rcu_ctrlblk.state.rcu_cpu_mask bitmap. + * rcu_state.rcu_cpu_mask bitmap. * - All cpus must go through a quiescent state. * Since the start of the grace period is not broadcasted, at least two * calls to rcu_check_quiescent_state are required: * The first call just notices that a new grace period is running. The * following calls check if there was a quiescent state since the beginning - * of the grace period. If so, it updates rcu_ctrlblk.state.rcu_cpu_mask. If + * of the grace period. If so, it updates rcu_state.rcu_cpu_mask. If * the bitmap is empty, then the grace period is completed. * rcu_check_quiescent_state calls rcu_start_batch(0) to start the next grace * period (if necessary). @@ -117,25 +126,25 @@ static void rcu_do_batch(struct list_head *list) /* * Register a new batch of callbacks, and start it up if there is currently no * active batch and the batch to be registered has not already occurred. - * Caller must hold the rcu_ctrlblk.state lock. + * Caller must hold rcu_state.mutex. */ static void rcu_start_batch(int next_pending) { cpumask_t active; if (next_pending) - rcu_ctrlblk.batch.next_pending = 1; + rcu_ctrlblk.next_pending = 1; - if (rcu_ctrlblk.batch.next_pending && - rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { + if (rcu_ctrlblk.next_pending && + rcu_ctrlblk.completed == rcu_ctrlblk.cur) { /* Can't change, since spin lock held. */ active = nohz_cpu_mask; cpus_complement(active); - cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); - write_seqcount_begin(&rcu_ctrlblk.batch.lock); - rcu_ctrlblk.batch.next_pending = 0; - rcu_ctrlblk.batch.cur++; - write_seqcount_end(&rcu_ctrlblk.batch.lock); + cpus_and(rcu_state.rcu_cpu_mask, cpu_online_map, active); + write_seqcount_begin(&rcu_ctrlblk.lock); + rcu_ctrlblk.next_pending = 0; + rcu_ctrlblk.cur++; + write_seqcount_end(&rcu_ctrlblk.lock); } } @@ -146,10 +155,10 @@ static void rcu_start_batch(int next_pending) */ static void cpu_quiet(int cpu) { - cpu_clear(cpu, rcu_ctrlblk.state.rcu_cpu_mask); - if (cpus_empty(rcu_ctrlblk.state.rcu_cpu_mask)) { + cpu_clear(cpu, rcu_state.rcu_cpu_mask); + if (cpus_empty(rcu_state.rcu_cpu_mask)) { /* batch completed ! */ - rcu_ctrlblk.batch.completed = rcu_ctrlblk.batch.cur; + rcu_ctrlblk.completed = rcu_ctrlblk.cur; rcu_start_batch(0); } } @@ -163,11 +172,11 @@ static void rcu_check_quiescent_state(void) { int cpu = smp_processor_id(); - if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur) { + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur) { /* new grace period: record qsctr value. */ RCU_qs_pending(cpu) = 1; RCU_last_qsctr(cpu) = RCU_qsctr(cpu); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.cur; + RCU_quiescbatch(cpu) = rcu_ctrlblk.cur; return; } @@ -187,15 +196,15 @@ static void rcu_check_quiescent_state(void) return; RCU_qs_pending(cpu) = 0; - spin_lock(&rcu_ctrlblk.state.mutex); + spin_lock(&rcu_state.mutex); /* * RCU_quiescbatch/batch.cur and the cpu bitmap can come out of sync * during cpu startup. Ignore the quiescent state. */ - if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.batch.cur)) + if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.cur)) cpu_quiet(cpu); - spin_unlock(&rcu_ctrlblk.state.mutex); + spin_unlock(&rcu_state.mutex); } @@ -225,11 +234,11 @@ static void rcu_offline_cpu(int cpu) * we can block indefinitely waiting for it, so flush * it here */ - spin_lock_bh(&rcu_ctrlblk.state.mutex); - if (rcu_ctrlblk.batch.cur != rcu_ctrlblk.batch.completed) + spin_lock_bh(&rcu_state.mutex); + if (rcu_ctrlblk.cur != rcu_ctrlblk.completed) cpu_quiet(cpu); unlock: - spin_unlock_bh(&rcu_ctrlblk.state.mutex); + spin_unlock_bh(&rcu_state.mutex); rcu_move_batch(&RCU_curlist(cpu)); rcu_move_batch(&RCU_nxtlist(cpu)); @@ -241,10 +250,10 @@ unlock: void rcu_restart_cpu(int cpu) { - spin_lock_bh(&rcu_ctrlblk.state.mutex); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + spin_lock_bh(&rcu_state.mutex); + RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; - spin_unlock_bh(&rcu_ctrlblk.state.mutex); + spin_unlock_bh(&rcu_state.mutex); } /* @@ -256,7 +265,7 @@ static void rcu_process_callbacks(unsigned long unused) LIST_HEAD(list); if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) { + !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) { __list_splice(&RCU_curlist(cpu), &list); INIT_LIST_HEAD(&RCU_curlist(cpu)); } @@ -273,17 +282,17 @@ static void rcu_process_callbacks(unsigned long unused) * start the next batch of callbacks */ do { - seq = read_seqcount_begin(&rcu_ctrlblk.batch.lock); + seq = read_seqcount_begin(&rcu_ctrlblk.lock); /* determine batch number */ - RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; - next_pending = rcu_ctrlblk.batch.next_pending; - } while (read_seqcount_retry(&rcu_ctrlblk.batch.lock, seq)); + RCU_batch(cpu) = rcu_ctrlblk.cur + 1; + next_pending = rcu_ctrlblk.next_pending; + } while (read_seqcount_retry(&rcu_ctrlblk.lock, seq)); if (!next_pending) { /* and start it/schedule start if it's a new batch */ - spin_lock(&rcu_ctrlblk.state.mutex); + spin_lock(&rcu_state.mutex); rcu_start_batch(1); - spin_unlock(&rcu_ctrlblk.state.mutex); + spin_unlock(&rcu_state.mutex); } } else { local_irq_enable(); @@ -308,7 +317,7 @@ static void __devinit rcu_online_cpu(int cpu) tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); INIT_LIST_HEAD(&RCU_curlist(cpu)); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; } -- cgit v1.2.3 From b659a6fbb927a79acd606c4466d03cb615879f9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:06 -0700 Subject: [PATCH] reduce rcu_head size - core From: Dipankar Sarma This reduces the RCU head size by using a singly linked to maintain them. The ordering of the callbacks is still maintained as before by using a tail pointer for the next list. Signed-Off-By : Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 24 +++++++++++++----------- kernel/rcupdate.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 967b2d47014b..8fafbdf06866 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -36,7 +36,6 @@ #ifdef __KERNEL__ #include -#include #include #include #include @@ -45,21 +44,20 @@ /** * struct rcu_head - callback structure for use with RCU - * @list: list_head to queue the update requests + * @next: next update requests in a list * @func: actual update function to call after the grace period. * @arg: argument to be passed to the actual update function. */ struct rcu_head { - struct list_head list; + struct rcu_head *next; void (*func)(void *obj); void *arg; }; -#define RCU_HEAD_INIT(head) \ - { .list = LIST_HEAD_INIT(head.list), .func = NULL, .arg = NULL } +#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL, .arg = NULL } #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) #define INIT_RCU_HEAD(ptr) do { \ - INIT_LIST_HEAD(&(ptr)->list); (ptr)->func = NULL; (ptr)->arg = NULL; \ + (ptr)->next = NULL; (ptr)->func = NULL; (ptr)->arg = NULL; \ } while (0) @@ -99,8 +97,9 @@ struct rcu_data { /* 2) batch handling */ long batch; /* Batch # for current RCU batch */ - struct list_head nxtlist; - struct list_head curlist; + struct rcu_head *nxtlist; + struct rcu_head **nxttail; + struct rcu_head *curlist; }; DECLARE_PER_CPU(struct rcu_data, rcu_data); @@ -113,22 +112,25 @@ extern struct rcu_ctrlblk rcu_ctrlblk; #define RCU_batch(cpu) (per_cpu(rcu_data, (cpu)).batch) #define RCU_nxtlist(cpu) (per_cpu(rcu_data, (cpu)).nxtlist) #define RCU_curlist(cpu) (per_cpu(rcu_data, (cpu)).curlist) +#define RCU_nxttail(cpu) (per_cpu(rcu_data, (cpu)).nxttail) static inline int rcu_pending(int cpu) { /* This cpu has pending rcu entries and the grace period * for them has completed. */ - if (!list_empty(&RCU_curlist(cpu)) && + if (RCU_curlist(cpu) && !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) return 1; + /* This cpu has no pending entries, but there are new entries */ - if (list_empty(&RCU_curlist(cpu)) && - !list_empty(&RCU_nxtlist(cpu))) + if (!RCU_curlist(cpu) && RCU_nxtlist(cpu)) return 1; + /* The rcu core waits for a quiescent state from the cpu */ if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur || RCU_qs_pending(cpu)) return 1; + /* nothing to do */ return 0; } diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 0e13bdbb9fd7..cdb59f12a5fa 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -82,9 +82,11 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg head->func = func; head->arg = arg; + head->next = NULL; local_irq_save(flags); cpu = smp_processor_id(); - list_add_tail(&head->list, &RCU_nxtlist(cpu)); + *RCU_nxttail(cpu) = head; + RCU_nxttail(cpu) = &head->next; local_irq_restore(flags); } @@ -92,16 +94,14 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg * Invoke the completed RCU callbacks. They are expected to be in * a per-cpu list. */ -static void rcu_do_batch(struct list_head *list) +static void rcu_do_batch(struct rcu_head *list) { - struct list_head *entry; - struct rcu_head *head; + struct rcu_head *next; - while (!list_empty(list)) { - entry = list->next; - list_del(entry); - head = list_entry(entry, struct rcu_head, list); - head->func(head->arg); + while (list) { + next = list->next; + list->func(list->arg); + list = next; } } @@ -262,20 +262,21 @@ void rcu_restart_cpu(int cpu) static void rcu_process_callbacks(unsigned long unused) { int cpu = smp_processor_id(); - LIST_HEAD(list); + struct rcu_head *rcu_list = NULL; - if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) { - __list_splice(&RCU_curlist(cpu), &list); - INIT_LIST_HEAD(&RCU_curlist(cpu)); + if (RCU_curlist(cpu) && + !rcu_batch_before(rcu_ctrlblk.completed, RCU_batch(cpu))) { + rcu_list = RCU_curlist(cpu); + RCU_curlist(cpu) = NULL; } local_irq_disable(); - if (!list_empty(&RCU_nxtlist(cpu)) && list_empty(&RCU_curlist(cpu))) { + if (RCU_nxtlist(cpu) && !RCU_curlist(cpu)) { int next_pending, seq; - __list_splice(&RCU_nxtlist(cpu), &RCU_curlist(cpu)); - INIT_LIST_HEAD(&RCU_nxtlist(cpu)); + RCU_curlist(cpu) = RCU_nxtlist(cpu); + RCU_nxtlist(cpu) = NULL; + RCU_nxttail(cpu) = &RCU_nxtlist(cpu); local_irq_enable(); /* @@ -298,8 +299,8 @@ static void rcu_process_callbacks(unsigned long unused) local_irq_enable(); } rcu_check_quiescent_state(); - if (!list_empty(&list)) - rcu_do_batch(&list); + if (rcu_list) + rcu_do_batch(rcu_list); } void rcu_check_callbacks(int cpu, int user) @@ -315,8 +316,7 @@ static void __devinit rcu_online_cpu(int cpu) { memset(&per_cpu(rcu_data, cpu), 0, sizeof(struct rcu_data)); tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); - INIT_LIST_HEAD(&RCU_nxtlist(cpu)); - INIT_LIST_HEAD(&RCU_curlist(cpu)); + RCU_nxttail(cpu) = &RCU_nxtlist(cpu); RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; } -- cgit v1.2.3 From 8c1ce9d6d628945ff23f844dbe9f21f5d5383b99 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:18 -0700 Subject: [PATCH] rcu: avoid passing an argument to the callback function From: Dipankar Sarma This patch changes the call_rcu() API and avoids passing an argument to the callback function as suggested by Rusty. Instead, it is assumed that the user has embedded the rcu head into a structure that is useful in the callback and the rcu_head pointer is passed to the callback. The callback can use container_of() to get the pointer to its structure and work with it. Together with the rcu-singly-link patch, it reduces the rcu_head size by 50%. Considering that we use these in things like struct dentry and struct dst_entry, this is good savings in space. An example : struct my_struct { struct rcu_head rcu; int x; int y; }; void my_rcu_callback(struct rcu_head *head) { struct my_struct *p = container_of(head, struct my_struct, rcu); free(p); } void my_delete(struct my_struct *p) { ... call_rcu(&p->rcu, my_rcu_callback); ... } Signed-Off-By: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/mm/tlb.c | 7 ++++--- fs/dcache.c | 6 +++--- include/linux/rcupdate.h | 10 ++++------ include/net/dst.h | 6 ++++++ ipc/util.c | 25 ++++++++++++++++++++----- kernel/auditsc.c | 7 ++++--- kernel/rcupdate.c | 26 ++++++++++++++++---------- net/bridge/br_if.c | 12 +++++++++--- net/decnet/dn_route.c | 4 ++-- net/ipv4/route.c | 4 ++-- net/sched/sch_generic.c | 6 +++--- security/selinux/netif.c | 6 +++--- 12 files changed, 76 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index 980443bebed1..8825e14cb35a 100644 --- a/arch/ppc64/mm/tlb.c +++ b/arch/ppc64/mm/tlb.c @@ -158,9 +158,10 @@ void pte_free_now(struct page *ptepage) pte_free(ptepage); } -static void pte_free_rcu_callback(void *arg) +static void pte_free_rcu_callback(struct rcu_head *head) { - struct pte_freelist_batch *batch = arg; + struct pte_freelist_batch *batch = + container_of(head, struct pte_freelist_batch, rcu); unsigned int i; for (i = 0; i < batch->index; i++) @@ -171,7 +172,7 @@ static void pte_free_rcu_callback(void *arg) void pte_free_submit(struct pte_freelist_batch *batch) { INIT_RCU_HEAD(&batch->rcu); - call_rcu(&batch->rcu, pte_free_rcu_callback, batch); + call_rcu(&batch->rcu, pte_free_rcu_callback); } void pte_free_finish(void) diff --git a/fs/dcache.c b/fs/dcache.c index 4c632e1261dc..02df5d45b82e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -65,9 +65,9 @@ struct dentry_stat_t dentry_stat = { .age_limit = 45, }; -static void d_callback(void *arg) +static void d_callback(struct rcu_head *head) { - struct dentry * dentry = (struct dentry *)arg; + struct dentry * dentry = container_of(head, struct dentry, d_rcu); if (dname_external(dentry)) kfree(dentry->d_name.name); @@ -82,7 +82,7 @@ static void d_free(struct dentry *dentry) { if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - call_rcu(&dentry->d_rcu, d_callback, dentry); + call_rcu(&dentry->d_rcu, d_callback); } /* diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 8fafbdf06866..10c4b8f24f08 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -46,18 +46,16 @@ * struct rcu_head - callback structure for use with RCU * @next: next update requests in a list * @func: actual update function to call after the grace period. - * @arg: argument to be passed to the actual update function. */ struct rcu_head { struct rcu_head *next; - void (*func)(void *obj); - void *arg; + void (*func)(struct rcu_head *head); }; -#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL, .arg = NULL } +#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL } #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) #define INIT_RCU_HEAD(ptr) do { \ - (ptr)->next = NULL; (ptr)->func = NULL; (ptr)->arg = NULL; \ + (ptr)->next = NULL; (ptr)->func = NULL; \ } while (0) @@ -144,7 +142,7 @@ extern void rcu_restart_cpu(int cpu); /* Exported interfaces */ extern void FASTCALL(call_rcu(struct rcu_head *head, - void (*func)(void *arg), void *arg)); + void (*func)(struct rcu_head *head))); extern void synchronize_kernel(void); #endif /* __KERNEL__ */ diff --git a/include/net/dst.h b/include/net/dst.h index ed2504c6b4e9..543ff945bb2f 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -183,6 +183,12 @@ static inline void dst_free(struct dst_entry * dst) __dst_free(dst); } +static inline void dst_rcu_free(struct rcu_head *head) +{ + struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head); + dst_free(dst); +} + static inline void dst_confirm(struct dst_entry *dst) { if (dst) diff --git a/ipc/util.c b/ipc/util.c index 81a145eded63..727c33233f5f 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -333,25 +333,40 @@ void* ipc_rcu_alloc(int size) * Since RCU callback function is called in bh, * we need to defer the vfree to schedule_work */ -static void ipc_schedule_free(void* arg) +static void ipc_schedule_free(struct rcu_head *head) { - struct ipc_rcu_vmalloc *free = arg; + struct ipc_rcu_vmalloc *free = + container_of(head, struct ipc_rcu_vmalloc, rcu); INIT_WORK(&free->work, vfree, free); schedule_work(&free->work); } +/** + * ipc_immediate_free - free ipc + rcu space + * + * Free from the RCU callback context + * + */ +static void ipc_immediate_free(struct rcu_head *head) +{ + struct ipc_rcu_kmalloc *free = + container_of(head, struct ipc_rcu_kmalloc, rcu); + kfree(free); +} + + + void ipc_rcu_free(void* ptr, int size) { if (rcu_use_vmalloc(size)) { struct ipc_rcu_vmalloc *free; free = ptr - sizeof(*free); - call_rcu(&free->rcu, ipc_schedule_free, free); + call_rcu(&free->rcu, ipc_schedule_free); } else { struct ipc_rcu_kmalloc *free; free = ptr - sizeof(*free); - /* kfree takes a "const void *" so gcc warns. So we cast. */ - call_rcu(&free->rcu, (void (*)(void *))kfree, free); + call_rcu(&free->rcu, ipc_immediate_free); } } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 342b57141fd9..e688c73f6a9e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -177,9 +177,10 @@ static inline int audit_add_rule(struct audit_entry *entry, return 0; } -static void audit_free_rule(void *arg) +static void audit_free_rule(struct rcu_head *head) { - kfree(arg); + struct audit_entry *e = container_of(head, struct audit_entry, rcu); + kfree(e); } /* Note that audit_add_rule and audit_del_rule are called via @@ -195,7 +196,7 @@ static inline int audit_del_rule(struct audit_rule *rule, list_for_each_entry(e, list, list) { if (!audit_compare_rule(rule, &e->rule)) { list_del_rcu(&e->list); - call_rcu(&e->rcu, audit_free_rule, e); + call_rcu(&e->rcu, audit_free_rule); return 0; } } diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index cdb59f12a5fa..7282889a5fd9 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -68,20 +68,19 @@ static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; * call_rcu - Queue an RCU update request. * @head: structure to be used for queueing the RCU updates. * @func: actual update function to be invoked after the grace period - * @arg: argument to be passed to the update function * * The update function will be invoked as soon as all CPUs have performed * a context switch or been seen in the idle loop or in a user process. * The read-side of critical section that use call_rcu() for updation must * be protected by rcu_read_lock()/rcu_read_unlock(). */ -void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg) +void fastcall call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *rcu)) { int cpu; unsigned long flags; head->func = func; - head->arg = arg; head->next = NULL; local_irq_save(flags); cpu = smp_processor_id(); @@ -100,7 +99,7 @@ static void rcu_do_batch(struct rcu_head *list) while (list) { next = list->next; - list->func(list->arg); + list->func(list); list = next; } } @@ -358,11 +357,18 @@ void __init rcu_init(void) register_cpu_notifier(&rcu_nb); } +struct rcu_synchronize { + struct rcu_head head; + struct completion completion; +}; /* Because of FASTCALL declaration of complete, we use this wrapper */ -static void wakeme_after_rcu(void *completion) +static void wakeme_after_rcu(struct rcu_head *head) { - complete(completion); + struct rcu_synchronize *rcu; + + rcu = container_of(head, struct rcu_synchronize, head); + complete(&rcu->completion); } /** @@ -371,14 +377,14 @@ static void wakeme_after_rcu(void *completion) */ void synchronize_kernel(void) { - struct rcu_head rcu; - DECLARE_COMPLETION(completion); + struct rcu_synchronize rcu; + init_completion(&rcu.completion); /* Will wake me after RCU finished */ - call_rcu(&rcu, wakeme_after_rcu, &completion); + call_rcu(&rcu.head, wakeme_after_rcu); /* Wait for it */ - wait_for_completion(&completion); + wait_for_completion(&rcu.completion); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 20275604941a..6bb2ed24718f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -75,9 +75,8 @@ static int br_initial_port_cost(struct net_device *dev) return 100; /* assume old 10Mbps */ } -static void destroy_nbp(void *arg) +static void destroy_nbp(struct net_bridge_port *p) { - struct net_bridge_port *p = arg; struct net_device *dev = p->dev; dev->br_port = NULL; @@ -88,6 +87,13 @@ static void destroy_nbp(void *arg) br_sysfs_freeif(p); } +static void destroy_nbp_rcu(struct rcu_head *head) +{ + struct net_bridge_port *p = + container_of(head, struct net_bridge_port, rcu); + destroy_nbp(p); +} + /* called with RTNL */ static void del_nbp(struct net_bridge_port *p) { @@ -108,7 +114,7 @@ static void del_nbp(struct net_bridge_port *p) del_timer_sync(&p->forward_delay_timer); del_timer_sync(&p->hold_timer); - call_rcu(&p->rcu, destroy_nbp, p); + call_rcu(&p->rcu, destroy_nbp_rcu); } /* called with RTNL */ diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 90d0583f56f4..c181467ddca3 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -146,14 +146,14 @@ static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst) static inline void dnrt_free(struct dn_route *rt) { - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static inline void dnrt_drop(struct dn_route *rt) { if (rt) dst_release(&rt->u.dst); - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static void dn_dst_check_expire(unsigned long dummy) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a570e709f738..46aeef6fa4e1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -439,13 +439,13 @@ static struct file_operations rt_cpu_seq_fops = { static __inline__ void rt_free(struct rtable *rt) { - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static __inline__ void rt_drop(struct rtable *rt) { ip_rt_put(rt); - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static __inline__ int rt_fast_clean(struct rtable *rth) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 111dad476d2b..db8cab2cf1d5 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -411,9 +411,9 @@ void qdisc_reset(struct Qdisc *qdisc) /* this is the rcu callback function to clean up a qdisc when there * are no further references to it */ -static void __qdisc_destroy (void * arg) +static void __qdisc_destroy(struct rcu_head *head) { - struct Qdisc *qdisc = (struct Qdisc *) arg; + struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu); struct Qdisc_ops *ops = qdisc->ops; #ifdef CONFIG_NET_ESTIMATOR @@ -448,7 +448,7 @@ void qdisc_destroy(struct Qdisc *qdisc) } } - call_rcu(&qdisc->q_rcu, __qdisc_destroy, qdisc); + call_rcu(&qdisc->q_rcu, __qdisc_destroy); } diff --git a/security/selinux/netif.c b/security/selinux/netif.c index 4cbf8f259d93..d23bd7e6345e 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -134,9 +134,9 @@ out: return netif; } -static void sel_netif_free(void *p) +static void sel_netif_free(struct rcu_head *p) { - struct sel_netif *netif = p; + struct sel_netif *netif = container_of(p, struct sel_netif, rcu_head); DEBUGP("%s: %s\n", __FUNCTION__, netif->nsec.dev->name); kfree(netif); @@ -151,7 +151,7 @@ static void sel_netif_destroy(struct sel_netif *netif) sel_netif_total--; spin_unlock_bh(&sel_netif_lock); - call_rcu(&netif->rcu_head, sel_netif_free, netif); + call_rcu(&netif->rcu_head, sel_netif_free); } void sel_netif_put(struct sel_netif *netif) -- cgit v1.2.3 From d2cec97bc421d6f9c2ee0d9bd8e0ce47d0022cac Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:29 -0700 Subject: [PATCH] cpumask: make cpu_present_map real even on non-smp From: Paul Jackson This patch makes cpu_present_map a real map for all configurations, instead of a constant for non-SMP. It also moves the definition of cpu_present_map out of kernel/cpu.c into kernel/sched.c, because cpu.c isn't compiled into non-SMP kernels. The pattern is that each of the possible, present and online cpu maps are actual kernel global cpumask_t variables, for all configurations. They are documented in include/linux/cpumask.h. Some of the UP (NR_CPUS=1) code cheats, and hardcodes the assumption that the single bit position of these maps is always set, as an optimization. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 13 +++++-------- kernel/cpu.c | 8 -------- kernel/sched.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 4293a465d87b..dced3ec2b0c8 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -10,15 +10,12 @@ extern cpumask_t cpu_online_map; extern cpumask_t cpu_possible_map; -extern cpumask_t cpu_present_map; #define num_online_cpus() cpus_weight(cpu_online_map) #define num_possible_cpus() cpus_weight(cpu_possible_map) -#define num_present_cpus() cpus_weight(cpu_present_map) #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) -#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) #define for_each_cpu_mask(cpu, mask) \ for (cpu = first_cpu_const(mk_cpumask_const(mask)); \ @@ -27,26 +24,26 @@ extern cpumask_t cpu_present_map; #define for_each_cpu(cpu) for_each_cpu_mask(cpu, cpu_possible_map) #define for_each_online_cpu(cpu) for_each_cpu_mask(cpu, cpu_online_map) -#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) #else #define cpu_online_map cpumask_of_cpu(0) #define cpu_possible_map cpumask_of_cpu(0) -#define cpu_present_map cpumask_of_cpu(0) #define num_online_cpus() 1 #define num_possible_cpus() 1 -#define num_present_cpus() 1 #define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define cpu_present(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++) #define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) -#define for_each_present_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #endif +extern cpumask_t cpu_present_map; +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) +#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) + #define cpumask_scnprintf(buf, buflen, map) \ bitmap_scnprintf(buf, buflen, cpus_addr(map), NR_CPUS) diff --git a/kernel/cpu.c b/kernel/cpu.c index 72b984c67eb3..083521327e64 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -20,14 +20,6 @@ DECLARE_MUTEX(cpucontrol); static struct notifier_block *cpu_chain; -/* - * Represents all cpu's present in the system - * In systems capable of hotplug, this map could dynamically grow - * as new cpu's are detected in the system via any platform specific - * method, such as ACPI for e.g. - */ -cpumask_t cpu_present_map; -EXPORT_SYMBOL(cpu_present_map); /* Need to know about CPUs going up/down? */ int register_cpu_notifier(struct notifier_block *nb) diff --git a/kernel/sched.c b/kernel/sched.c index 8f49ba1202c3..a614d7ebf7c3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2941,6 +2941,16 @@ out_unlock: return retval; } +/* + * Represents all cpu's present in the system + * In systems capable of hotplug, this map could dynamically grow + * as new cpu's are detected in the system via any platform specific + * method, such as ACPI for e.g. + */ + +cpumask_t cpu_present_map; +EXPORT_SYMBOL(cpu_present_map); + /** * sys_sched_getaffinity - get the cpu affinity of a process * @pid: pid of the process -- cgit v1.2.3 From ea0c19290646e6bb7cd3657db83eac3a0d641418 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:40 -0700 Subject: [PATCH] cpumask: bitmap cleanup preparation for cpumask overhaul From: Paul Jackson Document the bitmap bit model and handling of unused bits. Tighten up bitmap so it does not generate nonzero bits in the unused tail if it is not given any on input. Add intersects, subset, xor and andnot operators. Change bitmap_complement to take two operands. Add a couple of missing 'const' qualifiers on bitops test_bit and bitmap_equal args. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/smpboot.c | 2 +- include/asm-generic/bitops.h | 2 +- include/asm-generic/cpumask_array.h | 2 +- include/asm-i386/mpspec.h | 2 +- include/asm-x86_64/mpspec.h | 2 +- include/linux/bitmap.h | 12 ++++- lib/bitmap.c | 87 ++++++++++++++++++++++++++++++++++--- mm/mempolicy.c | 14 +++--- 8 files changed, 102 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index ba2cba68da14..06937402b31c 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -827,7 +827,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) if (apicid == boot_cpu_id || (apicid == BAD_APICID)) continue; - if (!cpu_isset(apicid, phys_cpu_present_map)) + if (!physid_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h index 23ac5227b702..ce31b739fd80 100644 --- a/include/asm-generic/bitops.h +++ b/include/asm-generic/bitops.h @@ -42,7 +42,7 @@ extern __inline__ int clear_bit(int nr, long * addr) return retval; } -extern __inline__ int test_bit(int nr, long * addr) +extern __inline__ int test_bit(int nr, const unsigned long * addr) { int mask; diff --git a/include/asm-generic/cpumask_array.h b/include/asm-generic/cpumask_array.h index ddd6e1185dba..1be08ae2e93b 100644 --- a/include/asm-generic/cpumask_array.h +++ b/include/asm-generic/cpumask_array.h @@ -17,7 +17,7 @@ #define cpus_and(dst,src1,src2) bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS) #define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) #define cpus_clear(map) bitmap_zero((map).mask, NR_CPUS) -#define cpus_complement(map) bitmap_complement((map).mask, NR_CPUS) +#define cpus_complement(map) bitmap_complement((map).mask, (map).mask, NR_CPUS) #define cpus_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, NR_CPUS) #define cpus_empty(map) bitmap_empty(map.mask, NR_CPUS) #define cpus_addr(map) ((map).mask) diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index b2cc2feeb8a4..31a9717c1a8b 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h @@ -53,7 +53,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h index fd707a6a8bcd..a9a6f16672f2 100644 --- a/include/asm-x86_64/mpspec.h +++ b/include/asm-x86_64/mpspec.h @@ -212,7 +212,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index c301d121c8d0..bc93e0167a81 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -13,8 +13,8 @@ int bitmap_empty(const unsigned long *bitmap, int bits); int bitmap_full(const unsigned long *bitmap, int bits); int bitmap_equal(const unsigned long *bitmap1, - unsigned long *bitmap2, int bits); -void bitmap_complement(unsigned long *bitmap, int bits); + const unsigned long *bitmap2, int bits); +void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits); static inline void bitmap_zero(unsigned long *bitmap, int bits) { @@ -41,6 +41,14 @@ void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); +void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +int bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +int bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); int bitmap_weight(const unsigned long *bitmap, int bits); int bitmap_scnprintf(char *buf, unsigned int buflen, const unsigned long *maskp, int bits); diff --git a/lib/bitmap.c b/lib/bitmap.c index 779d30365e46..a96433e37102 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -12,6 +12,26 @@ #include #include +/* + * bitmaps provide an array of bits, implemented using an an + * array of unsigned longs. The number of valid bits in a + * given bitmap need not be an exact multiple of BITS_PER_LONG. + * + * The possible unused bits in the last, partially used word + * of a bitmap are 'don't care'. The implementation makes + * no particular effort to keep them zero. It ensures that + * their value will not affect the results of any operation. + * The bitmap operations that return Boolean (bitmap_empty, + * for example) or scalar (bitmap_weight, for example) results + * carefully filter out these unused bits from impacting their + * results. + * + * These operations actually hold to a slightly stronger rule: + * if you don't input any bitmaps to these ops that have some + * unused bits set, then they won't output any set unused bits + * in output bitmaps. + */ + int bitmap_empty(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -43,7 +63,7 @@ int bitmap_full(const unsigned long *bitmap, int bits) EXPORT_SYMBOL(bitmap_full); int bitmap_equal(const unsigned long *bitmap1, - unsigned long *bitmap2, int bits) + const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -59,13 +79,14 @@ int bitmap_equal(const unsigned long *bitmap1, } EXPORT_SYMBOL(bitmap_equal); -void bitmap_complement(unsigned long *bitmap, int bits) +void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) { - int k; - int nr = BITS_TO_LONGS(bits); + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + dst[k] = ~src[k]; - for (k = 0; k < nr; ++k) - bitmap[k] = ~bitmap[k]; + if (bits % BITS_PER_LONG) + dst[k] = ~src[k] & ((1UL << (bits % BITS_PER_LONG)) - 1); } EXPORT_SYMBOL(bitmap_complement); @@ -173,6 +194,60 @@ void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, } EXPORT_SYMBOL(bitmap_or); +void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] ^ bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_xor); + +void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] & ~bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_andnot); + +int bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap1[k] & bitmap2[k]) + return 1; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] & bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 1; + return 0; +} +EXPORT_SYMBOL(bitmap_intersects); + +int bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap1[k] & ~bitmap2[k]) + return 0; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] & ~bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + return 1; +} +EXPORT_SYMBOL(bitmap_subset); + #if BITS_PER_LONG == 32 int bitmap_weight(const unsigned long *bitmap, int bits) { diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4f1fc840550a..d06eabbf74f0 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -93,14 +93,12 @@ static struct mempolicy default_policy = { /* Check if all specified nodes are online */ static int nodes_online(unsigned long *nodes) { - DECLARE_BITMAP(offline, MAX_NUMNODES); - - bitmap_copy(offline, node_online_map, MAX_NUMNODES); - if (bitmap_empty(offline, MAX_NUMNODES)) - set_bit(0, offline); - bitmap_complement(offline, MAX_NUMNODES); - bitmap_and(offline, offline, nodes, MAX_NUMNODES); - if (!bitmap_empty(offline, MAX_NUMNODES)) + DECLARE_BITMAP(online2, MAX_NUMNODES); + + bitmap_copy(online2, node_online_map, MAX_NUMNODES); + if (bitmap_empty(online2, MAX_NUMNODES)) + set_bit(0, online2); + if (!bitmap_subset(nodes, online2, MAX_NUMNODES)) return -EINVAL; return 0; } -- cgit v1.2.3 From d6cf71d3086ea9be652ac95616cd111157fdd4c5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:51 -0700 Subject: [PATCH] cpumask: bitmap inlining and optimizations From: Paul Jackson These bitmap improvements make it a suitable basis for fully supporting cpumask_t and nodemask_t. Inline macros with compile-time checks enable generating tight code on both small and large systems (large meaning cpumask_t requires more than one unsigned long's worth of bits). The existing bitmap_ macros in lib/bitmap.c are renamed to __bitmap_, and wrappers for each bitmap_ are exposed in include/linux/bitmap.h This patch _includes_ Bill Irwins rewrite of the bitmap_shift operators to not require a fixed length intermediate bitmap. Improved comments list each available operator for easy browsing. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bitmap.h | 264 ++++++++++++++++++++++++++++++++++++++++++------- lib/bitmap.c | 91 ++++++++--------- 2 files changed, 275 insertions(+), 80 deletions(-) (limited to 'include') diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index bc93e0167a81..9dadd08e2b53 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -3,57 +3,249 @@ #ifndef __ASSEMBLY__ -#include -#include #include -#include #include #include -int bitmap_empty(const unsigned long *bitmap, int bits); -int bitmap_full(const unsigned long *bitmap, int bits); -int bitmap_equal(const unsigned long *bitmap1, +/* + * bitmaps provide bit arrays that consume one or more unsigned + * longs. The bitmap interface and available operations are listed + * here, in bitmap.h + * + * Function implementations generic to all architectures are in + * lib/bitmap.c. Functions implementations that are architecture + * specific are in various include/asm-/bitops.h headers + * and other arch/ specific files. + * + * See lib/bitmap.c for more details. + */ + +/* + * The available bitmap operations and their rough meaning in the + * case that the bitmap is a single unsigned long are thus: + * + * bitmap_zero(dst, nbits) *dst = 0UL + * bitmap_fill(dst, nbits) *dst = ~0UL + * bitmap_copy(dst, src, nbits) *dst = *src + * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 + * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 + * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 + * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) + * bitmap_complement(dst, src, nbits) *dst = ~(*src) + * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? + * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? + * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? + * bitmap_empty(src, nbits) Are all bits zero in *src? + * bitmap_full(src, nbits) Are all bits set in *src? + * bitmap_weight(src, nbits) Hamming Weight: number set bits + * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n + * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n + * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf + * bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from buf + */ + +/* + * Also the following operations in asm/bitops.h apply to bitmaps. + * + * set_bit(bit, addr) *addr |= bit + * clear_bit(bit, addr) *addr &= ~bit + * change_bit(bit, addr) *addr ^= bit + * test_bit(bit, addr) Is bit set in *addr? + * test_and_set_bit(bit, addr) Set bit and return old value + * test_and_clear_bit(bit, addr) Clear bit and return old value + * test_and_change_bit(bit, addr) Change bit and return old value + * find_first_zero_bit(addr, nbits) Position first zero bit in *addr + * find_first_bit(addr, nbits) Position first set bit in *addr + * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit + * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit + */ + +/* + * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used + * to declare an array named 'name' of just enough unsigned longs to + * contain all bit positions from 0 to 'bits' - 1. + */ + +/* + * lib/bitmap.c provides these functions: + */ + +extern int __bitmap_empty(const unsigned long *bitmap, int bits); +extern int __bitmap_full(const unsigned long *bitmap, int bits); +extern int __bitmap_equal(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_complement(unsigned long *dst, const unsigned long *src, + int bits); +extern void __bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int shift, int bits); +extern void __bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits); +extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); -void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits); +extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_weight(const unsigned long *bitmap, int bits); + +extern int bitmap_scnprintf(char *buf, unsigned int len, + const unsigned long *src, int nbits); +extern int bitmap_parse(const char __user *ubuf, unsigned int ulen, + unsigned long *dst, int nbits); -static inline void bitmap_zero(unsigned long *bitmap, int bits) +#define BITMAP_LAST_WORD_MASK(nbits) \ +( \ + ((nbits) % BITS_PER_LONG) ? \ + (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ +) + +static inline void bitmap_zero(unsigned long *dst, int nbits) { - memset(bitmap, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long)); + if (nbits <= BITS_PER_LONG) + *dst = 0UL; + else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); + } } -static inline void bitmap_fill(unsigned long *bitmap, int bits) +static inline void bitmap_fill(unsigned long *dst, int nbits) { - memset(bitmap, 0xff, BITS_TO_LONGS(bits)*sizeof(unsigned long)); + size_t nlongs = BITS_TO_LONGS(nbits); + if (nlongs > 1) { + int len = (nlongs - 1) * sizeof(unsigned long); + memset(dst, 0xff, len); + } + dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); } -static inline void bitmap_copy(unsigned long *dst, - const unsigned long *src, int bits) +static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, + int nbits) { - int len = BITS_TO_LONGS(bits)*sizeof(unsigned long); - memcpy(dst, src, len); + if (nbits <= BITS_PER_LONG) + *dst = *src; + else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memcpy(dst, src, len); + } } -void bitmap_shift_right(unsigned long *dst, - const unsigned long *src, int shift, int bits); -void bitmap_shift_left(unsigned long *dst, - const unsigned long *src, int shift, int bits); -void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_intersects(const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_subset(const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_weight(const unsigned long *bitmap, int bits); -int bitmap_scnprintf(char *buf, unsigned int buflen, - const unsigned long *maskp, int bits); -int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, - unsigned long *maskp, int bits); +static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 & *src2; + else + __bitmap_and(dst, src1, src2, nbits); +} + +static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 | *src2; + else + __bitmap_or(dst, src1, src2, nbits); +} + +static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 ^ *src2; + else + __bitmap_xor(dst, src1, src2, nbits); +} + +static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 & ~(*src2); + else + __bitmap_andnot(dst, src1, src2, nbits); +} + +static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, + int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); + else + __bitmap_complement(dst, src, nbits); +} + +static inline int bitmap_equal(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_equal(src1, src2, nbits); +} + +static inline int bitmap_intersects(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; + else + return __bitmap_intersects(src1, src2, nbits); +} + +static inline int bitmap_subset(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_subset(src1, src2, nbits); +} + +static inline int bitmap_empty(const unsigned long *src, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_empty(src, nbits); +} + +static inline int bitmap_full(const unsigned long *src, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_full(src, nbits); +} + +static inline int bitmap_weight(const unsigned long *src, int nbits) +{ + return __bitmap_weight(src, nbits); +} + +static inline void bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int n, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src >> n; + else + __bitmap_shift_right(dst, src, n, nbits); +} + +static inline void bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int n, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); + else + __bitmap_shift_left(dst, src, n, nbits); +} #endif /* __ASSEMBLY__ */ diff --git a/lib/bitmap.c b/lib/bitmap.c index a96433e37102..7eb16be309b5 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -15,7 +15,8 @@ /* * bitmaps provide an array of bits, implemented using an an * array of unsigned longs. The number of valid bits in a - * given bitmap need not be an exact multiple of BITS_PER_LONG. + * given bitmap does _not_ need to be an exact multiple of + * BITS_PER_LONG. * * The possible unused bits in the last, partially used word * of a bitmap are 'don't care'. The implementation makes @@ -30,9 +31,14 @@ * if you don't input any bitmaps to these ops that have some * unused bits set, then they won't output any set unused bits * in output bitmaps. + * + * The byte ordering of bitmaps is more natural on little + * endian architectures. See the big-endian headers + * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h + * for the best explanations of this ordering. */ -int bitmap_empty(const unsigned long *bitmap, int bits) +int __bitmap_empty(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -40,14 +46,14 @@ int bitmap_empty(const unsigned long *bitmap, int bits) return 0; if (bits % BITS_PER_LONG) - if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_empty); +EXPORT_SYMBOL(__bitmap_empty); -int bitmap_full(const unsigned long *bitmap, int bits) +int __bitmap_full(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -55,14 +61,14 @@ int bitmap_full(const unsigned long *bitmap, int bits) return 0; if (bits % BITS_PER_LONG) - if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_full); +EXPORT_SYMBOL(__bitmap_full); -int bitmap_equal(const unsigned long *bitmap1, +int __bitmap_equal(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -71,27 +77,26 @@ int bitmap_equal(const unsigned long *bitmap1, return 0; if (bits % BITS_PER_LONG) - if ((bitmap1[k] ^ bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_equal); +EXPORT_SYMBOL(__bitmap_equal); -void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) +void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) dst[k] = ~src[k]; if (bits % BITS_PER_LONG) - dst[k] = ~src[k] & ((1UL << (bits % BITS_PER_LONG)) - 1); + dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits); } -EXPORT_SYMBOL(bitmap_complement); +EXPORT_SYMBOL(__bitmap_complement); /* - * bitmap_shift_right - logical right shift of the bits in a bitmap + * __bitmap_shift_right - logical right shift of the bits in a bitmap * @dst - destination bitmap * @src - source bitmap * @nbits - shift by this many bits @@ -101,7 +106,7 @@ EXPORT_SYMBOL(bitmap_complement); * direction. Zeros are fed into the vacated MS positions and the * LS bits shifted off the bottom are lost. */ -void bitmap_shift_right(unsigned long *dst, +void __bitmap_shift_right(unsigned long *dst, const unsigned long *src, int shift, int bits) { int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG; @@ -131,10 +136,11 @@ void bitmap_shift_right(unsigned long *dst, if (off) memset(&dst[lim - off], 0, off*sizeof(unsigned long)); } -EXPORT_SYMBOL(bitmap_shift_right); +EXPORT_SYMBOL(__bitmap_shift_right); + /* - * bitmap_shift_left - logical left shift of the bits in a bitmap + * __bitmap_shift_left - logical left shift of the bits in a bitmap * @dst - destination bitmap * @src - source bitmap * @nbits - shift by this many bits @@ -144,7 +150,8 @@ EXPORT_SYMBOL(bitmap_shift_right); * direction. Zeros are fed into the vacated LS bit positions * and those MS bits shifted off the top are lost. */ -void bitmap_shift_left(unsigned long *dst, + +void __bitmap_shift_left(unsigned long *dst, const unsigned long *src, int shift, int bits) { int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG; @@ -170,9 +177,9 @@ void bitmap_shift_left(unsigned long *dst, if (off) memset(dst, 0, off*sizeof(unsigned long)); } -EXPORT_SYMBOL(bitmap_shift_left); +EXPORT_SYMBOL(__bitmap_shift_left); -void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -181,9 +188,9 @@ void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] & bitmap2[k]; } -EXPORT_SYMBOL(bitmap_and); +EXPORT_SYMBOL(__bitmap_and); -void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -192,9 +199,9 @@ void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] | bitmap2[k]; } -EXPORT_SYMBOL(bitmap_or); +EXPORT_SYMBOL(__bitmap_or); -void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -203,9 +210,9 @@ void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] ^ bitmap2[k]; } -EXPORT_SYMBOL(bitmap_xor); +EXPORT_SYMBOL(__bitmap_xor); -void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -214,9 +221,9 @@ void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] & ~bitmap2[k]; } -EXPORT_SYMBOL(bitmap_andnot); +EXPORT_SYMBOL(__bitmap_andnot); -int bitmap_intersects(const unsigned long *bitmap1, +int __bitmap_intersects(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -225,14 +232,13 @@ int bitmap_intersects(const unsigned long *bitmap1, return 1; if (bits % BITS_PER_LONG) - if ((bitmap1[k] & bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 1; return 0; } -EXPORT_SYMBOL(bitmap_intersects); +EXPORT_SYMBOL(__bitmap_intersects); -int bitmap_subset(const unsigned long *bitmap1, +int __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -241,15 +247,14 @@ int bitmap_subset(const unsigned long *bitmap1, return 0; if (bits % BITS_PER_LONG) - if ((bitmap1[k] & ~bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_subset); +EXPORT_SYMBOL(__bitmap_subset); #if BITS_PER_LONG == 32 -int bitmap_weight(const unsigned long *bitmap, int bits) +int __bitmap_weight(const unsigned long *bitmap, int bits) { int k, w = 0, lim = bits/BITS_PER_LONG; @@ -257,13 +262,12 @@ int bitmap_weight(const unsigned long *bitmap, int bits) w += hweight32(bitmap[k]); if (bits % BITS_PER_LONG) - w += hweight32(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); + w += hweight32(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); return w; } #else -int bitmap_weight(const unsigned long *bitmap, int bits) +int __bitmap_weight(const unsigned long *bitmap, int bits) { int k, w = 0, lim = bits/BITS_PER_LONG; @@ -271,13 +275,12 @@ int bitmap_weight(const unsigned long *bitmap, int bits) w += hweight64(bitmap[k]); if (bits % BITS_PER_LONG) - w += hweight64(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); + w += hweight64(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); return w; } #endif -EXPORT_SYMBOL(bitmap_weight); +EXPORT_SYMBOL(__bitmap_weight); /* * Bitmap printing & parsing functions: first version by Bill Irwin, @@ -394,7 +397,7 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, if (nchunks == 0 && chunk == 0) continue; - bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); + __bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); *maskp |= chunk; nchunks++; nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; -- cgit v1.2.3 From f3344dc35c26c28647ae4a6b9cdd9df3fa65777e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:00 -0700 Subject: [PATCH] cpumask: rewrite cpumask.h - single bitmap based implementation From: Paul Jackson Major rewrite of cpumask to use a single implementation, as a struct-wrapped bitmap. This patch leaves some 26 include/asm-*/cpumask*.h header files orphaned - to be removed next patch. Some nine cpumask macros for const variants and to coerce and promote between an unsigned long and a cpumask are obsolete. Simple emulation wrappers are provided in this patch for these obsolete macros, which can be removed once each of the 3 archs (i386, ppc64, x86_64) using them are recoded in follow-on patches to not need them. The CPU_MASK_ALL macro now avoids leaving possible garbage one bits in any unused portion of the high word. An inproved comment lists all available operators, for convenient browsing. From: Mikael Pettersson 2.6.7-rc3-mm1 changed CPU_MASK_NONE into something that isn't a valid rvalue (it only works inside struct initializers). This caused compile-time errors in perfctr in UP x86 builds. From: Arnd Bergmann cpumask-5-10-rewrite-cpumaskh-single-bitmap-based from 2.6.7-rc3-mm1 causes include2/asm/smp.h:54:1: warning: "cpu_online" redefined Signed-off-by: Paul Jackson Signed-off-by: Mikael Pettersson Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/irq.c | 6 +- include/asm-s390/smp.h | 6 - include/linux/cpumask.h | 388 ++++++++++++++++++++++++++++++++++++++++++---- kernel/rcupdate.c | 7 +- kernel/sched.c | 5 + 5 files changed, 368 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index b7f6a1eb922f..35243558bfc0 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -691,9 +691,10 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) * Just Do It. */ struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask = get_smpaff_in_irqaction(ap); + cpumask_t cpu_mask; unsigned int buddy, ticks; + cpus_addr(cpu_mask)[0] = get_smpaff_in_irqaction(ap); cpus_and(cpu_mask, cpu_mask, cpu_online_map); if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; @@ -1210,9 +1211,10 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, { struct ino_bucket *bp = ivector_table + (long)data; struct irqaction *ap = bp->irq_info; - cpumask_t mask = get_smpaff_in_irqaction(ap); + cpumask_t mask; int len; + cpus_addr(mask)[0] = get_smpaff_in_irqaction(ap); if (cpus_empty(mask)) mask = cpu_online_map; diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 7e613240088e..70d06261bb9e 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -31,10 +31,6 @@ typedef struct extern int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, int wait, int cpu); - -extern cpumask_t cpu_online_map; -extern cpumask_t cpu_possible_map; - #define NO_PROC_ID 0xFF /* No processor magic marker */ /* @@ -51,8 +47,6 @@ extern cpumask_t cpu_possible_map; #define smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - extern __inline__ __u16 hard_smp_processor_id(void) { __u16 cpu_address; diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index dced3ec2b0c8..f05bf9402dfc 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -1,53 +1,379 @@ #ifndef __LINUX_CPUMASK_H #define __LINUX_CPUMASK_H +/* + * Cpumasks provide a bitmap suitable for representing the + * set of CPU's in a system, one bit position per CPU number. + * + * See detailed comments in the file linux/bitmap.h describing the + * data type on which these cpumasks are based. + * + * For details of cpumask_scnprintf() and cpumask_parse(), + * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c. + * + * The available cpumask operations are: + * + * void cpu_set(cpu, mask) turn on bit 'cpu' in mask + * void cpu_clear(cpu, mask) turn off bit 'cpu' in mask + * void cpus_setall(mask) set all bits + * void cpus_clear(mask) clear all bits + * int cpu_isset(cpu, mask) true iff bit 'cpu' set in mask + * int cpu_test_and_set(cpu, mask) test and set bit 'cpu' in mask + * + * void cpus_and(dst, src1, src2) dst = src1 & src2 [intersection] + * void cpus_or(dst, src1, src2) dst = src1 | src2 [union] + * void cpus_xor(dst, src1, src2) dst = src1 ^ src2 + * void cpus_andnot(dst, src1, src2) dst = src1 & ~src2 + * void cpus_complement(dst, src) dst = ~src + * + * int cpus_equal(mask1, mask2) Does mask1 == mask2? + * int cpus_intersects(mask1, mask2) Do mask1 and mask2 intersect? + * int cpus_subset(mask1, mask2) Is mask1 a subset of mask2? + * int cpus_empty(mask) Is mask empty (no bits sets)? + * int cpus_full(mask) Is mask full (all bits sets)? + * int cpus_weight(mask) Hamming weigh - number of set bits + * + * void cpus_shift_right(dst, src, n) Shift right + * void cpus_shift_left(dst, src, n) Shift left + * + * int first_cpu(mask) Number lowest set bit, or NR_CPUS + * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS + * + * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set + * CPU_MASK_ALL Initializer - all bits set + * CPU_MASK_NONE Initializer - no bits set + * unsigned long *cpus_addr(mask) Array of unsigned long's in mask + * + * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing + * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask + * + * int num_online_cpus() Number of online CPUs + * int num_possible_cpus() Number of all possible CPUs + * int cpu_online(cpu) Is some cpu online? + * int cpu_possible(cpu) Is some cpu possible? + * void cpu_set_online(cpu) set cpu in cpu_online_map + * void cpu_set_offline(cpu) clear cpu in cpu_online_map + * int any_online_cpu(mask) First online cpu in mask + * + * for_each_cpu_mask(cpu, mask) for-loop cpu over mask + * for_each_cpu(cpu) for-loop cpu over cpu_possible_map + * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map + * + * Subtlety: + * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway) + * to generate slightly worse code. Note for example the additional + * 40 lines of assembly code compiling the "for each possible cpu" + * loops buried in the disk_stat_read() macros calls when compiling + * drivers/block/genhd.c (arch i386, CONFIG_SMP=y). So use a simple + * one-line #define for cpu_isset(), instead of wrapping an inline + * inside a macro, the way we do the other calls. + */ + #include #include -#include #include -#ifdef CONFIG_SMP +typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; +extern cpumask_t _unused_cpumask_arg_; -extern cpumask_t cpu_online_map; -extern cpumask_t cpu_possible_map; +#define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) +static inline void __cpu_set(int cpu, volatile cpumask_t *dstp) +{ + set_bit(cpu, dstp->bits); +} -#define num_online_cpus() cpus_weight(cpu_online_map) -#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst)) +static inline void __cpu_clear(int cpu, volatile cpumask_t *dstp) +{ + clear_bit(cpu, dstp->bits); +} -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) +#define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS) +static inline void __cpus_setall(cpumask_t *dstp, int nbits) +{ + bitmap_fill(dstp->bits, nbits); +} -#define for_each_cpu_mask(cpu, mask) \ - for (cpu = first_cpu_const(mk_cpumask_const(mask)); \ - cpu < NR_CPUS; \ - cpu = next_cpu_const(cpu, mk_cpumask_const(mask))) +#define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS) +static inline void __cpus_clear(cpumask_t *dstp, int nbits) +{ + bitmap_zero(dstp->bits, nbits); +} -#define for_each_cpu(cpu) for_each_cpu_mask(cpu, cpu_possible_map) -#define for_each_online_cpu(cpu) for_each_cpu_mask(cpu, cpu_online_map) -#else -#define cpu_online_map cpumask_of_cpu(0) -#define cpu_possible_map cpumask_of_cpu(0) +/* No static inline type checking - see Subtlety (1) above. */ +#define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits) + +#define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask)) +static inline int __cpu_test_and_set(int cpu, cpumask_t *addr) +{ + return test_and_set_bit(cpu, addr->bits); +} + +#define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_and(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_or(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_xor(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_andnot(dst, src1, src2) \ + __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_andnot(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS) +static inline void __cpus_complement(cpumask_t *dstp, + cpumask_t *srcp, int nbits) +{ + bitmap_complement(dstp->bits, srcp->bits, nbits); +} + +#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS) +static inline int __cpus_equal(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_equal(src1p->bits, src2p->bits, nbits); +} + +#define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS) +static inline int __cpus_intersects(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_intersects(src1p->bits, src2p->bits, nbits); +} + +#define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS) +static inline int __cpus_subset(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_subset(src1p->bits, src2p->bits, nbits); +} + +#define cpus_empty(src) __cpus_empty(&(src), NR_CPUS) +static inline int __cpus_empty(cpumask_t *srcp, int nbits) +{ + return bitmap_empty(srcp->bits, nbits); +} + +#define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS) +static inline int __cpus_full(cpumask_t *srcp, int nbits) +{ + return bitmap_full(srcp->bits, nbits); +} + +#define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS) +static inline int __cpus_weight(cpumask_t *srcp, int nbits) +{ + return bitmap_weight(srcp->bits, nbits); +} + +#define cpus_shift_right(dst, src, n) \ + __cpus_shift_right(&(dst), &(src), (n), NR_CPUS) +static inline void __cpus_shift_right(cpumask_t *dstp, + cpumask_t *srcp, int n, int nbits) +{ + bitmap_shift_right(dstp->bits, srcp->bits, n, nbits); +} + +#define cpus_shift_left(dst, src, n) \ + __cpus_shift_left(&(dst), &(src), (n), NR_CPUS) +static inline void __cpus_shift_left(cpumask_t *dstp, + cpumask_t *srcp, int n, int nbits) +{ + bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); +} + +#define first_cpu(src) __first_cpu(&(src), NR_CPUS) +static inline int __first_cpu(cpumask_t *srcp, int nbits) +{ + return find_first_bit(srcp->bits, nbits); +} -#define num_online_cpus() 1 -#define num_possible_cpus() 1 +#define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS) +static inline int __next_cpu(int n, cpumask_t *srcp, int nbits) +{ + return find_next_bit(srcp->bits, nbits, n+1); +} -#define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#define cpumask_of_cpu(cpu) \ +({ \ + typeof(_unused_cpumask_arg_) m; \ + if (sizeof(m) == sizeof(unsigned long)) { \ + m.bits[0] = 1UL<<(cpu); \ + } else { \ + cpus_clear(m); \ + cpu_set((cpu), m); \ + } \ + m; \ +}) + +#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) + +#if NR_CPUS <= BITS_PER_LONG + +#define CPU_MASK_ALL \ +((cpumask_t) { { \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} }) + +#else + +#define CPU_MASK_ALL \ +((cpumask_t) { { \ + [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} }) -#define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++) -#define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) -#define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #endif +#define CPU_MASK_NONE \ +((cpumask_t) { { \ + [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ +} }) + +#define cpus_addr(src) ((src).bits) + +#define cpumask_scnprintf(buf, len, src) \ + __cpumask_scnprintf((buf), (len), &(src), NR_CPUS) +static inline int __cpumask_scnprintf(char *buf, int len, + cpumask_t *srcp, int nbits) +{ + return bitmap_scnprintf(buf, len, srcp->bits, nbits); +} + +#define cpumask_parse(ubuf, ulen, src) \ + __cpumask_parse((ubuf), (ulen), &(src), NR_CPUS) +static inline int __cpumask_parse(const char __user *buf, int len, + cpumask_t *srcp, int nbits) +{ + return bitmap_parse(buf, len, srcp->bits, nbits); +} + +#if NR_CPUS > 1 +#define for_each_cpu_mask(cpu, mask) \ + for ((cpu) = first_cpu(mask); \ + (cpu) < NR_CPUS; \ + (cpu) = next_cpu((cpu), (mask))) +#else /* NR_CPUS == 1 */ +#define for_each_cpu_mask(cpu, mask) for ((cpu) = 0; (cpu) < 1; (cpu)++) +#endif /* NR_CPUS */ + +/* + * The following particular system cpumasks and operations manage + * possible, present and online cpus. Each of them is a fixed size + * bitmap of size NR_CPUS. + * + * #ifdef CONFIG_HOTPLUG_CPU + * cpu_possible_map - all NR_CPUS bits set + * cpu_present_map - has bit 'cpu' set iff cpu is populated + * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler + * #else + * cpu_possible_map - has bit 'cpu' set iff cpu is populated + * cpu_present_map - copy of cpu_possible_map + * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler + * #endif + * + * In either case, NR_CPUS is fixed at compile time, as the static + * size of these bitmaps. The cpu_possible_map is fixed at boot + * time, as the set of CPU id's that it is possible might ever + * be plugged in at anytime during the life of that system boot. + * The cpu_present_map is dynamic(*), representing which CPUs + * are currently plugged in. And cpu_online_map is the dynamic + * subset of cpu_present_map, indicating those CPUs available + * for scheduling. + * + * If HOTPLUG is enabled, then cpu_possible_map is forced to have + * all NR_CPUS bits set, otherwise it is just the set of CPUs that + * ACPI reports present at boot. + * + * If HOTPLUG is enabled, then cpu_present_map varies dynamically, + * depending on what ACPI reports as currently plugged in, otherwise + * cpu_present_map is just a copy of cpu_possible_map. + * + * (*) Well, cpu_present_map is dynamic in the hotplug case. If not + * hotplug, it's a copy of cpu_possible_map, hence fixed at boot. + * + * Subtleties: + * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode + * assumption that their single CPU is online. The UP + * cpu_{online,possible,present}_maps are placebos. Changing them + * will have no useful affect on the following num_*_cpus() + * and cpu_*() macros in the UP case. This ugliness is a UP + * optimization - don't waste any instructions or memory references + * asking if you're online or how many CPUs there are if there is + * only one CPU. + * 2) Most SMP arch's #define some of these maps to be some + * other map specific to that arch. Therefore, the following + * must be #define macros, not inlines. To see why, examine + * the assembly code produced by the following. Note that + * set1() writes phys_x_map, but set2() writes x_map: + * int x_map, phys_x_map; + * #define set1(a) x_map = a + * inline void set2(int a) { x_map = a; } + * #define x_map phys_x_map + * main(){ set1(3); set2(5); } + */ + +extern cpumask_t cpu_possible_map; +extern cpumask_t cpu_online_map; extern cpumask_t cpu_present_map; -#define num_present_cpus() cpus_weight(cpu_present_map) -#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) -#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) -#define cpumask_scnprintf(buf, buflen, map) \ - bitmap_scnprintf(buf, buflen, cpus_addr(map), NR_CPUS) +#if NR_CPUS > 1 +#define num_online_cpus() cpus_weight(cpu_online_map) +#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) +#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) +#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) +#else +#define num_online_cpus() 1 +#define num_possible_cpus() 1 +#define num_present_cpus() 1 +#define cpu_online(cpu) ((cpu) == 0) +#define cpu_possible(cpu) ((cpu) == 0) +#define cpu_present(cpu) ((cpu) == 0) +#endif + +#define any_online_cpu(mask) \ +({ \ + int cpu; \ + for_each_cpu_mask(cpu, (mask)) \ + if (cpu_online(cpu)) \ + break; \ + cpu; \ +}) + +#define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) +#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) +#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) -#define cpumask_parse(buf, buflen, map) \ - bitmap_parse(buf, buflen, cpus_addr(map), NR_CPUS) +/* Begin obsolete cpumask operator emulation */ +#define cpu_isset_const(a,b) cpu_isset(a,b) +#define cpumask_const_t cpumask_t +#define cpus_coerce(m) (cpus_addr(m)[0]) +#define cpus_coerce_const cpus_coerce +#define cpus_promote(x) ({ cpumask_t m; m.bits[0] = x; m; }) +#define cpus_weight_const cpus_weight +#define first_cpu_const first_cpu +#define mk_cpumask_const(x) x +#define next_cpu_const next_cpu +/* End of obsolete cpumask operator emulation */ #endif /* __LINUX_CPUMASK_H */ diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 7282889a5fd9..f35f944abe3d 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -129,17 +129,14 @@ static void rcu_do_batch(struct rcu_head *list) */ static void rcu_start_batch(int next_pending) { - cpumask_t active; - if (next_pending) rcu_ctrlblk.next_pending = 1; if (rcu_ctrlblk.next_pending && rcu_ctrlblk.completed == rcu_ctrlblk.cur) { /* Can't change, since spin lock held. */ - active = nohz_cpu_mask; - cpus_complement(active); - cpus_and(rcu_state.rcu_cpu_mask, cpu_online_map, active); + cpus_andnot(rcu_state.rcu_cpu_mask, cpu_online_map, + nohz_cpu_mask); write_seqcount_begin(&rcu_ctrlblk.lock); rcu_ctrlblk.next_pending = 0; rcu_ctrlblk.cur++; diff --git a/kernel/sched.c b/kernel/sched.c index a614d7ebf7c3..f0103ee1d66a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2951,6 +2951,11 @@ out_unlock: cpumask_t cpu_present_map; EXPORT_SYMBOL(cpu_present_map); +#ifndef CONFIG_SMP +cpumask_t cpu_online_map = CPU_MASK_ALL; +cpumask_t cpu_possible_map = CPU_MASK_ALL; +#endif + /** * sys_sched_getaffinity - get the cpu affinity of a process * @pid: pid of the process -- cgit v1.2.3 From ed880528b07445a2b3932f839727d7d740f03cc4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:14 -0700 Subject: [PATCH] cpumask: remove 26 no longer used cpumask*.h files From: Paul Jackson With the cpumask rewrite in the previous patch, these various include/asm-*/cpumask*.h headers are no longer used. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/cpumask.h | 6 --- include/asm-arm/cpumask.h | 6 --- include/asm-arm26/cpumask.h | 6 --- include/asm-cris/cpumask.h | 6 --- include/asm-generic/cpumask.h | 40 ------------------ include/asm-generic/cpumask_arith.h | 49 ---------------------- include/asm-generic/cpumask_array.h | 54 ------------------------ include/asm-generic/cpumask_const_reference.h | 29 ------------- include/asm-generic/cpumask_const_value.h | 21 ---------- include/asm-generic/cpumask_up.h | 59 --------------------------- include/asm-h8300/cpumask.h | 6 --- include/asm-i386/cpumask.h | 6 --- include/asm-ia64/cpumask.h | 6 --- include/asm-m68k/cpumask.h | 6 --- include/asm-m68knommu/cpumask.h | 6 --- include/asm-mips/cpumask.h | 6 --- include/asm-parisc/cpumask.h | 6 --- include/asm-ppc/cpumask.h | 6 --- include/asm-ppc64/cpumask.h | 6 --- include/asm-s390/cpumask.h | 6 --- include/asm-sh/cpumask.h | 6 --- include/asm-sparc/cpumask.h | 6 --- include/asm-sparc64/cpumask.h | 6 --- include/asm-um/cpumask.h | 6 --- include/asm-v850/cpumask.h | 6 --- include/asm-x86_64/cpumask.h | 6 --- 26 files changed, 372 deletions(-) delete mode 100644 include/asm-alpha/cpumask.h delete mode 100644 include/asm-arm/cpumask.h delete mode 100644 include/asm-arm26/cpumask.h delete mode 100644 include/asm-cris/cpumask.h delete mode 100644 include/asm-generic/cpumask.h delete mode 100644 include/asm-generic/cpumask_arith.h delete mode 100644 include/asm-generic/cpumask_array.h delete mode 100644 include/asm-generic/cpumask_const_reference.h delete mode 100644 include/asm-generic/cpumask_const_value.h delete mode 100644 include/asm-generic/cpumask_up.h delete mode 100644 include/asm-h8300/cpumask.h delete mode 100644 include/asm-i386/cpumask.h delete mode 100644 include/asm-ia64/cpumask.h delete mode 100644 include/asm-m68k/cpumask.h delete mode 100644 include/asm-m68knommu/cpumask.h delete mode 100644 include/asm-mips/cpumask.h delete mode 100644 include/asm-parisc/cpumask.h delete mode 100644 include/asm-ppc/cpumask.h delete mode 100644 include/asm-ppc64/cpumask.h delete mode 100644 include/asm-s390/cpumask.h delete mode 100644 include/asm-sh/cpumask.h delete mode 100644 include/asm-sparc/cpumask.h delete mode 100644 include/asm-sparc64/cpumask.h delete mode 100644 include/asm-um/cpumask.h delete mode 100644 include/asm-v850/cpumask.h delete mode 100644 include/asm-x86_64/cpumask.h (limited to 'include') diff --git a/include/asm-alpha/cpumask.h b/include/asm-alpha/cpumask.h deleted file mode 100644 index bc3381ad1643..000000000000 --- a/include/asm-alpha/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ALPHA_CPUMASK_H -#define _ASM_ALPHA_CPUMASK_H - -#include - -#endif /* _ASM_ALPHA_CPUMASK_H */ diff --git a/include/asm-arm/cpumask.h b/include/asm-arm/cpumask.h deleted file mode 100644 index e3cf01fdf9c9..000000000000 --- a/include/asm-arm/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ARM_CPUMASK_H -#define _ASM_ARM_CPUMASK_H - -#include - -#endif /* _ASM_ARM_CPUMASK_H */ diff --git a/include/asm-arm26/cpumask.h b/include/asm-arm26/cpumask.h deleted file mode 100644 index d181df4ed512..000000000000 --- a/include/asm-arm26/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ARM26_CPUMASK_H -#define _ASM_ARM26_CPUMASK_H - -#include - -#endif /* _ASM_ARM26_CPUMASK_H */ diff --git a/include/asm-cris/cpumask.h b/include/asm-cris/cpumask.h deleted file mode 100644 index 123b032a6eae..000000000000 --- a/include/asm-cris/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_CRIS_CPUMASK_H -#define _ASM_CRIS_CPUMASK_H - -#include - -#endif /* _ASM_CRIS_CPUMASK_H */ diff --git a/include/asm-generic/cpumask.h b/include/asm-generic/cpumask.h deleted file mode 100644 index a5103259d7a9..000000000000 --- a/include/asm-generic/cpumask.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_H -#define __ASM_GENERIC_CPUMASK_H - -#include -#include -#include -#include -#include - -#if NR_CPUS > BITS_PER_LONG && NR_CPUS != 1 -#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) - -struct cpumask -{ - unsigned long mask[CPU_ARRAY_SIZE]; -}; - -typedef struct cpumask cpumask_t; - -#else -typedef unsigned long cpumask_t; -#endif - -#ifdef CONFIG_SMP -#if NR_CPUS > BITS_PER_LONG -#include -#else -#include -#endif -#else -#include -#endif - -#if NR_CPUS <= 4*BITS_PER_LONG -#include -#else -#include -#endif - -#endif /* __ASM_GENERIC_CPUMASK_H */ diff --git a/include/asm-generic/cpumask_arith.h b/include/asm-generic/cpumask_arith.h deleted file mode 100644 index b4d25ac46a9f..000000000000 --- a/include/asm-generic/cpumask_arith.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_ARITH_H -#define __ASM_GENERIC_CPUMASK_ARITH_H - -/* - * Arithmetic type -based cpu bitmaps. A single unsigned long is used - * to contain the whole cpu bitmap. - */ - -#define cpu_set(cpu, map) set_bit(cpu, &(map)) -#define cpu_clear(cpu, map) clear_bit(cpu, &(map)) -#define cpu_isset(cpu, map) test_bit(cpu, &(map)) -#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, &(map)) - -#define cpus_and(dst,src1,src2) do { dst = (src1) & (src2); } while (0) -#define cpus_or(dst,src1,src2) do { dst = (src1) | (src2); } while (0) -#define cpus_clear(map) do { map = 0; } while (0) -#define cpus_complement(map) do { map = ~(map); } while (0) -#define cpus_equal(map1, map2) ((map1) == (map2)) -#define cpus_empty(map) ((map) == 0) -#define cpus_addr(map) (&(map)) - -#if BITS_PER_LONG == 32 -#define cpus_weight(map) hweight32(map) -#elif BITS_PER_LONG == 64 -#define cpus_weight(map) hweight64(map) -#endif - -#define cpus_shift_right(dst, src, n) do { dst = (src) >> (n); } while (0) -#define cpus_shift_left(dst, src, n) do { dst = (src) << (n); } while (0) - -#define any_online_cpu(map) \ -({ \ - cpumask_t __tmp__; \ - cpus_and(__tmp__, map, cpu_online_map); \ - __tmp__ ? first_cpu(__tmp__) : NR_CPUS; \ -}) - -#define CPU_MASK_ALL (~((cpumask_t)0) >> (8*sizeof(cpumask_t) - NR_CPUS)) -#define CPU_MASK_NONE ((cpumask_t)0) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce(map) ((unsigned long)(map)) -#define cpus_promote(map) ({ map; }) -#define cpumask_of_cpu(cpu) ({ ((cpumask_t)1) << (cpu); }) - -#define first_cpu(map) find_first_bit(&(map), NR_CPUS) -#define next_cpu(cpu, map) find_next_bit(&(map), NR_CPUS, cpu + 1) - -#endif /* __ASM_GENERIC_CPUMASK_ARITH_H */ diff --git a/include/asm-generic/cpumask_array.h b/include/asm-generic/cpumask_array.h deleted file mode 100644 index 1be08ae2e93b..000000000000 --- a/include/asm-generic/cpumask_array.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_ARRAY_H -#define __ASM_GENERIC_CPUMASK_ARRAY_H - -/* - * Array-based cpu bitmaps. An array of unsigned longs is used to contain - * the bitmap, and then contained in a structure so it may be passed by - * value. - */ - -#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) - -#define cpu_set(cpu, map) set_bit(cpu, (map).mask) -#define cpu_clear(cpu, map) clear_bit(cpu, (map).mask) -#define cpu_isset(cpu, map) test_bit(cpu, (map).mask) -#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, (map).mask) - -#define cpus_and(dst,src1,src2) bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS) -#define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) -#define cpus_clear(map) bitmap_zero((map).mask, NR_CPUS) -#define cpus_complement(map) bitmap_complement((map).mask, (map).mask, NR_CPUS) -#define cpus_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, NR_CPUS) -#define cpus_empty(map) bitmap_empty(map.mask, NR_CPUS) -#define cpus_addr(map) ((map).mask) -#define cpus_weight(map) bitmap_weight((map).mask, NR_CPUS) -#define cpus_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, NR_CPUS) -#define cpus_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, NR_CPUS) -#define first_cpu(map) find_first_bit((map).mask, NR_CPUS) -#define next_cpu(cpu, map) find_next_bit((map).mask, NR_CPUS, cpu + 1) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce(map) ((map).mask[0]) -#define cpus_promote(map) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ - __cpu_mask.mask[0] = map; \ - __cpu_mask; \ - }) -#define cpumask_of_cpu(cpu) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ - cpu_set(cpu, __cpu_mask); \ - __cpu_mask; \ - }) -#define any_online_cpu(map) \ -({ \ - cpumask_t __tmp__; \ - cpus_and(__tmp__, map, cpu_online_map); \ - find_first_bit(__tmp__.mask, NR_CPUS); \ -}) - - -/* - * um, these need to be usable as static initializers - */ -#define CPU_MASK_ALL ((cpumask_t) { {[0 ... CPU_ARRAY_SIZE-1] = ~0UL} }) -#define CPU_MASK_NONE ((cpumask_t) { {[0 ... CPU_ARRAY_SIZE-1] = 0UL} }) - -#endif /* __ASM_GENERIC_CPUMASK_ARRAY_H */ diff --git a/include/asm-generic/cpumask_const_reference.h b/include/asm-generic/cpumask_const_reference.h deleted file mode 100644 index e98da01bcfdf..000000000000 --- a/include/asm-generic/cpumask_const_reference.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H -#define __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H - -struct cpumask_ref { - const cpumask_t *val; -}; - -typedef const struct cpumask_ref cpumask_const_t; - -#define mk_cpumask_const(map) ((cpumask_const_t){ &(map) }) -#define cpu_isset_const(cpu, map) cpu_isset(cpu, *(map).val) - -#define cpus_and_const(dst,src1,src2) cpus_and(dst,*(src1).val,*(src2).val) -#define cpus_or_const(dst,src1,src2) cpus_or(dst,*(src1).val,*(src2).val) - -#define cpus_equal_const(map1, map2) cpus_equal(*(map1).val, *(map2).val) - -#define cpus_copy_const(map1, map2) bitmap_copy((map1).mask, (map2).val->mask, NR_CPUS) - -#define cpus_empty_const(map) cpus_empty(*(map).val) -#define cpus_weight_const(map) cpus_weight(*(map).val) -#define first_cpu_const(map) first_cpu(*(map).val) -#define next_cpu_const(cpu, map) next_cpu(cpu, *(map).val) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce_const(map) cpus_coerce(*(map).val) -#define any_online_cpu_const(map) any_online_cpu(*(map).val) - -#endif /* __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H */ diff --git a/include/asm-generic/cpumask_const_value.h b/include/asm-generic/cpumask_const_value.h deleted file mode 100644 index 16ca16d286dc..000000000000 --- a/include/asm-generic/cpumask_const_value.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_CONST_VALUE_H -#define __ASM_GENERIC_CPUMASK_CONST_VALUE_H - -typedef const cpumask_t cpumask_const_t; - -#define mk_cpumask_const(map) (map) -#define cpu_isset_const(cpu, map) cpu_isset(cpu, map) -#define cpus_and_const(dst,src1,src2) cpus_and(dst, src1, src2) -#define cpus_or_const(dst,src1,src2) cpus_or(dst, src1, src2) -#define cpus_equal_const(map1, map2) cpus_equal(map1, map2) -#define cpus_empty_const(map) cpus_empty(map) -#define cpus_copy_const(map1, map2) do { map1 = (cpumask_t)map2; } while (0) -#define cpus_weight_const(map) cpus_weight(map) -#define first_cpu_const(map) first_cpu(map) -#define next_cpu_const(cpu, map) next_cpu(cpu, map) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce_const(map) cpus_coerce(map) -#define any_online_cpu_const(map) any_online_cpu(map) - -#endif /* __ASM_GENERIC_CPUMASK_CONST_VALUE_H */ diff --git a/include/asm-generic/cpumask_up.h b/include/asm-generic/cpumask_up.h deleted file mode 100644 index f55c265a0e3b..000000000000 --- a/include/asm-generic/cpumask_up.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_UP_H -#define __ASM_GENERIC_CPUMASK_UP_H - -#define cpus_coerce(map) (map) - -#define cpu_set(cpu, map) do { (void)(cpu); cpus_coerce(map) = 1UL; } while (0) -#define cpu_clear(cpu, map) do { (void)(cpu); cpus_coerce(map) = 0UL; } while (0) -#define cpu_isset(cpu, map) ((void)(cpu), cpus_coerce(map) != 0UL) -#define cpu_test_and_set(cpu, map) ((void)(cpu), test_and_set_bit(0, &(map))) - -#define cpus_and(dst, src1, src2) \ - do { \ - if (cpus_coerce(src1) && cpus_coerce(src2)) \ - cpus_coerce(dst) = 1UL; \ - else \ - cpus_coerce(dst) = 0UL; \ - } while (0) - -#define cpus_or(dst, src1, src2) \ - do { \ - if (cpus_coerce(src1) || cpus_coerce(src2)) \ - cpus_coerce(dst) = 1UL; \ - else \ - cpus_coerce(dst) = 0UL; \ - } while (0) - -#define cpus_clear(map) do { cpus_coerce(map) = 0UL; } while (0) - -#define cpus_complement(map) \ - do { \ - cpus_coerce(map) = !cpus_coerce(map); \ - } while (0) - -#define cpus_equal(map1, map2) (cpus_coerce(map1) == cpus_coerce(map2)) -#define cpus_empty(map) (cpus_coerce(map) == 0UL) -#define cpus_addr(map) (&(map)) -#define cpus_weight(map) (cpus_coerce(map) ? 1UL : 0UL) -#define cpus_shift_right(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) -#define cpus_shift_left(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) -#define first_cpu(map) (cpus_coerce(map) ? 0 : 1) -#define next_cpu(cpu, map) 1 - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_promote(map) \ - ({ \ - cpumask_t __tmp__; \ - cpus_coerce(__tmp__) = map; \ - __tmp__; \ - }) -#define cpumask_of_cpu(cpu) ((void)(cpu), cpus_promote(1)) -#define any_online_cpu(map) (cpus_coerce(map) ? 0 : 1) - -/* - * um, these need to be usable as static initializers - */ -#define CPU_MASK_ALL 1UL -#define CPU_MASK_NONE 0UL - -#endif /* __ASM_GENERIC_CPUMASK_UP_H */ diff --git a/include/asm-h8300/cpumask.h b/include/asm-h8300/cpumask.h deleted file mode 100644 index 3b403850c043..000000000000 --- a/include/asm-h8300/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_H8300_CPUMASK_H -#define _ASM_H8300_CPUMASK_H - -#include - -#endif /* _ASM_H8300_CPUMASK_H */ diff --git a/include/asm-i386/cpumask.h b/include/asm-i386/cpumask.h deleted file mode 100644 index 8bf5a829c528..000000000000 --- a/include/asm-i386/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_I386_CPUMASK_H -#define _ASM_I386_CPUMASK_H - -#include - -#endif /* _ASM_I386_CPUMASK_H */ diff --git a/include/asm-ia64/cpumask.h b/include/asm-ia64/cpumask.h deleted file mode 100644 index 7764aef653e8..000000000000 --- a/include/asm-ia64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_IA64_CPUMASK_H -#define _ASM_IA64_CPUMASK_H - -#include - -#endif /* _ASM_IA64_CPUMASK_H */ diff --git a/include/asm-m68k/cpumask.h b/include/asm-m68k/cpumask.h deleted file mode 100644 index b12450332e19..000000000000 --- a/include/asm-m68k/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_CPUMASK_H -#define _ASM_M68K_CPUMASK_H - -#include - -#endif /* _ASM_M68K_CPUMASK_H */ diff --git a/include/asm-m68knommu/cpumask.h b/include/asm-m68knommu/cpumask.h deleted file mode 100644 index cd9cc78af838..000000000000 --- a/include/asm-m68knommu/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68KNOMMU_CPUMASK_H -#define _ASM_M68KNOMMU_CPUMASK_H - -#include - -#endif /* _ASM_M68KNOMMU_CPUMASK_H */ diff --git a/include/asm-mips/cpumask.h b/include/asm-mips/cpumask.h deleted file mode 100644 index cf562af10d6f..000000000000 --- a/include/asm-mips/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_MIPS_CPUMASK_H -#define _ASM_MIPS_CPUMASK_H - -#include - -#endif /* _ASM_MIPS_CPUMASK_H */ diff --git a/include/asm-parisc/cpumask.h b/include/asm-parisc/cpumask.h deleted file mode 100644 index 27f4f17fb15a..000000000000 --- a/include/asm-parisc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PARISC_CPUMASK_H -#define _ASM_PARISC_CPUMASK_H - -#include - -#endif /* _ASM_PARISC_CPUMASK_H */ diff --git a/include/asm-ppc/cpumask.h b/include/asm-ppc/cpumask.h deleted file mode 100644 index 30901089dd41..000000000000 --- a/include/asm-ppc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PPC_CPUMASK_H -#define _ASM_PPC_CPUMASK_H - -#include - -#endif /* _ASM_PPC_CPUMASK_H */ diff --git a/include/asm-ppc64/cpumask.h b/include/asm-ppc64/cpumask.h deleted file mode 100644 index 0914511db218..000000000000 --- a/include/asm-ppc64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PPC64_CPUMASK_H -#define _ASM_PPC64_CPUMASK_H - -#include - -#endif /* _ASM_PPC64_CPUMASK_H */ diff --git a/include/asm-s390/cpumask.h b/include/asm-s390/cpumask.h deleted file mode 100644 index 4deef1641ec6..000000000000 --- a/include/asm-s390/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_S390_CPUMASK_H -#define _ASM_S390_CPUMASK_H - -#include - -#endif /* _ASM_S390_CPUMASK_H */ diff --git a/include/asm-sh/cpumask.h b/include/asm-sh/cpumask.h deleted file mode 100644 index deaf3bb85d7e..000000000000 --- a/include/asm-sh/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SH_CPUMASK_H -#define _ASM_SH_CPUMASK_H - -#include - -#endif /* _ASM_SH_CPUMASK_H */ diff --git a/include/asm-sparc/cpumask.h b/include/asm-sparc/cpumask.h deleted file mode 100644 index 272f31de7bc1..000000000000 --- a/include/asm-sparc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SPARC_CPUMASK_H -#define _ASM_SPARC_CPUMASK_H - -#include - -#endif /* _ASM_SPARC_CPUMASK_H */ diff --git a/include/asm-sparc64/cpumask.h b/include/asm-sparc64/cpumask.h deleted file mode 100644 index ee60cae3dcd1..000000000000 --- a/include/asm-sparc64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SPARC64_CPUMASK_H -#define _ASM_SPARC64_CPUMASK_H - -#include - -#endif /* _ASM_SPARC64_CPUMASK_H */ diff --git a/include/asm-um/cpumask.h b/include/asm-um/cpumask.h deleted file mode 100644 index 90f0d003d74e..000000000000 --- a/include/asm-um/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_CPUMASK_H -#define _ASM_UM_CPUMASK_H - -#include - -#endif /* _ASM_UM_CPUMASK_H */ diff --git a/include/asm-v850/cpumask.h b/include/asm-v850/cpumask.h deleted file mode 100644 index 09aebd0c28d7..000000000000 --- a/include/asm-v850/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_V850_CPUMASK_H -#define _ASM_V850_CPUMASK_H - -#include - -#endif /* _ASM_V850_CPUMASK_H */ diff --git a/include/asm-x86_64/cpumask.h b/include/asm-x86_64/cpumask.h deleted file mode 100644 index d9ea497140a1..000000000000 --- a/include/asm-x86_64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_X86_64_CPUMASK_H -#define _ASM_X86_64_CPUMASK_H - -#include - -#endif /* _ASM_X86_64_CPUMASK_H */ -- cgit v1.2.3 From 9eb0dcc1d86252f9f216fd2f09868fdd28272abd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:25 -0700 Subject: [PATCH] cpumask: remove obsolete cpumask macro uses - i386 arch From: Paul Jackson Remove by recoding i386 uses of the obsolete cpumask const, coerce and promote macros. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 2 +- arch/i386/kernel/smp.c | 2 +- arch/i386/mach-voyager/voyager_smp.c | 30 +++++++++++++++--------------- include/asm-i386/genapic.h | 2 +- include/asm-i386/mach-bigsmp/mach_apic.h | 10 +++++----- include/asm-i386/mach-default/mach_apic.h | 10 +++++----- include/asm-i386/mach-es7000/mach_apic.h | 10 +++++----- include/asm-i386/mach-numaq/mach_apic.h | 2 +- include/asm-i386/mach-summit/mach_apic.h | 8 ++++---- include/asm-i386/mach-visws/mach_apic.h | 4 ++-- 10 files changed, 40 insertions(+), 40 deletions(-) (limited to 'include') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 70f329ed696f..28b4d7c4e3c6 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -224,7 +224,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) struct irq_pin_list *entry = irq_2_pin + irq; unsigned int apicid_value; - apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask)); + apicid_value = cpu_mask_to_apicid(cpumask); /* Prepare to do the io_apic_write */ apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index c4313dcfe63c..5e3ac93253d2 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -159,7 +159,7 @@ void fastcall send_IPI_self(int vector) */ inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index b99561d19839..90c918f11f0b 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -153,7 +153,7 @@ static inline void send_CPI_allbutself(__u8 cpi) { __u8 cpu = smp_processor_id(); - __u32 mask = cpus_coerce(cpu_online_map) & ~(1 << cpu); + __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); send_CPI(mask, cpi); } @@ -402,11 +402,11 @@ find_smp_config(void) /* set up everything for just this CPU, we can alter * this as we start the other CPUs later */ /* now get the CPU disposition from the extended CMOS */ - phys_cpu_present_map = cpus_promote(voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK)); - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; - printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_coerce(phys_cpu_present_map)); + cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; + printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]); /* Here we set up the VIC to enable SMP */ /* enable the CPIs by writing the base vector to their register */ outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); @@ -706,12 +706,12 @@ smp_boot_cpus(void) /* now that the cat has probed the Voyager System Bus, sanity * check the cpu map */ if( ((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_coerce(phys_cpu_present_map)) != cpus_coerce(phys_cpu_present_map)) { + & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) { /* should panic */ printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n"); } } else if(voyager_level == 4) - voyager_extended_vic_processors = cpus_coerce(phys_cpu_present_map); + voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0]; /* this sets up the idle task to run on the current cpu */ voyager_extended_cpus = 1; @@ -909,7 +909,7 @@ flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, if (!cpumask) BUG(); - if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask) + if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask) BUG(); if (cpumask & (1 << smp_processor_id())) BUG(); @@ -952,7 +952,7 @@ flush_tlb_current_task(void) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); local_flush_tlb(); if (cpu_mask) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); @@ -968,7 +968,7 @@ flush_tlb_mm (struct mm_struct * mm) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if (current->mm) @@ -989,7 +989,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if(current->mm) __flush_tlb_one(va); @@ -1098,7 +1098,7 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { struct call_data_struct data; - __u32 mask = cpus_coerce(cpu_online_map); + __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1<= NR_CPUS) - cpu = first_cpu_const(cpu_online_map); + cpu = first_cpu(cpu_online_map); else - cpu = next_cpu_const(cpu, cpu_online_map); + cpu = next_cpu(cpu, cpu_online_map); } while (cpu >= NR_CPUS); - return mk_cpumask_const(cpumask_of_cpu(cpu)); + return cpumask_of_cpu(cpu); } #define TARGET_CPUS (target_cpus()) @@ -149,12 +149,12 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) } /* As we are using single CPU as destination, pick only one CPU here */ -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int cpu; int apicid; - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); return apicid; } diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index 87f688705979..627f1cd084ba 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -6,12 +6,12 @@ #define APIC_DFR_VALUE (APIC_DFR_FLAT) -static inline cpumask_const_t target_cpus(void) +static inline cpumask_t target_cpus(void) { #ifdef CONFIG_SMP - return mk_cpumask_const(cpu_online_map); + return cpu_online_map; #else - return mk_cpumask_const(cpumask_of_cpu(0)); + return cpumask_of_cpu(0); #endif } #define TARGET_CPUS (target_cpus()) @@ -116,9 +116,9 @@ static inline int apic_id_registered(void) return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } static inline void enable_apic_mode(void) diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index fd0430c77565..888f7f04262d 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h @@ -88,7 +88,7 @@ static inline void clustered_apic_check(void) int apic = bios_cpu_apicid[smp_processor_id()]; printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", (apic_version[apic] == 0x14) ? - "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_coerce(TARGET_CPUS)); + "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]); } static inline int multi_timer_check(int apic, int irq) @@ -158,14 +158,14 @@ static inline int check_phys_apicid_present(int cpu_physical_apicid) return (1); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = cpus_weight_const(cpumask); + num_bits_set = cpus_weight(cpumask); /* Return id to all */ if (num_bits_set == NR_CPUS) #if defined CONFIG_ES7000_CLUSTERED_APIC @@ -177,10 +177,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpu_isset_const(cpu, cpumask)) { + if (cpu_isset(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index b66e78d7b6df..e40c308b15d3 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -135,7 +135,7 @@ static inline void enable_apic_mode(void) * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { return (int) 0xF; } diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 9ea48a79d629..4bf36ddba96d 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -139,14 +139,14 @@ static inline void enable_apic_mode(void) { } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = cpus_weight_const(cpumask); + num_bits_set = cpus_weight(cpumask); /* Return id to all */ if (num_bits_set == NR_CPUS) return (int) 0xFF; @@ -154,10 +154,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpu_isset_const(cpu, cpumask)) { + if (cpu_isset(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h index 4b92eabb92ff..c367d820f23f 100644 --- a/include/asm-i386/mach-visws/mach_apic.h +++ b/include/asm-i386/mach-visws/mach_apic.h @@ -86,9 +86,9 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) -- cgit v1.2.3 From 7f1c9f57926f2249f01143b18fbc26cb57ef28bf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:37 -0700 Subject: [PATCH] cpumask: remove obsolete cpumask macro uses - other archs From: Paul Jackson Remove by recoding other uses of the obsolete cpumask const, coerce and promote macros. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/open_pic.c | 8 ++++---- arch/ppc64/kernel/rtasd.c | 6 +++--- arch/x86_64/kernel/io_apic.c | 2 +- arch/x86_64/kernel/pci-gart.c | 4 ++-- arch/x86_64/kernel/smp.c | 2 +- include/asm-x86_64/smp.h | 5 ++--- 6 files changed, 13 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c index 0eed791f3eb6..874afcb5f1a4 100644 --- a/arch/ppc64/kernel/open_pic.c +++ b/arch/ppc64/kernel/open_pic.c @@ -591,7 +591,7 @@ static inline u32 physmask(u32 cpumask) void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } #ifdef CONFIG_SMP @@ -625,7 +625,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask) CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } void openpic_request_IPIs(void) @@ -711,7 +711,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } @@ -844,7 +844,7 @@ static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask) cpumask_t tmp; cpus_and(tmp, cpumask, cpu_online_map); - openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_coerce(tmp))); + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_addr(tmp)[0])); } #ifdef CONFIG_SMP diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index eea82c7b29d1..243d2ee8de8a 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c @@ -415,7 +415,7 @@ static int rtasd(void *unused) } lock_cpu_hotplug(); - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); for (;;) { set_cpus_allowed(current, cpumask_of_cpu(cpu)); do_event_scan(event_scan); @@ -429,9 +429,9 @@ static int rtasd(void *unused) schedule_timeout((HZ*60/rtas_event_scan_rate) / 2); lock_cpu_hotplug(); - cpu = next_cpu_const(cpu, mk_cpumask_const(cpu_online_map)); + cpu = next_cpu(cpu, cpu_online_map); if (cpu == NR_CPUS) - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); } error: diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 718504a32741..3c3a310be3e1 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1384,7 +1384,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) unsigned long flags; unsigned int dest; - dest = cpu_mask_to_apicid(mk_cpumask_const(mask)); + dest = cpu_mask_to_apicid(mask); /* * Only the first 8 bits are valid. diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index fd1c2d79131d..261700eacb18 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -148,7 +148,7 @@ static void flush_gart(struct pci_dev *dev) { unsigned long flags; int bus = dev ? dev->bus->number : -1; - cpumask_const_t bus_cpumask = pcibus_to_cpumask(bus); + cpumask_t bus_cpumask = pcibus_to_cpumask(bus); int flushed = 0; int i; @@ -158,7 +158,7 @@ static void flush_gart(struct pci_dev *dev) u32 w; if (!northbridges[i]) continue; - if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask))) + if (bus >= 0 && !(cpu_isset(i, bus_cpumask))) continue; pci_write_config_dword(northbridges[i], 0x9c, northbridge_flush_word[i] | 1); diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index fec777046b9a..4246255697ab 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -94,7 +94,7 @@ void send_IPI_self(int vector) static inline void send_IPI_mask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 2878896de037..7fe450245697 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -105,7 +105,6 @@ static inline int cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #endif /* !ASSEMBLY */ #define NO_PROC_ID 0xFF /* No processor magic marker */ @@ -115,9 +114,9 @@ static inline int cpu_present_to_apicid(int mps_cpu) #define TARGET_CPUS 1 #ifndef ASSEMBLY -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } #endif -- cgit v1.2.3 From b8a02d077cb2e53046000591485d4767192f491a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:48 -0700 Subject: [PATCH] x86_64: cpu_online fix Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/smp.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 7fe450245697..c210e398a649 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -60,7 +60,6 @@ extern char phys_proc_id[NR_CPUS]; extern cpumask_t cpu_callout_map; #define cpu_possible_map cpu_callout_map -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) static inline int num_booting_cpus(void) { -- cgit v1.2.3 From ea72b2418251ee5b377136929b47ed83a24492cf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:59 -0700 Subject: [PATCH] ppc64: cpu_online fix include/asm/smp.h:55:1: warning: "cpu_possible" redefined include/asm/smp.h:54:1: warning: "cpu_online" redefined Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/smp.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index 3d7e3d7c7663..3b14c7145546 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -51,8 +51,6 @@ extern cpumask_t cpu_possible_map; extern cpumask_t cpu_available_map; #define cpu_present_at_boot(cpu) cpu_isset(cpu, cpu_present_at_boot) -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) #define cpu_available(cpu) cpu_isset(cpu, cpu_available_map) /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. -- cgit v1.2.3 From 5ffa67fc1233d9d065f9b3fcd6bc13425af54f89 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:10 -0700 Subject: [PATCH] cpumask: Remove no longer used obsolete macro emulation From: Paul Jackson Now that the emulation of the obsolete cpumask macros is no longer needed, remove it from cpumask.h Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index f05bf9402dfc..4d2cf59e5089 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -364,16 +364,4 @@ extern cpumask_t cpu_present_map; #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) -/* Begin obsolete cpumask operator emulation */ -#define cpu_isset_const(a,b) cpu_isset(a,b) -#define cpumask_const_t cpumask_t -#define cpus_coerce(m) (cpus_addr(m)[0]) -#define cpus_coerce_const cpus_coerce -#define cpus_promote(x) ({ cpumask_t m; m.bits[0] = x; m; }) -#define cpus_weight_const cpus_weight -#define first_cpu_const first_cpu -#define mk_cpumask_const(x) x -#define next_cpu_const next_cpu -/* End of obsolete cpumask operator emulation */ - #endif /* __LINUX_CPUMASK_H */ -- cgit v1.2.3 From 4b81e400a9ea37a5888434234befaf389a36e72b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:21 -0700 Subject: [PATCH] cpumask: optimize various uses of new cpumasks From: Paul Jackson Make use of for_each_cpu_mask() macro to simplify and optimize a couple of sparc64 per-CPU loops. Optimize a bit of cpumask code for asm-i386/mach-es7000 Convert physids_complement() to use both args in the files include/asm-i386/mpspec.h, include/asm-x86_64/mpspec.h. Remove cpumask hack from asm-x86_64/topology.h routine pcibus_to_cpumask(). Clarify and slightly optimize several cpumask manipulations in kernel/sched.c Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/smp.c | 66 ++++++++++++--------------------- include/asm-i386/mach-es7000/mach_ipi.h | 5 +-- include/asm-i386/mpspec.h | 2 +- include/asm-x86_64/mpspec.h | 2 +- include/asm-x86_64/topology.h | 6 ++- kernel/sched.c | 18 ++++----- 6 files changed, 39 insertions(+), 60 deletions(-) (limited to 'include') diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 64b873212243..58c3792b4af1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -406,14 +406,8 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c int i; __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, mask)) { - spitfire_xcall_helper(data0, data1, data2, pstate, i); - cpu_clear(i, mask); - if (cpus_empty(mask)) - break; - } - } + for_each_cpu_mask(i, mask) + spitfire_xcall_helper(data0, data1, data2, pstate, i); } /* Cheetah now allows to send the whole 64-bytes of data in the interrupt @@ -456,25 +450,19 @@ retry: nack_busy_id = 0; { - cpumask_t work_mask = mask; int i; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 target = (i << 14) | 0x70; - - if (!is_jalapeno) - target |= (nack_busy_id << 24); - __asm__ __volatile__( - "stxa %%g0, [%0] %1\n\t" - "membar #Sync\n\t" - : /* no outputs */ - : "r" (target), "i" (ASI_INTR_W)); - nack_busy_id++; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 target = (i << 14) | 0x70; + + if (!is_jalapeno) + target |= (nack_busy_id << 24); + __asm__ __volatile__( + "stxa %%g0, [%0] %1\n\t" + "membar #Sync\n\t" + : /* no outputs */ + : "r" (target), "i" (ASI_INTR_W)); + nack_busy_id++; } } @@ -507,7 +495,6 @@ retry: printk("CPU[%d]: mondo stuckage result[%016lx]\n", smp_processor_id(), dispatch_stat); } else { - cpumask_t work_mask = mask; int i, this_busy_nack = 0; /* Delay some random time with interrupts enabled @@ -518,22 +505,17 @@ retry: /* Clear out the mask bits for cpus which did not * NACK us. */ - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 check_mask; - - if (is_jalapeno) - check_mask = (0x2UL << (2*i)); - else - check_mask = (0x2UL << - this_busy_nack); - if ((dispatch_stat & check_mask) == 0) - cpu_clear(i, mask); - this_busy_nack += 2; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 check_mask; + + if (is_jalapeno) + check_mask = (0x2UL << (2*i)); + else + check_mask = (0x2UL << + this_busy_nack); + if ((dispatch_stat & check_mask) == 0) + cpu_clear(i, mask); + this_busy_nack += 2; } goto retry; diff --git a/include/asm-i386/mach-es7000/mach_ipi.h b/include/asm-i386/mach-es7000/mach_ipi.h index 6b7a56c1ddd5..cb8a2fdb5c59 100644 --- a/include/asm-i386/mach-es7000/mach_ipi.h +++ b/include/asm-i386/mach-es7000/mach_ipi.h @@ -10,9 +10,8 @@ static inline void send_IPI_mask(cpumask_t mask, int vector) static inline void send_IPI_allbutself(int vector) { - cpumask_t mask = cpumask_of_cpu(smp_processor_id()); - cpus_complement(mask); - cpus_and(mask, mask, cpu_online_map); + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index 31a9717c1a8b..8170e019af8d 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h @@ -53,7 +53,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) +#define physids_complement(dst, src) bitmap_complement((dst).mask,(src).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h index a9a6f16672f2..219d40acd489 100644 --- a/include/asm-x86_64/mpspec.h +++ b/include/asm-x86_64/mpspec.h @@ -212,7 +212,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) +#define physids_complement(dst, src) bitmap_complement((dst).mask, (src).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index bb9a99ba2065..9310f9a1c1c5 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h @@ -20,9 +20,11 @@ extern cpumask_t node_to_cpumask[]; #define node_to_first_cpu(node) (__ffs(node_to_cpumask[node])) #define node_to_cpumask(node) (node_to_cpumask[node]) -static inline unsigned long pcibus_to_cpumask(int bus) +static inline cpumask_t pcibus_to_cpumask(int bus) { - return mp_bus_to_cpumask[bus] & cpu_online_map; + cpumask_t tmp; + cpus_and(tmp, mp_bus_to_cpumask[bus], cpu_online_map); + return tmp; } #define NODE_BALANCE_RATE 30 /* CHECKME */ diff --git a/kernel/sched.c b/kernel/sched.c index f0103ee1d66a..017b59b8de5e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -696,10 +696,9 @@ static int wake_idle(int cpu, task_t *p) return cpu; cpus_and(tmp, sd->span, cpu_online_map); - for_each_cpu_mask(i, tmp) { - if (!cpu_isset(i, p->cpus_allowed)) - continue; + cpus_and(tmp, tmp, p->cpus_allowed); + for_each_cpu_mask(i, tmp) { if (idle_cpu(i)) return i; } @@ -3335,7 +3334,7 @@ int set_cpus_allowed(task_t *p, cpumask_t new_mask) runqueue_t *rq; rq = task_rq_lock(p, &flags); - if (any_online_cpu(new_mask) == NR_CPUS) { + if (!cpus_intersects(new_mask, cpu_online_map)) { ret = -EINVAL; goto out; } @@ -3510,8 +3509,7 @@ static void migrate_all_tasks(int src_cpu) if (dest_cpu == NR_CPUS) dest_cpu = any_online_cpu(tsk->cpus_allowed); if (dest_cpu == NR_CPUS) { - cpus_clear(tsk->cpus_allowed); - cpus_complement(tsk->cpus_allowed); + cpus_setall(tsk->cpus_allowed); dest_cpu = any_online_cpu(tsk->cpus_allowed); /* Don't tell them about moving exiting tasks @@ -3827,7 +3825,7 @@ void sched_domain_debug(void) int j; char str[NR_CPUS]; struct sched_group *group = sd->groups; - cpumask_t groupmask, tmp; + cpumask_t groupmask; cpumask_scnprintf(str, NR_CPUS, sd->span); cpus_clear(groupmask); @@ -3857,8 +3855,7 @@ void sched_domain_debug(void) if (!cpus_weight(group->cpumask)) printk(" ERROR empty group:"); - cpus_and(tmp, groupmask, group->cpumask); - if (cpus_weight(tmp) > 0) + if (cpus_intersects(groupmask, group->cpumask)) printk(" ERROR repeated CPUs:"); cpus_or(groupmask, groupmask, group->cpumask); @@ -3877,8 +3874,7 @@ void sched_domain_debug(void) sd = sd->parent; if (sd) { - cpus_and(tmp, groupmask, sd->span); - if (!cpus_equal(tmp, groupmask)) + if (!cpus_subset(groupmask, sd->span)) printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n"); } -- cgit v1.2.3 From 02d7effd5c525290aad9c0fa491dd9a3f035380e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:33 -0700 Subject: [PATCH] cpumask: comment, spacing tweaks From: Paul Jackson Tweak cpumask.h comments, spacing: - Add comments for cpu_present_map macros: num_present_cpus() and cpu_present() - Remove comments for obsolete macros: cpu_set_online(), cpu_set_offline() - Reorder a few comment lines, to match the code and confuse readers of this patch - Tabify one chunk of code Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 4d2cf59e5089..1d06e38480f7 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -47,17 +47,21 @@ * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask * + * for_each_cpu_mask(cpu, mask) for-loop cpu over mask + * * int num_online_cpus() Number of online CPUs * int num_possible_cpus() Number of all possible CPUs + * int num_present_cpus() Number of present CPUs + * * int cpu_online(cpu) Is some cpu online? * int cpu_possible(cpu) Is some cpu possible? - * void cpu_set_online(cpu) set cpu in cpu_online_map - * void cpu_set_offline(cpu) clear cpu in cpu_online_map + * int cpu_present(cpu) Is some cpu present (can schedule)? + * * int any_online_cpu(mask) First online cpu in mask * - * for_each_cpu_mask(cpu, mask) for-loop cpu over mask * for_each_cpu(cpu) for-loop cpu over cpu_possible_map * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map + * for_each_present_cpu(cpu) for-loop cpu over cpu_present_map * * Subtlety: * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway) @@ -336,19 +340,19 @@ extern cpumask_t cpu_online_map; extern cpumask_t cpu_present_map; #if NR_CPUS > 1 -#define num_online_cpus() cpus_weight(cpu_online_map) -#define num_possible_cpus() cpus_weight(cpu_possible_map) -#define num_present_cpus() cpus_weight(cpu_present_map) -#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) -#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) -#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) +#define num_online_cpus() cpus_weight(cpu_online_map) +#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) +#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) +#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) #else -#define num_online_cpus() 1 -#define num_possible_cpus() 1 -#define num_present_cpus() 1 -#define cpu_online(cpu) ((cpu) == 0) -#define cpu_possible(cpu) ((cpu) == 0) -#define cpu_present(cpu) ((cpu) == 0) +#define num_online_cpus() 1 +#define num_possible_cpus() 1 +#define num_present_cpus() 1 +#define cpu_online(cpu) ((cpu) == 0) +#define cpu_possible(cpu) ((cpu) == 0) +#define cpu_present(cpu) ((cpu) == 0) #endif #define any_online_cpu(mask) \ -- cgit v1.2.3 From a3dcb7f41eced06d4e43365fefd98a3b9b48e340 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:44 -0700 Subject: [PATCH] clean up cpumask_t temporaries From: Rusty Russell Paul Jackson's cpumask tour-de-force allows us to get rid of those stupid temporaries which we used to hold CPU_MASK_ALL to hand them to functions. This used to break NR_CPUS > BITS_PER_LONG. Signed-off-by: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/irq.c | 3 +-- arch/ppc64/kernel/rtasd.c | 3 +-- arch/ppc64/kernel/xics.c | 6 ++---- include/asm-i386/mach-numaq/mach_apic.h | 3 +-- include/asm-i386/mach-summit/mach_apic.h | 3 +-- kernel/kmod.c | 3 +-- kernel/kthread.c | 3 +-- kernel/sched.c | 5 ++--- 8 files changed, 10 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 7335442e4178..004c3c1a034e 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -738,7 +738,6 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer irq_desc_t *desc = get_irq_desc(irq); int ret; cpumask_t new_value, tmp; - cpumask_t allcpus = CPU_MASK_ALL; if (!desc->handler->set_affinity) return -EIO; @@ -753,7 +752,7 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer * NR_CPUS == 32 and cpumask is a long), so we mask it here to * be consistent. */ - cpus_and(new_value, new_value, allcpus); + cpus_and(new_value, new_value, CPU_MASK_ALL); /* * Grab lock here so cpu_online_map can't change, and also diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index 243d2ee8de8a..aa649a24a947 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c @@ -364,7 +364,6 @@ static int rtasd(void *unused) unsigned int err_type; int cpu = 0; int event_scan = rtas_token("event-scan"); - cpumask_t all = CPU_MASK_ALL; int rc; daemonize("rtasd"); @@ -419,7 +418,7 @@ static int rtasd(void *unused) for (;;) { set_cpus_allowed(current, cpumask_of_cpu(cpu)); do_event_scan(event_scan); - set_cpus_allowed(current, all); + set_cpus_allowed(current, CPU_MASK_ALL); /* Drop hotplug lock, and sleep for a bit (at least * one second since some machines have problems if we diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 1d9cf20a2900..32adc8c22953 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -240,14 +240,13 @@ static unsigned int real_irq_to_virt(unsigned int real_irq) static int get_irq_server(unsigned int irq) { cpumask_t cpumask = irq_affinity[irq]; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; unsigned int server; #ifdef CONFIG_IRQ_ALL_CPUS /* For the moment only implement delivery to all cpus or one cpu */ if (smp_threads_ready) { - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { server = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); @@ -616,7 +615,6 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) long status; unsigned long xics_status[2]; unsigned long newmask; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; irq = virt_irq_to_real(irq_offset_down(virq)); @@ -632,7 +630,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) } /* For the moment only implement delivery to all cpus or one cpu */ - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { newmask = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index e40c308b15d3..b852593a1c7b 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -8,8 +8,7 @@ static inline cpumask_t target_cpus(void) { - cpumask_t tmp = CPU_MASK_ALL; - return tmp; + return CPU_MASK_ALL; } #define TARGET_CPUS (target_cpus()) diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 4bf36ddba96d..214263a48f71 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -19,8 +19,7 @@ static inline cpumask_t target_cpus(void) { - cpumask_t tmp = CPU_MASK_ALL; - return tmp; + return CPU_MASK_ALL; } #define TARGET_CPUS (target_cpus()) diff --git a/kernel/kmod.c b/kernel/kmod.c index ea62192b7597..579269c38a3b 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -154,7 +154,6 @@ static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; int retval; - cpumask_t mask = CPU_MASK_ALL; /* Unblock all signals. */ flush_signals(current); @@ -165,7 +164,7 @@ static int ____call_usermodehelper(void *data) spin_unlock_irq(¤t->sighand->siglock); /* We can run anywhere, unlike our parent keventd(). */ - set_cpus_allowed(current, mask); + set_cpus_allowed(current, CPU_MASK_ALL); retval = -EPERM; if (current->fs->root) diff --git a/kernel/kthread.c b/kernel/kthread.c index da0ec5b25cdf..5689ebb1a250 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -65,7 +65,6 @@ static int kthread(void *_create) void *data; sigset_t blocked; int ret = -EINTR; - cpumask_t mask = CPU_MASK_ALL; kthread_exit_files(); @@ -79,7 +78,7 @@ static int kthread(void *_create) flush_signals(current); /* By default we can run anywhere, unlike keventd. */ - set_cpus_allowed(current, mask); + set_cpus_allowed(current, CPU_MASK_ALL); /* OK, tell user we're spawned, wait for stop or wakeup */ __set_current_state(TASK_INTERRUPTIBLE); diff --git a/kernel/sched.c b/kernel/sched.c index 017b59b8de5e..95f18cf8a5b6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3913,16 +3913,15 @@ void __init sched_init(void) /* Set up an initial dummy domain for early boot */ static struct sched_domain sched_domain_init; static struct sched_group sched_group_init; - cpumask_t cpu_mask_all = CPU_MASK_ALL; memset(&sched_domain_init, 0, sizeof(struct sched_domain)); - sched_domain_init.span = cpu_mask_all; + sched_domain_init.span = CPU_MASK_ALL; sched_domain_init.groups = &sched_group_init; sched_domain_init.last_balance = jiffies; sched_domain_init.balance_interval = INT_MAX; /* Don't balance */ memset(&sched_group_init, 0, sizeof(struct sched_group)); - sched_group_init.cpumask = cpu_mask_all; + sched_group_init.cpumask = CPU_MASK_ALL; sched_group_init.next = &sched_group_init; sched_group_init.cpu_power = SCHED_LOAD_SCALE; #endif -- cgit v1.2.3 From 4320cbbd16791e039a04c390aa778a66c18220cd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:55 -0700 Subject: [PATCH] alpha: cpumask fixups From: William Lee Irwin III The cpumask patches broke alpha's build, even without the irqaction patch, largely centering around cpu_possible_map. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq.c | 63 ++++++++----------------------------------- arch/alpha/kernel/process.c | 4 +-- arch/alpha/kernel/setup.c | 4 +-- arch/alpha/kernel/smp.c | 39 ++++++++++++--------------- arch/alpha/kernel/sys_dp264.c | 17 ++++++------ include/asm-alpha/smp.h | 4 +-- 6 files changed, 41 insertions(+), 90 deletions(-) (limited to 'include') diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 9e8eab6dcc0a..0b2f63016044 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -227,7 +227,7 @@ static struct proc_dir_entry * irq_dir[NR_IRQS]; #ifdef CONFIG_SMP static struct proc_dir_entry * smp_affinity_entry[NR_IRQS]; static char irq_user_affinity[NR_IRQS]; -static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; static void select_smp_affinity(int irq) @@ -238,16 +238,14 @@ select_smp_affinity(int irq) if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) return; - while (((cpu_present_mask >> cpu) & 1) == 0) + while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = 1UL << cpu; - irq_desc[irq].handler->set_affinity(irq, 1UL << cpu); + irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); } -#define HEX_DIGITS 16 - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) @@ -259,67 +257,28 @@ irq_affinity_read_proc (char *page, char **start, off_t off, return len; } -static unsigned int -parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - unsigned long i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value; if (!irq_desc[irq].handler->set_affinity) return -EIO; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* The special value 0 means release control of the affinity to kernel. */ - if (new_value == 0) { + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) { irq_user_affinity[irq] = 0; select_smp_affinity(irq); } /* Do not allow disabling IRQs completely - it's a too easy way to make the system unusable accidentally :-) At least one online CPU still has to be targeted. */ - else if (!(new_value & cpu_present_mask)) - return -EINVAL; else { irq_affinity[irq] = new_value; irq_user_affinity[irq] = 1; @@ -344,10 +303,10 @@ static int prof_cpu_mask_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + unsigned long full_count = count, err; + cpumask_t new_value, *mask = (cpumask_t *)data; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index f5c5969b7cae..c82286424aa2 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -119,8 +119,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - clear_bit(boot_cpuid, &cpu_present_mask); - while (cpu_present_mask) + cpu_clear(boot_cpuid, cpu_possible_map); + while (cpus_weight(cpu_possible_map)) barrier(); #endif diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 4e93fe9cc6b6..c637c38d5b0e 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -1245,9 +1245,9 @@ show_cpuinfo(struct seq_file *f, void *slot) platform_string(), nr_processors); #ifdef CONFIG_SMP - seq_printf(f, "cpus active\t\t: %ld\n" + seq_printf(f, "cpus active\t\t: %d\n" "cpu active mask\t\t: %016lx\n", - num_online_cpus(), cpu_present_mask); + num_online_cpus(), cpus_addr(cpu_possible_map)[0]); #endif show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape); diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 9f4aed85950f..5e0dc627838c 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -68,7 +68,7 @@ enum ipi_message_type { static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ -unsigned long cpu_present_mask; +cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -522,7 +522,7 @@ setup_smp(void) smp_num_probed = 1; hwrpb_cpu_present_mask = (1UL << boot_cpuid); } - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", smp_num_probed, hwrpb_cpu_present_mask); @@ -547,7 +547,7 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -562,7 +562,7 @@ smp_prepare_cpus(unsigned int max_cpus) if (((hwrpb_cpu_present_mask >> i) & 1) == 0) continue; - cpu_present_mask |= 1UL << i; + cpu_set(i, cpu_possible_map); cpu_count++; } @@ -597,7 +597,7 @@ smp_cpus_done(unsigned int max_cpus) if (cpu_online(cpu)) bogosum += cpu_data[cpu].loops_per_jiffy; - printk(KERN_INFO "SMP: Total of %ld processors activated " + printk(KERN_INFO "SMP: Total of %d processors activated " "(%lu.%02lu BogoMIPS).\n", num_online_cpus(), (bogosum + 2500) / (500000/HZ), @@ -638,23 +638,17 @@ setup_profiling_timer(unsigned int multiplier) static void -send_ipi_message(unsigned long to_whom, enum ipi_message_type operation) +send_ipi_message(cpumask_t to_whom, enum ipi_message_type operation) { - unsigned long i, set, n; + int i; mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - set_bit(operation, &ipi_data[n].bits); - } + for_each_cpu_mask(i, to_whom) + set_bit(operation, &ipi_data[i].bits); mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - wripir(n); - } + for_each_cpu_mask(i, to_whom) + wripir(i); } /* Structure and data for smp_call_function. This is designed to @@ -784,13 +778,14 @@ smp_send_reschedule(int cpu) printk(KERN_WARNING "smp_send_reschedule: Sending IPI to self.\n"); #endif - send_ipi_message(1UL << cpu, IPI_RESCHEDULE); + send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) { - unsigned long to_whom = cpu_present_mask & ~(1UL << smp_processor_id()); + cpumask_t to_whom = cpu_possible_map; + cpu_clear(smp_processor_id(), to_whom); #ifdef DEBUG_IPI_MSG if (hard_smp_processor_id() != boot_cpu_id) printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n"); @@ -814,7 +809,7 @@ smp_send_stop(void) int smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, - int wait, unsigned long to_whom) + int wait, cpumask_t to_whom) { struct smp_call_struct data; unsigned long timeout; @@ -827,8 +822,8 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, data.info = info; data.wait = wait; - to_whom &= ~(1L << smp_processor_id()); - num_cpus_to_call = hweight64(to_whom); + cpu_clear(smp_processor_id(), to_whom); + num_cpus_to_call = cpus_weight(to_whom); atomic_set(&data.unstarted_count, num_cpus_to_call); atomic_set(&data.unfinished_count, num_cpus_to_call); diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 307ce54aca38..119501849e95 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -53,7 +53,6 @@ tsunami_update_irq_hw(unsigned long mask) register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - register unsigned long cpm = cpu_present_mask; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; @@ -72,10 +71,10 @@ tsunami_update_irq_hw(unsigned long mask) dim1 = &cchip->dim1.csr; dim2 = &cchip->dim2.csr; dim3 = &cchip->dim3.csr; - if ((cpm & 1) == 0) dim0 = &dummy; - if ((cpm & 2) == 0) dim1 = &dummy; - if ((cpm & 4) == 0) dim2 = &dummy; - if ((cpm & 8) == 0) dim3 = &dummy; + if (cpu_possible(0)) dim0 = &dummy; + if (cpu_possible(1)) dim1 = &dummy; + if (cpu_possible(2)) dim2 = &dummy; + if (cpu_possible(3)) dim3 = &dummy; *dim0 = mask0; *dim1 = mask1; @@ -164,13 +163,13 @@ clipper_end_irq(unsigned int irq) } static void -cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) +cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) { int cpu; for (cpu = 0; cpu < 4; cpu++) { unsigned long aff = cpu_irq_affinity[cpu]; - if (affinity & (1UL << cpu)) + if (cpu_isset(cpu, affinity)) aff |= 1UL << irq; else aff &= ~(1UL << irq); @@ -179,7 +178,7 @@ cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) } static void -dp264_set_affinity(unsigned int irq, unsigned long affinity) +dp264_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq, affinity); @@ -188,7 +187,7 @@ dp264_set_affinity(unsigned int irq, unsigned long affinity) } static void -clipper_set_affinity(unsigned int irq, unsigned long affinity) +clipper_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq - 16, affinity); diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h index d342a017ceb6..cbc173ae45aa 100644 --- a/include/asm-alpha/smp.h +++ b/include/asm-alpha/smp.h @@ -50,9 +50,7 @@ extern cpumask_t cpu_online_map; extern int smp_num_cpus; #define cpu_possible_map cpu_present_mask -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - -extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu); +int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, cpumask_t cpu); #else /* CONFIG_SMP */ -- cgit v1.2.3 From 8c05319ff168610fd6e3ce043bf5217a9ff7a4f3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:08 -0700 Subject: [PATCH] make irqaction use a cpu mask From: William Lee Irwin III The following patch makes irqaction's ->mask a cpumask as it was intended to be and wraps up the rest of the sweep. Only struct irqaction is usefully greppable, so there may be some assignments to ->mask missing still. This removes more code than it adds. From: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq.c | 2 +- arch/arm/kernel/irq.c | 2 +- arch/arm/mach-clps7500/core.c | 2 +- arch/arm26/kernel/irq.c | 2 +- arch/cris/arch-v10/kernel/time.c | 2 +- arch/cris/kernel/irq.c | 2 +- arch/i386/kernel/i8259.c | 2 +- arch/i386/kernel/irq.c | 2 +- arch/i386/mach-default/setup.c | 4 +- arch/i386/mach-voyager/setup.c | 4 +- arch/ia64/kernel/irq.c | 2 +- arch/mips/baget/irq.c | 4 +- arch/mips/baget/time.c | 2 +- arch/mips/ddb5xxx/ddb5074/irq.c | 2 +- arch/mips/ddb5xxx/ddb5476/irq.c | 4 +- arch/mips/ddb5xxx/ddb5477/irq.c | 2 +- arch/mips/gt64120/common/time.c | 2 +- arch/mips/jmr3927/rbhma3100/irq.c | 8 +-- arch/mips/kernel/irq.c | 2 +- arch/mips/momentum/jaguar_atx/irq.c | 2 +- arch/mips/momentum/ocelot_c/irq.c | 4 +- arch/mips/sgi-ip32/ip32-irq.c | 4 +- arch/mips/sibyte/sb1250/irq.c | 2 +- arch/mips/tx4927/common/tx4927_irq.c | 2 +- .../tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 4 +- arch/mips/vr4181/common/irq.c | 4 +- arch/mips/vr41xx/common/giu.c | 2 +- arch/mips/vr41xx/common/icu.c | 2 +- arch/parisc/kernel/irq.c | 2 +- arch/ppc/kernel/irq.c | 2 +- arch/ppc64/kernel/irq.c | 2 +- arch/sh/cchips/hd6446x/hd64461/setup.c | 2 +- arch/sh/cchips/hd6446x/hd64465/setup.c | 2 +- arch/sh/kernel/irq.c | 2 +- arch/sh/kernel/time.c | 2 +- arch/sparc/kernel/irq.c | 4 +- arch/sparc/kernel/sun4d_irq.c | 2 +- arch/sparc64/kernel/irq.c | 68 ++++------------------ arch/sparc64/kernel/smp.c | 3 - arch/um/kernel/irq.c | 2 +- arch/v850/kernel/fpga85e2c.c | 2 +- arch/v850/kernel/irq.c | 2 +- arch/v850/kernel/time.c | 2 +- arch/x86_64/kernel/i8259.c | 2 +- arch/x86_64/kernel/irq.c | 2 +- arch/x86_64/kernel/time.c | 2 +- include/linux/interrupt.h | 3 +- 47 files changed, 68 insertions(+), 118 deletions(-) (limited to 'include') diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 0b2f63016044..b52a52b7b918 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -416,7 +416,7 @@ request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 5777a8c2faec..68636bd7c2be 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -674,7 +674,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index ee1a3192ad7b..11fa530af3ba 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -188,7 +188,7 @@ static struct irqchip clps7500_no_chip = { .unmask = cl7500_no_action, }; -static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL }; +static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; static void __init clps7500_init_irq(void) { diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c index d627cedab805..7869d1b22621 100644 --- a/arch/arm26/kernel/irq.c +++ b/arch/arm26/kernel/irq.c @@ -549,7 +549,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index c4d78d52f774..298e86a01c01 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -253,7 +253,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ static struct irqaction irq2 = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT, - 0, "timer", NULL, NULL}; + CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index a963dda74413..94d70279058e 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -240,7 +240,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 92061fd4cc0b..fc991989284b 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -332,7 +332,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) * New motherboards sometimes make IRQ 13 be a PCI interrupt, * so allow interrupt sharing. */ -static struct irqaction fpu_irq = { math_error_irq, 0, 0, "fpu", NULL, NULL }; +static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; void __init init_ISA_irqs (void) { diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index cd2ed69f8367..ba2055a3959b 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -652,7 +652,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index 718f718d0d78..0aa08eaa8932 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c @@ -27,7 +27,7 @@ void __init pre_intr_init_hook(void) /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; /** * intr_init_hook - post gate setup interrupt initialisation @@ -71,7 +71,7 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; /** * time_init_hook - do any specific initialisations for the system timer. diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index 9bbf8953f833..df123fc487bb 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c @@ -17,7 +17,7 @@ void __init pre_intr_init_hook(void) /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init intr_init_hook(void) { @@ -40,7 +40,7 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 3087c13d08d7..8355dda0188c 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -607,7 +607,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c index fe158acf8921..d2067c037c35 100644 --- a/arch/mips/baget/irq.c +++ b/arch/mips/baget/irq.c @@ -325,7 +325,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -389,7 +389,7 @@ static void write_err_interrupt(int irq, void *dev_id, struct pt_regs * regs) } static struct irqaction irq0 = -{ write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; +{ write_err_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "bus write error", NULL, NULL}; void __init init_IRQ(void) { diff --git a/arch/mips/baget/time.c b/arch/mips/baget/time.c index 205bde31215e..ed82c62df3d6 100644 --- a/arch/mips/baget/time.c +++ b/arch/mips/baget/time.c @@ -67,7 +67,7 @@ static void __init timer_enable(void) } static struct irqaction timer_irq = -{ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +{ timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) { diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c index dc4e643496b2..547386de484a 100644 --- a/arch/mips/ddb5xxx/ddb5074/irq.c +++ b/arch/mips/ddb5xxx/ddb5074/irq.c @@ -24,7 +24,7 @@ extern asmlinkage void ddbIRQ(void); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ #define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c index 58e794f01ed5..6a1202aec98f 100644 --- a/arch/mips/ddb5xxx/ddb5476/irq.c +++ b/arch/mips/ddb5xxx/ddb5476/irq.c @@ -107,8 +107,8 @@ static void nile4_irq_setup(void) /* memory resource acquire in ddb_setup */ } -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; -static struct irqaction irq_error = { no_action, 0, 0, "error", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; +static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; extern asmlinkage void ddb5476_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 0ae83365fe75..dfc2559aaace 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c @@ -77,7 +77,7 @@ extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; void ddb5477_irq_setup(void) diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index 86a2100db00d..44f33caf298e 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c @@ -80,7 +80,7 @@ void gt64120_time_init(void) timer.name = "timer"; timer.dev_id = NULL; timer.next = NULL; - timer.mask = 0; + timer.mask = CPU_MASK_NONE; irq_desc[GT_TIMER].action = &timer; enable_irq(GT_TIMER); diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 442dc6df4b6b..4ab85b5b2b4d 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -301,7 +301,7 @@ static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static struct irqaction ioc_action = { - jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL, + jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -318,7 +318,7 @@ static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static struct irqaction isac_action = { - jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL, + jmr3927_isac_interrupt, 0, CPU_MASK_NONE, "ISAC", NULL, NULL, }; @@ -327,7 +327,7 @@ static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * re printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); } static struct irqaction isaerr_action = { - jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL, + jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, }; static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) @@ -337,7 +337,7 @@ static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * re tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); } static struct irqaction pcierr_action = { - jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL, + jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL, }; int jmr3927_ether1_irq = 0; diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 845e0914ffe5..13acf876b46f 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -487,7 +487,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c index f13f856067e7..cc25cbcb4bb2 100644 --- a/arch/mips/momentum/jaguar_atx/irq.c +++ b/arch/mips/momentum/jaguar_atx/irq.c @@ -42,7 +42,7 @@ extern asmlinkage void jaguar_handle_int(void); static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "MV64340-Cascade", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL }; void __init init_IRQ(void) diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index d12f5befdf6f..37ad81291d82 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c @@ -53,11 +53,11 @@ extern void uart_irq_init(void); extern void cpci_irq_init(void); static struct irqaction cascade_fpga = { - no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL }; static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL }; void __init init_IRQ(void) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 5091454ca197..75846d6e8154 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -123,9 +123,9 @@ extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id, struct pt_regs *regs); struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, NULL }; + CPU_MASK_NONE, "CRIME memory error", NULL, NULL }; struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, NULL }; + CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; extern void ip32_handle_int(void); diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index e2216ee9ba49..ddbe64b2d371 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -279,7 +279,7 @@ static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id, static struct irqaction sb1250_dummy_action = { .handler = sb1250_dummy_handler, .flags = 0, - .mask = 0, + .mask = CPU_MASK_NONE, .name = "sb1250-private", .next = NULL, .dev_id = 0 diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 14591d16e41a..bf59409eea36 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -172,7 +172,7 @@ static struct hw_interrupt_type tx4927_irq_pic_type = { .set_affinity = NULL }; -#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction tx4927_irq_pic_action = TX4927_PIC_ACTION(TX4927_PIC_NAME); diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index f4fe81eb7a28..930304585443 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -337,8 +337,8 @@ int toshiba_rbtx4927_irq_nested(int sw_irq) return (sw_irq); } -//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } -#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction toshiba_rbtx4927_irq_ioc_action = TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); #ifdef CONFIG_TOSHIBA_FPCIB0 diff --git a/arch/mips/vr4181/common/irq.c b/arch/mips/vr4181/common/irq.c index 7b5a1a4f313c..4a2458f8bc8b 100644 --- a/arch/mips/vr4181/common/irq.c +++ b/arch/mips/vr4181/common/irq.c @@ -180,9 +180,9 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); extern void mips_cpu_irq_init(u32 irq_base); static struct irqaction cascade = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; static struct irqaction reserved = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; void __init init_IRQ(void) { diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c index 6fe6a73ff99b..6ee189968e8b 100644 --- a/arch/mips/vr41xx/common/giu.c +++ b/arch/mips/vr41xx/common/giu.c @@ -209,7 +209,7 @@ struct vr41xx_giuint_cascade { }; static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS]; -static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction giu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; static int no_irq_number(int irq) { diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index bd67058e4743..1f223d70e4e6 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -288,7 +288,7 @@ static struct hw_interrupt_type giuint_irq_type = { /*=======================================================================*/ -static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction icu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; static void __init vr41xx_icu_init(void) { diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 72f748905f18..ca1acad13e09 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -644,7 +644,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index f3c0d2cc2205..6da092941c73 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -241,7 +241,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 004c3c1a034e..6971f8a0cba0 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -206,7 +206,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c index 5e03ea93838e..f014b9bf6922 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -134,7 +134,7 @@ int hd64461_irq_demux(int irq) return __irq_demux(irq); } -static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL }; +static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64461", NULL, NULL }; int __init setup_hd64461(void) { diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index 73a44a7701bb..68e4c4e4283d 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -154,7 +154,7 @@ int hd64465_irq_demux(int irq) return irq; } -static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, 0, "HD64465", NULL, NULL}; +static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64465", NULL, NULL}; static int __init setup_hd64465(void) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index a37e2d1cffce..18f056b15b74 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -436,7 +436,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index cd91a59a9fff..37d66714edba 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -391,7 +391,7 @@ static int __init sh_pclk_setup(char *str) } __setup("sh_pclk=", sh_pclk_setup); -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc) { diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index 6b1698b5ad6f..237764bb69fd 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -449,7 +449,7 @@ int request_fast_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = NULL; action->next = NULL; @@ -529,7 +529,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 5e9a705c1093..93e385611b95 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -336,7 +336,7 @@ int sun4d_request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 35243558bfc0..10c0c4ed6e89 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -118,10 +118,6 @@ static void register_irq_proc (unsigned int irq); action->flags |= __irq_ino(irq) << 48; #define get_ino_in_irqaction(action) (action->flags >> 48) -#if NR_CPUS > 64 -#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME -#endif - #define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff) #define get_smpaff_in_irqaction(action) ((action)->mask) @@ -458,7 +454,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->next = NULL; action->dev_id = dev_id; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); if (tmp) tmp->next = action; @@ -694,7 +690,7 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) cpumask_t cpu_mask; unsigned int buddy, ticks; - cpus_addr(cpu_mask)[0] = get_smpaff_in_irqaction(ap); + cpu_mask = get_smpaff_in_irqaction(ap); cpus_and(cpu_mask, cpu_mask, cpu_online_map); if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; @@ -715,7 +711,7 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) if (++buddy >= NR_CPUS) buddy = 0; if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, 0); + put_smpaff_in_irqaction(ap, CPU_MASK_NONE); goto out; } } @@ -949,7 +945,7 @@ int request_fast_irq(unsigned int irq, action->name = name; action->next = NULL; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); *(bucket->pil + irq_action) = action; enable_irq(irq); @@ -1167,45 +1163,6 @@ static struct proc_dir_entry * irq_dir [NUM_IVECS]; #ifdef CONFIG_SMP -#define HEX_DIGITS 16 - -static unsigned int parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - int i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1214,7 +1171,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, cpumask_t mask; int len; - cpus_addr(mask)[0] = get_smpaff_in_irqaction(ap); + mask = get_smpaff_in_irqaction(ap); if (cpus_empty(mask)) mask = cpu_online_map; @@ -1225,7 +1182,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, return len; } -static inline void set_intr_affinity(int irq, unsigned long hw_aff) +static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; @@ -1243,22 +1200,17 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value, i; + cpumask_t new_value; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - for (i = 0; i < NR_CPUS; i++) { - if ((new_value & (1UL << i)) != 0 && - !cpu_online(i)) - new_value &= ~(1UL << i); - } - - if (!new_value) + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) return -EINVAL; set_intr_affinity(irq, new_value); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 58c3792b4af1..c0f729f9167f 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -414,9 +414,6 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c * packet, but we have no use for that. However we do take advantage of * the new pipelining feature (ie. dispatch to multiple cpus simultaneously). */ -#if NR_CPUS > 32 -#error Fixup cheetah_xcall_deliver Dave... -#endif static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate, ver; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 5f6c8502a248..0e968bb11a45 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -419,7 +419,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c index 72dda796fac6..17e3dbafc371 100644 --- a/arch/v850/kernel/fpga85e2c.c +++ b/arch/v850/kernel/fpga85e2c.c @@ -168,5 +168,5 @@ static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs) static int reg_snap_dev_id; static struct irqaction reg_snap_action = { - make_reg_snap, 0, 0, "reg_snap", ®_snap_dev_id, 0 + make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", ®_snap_dev_id, 0 }; diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c index a5d918e71be9..d97864021730 100644 --- a/arch/v850/kernel/irq.c +++ b/arch/v850/kernel/irq.c @@ -392,7 +392,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c index fee3e957da5c..74067adea388 100644 --- a/arch/v850/kernel/time.c +++ b/arch/v850/kernel/time.c @@ -203,7 +203,7 @@ static int timer_dev_id; static struct irqaction timer_irqaction = { timer_interrupt, SA_INTERRUPT, - 0, + CPU_MASK_NONE, "timer", &timer_dev_id, NULL diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 304b6a37f58b..8b1e2dffec67 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -365,7 +365,7 @@ void __init init_8259A(int auto_eoi) * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init init_ISA_irqs (void) { diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index bfdb95e8bf95..fcaaa8c17262 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -488,7 +488,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index d47d3f8de44e..10c511f50d1d 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -689,7 +689,7 @@ int __init time_setup(char *str) } static struct irqaction irq0 = { - timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL + timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL }; extern void __init config_acpi_tables(void); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 220f2a8602b4..565321b05213 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,7 @@ typedef int irqreturn_t; struct irqaction { irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; - unsigned long mask; + cpumask_t mask; const char *name; void *dev_id; struct irqaction *next; -- cgit v1.2.3 From 0342e1625c4fdcae2df9817d73225478eeb384a6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:18 -0700 Subject: [PATCH] Fix and Reenable MSI Support on x86_64 From: long MSI support for x86_64 is currently disabled in the kernel 2.6.x. Below is the patch, which provides a fix and reenable it. In addition, the patch provides a info message during kernel boot if configuring vector-base indexing. Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 7 ++++++- arch/x86_64/kernel/i8259.c | 24 ++++++++++++++++++++++++ arch/x86_64/kernel/io_apic.c | 26 ++++++++++++++++++-------- drivers/pci/Kconfig | 2 +- include/asm-x86_64/hw_irq.h | 1 + include/asm-x86_64/msi.h | 7 +------ 6 files changed, 51 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 28b4d7c4e3c6..8a3af5697f64 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1411,12 +1411,17 @@ void __init print_IO_APIC(void) ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 8b1e2dffec67..94e77bd96ff8 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -47,6 +47,12 @@ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) +#define BUILD_14_IRQS(x) \ + BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ + BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ + BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ + BI(x,c) BI(x,d) + /* * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: * (these are usually mapped to vectors 0x20-0x2f) @@ -68,9 +74,15 @@ BUILD_16_IRQS(0x0) BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + BUILD_14_IRQS(0xe) +#endif + #endif #undef BUILD_16_IRQS +#undef BUILD_14_IRQS #undef BI @@ -83,6 +95,12 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) +#define IRQLIST_14(x) \ + IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ + IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ + IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ + IRQ(x,c), IRQ(x,d) + void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), @@ -91,11 +109,17 @@ void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), IRQLIST_16(0xc), IRQLIST_16(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + , IRQLIST_14(0xe) +#endif + #endif }; #undef IRQ #undef IRQLIST_16 +#undef IRQLIST_14 /* * This is the 'legacy' 8259A Programmable Interrupt Controller, diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 3c3a310be3e1..3869af670b28 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -67,8 +67,8 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; #ifdef CONFIG_PCI_USE_VECTOR -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; #define vector_to_irq(vector) \ (platform_legacy_irq(vector) ? vector : vector_irq[vector]) #else @@ -656,10 +656,14 @@ static inline int IO_APIC_irq_trigger(int irq) /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -#ifndef CONFIG_PCI_USE_VECTOR +#ifdef CONFIG_PCI_USE_VECTOR +int assign_irq_vector(int irq) +#else int __init assign_irq_vector(int irq) +#endif { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + BUG_ON(irq >= NR_IRQ_VECTORS); if (IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); @@ -668,18 +672,19 @@ next: if (current_vector == IA32_SYSCALL_VECTOR) goto next; - if (current_vector > FIRST_SYSTEM_VECTOR) { + if (current_vector >= FIRST_SYSTEM_VECTOR) { offset++; + if (!(offset%8)) + return -ENOSPC; current_vector = FIRST_DEVICE_VECTOR + offset; } - if (current_vector == FIRST_SYSTEM_VECTOR) - panic("ran out of interrupt sources!"); + vector_irq[current_vector] = irq; + if (irq != AUTO_ASSIGN) + IO_APIC_VECTOR(irq) = current_vector; - IO_APIC_VECTOR(irq) = current_vector; return current_vector; } -#endif extern void (*interrupt[NR_IRQS])(void); static struct hw_interrupt_type ioapic_level_type; @@ -925,12 +930,17 @@ void __init print_IO_APIC(void) ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8f764fd210f..03681b915a56 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -3,7 +3,7 @@ # config PCI_USE_VECTOR bool "Vector-based interrupt indexing (MSI)" - depends on (X86_LOCAL_APIC && X86_IO_APIC && !X86_64) || IA64 + depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 default n help This replaces the current existing IRQ-based index interrupt scheme diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 161edad6afdf..2df689dd6d77 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h @@ -78,6 +78,7 @@ struct hw_interrupt_type; #ifndef __ASSEMBLY__ extern u8 irq_vector[NR_IRQ_VECTORS]; #define IO_APIC_VECTOR(irq) (irq_vector[irq]) +#define AUTO_ASSIGN -1 /* * Various low-level irq details needed by irq.c, process.c, diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h index 727b911f29ca..e0e1e9b3bd87 100644 --- a/include/asm-x86_64/msi.h +++ b/include/asm-x86_64/msi.h @@ -11,11 +11,6 @@ #define LAST_DEVICE_VECTOR 232 #define MSI_DEST_MODE MSI_LOGICAL_MODE #define MSI_TARGET_CPU_SHIFT 12 - -#ifdef CONFIG_SMP -#define MSI_TARGET_CPU logical_smp_processor_id() -#else -#define MSI_TARGET_CPU TARGET_CPUS -#endif +#define MSI_TARGET_CPU TARGET_CPUS #endif /* ASM_MSI_H */ -- cgit v1.2.3 From 2332dc7870b6f40eff03df88cbb03f4ffddbd086 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:40 -0700 Subject: [PATCH] vmscan.c scan rate fixes We've been futzing with the scan rates of the inactive and active lists far too much, and it's still not right (Anton reports interrupt-off times of over a second). - We have this logic in there from 2.4.early (at least) which tries to keep the inactive list 1/3rd the size of the active list. Or something. I really cannot see any logic behind this, so toss it out and change the arithmetic in there so that all pages on both lists have equal scan rates. - Chunk the work up so we never hold interrupts off for more that 32 pages worth of scanning. - Make the per-zone scan-count accumulators unsigned long rather than atomic_t. Mainly because atomic_t's could conceivably overflow, but also because access to these counters is racy-by-design anyway. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 4 +-- mm/page_alloc.c | 4 +-- mm/vmscan.c | 70 ++++++++++++++++++++++---------------------------- 3 files changed, 35 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 373a13ba6f3f..2f41b635580b 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -118,8 +118,8 @@ struct zone { spinlock_t lru_lock; struct list_head active_list; struct list_head inactive_list; - atomic_t nr_scan_active; - atomic_t nr_scan_inactive; + unsigned long nr_scan_active; + unsigned long nr_scan_inactive; unsigned long nr_active; unsigned long nr_inactive; int all_unreclaimable; /* All pages pinned */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 16d5c2af94ee..b30e78c2a939 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1482,8 +1482,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone_names[j], realsize, batch); INIT_LIST_HEAD(&zone->active_list); INIT_LIST_HEAD(&zone->inactive_list); - atomic_set(&zone->nr_scan_active, 0); - atomic_set(&zone->nr_scan_inactive, 0); + zone->nr_scan_active = 0; + zone->nr_scan_inactive = 0; zone->nr_active = 0; zone->nr_inactive = 0; if (!size) diff --git a/mm/vmscan.c b/mm/vmscan.c index 5d856f4244bf..3fe27c1d2381 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -789,54 +789,46 @@ refill_inactive_zone(struct zone *zone, struct scan_control *sc) } /* - * Scan `nr_pages' from this zone. Returns the number of reclaimed pages. * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. */ static void shrink_zone(struct zone *zone, struct scan_control *sc) { - unsigned long scan_active, scan_inactive; - int count; - - scan_inactive = (zone->nr_active + zone->nr_inactive) >> sc->priority; + unsigned long nr_active; + unsigned long nr_inactive; /* - * Try to keep the active list 2/3 of the size of the cache. And - * make sure that refill_inactive is given a decent number of pages. - * - * The "scan_active + 1" here is important. With pagecache-intensive - * workloads the inactive list is huge, and `ratio' evaluates to zero - * all the time. Which pins the active list memory. So we add one to - * `scan_active' just to make sure that the kernel will slowly sift - * through the active list. + * Add one to `nr_to_scan' just to make sure that the kernel will + * slowly sift through the active list. */ - if (zone->nr_active >= 4*(zone->nr_inactive*2 + 1)) { - /* Don't scan more than 4 times the inactive list scan size */ - scan_active = 4*scan_inactive; - } else { - unsigned long long tmp; - - /* Cast to long long so the multiply doesn't overflow */ - - tmp = (unsigned long long)scan_inactive * zone->nr_active; - do_div(tmp, zone->nr_inactive*2 + 1); - scan_active = (unsigned long)tmp; - } - - atomic_add(scan_active + 1, &zone->nr_scan_active); - count = atomic_read(&zone->nr_scan_active); - if (count >= SWAP_CLUSTER_MAX) { - atomic_set(&zone->nr_scan_active, 0); - sc->nr_to_scan = count; - refill_inactive_zone(zone, sc); - } + zone->nr_scan_active += (zone->nr_active >> sc->priority) + 1; + nr_active = zone->nr_scan_active; + if (nr_active >= SWAP_CLUSTER_MAX) + zone->nr_scan_active = 0; + else + nr_active = 0; + + zone->nr_scan_inactive += (zone->nr_inactive >> sc->priority) + 1; + nr_inactive = zone->nr_scan_inactive; + if (nr_inactive >= SWAP_CLUSTER_MAX) + zone->nr_scan_inactive = 0; + else + nr_inactive = 0; + + while (nr_active || nr_inactive) { + if (nr_active) { + sc->nr_to_scan = min(nr_active, + (unsigned long)SWAP_CLUSTER_MAX); + nr_active -= sc->nr_to_scan; + refill_inactive_zone(zone, sc); + } - atomic_add(scan_inactive, &zone->nr_scan_inactive); - count = atomic_read(&zone->nr_scan_inactive); - if (count >= SWAP_CLUSTER_MAX) { - atomic_set(&zone->nr_scan_inactive, 0); - sc->nr_to_scan = count; - shrink_cache(zone, sc); + if (nr_inactive) { + sc->nr_to_scan = min(nr_inactive, + (unsigned long)SWAP_CLUSTER_MAX); + nr_inactive -= sc->nr_to_scan; + shrink_cache(zone, sc); + } } } -- cgit v1.2.3 From a44115192f55f8b7a22d511cc194d7880a2ba553 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:04 -0700 Subject: [PATCH] vm: vfs shrinkage tuning Some people want the dentry and inode caches shrink harder, others want them shrunk more reluctantly. The patch adds /proc/sys/vm/vfs_cache_pressure, which tunes the vfs cache versus pagecache scanning pressure. - at vfs_cache_pressure=0 we don't shrink dcache and icache at all. - at vfs_cache_pressure=100 there is no change in behaviour. - at vfs_cache_pressure > 100 we reclaim dentries and inodes harder. The number of megabytes of slab left after a slocate.cron on my 256MB test box: vfs_cache_pressure=100000 33480 vfs_cache_pressure=10000 61996 vfs_cache_pressure=1000 104056 vfs_cache_pressure=200 166340 vfs_cache_pressure=100 190200 vfs_cache_pressure=50 206168 Of course, this just left more directory and inode pagecache behind instead of vfs cache. Interestingly, on this machine the entire slocate run fits into pagecache, but not into VFS caches. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 12 ++++++++++++ Documentation/sysctl/vm.txt | 2 +- fs/dcache.c | 5 +++-- fs/inode.c | 2 +- include/linux/dcache.h | 2 ++ include/linux/sysctl.h | 1 + kernel/sysctl.c | 12 ++++++++++++ 7 files changed, 32 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 995da97a2633..b84b7a7cc723 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1115,6 +1115,18 @@ program to load modules on demand. The files in this directory can be used to tune the operation of the virtual memory (VM) subsystem of the Linux kernel. +vfs_cache_pressure +------------------ + +Controls the tendency of the kernel to reclaim the memory which is used for +caching of directory and inode objects. + +At the default value of vfs_cache_pressure=100 the kernel will attempt to +reclaim dentries and inodes at a "fair" rate with respect to pagecache and +swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer +to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 +causes the kernel to prefer to reclaim dentries and inodes. + dirty_background_ratio ---------------------- diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index fc3e413c3721..c873ef92fbfa 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -28,7 +28,7 @@ Currently, these files are in /proc/sys/vm: ============================================================== dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, -dirty_writeback_centisecs: +dirty_writeback_centisecs, vfs_cache_pressure: See Documentation/filesystems/proc.txt diff --git a/fs/dcache.c b/fs/dcache.c index 02df5d45b82e..ac36b5c5fdf2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,9 +32,10 @@ #include #include -#define DCACHE_PARANOIA 1 /* #define DCACHE_DEBUG 1 */ +int sysctl_vfs_cache_pressure = 100; + spinlock_t dcache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; @@ -664,7 +665,7 @@ static int shrink_dcache_memory(int nr, unsigned int gfp_mask) return -1; prune_dcache(nr); } - return dentry_stat.nr_unused; + return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; } /** diff --git a/fs/inode.c b/fs/inode.c index e802a3c35fd2..ad1dd009acbc 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -488,7 +488,7 @@ static int shrink_icache_memory(int nr, unsigned int gfp_mask) if (gfp_mask & __GFP_FS) prune_icache(nr); } - return inodes_stat.nr_unused; + return (inodes_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; } static void __wait_on_freeing_inode(struct inode *inode); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 72f48658a7d7..66e27328434b 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -313,6 +313,8 @@ static inline int d_mountpoint(struct dentry *dentry) extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *); extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); +extern int sysctl_vfs_cache_pressure; + #endif /* __KERNEL__ */ #endif /* __LINUX_DCACHE_H */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index f70f7fc14498..38acd5d4b691 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -164,6 +164,7 @@ enum VM_LAPTOP_MODE=23, /* vm laptop mode */ VM_BLOCK_DUMP=24, /* block dump mode */ VM_HUGETLB_GROUP=25, /* permitted hugetlb group */ + VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 7dca63a88ea2..641727bab22f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -39,6 +39,8 @@ #include #include #include +#include + #include #ifdef CONFIG_ROOT_NFS @@ -777,6 +779,16 @@ static ctl_table vm_table[] = { .strategy = &sysctl_intvec, .extra1 = &zero, }, + { + .ctl_name = VM_VFS_CACHE_PRESSURE, + .procname = "vfs_cache_pressure", + .data = &sysctl_vfs_cache_pressure, + .maxlen = sizeof(sysctl_vfs_cache_pressure), + .mode = 0644, + .proc_handler = &proc_dointvec, + .strategy = &sysctl_intvec, + .extra1 = &zero, + }, { .ctl_name = 0 } }; -- cgit v1.2.3 From 758e48e4186f474b3258b9c4b4480511df1e6808 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:26 -0700 Subject: [PATCH] Use fancy wakeups in wait.h Use the more SMP-friendly prepare_to_wait()/finish_wait() in wait_event() and friends. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/wait.h | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/linux/wait.h b/include/linux/wait.h index 4a9f996bb6cc..e0f2b2ffc16f 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -120,18 +120,15 @@ extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int #define __wait_event(wq, condition) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_UNINTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ if (condition) \ break; \ schedule(); \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event(wq, condition) \ @@ -143,12 +140,10 @@ do { \ #define __wait_event_interruptible(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -158,8 +153,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible(wq, condition) \ @@ -172,12 +166,10 @@ do { \ #define __wait_event_interruptible_timeout(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -189,8 +181,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_timeout(wq, condition, timeout) \ @@ -203,12 +194,11 @@ do { \ #define __wait_event_interruptible_exclusive(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue_exclusive(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait_exclusive(&wq, &__wait, \ + TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -218,8 +208,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_exclusive(wq, condition) \ -- cgit v1.2.3 From 8dac324845379809bea5d35ece79521094f3e6f4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:11 -0700 Subject: [PATCH] abs() fixes OK, the pending abs() disaster has hit: drivers/usb/class/audio.c:404: warning: static declaration of 'abs' follows non-static declaration This is due to the declaration in kernel.h. AFAIK there's not even a matching definition for that. The patch implements abs() as a macro in kernel.h and kills off various private implementations. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/ppc_ksyms.c | 4 ---- drivers/usb/class/audio.c | 14 -------------- include/asm-ppc64/system.h | 2 -- include/linux/kernel.h | 11 ++++++++++- 4 files changed, 10 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index 1a8e1bf630c6..836cf2a43eab 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -47,8 +47,6 @@ extern int do_signal(sigset_t *, struct pt_regs *); -int abs(int); - EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(isa_io_base); @@ -157,8 +155,6 @@ EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memchr); -EXPORT_SYMBOL(abs); - EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(get_wchan); diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 96a1c025ddf0..648bbb033bb2 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -212,9 +212,6 @@ #define dprintk(x) -#undef abs -extern int abs(int __x) __attribute_const__; /* Shut up warning */ - /* --------------------------------------------------------------------- */ /* @@ -398,17 +395,6 @@ struct usb_audio_state { /* --------------------------------------------------------------------- */ -/* prevent picking up a bogus abs macro */ -#undef abs -static inline int abs(int x) -{ - if (x < 0) - return -x; - return x; -} - -/* --------------------------------------------------------------------- */ - static inline unsigned ld2(unsigned int x) { unsigned r = 0; diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 06ecd1bb285d..47c78eef463c 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -128,8 +128,6 @@ static inline void flush_altivec_to_thread(struct task_struct *t) } #endif -extern int abs(int); - extern struct task_struct *__switch_to(struct task_struct *, struct task_struct *); #define switch_to(prev, next, last) ((last) = __switch_to((prev), (next))) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 9eb023020b44..d6ed9b926c6f 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -54,6 +54,16 @@ void __might_sleep(char *file, int line); #define might_sleep_if(cond) do {} while (0) #endif +#define abs(x) ({ \ + int __x = (x); \ + (__x < 0) ? -__x : __x; \ + }) + +#define labs(x) ({ \ + long __x = (x); \ + (__x < 0) ? -__x : __x; \ + }) + extern struct notifier_block *panic_notifier_list; NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))); @@ -61,7 +71,6 @@ asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET; NORET_TYPE void complete_and_exit(struct completion *, long) ATTRIB_NORET; -extern int abs(int); extern unsigned long simple_strtoul(const char *,char **,unsigned int); extern long simple_strtol(const char *,char **,unsigned int); extern unsigned long long simple_strtoull(const char *,char **,unsigned int); -- cgit v1.2.3 From 296d3c783b83b8a80cd16301ea6d0dabe2b77637 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:22 -0700 Subject: [PATCH] Support NetMOS based PCI cards providing serial and parallel ports From: Christoph Lameter Attached a patch to support a variety of PCI based serial and parallel port I/O ports (typically labeled 222N-2 or 9835). I think this should go into 2.6.0 since it has been out there for a long time and is just some additional driver support that somehow fell through the cracks in 2.4.X. Tim Waugh submitted it in the 2.4.X series. See also http://winterwolf.co.uk/pciio Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/ChangeLog | 4 ++++ drivers/parport/parport_pc.c | 17 +++++++++++++++++ drivers/parport/parport_serial.c | 10 ++++++++++ include/linux/pci_ids.h | 4 ++++ 4 files changed, 35 insertions(+) (limited to 'include') diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog index 692415edb153..db717c1d62a5 100644 --- a/drivers/parport/ChangeLog +++ b/drivers/parport/ChangeLog @@ -1,3 +1,7 @@ +2001-10-11 Tim Waugh + * parport_pc.c, parport_serial.c: Support for NetMos cards. + + Patch originally from Michael Reinelt . + 2002-04-25 Tim Waugh * parport_serial.c, parport_pc.c: Move some SIIG cards around. diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 218eb4fd785e..fe4cc866de08 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2632,6 +2632,10 @@ enum parport_pc_pci_cards { oxsemi_840, aks_0100, mobility_pp, + netmos_9705, + netmos_9805, + netmos_9815, + netmos_9855, }; @@ -2701,6 +2705,10 @@ static struct parport_pc_pci { /* oxsemi_840 */ { 1, { { 0, -1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, + /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ + /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ }; static struct pci_device_id parport_pc_pci_tbl[] = { @@ -2769,6 +2777,15 @@ static struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 }, { PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 }, + /* NetMos communication controllers */ + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9805, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index c29e8ded5fbc..1f17d0124cc7 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -33,6 +33,8 @@ enum parport_pc_pci_cards { titan_110l = 0, titan_210l, + netmos_9735, + netmos_9835, avlab_1s1p, avlab_1s1p_650, avlab_1s1p_850, @@ -71,6 +73,8 @@ static struct parport_pc_pci { } cards[] __devinitdata = { /* titan_110l */ { 1, { { 3, -1 }, } }, /* titan_210l */ { 1, { { 3, -1 }, } }, + /* netmos_9735 (not tested) */ { 1, { { 2, -1 }, } }, + /* netmos_9835 */ { 1, { { 2, -1 }, } }, /* avlab_1s1p */ { 1, { { 1, 2}, } }, /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, @@ -93,6 +97,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9735 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9835 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, @@ -172,6 +180,8 @@ static struct pci_board_no_ids pci_boards[] __devinitdata = { /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, +/* netmos_9735 (n/t)*/ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, +/* netmos_9835 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 45d805ddeb9e..ba2d0b357306 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2252,8 +2252,12 @@ #define PCI_DEVICE_ID_HOLTEK_6565 0x6565 #define PCI_VENDOR_ID_NETMOS 0x9710 +#define PCI_DEVICE_ID_NETMOS_9705 0x9705 #define PCI_DEVICE_ID_NETMOS_9735 0x9735 +#define PCI_DEVICE_ID_NETMOS_9805 0x9805 +#define PCI_DEVICE_ID_NETMOS_9815 0x9815 #define PCI_DEVICE_ID_NETMOS_9835 0x9835 +#define PCI_DEVICE_ID_NETMOS_9855 0x9855 #define PCI_SUBVENDOR_ID_EXSYS 0xd84d #define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 -- cgit v1.2.3 From 6a948bc8ac0d7b3c4bf1a46838fb3786ecffbd93 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:44 -0700 Subject: [PATCH] nr_pagecache can go negative We use per-cpu counters for the system-wide pagecache accounting. The counters spill into the global nr_pagecache atomic_t when they underflow or overflow. Hence it is possible, under weird circumstances, for nr_pagecache to go negative. Anton says he has hit this. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 427b696f484b..4da205f3cb26 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -136,7 +137,10 @@ static inline void pagecache_acct(int count) static inline unsigned long get_page_cache_size(void) { - return atomic_read(&nr_pagecache); + int ret = atomic_read(&nr_pagecache); + if (unlikely(ret < 0)) + ret = 0; + return ret; } static inline pgoff_t linear_page_index(struct vm_area_struct *vma, -- cgit v1.2.3 From a5b5323bfe43d8a284119248d54008fc7b483608 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:56 -0700 Subject: [PATCH] Make nr_swap_pages a long From: Anton Blanchard ../include/linux/swap.h:extern int nr_swap_pages; /* XXX: shouldn't this be ulong? --hch */ Sounds like it should be too me. Some of the code checks for nr_swap_pages < 0 so I made it a long instead. I had to fix up the ppc64 show_mem() (Im guessing there will be other trivial changes required in other 64bit archs, I can find and fix those if you want). I also noticed that the ppc64 show_mem() used ints to store page counts. We can overflow that, so make them unsigned long. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/mm/init.c | 2 +- arch/alpha/mm/numa.c | 2 +- arch/arm/mm/init.c | 2 +- arch/arm26/mm/init.c | 2 +- arch/cris/mm/init.c | 2 +- arch/i386/mm/pgtable.c | 2 +- arch/ia64/mm/contig.c | 2 +- arch/ia64/mm/discontig.c | 2 +- arch/m68k/atari/stram.c | 4 ++-- arch/m68k/mm/init.c | 2 +- arch/mips/mm/pgtable.c | 2 +- arch/parisc/mm/init.c | 3 ++- arch/ppc/mm/init.c | 2 +- arch/ppc64/mm/init.c | 14 +++++++------- arch/s390/mm/init.c | 2 +- arch/sh/mm/init.c | 2 +- arch/sparc/mm/init.c | 2 +- arch/sparc64/mm/init.c | 2 +- arch/um/kernel/mem.c | 2 +- arch/x86_64/mm/init.c | 2 +- include/linux/swap.h | 2 +- mm/page_alloc.c | 2 +- 22 files changed, 30 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 0a5873f7e3fb..3ea81ca1c6d9 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -106,7 +106,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index 91f5f373f811..31a3f63433f3 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -371,7 +371,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (nid = 0; nid < numnodes; nid++) { struct page * lmem_map = node_mem_map(nid); i = node_spanned_pages(nid); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 07ddce79808c..c183e6537114 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -58,7 +58,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (node = 0; node < numnodes; node++) { struct page *page, *end; diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c index a4f56b2b493b..ad41cebe207a 100644 --- a/arch/arm26/mm/init.c +++ b/arch/arm26/mm/init.c @@ -67,7 +67,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); page = NODE_MEM_MAP(0); diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index d0bd0c957d28..31a0018b525a 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -138,7 +138,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 49561339cbcc..137d18db72ff 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -33,7 +33,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { page = pgdat->node_mem_map + i; diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 183533a62dbd..c0f8f4a3e019 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -43,7 +43,7 @@ show_mem (void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { if (!pfn_valid(i)) diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index b8472d960191..788aa84e3420 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -498,7 +498,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { printk("Node ID: %d\n", pgdat->node_id); for(i = 0; i < pgdat->node_spanned_pages; i++) { diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index b03d03163496..f7cfaa6db534 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -743,7 +743,7 @@ static int unswap_by_read(unsigned short *map, unsigned long max, if (map[i]) { entry = swp_entry(stram_swap_type, i); - DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages); swap_device_lock(stram_swap_info); @@ -772,7 +772,7 @@ static int unswap_by_read(unsigned short *map, unsigned long max, #endif } - DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages ); swap_list_lock(); swap_device_lock(stram_swap_info); diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index d79dbfae6b21..c45beb955943 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -47,7 +47,7 @@ void show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c index b1722b8f6e5e..8c30f32a66e8 100644 --- a/arch/mips/mm/pgtable.c +++ b/arch/mips/mm/pgtable.c @@ -12,7 +12,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while (pfn-- > 0) { page = pfn_to_page(pfn); diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index e7a8b1bc9ae4..94f5d4e60920 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -484,7 +484,8 @@ void show_mem(void) printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index b53c0f0f3347..448e80c11518 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -118,7 +118,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index 5043702a470f..857e8915ee89 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -89,15 +89,15 @@ unsigned long top_of_ram; void show_mem(void) { - int total = 0, reserved = 0; - int shared = 0, cached = 0; + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; struct page *page; pg_data_t *pgdat; unsigned long i; printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; i++) { page = pgdat->node_mem_map + i; @@ -110,10 +110,10 @@ void show_mem(void) shared += page_count(page) - 1; } } - printk("%d pages of RAM\n",total); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); + printk("%ld pages of RAM\n", total); + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); } #ifdef CONFIG_PPC_ISERIES diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 177a3d26e261..1541b8699c17 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -60,7 +60,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 95b5368c0670..7b2bcad145ca 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -66,7 +66,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 1d61ed4130b3..4bc6aff2c8c3 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -76,7 +76,7 @@ void show_mem(void) { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", totalram_pages); printk("%d free pages\n", nr_free_pages()); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 043861f313c2..72a2164bdf67 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -348,7 +348,7 @@ void show_mem(void) { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", num_physpages); printk("%d free pages\n", nr_free_pages()); diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index ec2be14beedf..84a895c2a365 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -380,7 +380,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while(pfn-- > 0) { page = pfn_to_page(pfn); diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index fa8cc36487d7..f393e3355b99 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -60,7 +60,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { diff --git a/include/linux/swap.h b/include/linux/swap.h index a748538f3a31..62a841cc18b2 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -156,7 +156,7 @@ extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct * /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalhigh_pages; -extern int nr_swap_pages; /* XXX: shouldn't this be ulong? --hch */ +extern long nr_swap_pages; extern unsigned int nr_free_pages(void); extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat); extern unsigned int nr_free_buffer_pages(void); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f8dbd8be97b5..fe55c14bd4dc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -38,7 +38,7 @@ DECLARE_BITMAP(node_online_map, MAX_NUMNODES); struct pglist_data *pgdat_list; unsigned long totalram_pages; unsigned long totalhigh_pages; -int nr_swap_pages; +long nr_swap_pages; int numnodes = 1; int sysctl_lower_zone_protection = 0; -- cgit v1.2.3 From e62d1b673e80773490a0b2362e85ea4e64c50709 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:56:08 -0700 Subject: [PATCH] make total_swap_pages a long Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 2 +- mm/swapfile.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/swap.h b/include/linux/swap.h index 62a841cc18b2..b9edc335a563 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -206,7 +206,7 @@ extern struct page * read_swap_cache_async(swp_entry_t, struct vm_area_struct *v unsigned long addr); /* linux/mm/swapfile.c */ -extern int total_swap_pages; +extern long total_swap_pages; extern unsigned int nr_swapfiles; extern struct swap_info_struct swap_info[]; extern void si_swapinfo(struct sysinfo *); diff --git a/mm/swapfile.c b/mm/swapfile.c index 6422f1b8d810..714c8339c5f2 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -32,7 +32,7 @@ spinlock_t swaplock = SPIN_LOCK_UNLOCKED; unsigned int nr_swapfiles; -int total_swap_pages; +long total_swap_pages; static int swap_overflow; EXPORT_SYMBOL(total_swap_pages); -- cgit v1.2.3 From fb9c90ba9f4166c3b9a51b5728db69968852b231 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:19:53 -0700 Subject: [PATCH] MIPS Update From: Ralf Baechle MIPS update: - Further conversion of MIPS kernel configuration to reverse dependencies. - Support for the PMC-Sierra Yosemite evaluation board. - Merge arch/mips/mm-32 and arch/mips/mm-32 into arch/mips/mm. - Partial support for the R8000 now that I finally have clearance for the documentation previously covered by NDA. - Make distclean fixes. - Regenerate default configuration files against latest Kconfig files. - Fix handling of data bus errors in modules. - Make R4000 bug probing more bullet proof. - Rewrite semaphore code folloing the PPC implementation to no longer manipulate 2 32-bit quantities atomically using 64-bit instructions. Occasionally this did cause problems due to struct semaphore not having sufficient alignment. - Make sys_pipe() code bullet proof against gcc 3.5 over-optimization. - Fix possibly exploitable bug in IRIX compatibility statvfs(2). - Make sched_clock() an outline function. - Support for the MIPS 24K and 25K processors. - Make functions static that aren't needed anywhere else. - Factor out some more generic MIPS SMP code. - Factor out common part of the GT-64240 code. - Ocelot C now uses the generic MV-64340 interrupt handler code. - Factor out common board support code - More cleanup and bug fixes for the NEC VR41xx code. - Start cleanup of hazard handling as required for MIPS32/64 V2 processors. - Enforce minimal kmalloc alignment of 8 byte so 64-bit registers can be stored into fields without exceptions. - Speeling and warning fixes. Signed-off-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/Kconfig | 78 +- arch/mips/Makefile | 9 +- arch/mips/boot/Makefile | 2 +- arch/mips/configs/atlas_defconfig | 9 +- arch/mips/configs/bosporus_defconfig | 7 +- arch/mips/configs/capcella_defconfig | 12 +- arch/mips/configs/cobalt_defconfig | 8 +- arch/mips/configs/db1000_defconfig | 8 +- arch/mips/configs/db1100_defconfig | 7 +- arch/mips/configs/db1500_defconfig | 10 +- arch/mips/configs/ddb5476_defconfig | 9 +- arch/mips/configs/ddb5477_defconfig | 7 +- arch/mips/configs/decstation_defconfig | 4 +- arch/mips/configs/e55_defconfig | 6 +- arch/mips/configs/eagle_defconfig | 11 +- arch/mips/configs/ev64120_defconfig | 6 +- arch/mips/configs/ev96100_defconfig | 4 +- arch/mips/configs/ip22_defconfig | 5 +- arch/mips/configs/ip27_defconfig | 9 +- arch/mips/configs/ip32_defconfig | 8 +- arch/mips/configs/it8172_defconfig | 6 +- arch/mips/configs/ivr_defconfig | 8 +- arch/mips/configs/jaguar-atx_defconfig | 4 +- arch/mips/configs/jmr3927_defconfig | 7 +- arch/mips/configs/lasat200_defconfig | 8 +- arch/mips/configs/malta_defconfig | 6 +- arch/mips/configs/mirage_defconfig | 7 +- arch/mips/configs/mpc30x_defconfig | 9 +- arch/mips/configs/mtx1_defconfig | 7 +- arch/mips/configs/ocelot_c_defconfig | 50 +- arch/mips/configs/ocelot_defconfig | 4 +- arch/mips/configs/ocelot_g_defconfig | 587 +++++++++ arch/mips/configs/osprey_defconfig | 4 +- arch/mips/configs/pb1000_defconfig | 7 +- arch/mips/configs/pb1100_defconfig | 7 +- arch/mips/configs/pb1500_defconfig | 12 +- arch/mips/configs/pb1550_defconfig | 12 +- arch/mips/configs/rm200_defconfig | 17 +- arch/mips/configs/sb1250-swarm_defconfig | 34 +- arch/mips/configs/sead_defconfig | 3 +- arch/mips/configs/tb0226_defconfig | 8 +- arch/mips/configs/tb0229_defconfig | 10 +- arch/mips/configs/workpad_defconfig | 5 +- arch/mips/configs/xxs1500_defconfig | 7 +- arch/mips/configs/yosemite_defconfig | 181 ++- arch/mips/defconfig | 5 +- arch/mips/kernel/Makefile | 3 +- arch/mips/kernel/cpu-bugs64.c | 40 +- arch/mips/kernel/cpu-probe.c | 46 +- arch/mips/kernel/module-elf32.c | 11 - arch/mips/kernel/module-elf64.c | 11 - arch/mips/kernel/module.c | 53 + arch/mips/kernel/scall32-o32.S | 1 + arch/mips/kernel/scall64-64.S | 1 + arch/mips/kernel/scall64-n32.S | 1 + arch/mips/kernel/scall64-o32.S | 1 + arch/mips/kernel/semaphore.c | 328 ++--- arch/mips/kernel/setup.c | 14 +- arch/mips/kernel/syscall.c | 2 +- arch/mips/kernel/sysirix.c | 2 +- arch/mips/kernel/time.c | 5 + arch/mips/kernel/traps.c | 59 +- arch/mips/lib-32/Makefile | 22 +- arch/mips/lib-64/Makefile | 22 +- arch/mips/mips-boards/generic/cmdline.c | 6 +- arch/mips/mips-boards/generic/printf.c | 34 +- arch/mips/mm-32/Makefile | 19 - arch/mips/mm-32/tlbex-r4k.S | 524 -------- arch/mips/mm-64/Makefile | 25 - arch/mips/mm-64/tlb-dbg-r4k.c | 71 -- arch/mips/mm-64/tlb-glue-r4k.S | 41 - arch/mips/mm-64/tlb-glue-sb1.S | 66 - arch/mips/mm-64/tlbex-r4k.S | 203 ---- arch/mips/mm/Makefile | 39 +- arch/mips/mm/tlb-r8k.c | 253 ++++ arch/mips/mm/tlb-sb1.c | 2 +- arch/mips/mm/tlb64-glue-r4k.S | 41 + arch/mips/mm/tlb64-glue-sb1.S | 66 + arch/mips/mm/tlbex-r3k.S | 224 ---- arch/mips/mm/tlbex32-r3k.S | 224 ++++ arch/mips/mm/tlbex32-r4k.S | 524 ++++++++ arch/mips/mm/tlbex64-r4k.S | 203 ++++ arch/mips/momentum/jaguar_atx/prom.c | 14 - arch/mips/momentum/jaguar_atx/setup.c | 2 +- arch/mips/momentum/ocelot_c/Makefile | 4 +- arch/mips/momentum/ocelot_c/irq.c | 3 +- arch/mips/momentum/ocelot_c/pci-irq.c | 72 -- arch/mips/momentum/ocelot_c/prom.c | 3 +- arch/mips/momentum/ocelot_c/setup.c | 2 +- arch/mips/momentum/ocelot_g/Makefile | 3 +- arch/mips/momentum/ocelot_g/gt-irq.c | 96 +- arch/mips/momentum/ocelot_g/gt64240.h | 1238 ------------------- arch/mips/momentum/ocelot_g/gt64240_dep.h | 57 - arch/mips/momentum/ocelot_g/pci-irq.c | 73 -- arch/mips/momentum/ocelot_g/prom.c | 8 +- arch/mips/momentum/ocelot_g/setup.c | 116 +- arch/mips/pci/Makefile | 17 +- arch/mips/pci/fixup-capcella.c | 28 +- arch/mips/pci/fixup-jaguar.c | 42 + arch/mips/pci/fixup-mpc30x.c | 48 + arch/mips/pci/fixup-mv64340.c | 42 - arch/mips/pci/fixup-ocelot-c.c | 39 + arch/mips/pci/fixup-ocelot-g.c | 35 + arch/mips/pci/fixup-tb0219.c | 64 + arch/mips/pci/fixup-tb0226.c | 117 +- arch/mips/pci/fixup-tb0229.c | 64 - arch/mips/pci/fixup-victor-mpc30x.c | 48 - arch/mips/pci/fixup-yosemite.c | 17 +- arch/mips/pci/ops-gt64240.c | 149 +++ arch/mips/pci/ops-msc.c | 6 +- arch/mips/pci/ops-titan-ht.c | 125 ++ arch/mips/pci/ops-titan.c | 32 +- arch/mips/pci/ops-vr41xx.c | 126 ++ arch/mips/pci/pci-ocelot-c.c | 161 ++- arch/mips/pci/pci-ocelot-g.c | 496 +------- arch/mips/pci/pci-vr41xx.c | 398 +++--- arch/mips/pci/pci-vr41xx.h | 283 +++-- arch/mips/pci/pci-yosemite.c | 37 + arch/mips/pci/pci.c | 2 +- arch/mips/pmc-sierra/yosemite/Makefile | 7 +- arch/mips/pmc-sierra/yosemite/dbg_io.c | 184 +++ arch/mips/pmc-sierra/yosemite/i2c-yosemite.c | 188 +++ arch/mips/pmc-sierra/yosemite/i2c-yosemite.h | 52 +- arch/mips/pmc-sierra/yosemite/irq-handler.S | 87 +- arch/mips/pmc-sierra/yosemite/irq.c | 247 ++-- arch/mips/pmc-sierra/yosemite/prom.c | 144 +-- arch/mips/pmc-sierra/yosemite/py-console.c | 130 ++ arch/mips/pmc-sierra/yosemite/setup.c | 175 ++- arch/mips/pmc-sierra/yosemite/setup.h | 18 +- arch/mips/ramdisk/Makefile | 2 +- arch/mips/sgi-ip22/ip22-setup.c | 3 + arch/mips/vr41xx/common/bcu.c | 54 +- arch/mips/vr41xx/common/cmu.c | 6 +- arch/mips/vr41xx/common/giu.c | 242 +++- arch/mips/vr41xx/common/icu.c | 499 +++++--- arch/mips/vr41xx/common/init.c | 15 - arch/mips/vr41xx/common/ksyms.c | 2 - arch/mips/vr41xx/common/pmu.c | 8 +- arch/mips/vr41xx/common/rtc.c | 8 +- arch/mips/vr41xx/common/serial.c | 2 +- arch/mips/vr41xx/common/vrc4173.c | 404 +++++-- arch/mips/vr41xx/tanbac-tb0226/setup.c | 61 +- arch/mips/vr41xx/tanbac-tb0229/Makefile | 2 +- arch/mips/vr41xx/tanbac-tb0229/reboot.c | 27 - arch/mips/vr41xx/tanbac-tb0229/setup.c | 66 +- arch/mips/vr41xx/tanbac-tb0229/tb0219.c | 44 + arch/mips/vr41xx/victor-mpc30x/setup.c | 61 +- arch/mips/vr41xx/zao-capcella/setup.c | 61 +- include/asm-mips/asmmacro.h | 4 +- include/asm-mips/atomic.h | 130 +- include/asm-mips/cache.h | 2 + include/asm-mips/gt64240.h | 1264 ++++++++++++++++++++ include/asm-mips/hazards.h | 117 +- .../asm-mips/mach-yosemite/cpu-feature-overrides.h | 38 + include/asm-mips/mipsregs.h | 2 +- include/asm-mips/mmu_context.h | 12 +- include/asm-mips/module.h | 19 +- include/asm-mips/page.h | 6 +- include/asm-mips/pci.h | 3 + include/asm-mips/pgtable-32.h | 72 +- include/asm-mips/pgtable-64.h | 33 +- include/asm-mips/pgtable-bits.h | 18 +- include/asm-mips/pgtable.h | 2 - include/asm-mips/pmon.h | 3 + include/asm-mips/processor.h | 9 - include/asm-mips/semaphore.h | 265 +--- include/asm-mips/serial.h | 19 - include/asm-mips/smp.h | 8 - include/asm-mips/stackframe.h | 3 + include/asm-mips/system.h | 21 +- include/asm-mips/thread_info.h | 3 + include/asm-mips/titan_dep.h | 181 ++- include/asm-mips/unistd.h | 15 +- include/asm-mips/vr41xx/capcella.h | 54 +- include/asm-mips/vr41xx/mpc30x.h | 54 +- include/asm-mips/vr41xx/tb0219.h | 42 + include/asm-mips/vr41xx/tb0226.h | 54 +- include/asm-mips/vr41xx/tb0229.h | 73 -- include/asm-mips/vr41xx/vr41xx.h | 144 ++- include/asm-mips/vr41xx/vrc4173.h | 78 +- 180 files changed, 7917 insertions(+), 6118 deletions(-) create mode 100644 arch/mips/configs/ocelot_g_defconfig create mode 100644 arch/mips/kernel/module.c delete mode 100644 arch/mips/mm-32/Makefile delete mode 100644 arch/mips/mm-32/tlbex-r4k.S delete mode 100644 arch/mips/mm-64/Makefile delete mode 100644 arch/mips/mm-64/tlb-dbg-r4k.c delete mode 100644 arch/mips/mm-64/tlb-glue-r4k.S delete mode 100644 arch/mips/mm-64/tlb-glue-sb1.S delete mode 100644 arch/mips/mm-64/tlbex-r4k.S create mode 100644 arch/mips/mm/tlb-r8k.c create mode 100644 arch/mips/mm/tlb64-glue-r4k.S create mode 100644 arch/mips/mm/tlb64-glue-sb1.S delete mode 100644 arch/mips/mm/tlbex-r3k.S create mode 100644 arch/mips/mm/tlbex32-r3k.S create mode 100644 arch/mips/mm/tlbex32-r4k.S create mode 100644 arch/mips/mm/tlbex64-r4k.S delete mode 100644 arch/mips/momentum/ocelot_c/pci-irq.c delete mode 100644 arch/mips/momentum/ocelot_g/gt64240.h delete mode 100644 arch/mips/momentum/ocelot_g/gt64240_dep.h delete mode 100644 arch/mips/momentum/ocelot_g/pci-irq.c create mode 100644 arch/mips/pci/fixup-jaguar.c create mode 100644 arch/mips/pci/fixup-mpc30x.c delete mode 100644 arch/mips/pci/fixup-mv64340.c create mode 100644 arch/mips/pci/fixup-ocelot-c.c create mode 100644 arch/mips/pci/fixup-ocelot-g.c create mode 100644 arch/mips/pci/fixup-tb0219.c delete mode 100644 arch/mips/pci/fixup-tb0229.c delete mode 100644 arch/mips/pci/fixup-victor-mpc30x.c create mode 100644 arch/mips/pci/ops-gt64240.c create mode 100644 arch/mips/pci/ops-titan-ht.c create mode 100644 arch/mips/pci/ops-vr41xx.c create mode 100644 arch/mips/pci/pci-yosemite.c create mode 100644 arch/mips/pmc-sierra/yosemite/dbg_io.c create mode 100644 arch/mips/pmc-sierra/yosemite/i2c-yosemite.c create mode 100644 arch/mips/pmc-sierra/yosemite/py-console.c delete mode 100644 arch/mips/vr41xx/tanbac-tb0229/reboot.c create mode 100644 arch/mips/vr41xx/tanbac-tb0229/tb0219.c create mode 100644 include/asm-mips/gt64240.h create mode 100644 include/asm-mips/mach-yosemite/cpu-feature-overrides.h create mode 100644 include/asm-mips/vr41xx/tb0219.h delete mode 100644 include/asm-mips/vr41xx/tb0229.h (limited to 'include') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 080eb3c37aba..ebfd35e5544d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -96,11 +96,13 @@ config NEC_EAGLE select DMA_NONCOHERENT select IRQ_CPU depends on MACH_VR41XX + select HW_HAS_PCI config TANBAC_TB0226 bool "Support for TANBAC TB0226 (Mbase)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0226 (Mbase) is a MIPS-based platform manufactured by TANBAC. @@ -110,6 +112,7 @@ config TANBAC_TB0229 bool "Support for TANBAC TB0229 (VR4131DIMM)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC. @@ -118,6 +121,7 @@ config TANBAC_TB0229 config VICTOR_MPC30X bool "Support for Victor MP-C303/304" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU depends on MACH_VR41XX @@ -125,17 +129,22 @@ config ZAO_CAPCELLA bool "Support for ZAO Networks Capcella" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU +config PCI_VR41XX + bool "Add PCI control unit support of NEC VR4100 series" + depends on MACH_VR41XX && PCI + config VRC4171 - tristate "add NEC VRC4171 companion chip support" + tristate "Add NEC VRC4171 companion chip support" depends on MACH_VR41XX && ISA ---help--- The NEC VRC4171/4171A is a companion chip for NEC VR4111/VR4121. config VRC4173 - tristate "add NEC VRC4173 companion chip support" - depends on MACH_VR41XX && PCI + tristate "Add NEC VRC4173 companion chip support" + depends on MACH_VR41XX && PCI_VR41XX ---help--- The NEC VRC4173 is a companion chip for NEC VR4122/VR4131. @@ -143,11 +152,13 @@ config TOSHIBA_JMR3927 bool "Support for Toshiba JMR-TX3927 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_COBALT bool "Support for Cobalt Server (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MACH_DECSTATION @@ -174,6 +185,7 @@ config MIPS_EV64120 bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible @@ -189,6 +201,7 @@ config MIPS_EV96100 bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select MIPS_GT96100 select RM7000_CPU_SCACHE @@ -201,6 +214,7 @@ config MIPS_EV96100 config MIPS_IVR bool "Support for Globespan IVR board" select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board built by Globespan to showcase thir iVR (Internet Video Recorder) design. It utilizes a QED RM5231 @@ -211,6 +225,7 @@ config MIPS_IVR config LASAT bool "Support for LASAT Networks platforms" select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE config PICVUE @@ -233,11 +248,13 @@ config HP_LASERJET bool "Support for Hewlett Packard LaserJet board" depends on BROKEN select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MIPS_ITE8172 bool "Support for ITE 8172G board" select DMA_NONCOHERENT + select HW_HAS_PCI help Ths is an evaluation board made by ITE with ATX form factor that utilizes a MIPS R5000 to work with its @@ -257,6 +274,7 @@ config IT8172_REVC config MIPS_ATLAS bool "Support for MIPS Atlas board" select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the QED R5231-based MIPS Atlas evaluation board. @@ -265,6 +283,7 @@ config MIPS_MALTA bool "Support for MIPS Malta board" select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the VR5000-based MIPS Malta evaluation board. @@ -278,6 +297,7 @@ config MIPS_SEAD config MOMENCO_OCELOT bool "Support for Momentum Ocelot board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -288,6 +308,7 @@ config MOMENCO_OCELOT config MOMENCO_OCELOT_G bool "Support for Momentum Ocelot-G board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -298,6 +319,7 @@ config MOMENCO_OCELOT_G config MOMENCO_OCELOT_C bool "Support for Momentum Ocelot-C board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select RM7000_CPU_SCACHE help @@ -307,6 +329,7 @@ config MOMENCO_OCELOT_C config MOMENCO_JAGUAR_ATX bool "Support for Momentum Jaguar board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select LIMITED_DMA @@ -324,7 +347,10 @@ config JAGUAR_DMALOW config PMC_YOSEMITE bool "Support for PMC-Sierra Yosemite eval board" - select DMA_NONCOHERENT + select DMA_COHERENT + select HW_HAS_PCI + select IRQ_CPU + select IRQ_CPU_RM7K help Yosemite is an evaluation board for the RM9000x2 processor manufactured by PMC-Sierra @@ -338,6 +364,7 @@ config DDB5074 depends on EXPERIMENTAL select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -348,6 +375,7 @@ config DDB5476 bool "Support for NEC DDB Vrc-5476" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -361,6 +389,7 @@ config DDB5476 config DDB5477 bool "Support for NEC DDB Vrc-5477" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help This enables support for the R5432-based NEC DDB Vrc-5477, @@ -393,6 +422,7 @@ config SGI_IP27 bool "Support for SGI IP27 (Origin200/2000)" depends on MIPS64 select DMA_IP27 + select HW_HAS_PCI help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -457,6 +487,7 @@ config SGI_IP32 bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE select RM7000_CPU_SCACHE help @@ -499,26 +530,31 @@ config MIPS_PB1000 bool "PB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1100 bool "PB1100 board" depends on SOC_AU1100 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1500 bool "PB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1550 bool "PB1550 board" depends on SOC_AU1550 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1000 bool "DB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1100 bool "DB1100 board" @@ -529,10 +565,12 @@ config MIPS_DB1500 bool "DB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1550 bool "DB1550 board" depends on SOC_AU1550 + select HW_HAS_PCI config MIPS_BOSPORUS bool "Bosporus board" @@ -642,6 +680,7 @@ endchoice config SIBYTE_SB1250 bool + select HW_HAS_PCI config SIBYTE_BCM1120 bool @@ -649,10 +688,12 @@ config SIBYTE_BCM1120 config SIBYTE_BCM1125 bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM1125H bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM112X @@ -699,11 +740,6 @@ endchoice config CPU_SB1_PASS_2 bool -config SIBYTE_HAS_PCI - bool - depends on SIBYTE_SB1250 || SIBYTE_BCM1125 || SIBYTE_BCM1125H - default y - config SIBYTE_HAS_LDT bool depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) @@ -770,6 +806,7 @@ config SNI_RM200_PCI bool "Support for SNI RM200 PCI" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select ISA help The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens @@ -781,6 +818,7 @@ config TOSHIBA_RBTX4927 bool "Support for Toshiba TBTX49[23]7 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI select ISA config RWSEM_GENERIC_SPINLOCK @@ -860,11 +898,6 @@ config IRQ_CPU config IRQ_CPU_RM7K bool -config DUMMY_KEYB - bool - depends on ZAO_CAPCELLA || VICTOR_MPC30X || SIBYTE_SB1xxx_SOC || NEC_EAGLE || NEC_OSPREY || DDB5477 || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 - default y - config DDB5XXX_COMMON bool depends on DDB5074 || DDB5476 || DDB5477 @@ -1164,6 +1197,16 @@ config PAGE_SIZE_4KB 4kB page size will minimize memory consumption and is therefore recommended for low memory systems. +config PAGE_SIZE_8KB + bool "8kB" + depends on EXPERIMENTAL && CPU_R8000 + help + Using 8kB page size will result in higher performance kernel at + the price of higher memory consumption. This option is available + only on the R8000 processor. Not that at the time of this writing + this option is still high experimental; there are also issues with + compatibility of user applications. + config PAGE_SIZE_16KB bool "16kB" depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX @@ -1377,9 +1420,12 @@ endmenu menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" +config HW_HAS_PCI + bool + config PCI bool "Support for PCI controller" - depends on MIPS_DB1000 || DDB5074 || DDB5476 || DDB5477 || HP_LASERJET || LASAT || MIPS_IVR || MIPS_ATLAS || MIPS_COBALT || MIPS_EV64120 || MIPS_EV96100 || MIPS_ITE8172 || MIPS_MALTA || MOMENCO_OCELOT || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MOMENCO_JAGUAR_ATX || MIPS_PB1000 || MIPS_PB1100 || SOC_AU1500 || SOC_AU1550 || NEC_EAGLE || SGI_IP27 || SGI_IP32 || SIBYTE_HAS_PCI || SNI_RM200_PCI || TANBAC_TB0226 || TANBAC_TB0229 || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || VICTOR_MPC30X || ZAO_CAPCELLA + depends on HW_HAS_PCI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -1559,7 +1605,7 @@ config DEBUG_STACK_USAGE config DEBUG_SLAB bool "Debug memory allocations" - depends on DEBUG_KERNEL && !CPU_HAS_LLDSCD + depends on DEBUG_KERNEL help Say Y here to have the kernel do limited verification on memory allocation as well as poisoning memory on free to catch use of freed diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8c4fb4b1d33f..c1aabc835f62 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -405,6 +405,13 @@ load-$(CONFIG_MOMENCO_OCELOT_G) += 0x80100000 core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ load-$(CONFIG_MOMENCO_OCELOT_C) += 0x80100000 +# +# PMC-Sierra Yosemite +# +core-$(CONFIG_PMC_YOSEMITE) += arch/mips/pmc-sierra/yosemite/ +cflags-$(CONFIG_PMC_YOSEMITE) += -Iinclude/asm-mips/mach-yosemite +load-$(CONFIG_PMC_YOSEMITE) += 0x80100000 + # # Momentum Jaguar ATX # @@ -659,8 +666,6 @@ libs-$(CONFIG_MIPS32) += arch/mips/lib-32/ libs-$(CONFIG_MIPS64) += arch/mips/lib-64/ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ -core-$(CONFIG_MIPS32) += arch/mips/mm-32/ -core-$(CONFIG_MIPS64) += arch/mips/mm-64/ ifdef CONFIG_BAGET_MIPS diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index a6e88d3180cb..c010290e55a6 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -39,7 +39,7 @@ $(obj)/addinitrd: $(obj)/addinitrd.c archhelp: @echo '* vmlinux.ecoff - ECOFF boot image' -CLEAN_FILES += addinitrd \ +clean-files += addinitrd \ elf2ecoff \ vmlinux.ecoff \ vmlinux.srec \ diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 9814c8e6dc79..cd4da1fb9f85 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -107,6 +107,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -121,6 +122,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ CONFIG_BLK_DEV_SD=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -216,11 +217,11 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -229,6 +230,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -395,7 +397,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -616,7 +617,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -651,3 +651,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/bosporus_defconfig b/arch/mips/configs/bosporus_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/bosporus_defconfig +++ b/arch/mips/configs/bosporus_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 910a796dfb0f..44799daa96b6 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -59,7 +59,8 @@ CONFIG_MACH_VR41XX=y # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set CONFIG_ZAO_CAPCELLA=y -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -185,7 +187,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -197,6 +198,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -214,7 +216,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -591,7 +591,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -626,3 +625,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index fb148427e050..c3fda0f4e154 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -104,6 +104,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -116,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -176,7 +178,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -188,6 +189,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -205,7 +207,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -344,7 +345,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -567,7 +567,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +601,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index fbb3ecda03ca..3ec36c06285c 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -522,6 +524,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -593,7 +598,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -678,11 +682,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 088b3a1069c8..f649a7cafc04 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -518,6 +519,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -589,7 +593,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -674,11 +677,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 86ecbe185aa3..ff5ec324a67e 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -259,7 +261,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -271,6 +272,7 @@ CONFIG_BLK_DEV_IDECS=m # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -592,6 +594,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -665,7 +670,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -750,11 +754,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig index 5f74857ae904..2385348b99a7 100644 --- a/arch/mips/configs/ddb5476_defconfig +++ b/arch/mips/configs/ddb5476_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_R5432=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -117,6 +118,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -214,7 +216,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -363,7 +364,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -487,6 +487,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -606,7 +607,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -641,3 +641,4 @@ CONFIG_CMDLINE="ip=any" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 13222c363ccf..3a2e7ca35066 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -80,7 +80,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_I8259=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_DDB5XXX_COMMON=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +105,7 @@ CONFIG_CPU_R5432=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -118,6 +118,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +185,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -345,7 +345,6 @@ CONFIG_PCNET32=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -567,7 +566,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +600,4 @@ CONFIG_CMDLINE="ip=any" # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 9f41a3d0f6e4..c2bf43ff126b 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -109,6 +109,7 @@ CONFIG_CPU_R3000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -184,7 +185,6 @@ CONFIG_BLK_DEV_SD=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -537,7 +537,6 @@ CONFIG_RAMFS=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -587,3 +586,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index b0154fa605f7..cda052941dbb 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -91,7 +91,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +115,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -180,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +190,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -570,7 +570,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -605,3 +604,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/eagle_defconfig b/arch/mips/configs/eagle_defconfig index 9a4517f6afbd..78feb1ac0945 100644 --- a/arch/mips/configs/eagle_defconfig +++ b/arch/mips/configs/eagle_defconfig @@ -59,6 +59,7 @@ CONFIG_NEC_EAGLE=y # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -261,7 +263,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -274,6 +275,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -291,7 +293,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -447,7 +448,6 @@ CONFIG_PCMCIA_PCNET=m # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -692,7 +692,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -739,11 +738,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig index 2cbeb69b967a..f1c310de72cc 100644 --- a/arch/mips/configs/ev64120_defconfig +++ b/arch/mips/configs/ev64120_defconfig @@ -111,6 +111,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -124,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -191,7 +193,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -339,7 +340,6 @@ CONFIG_PPP_ASYNC=y # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -559,7 +559,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -594,3 +593,4 @@ CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/d # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig index 4d6bd5352903..506214b4bbeb 100644 --- a/arch/mips/configs/ev96100_defconfig +++ b/arch/mips/configs/ev96100_defconfig @@ -110,6 +110,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -514,7 +516,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -549,3 +550,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 912beee0c66c..83d850031444 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -114,6 +114,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ CONFIG_BLK_DEV_SR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -750,7 +750,6 @@ CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index c7cff248c5c7..a75dfcdd4bf4 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -113,6 +113,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -128,6 +129,7 @@ CONFIG_NR_CPUS=64 # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -203,7 +205,6 @@ CONFIG_CHR_DEV_ST=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -226,7 +227,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -235,6 +235,7 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set CONFIG_SCSI_QLOGIC_ISP=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -267,6 +268,7 @@ CONFIG_SCSI_QLA2XXX=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -638,7 +640,6 @@ CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,11 +701,13 @@ CONFIG_CRYPTO_CAST6=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 7dcbf62c9219..f6e3592da18b 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -102,6 +102,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -116,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -193,7 +195,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -222,7 +223,6 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -231,6 +231,7 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -263,6 +264,7 @@ CONFIG_SCSI_QLA2XXX=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -617,7 +619,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -663,3 +664,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig index d7f83618a35a..3460da6ad76a 100644 --- a/arch/mips/configs/it8172_defconfig +++ b/arch/mips/configs/it8172_defconfig @@ -110,6 +110,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -122,6 +123,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -231,7 +233,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -242,6 +243,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -615,7 +617,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -650,3 +651,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig index 58a83eece110..4f3e01b3b8cc 100644 --- a/arch/mips/configs/ivr_defconfig +++ b/arch/mips/configs/ivr_defconfig @@ -108,6 +108,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -120,6 +121,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -208,7 +210,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -350,7 +351,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -571,7 +571,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -606,3 +605,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig index 99cda767b71c..f28e0657e6a7 100644 --- a/arch/mips/configs/jaguar-atx_defconfig +++ b/arch/mips/configs/jaguar-atx_defconfig @@ -100,6 +100,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -118,6 +119,7 @@ CONFIG_HIGHMEM=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +186,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -538,3 +539,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 95e463724cda..17b715a04735 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -104,6 +104,7 @@ CONFIG_CPU_TX39XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -115,6 +116,7 @@ CONFIG_RTC_DS1742=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -182,7 +184,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -324,7 +325,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -462,6 +462,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -578,7 +579,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -613,3 +613,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index f7208748c51f..d5874a83fbf4 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -112,6 +112,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -127,6 +128,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -242,7 +244,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -283,6 +284,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -301,7 +303,6 @@ CONFIG_IDEDMA_AUTO=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -438,7 +439,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -665,7 +665,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,3 +699,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 67a995528818..87e171b5f008 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -115,6 +115,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -129,6 +130,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ CONFIG_PCNET32=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -580,7 +580,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -615,3 +614,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/mirage_defconfig b/arch/mips/configs/mirage_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/mirage_defconfig +++ b/arch/mips/configs/mirage_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 3ccf5a617072..a78627cddd1d 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -59,6 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_TANBAC_TB0229 is not set CONFIG_VICTOR_MPC30X=y # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -192,7 +194,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -335,7 +336,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -555,7 +555,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,11 +601,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index f33d867cc300..704bd7e7845d 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -100,6 +100,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -114,7 +115,10 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_PCI is not set +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -154,8 +158,13 @@ CONFIG_BINFMT_ELF32=y # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set # @@ -185,6 +194,7 @@ CONFIG_BINFMT_ELF32=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -257,27 +267,51 @@ CONFIG_NETDEVICES=y # CONFIG_TUN is not set # CONFIG_ETHERTAP is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # -CONFIG_MV64340_ETH=y -CONFIG_MV64340_ETH_0=y -# CONFIG_MV64340_ETH_1 is not set -# CONFIG_MV64340_ETH_2 is not set +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_MV64340_ETH is not set # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -288,6 +322,8 @@ CONFIG_MV64340_ETH_0=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -329,6 +365,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # # Input Device Drivers @@ -426,6 +463,7 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -509,7 +547,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -544,3 +581,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index c3d713ac4ebd..e83e3f965082 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -108,6 +108,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -124,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -513,7 +515,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -548,3 +549,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig new file mode 100644 index 000000000000..d8e4d007a8c5 --- /dev/null +++ b/arch/mips/configs/ocelot_g_defconfig @@ -0,0 +1,587 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS64=y +CONFIG_64BIT=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_MACH_JAZZ is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +CONFIG_MOMENCO_OCELOT_G=y +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_SYSCLK_75 is not set +# CONFIG_SYSCLK_83 is not set +CONFIG_SYSCLK_100=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_RM7000_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_GALILEO_64240_ETH=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/osprey_defconfig b/arch/mips/configs/osprey_defconfig index 6d6e26201134..c7a3bbd48560 100644 --- a/arch/mips/configs/osprey_defconfig +++ b/arch/mips/configs/osprey_defconfig @@ -83,7 +83,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_VR4181=y @@ -109,6 +108,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -507,7 +507,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -542,3 +541,4 @@ CONFIG_CMDLINE="ip=bootp ether=46,0x03fe0300,eth0" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/pb1000_defconfig b/arch/mips/configs/pb1000_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/pb1000_defconfig +++ b/arch/mips/configs/pb1000_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 533dc53ae283..fbf01a172524 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -123,6 +123,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -137,6 +138,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +215,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -254,6 +255,7 @@ CONFIG_BLK_DEV_HPT366=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -272,7 +274,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -452,7 +453,6 @@ CONFIG_PPP_DEFLATE=m # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -611,6 +611,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -682,7 +685,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -767,11 +769,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index ad953c3a9630..382b9f126477 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -212,7 +214,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -253,6 +254,7 @@ CONFIG_BLK_DEV_HPT366=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -271,7 +273,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -451,7 +452,6 @@ CONFIG_PPP_DEFLATE=m # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -610,6 +610,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -681,7 +684,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -766,11 +768,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 2317b23ed6e1..68d9ef86ac1c 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -116,6 +116,7 @@ CONFIG_CPU_R4X00=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -129,6 +130,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -246,7 +248,6 @@ CONFIG_BLK_DEV_SR_VENDOR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -268,12 +269,12 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -294,6 +295,7 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set @@ -695,7 +697,6 @@ CONFIG_PLIP=m # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -908,6 +909,7 @@ CONFIG_USB_WACOM=m CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m # CONFIG_USB_MTOUCH is not set +CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m # CONFIG_USB_ATI_REMOTE is not set @@ -1016,6 +1018,7 @@ CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_LED=m CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGETSERVO=m CONFIG_USB_TEST=m # @@ -1051,10 +1054,14 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=m # CONFIG_JFS_POSIX_ACL is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set CONFIG_XFS_QUOTA=y @@ -1140,6 +1147,7 @@ CONFIG_RPCSEC_GSS_KRB5=m CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -1151,7 +1159,6 @@ CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m CONFIG_CODA_FS_OLD_API=y -CONFIG_INTERMEZZO_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m @@ -1252,11 +1259,13 @@ CONFIG_CRYPTO_CAST6=m # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_TEST=m # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 593f119b4b76..7d3c4df26207 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -93,7 +93,6 @@ CONFIG_CPU_SB1_PASS_1=y # CONFIG_CPU_SB1_PASS_4 is not set # CONFIG_CPU_SB1_PASS_2_112x is not set # CONFIG_CPU_SB1_PASS_3 is not set -CONFIG_SIBYTE_HAS_PCI=y CONFIG_SIBYTE_HAS_LDT=y # CONFIG_SIMULATION is not set CONFIG_SIBYTE_CFE=y @@ -107,7 +106,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_DUMMY_KEYB=y CONFIG_SWAP_IO_SPACE=y CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 @@ -134,6 +132,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_SIBYTE_DMA_PAGEOPS is not set @@ -154,6 +153,7 @@ CONFIG_NR_CPUS=2 # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +213,30 @@ CONFIG_BLK_DEV_INITRD=y # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=y +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPCI is not set +CONFIG_BLK_DEV_IDE_SWARM=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -228,7 +251,6 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -371,7 +393,6 @@ CONFIG_NET_SB1250_MAC=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -575,7 +596,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -623,11 +643,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index ba93024bf7ad..d9b6532c23c4 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -19,7 +19,6 @@ CONFIG_BROKEN_ON_SMP=y # CONFIG_SWAP=y # CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set @@ -103,6 +102,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -429,3 +429,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index f32841b8023d..818bf63b72ea 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -90,7 +90,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_FB=y @@ -115,6 +114,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -125,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -179,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +191,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -215,7 +216,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -608,7 +608,6 @@ CONFIG_SMB_NLS_REMOTE="cp932" # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -681,5 +680,6 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig index 730a994abc2c..146c70cd6944 100644 --- a/arch/mips/configs/tb0229_defconfig +++ b/arch/mips/configs/tb0229_defconfig @@ -59,7 +59,8 @@ CONFIG_MACH_VR41XX=y CONFIG_TANBAC_TB0229=y # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_TANBAC_TB0219=y @@ -117,6 +117,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -127,6 +128,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -196,7 +198,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -355,7 +356,6 @@ CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -599,7 +599,6 @@ CONFIG_SMB_NLS_REMOTE="cp932" # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -672,5 +671,6 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index cfe12d1c4a7f..e1923900c710 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -115,6 +115,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -179,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -190,6 +190,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -573,7 +574,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -608,3 +608,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/xxs1500_defconfig b/arch/mips/configs/xxs1500_defconfig index edf9ced7a727..188176e34b83 100644 --- a/arch/mips/configs/xxs1500_defconfig +++ b/arch/mips/configs/xxs1500_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index fc1eddbbd1d2..37d39a6677b5 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -9,20 +9,20 @@ CONFIG_MIPS32=y # # Code maturity level options # -CONFIG_EXPERIMENTAL=y +# CONFIG_EXPERIMENTAL is not set CONFIG_CLEAN_COMPILE=y CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y # # General setup # CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=15 +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -41,47 +41,40 @@ CONFIG_IOSCHED_CFQ=y # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -CONFIG_MODVERSIONS=y CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y # # Machine selection # # CONFIG_MACH_JAZZ is not set -# CONFIG_BAGET_MIPS is not set # CONFIG_MACH_VR41XX is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_DDB5074 is not set +CONFIG_PMC_YOSEMITE=y +# CONFIG_HYPERTRANSPORT is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SOC_AU1X00 is not set -# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +99,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -114,15 +108,18 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y CONFIG_CPU_HAS_SYNC=y -# CONFIG_HIGHMEM is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 +CONFIG_HIGHMEM=y +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -159,11 +156,14 @@ CONFIG_TRAD_SIGNALS=y # Block devices # # CONFIG_BLK_DEV_FD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_LBD=y +# CONFIG_LBD is not set # # ATA/ATAPI/MFM/RLL support @@ -173,40 +173,7 @@ CONFIG_LBD=y # # SCSI device support # -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # Multi-device support (RAID and LVM) @@ -225,6 +192,7 @@ CONFIG_SCSI_REPORT_LUNS=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -234,46 +202,31 @@ CONFIG_NET=y # # Networking options # -CONFIG_PACKET=y +CONFIG_PACKET=m CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set +CONFIG_NETLINK_DEV=m CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing @@ -295,23 +248,50 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +CONFIG_TITAN_GE=y # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -322,10 +302,9 @@ CONFIG_NET_ETHERNET=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set # # ISDN subsystem @@ -351,10 +330,8 @@ CONFIG_NET_ETHERNET=y # # CONFIG_GAMEPORT is not set CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set # # Input Device Drivers @@ -364,22 +341,21 @@ CONFIG_SERIO_SERPORT=y # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_SYNCLINK is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_N_HDLC is not set -# CONFIG_STALDRV is not set +# CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -403,6 +379,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -438,6 +415,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -448,13 +426,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # File systems # # CONFIG_EXT2_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set @@ -482,7 +455,6 @@ CONFIG_FS_MBCACHE=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set @@ -491,13 +463,7 @@ CONFIG_RAMFS=y # # Miscellaneous filesystems # -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -509,22 +475,16 @@ CONFIG_RAMFS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFS_V3 is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y # CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_AFS_FS is not set # # Partition Types @@ -558,3 +518,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 912beee0c66c..83d850031444 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -114,6 +114,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ CONFIG_BLK_DEV_SR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -750,7 +750,6 @@ CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 9ce8090eff68..3a7f766fd961 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -9,7 +9,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ time.o traps.o unaligned.o ifdef CONFIG_MODULES -obj-y += mips_ksyms.o +obj-y += mips_ksyms.o module.o obj-$(CONFIG_MIPS32) += module-elf32.o obj-$(CONFIG_MIPS64) += module-elf64.o endif @@ -23,6 +23,7 @@ obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 31c17ced894e..1375d448308b 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -177,7 +177,7 @@ static inline void check_daddi(void) extern asmlinkage void handle_daddi_ov(void); unsigned long flags; void *handler; - long v; + long v, tmp; printk("Checking for the daddi bug... "); @@ -197,13 +197,15 @@ static inline void check_daddi(void) ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddi %0, %1, %2\n\t" + "daddi %0, %1, %3\n\t" ".set pop" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -217,9 +219,11 @@ static inline void check_daddi(void) local_irq_save(flags); handler = set_except_vector(12, handle_daddi_ov); asm volatile( - "daddi %0, %1, %2" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" + "daddi %0, %1, %3" + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -240,7 +244,7 @@ static inline void check_daddi(void) static inline void check_daddiu(void) { - long v, w; + long v, w, tmp; printk("Checking for the daddiu bug... "); @@ -265,15 +269,17 @@ static inline void check_daddiu(void) ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2\n\t" ".set pop" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("no.\n"); @@ -283,11 +289,13 @@ static inline void check_daddiu(void) printk("yes, workaround... "); asm volatile( - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("yes.\n"); diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5013599347e3..36777476dae1 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1,6 +1,8 @@ /* * Processor capabilities determination functions. * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki * Copyright (C) 1994 - 2003 Ralf Baechle * Copyright (C) 2001 MIPS Inc. * @@ -49,6 +51,14 @@ static void r4k_wait(void) ".set\tmips0"); } +/* + * The Au1xxx wait is available only if we run CONFIG_PM and + * the timer setup found we had a 32KHz counter available. + * There are still problems with functions that may call au1k_wait + * directly, but that will be discovered pretty quickly. + */ +extern void (*au1k_wait_ptr)(void); + void au1k_wait(void) { #ifdef CONFIG_PM @@ -90,7 +100,6 @@ static inline void check_wait(void) case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: -/* case CPU_RM9000: */ case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: @@ -102,12 +111,19 @@ static inline void check_wait(void) cpu_wait = r4k_wait; printk(" available.\n"); break; +#ifdef CONFIG_PM case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: - cpu_wait = au1k_wait; - printk(" available.\n"); + if (au1k_wait_ptr != NULL) { + cpu_wait = au1k_wait_ptr; + printk(" available.\n"); + } + else { + printk(" unavailable.\n"); + } break; +#endif default: printk(" unavailable.\n"); break; @@ -238,8 +254,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - c->cputype = CPU_VR41XX; - break; + c->cputype = CPU_VR41XX; + break; } c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS; @@ -371,7 +387,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) c->cputype = CPU_RM9000; c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; + MIPS_CPU_LLSC; /* * Bit 29 in the info register of the RM9000 * indicates if the TLB has 48 or 64 entries. @@ -407,9 +423,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) MIPS_CPU_LLSC; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -475,9 +488,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) /* Probe for L2 cache */ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -505,9 +515,6 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) break; } c->isa_level = MIPS_CPU_ISA_M32; - break; - default: - c->cputype = CPU_UNKNOWN; break; } } @@ -528,9 +535,6 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -542,14 +546,11 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) c->cputype = CPU_SR71000; c->isa_level = MIPS_CPU_ISA_M64; c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; c->scache.ways = 8; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -563,7 +564,6 @@ __init void cpu_probe(void) c->processor_id = read_c0_prid(); switch (c->processor_id & 0xff0000) { - case PRID_COMP_LEGACY: cpu_probe_legacy(c); break; diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c index 35818bb1a359..ffd216d6d6dc 100644 --- a/arch/mips/kernel/module-elf32.c +++ b/arch/mips/kernel/module-elf32.c @@ -248,14 +248,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, me->name); return -ENOEXEC; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c index da7295d53113..e804792ee1ee 100644 --- a/arch/mips/kernel/module-elf64.c +++ b/arch/mips/kernel/module-elf64.c @@ -272,14 +272,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return 0; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c new file mode 100644 index 000000000000..581687080082 --- /dev/null +++ b/arch/mips/kernel/module.c @@ -0,0 +1,53 @@ +#include +#include + +static LIST_HEAD(dbe_list); +static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED; + +/* Given an address, look for it in the module exception tables. */ +const struct exception_table_entry *search_module_dbetables(unsigned long addr) +{ + unsigned long flags; + const struct exception_table_entry *e = NULL; + struct mod_arch_specific *dbe; + + spin_lock_irqsave(&dbe_lock, flags); + list_for_each_entry(dbe, &dbe_list, dbe_list) { + e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr); + if (e) + break; + } + spin_unlock_irqrestore(&dbe_lock, flags); + + /* Now, if we found one, we are running inside it now, hence + we cannot unload the module, hence no refcnt needed. */ + return e; +} + +/* Put in dbe list if neccessary. */ +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + const Elf_Shdr *s; + char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + INIT_LIST_HEAD(&me->arch.dbe_list); + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + if (strcmp("__dbe_table", secstrings + s->sh_name) != 0) + continue; + me->arch.dbe_start = (void *)s->sh_addr; + me->arch.dbe_end = (void *)s->sh_addr + s->sh_size; + spin_lock_irq(&dbe_lock); + list_add(&me->arch.dbe_list, &dbe_list); + spin_unlock_irq(&dbe_lock); + } + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ + spin_lock_irq(&dbe_lock); + list_del(&mod->arch.dbe_list); + spin_unlock_irq(&dbe_lock); +} diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 09477c1e3e7b..24eab2f9d7dd 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -627,6 +627,7 @@ out: jr ra sys sys_mq_timedreceive 5 sys sys_mq_notify 2 /* 4275 */ sys sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 19e430d62c47..3125b634faec 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -447,3 +447,4 @@ sys_call_table: PTR sys_mq_timedreceive PTR sys_mq_notify PTR sys_mq_getsetattr /* 5235 */ + PTR sys_ni_syscall /* sys_vserver */ diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 9993a8a15397..c00459f8f59d 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -357,3 +357,4 @@ EXPORT(sysn32_call_table) PTR compat_sys_mq_timedreceive PTR compat_sys_mq_notify PTR compat_sys_mq_getsetattr /* 6239 */ + PTR sys_ni_syscall /* sys_vserver */ diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b351656863af..3a89bf425bf6 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -535,6 +535,7 @@ out: jr ra sys compat_sys_mq_timedreceive 5 sys compat_sys_mq_notify 2 /* 4275 */ sys compat_sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c index 51c3e772c029..4197b4109dc3 100644 --- a/arch/mips/kernel/semaphore.c +++ b/arch/mips/kernel/semaphore.c @@ -1,273 +1,165 @@ /* - * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * MIPS-specific semaphore code. * - * Heavily inspired by the Alpha implementation + * Copyright (C) 1999 Cort Dougan + * Copyright (C) 2004 Ralf Baechle + * + * 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. + * + * April 2001 - Reworked by Paul Mackerras + * to eliminate the SMP races in the old version between the updates + * of `count' and `waking'. Now we use negative `count' values to + * indicate that some process(es) are waiting for the semaphore. */ + #include -#include #include -#include #include +#include +#include +#include +#include -#ifdef CONFIG_CPU_HAS_LLDSCD -/* - * On machines without lld/scd we need a spinlock to make the manipulation of - * sem->count and sem->waking atomic. Scalability isn't an issue because - * this lock is used on UP only so it's just an empty variable. - */ -spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; - -EXPORT_SYMBOL(semaphore_lock); -#endif +#ifdef CONFIG_CPU_HAS_LLSC /* - * Semaphores are implemented using a two-way counter: The "count" variable is - * decremented for each process that tries to sleep, while the "waking" variable - * is incremented when the "up()" code goes to wake up waiting processes. - * - * Notably, the inline "up()" and "down()" functions can efficiently test if - * they need to do any extra work (up needs to do something only if count was - * negative before the increment operation. - * - * waking_non_zero() must execute atomically. + * Atomically update sem->count. + * This does the equivalent of the following: * - * When __up() is called, the count was negative before incrementing it, and we - * need to wake up somebody. - * - * This routine adds one to the count of processes that need to wake up and - * exit. ALL waiting processes actually wake up but only the one that gets to - * the "waking" field first will gate through and acquire the semaphore. The - * others will go back to sleep. - * - * Note that these functions are only called when there is contention on the - * lock, and as such all this is the "non-critical" part of the whole semaphore - * business. The critical part is the inline stuff in where - * we want to avoid any extra jumps and calls. + * old_count = sem->count; + * tmp = MAX(old_count, 0) + incr; + * sem->count = tmp; + * return old_count; */ -void __up_wakeup(struct semaphore *sem) +static inline int __sem_update_count(struct semaphore *sem, int incr) { - wake_up(&sem->wait); -} - -EXPORT_SYMBOL(__up_wakeup); - -#ifdef CONFIG_CPU_HAS_LLSC - -static inline int waking_non_zero(struct semaphore *sem) -{ - int ret, tmp; + int old_count, tmp; __asm__ __volatile__( - "1: ll %1, %2 # waking_non_zero \n" - " blez %1, 2f \n" - " subu %0, %1, 1 \n" - " sc %0, %2 \n" - " beqz %0, 1b \n" - "2: \n" - : "=r" (ret), "=r" (tmp), "+m" (sem->waking) - : "0" (0)); - - return ret; + "1: ll %0, %2 \n" + " sra %1, %0, 31 \n" + " not %1 \n" + " and %1, %0, %1 \n" + " add %1, %1, %3 \n" + " sc %1, %2 \n" + " beqz %1, 1b \n" + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (incr), "m" (sem->count)); + + return old_count; } -#else /* !CONFIG_CPU_HAS_LLSC */ +#else -static inline int waking_non_zero(struct semaphore *sem) +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +static inline int __sem_update_count(struct semaphore *sem, int incr) { unsigned long flags; - int waking, ret = 0; + int old_count, tmp; spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } + old_count = atomic_read(&sem->count); + tmp = max_t(int, old_count, 0) + incr; + atomic_set(&sem->count, tmp); spin_unlock_irqrestore(&semaphore_lock, flags); - return ret; + return old_count; } -#endif /* !CONFIG_CPU_HAS_LLSC */ - -/* - * Perform the "down" function. Return zero for semaphore acquired, return - * negative for signalled out of the function. - * - * If called from down, the return is ignored and the wait loop is not - * interruptible. This means that a task waiting on a semaphore using "down()" - * cannot be killed until someone does an "up()" on the semaphore. - * - * If called from down_interruptible, the return value gets checked upon return. - * If the return value is negative then the task continues with the negative - * value in the return register (it can be tested by the caller). - * - * Either form may be used in conjunction with "up()". - */ +#endif -void __sched __down_failed(struct semaphore * sem) +void __up(struct semaphore *sem) { - struct task_struct *tsk = current; - wait_queue_t wait; - - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. + * Note that we incremented count in up() before we came here, + * but that was ineffective since the result was <= 0, and + * any negative value of count is equivalent to 0. + * This ends up setting count to 1, unless count is now > 0 + * (i.e. because some other cpu has called up() in the meantime), + * in which case we just increment count. */ - for (;;) { - if (waking_non_zero(sem)) - break; - schedule(); - __set_current_state(TASK_UNINTERRUPTIBLE); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&sem->wait, &wait); + __sem_update_count(sem, 1); + wake_up(&sem->wait); } -EXPORT_SYMBOL(__down_failed); - -#ifdef CONFIG_CPU_HAS_LLDSCD +EXPORT_SYMBOL(__up); /* - * waking_non_zero_interruptible: - * 1 got the lock - * 0 go to sleep - * -EINTR interrupted - * - * We must undo the sem->count down_interruptible decrement - * simultaneously and atomically with the sem->waking adjustment, - * otherwise we can race with wake_one_more. - * - * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. - * - * This is crazy. Normally it's strictly forbidden to use 64-bit operations - * in the 32-bit MIPS kernel. In this case it's however ok because if an - * interrupt has destroyed the upper half of registers sc will fail. - * Note also that this will not work for MIPS32 CPUs! - * - * Pseudocode: - * - * If(sem->waking > 0) { - * Decrement(sem->waking) - * Return(SUCCESS) - * } else If(signal_pending(tsk)) { - * Increment(sem->count) - * Return(-EINTR) - * } else { - * Return(SLEEP) - * } + * Note that when we come in to __down or __down_interruptible, + * we have already decremented count, but that decrement was + * ineffective since the result was < 0, and any negative value + * of count is equivalent to 0. + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. */ - -static inline int -waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) -{ - long ret, tmp; - - __asm__ __volatile__( - " .set push # waking_non_zero_interruptible \n" - " .set mips3 \n" - " .set noat \n" - "0: lld %1, %2 \n" - " li %0, 0 \n" - " sll $1, %1, 0 \n" - " blez $1, 1f \n" - " daddiu %1, %1, -1 \n" - " li %0, 1 \n" - " b 2f \n" - "1: beqz %3, 2f \n" - " li %0, %4 \n" - " dli $1, 0x0000000100000000 \n" - " daddu %1, %1, $1 \n" - "2: scd %1, %2 \n" - " beqz %1, 0b \n" - " .set pop \n" - : "=&r" (ret), "=&r" (tmp), "=m" (*sem) - : "r" (signal_pending(tsk)), "i" (-EINTR)); - - return ret; -} - -#else /* !CONFIG_CPU_HAS_LLDSCD */ - -static inline int waking_non_zero_interruptible(struct semaphore *sem, - struct task_struct *tsk) +void __sched __down(struct semaphore *sem) { - int waking, pending, ret = 0; - unsigned long flags; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); - pending = signal_pending(tsk); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); - spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } else if (pending) { - atomic_set(&sem->count, atomic_read(&sem->count) + 1); - ret = -EINTR; + /* + * Try to get the semaphore. If the count is > 0, then we've + * got the semaphore; we decrement count and exit the loop. + * If the count is 0 or negative, we set it to -1, indicating + * that we are asleep, and then sleep. + */ + while (__sem_update_count(sem, -1) <= 0) { + schedule(); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); } - spin_unlock_irqrestore(&semaphore_lock, flags); + remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + /* + * If there are any more sleepers, wake one of them up so + * that it can either get the semaphore, or set count to -1 + * indicating that there are still processes sleeping. + */ + wake_up(&sem->wait); } -#endif /* !CONFIG_CPU_HAS_LLDSCD */ +EXPORT_SYMBOL(__down); -int __sched __down_failed_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { + int retval = 0; struct task_struct *tsk = current; - wait_queue_t wait; - int ret = 0; + DECLARE_WAITQUEUE(wait, tsk); - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_INTERRUPTIBLE); + __set_task_state(tsk, TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. - */ - for (;;) { - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; + while (__sem_update_count(sem, -1) <= 0) { + if (signal_pending(current)) { + /* + * A signal is pending - give up trying. + * Set sem->count to 0 if it is negative, + * since we are no longer sleeping. + */ + __sem_update_count(sem, 0); + retval = -EINTR; break; } schedule(); - __set_current_state(TASK_INTERRUPTIBLE); + set_task_state(tsk, TASK_INTERRUPTIBLE); } - __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + wake_up(&sem->wait); + return retval; } -EXPORT_SYMBOL(__down_failed_interruptible); +EXPORT_SYMBOL(__down_interruptible); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 8a5acf174730..c7d1d76c9c8b 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -452,14 +452,18 @@ static void __init do_earlyinitcalls(void) void __init setup_arch(char **cmdline_p) { + unsigned int status; + cpu_probe(); prom_init(); cpu_report(); #ifdef CONFIG_MIPS32 /* Disable coprocessors and set FPU for 16/32 FPR register model */ - clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - set_c0_status(ST0_CU0); + status = read_c0_status(); + status &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + status |= ST0_CU0; + write_c0_status(status); #endif #ifdef CONFIG_MIPS64 /* @@ -467,8 +471,10 @@ void __init setup_arch(char **cmdline_p) * Maybe because the kernel is in ckseg0 and not xkphys? Clear it * anyway ... */ - clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); - set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + status = read_c0_status(); + status &= ~(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + status |= (ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + write_c0_status(status); #endif #if defined(CONFIG_VT) diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 7e1eca9736b1..16519f7e8c3b 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -36,7 +36,7 @@ #include #include -asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs) +asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs) { int fd[2]; int error, res; diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 25d7e97edfca..494d1872df32 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1639,7 +1639,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf) printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", current->comm, current->pid, fname, buf); - error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); + error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64)); if(error) goto out; error = user_path_walk(fname, &nd); diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index d0c980a9b859..0199485a4a8f 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -789,3 +789,8 @@ EXPORT_SYMBOL(rtc_lock); EXPORT_SYMBOL(to_tm); EXPORT_SYMBOL(rtc_set_time); EXPORT_SYMBOL(rtc_get_time); + +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies*(1000000000/HZ); +} diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 752dbd3e93fb..362c1fd66b12 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -234,6 +234,7 @@ void show_regs(struct pt_regs *regs) void show_registers(struct pt_regs *regs) { show_regs(regs); + print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); show_stack(current, (long *) regs->regs[29]); @@ -278,47 +279,8 @@ void __declare_dbe_table(void) ); } -#ifdef CONFIG_MDULES - -/* Given an address, look for it in the module exception tables. */ -const struct exception_table_entry *search_module_dbetables(unsigned long addr) -{ - unsigned long flags; - const struct exception_table_entry *e = NULL; - struct module *mod; - - spin_lock_irqsave(&modlist_lock, flags); - list_for_each_entry(mod, &modules, list) { - if (mod->arch.num_dbeentries == 0) - continue; - - e = search_extable(mod->arch.dbe_table_start, - mod->arch.dbe_table_end + - mod->arch.num_dbeentries - 1, - addr); - if (e) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - - /* Now, if we found one, we are running inside it now, hence - we cannot unload the module, hence no refcnt needed. */ - return e; -} - -#else - /* Given an address, look for it in the exception tables. */ -static inline const struct exception_table_entry * -search_module_dbetables(unsigned long addr) -{ - return NULL; -} - -#endif - -/* Given an address, look for it in the exception tables. */ -const struct exception_table_entry *search_dbe_tables(unsigned long addr) +static const struct exception_table_entry *search_dbe_tables(unsigned long addr) { const struct exception_table_entry *e; @@ -745,12 +707,25 @@ asmlinkage void do_reserved(struct pt_regs *regs) static inline void parity_protection_init(void) { switch (current_cpu_data.cputype) { + case CPU_24K: + /* 24K cache parity not currently implemented in FPGA */ + printk(KERN_INFO "Disable cache parity protection for " + "MIPS 24K CPU.\n"); + write_c0_ecc(read_c0_ecc() & ~0x80000000); + break; case CPU_5KC: /* Set the PE bit (bit 31) in the c0_ecc register. */ - printk(KERN_INFO "Enable the cache parity protection for " - "MIPS 5KC CPUs.\n"); + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 5KC/24K CPUs.\n"); write_c0_ecc(read_c0_ecc() | 0x80000000); break; + case CPU_20KC: + case CPU_25KF: + /* Clear the DE bit (bit 16) in the c0_status register. */ + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 20KC/25KF CPUs.\n"); + clear_c0_status(ST0_DE); + break; default: break; } diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile index 1bde2a003249..fd6a2bafdfcf 100644 --- a/arch/mips/lib-32/Makefile +++ b/arch/mips/lib-32/Makefile @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile index 1bde2a003249..fd6a2bafdfcf 100644 --- a/arch/mips/lib-64/Makefile +++ b/arch/mips/lib-64/Makefile @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c index c1b46edc6ed9..1871c30ed2eb 100644 --- a/arch/mips/mips-boards/generic/cmdline.c +++ b/arch/mips/mips-boards/generic/cmdline.c @@ -51,7 +51,9 @@ void __init prom_init_cmdline(void) *cp++ = ' '; actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + if (cp != &(arcs_cmdline[0])) { + /* get rid of trailing space */ --cp; - *cp = '\0'; + *cp = '\0'; + } } diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c index b1edd90b9805..2c1ab1f19fdc 100644 --- a/arch/mips/mips-boards/generic/printf.c +++ b/arch/mips/mips-boards/generic/printf.c @@ -59,7 +59,7 @@ static inline void serial_out(int offset, int value) outb(value, PORT(offset)); } -int putPromChar(char c) +int prom_putchar(char c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; @@ -69,7 +69,7 @@ int putPromChar(char c) return 1; } -char getPromChar(void) +char prom_getchar(void) { while (!(serial_in(UART_LSR) & UART_LSR_DR)) ; @@ -77,33 +77,3 @@ char getPromChar(void) return serial_in(UART_RX); } -static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; - -static char buf[1024]; - -void __init prom_printf(char *fmt, ...) -{ - va_list args; - int l; - char *p, *buf_end; - long flags; - - spin_lock_irqsave(con_lock, flags); - - va_start(args, fmt); - l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ - va_end(args); - - buf_end = buf + l; - - for (p = buf; p < buf_end; p++) { - /* Crude cr/nl handling is better than none */ - if (*p == '\n') - putPromChar('\r'); - putPromChar(*p); - } - /* wait for output to drain */ - while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0) - ; - spin_unlock_irqrestore(con_lock, flags); -} diff --git a/arch/mips/mm-32/Makefile b/arch/mips/mm-32/Makefile deleted file mode 100644 index 956f4bb8a29d..000000000000 --- a/arch/mips/mm-32/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-$(CONFIG_CPU_TX49XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4300) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlbex-r4k.o -obj-$(CONFIG_CPU_VR41XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5000) += tlbex-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5432) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlbex-r4k.o -obj-$(CONFIG_CPU_R10000) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS32) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS64) += tlbex-r4k.o -obj-$(CONFIG_CPU_SB1) += tlbex-r4k.o - -EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mm-32/tlbex-r4k.S b/arch/mips/mm-32/tlbex-r4k.S deleted file mode 100644 index 49742718da0a..000000000000 --- a/arch/mips/mm-32/tlbex-r4k.S +++ /dev/null @@ -1,524 +0,0 @@ -/* - * TLB exception handling code for r4k. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PTE_L ld -#define PTE_S sd -#define PTE_SRL dsrl -#define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 -#else -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 -#endif - -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - - __INIT - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define GET_PTE_OFF(reg) -#elif CONFIG_CPU_VR41XX -#define GET_PTE_OFF(reg) srl reg, reg, 3 -#else -#define GET_PTE_OFF(reg) srl reg, reg, 1 -#endif - -/* - * These handlers much be written in a relocatable manner - * because based upon the cpu type an arbitrary one of the - * following pieces of code will be copied to the KSEG0 - * vector location. - */ - /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ - .set noreorder - .set noat - LEAF(except_vec0_r4000) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - mtc0_tlbw_hazard - tlbwr # write random tlb entry - tlbw_eret_hazard - eret # return from trap - END(except_vec0_r4000) - - /* TLB refill, EXL == 0, R4600 version */ - LEAF(except_vec0_r4600) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 k1, CP0_ENTRYLO1 - nop - tlbwr - nop - eret - END(except_vec0_r4600) - - /* TLB refill, EXL == 0, R52x0 "Nevada" version */ - /* - * This version has a bug workaround for the Nevada. It seems - * as if under certain circumstances the move from cp0_context - * might produce a bogus result when the mfc0 instruction and - * it's consumer are in a different cacheline or a load instruction, - * probably any memory reference, is between them. This is - * potencially slower than the R4000 version, so we use this - * special version. - */ - .set noreorder - .set noat - LEAF(except_vec0_nevada) - .set mips3 - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - lw k1, pgd_current # get pgd pointer - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 # add in pgd offset - lw k1, (k1) - mfc0 k0, CP0_CONTEXT # get context reg - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - nop # QED specified nops - nop - tlbwr # write random tlb entry - nop # traditional nop - eret # return from trap - END(except_vec0_nevada) - - /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ - LEAF(except_vec0_sb1) -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - bnez k0, 1f -#endif - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - tlbwr # write random tlb entry -1: eret # return from trap - END(except_vec0_sb1) - - /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ - LEAF(except_vec0_r45k_bvahwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r45k_bvahwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ - LEAF(except_vec0_r4k_mphwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_mphwbug) -#endif - - /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ - LEAF(except_vec0_r4k_250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - b 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_250MHZhwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ - LEAF(except_vec0_r4k_MP250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - mfc0 k0, CP0_INDEX - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_MP250MHZhwbug) -#endif - - __FINIT - - .set noreorder - -/* - * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: - * 2. A timing hazard exists for the TLBP instruction. - * - * stalling_instruction - * TLBP - * - * The JTLB is being read for the TLBP throughout the stall generated by the - * previous instruction. This is not really correct as the stalling instruction - * can modify the address used to access the JTLB. The failure symptom is that - * the TLBP instruction will use an address created for the stalling instruction - * and not the address held in C0_ENHI and thus report the wrong results. - * - * The software work-around is to not allow the instruction preceding the TLBP - * to stall - make it an NOP or some other instruction guaranteed not to stall. - * - * Errata 2 will not be fixed. This errata is also on the R5000. - * - * As if we MIPS hackers wouldn't know how to nop pipelines happy ... - */ -#define R5K_HAZARD nop - - /* - * Note for many R4k variants tlb probes cannot be executed out - * of the instruction cache else you get bogus results. - */ - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - beqz k0, 1f - nop - .set mips3 - eret - .set mips0 -1: -#endif -invalid_tlbl: -#ifdef TLB_OPTIMIZE - .set mips3 - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - li k0,0 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - PTE_L k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) diff --git a/arch/mips/mm-64/Makefile b/arch/mips/mm-64/Makefile deleted file mode 100644 index 30b4d332e7ec..000000000000 --- a/arch/mips/mm-64/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-y := tlbex-r4k.o - -obj-$(CONFIG_CPU_R4300) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5432) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R10000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += tlb-glue-sb1.o -obj-$(CONFIG_CPU_MIPS64) += tlb-glue-r4k.o - -# -# Debug TLB exception handler, currently unused -# -#obj-y += tlb-dbg-r4k.o - -AFLAGS_tlb-glue-r4k.o := -P - -EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mm-64/tlb-dbg-r4k.c b/arch/mips/mm-64/tlb-dbg-r4k.c deleted file mode 100644 index 44e64f7ca420..000000000000 --- a/arch/mips/mm-64/tlb-dbg-r4k.c +++ /dev/null @@ -1,71 +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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * TLB debugging routines. These perform horribly slow but can easily be - * modified for debugging purposes. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, - unsigned long address); - -asmlinkage void tlb_refill_debug(struct pt_regs regs) -{ - show_regs(®s); - panic("%s called. This Does Not Happen (TM).", __FUNCTION__); -} - -asmlinkage void xtlb_refill_debug(struct pt_regs *regs) -{ - unsigned long addr; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1); - pgd = pgd_offset(current->active_mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - - write_c0_entrylo0(pte_val(pte[0]) >> 6); - write_c0_entrylo1(pte_val(pte[1]) >> 6); - __asm__ __volatile__("nop;nop;nop"); - - tlb_write_random(); -} - -asmlinkage void xtlb_mod_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} - -asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 0, addr); -} - -asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} diff --git a/arch/mips/mm-64/tlb-glue-r4k.S b/arch/mips/mm-64/tlb-glue-r4k.S deleted file mode 100644 index 4e0194aa58f1..000000000000 --- a/arch/mips/mm-64/tlb-glue-r4k.S +++ /dev/null @@ -1,41 +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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 - tlb_handler xtlb_tlbl kmode 0 - tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm-64/tlb-glue-sb1.S b/arch/mips/mm-64/tlb-glue-sb1.S deleted file mode 100644 index 3c236539f423..000000000000 --- a/arch/mips/mm-64/tlb-glue-sb1.S +++ /dev/null @@ -1,66 +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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - .macro tlb_handler_m3 name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, PAGE_SHIFT + 1 - bnez k0, 1f - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault -1: - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 -#if BCM1250_M3_WAR - tlb_handler_m3 xtlb_tlbl kmode 0 -#else - tlb_handler xtlb_tlbl kmode 0 -#endif - tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm-64/tlbex-r4k.S b/arch/mips/mm-64/tlbex-r4k.S deleted file mode 100644 index 728d18f004d2..000000000000 --- a/arch/mips/mm-64/tlbex-r4k.S +++ /dev/null @@ -1,203 +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 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * Copyright (C) 2002 Maciej W. Rozycki - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define _VMALLOC_START 0xc000000000000000 - - /* - * After this macro runs we have a pointer to the pte of the address - * that caused the fault in PTR. - */ - .macro LOAD_PTE2, ptr, tmp, kaddr -#ifdef CONFIG_SMP - dmfc0 \ptr, CP0_CONTEXT - dmfc0 \tmp, CP0_BADVADDR - dsra \ptr, 23 # get pgd_current[cpu] -#else - dmfc0 \tmp, CP0_BADVADDR - dla \ptr, pgd_current -#endif - bltz \tmp, \kaddr - ld \ptr, (\ptr) - dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((_PTRS_PER_PGD - 1)<<3) - daddu \ptr, \tmp # add in pgd offset - dmfc0 \tmp, CP0_BADVADDR - ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((_PTRS_PER_PMD - 1)<<3) - daddu \ptr, \tmp # add in pmd offset - dmfc0 \tmp, CP0_XCONTEXT - ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset - daddu \ptr, \tmp - .endm - - - /* - * Ditto for the kernel table. - */ - .macro LOAD_KPTE2, ptr, tmp, not_vmalloc - /* - * First, determine that the address is in/above vmalloc range. - */ - dmfc0 \tmp, CP0_BADVADDR - dli \ptr, _VMALLOC_START - - /* - * Now find offset into kptbl. - */ - dsubu \tmp, \tmp, \ptr - dla \ptr, kptbl - dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 - dsll \tmp, 4 # byte offset of pte - daddu \ptr, \ptr, \tmp - - /* - * Determine that fault address is within vmalloc range. - */ - dla \tmp, ekptbl - slt \tmp, \ptr, \tmp - beqz \tmp, \not_vmalloc # not vmalloc - nop - .endm - - - /* - * This places the even/odd pte pair in the page table at the pte - * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. - */ - .macro PTE_RELOAD, pte0, pte1 - dsrl \pte0, 6 # convert to entrylo0 - dmtc0 \pte0, CP0_ENTRYLO0 # load it - dsrl \pte1, 6 # convert to entrylo1 - dmtc0 \pte1, CP0_ENTRYLO1 # load it - .endm - - - .text - .set noreorder - .set mips3 - - __INIT - - /* - * TLB refill handlers for the R4000 and SB1. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r4k) - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop -END(except_vec1_r4k) - -LEAF(except_vec1_sb1) -#if BCM1250_M3_WAR - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, _PAGE_SHIFT+1 - bnez k0, 1f -#endif - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop - -1: eret - nop -END(except_vec1_sb1) - - __FINIT - - .align 5 -LEAF(handle_vec1_r4k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret -END(handle_vec1_r4k) - - - __INIT - - /* - * TLB refill handler for the R10000. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r10k) - .set noat - dla k0, handle_vec1_r10k - jr k0 - nop -END(except_vec1_r10k) - - __FINIT - - .align 5 -LEAF(handle_vec1_r10k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret -END(handle_vec1_r10k) - - - .align 5 -LEAF(invalid_vmalloc_address) - .set noat - SAVE_ALL - CLI - dmfc0 t0, CP0_BADVADDR - sd t0, PT_BVADDR(sp) - move a0, sp - jal show_regs - PANIC("Invalid kernel address") -END(invalid_vmalloc_address) diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 2fdae0a8739f..04c393f26228 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -12,19 +12,54 @@ obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o -obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o +obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_SB1) += c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \ tlb-sb1.o -obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o +# +# TLB exception handling code differs between 32-bit and 64-bit kernels. +# +ifdef CONFIG_MIPS32 +obj-$(CONFIG_CPU_R3000) += tlbex32-r3k.o +obj-$(CONFIG_CPU_TX49XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4300) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlbex32-r4k.o +obj-$(CONFIG_CPU_VR41XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5432) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R10000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS32) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlbex32-r4k.o +obj-$(CONFIG_CPU_SB1) += tlbex32-r4k.o +obj-$(CONFIG_CPU_TX39XX) += tlbex32-r3k.o +endif +ifdef CONFIG_MIPS64 +obj-$(CONFIG_CPU_R4300) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5432) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R10000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_SB1) += tlb64-glue-sb1.o tlbex64-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlb64-glue-r4k.o tlbex64-r4k.o +endif + + obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c new file mode 100644 index 000000000000..daac80ea3c0a --- /dev/null +++ b/arch/mips/mm/tlb-r8k.c @@ -0,0 +1,253 @@ +/* + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern void except_vec0_generic(void); +extern void except_vec1_r8k(void); + +#define TFP_TLB_SIZE 384 +#define TFP_TLB_SET_SHIFT 7 + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi(); + write_c0_entrylo(0); + + for (entry = 0; entry < TFP_TLB_SIZE; entry++) { + write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT); + write_c0_vaddr(entry << PAGE_SHIFT); + write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); + mtc0_tlbw_hazard(); + tlb_write(); + } + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) + drop_mmu_context(mm,cpu); +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid, size; + + if (!cpu_context(cpu, mm)) + return; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + + if (size > TFP_TLB_SIZE / 2) { + drop_mmu_context(mm, cpu); + goto out_restore; + } + + oldpid = read_c0_entryhi(); + newpid = cpu_asid(cpu, mm); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + write_c0_entryhi(oldpid); + +out_restore: + local_irq_restore(flags); +} + +/* Usable for KV1 addresses only! */ +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + if (size > TFP_TLB_SIZE / 2) { + local_flush_tlb_all(); + return; + } + + local_irq_save(flags); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid; + signed long idx; + + if (!cpu_context(cpu, vma->vm_mm)) + return; + + newpid = cpu_asid(cpu, vma->vm_mm); + page &= PAGE_MASK; + local_irq_save(flags); + oldpid = read_c0_entryhi(); + write_c0_vaddr(page); + write_c0_entryhi(newpid); + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + goto finish; + + write_c0_entrylo(0); + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + +finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + +/* + * We will need multiple versions of update_mmu_cache(), one that just + * updates the TLB with the new pte(s), and another which also checks + * for the R4k "end of page" hardware bug and does the needy. + */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + address &= PAGE_MASK; + write_c0_vaddr(address); + write_c0_entryhi(pid); + pgdp = pgd_offset(vma->vm_mm, address); + pmdp = pmd_offset(pgdp, address); + ptep = pte_offset_map(pmdp, address); + tlb_probe(); + + write_c0_entrylo(pte_val(*ptep++) >> 6); + tlb_write(); + + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +static void __init probe_tlb(unsigned long config) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ +} + +void __init tlb_init(void) +{ + unsigned int config = read_c0_config(); + unsigned long status; + + probe_tlb(config); + + status = read_c0_status(); + status &= ~(ST0_UPS | ST0_KPS); +#ifdef CONFIG_PAGE_SIZE_4KB + status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36); +#elif defined(CONFIG_PAGE_SIZE_8KB) + status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36); +#elif defined(CONFIG_PAGE_SIZE_16KB) + status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36); +#elif defined(CONFIG_PAGE_SIZE_64KB) + status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36); +#endif + write_c0_status(status); + + write_c0_wired(0); + + local_flush_tlb_all(); + + memcpy((void *)(CKSEG0 + 0x00), &except_vec0_generic, 0x80); + memcpy((void *)(CKSEG0 + 0x80), except_vec1_r8k, 0x80); + flush_icache_range(CKSEG0 + 0x80, CKSEG0 + 0x100); +} diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c index e2096dc21ac0..33c177e65908 100644 --- a/arch/mips/mm/tlb-sb1.c +++ b/arch/mips/mm/tlb-sb1.c @@ -125,7 +125,7 @@ void local_flush_tlb_all(void) * with the firmware, go back and give all the entries invalid addresses with * the normal flush routine. Wired entries will be killed as well! */ -void sb1_sanitize_tlb(void) +static void __init sb1_sanitize_tlb(void) { int entry; long addr = 0; diff --git a/arch/mips/mm/tlb64-glue-r4k.S b/arch/mips/mm/tlb64-glue-r4k.S new file mode 100644 index 000000000000..4e0194aa58f1 --- /dev/null +++ b/arch/mips/mm/tlb64-glue-r4k.S @@ -0,0 +1,41 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm/tlb64-glue-sb1.S b/arch/mips/mm/tlb64-glue-sb1.S new file mode 100644 index 000000000000..3c236539f423 --- /dev/null +++ b/arch/mips/mm/tlb64-glue-sb1.S @@ -0,0 +1,66 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm/tlbex-r3k.S b/arch/mips/mm/tlbex-r3k.S deleted file mode 100644 index cc4a4642e28c..000000000000 --- a/arch/mips/mm/tlbex-r3k.S +++ /dev/null @@ -1,224 +0,0 @@ -/* - * TLB exception handling code for R2000/R3000. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-CPU abstraction reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Further modifications to make this work: - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov - * Copyright (c) 2001 Ralf Baechle - * Copyright (c) 2001 MIPS Technologies, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - - .text - .set mips1 - .set noreorder - - __INIT - - /* TLB refill, R[23]00 version */ - LEAF(except_vec0_r2300) - .set noat - .set mips1 - mfc0 k0, CP0_BADVADDR - lw k1, pgd_current # get pgd pointer - srl k0, k0, 22 - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - and k0, k0, 0xffc - addu k1, k1, k0 - lw k0, (k1) - nop - mtc0 k0, CP0_ENTRYLO0 - mfc0 k1, CP0_EPC - tlbwr - jr k1 - rfe - END(except_vec0_r2300) - - __FINIT - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ -#define LOAD_PTE(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, pgd_current; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_CONTEXT; \ - lw ptr, (ptr); \ - andi pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); \ - nop; - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr) \ - lw ptr, (ptr) ; \ - nop ; \ - mtc0 ptr, CP0_ENTRYLO0; \ - nop; - -#define DO_FAULT(write) \ - .set noat; \ - .set macro; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; \ - .set nomacro; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - -/* - * The index register may have the probe fail bit set, - * because we would trap on access kseg2, i.e. without refill. - */ -#define TLB_WRITE(reg) \ - mfc0 reg, CP0_INDEX; \ - nop; \ - bltz reg, 1f; \ - nop; \ - tlbwi; \ - j 2f; \ - nop; \ -1: tlbwr; \ -2: - -#define RET(reg) \ - mfc0 reg, CP0_EPC; \ - nop; \ - jr reg; \ - rfe - - .set noreorder - - .align 5 -NESTED(handle_tlbl, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbl: -#endif - - DO_FAULT(0) -END(handle_tlbl) - -NESTED(handle_tlbs, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbs: -#endif - - DO_FAULT(1) -END(handle_tlbs) - - .align 5 -NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - .set push - .set reorder - lw k0, (k1) - .set pop - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1) - tlbwi - RET(k0) -#endif - -nowrite_mod: - DO_FAULT(1) -END(handle_mod) diff --git a/arch/mips/mm/tlbex32-r3k.S b/arch/mips/mm/tlbex32-r3k.S new file mode 100644 index 000000000000..cc4a4642e28c --- /dev/null +++ b/arch/mips/mm/tlbex32-r3k.S @@ -0,0 +1,224 @@ +/* + * TLB exception handling code for R2000/R3000. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-CPU abstraction reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Further modifications to make this work: + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov + * Copyright (c) 2001 Ralf Baechle + * Copyright (c) 2001 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + + .text + .set mips1 + .set noreorder + + __INIT + + /* TLB refill, R[23]00 version */ + LEAF(except_vec0_r2300) + .set noat + .set mips1 + mfc0 k0, CP0_BADVADDR + lw k1, pgd_current # get pgd pointer + srl k0, k0, 22 + sll k0, k0, 2 + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + and k0, k0, 0xffc + addu k1, k1, k0 + lw k0, (k1) + nop + mtc0 k0, CP0_ENTRYLO0 + mfc0 k1, CP0_EPC + tlbwr + jr k1 + rfe + END(except_vec0_r2300) + + __FINIT + + /* ABUSE of CPP macros 101. */ + + /* After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ +#define LOAD_PTE(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, pgd_current; \ + srl pte, pte, 22; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_CONTEXT; \ + lw ptr, (ptr); \ + andi pte, pte, 0xffc; \ + addu ptr, ptr, pte; \ + lw pte, (ptr); \ + nop; + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr) \ + lw ptr, (ptr) ; \ + nop ; \ + mtc0 ptr, CP0_ENTRYLO0; \ + nop; + +#define DO_FAULT(write) \ + .set noat; \ + .set macro; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; \ + .set nomacro; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + sw pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + sw pte, (ptr); + +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +#define TLB_WRITE(reg) \ + mfc0 reg, CP0_INDEX; \ + nop; \ + bltz reg, 1f; \ + nop; \ + tlbwi; \ + j 2f; \ + nop; \ +1: tlbwr; \ +2: + +#define RET(reg) \ + mfc0 reg, CP0_EPC; \ + nop; \ + jr reg; \ + rfe + + .set noreorder + + .align 5 +NESTED(handle_tlbl, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbl: +#endif + + DO_FAULT(0) +END(handle_tlbl) + +NESTED(handle_tlbs, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbs: +#endif + + DO_FAULT(1) +END(handle_tlbs) + + .align 5 +NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + .set push + .set reorder + lw k0, (k1) + .set pop + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1) + tlbwi + RET(k0) +#endif + +nowrite_mod: + DO_FAULT(1) +END(handle_mod) diff --git a/arch/mips/mm/tlbex32-r4k.S b/arch/mips/mm/tlbex32-r4k.S new file mode 100644 index 000000000000..49742718da0a --- /dev/null +++ b/arch/mips/mm/tlbex32-r4k.S @@ -0,0 +1,524 @@ +/* + * TLB exception handling code for r4k. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTE_L ld +#define PTE_S sd +#define PTE_SRL dsrl +#define P_MTC0 dmtc0 +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#else +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#endif + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#elif CONFIG_CPU_VR41XX +#define GET_PTE_OFF(reg) srl reg, reg, 3 +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + mtc0_tlbw_hazard + tlbwr # write random tlb entry + tlbw_eret_hazard + eret # return from trap + END(except_vec0_r4000) + + /* TLB refill, EXL == 0, R4600 version */ + LEAF(except_vec0_r4600) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 k1, CP0_ENTRYLO1 + nop + tlbwr + nop + eret + END(except_vec0_r4600) + + /* TLB refill, EXL == 0, R52x0 "Nevada" version */ + /* + * This version has a bug workaround for the Nevada. It seems + * as if under certain circumstances the move from cp0_context + * might produce a bogus result when the mfc0 instruction and + * it's consumer are in a different cacheline or a load instruction, + * probably any memory reference, is between them. This is + * potencially slower than the R4000 version, so we use this + * special version. + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + lw k1, pgd_current # get pgd pointer + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 # add in pgd offset + lw k1, (k1) + mfc0 k0, CP0_CONTEXT # get context reg + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + nop # QED specified nops + nop + tlbwr # write random tlb entry + nop # traditional nop + eret # return from trap + END(except_vec0_nevada) + + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ + LEAF(except_vec0_r45k_bvahwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r45k_bvahwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ + LEAF(except_vec0_r4k_mphwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_mphwbug) +#endif + + /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ + LEAF(except_vec0_r4k_250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + b 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_250MHZhwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ + LEAF(except_vec0_r4k_MP250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + mfc0 k0, CP0_INDEX + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_MP250MHZhwbug) +#endif + + __FINIT + + .set noreorder + +/* + * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: + * 2. A timing hazard exists for the TLBP instruction. + * + * stalling_instruction + * TLBP + * + * The JTLB is being read for the TLBP throughout the stall generated by the + * previous instruction. This is not really correct as the stalling instruction + * can modify the address used to access the JTLB. The failure symptom is that + * the TLBP instruction will use an address created for the stalling instruction + * and not the address held in C0_ENHI and thus report the wrong results. + * + * The software work-around is to not allow the instruction preceding the TLBP + * to stall - make it an NOP or some other instruction guaranteed not to stall. + * + * Errata 2 will not be fixed. This errata is also on the R5000. + * + * As if we MIPS hackers wouldn't know how to nop pipelines happy ... + */ +#define R5K_HAZARD nop + + /* + * Note for many R4k variants tlb probes cannot be executed out + * of the instruction cache else you get bogus results. + */ + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif +invalid_tlbl: +#ifdef TLB_OPTIMIZE + .set mips3 + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) diff --git a/arch/mips/mm/tlbex64-r4k.S b/arch/mips/mm/tlbex64-r4k.S new file mode 100644 index 000000000000..728d18f004d2 --- /dev/null +++ b/arch/mips/mm/tlbex64-r4k.S @@ -0,0 +1,203 @@ +/* + * 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 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define _VMALLOC_START 0xc000000000000000 + + /* + * After this macro runs we have a pointer to the pte of the address + * that caused the fault in PTR. + */ + .macro LOAD_PTE2, ptr, tmp, kaddr +#ifdef CONFIG_SMP + dmfc0 \ptr, CP0_CONTEXT + dmfc0 \tmp, CP0_BADVADDR + dsra \ptr, 23 # get pgd_current[cpu] +#else + dmfc0 \tmp, CP0_BADVADDR + dla \ptr, pgd_current +#endif + bltz \tmp, \kaddr + ld \ptr, (\ptr) + dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes + andi \tmp, ((_PTRS_PER_PGD - 1)<<3) + daddu \ptr, \tmp # add in pgd offset + dmfc0 \tmp, CP0_BADVADDR + ld \ptr, (\ptr) # get pmd pointer + dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes + andi \tmp, ((_PTRS_PER_PMD - 1)<<3) + daddu \ptr, \tmp # add in pmd offset + dmfc0 \tmp, CP0_XCONTEXT + ld \ptr, (\ptr) # get pte pointer + andi \tmp, 0xff0 # get pte offset + daddu \ptr, \tmp + .endm + + + /* + * Ditto for the kernel table. + */ + .macro LOAD_KPTE2, ptr, tmp, not_vmalloc + /* + * First, determine that the address is in/above vmalloc range. + */ + dmfc0 \tmp, CP0_BADVADDR + dli \ptr, _VMALLOC_START + + /* + * Now find offset into kptbl. + */ + dsubu \tmp, \tmp, \ptr + dla \ptr, kptbl + dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 + dsll \tmp, 4 # byte offset of pte + daddu \ptr, \ptr, \tmp + + /* + * Determine that fault address is within vmalloc range. + */ + dla \tmp, ekptbl + slt \tmp, \ptr, \tmp + beqz \tmp, \not_vmalloc # not vmalloc + nop + .endm + + + /* + * This places the even/odd pte pair in the page table at the pte + * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. + */ + .macro PTE_RELOAD, pte0, pte1 + dsrl \pte0, 6 # convert to entrylo0 + dmtc0 \pte0, CP0_ENTRYLO0 # load it + dsrl \pte1, 6 # convert to entrylo1 + dmtc0 \pte1, CP0_ENTRYLO1 # load it + .endm + + + .text + .set noreorder + .set mips3 + + __INIT + + /* + * TLB refill handlers for the R4000 and SB1. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r4k) + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop +END(except_vec1_r4k) + +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, _PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + + __FINIT + + .align 5 +LEAF(handle_vec1_r4k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret +END(handle_vec1_r4k) + + + __INIT + + /* + * TLB refill handler for the R10000. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r10k) + .set noat + dla k0, handle_vec1_r10k + jr k0 + nop +END(except_vec1_r10k) + + __FINIT + + .align 5 +LEAF(handle_vec1_r10k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret +END(handle_vec1_r10k) + + + .align 5 +LEAF(invalid_vmalloc_address) + .set noat + SAVE_ALL + CLI + dmfc0 t0, CP0_BADVADDR + sd t0, PT_BVADDR(sp) + move a0, sp + jal show_regs + PANIC("Invalid kernel address") +END(invalid_vmalloc_address) diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c index 10acbe9b0cb6..0ec82a10df5c 100644 --- a/arch/mips/momentum/jaguar_atx/prom.c +++ b/arch/mips/momentum/jaguar_atx/prom.c @@ -245,20 +245,6 @@ void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. - * Hence, this can be hardcoded for now. - */ - return num_cpus; -} - int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) { /* Clear the semaphore */ diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 7c2f25ffc6df..261250737528 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 6efdd145e7d7..91240777f978 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile @@ -2,7 +2,7 @@ # Makefile for Momentum Computer's Ocelot-C and -CS boards. # -obj-y += cpci-irq.o uart-irq.o int-handler.o irq.o pci-irq.o \ - prom.o reset.o setup.o +obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ + setup.o uart-irq.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index 37ad81291d82..13dd8bd74041 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c @@ -44,8 +44,9 @@ #include #include #include -#include +#include #include +#include #include extern asmlinkage void ocelot_handle_int(void); diff --git a/arch/mips/momentum/ocelot_c/pci-irq.c b/arch/mips/momentum/ocelot_c/pci-irq.c deleted file mode 100644 index c14b6d99577e..000000000000 --- a/arch/mips/momentum/ocelot_c/pci-irq.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for mv64340 controller. - * - * 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. - */ -#include -#include -#include -#include -#include - - -void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 0)) { - /* LSI 53C10101R SCSI (A) */ - devices->irq = 2; - } else if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 1)) { - /* LSI 53C10101R SCSI (B) */ - devices->irq = 2; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 1)) { - /* Intel 21555 bridge */ - devices->irq = 12; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 2)) { - /* PMC Slot */ - devices->irq = 4; - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); - - /* enable master for everything but the MV-64340 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read_word(devices, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write_word(devices, PCI_COMMAND, cmd); - } - } -} diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 0387b562b6a8..a01bedb4485c 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -147,13 +147,14 @@ char *arg64(unsigned long addrin, int arg_index) #endif /* CONFIG_MIPS64 */ -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; int i; + #ifdef CONFIG_MIPS64 char *ptr; diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 1079858bff79..1bd2ba659bfd 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -193,7 +193,7 @@ int m48t37y_set_time(unsigned long sec) rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN2BCD(tm.tm_wday + 1); + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); /* disable writing */ rtc_base[0x7ff8] = 0x00; diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile index bdd8d3292d7b..e5f1cb086973 100644 --- a/arch/mips/momentum/ocelot_g/Makefile +++ b/arch/mips/momentum/ocelot_g/Makefile @@ -2,8 +2,7 @@ # Makefile for Momentum Computer's Ocelot-G board. # -obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o \ - reset.o setup.o +obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o obj-$(CONFIG_KGDB) += dbg_io.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c index 3afe3273921c..4ec4aefd6952 100644 --- a/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/arch/mips/momentum/ocelot_g/gt-irq.c @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include "gt64240.h" unsigned long bus_clock; @@ -108,25 +108,25 @@ int disable_galileo_irq(int int_cause, int bit_num) * we keep this particular structure in the function. */ -static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs) { uint32_t irq_src, irq_src_mask; int handled; /* get the low interrupt cause register */ - GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src); + irq_src = GT_READ(LOW_INTERRUPT_CAUSE_REGISTER); /* get the mask register for this pin */ - GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask); + irq_src_mask = GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW); /* mask off only the interrupts we're interested in */ irq_src = irq_src & irq_src_mask; - handled = 0; + handled = IRQ_NONE; /* Check for timer interrupt */ if (irq_src & 0x00000100) { - handled = 1; + handled = IRQ_HANDLED; irq_src &= ~0x00000100; /* Clear any pending cause bits */ @@ -141,90 +141,8 @@ static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n", irq_src); } -} - -/* - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be built in ethernet ports etc... - */ -static void gt64240_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - -#if 0 - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); -#endif - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } -#if 0 - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); -#endif -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - * Future I2O support. We currently attach I2O interrupt handlers to - * the Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - * This normally would be outside of the ifdef, but since we're - * handling I2O outside of this handler, this printk shows up every - * time we get a valid I2O interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif + return handled; } /* diff --git a/arch/mips/momentum/ocelot_g/gt64240.h b/arch/mips/momentum/ocelot_g/gt64240.h deleted file mode 100644 index c6cfc0b06e26..000000000000 --- a/arch/mips/momentum/ocelot_g/gt64240.h +++ /dev/null @@ -1,1238 +0,0 @@ -/* gt64240r.h - GT-64240 Internal registers definition file */ - -/* Copyright - Galileo technology. */ - -#ifndef __INCgt64240rh -#define __INCgt64240rh - -#define GTREG(v) (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \ - (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00) - -#if 0 -#define GTREG_SHORT(X) (((X) << 8) | ((X) >> 8)) - -#define LONG_GTREG(X) ((l64) \ - (((X)&0x00000000000000ffULL) << 56) | \ - (((X)&0x000000000000ff00ULL) << 40) | \ - (((X)&0x0000000000ff0000ULL) << 24) | \ - (((X)&0x00000000ff000000ULL) << 8) | \ - (((X)&0x000000ff00000000ULL) >> 8) | \ - (((X)&0x0000ff0000000000ULL) >> 24) | \ - (((X)&0x00ff000000000000ULL) >> 40) | \ - (((X)&0xff00000000000000ULL) >> 56)) -#endif - -#include "gt64240_dep.h" - -/****************************************/ -/* CPU Control Registers */ -/****************************************/ - -#define CPU_CONFIGURATION 0x000 -#define CPU_MODE 0x120 -#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 -#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 - -/****************************************/ -/* Processor Address Space */ -/****************************************/ - -/* Sdram's BAR'S */ -#define SCS_0_LOW_DECODE_ADDRESS 0x008 -#define SCS_0_HIGH_DECODE_ADDRESS 0x010 -#define SCS_1_LOW_DECODE_ADDRESS 0x208 -#define SCS_1_HIGH_DECODE_ADDRESS 0x210 -#define SCS_2_LOW_DECODE_ADDRESS 0x018 -#define SCS_2_HIGH_DECODE_ADDRESS 0x020 -#define SCS_3_LOW_DECODE_ADDRESS 0x218 -#define SCS_3_HIGH_DECODE_ADDRESS 0x220 -/* Devices BAR'S */ -#define CS_0_LOW_DECODE_ADDRESS 0x028 -#define CS_0_HIGH_DECODE_ADDRESS 0x030 -#define CS_1_LOW_DECODE_ADDRESS 0x228 -#define CS_1_HIGH_DECODE_ADDRESS 0x230 -#define CS_2_LOW_DECODE_ADDRESS 0x248 -#define CS_2_HIGH_DECODE_ADDRESS 0x250 -#define CS_3_LOW_DECODE_ADDRESS 0x038 -#define CS_3_HIGH_DECODE_ADDRESS 0x040 -#define BOOTCS_LOW_DECODE_ADDRESS 0x238 -#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 - -#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 -#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 -#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 -#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 -#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 -#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 -#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 -#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 -#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 -#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 - -#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 -#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 -#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 -#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 -#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 -#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 -#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 -#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 -#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 -#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 - -#define INTERNAL_SPACE_DECODE 0x068 - -#define CPU_0_LOW_DECODE_ADDRESS 0x290 -#define CPU_0_HIGH_DECODE_ADDRESS 0x298 -#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 -#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 - -#define PCI_0I_O_ADDRESS_REMAP 0x0f0 -#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 -#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 -#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 -#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 -#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 -#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 -#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 -#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 - -#define PCI_1I_O_ADDRESS_REMAP 0x108 -#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 -#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 -#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 -#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 -#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 -#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 -#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 -#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 - -/****************************************/ -/* CPU Sync Barrier */ -/****************************************/ - -#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 -#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 - - -/****************************************/ -/* CPU Access Protect */ -/****************************************/ - -#define CPU_LOW_PROTECT_ADDRESS_0 0X180 -#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 -#define CPU_LOW_PROTECT_ADDRESS_1 0X190 -#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 -#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 -#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 -#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 -#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 -#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 -#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 -#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 -#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 -#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 -#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 -#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 -#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 - - -/****************************************/ -/* Snoop Control */ -/****************************************/ - -#define SNOOP_BASE_ADDRESS_0 0x380 -#define SNOOP_TOP_ADDRESS_0 0x388 -#define SNOOP_BASE_ADDRESS_1 0x390 -#define SNOOP_TOP_ADDRESS_1 0x398 -#define SNOOP_BASE_ADDRESS_2 0x3a0 -#define SNOOP_TOP_ADDRESS_2 0x3a8 -#define SNOOP_BASE_ADDRESS_3 0x3b0 -#define SNOOP_TOP_ADDRESS_3 0x3b8 - -/****************************************/ -/* CPU Error Report */ -/****************************************/ - -#define CPU_ERROR_ADDRESS_LOW 0x070 -#define CPU_ERROR_ADDRESS_HIGH 0x078 -#define CPU_ERROR_DATA_LOW 0x128 -#define CPU_ERROR_DATA_HIGH 0x130 -#define CPU_ERROR_PARITY 0x138 -#define CPU_ERROR_CAUSE 0x140 -#define CPU_ERROR_MASK 0x148 - -/****************************************/ -/* Pslave Debug */ -/****************************************/ - -#define X_0_ADDRESS 0x360 -#define X_0_COMMAND_ID 0x368 -#define X_1_ADDRESS 0x370 -#define X_1_COMMAND_ID 0x378 -#define WRITE_DATA_LOW 0x3c0 -#define WRITE_DATA_HIGH 0x3c8 -#define WRITE_BYTE_ENABLE 0X3e0 -#define READ_DATA_LOW 0x3d0 -#define READ_DATA_HIGH 0x3d8 -#define READ_ID 0x3e8 - - -/****************************************/ -/* SDRAM and Device Address Space */ -/****************************************/ - - -/****************************************/ -/* SDRAM Configuration */ -/****************************************/ - -#define SDRAM_CONFIGURATION 0x448 -#define SDRAM_OPERATION_MODE 0x474 -#define SDRAM_ADDRESS_DECODE 0x47C -#define SDRAM_TIMING_PARAMETERS 0x4b4 -#define SDRAM_UMA_CONTROL 0x4a4 -#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 -#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac -#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 - - -/****************************************/ -/* SDRAM Parameters */ -/****************************************/ - -#define SDRAM_BANK0PARAMETERS 0x44C -#define SDRAM_BANK1PARAMETERS 0x450 -#define SDRAM_BANK2PARAMETERS 0x454 -#define SDRAM_BANK3PARAMETERS 0x458 - - -/****************************************/ -/* SDRAM Error Report */ -/****************************************/ - -#define SDRAM_ERROR_DATA_LOW 0x484 -#define SDRAM_ERROR_DATA_HIGH 0x480 -#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 -#define SDRAM_RECEIVED_ECC 0x488 -#define SDRAM_CALCULATED_ECC 0x48c -#define SDRAM_ECC_CONTROL 0x494 -#define SDRAM_ECC_ERROR_COUNTER 0x498 - - -/****************************************/ -/* SDunit Debug (for internal use) */ -/****************************************/ - -#define X0_ADDRESS 0x500 -#define X0_COMMAND_AND_ID 0x504 -#define X0_WRITE_DATA_LOW 0x508 -#define X0_WRITE_DATA_HIGH 0x50c -#define X0_WRITE_BYTE_ENABLE 0x518 -#define X0_READ_DATA_LOW 0x510 -#define X0_READ_DATA_HIGH 0x514 -#define X0_READ_ID 0x51c -#define X1_ADDRESS 0x520 -#define X1_COMMAND_AND_ID 0x524 -#define X1_WRITE_DATA_LOW 0x528 -#define X1_WRITE_DATA_HIGH 0x52c -#define X1_WRITE_BYTE_ENABLE 0x538 -#define X1_READ_DATA_LOW 0x530 -#define X1_READ_DATA_HIGH 0x534 -#define X1_READ_ID 0x53c -#define X0_SNOOP_ADDRESS 0x540 -#define X0_SNOOP_COMMAND 0x544 -#define X1_SNOOP_ADDRESS 0x548 -#define X1_SNOOP_COMMAND 0x54c - - -/****************************************/ -/* Device Parameters */ -/****************************************/ - -#define DEVICE_BANK0PARAMETERS 0x45c -#define DEVICE_BANK1PARAMETERS 0x460 -#define DEVICE_BANK2PARAMETERS 0x464 -#define DEVICE_BANK3PARAMETERS 0x468 -#define DEVICE_BOOT_BANK_PARAMETERS 0x46c -#define DEVICE_CONTROL 0x4c0 -#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 -#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc -#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 - - -/****************************************/ -/* Device Interrupt */ -/****************************************/ - -#define DEVICE_INTERRUPT_CAUSE 0x4d0 -#define DEVICE_INTERRUPT_MASK 0x4d4 -#define DEVICE_ERROR_ADDRESS 0x4d8 - -/****************************************/ -/* DMA Record */ -/****************************************/ - -#define CHANNEL0_DMA_BYTE_COUNT 0x800 -#define CHANNEL1_DMA_BYTE_COUNT 0x804 -#define CHANNEL2_DMA_BYTE_COUNT 0x808 -#define CHANNEL3_DMA_BYTE_COUNT 0x80C -#define CHANNEL4_DMA_BYTE_COUNT 0x900 -#define CHANNEL5_DMA_BYTE_COUNT 0x904 -#define CHANNEL6_DMA_BYTE_COUNT 0x908 -#define CHANNEL7_DMA_BYTE_COUNT 0x90C -#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 -#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 -#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 -#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C -#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 -#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 -#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 -#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C -#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 -#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 -#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 -#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C -#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 -#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 -#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 -#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C -#define CHANNEL0NEXT_RECORD_POINTER 0x830 -#define CHANNEL1NEXT_RECORD_POINTER 0x834 -#define CHANNEL2NEXT_RECORD_POINTER 0x838 -#define CHANNEL3NEXT_RECORD_POINTER 0x83C -#define CHANNEL4NEXT_RECORD_POINTER 0x930 -#define CHANNEL5NEXT_RECORD_POINTER 0x934 -#define CHANNEL6NEXT_RECORD_POINTER 0x938 -#define CHANNEL7NEXT_RECORD_POINTER 0x93C -#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 -#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 -#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 -#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C -#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 -#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 -#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 -#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C -#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 -#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 -#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 -#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c -#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 -#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 -#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 -#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c -#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 -#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 -#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 -#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac -#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 -#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 -#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 -#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac -#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 -#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 -#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 -#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc -#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 -#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 -#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 -#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc - -/****************************************/ -/* DMA Channel Control */ -/****************************************/ - -#define CHANNEL0CONTROL 0x840 -#define CHANNEL0CONTROL_HIGH 0x880 - -#define CHANNEL1CONTROL 0x844 -#define CHANNEL1CONTROL_HIGH 0x884 - -#define CHANNEL2CONTROL 0x848 -#define CHANNEL2CONTROL_HIGH 0x888 - -#define CHANNEL3CONTROL 0x84C -#define CHANNEL3CONTROL_HIGH 0x88C - -#define CHANNEL4CONTROL 0x940 -#define CHANNEL4CONTROL_HIGH 0x980 - -#define CHANNEL5CONTROL 0x944 -#define CHANNEL5CONTROL_HIGH 0x984 - -#define CHANNEL6CONTROL 0x948 -#define CHANNEL6CONTROL_HIGH 0x988 - -#define CHANNEL7CONTROL 0x94C -#define CHANNEL7CONTROL_HIGH 0x98C - - -/****************************************/ -/* DMA Arbiter */ -/****************************************/ - -#define ARBITER_CONTROL_0_3 0x860 -#define ARBITER_CONTROL_4_7 0x960 - - -/****************************************/ -/* DMA Interrupt */ -/****************************************/ - -#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 -#define CHANELS0_3_INTERRUPT_MASK 0x8c4 -#define CHANELS0_3_ERROR_ADDRESS 0x8c8 -#define CHANELS0_3_ERROR_SELECT 0x8cc -#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 -#define CHANELS4_7_INTERRUPT_MASK 0x9c4 -#define CHANELS4_7_ERROR_ADDRESS 0x9c8 -#define CHANELS4_7_ERROR_SELECT 0x9cc - - -/****************************************/ -/* DMA Debug (for internal use) */ -/****************************************/ - -#define DMA_X0_ADDRESS 0x8e0 -#define DMA_X0_COMMAND_AND_ID 0x8e4 -#define DMA_X0_WRITE_DATA_LOW 0x8e8 -#define DMA_X0_WRITE_DATA_HIGH 0x8ec -#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 -#define DMA_X0_READ_DATA_LOW 0x8f0 -#define DMA_X0_READ_DATA_HIGH 0x8f4 -#define DMA_X0_READ_ID 0x8fc -#define DMA_X1_ADDRESS 0x9e0 -#define DMA_X1_COMMAND_AND_ID 0x9e4 -#define DMA_X1_WRITE_DATA_LOW 0x9e8 -#define DMA_X1_WRITE_DATA_HIGH 0x9ec -#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 -#define DMA_X1_READ_DATA_LOW 0x9f0 -#define DMA_X1_READ_DATA_HIGH 0x9f4 -#define DMA_X1_READ_ID 0x9fc - -/****************************************/ -/* Timer_Counter */ -/****************************************/ - -#define TIMER_COUNTER0 0x850 -#define TIMER_COUNTER1 0x854 -#define TIMER_COUNTER2 0x858 -#define TIMER_COUNTER3 0x85C -#define TIMER_COUNTER_0_3_CONTROL 0x864 -#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 -#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c -#define TIMER_COUNTER4 0x950 -#define TIMER_COUNTER5 0x954 -#define TIMER_COUNTER6 0x958 -#define TIMER_COUNTER7 0x95C -#define TIMER_COUNTER_4_7_CONTROL 0x964 -#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 -#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c - -/****************************************/ -/* PCI Slave Address Decoding */ -/****************************************/ - -#define PCI_0SCS_0_BANK_SIZE 0xc08 -#define PCI_1SCS_0_BANK_SIZE 0xc88 -#define PCI_0SCS_1_BANK_SIZE 0xd08 -#define PCI_1SCS_1_BANK_SIZE 0xd88 -#define PCI_0SCS_2_BANK_SIZE 0xc0c -#define PCI_1SCS_2_BANK_SIZE 0xc8c -#define PCI_0SCS_3_BANK_SIZE 0xd0c -#define PCI_1SCS_3_BANK_SIZE 0xd8c -#define PCI_0CS_0_BANK_SIZE 0xc10 -#define PCI_1CS_0_BANK_SIZE 0xc90 -#define PCI_0CS_1_BANK_SIZE 0xd10 -#define PCI_1CS_1_BANK_SIZE 0xd90 -#define PCI_0CS_2_BANK_SIZE 0xd18 -#define PCI_1CS_2_BANK_SIZE 0xd98 -#define PCI_0CS_3_BANK_SIZE 0xc14 -#define PCI_1CS_3_BANK_SIZE 0xc94 -#define PCI_0CS_BOOT_BANK_SIZE 0xd14 -#define PCI_1CS_BOOT_BANK_SIZE 0xd94 -#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c -#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c -#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 -#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 -#define PCI_0P2P_I_O_BAR_SIZE 0xd24 -#define PCI_1P2P_I_O_BAR_SIZE 0xda4 -#define PCI_0CPU_BAR_SIZE 0xd28 -#define PCI_1CPU_BAR_SIZE 0xda8 -#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 -#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 -#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 -#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 -#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 -#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 -#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c -#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c -#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 -#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 -#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 -#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 -#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 -#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 -#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c -#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c -#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 -#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 -#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 -#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 -#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 -#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 -#define PCI_0DAC_CPU_BAR_SIZE 0xe2c -#define PCI_1DAC_CPU_BAR_SIZE 0xeac -#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c -#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac -#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c -#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc -#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 -#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 -#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 -#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 -#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c -#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc -#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c -#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc -#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 -#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 -#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 -#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 -#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 -#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 -#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 -#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 -#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 -#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 -#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c -#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec -#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 -#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 -#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 -#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 -#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 -#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 -#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 -#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 -#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c -#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c -#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 -#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 -#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 -#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 -#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 -#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 -#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c -#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c -#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 -#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 -#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 -#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 -#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 -#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 -#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c -#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc - -/****************************************/ -/* PCI Control */ -/****************************************/ - -#define PCI_0COMMAND 0xc00 -#define PCI_1COMMAND 0xc80 -#define PCI_0MODE 0xd00 -#define PCI_1MODE 0xd80 -#define PCI_0TIMEOUT_RETRY 0xc04 -#define PCI_1TIMEOUT_RETRY 0xc84 -#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 -#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 -#define MSI_0TRIGGER_TIMER 0xc38 -#define MSI_1TRIGGER_TIMER 0xcb8 -#define PCI_0ARBITER_CONTROL 0x1d00 -#define PCI_1ARBITER_CONTROL 0x1d80 -/* changing untill here */ -#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 -#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c -#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c -#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 -#define PCI_0P2P_CONFIGURATION 0x1d14 -#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 -#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 -#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 -#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 -#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 -#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 -#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 -#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 -#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 -#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 -#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 -#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 -#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 -#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 -#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 -#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 -#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 -#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 -#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 -#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 -#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 -#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 -#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 -#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 -#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 -#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c -#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c -#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 -#define PCI_1P2P_CONFIGURATION 0x1d94 -#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 -#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 -#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 -#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 -#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 -#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 -#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 -#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 -#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 -#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 -#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 -#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 -#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 -#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 -#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 -#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 -#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 -#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 -#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 -#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 -#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 -#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 -#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 -#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 - -/****************************************/ -/* PCI Snoop Control */ -/****************************************/ - -#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 -#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 -#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 -#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 -#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 -#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 -#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 -#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 -#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 -#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 -#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 -#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 -#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 -#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 -#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 -#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 -#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 -#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 -#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 -#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 -#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 -#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 -#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 -#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 - -/****************************************/ -/* PCI Configuration Address */ -/****************************************/ - -#define PCI_0CONFIGURATION_ADDRESS 0xcf8 -#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc -#define PCI_1CONFIGURATION_ADDRESS 0xc78 -#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c -#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 -#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 - -/****************************************/ -/* PCI Error Report */ -/****************************************/ - -#define PCI_0SERR_MASK 0xc28 -#define PCI_0ERROR_ADDRESS_LOW 0x1d40 -#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 -#define PCI_0ERROR_DATA_LOW 0x1d48 -#define PCI_0ERROR_DATA_HIGH 0x1d4c -#define PCI_0ERROR_COMMAND 0x1d50 -#define PCI_0ERROR_CAUSE 0x1d58 -#define PCI_0ERROR_MASK 0x1d5c - -#define PCI_1SERR_MASK 0xca8 -#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 -#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 -#define PCI_1ERROR_DATA_LOW 0x1dc8 -#define PCI_1ERROR_DATA_HIGH 0x1dcc -#define PCI_1ERROR_COMMAND 0x1dd0 -#define PCI_1ERROR_CAUSE 0x1dd8 -#define PCI_1ERROR_MASK 0x1ddc - - -/****************************************/ -/* Lslave Debug (for internal use) */ -/****************************************/ - -#define L_SLAVE_X0_ADDRESS 0x1d20 -#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 -#define L_SLAVE_X1_ADDRESS 0x1d28 -#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c -#define L_SLAVE_WRITE_DATA_LOW 0x1d30 -#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 -#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 -#define L_SLAVE_READ_DATA_LOW 0x1d38 -#define L_SLAVE_READ_DATA_HIGH 0x1d3c -#define L_SLAVE_READ_ID 0x1d64 - -/****************************************/ -/* PCI Configuration Function 0 */ -/****************************************/ - -#define PCI_DEVICE_AND_VENDOR_ID 0x000 -#define PCI_STATUS_AND_COMMAND 0x004 -#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 -#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C -#define PCI_SCS_0_BASE_ADDRESS 0x010 -#define PCI_SCS_1_BASE_ADDRESS 0x014 -#define PCI_SCS_2_BASE_ADDRESS 0x018 -#define PCI_SCS_3_BASE_ADDRESS 0x01C -#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 -#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 -#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C -#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 -#define PCI_CAPABILTY_LIST_POINTER 0x034 -#define PCI_INTERRUPT_PIN_AND_LINE 0x03C -#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 -#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 -#define PCI_VPD_ADDRESS 0x048 -#define PCI_VPD_DATA 0X04c -#define PCI_MSI_MESSAGE_CONTROL 0x050 -#define PCI_MSI_MESSAGE_ADDRESS 0x054 -#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 -#define PCI_MSI_MESSAGE_DATA 0x05c -#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 - -/****************************************/ -/* PCI Configuration Function 1 */ -/****************************************/ - -#define PCI_CS_0_BASE_ADDRESS 0x110 -#define PCI_CS_1_BASE_ADDRESS 0x114 -#define PCI_CS_2_BASE_ADDRESS 0x118 -#define PCI_CS_3_BASE_ADDRESS 0x11c -#define PCI_BOOTCS_BASE_ADDRESS 0x120 - -/****************************************/ -/* PCI Configuration Function 2 */ -/****************************************/ - -#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 -#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 -#define PCI_P2P_I_O_BASE_ADDRESS 0x218 -#define PCI_CPU_BASE_ADDRESS 0x21c - -/****************************************/ -/* PCI Configuration Function 4 */ -/****************************************/ - -#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 -#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 -#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 -#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 - - -/****************************************/ -/* PCI Configuration Function 5 */ -/****************************************/ - -#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 -#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 -#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 -#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 - - -/****************************************/ -/* PCI Configuration Function 6 */ -/****************************************/ - -#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 -#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 -#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 -#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c -#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 -#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 - -/****************************************/ -/* PCI Configuration Function 7 */ -/****************************************/ - -#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 -#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c -#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 -#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 - -/****************************************/ -/* Interrupts */ -/****************************************/ - -#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 -#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 -#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c -#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c -#define CPU_SELECT_CAUSE_REGISTER 0xc70 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 -#define PCI_0SELECT_CAUSE 0xc74 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 -#define PCI_1SELECT_CAUSE 0xcf4 -#define CPU_INT_0_MASK 0xe60 -#define CPU_INT_1_MASK 0xe64 -#define CPU_INT_2_MASK 0xe68 -#define CPU_INT_3_MASK 0xe6c - -/****************************************/ -/* I20 Support registers */ -/****************************************/ - -#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 -#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 -#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 -#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C -#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 -#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 -#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC - -#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 -#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 -#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 -#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C -#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 -#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 -#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C - -#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 -#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 -#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 -#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C -#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 -#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 -#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC - -#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 -#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 -#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 -#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C -#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 -#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 -#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C - -/****************************************/ -/* Communication Unit Registers */ -/****************************************/ - -#define ETHERNET_0_ADDRESS_CONTROL_LOW -#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 -#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 -#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c -#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 -#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 -#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 -#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 -#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 -#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 -#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c -#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 -#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 -#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 -#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 -#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 -#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 -#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c -#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 -#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 -#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 -#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 -#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 -#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 -#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c -#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 -#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 -#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 -#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 -#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 -#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac -#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 -#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 -#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 -#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 -#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 -#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc -#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 -#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 -#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 -#define SERIAL_INIT_LAST_DATA 0xf324 -#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 -#define COMM_UNIT_ARBITER_CONTROL 0xf300 -#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 -#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 -#define COMM_UNIT_INTERRUPT_MASK 0xf314 -#define COMM_UNIT_ERROR_ADDRESS 0xf314 - -/****************************************/ -/* Cunit Debug (for internal use) */ -/****************************************/ - -#define CUNIT_ADDRESS 0xf340 -#define CUNIT_COMMAND_AND_ID 0xf344 -#define CUNIT_WRITE_DATA_LOW 0xf348 -#define CUNIT_WRITE_DATA_HIGH 0xf34c -#define CUNIT_WRITE_BYTE_ENABLE 0xf358 -#define CUNIT_READ_DATA_LOW 0xf350 -#define CUNIT_READ_DATA_HIGH 0xf354 -#define CUNIT_READ_ID 0xf35c - -/****************************************/ -/* Fast Ethernet Unit Registers */ -/****************************************/ - -/* Ethernet */ - -#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 -#define ETHERNET_SMI_REGISTER 0x2010 - -/* Ethernet 0 */ - -#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 -#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 -#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 -#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 -#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 -#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 -#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 -#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 -#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 -#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 -#define ETHERNET0_MIB_COUNTER_BASE 0x2500 - -/* Ethernet 1 */ - -#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 -#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 -#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 -#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 -#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 -#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 -#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 -#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 -#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 -#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 -#define ETHERNET1_MIB_COUNTER_BASE 0x2900 - -/* Ethernet 2 */ - -#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 -#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 -#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 -#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 -#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 -#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 -#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 -#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 -#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 -#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 -#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 - -/****************************************/ -/* SDMA Registers */ -/****************************************/ - -#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 -#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 -#define CHANNEL0_COMMAND_REGISTER 0x4008 -#define CHANNEL0_RX_CMD_STATUS 0x4800 -#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 -#define CHANNEL0_RX_BUFFER_POINTER 0x4808 -#define CHANNEL0_RX_NEXT_POINTER 0x480c -#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 -#define CHANNEL0_TX_CMD_STATUS 0x4C00 -#define CHANNEL0_TX_PACKET_SIZE 0x4C04 -#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 -#define CHANNEL0_TX_NEXT_POINTER 0x4C0c -#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 -#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 -#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 -#define CHANNEL1_COMMAND_REGISTER 0x6008 -#define CHANNEL1_RX_CMD_STATUS 0x6800 -#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 -#define CHANNEL1_RX_BUFFER_POINTER 0x6808 -#define CHANNEL1_RX_NEXT_POINTER 0x680c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_TX_CMD_STATUS 0x6C00 -#define CHANNEL1_TX_PACKET_SIZE 0x6C04 -#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 -#define CHANNEL1_TX_NEXT_POINTER 0x6C0c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 -#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 - -/* SDMA Interrupt */ - -#define SDMA_CAUSE 0xb820 -#define SDMA_MASK 0xb8a0 - - -/****************************************/ -/* Baude Rate Generators Registers */ -/****************************************/ - -/* BRG 0 */ - -#define BRG0_CONFIGURATION_REGISTER 0xb200 -#define BRG0_BAUDE_TUNING_REGISTER 0xb204 - -/* BRG 1 */ - -#define BRG1_CONFIGURATION_REGISTER 0xb208 -#define BRG1_BAUDE_TUNING_REGISTER 0xb20c - -/* BRG 2 */ - -#define BRG2_CONFIGURATION_REGISTER 0xb210 -#define BRG2_BAUDE_TUNING_REGISTER 0xb214 - -/* BRG Interrupts */ - -#define BRG_CAUSE_REGISTER 0xb834 -#define BRG_MASK_REGISTER 0xb8b4 - -/* MISC */ - -#define MAIN_ROUTING_REGISTER 0xb400 -#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 -#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 -#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c -#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 -#define WATCHDOG_VALUE_REGISTER 0xb414 - - -/****************************************/ -/* Flex TDM Registers */ -/****************************************/ - -/* FTDM Port */ - -#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 -#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 -#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 -#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c -#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 -#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 -#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 - -/* FTDM Interrupts */ - -#define FTDM_CAUSE_REGISTER 0xb830 -#define FTDM_MASK_REGISTER 0xb8b0 - - -/****************************************/ -/* GPP Interface Registers */ -/****************************************/ - -#define GPP_IO_CONTROL 0xf100 -#define GPP_LEVEL_CONTROL 0xf110 -#define GPP_VALUE 0xf104 -#define GPP_INTERRUPT_CAUSE 0xf108 -#define GPP_INTERRUPT_MASK 0xf10c - -#define MPP_CONTROL0 0xf000 -#define MPP_CONTROL1 0xf004 -#define MPP_CONTROL2 0xf008 -#define MPP_CONTROL3 0xf00c -#define DEBUG_PORT_MULTIPLEX 0xf014 -#define SERIAL_PORT_MULTIPLEX 0xf010 - -/****************************************/ -/* I2C Registers */ -/****************************************/ - -#define I2C_SLAVE_ADDRESS 0xc000 -#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 -#define I2C_DATA 0xc004 -#define I2C_CONTROL 0xc008 -#define I2C_STATUS_BAUDE_RATE 0xc00C -#define I2C_SOFT_RESET 0xc01c - -/****************************************/ -/* MPSC Registers */ -/****************************************/ - -/* MPSC0 */ - -#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 -#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 -#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 -#define CHANNEL0_REGISTER1 0x800c -#define CHANNEL0_REGISTER2 0x8010 -#define CHANNEL0_REGISTER3 0x8014 -#define CHANNEL0_REGISTER4 0x8018 -#define CHANNEL0_REGISTER5 0x801c -#define CHANNEL0_REGISTER6 0x8020 -#define CHANNEL0_REGISTER7 0x8024 -#define CHANNEL0_REGISTER8 0x8028 -#define CHANNEL0_REGISTER9 0x802c -#define CHANNEL0_REGISTER10 0x8030 -#define CHANNEL0_REGISTER11 0x8034 - -/* MPSC1 */ - -#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 -#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 -#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 -#define CHANNEL1_REGISTER1 0x900c -#define CHANNEL1_REGISTER2 0x9010 -#define CHANNEL1_REGISTER3 0x9014 -#define CHANNEL1_REGISTER4 0x9018 -#define CHANNEL1_REGISTER5 0x901c -#define CHANNEL1_REGISTER6 0x9020 -#define CHANNEL1_REGISTER7 0x9024 -#define CHANNEL1_REGISTER8 0x9028 -#define CHANNEL1_REGISTER9 0x902c -#define CHANNEL1_REGISTER10 0x9030 -#define CHANNEL1_REGISTER11 0x9034 - -/* MPSCs Interupts */ - -#define MPSC0_CAUSE 0xb804 -#define MPSC0_MASK 0xb884 -#define MPSC1_CAUSE 0xb80c -#define MPSC1_MASK 0xb88c - -#endif /* __INCgt64240rh */ diff --git a/arch/mips/momentum/ocelot_g/gt64240_dep.h b/arch/mips/momentum/ocelot_g/gt64240_dep.h deleted file mode 100644 index f51bf0d6e1fb..000000000000 --- a/arch/mips/momentum/ocelot_g/gt64240_dep.h +++ /dev/null @@ -1,57 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64240/gt64240-dep.h - * Board-dependent definitions for GT-64120 chip. - * - * 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_GT64240_DEP_H -#define _ASM_GT64240_DEP_H - -#include /* for KSEG1ADDR() */ -#include /* for cpu_to_le32() */ - -/* - * PCI address allocation - */ -#if 0 -#define GT_PCI_MEM_BASE (0x22000000) -#define GT_PCI_MEM_SIZE GT_DEF_PCI0_MEM0_SIZE -#define GT_PCI_IO_BASE (0x20000000) -#define GT_PCI_IO_SIZE GT_DEF_PCI0_IO_SIZE -#endif - -extern unsigned long gt64240_base; - -#define GT64240_BASE (gt64240_base) - -/* - * Because of an error/peculiarity in the Galileo chip, we need to swap the - * bytes when running bigendian. - */ - -#define GT_WRITE(ofs, data) \ - *(volatile u32 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data) -#define GT_READ(ofs, data) \ - *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) -#define GT_READ_DATA(ofs) \ - le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_16(ofs, data) \ - *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) -#define GT_READ_16(ofs, data) \ - *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_8(ofs, data) \ - *(volatile u8 *)(GT64240_BASE+(ofs)) = data -#define GT_READ_8(ofs, data) \ - *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) - -#endif /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */ diff --git a/arch/mips/momentum/ocelot_g/pci-irq.c b/arch/mips/momentum/ocelot_g/pci-irq.c deleted file mode 100644 index e300e151ff85..000000000000 --- a/arch/mips/momentum/ocelot_g/pci-irq.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for gt64240 controller. - * - * 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. - */ -#include -#include -#include -#include -#include - - -void __devinit gt64240_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 1) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 2; /* irq_nr is 2 for INT0 */ - } else if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 2) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 3; /* irq_nr is 3 for INT1 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 3) { - /* Intel 21555 bridge */ - devices->irq = 5; /* irq_nr is 8 for INT6 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 4) { - /* PMC Slot */ - devices->irq = 9; /* irq_nr is 9 for INT7 */ - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write(current_bus, devices, - PCI_INTERRUPT_LINE, 1, devices->irq); - - /* enable master for everything but the GT-64240 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read(current_bus, devices, - PCI_COMMAND, 2, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write(current_bus, devices, - PCI_COMMAND, 2, cmd); - } - } -} diff --git a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c index 2b480b2ef03b..82bebaeb0087 100644 --- a/arch/mips/momentum/ocelot_g/prom.c +++ b/arch/mips/momentum/ocelot_g/prom.c @@ -20,8 +20,8 @@ #include #include #include +#include -#include "gt64240.h" #include "ocelot_pld.h" struct callvectors* debug_vectors; @@ -38,10 +38,8 @@ const char *get_system_type(void) return "Momentum Ocelot"; } -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { - uint32_t tmp; int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; @@ -78,10 +76,8 @@ void __init prom_init(void) bus_clock = simple_strtol(*env + strlen("busclock="), NULL, 10); } - *env++; + env++; } - - debug_vectors->printf("Booting Linux kernel...\n"); } unsigned long __init prom_free_prom_memory(void) diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c index 9a3010dae023..1d313eb56059 100644 --- a/arch/mips/momentum/ocelot_g/setup.c +++ b/arch/mips/momentum/ocelot_g/setup.c @@ -1,6 +1,4 @@ /* - * setup.c - * * BRIEF MODULE DESCRIPTION * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines * @@ -55,14 +53,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include -#include "gt64240.h" + #include "ocelot_pld.h" #ifdef CONFIG_GALILLEO_GT64240_ETH @@ -88,8 +86,6 @@ static unsigned long ENTRYLO(unsigned long paddr) _CACHE_UNCACHED)) >> 6; } -static void __init setup_l3cache(unsigned long size); - /* setup code for a handoff from a version 2 PMON 2000 PROM */ void PMON_v2_setup(void) { @@ -104,8 +100,10 @@ void PMON_v2_setup(void) GT64240 Internal Regs 0xf4000000 0xe0000000 UARTs (CS2) 0xfd000000 0xe0001000 */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); - add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K); + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), + 0xf4000000, PM_64K); + add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), + 0xfd000000, PM_4K); /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM in the CS[012] region. We can't use ioremap() yet. The NVRAM @@ -114,15 +112,57 @@ void PMON_v2_setup(void) Ocelot PLD (CS0) 0xfc000000 0xe0020000 NVRAM (CS1) 0xfc800000 0xe0030000 */ - add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K); - add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), + 0xfc000000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), + 0xfc800000, PM_64K); gt64240_base = 0xf4000000; } -static void __init momenco_ocelot_g_setup(void) +extern int rm7k_tcache_enabled; + +/* + * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() + */ +#define Page_Invalidate_T 0x16 +static void __init setup_l3cache(unsigned long size) { - void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + int register i; + + printk("Enabling L3 cache..."); + + /* Enable the L3 cache in the GT64120A's CPU Configuration register */ + GT_WRITE(0, GT_READ(0) | (1<<14)); + + /* Enable the L3 cache in the CPU */ + set_c0_config(1<<12 /* CONF_TE */); + + /* Clear the cache */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i < size; i+= 4096) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Page_Invalidate_T)); + } + + /* Let the RM7000 MM code know that the tertiary cache is enabled */ + rm7k_tcache_enabled = 1; + + printk("Done\n"); +} + +static int __init momenco_ocelot_g_setup(void) +{ + void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); unsigned int tmpword; board_time_init = gt64240_time_init; @@ -200,51 +240,11 @@ static void __init momenco_ocelot_g_setup(void) /* FIXME: Fix up the DiskOnChip mapping */ GT_WRITE(0x468, 0xfef73); -} -early_initcall(momenco_ocelot_g_setup); - -extern int rm7k_tcache_enabled; -/* - * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() - */ -#define Page_Invalidate_T 0x16 -static void __init setup_l3cache(unsigned long size) -{ - int register i; - unsigned long tmp; - - printk("Enabling L3 cache..."); - - /* Enable the L3 cache in the GT64120A's CPU Configuration register */ - GT_READ(0, &tmp); - GT_WRITE(0, tmp | (1<<14)); - - /* Enable the L3 cache in the CPU */ - set_c0_config(1<<12 /* CONF_TE */); - - /* Clear the cache */ - write_c0_taglo(0); - write_c0_taghi(0); - - for (i=0; i < size; i+= 4096) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (KSEG0ADDR(i)), - "i" (Page_Invalidate_T)); - } - - /* Let the RM7000 MM code know that the tertiary cache is enabled */ - rm7k_tcache_enabled = 1; - - printk("Done\n"); + return 0; } +early_initcall(momenco_ocelot_g_setup); /* This needs to be one of the first initcalls, because no I/O port access can work before this */ @@ -252,12 +252,12 @@ static void __init setup_l3cache(unsigned long size) static int io_base_ioremap(void) { /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ - void *io_remap_range = ioremap(0xc0000000, 0x30000000); + unsigned long io_remap_range; - if (!io_remap_range) { + io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000); + if (!io_remap_range) panic("Could not ioremap I/O port range"); - } - printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); return 0; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index a380308eff83..9cdb8b8ba00a 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MIPS_MV64340) += ops-mv64340.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_MIPS_TX3927) += ops-jmr3927.o +obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o # # These are still pretty much in the old state, watch, go blind. @@ -34,20 +35,20 @@ obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o -obj-$(CONFIG_MIPS_MV64340) += fixup-mv64340.o +obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o -obj-$(CONFIG_MOMENCO_OCELOT_C) += pci-ocelot-c.o -obj-$(CONFIG_MOMENCO_OCELOT_G) += pci-ocelot-g.o +obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o +obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o ops-gt64240.o pci-ocelot-g.o obj-$(CONFIG_NEC_EAGLE) += fixup-eagle.o ops-vrc4173.o -obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o +obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ + pci-yosemite.o obj-$(CONFIG_SGI_IP27) += pci-ip27.o obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += pci-sb1250.o obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o +obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o -obj-$(CONFIG_TANBAC_TB0229) += fixup-tb0229.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_VICTOR_MPC30X) += fixup-capcella.o -obj-$(CONFIG_MACH_VR41XX) += pci-vr41xx.o -obj-$(CONFIG_ZAO_CAPCELLA) += fixup-victor-mpc30x.o +obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o +obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c index 167ed4367cdb..9a0d68ed69d5 100644 --- a/arch/mips/pci/fixup-capcella.c +++ b/arch/mips/pci/fixup-capcella.c @@ -1,17 +1,21 @@ /* - * FILE NAME - * arch/mips/vr41xx/zao-capcella/pci_fixup.c + * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The ZAO Networks Capcella specific PCI fixups. + * Copyright (C) 2002,2004 Yoichi Yuasa * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 */ #include #include @@ -38,3 +42,7 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_capcella[slot][pin]; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c new file mode 100644 index 000000000000..fa78b9b1f435 --- /dev/null +++ b/arch/mips/pci/fixup-jaguar.c @@ -0,0 +1,42 @@ +/* + * 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. + * + * Marvell MV64340 interrupt fixup code. + * + * Marvell wants an NDA for their docs so this was written without + * documentation. You've been warned. + * + * Copyright (C) 2004 Ralf Baechle + */ +#include +#include +#include + +#include +#include + +/* + * WARNING: Example of how _NOT_ to do it. + */ +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 3; /* PCI-X A */ + if (bus == 0 && slot == 2) + return 4; /* PCI-X B */ + if (bus == 1 && slot == 1) + return 5; /* PCI A */ + if (bus == 1 && slot == 2) + return 6; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c new file mode 100644 index 000000000000..1320c42af570 --- /dev/null +++ b/arch/mips/pci/fixup-mpc30x.c @@ -0,0 +1,48 @@ +/* + * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups. + * + * Copyright (C) 2002,2004 Yoichi Yuasa + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +#include +#include + +#include +#include + +static const int internal_func_irqs[] __initdata = { + VRC4173_CASCADE_IRQ, + VRC4173_AC97_IRQ, + VRC4173_USB_IRQ, +}; + +static char irq_tab_mpc30x[] __initdata = { + [12] = VRC4173_PCMCIA1_IRQ, + [13] = VRC4173_PCMCIA2_IRQ, + [29] = MQ200_IRQ, +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == 30) + return internal_func_irqs[PCI_FUNC(dev->devfn)]; + + return irq_tab_mpc30x[slot]; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-mv64340.c b/arch/mips/pci/fixup-mv64340.c deleted file mode 100644 index fa78b9b1f435..000000000000 --- a/arch/mips/pci/fixup-mv64340.c +++ /dev/null @@ -1,42 +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. - * - * Marvell MV64340 interrupt fixup code. - * - * Marvell wants an NDA for their docs so this was written without - * documentation. You've been warned. - * - * Copyright (C) 2004 Ralf Baechle - */ -#include -#include -#include - -#include -#include - -/* - * WARNING: Example of how _NOT_ to do it. - */ -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int bus = dev->bus->number; - - if (bus == 0 && slot == 1) - return 3; /* PCI-X A */ - if (bus == 0 && slot == 2) - return 4; /* PCI-X B */ - if (bus == 1 && slot == 1) - return 5; /* PCI A */ - if (bus == 1 && slot == 2) - return 6; /* PCI B */ - -return 0; - panic("Whooops in pcibios_map_irq"); -} - -struct pci_fixup pcibios_fixups[] = { - {0} -}; diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c new file mode 100644 index 000000000000..0cc86ecebff8 --- /dev/null +++ b/arch/mips/pci/fixup-ocelot-c.c @@ -0,0 +1,39 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * 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. + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 2; /* PCI-X A */ + if (bus == 1 && slot == 1) + return 12; /* PCI-X B */ + if (bus == 1 && slot == 2) + return 4; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c new file mode 100644 index 000000000000..9a2cc8505db8 --- /dev/null +++ b/arch/mips/pci/fixup-ocelot-g.c @@ -0,0 +1,35 @@ +/* + * 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. + * + * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) /* Intel 82543 Gigabit MAC */ + return 2; /* irq_nr is 2 for INT0 */ + + if (bus == 0 && slot == 2) /* Intel 82543 Gigabit MAC */ + return 3; /* irq_nr is 3 for INT1 */ + + if (bus == 1 && slot == 3) /* Intel 21555 bridge */ + return 5; /* irq_nr is 8 for INT6 */ + + if (bus == 1 && slot == 4) /* PMC Slot */ + return 9; /* irq_nr is 9 for INT7 */ + + return -1; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c new file mode 100644 index 000000000000..ca4d99fbe123 --- /dev/null +++ b/arch/mips/pci/fixup-tb0219.c @@ -0,0 +1,64 @@ +/* + * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +#include +#include + +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + return irq; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c index 17c300c8ae34..50e639e04a4a 100644 --- a/arch/mips/pci/fixup-tb0226.c +++ b/arch/mips/pci/fixup-tb0226.c @@ -1,78 +1,83 @@ /* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0226 specific PCI fixups. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 */ #include #include #include -void __init pcibios_fixup_irqs(void) +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_dev *dev = NULL; - u8 slot, pin; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; + int irq = -1; - switch (slot) { - case 12: - vr41xx_set_irq_trigger(GD82559_1_PIN, + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + irq = GD82559_2_IRQ; + break; + case 14: + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, + LEVEL_LOW); + irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); - dev->irq = GD82559_1_IRQ; + vr41xx_set_irq_level(UPD720100_INTB_PIN, + LEVEL_LOW); + irq = UPD720100_INTB_IRQ; break; - case 13: - vr41xx_set_irq_trigger(GD82559_2_PIN, + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); - dev->irq = GD82559_2_IRQ; + vr41xx_set_irq_level(UPD720100_INTC_PIN, + LEVEL_LOW); + irq = UPD720100_INTC_IRQ; break; - case 14: - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - switch (pin) { - case 1: - vr41xx_set_irq_trigger(UPD720100_INTA_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTA_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTA_IRQ; - break; - case 2: - vr41xx_set_irq_trigger(UPD720100_INTB_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTB_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTB_IRQ; - break; - case 3: - vr41xx_set_irq_trigger(UPD720100_INTC_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTC_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTC_IRQ; - break; - } + default: break; } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + default: + break; } + + return irq; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-tb0229.c b/arch/mips/pci/fixup-tb0229.c deleted file mode 100644 index 8109c05c5832..000000000000 --- a/arch/mips/pci/fixup-tb0229.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * 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. - */ -#include -#include -#include - -#include - -void __init pcibios_fixup_irqs(void) -{ -#ifdef CONFIG_TANBAC_TB0219 - struct pci_dev *dev = NULL; - u8 slot; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; - - switch (slot) { - case 12: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT1_IRQ; - break; - case 13: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT2_IRQ; - break; - case 14: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT3_IRQ; - break; - default: - break; - } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } -#endif -} diff --git a/arch/mips/pci/fixup-victor-mpc30x.c b/arch/mips/pci/fixup-victor-mpc30x.c deleted file mode 100644 index 3ec5951feab2..000000000000 --- a/arch/mips/pci/fixup-victor-mpc30x.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The Victor MP-C303/304 specific PCI fixups. - * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp - * - * 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. - */ -#include -#include - -#include -#include - -/* - * Shortcuts - */ -#define PCMCIA1 VRC4173_PCMCIA1_IRQ -#define PCMCIA2 VRC4173_PCMCIA2_IRQ -#define MQ MQ200_IRQ - -static const int internal_func_irqs[8] __initdata = { - VRC4173_CASCADE_IRQ, - VRC4173_AC97_IRQ, - VRC4173_USB_IRQ, - -}; - -static char irq_tab_mpc30x[][5] __initdata = { - [12] = { PCMCIA1, PCMCIA1, 0, 0 }, - [13] = { PCMCIA2, PCMCIA2, 0, 0 }, - [29] = { MQ, MQ, 0, 0 }, /* mediaQ MQ-200 */ -}; - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (slot == 30) - return internal_func_irqs[PCI_FUNC(dev->devfn)]; - - return irq_tab_mpc30x[slot][pin]; -} diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c index 72b809685bdf..92e40b091643 100644 --- a/arch/mips/pci/fixup-yosemite.c +++ b/arch/mips/pci/fixup-yosemite.c @@ -26,21 +26,12 @@ #include #include -static char irq_tab_yosemite[8][5] __initdata = { - /* INTA INTB INTC INTD */ - { -1, -1, -1, -1, -1 }, - { -1, 3, 3, 3, 3 }, - { -1, 4, 4, 4, 4 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, -}; - int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - return irq_tab_yosemite[slot][pin]; + if (pin == 0) + return -1; + + return 3; /* Everything goes to one irq bit */ } struct pci_fixup pcibios_fixups[] = { diff --git a/arch/mips/pci/ops-gt64240.c b/arch/mips/pci/ops-gt64240.c new file mode 100644 index 000000000000..6929faa65490 --- /dev/null +++ b/arch/mips/pci/ops-gt64240.c @@ -0,0 +1,149 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * Copyright (C) 2004 Ralf Baechle + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + + +#define MASTER_ABORT_BIT 0x100 + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + + +static int gt_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 *val, u32 address_reg, u32 data_reg) +{ + uint32_t address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_READ_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_READ_16(data_reg + (offset & 0x3), val); + break; + case 4: + *val = GT_READ(data_reg); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int gt_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 val, u32 address_reg, u32 data_reg) +{ + unsigned int address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_WRITE_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_WRITE_16(data_reg + (offset & 0x3), val); + break; + case 4: + GT_WRITE(data_reg, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +#define BUILD_PCI_OPS(host) \ + \ +static int gt_bus ## host ## _read_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 * val) \ +{ \ + return gt_read_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +static int gt_bus ## host ## _write_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 val) \ +{ \ + return gt_write_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +struct pci_ops gt_bus ## host ## _pci_ops = { \ + .read = gt_bus ## host ## _read_config, \ + .write = gt_bus ## host ## _write_config \ +}; + +BUILD_PCI_OPS(0) +BUILD_PCI_OPS(1) diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c index 51b16d48d031..11184fa64443 100644 --- a/arch/mips/pci/ops-msc.c +++ b/arch/mips/pci/ops-msc.c @@ -48,8 +48,12 @@ static int msc_pcibios_config_access(unsigned char access_type, unsigned char type; u32 intr; - if ((busnum == 0) && (PCI_SLOT(devfn) == 0)) +#ifdef CONFIG_MIPS_BOARDS_GEN + if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) { + /* MIPS Core boards have SOCit connected as device 17 */ return -1; + } +#endif /* Clear status register bits. */ MSC_WRITE(MSC01_PCI_INTSTAT, diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c new file mode 100644 index 000000000000..46c636c27e06 --- /dev/null +++ b/arch/mips/pci/ops-titan-ht.c @@ -0,0 +1,125 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, + int offset, u32 * val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + /* + * RM9000 HT Errata: Issue back to back HT config + * transcations. Issue a BIU sync before and + * after the HT cycle + */ + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(val) = *(volatile int32_t *) 0xfb0006fc; + + udelay(30); + + * (volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 * val) +{ + uint32_t dword; + + titan_ht_config_read_dword(bus, devfn, offset, &dword); + + dword >>= ((offset & 3) << 3); + dword &= (0xffffffffU >> ((4 - size) << 8)); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int titan_ht_config_write_dword(struct pci_bus *bus, + unsigned int devfn, int offset, u32 val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(volatile int32_t *) 0xfb0006fc = val; + + udelay(30); + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 val) +{ + uint32_t val1, val2, mask; + + titan_ht_config_read_dword(bus, devfn, offset, &val2); + + val1 = val << ((offset & 3) << 3); + mask = ~(0xffffffffU >> ((4 - size) << 8)); + val2 &= ~(mask << ((offset & 3) << 8)); + + titan_ht_config_write_dword(bus, devfn, offset, val1 | val2); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops titan_ht_pci_ops = { + .read = titan_ht_config_read, + .write = titan_ht_config_write, +}; diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c index 12e79346fa58..1ac7880dd2a0 100644 --- a/arch/mips/pci/ops-titan.c +++ b/arch/mips/pci/ops-titan.c @@ -39,30 +39,30 @@ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 * val) { - int dev, bus, func; + int dev, busno, func; uint32_t address_reg, data_reg; uint32_t address; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); switch (size) { case 1: - TITAN_READ_8(data_reg + (offset & 0x3), val); + TITAN_READ_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_READ_16(data_reg + (offset & 0x2), val); + TITAN_READ_16(data_reg + (reg & 0x2), val); break; case 4: @@ -80,17 +80,17 @@ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 val) { uint32_t address_reg, data_reg, address; - int dev, bus, func; + int dev, busno, func; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); @@ -98,11 +98,11 @@ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, /* write the data */ switch (size) { case 1: - TITAN_WRITE_8(data_reg + (offset & 0x3), val); + TITAN_WRITE_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_WRITE_16(data_reg + (offset & 0x2), val); + TITAN_WRITE_16(data_reg + (reg & 0x2), val); break; case 4: diff --git a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c new file mode 100644 index 000000000000..44654605e461 --- /dev/null +++ b/arch/mips/pci/ops-vr41xx.c @@ -0,0 +1,126 @@ +/* + * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series. + * + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +/* + * Changes: + * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include +#include + +#include + +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) + +static inline int set_pci_configuration_address(unsigned char number, + unsigned int devfn, int where) +{ + if (number == 0) { + /* + * Type 0 configuration + */ + if (PCI_SLOT(devfn) < 11 || where > 0xff) + return -EINVAL; + + writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) | + (where & 0xfc), PCICONFAREG); + } else { + /* + * Type 1 configuration + */ + if (where > 0xff) + return -EINVAL; + + writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) | + (where & 0xfc) | 1U, PCICONFAREG); + } + + return 0; +} + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *val) +{ + uint32_t data; + + *val = 0xffffffffU; + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xffU; + break; + case 2: + *val = (data >> ((where & 2) << 3)) & 0xffffU; + break; + case 4: + *val = data; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t val) +{ + uint32_t data; + int shift; + + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + shift = (where & 3) << 3; + data &= ~(0xffU << shift); + data |= ((val & 0xffU) << shift); + break; + case 2: + shift = (where & 2) << 3; + data &= ~(0xffffU << shift); + data |= ((val & 0xffffU) << shift); + break; + case 4: + data = val; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + writel(data, PCICONFDREG); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops vr41xx_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c index 29b52757a337..dec6d3754fde 100644 --- a/arch/mips/pci/pci-ocelot-c.c +++ b/arch/mips/pci/pci-ocelot-c.c @@ -1,61 +1,140 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * 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. * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * Copyright (C) 2004 by Ralf Baechle */ + #include #include -#include -#include -#include -#include #include +#include #include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. + * We assume the address ranges have already been setup appropriately by + * the firmware. PMON in case of the Ocelot C does that. */ +static struct resource mv_pci_io_mem0_resource = { + .name = "MV64340 PCI0 IO MEM", + .flags = IORESOURCE_IO +}; + +static struct resource mv_pci_mem0_resource = { + .name = "MV64340 PCI0 MEM", + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops mv64340_bus0_pci_ops; + +static struct pci_controller mv_bus0_controller = { + .pci_ops = &mv64340_bus0_pci_ops, + .mem_resource = &mv_pci_mem0_resource, + .io_resource = &mv_pci_io_mem0_resource, +}; + +static uint32_t mv_io_base, mv_io_size; + +static void mv64340_pci0_init(void) +{ + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16; + + mv_pci_io_mem0_resource.start = 0; + mv_pci_io_mem0_resource.end = io_size - 1; + mv_pci_mem0_resource.start = mem0_base; + mv_pci_mem0_resource.end = mem0_base + mem0_size - 1; + mv_bus0_controller.mem_offset = mem0_base; + mv_bus0_controller.io_offset = 0; + + ioport_resource.end = io_size - 1; + + register_pci_controller(&mv_bus0_controller); + + mv_io_base = io_base; + mv_io_size = io_size; +} + +static struct resource mv_pci_io_mem1_resource = { + .name = "MV64340 PCI1 IO MEM", + .flags = IORESOURCE_IO +}; + +static struct resource mv_pci_mem1_resource = { + .name = "MV64340 PCI1 MEM", + .flags = IORESOURCE_MEM +}; -void mv64340_board_pcibios_fixup_bus(struct pci_bus *c); +extern struct pci_ops mv64340_bus1_pci_ops; -struct pci_fixup pcibios_fixups[] = { - {0} +static struct pci_controller mv_bus1_controller = { + .pci_ops = &mv64340_bus1_pci_ops, + .mem_resource = &mv_pci_mem1_resource, + .io_resource = &mv_pci_io_mem1_resource, }; -void __init pcibios_fixup_bus(struct pci_bus *c) +static __init void mv64340_pci1_init(void) { - mv64340_board_pcibios_fixup_bus(c); + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16; + + /* + * Here we assume the I/O window of second bus to be contiguous with + * the first. A gap is no problem but would waste address space for + * remapping the port space. + */ + mv_pci_io_mem1_resource.start = mv_io_size; + mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1; + mv_pci_mem1_resource.start = mem0_base; + mv_pci_mem1_resource.end = mem0_base + mem0_size - 1; + mv_bus1_controller.mem_offset = mem0_base; + mv_bus1_controller.io_offset = 0; + + ioport_resource.end = io_base + io_size -mv_io_base - 1; + + register_pci_controller(&mv_bus1_controller); + + mv_io_size = io_base + io_size - mv_io_base; } -void __init pcibios_init(void) +static __init int __init ocelot_c_pci_init(void) { - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; - - pci_scan_bus(0, &mv64340_bus0_pci_ops, NULL); - pci_scan_bus(1, &mv64340_bus1_pci_ops, NULL); + unsigned long io_v_base; + uint32_t enable; + + enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); + + /* + * We require at least one enabled I/O or PCI memory window or we + * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3. + */ + if (enable & (0x01 << 9) || enable & (0x01 << 10)) + mv64340_pci0_init(); + + if (enable & (0x01 << 14) || enable & (0x01 << 15)) + mv64340_pci1_init(); + + if (mv_io_size) { + io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); + + set_io_port_base(io_v_base); + } + + return 0; } + +arch_initcall(ocelot_c_pci_init); diff --git a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c index 34c3ec8d1645..11b05c7e6751 100644 --- a/arch/mips/pci/pci-ocelot-g.c +++ b/arch/mips/pci/pci-ocelot-g.c @@ -1,460 +1,90 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * 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. * - * 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. + * Copyright (C) 2004 by Ralf Baechle * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This doesn't really fly - but I don't have a GT64240 system for testing. */ +#include +#include #include #include -#include -#include -#include -#include -#include "gt64240.h" - -#include - -#define SELF 0 -#define MASTER_ABORT_BIT 0x100 +#include +#include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -void gt64240_board_pcibios_fixup_bus(struct pci_bus *c); - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val); -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val); - -static int pci_read(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 * val); -static int pci_write(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 val); - -/* - * General-purpose PCI functions. - */ - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - /* Accessing device 31 crashes the GT-64240. */ - if (dev < 5) - return 0; - return -1; -} - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Note that bus 0 and bus 1 are local, and we assume all other busses are - * bridged from bus 1. This is a safe assumption, since any other - * configuration will require major modifications to the CP7000G - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + * We assume these address ranges have been programmed into the GT-64240 by + * the firmware. PMON in case of the Ocelot G does that. Note the size of + * the I/O range is completly stupid; I/O mappings are limited to at most + * 256 bytes by the PCI spec and deprecated; and just to make things worse + * apparently many devices don't decode more than 64k of I/O space. */ -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; +#define gt_io_size 0x20000000UL +#define gt_io_base 0xe0000000UL - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_READ_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops galileo_pci_ops = { - .read = pci_read, - .write = pci_write +static struct resource gt_pci_mem0_resource = { + .name = "MV64240 PCI0 MEM", + .start = 0xc0000000UL, + .end = 0xcfffffffUL, + .flags = IORESOURCE_MEM }; -static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) -{ - switch (size) { - case 1: - return galileo_pcibios_read_config_byte(bus->number, - devfn, where, - (u8 *) val); - case 2: - return galileo_pcibios_read_config_word(bus->number, - devfn, where, - (u16 *) val); - case 4: - return galileo_pcibios_read_config_dword(bus->number, - devfn, where, - (u32 *) val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - switch (size) { - case 1: - return galileo_pcibios_write_config_byte(bus->number, - devfn, where, - val); - case 2: - return galileo_pcibios_write_config_word(bus->number, - devfn, where, - val); - case 4: - return galileo_pcibios_write_config_dword(bus->number, - devfn, where, - val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -struct pci_fixup pcibios_fixups[] = { - {0} +static struct resource gt_pci_io_mem0_resource = { + .name = "MV64240 PCI0 IO MEM", + .start = 0xe0000000UL, + .end = 0xefffffffUL, + .flags = IORESOURCE_IO }; -void __devinit pcibios_fixup_bus(struct pci_bus *c) -{ - gt64240_board_pcibios_fixup_bus(c); -} +static struct pci_controller gt_bus0_controller = { + .pci_ops = >_bus0_pci_ops, + .mem_resource = >_pci_mem0_resource, + .mem_offset = 0xc0000000UL, + .io_resource = >_pci_io_mem0_resource, + .io_offset = 0x00000000UL +}; +static struct resource gt_pci_mem1_resource = { + .name = "MV64240 PCI1 MEM", + .start = 0xd0000000UL, + .end = 0xdfffffffUL, + .flags = IORESOURCE_MEM +}; -/******************************************************************** -* pci0P2PConfig - This function set the PCI_0 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci0P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) -{ - uint32_t regData; +static struct resource gt_pci_io_mem1_resource = { + .name = "MV64240 PCI1 IO MEM", + .start = 0xf0000000UL, + .end = 0xffffffffUL, + .flags = IORESOURCE_IO +}; - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_0P2P_CONFIGURATION, regData); -} +static struct pci_controller gt_bus1_controller = { + .pci_ops = >_bus1_pci_ops, + .mem_resource = >_pci_mem1_resource, + .mem_offset = 0xd0000000UL, + .io_resource = >_pci_io_mem1_resource, + .io_offset = 0x10000000UL +}; -/******************************************************************** -* pci1P2PConfig - This function set the PCI_1 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci1P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) +static __init int __init ocelot_g_pci_init(void) { - uint32_t regData; + unsigned long io_v_base; - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_1P2P_CONFIGURATION, regData); -} + if (gt_io_size) { + io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); -#define PCI0_STATUS_COMMAND_REG 0x4 -#define PCI1_STATUS_COMMAND_REG 0x84 - -static int __init pcibios_init(void) -{ - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + set_io_port_base(io_v_base); + } - pci_scan_bus(0, &galileo_pci_ops, NULL); - pci_scan_bus(1, &galileo_pci_ops, NULL); + register_pci_controller(>_bus0_controller); + register_pci_controller(>_bus1_controller); return 0; } -subsys_initcall(pcibios_init); +arch_initcall(ocelot_g_pci_init); diff --git a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c index 8068b0171f0c..a6db6f028574 100644 --- a/arch/mips/pci/pci-vr41xx.c +++ b/arch/mips/pci/pci-vr41xx.c @@ -1,48 +1,32 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.c + * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * PCI Control Unit routines for the NEC VR4100 series. + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * 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. * - * Copyright 2001-2003 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 */ /* * Changes: - * Paul Mundt - * - Fix deadlock-causing PCIU access race for VR4131. - * * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. */ -#include #include #include #include -#include #include #include @@ -51,183 +35,257 @@ #include "pci-vr41xx.h" -static inline int vr41xx_pci_config_access(unsigned char bus, - unsigned int devfn, int where) -{ - if (bus == 0) { - /* - * Type 0 configuration - */ - if (PCI_SLOT(devfn) < 11 || where > 255) - return -1; - - writel((1UL << PCI_SLOT(devfn)) | - (PCI_FUNC(devfn) << 8) | - (where & 0xfc), PCICONFAREG); - } else { - /* - * Type 1 configuration - */ - if (where > 255) - return -1; - - writel((bus << 16) | - (devfn << 8) | (where & 0xfc) | 1UL, PCICONFAREG); - } - - return 0; -} +extern struct pci_ops vr41xx_pci_ops; -static int vr41xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - u32 data; - - *val = 0xffffffffUL; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct pci_master_address_conversion pci_master_memory1 = { + .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS, +}; - data = readl(PCICONFDREG); +static struct pci_target_address_conversion pci_target_memory1 = { + .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK, + .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS, +}; - switch (size) { - case 1: - *val = (data >> ((where & 3) << 3)) & 0xffUL; - break; - case 2: - *val = (data >> ((where & 2) << 3)) & 0xffffUL; - break; - case 4: - *val = data; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_master_address_conversion pci_master_io = { + .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_IO_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS, +}; - return PCIBIOS_SUCCESSFUL; -} +static struct pci_mailbox_address pci_mailbox = { + .base_address = PCI_MAILBOX_BASE_ADDRESS, +}; -static int vr41xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data; - int shift; +static struct pci_target_address_window pci_target_window1 = { + .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS, +}; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct resource pci_mem_resource = { + .name = "PCI Memory resources", + .start = PCI_MEM_RESOURCE_START, + .end = PCI_MEM_RESOURCE_END, + .flags = IORESOURCE_MEM, +}; - data = readl(PCICONFDREG); +static struct resource pci_io_resource = { + .name = "PCI I/O resources", + .start = PCI_IO_RESOURCE_START, + .end = PCI_IO_RESOURCE_END, + .flags = IORESOURCE_IO, +}; - switch (size) { - case 1: - shift = (where & 3) << 3; - data &= ~(0xff << shift); - data |= ((val & 0xff) << shift); - break; - case 2: - shift = (where & 2) << 3; - data &= ~(0xffff << shift); - data |= ((val & 0xffff) << shift); - break; - case 4: - data = val; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = { + .master_memory1 = &pci_master_memory1, + .target_memory1 = &pci_target_memory1, + .master_io = &pci_master_io, + .exclusive_access = CANNOT_LOCK_FROM_DEVICE, + .wait_time_limit_from_irdy_to_trdy = 0, + .mailbox = &pci_mailbox, + .target_window1 = &pci_target_window1, + .master_latency_timer = 0x80, + .retry_limit = 0, + .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR, + .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE, +}; - writel(data, PCICONFDREG); +static struct pci_controller vr41xx_pci_controller = { + .pci_ops = &vr41xx_pci_ops, + .mem_resource = &pci_mem_resource, + .io_resource = &pci_io_resource, +}; - return PCIBIOS_SUCCESSFUL; +void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup) +{ + vr41xx_pci_controller_unit_setup = *setup; } -struct pci_ops vr41xx_pci_ops = { - .read = vr41xx_pci_config_read, - .write = vr41xx_pci_config_write, -}; - -void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) +static int __init vr41xx_pciu_init(void) { - struct vr41xx_pci_address_space *s; - unsigned long vtclock; - u32 config; - int n; + struct pci_controller_unit_setup *setup; + struct pci_master_address_conversion *master; + struct pci_target_address_conversion *target; + struct pci_mailbox_address *mailbox; + struct pci_target_address_window *window; + unsigned long vtclock, pci_clock_max; + uint32_t val; - if (!map) - return; + setup = &vr41xx_pci_controller_unit_setup; /* Disable PCI interrupt */ - writew(0, MPCIINTREG); + vr41xx_disable_pciint(); /* Supply VTClock to PCIU */ vr41xx_supply_clock(PCIU_CLOCK); - /* - * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK - * before doing any PCIU access to avoid deadlock on VR4131. - */ - udelay(1); + /* Dummy write, waiting for supply of VTClock. */ + vr41xx_disable_pciint(); /* Select PCI clock */ + if (setup->pci_clock_max != 0) + pci_clock_max = setup->pci_clock_max; + else + pci_clock_max = PCI_CLOCK_MAX; vtclock = vr41xx_get_vtclock_frequency(); - if (vtclock < MAX_PCI_CLOCK) + if (vtclock < pci_clock_max) writel(EQUAL_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 2) < MAX_PCI_CLOCK) + else if ((vtclock / 2) < pci_clock_max) writel(HALF_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 4) < MAX_PCI_CLOCK) + else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 && + (vtclock / 3) < pci_clock_max) + writel(ONE_THIRD_VTCLOCK, PCICLKSELREG); + else if ((vtclock / 4) < pci_clock_max) writel(QUARTER_VTCLOCK, PCICLKSELREG); - else - printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); + else { + printk(KERN_ERR "PCI Clock is over 33MHz.\n"); + return -EINVAL; + } /* Supply PCI clock by PCI bus */ vr41xx_supply_clock(PCI_CLOCK); - /* - * Set PCI memory & I/O space address conversion registers - * for master transaction. - */ - if (map->mem1 != NULL) { - s = map->mem1; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW1REG); + if (setup->master_memory1 != NULL) { + master = setup->master_memory1; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW1REG); + } else { + val = readl(PCIMMAW1REG); + val &= ~WINEN; + writel(val, PCIMMAW1REG); + } + + if (setup->master_memory2 != NULL) { + master = setup->master_memory2; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW2REG); + } else { + val = readl(PCIMMAW2REG); + val &= ~WINEN; + writel(val, PCIMMAW2REG); + } + + if (setup->target_memory1 != NULL) { + target = setup->target_memory1; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW1REG); + } else { + val = readl(PCITAW1REG); + val &= ~WINEN; + writel(val, PCITAW1REG); + } + + if (setup->target_memory2 != NULL) { + target = setup->target_memory2; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW2REG); + } else { + val = readl(PCITAW2REG); + val &= ~WINEN; + writel(val, PCITAW2REG); + } + + if (setup->master_io != NULL) { + master = setup->master_io; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIIA(master->pci_base_address); + writel(val, PCIMIOAWREG); + } else { + val = readl(PCIMIOAWREG); + val &= ~WINEN; + writel(val, PCIMIOAWREG); + } + + if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE) + writel(UNLOCK, PCIEXACCREG); + else + writel(0, PCIEXACCREG); + + if (current_cpu_data.cputype == CPU_VR4122) + writel(TRDYV(setup->wait_time_limit_from_irdy_to_trdy), PCITRDYVREG); + + writel(MLTIM(setup->master_latency_timer), LATTIMEREG); + + if (setup->mailbox != NULL) { + mailbox = setup->mailbox; + val = MBADD(mailbox->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, MAILBAREG); } - if (map->mem2 != NULL) { - s = map->mem2; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW2REG); + + if (setup->target_window1) { + window = setup->target_window1; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA1REG); + } + + if (setup->target_window2) { + window = setup->target_window2; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA2REG); } - if (map->io != NULL) { - s = map->io; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMIOAWREG); + + val = readl(RETVALREG); + val &= ~RTYVAL_MASK; + val |= RTYVAL(setup->retry_limit); + writel(val, RETVALREG); + + val = readl(PCIAPCNTREG); + val &= ~(TKYGNT | PAPC); + + switch (setup->arbiter_priority_control) { + case PCI_ARBITRATION_MODE_ALTERNATE_0: + val |= PAPC_ALTERNATE_0; + break; + case PCI_ARBITRATION_MODE_ALTERNATE_B: + val |= PAPC_ALTERNATE_B; + break; + default: + val |= PAPC_FAIR; + break; } - /* Set target memory windows */ - writel(0x00081000, PCITAW1REG); - writel(0UL, PCITAW2REG); - pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL); - pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL); + if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE) + val |= TKYGNT_ENABLE; + + writel(val, PCIAPCNTREG); + + writel(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR, COMMANDREG); /* Clear bus error */ - n = readl(BUSERRADREG); + readl(BUSERRADREG); + + writel(CONFIG_DONE, PCIENREG); + + if (setup->mem_resource != NULL) + vr41xx_pci_controller.mem_resource = setup->mem_resource; - if (current_cpu_data.cputype == CPU_VR4122) { - writel(0UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); + if (setup->io_resource != NULL) { + vr41xx_pci_controller.io_resource = setup->io_resource; } else { - writel(100UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004); + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; } - writel(CONFIG_DONE, PCIENREG); - pciu_write_config_dword(PCI_COMMAND, - PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + register_pci_controller(&vr41xx_pci_controller); + + return 0; } + +early_initcall(vr41xx_pciu_init); diff --git a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h index f0fca0c786a8..3a5f69bfb998 100644 --- a/arch/mips/pci/pci-vr41xx.h +++ b/arch/mips/pci/pci-vr41xx.h @@ -1,164 +1,151 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.h + * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Include file for PCI Control Unit of the NEC VR4100 series. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * 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. * - * Copyright 2002 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 */ +#ifndef __PCI_VR41XX_H +#define __PCI_VR41XX_H + +#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) +#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) +#define PCITAW1REG KSEG1ADDR(0x0f000c08) +#define PCITAW2REG KSEG1ADDR(0x0f000c0c) +#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) + #define IBA(addr) ((addr) & 0xff000000U) + #define MASTER_MSK(mask) (((mask) >> 11) & 0x000fe000U) + #define PCIA(addr) (((addr) >> 24) & 0x000000ffU) + #define TARGET_MSK(mask) (((mask) >> 8) & 0x000fe000U) + #define ITA(addr) (((addr) >> 24) & 0x000000ffU) + #define PCIIA(addr) (((addr) >> 24) & 0x000000ffU) + #define WINEN 0x1000U +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) +#define PCIMAILREG KSEG1ADDR(0x0f000c1c) +#define BUSERRADREG KSEG1ADDR(0x0f000c24) + #define EA(reg) ((reg) &0xfffffffc) + +#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) + #define MABTCLR 0x80000000U + #define TRDYCLR 0x40000000U + #define PARCLR 0x20000000U + #define MBCLR 0x10000000U + #define SERRCLR 0x08000000U + #define RTYCLR 0x04000000U + #define MABCLR 0x02000000U + #define TABCLR 0x01000000U + /* RFU */ + #define MABTMSK 0x00008000U + #define TRDYMSK 0x00004000U + #define PARMSK 0x00002000U + #define MBMSK 0x00001000U + #define SERRMSK 0x00000800U + #define RTYMSK 0x00000400U + #define MABMSK 0x00000200U + #define TABMSK 0x00000100U + #define IBAMABT 0x00000080U + #define TRDYRCH 0x00000040U + #define PAR 0x00000020U + #define MB 0x00000010U + #define PCISERR 0x00000008U + #define RTYRCH 0x00000004U + #define MABORT 0x00000002U + #define TABORT 0x00000001U + +#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) + #define UNLOCK 0x2U + #define EAREQ 0x1U +#define PCIRECONTREG KSEG1ADDR(0x0f000c30) + #define RTRYCNT(reg) ((reg) & 0x000000ffU) +#define PCIENREG KSEG1ADDR(0x0f000c34) + #define CONFIG_DONE 0x4U +#define PCICLKSELREG KSEG1ADDR(0x0f000c38) + #define EQUAL_VTCLOCK 0x2U + #define HALF_VTCLOCK 0x0U + #define ONE_THIRD_VTCLOCK 0x3U + #define QUARTER_VTCLOCK 0x1U +#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) + #define TRDYV(val) ((uint32_t)(val) & 0xffU) +#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) + +#define VENDORIDREG KSEG1ADDR(0x0f000d00) +#define DEVICEIDREG KSEG1ADDR(0x0f000d00) +#define COMMANDREG KSEG1ADDR(0x0f000d04) +#define STATUSREG KSEG1ADDR(0x0f000d04) +#define REVIDREG KSEG1ADDR(0x0f000d08) +#define CLASSREG KSEG1ADDR(0x0f000d08) +#define CACHELSREG KSEG1ADDR(0x0f000d0c) +#define LATTIMEREG KSEG1ADDR(0x0f000d0c) + #define MLTIM(val) (((uint32_t)(val) << 7) & 0xff00U) +#define MAILBAREG KSEG1ADDR(0x0f000d10) +#define PCIMBA1REG KSEG1ADDR(0x0f000d14) +#define PCIMBA2REG KSEG1ADDR(0x0f000d18) + #define MBADD(base) ((base) & 0xfffff800U) + #define PMBA(base) ((base) & 0xffe00000U) + #define PREF 0x8U + #define PREF_APPROVAL 0x8U + #define PREF_DISAPPROVAL 0x0U + #define TYPE 0x6U + #define TYPE_32BITSPACE 0x0U + #define MSI 0x1U + #define MSI_MEMORY 0x0U +#define INTLINEREG KSEG1ADDR(0x0f000d3c) +#define INTPINREG KSEG1ADDR(0x0f000d3c) +#define RETVALREG KSEG1ADDR(0x0f000d40) +#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) + #define TKYGNT 0x04000000U + #define TKYGNT_ENABLE 0x04000000U + #define TKYGNT_DISABLE 0x00000000U + #define PAPC 0x03000000U + #define PAPC_ALTERNATE_B 0x02000000U + #define PAPC_ALTERNATE_0 0x01000000U + #define PAPC_FAIR 0x00000000U + #define RTYVAL(val) (((uint32_t)(val) << 7) & 0xff00U) + #define RTYVAL_MASK 0xff00U + +#define PCI_CLOCK_MAX 33333333U + /* - * Changes: - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Default setup */ -#ifndef __VR41XX_PCIU_H -#define __VR41XX_PCIU_H - -#include -#include - -#define BIT(x) (1 << (x)) - -#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) -#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) -#define PCITAW1REG KSEG1ADDR(0x0f000c08) -#define PCITAW2REG KSEG1ADDR(0x0f000c0c) -#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) -#define INTERNAL_BUS_BASE_ADDRESS 0xff000000 -#define ADDRESS_MASK 0x000fe000 -#define PCI_ACCESS_ENABLE BIT(12) -#define PCI_ADDRESS_SETTING 0x000000ff - -#define PCICONFDREG KSEG1ADDR(0x0f000c14) -#define PCICONFAREG KSEG1ADDR(0x0f000c18) -#define PCIMAILREG KSEG1ADDR(0x0f000c1c) - -#define BUSERRADREG KSEG1ADDR(0x0f000c24) -#define ERROR_ADDRESS 0xfffffffc - -#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) -#define MABTCLR BIT(31) -#define TRDYCLR BIT(30) -#define PARCLR BIT(29) -#define MBCLR BIT(28) -#define SERRCLR BIT(27) - -#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) -#define UNLOCK BIT(1) -#define EAREQ BIT(0) - -#define PCIRECONTREG KSEG1ADDR(0x0f000c30) -#define RTRYCNT 0x000000ff - -#define PCIENREG KSEG1ADDR(0x0f000c34) -#define CONFIG_DONE BIT(2) - -#define PCICLKSELREG KSEG1ADDR(0x0f000c38) -#define EQUAL_VTCLOCK 0x00000002 -#define HALF_VTCLOCK 0x00000000 -#define QUARTER_VTCLOCK 0x00000001 - -#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) - -#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) - -#define PCIU_CONFIGREGS_BASE KSEG1ADDR(0x0f000d00) -#define VENDORIDREG KSEG1ADDR(0x0f000d00) -#define DEVICEIDREG KSEG1ADDR(0x0f000d00) -#define COMMANDREG KSEG1ADDR(0x0f000d04) -#define STATUSREG KSEG1ADDR(0x0f000d04) -#define REVIDREG KSEG1ADDR(0x0f000d08) -#define CLASSREG KSEG1ADDR(0x0f000d08) -#define CACHELSREG KSEG1ADDR(0x0f000d0c) -#define LATTIMEREG KSEG1ADDR(0x0f000d0c) -#define MAILBAREG KSEG1ADDR(0x0f000d10) -#define PCIMBA1REG KSEG1ADDR(0x0f000d14) -#define PCIMBA2REG KSEG1ADDR(0x0f000d18) -#define INTLINEREG KSEG1ADDR(0x0f000d3c) -#define INTPINREG KSEG1ADDR(0x0f000d3c) -#define RETVALREG KSEG1ADDR(0x0f000d40) -#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) - -#define MPCIINTREG KSEG1ADDR(0x0f0000b2) - -#define MAX_PCI_CLOCK 33333333 - -static inline int pciu_read_config_byte(int where, u8 * val) -{ - u32 data; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u8) (data >> ((where & 3) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_word(int where, u16 * val) -{ - u32 data; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u16) (data >> ((where & 2) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_dword(int where, u32 * val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - *val = readl(PCIU_CONFIGREGS_BASE + where); +#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS 0x10000000U +#define PCI_MASTER_MEM1_ADDRESS_MASK 0x7c000000U +#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS 0x10000000U - return PCIBIOS_SUCCESSFUL; -} +#define PCI_TARGET_MEM1_ADDRESS_MASK 0x08000000U +#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_byte(int where, u8 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_MASTER_IO_BUS_BASE_ADDRESS 0x16000000U +#define PCI_MASTER_IO_ADDRESS_MASK 0x7e000000U +#define PCI_MASTER_IO_PCI_BASE_ADDRESS 0x00000000U - return 0; -} +#define PCI_MAILBOX_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_word(int where, u16 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_TARGET_WINDOW1_BASE_ADDRESS 0x00000000U - return 0; -} +#define IO_PORT_BASE KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS) +#define IO_PORT_RESOURCE_START PCI_MASTER_IO_PCI_BASE_ADDRESS +#define IO_PORT_RESOURCE_END (~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK) -static inline int pciu_write_config_dword(int where, u32 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_IO_RESOURCE_START 0x01000000UL +#define PCI_IO_RESOURCE_END 0x01ffffffUL - return 0; -} +#define PCI_MEM_RESOURCE_START 0x11000000UL +#define PCI_MEM_RESOURCE_END 0x13ffffffUL -#endif /* __VR41XX_PCIU_H */ +#endif /* __PCI_VR41XX_H */ diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c new file mode 100644 index 000000000000..c1151f43c9af --- /dev/null +++ b/arch/mips/pci/pci-yosemite.c @@ -0,0 +1,37 @@ +/* + * 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) 2004 by Ralf Baechle + * + */ +#include +#include +#include +#include +#include +#include + +extern struct pci_ops titan_pci_ops; + +static struct resource py_mem_resource = { + "Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM +}; + +static struct resource py_io_resource = { + "Titan IO MEM", 0x00000000UL, 0x00ffffffUL, IORESOURCE_IO, +}; + +static struct pci_controller py_controller = { + .pci_ops = &titan_pci_ops, + .mem_resource = &py_mem_resource, + .mem_offset = 0x10000000UL, + .io_resource = &py_io_resource, + .io_offset = 0x00000000UL +}; + +static int __init pmc_yosemite_setup(void) +{ + register_pci_controller(&py_controller); +} diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index eacfcda3d282..9bee1e937ae6 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -231,7 +231,7 @@ static void __init pcibios_fixup_device_resources(struct pci_dev *dev, { /* Update device resources. */ struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - unsigned long offset; + unsigned long offset = 0; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index 1537b6d36617..bc17586235a3 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile @@ -1,8 +1,7 @@ # -# Makefile for the PMC-Sierra Titan +# Makefile for the PMC-Sierra Titan # -obj-y += irq-handler.o irq.o prom.o setup.o +obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_HYPERTRANSPORT) += ht-irq.o ht.o +obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c new file mode 100644 index 000000000000..1ff8d95d0970 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c @@ -0,0 +1,184 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Support for KGDB for the Yosemite board. We make use of single serial + * port to be used for KGDB as well as console. The second serial port + * seems to be having a problem. Single IRQ is allocated for both the + * ports. Hence, the interrupt routing code needs to figure out whether + * the interrupt came from channel A or B. + */ + +#include + +#if defined(CONFIG_KGDB) +#include + +/* + * Baud rate, Parity, Data and Stop bit settings for the + * serial port on the Yosemite. Note that the Early printk + * patch has been added. So, we should be all set to go + */ +#define YOSEMITE_BAUD_2400 2400 +#define YOSEMITE_BAUD_4800 4800 +#define YOSEMITE_BAUD_9600 9600 +#define YOSEMITE_BAUD_19200 19200 +#define YOSEMITE_BAUD_38400 38400 +#define YOSEMITE_BAUD_57600 57600 +#define YOSEMITE_BAUD_115200 115200 + +#define YOSEMITE_PARITY_NONE 0 +#define YOSEMITE_PARITY_ODD 0x08 +#define YOSEMITE_PARITY_EVEN 0x18 +#define YOSEMITE_PARITY_MARK 0x28 +#define YOSEMITE_PARITY_SPACE 0x38 + +#define YOSEMITE_DATA_5BIT 0x0 +#define YOSEMITE_DATA_6BIT 0x1 +#define YOSEMITE_DATA_7BIT 0x2 +#define YOSEMITE_DATA_8BIT 0x3 + +#define YOSEMITE_STOP_1BIT 0x0 +#define YOSEMITE_STOP_2BIT 0x4 + +/* This is crucial */ +#define SERIAL_REG_OFS 0x1 + +#define SERIAL_RCV_BUFFER 0x0 +#define SERIAL_TRANS_HOLD 0x0 +#define SERIAL_SEND_BUFFER 0x0 +#define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS) +#define SERIAL_INTR_ID (2 * SERIAL_REG_OFS) +#define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS) +#define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS) +#define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS) +#define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS) +#define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS) +#define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS) +#define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS) +#define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS) + +#define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS) +#define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS) + +/* + * Functions to READ and WRITE to serial port 0 + */ +#define SERIAL_READ(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) + +#define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) = val) + +/* + * Functions to READ and WRITE to serial port 1 + */ +#define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs) + +#define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs))) = val) + +/* + * Second serial port initialization + */ +void init_second_port(void) +{ + /* Disable Interrupts */ + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80); + divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200; + SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE_1(SERIAL_DIVISOR_MSB, + (divisor & 0xff00) >> 8); + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT | + YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT); + + /* Enable Interrupts */ + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf); +} + +/* Initialize the serial port for KGDB debugging */ +void debugInit(unsigned int baud, unsigned char data, unsigned char parity, + unsigned char stop) +{ + /* Disable Interrupts */ + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80); + + divisor = TITAN_SERIAL_BASE_BAUD / baud; + SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8); + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +unsigned char getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0); + return SERIAL_READ(SERIAL_RCV_BUFFER); +} + +int putDebugChar(unsigned char byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0); + SERIAL_WRITE(SERIAL_SEND_BUFFER, byte); + + return 1; +} +#endif diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c new file mode 100644 index 000000000000..416da22b3bf4 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Detailed Description: + * + * This block implements the I2C interface to the slave devices like the + * Atmel 24C32 EEPROM and the MAX 1619 Sensors device. The I2C Master interface + * can be controlled by the SCMB block. And the SCMB block kicks in only when + * using the Ethernet Mode of operation and __not__ the SysAD mode + * + * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to + * communicate with the Quad-PHY from Marvel. The I2C is used to communicate + * with the I2C slave devices. It seems that the driver does not explicitly + * deal with the control of SDA and SCL serial lines. So, the driver will set + * the slave address, drive the command and then the data. The SCMB will then + * control the two serial lines as required. + * + * It seems the documents are very unclear abt this. Hence, I took some time + * out to write the desciption to have an idea of how the I2C can actually + * work. Currently, this Linux driver wont be integrated into the generic Linux + * I2C framework. And finally, the I2C interface is also known as the 2BI + * interface. 2BI means 2-bit interface referring to SDA and SCL serial lines + * respectively. + * + * - Manish Lachwani (12/09/2003) + */ + +#include "i2c-yosemite.h" + +/* + * Poll the I2C interface for the BUSY bit. + */ +static int titan_i2c_poll(void) +{ + int i = 0; + unsigned long val = 0; + + for (i = 0; i < TITAN_I2C_MAX_POLL; i++) { + val = TITAN_I2C_READ(TITAN_I2C_COMMAND); + + if (!(val & 0x8000)) + return 0; + } + + return TITAN_I2C_ERR_TIMEOUT; +} + +/* + * Execute the I2C command + */ +int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, + int size, unsigned int *addr) +{ + int loop = 0, bytes, i; + unsigned int *write_data, data, *read_data; + unsigned long reg_val, val; + + write_data = cmd->data; + read_data = addr; + + TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr); + + if (cmd->type == TITAN_I2C_CMD_WRITE) + loop = cmd->write_size; + else + loop = size; + + while (loop > 0) { + if ((cmd->type == TITAN_I2C_CMD_WRITE) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, write_data += 2, reg_val += 4) { + if (bytes < cmd->write_size) { + data = write_data[0]; + ++data; + } + + if (bytes < cmd->write_size) { + data = write_data[1]; + ++data; + } + + TITAN_I2C_WRITE(reg_val, data); + } + } + + TITAN_I2C_WRITE(TITAN_I2C_COMMAND, + (unsigned int) (cmd->type << 13)); + if (titan_i2c_poll() != TITAN_I2C_ERR_OK) + return TITAN_I2C_ERR_TIMEOUT; + + if ((cmd->type == TITAN_I2C_CMD_READ) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, read_data += 2, reg_val += 4) { + data = TITAN_I2C_READ(reg_val); + + if (bytes < size) { + read_data[0] = data & 0xff; + ++bytes; + } + + if (bytes < size) { + read_data[1] = + ((data >> 8) & 0xff); + ++bytes; + } + } + } + + loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2); + } + + /* + * Read the Interrupt status and then return the appropriate error code + */ + + val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS); + if (val & 0x0020) + return TITAN_I2C_ERR_ARB_LOST; + + if (val & 0x0040) + return TITAN_I2C_ERR_NO_RESP; + + if (val & 0x0080) + return TITAN_I2C_ERR_DATA_COLLISION; + + return TITAN_I2C_ERR_OK; +} + +/* + * Init the I2C subsystem of the PMC-Sierra Yosemite board + */ +int titan_i2c_init(titan_i2c_config * config) +{ + unsigned int val; + + /* + * Reset the SCMB and program into the I2C mode + */ + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000); + + /* + * Configure the filtera and clka values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A); + val |= ((val & ~(0xF000)) | ((config->filtera << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clka & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val); + + /* + * Configure the filterb and clkb values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B); + val |= ((val & ~(0xF000)) | ((config->filterb << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clkb & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val); + + return TITAN_I2C_ERR_OK; +} diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h index 8b6e49c638d7..31c5523276fa 100644 --- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h @@ -31,7 +31,7 @@ /* Read and Write operations to the chip */ #define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */ - + #define TITAN_I2C_WRITE(offset, data) \ *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data @@ -48,14 +48,14 @@ #define TITAN_I2C_MAX_POLL 100 /* Registers used for I2C work */ -#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ -#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ -#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ -#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ -#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ +#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ +#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ +#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ +#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ +#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ #define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */ -#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ -#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ +#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ +#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ /* Error */ #define TITAN_I2C_ERR_ARB_LOST (-9220) @@ -66,31 +66,31 @@ /* I2C Command Type */ typedef enum { - TITAN_I2C_CMD_WRITE = 0, - TITAN_I2C_CMD_READ = 1, - TITAN_I2C_CMD_READ_WRITE = 2 + TITAN_I2C_CMD_WRITE = 0, + TITAN_I2C_CMD_READ = 1, + TITAN_I2C_CMD_READ_WRITE = 2 } titan_i2c_cmd_type; /* I2C structures */ typedef struct { - int filtera; /* Register 0x0184, bits 15 - 12*/ - int clka; /* Register 0x0184, bits 9 - 0 */ - int filterb; /* Register 0x0188, bits 15 - 12 */ - int clkb; /* Register 0x0188, bits 9 - 0 */ + int filtera; /* Register 0x0184, bits 15 - 12 */ + int clka; /* Register 0x0184, bits 9 - 0 */ + int filterb; /* Register 0x0188, bits 15 - 12 */ + int clkb; /* Register 0x0188, bits 9 - 0 */ } titan_i2c_config; /* I2C command type */ typedef struct { - titan_i2c_cmd_type type; /* Type of command */ - int num_arb; /* Register 0x01a0, bits 15 - 12 */ - int num_nak; /* Register 0x01a0, bits 11 - 8 */ - int addr_size; /* Register 0x01a0, bit 7 */ - int mst_code; /* Register 0x01a0, bits 6 - 4 */ - int arb_en; /* Register 0x01a0, bit 1 */ - int speed; /* Register 0x01a0, bit 0 */ - int slave_addr; /* Register 0x01a8 */ - int write_size; /* Register 0x01a4, bits 10 - 8 */ - unsigned int *data; /* Register 0x01ac */ + titan_i2c_cmd_type type; /* Type of command */ + int num_arb; /* Register 0x01a0, bits 15 - 12 */ + int num_nak; /* Register 0x01a0, bits 11 - 8 */ + int addr_size; /* Register 0x01a0, bit 7 */ + int mst_code; /* Register 0x01a0, bits 6 - 4 */ + int arb_en; /* Register 0x01a0, bit 1 */ + int speed; /* Register 0x01a0, bit 0 */ + int slave_addr; /* Register 0x01a8 */ + int write_size; /* Register 0x01a4, bits 10 - 8 */ + unsigned int *data; /* Register 0x01ac */ } titan_i2c_command; -#endif /* __I2C_YOSEMITE_H */ +#endif /* __I2C_YOSEMITE_H */ diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S index a7caeec63be2..ebe2e64e275b 100644 --- a/arch/mips/pmc-sierra/yosemite/irq-handler.S +++ b/arch/mips/pmc-sierra/yosemite/irq-handler.S @@ -8,6 +8,10 @@ * 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. + * + * Titan supports Hypertransport or PCI but not both. Hence, one interrupt + * line is shared between the PCI slot A and Hypertransport. This is the + * Processor INTB #0. */ #include @@ -17,109 +21,90 @@ #include #include -/* - * IRQ router for the Titan board - */ - .align 5 NESTED(titan_handle_int, PT_SIZE, sp) SAVE_ALL CLI .set at + .set noreorder mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - - andi t1, t0, STATUSF_IP0 /* INTB0 hardware line */ + + andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ bnez t1, ll_pcia_irq /* 64-bit PCI */ - andi t1, t0, STATUSF_IP1 /* INTB1 hardware line */ + andi t1, t0, STATUSF_IP3 /* INTB1 hardware line */ bnez t1, ll_pcib_irq /* second 64-bit PCI slot */ - andi t1, t0, STATUSF_IP2 /* INTB2 hardware line */ + andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ bnez t1, ll_duart_irq /* UART */ - andi t1, t0, STATUSF_IP3 /* INTB3 hardware line*/ - bnez t1, ll_ht_smp_irq /* Hypertransport */ - andi t1, t0, STATUSF_IP5 /* INTB5 hardware line */ + andi t1, t0, STATUSF_IP5 /* SMP inter-core interrupts */ + bnez t1, ll_smp_irq + andi t1, t0, STATUSF_IP6 + bnez t1, ll_ht_irq /* Hypertransport */ + andi t1, t0, STATUSF_IP7 /* INTB5 hardware line */ bnez t1, ll_timer_irq /* Timer */ nop nop /* Extended interrupts */ - mfc0 t0, CPU_CAUSE - cfc0 t1, CP0_S1_INTCONTROL + mfc0 t0, CP0_CAUSE + cfc0 t1, CP0_S1_INTCONTROL - sll t2, t1, 8 - - and t0, t2 - srl t0, t0, 16 + sll t2, t1, 8 - - andi t1, t0, STATUSF_IP6 /* INTB6 hardware line */ - bnez t1, ll_phy0_irq /* Ethernet port 0 */ - andi t1, t0, STATUSF_IP7 /* INTB7 hardware line */ - bnez t1, ll_phy1_irq /* Ethernet port 1 */ - andi t1, t0, STATUSF_IP8 /* INTB8 hardware line */ - bnez t1, ll_phy2_irq /* Ethernet Port 2 */ - - nop - nop + and t0, t2 + srl t0, t0, 16 .set reorder - /* No handler */ j spurious_interrupt nop END(titan_handle_int) .align 5 -/* Individual Handlers */ - ll_pcia_irq: - li a0, 1 - move a2, sp + li a0, 2 + move a1, sp +#ifdef CONFIG_HYPERTRANSPORT + jal ll_ht_smp_irq_handler +#else jal do_IRQ +#endif j ret_from_irq ll_pcib_irq: - li a0, 2 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_duart_irq: li a0, 3 move a1, sp jal do_IRQ j ret_from_irq -ll_ht_irq: +ll_duart_irq: li a0, 4 move a1, sp - jal ll_ht_smp_irq_handler /* Detailed HT & SMP IRQ handling */ + jal do_IRQ j ret_from_irq -ll_timer_irq: +ll_smp_irq: li a0, 5 move a1, sp +#ifdef CONFIG_SMP + jal jaguar_mailbox_irq +#else jal do_IRQ +#endif j ret_from_irq -ll_phy0_irq: +ll_ht_irq: li a0, 6 move a1, sp - jal do_IRQ - j ret_from_irq - -ll_phy1_irq: - li a0, 7 - move a1, sp - jal do_IRQ + jal ll_ht_smp_irq_handler j ret_from_irq -ll_phy2_irq: - li a0, 8 +ll_timer_irq: + li a0, 7 move a1, sp jal do_IRQ j ret_from_irq diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c index 294290f8ae4c..e8b7ed63eaa0 100644 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ b/arch/mips/pmc-sierra/yosemite/irq.c @@ -41,207 +41,116 @@ #include #include #include +#include #include #include +#include /* Hypertransport specific */ -#define IRQ_STATUS_REG_CPU0 0xbb001b30 /* INT# 3 status register on CPU 0*/ -#define IRQ_STATUS_REG_CPU1 0xbb002b30 /* INT# 3 status register on CPU 1*/ -#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 0*/ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 1*/ +#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -#define HYPERTRANSPORT_EOI 0xbb0006E0 /* End of Interrupt */ -#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ -#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ -#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ -#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ - -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); - -static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) -{ - unsigned long status; - unsigned clr_mask; - unsigned set_mask; - - /* do the low 8 bits first */ - clr_mask = 0xff & clr_mask_in; - set_mask = 0xff & set_mask_in; - status = read_c0_status(); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8 | 0x0000FF00; - write_c0_status(status); - - /* do the high 8 bits */ - clr_mask = 0xff & (clr_mask_in >> 8); - set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); -} - -static inline void mask_irq(unsigned int irq) -{ - modify_cp0_intmask(irq, 0); -} - -static inline void unmask_irq(unsigned int irq) -{ - modify_cp0_intmask(0, irq); -} - -static void enable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - unmask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -static unsigned int startup_rm9000_irq(unsigned int irq) -{ - enable_rm9000_irq(irq); - - return 0; /* never anything pending */ -} - -static void disable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - mask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -#define shutdown_rm9000_irq disable_rm9000_irq - -static void mask_and_ack_rm9000_irq(unsigned int irq) -{ - mask_irq(1 << (irq-1)); -} - -static void end_rm9000_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_irq(1 << (irq-1)); -} - -static struct hw_interrupt_type rm9000_hpcdma_irq_type = { - "RM9000", - startup_rm9000_irq, - shutdown_rm9000_irq, - enable_rm9000_irq, - disable_rm9000_irq, - mask_and_ack_rm9000_irq, - end_rm9000_irq, - NULL -}; +#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ +#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ +#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ +#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ extern asmlinkage void titan_handle_int(void); extern void jaguar_mailbox_irq(struct pt_regs *); /* - * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. For interprocessor - * interrupts, the best thing to do is to use the INTMSG register. We use the same external - * interrupt line, i.e. INTB3 and monitor another status bit + * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. + * For interprocessor interrupts, the best thing to do is to use the INTMSG + * register. We use the same external interrupt line, i.e. INTB3 and monitor + * another status bit */ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) { - u32 status; - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0); + u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); /* Ack all the bits that correspond to the interrupt sources */ if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1); + status = OCD_READ(RM9000x2_OCD_INTP1STATUS4); if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); -#ifdef CONFIG_SMP - if (status == 0x2) { - /* This is an SMP IPI sent from one core to another */ - jaguar_mailbox_irq(regs); - goto done; - } -#endif - #ifdef CONFIG_HT_LEVEL_TRIGGER - /* - * Level Trigger Mode only. Send the HT EOI message back to the source. - */ - switch (status) { - case 0x1000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - break; - case 0x2000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - break; - case 0x4000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - break; - case 0x8000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - case 0x0000001: - /* PLX */ - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = 0x20; - *(volatile uint32_t *)(IRQ_CLEAR_REG) = IRQ_ACK_BITS; - break; - case 0xf000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - } + /* + * Level Trigger Mode only. Send the HT EOI message back to the source. + */ + switch (status) { + case 0x1000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + break; + case 0x2000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + break; + case 0x4000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + break; + case 0x8000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + case 0x0000001: + /* PLX */ + OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20); + OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS); + break; + case 0xf000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + } #endif /* CONFIG_HT_LEVEL_TRIGGER */ -done: - if (status != 0x2) - /* Not for SMP */ - do_IRQ(irq, regs); + do_IRQ(irq, regs); } +#ifdef CONFIG_KGDB +extern void init_second_port(void); +extern void breakpoint(void); +extern void set_debug_traps(void); +#endif + /* * Initialize the next level interrupt handler */ void __init init_IRQ(void) { - int i; - - clear_c0_status(ST0_IM | ST0_BEV); - __cli(); + clear_c0_status(ST0_IM); set_except_vector(0, titan_handle_int); init_generic_irq(); + mips_cpu_irq_init(0); + rm7k_cpu_irq_init(8); + +#ifdef CONFIG_KGDB + /* At this point, initialize the second serial port */ + init_second_port(); + printk("Start kgdb ... \n"); + set_debug_traps(); + breakpoint(); +#endif - for (i = 0; i < 13; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].handler = &rm9000_hpcdma_irq_type; - } +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif } +#ifdef CONFIG_KGDB +/* + * The 16550 DUART has two ports, but is allocated one IRQ + * for the serial console. Hence, a generic framework for + * serial IRQ routing in place. Currently, just calls the + * do_IRQ fuction. But, going in the future, need to check + * DUART registers for channel A and B, then decide the + * appropriate action + */ +asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs) +{ + do_IRQ(irq, regs); +} +#endif diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index 70f68b7c0552..5b4ef33acf22 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c @@ -7,55 +7,44 @@ * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) */ - +#include #include #include +#include +#include + #include #include #include #include #include -#include -#include #include +#include #include "setup.h" -/* Call Vectors */ -struct callvectors { - int (*open) (char*, int, int); - int (*close) (int); - int (*read) (int, void*, int); - int (*write) (int, void*, int); - off_t (*lseek) (int, off_t, int); - int (*printf) (const char*, ...); - void (*cacheflush) (void); - char* (*gets) (char*); -}; - -struct callvectors* debug_vectors; +struct callvectors *debug_vectors; extern unsigned long yosemite_base; extern unsigned long cpu_clock; -unsigned char titan_ge_mac_addr_base[6]; const char *get_system_type(void) { - return "PMC-Sierra Yosemite"; + return "PMC-Sierra Yosemite"; } -static void prom_cpu0_exit(void) +static void prom_cpu0_exit(void *arg) { - void *nvram = YOSEMITE_NVRAM_BASE_ADDR; - + void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR; + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); + writeb(0x84, nvram + 0xff7); - /* wait for the watchdog to go off */ - mdelay(100+(1000/16)); + /* wait for the watchdog to go off */ + mdelay(100 + (1000 / 16)); - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); } /* @@ -68,78 +57,73 @@ static void prom_exit(void) /* CPU 1 */ smp_call_function(prom_cpu0_exit, NULL, 1, 1); #endif - prom_cpu0_exit; -} - -/* - * Get the MAC address from the EEPROM using the I2C protocol - */ -void get_mac_address(char dest[6]) -{ - /* Use the I2C command code in the i2c-yosemite */ + prom_cpu0_exit(NULL); } /* - * Halt the system + * Halt the system */ static void prom_halt(void) { printk(KERN_NOTICE "\n** You can safely turn off the power\n"); while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); + __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); } /* * Init routine which accepts the variables from PMON */ -__init prom_init(int argc, char **arg, char **env, struct callvectors *cv) +void __init prom_init(void) { - int i = 0; + int argc = fw_arg0; + char **arg = (char **) fw_arg1; + char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; + int i = 0; /* Callbacks for halt, restart */ - _machine_restart = (void (*)(char *))prom_exit; + _machine_restart = (void (*)(char *)) prom_exit; _machine_halt = prom_halt; _machine_power_off = prom_halt; -#ifdef CONFIG_MIPS64 - - /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ - -#else /* CONFIG_MIPS64 */ +#ifdef CONFIG_MIPS32 debug_vectors = cv; arcs_cmdline[0] = '\0'; /* Get the boot parameters */ for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) - break; + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= + sizeof(arcs_cmdline)) + break; strcat(arcs_cmdline, arg[i]); strcat(arcs_cmdline, " "); } while (*env) { - if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) - yosemite_base = simple_strtol(*env + strlen("ocd_base="), - NULL, 16); - - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) - cpu_clock = simple_strtol(*env + strlen("cpuclock="), - NULL, 10); - + if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) + yosemite_base = + simple_strtol(*env + strlen("ocd_base="), NULL, + 16); + + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) + cpu_clock = + simple_strtol(*env + strlen("cpuclock="), NULL, + 10); + env++; } +#endif /* CONFIG_MIPS32 */ + +#ifdef CONFIG_MIPS64 + + /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ + #endif /* CONFIG_MIPS64 */ mips_machgroup = MACH_GROUP_TITAN; mips_machtype = MACH_TITAN_YOSEMITE; - - get_mac_address(titan_ge_mac_addr_base); - - debug_vectors->printf("Booting Linux kernel...\n"); } void __init prom_free_prom_memory(void) @@ -149,41 +133,3 @@ void __init prom_free_prom_memory(void) void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } - -extern void asmlinkage smp_bootstrap(void); - -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this - * can be hardcoded for now. - */ - return num_cpus; -} - -int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) -{ - /* Clear the semaphore */ - *(volatile uint32_t *)(0xbb000a68) = 0x80000000; - - return 1; -} - -void prom_init_secondary(void) -{ - clear_c0_config(CONF_CM_CMASK); - set_c0_config(0x2); - - clear_c0_status(ST0_IM); - set_c0_status(0x1ffff); -} - -void prom_smp_finish(void) -{ -} - diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c new file mode 100644 index 000000000000..22c336f9a596 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/py-console.c @@ -0,0 +1,130 @@ +/* + * 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, 2004 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* SUPERIO uart register map */ +struct yo_uartregs { + union { + volatile u8 rbr; /* read only, DLAB == 0 */ + volatile u8 thr; /* write only, DLAB == 0 */ + volatile u8 dll; /* DLAB == 1 */ + } u1; + union { + volatile u8 ier; /* DLAB == 0 */ + volatile u8 dlm; /* DLAB == 1 */ + } u2; + union { + volatile u8 iir; /* read only */ + volatile u8 fcr; /* write only */ + } u3; + volatile u8 iu_lcr; + volatile u8 iu_mcr; + volatile u8 iu_lsr; + volatile u8 iu_msr; + volatile u8 iu_scr; +} yo_uregs_t; + +#define iu_rbr u1.rbr +#define iu_thr u1.thr +#define iu_dll u1.dll +#define iu_ier u2.ier +#define iu_dlm u2.dlm +#define iu_iir u3.iir +#define iu_fcr u3.fcr + +extern unsigned long uart_base; + +#define IO_BASE_64 0x9000000000000000ULL + +static unsigned char readb_outer_space(unsigned long phys) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned char res; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%0) \n" + " lbu %0, (%0) \n" + " .set mips0 \n" + : "=r" (res) + : "0" (&vaddr)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + return res; +} + +static void writeb_outer_space(unsigned long phys, unsigned char c) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned long tmp; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%1) \n" + " sb %2, (%0) \n" + " .set mips0 \n" + : "=r" (tmp) + : "r" (&vaddr), "r" (c)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); +} + +static inline struct yo_uartregs *console_uart(void) +{ + return (struct yo_uartregs *) (uart_base + 8); +} + +void prom_putchar(char c) +{ + unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr); + unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr); + + while ((readb_outer_space(lsr) & 0x20) == 0); + writeb_outer_space(thr, c); +} + +char __init prom_getchar(void) +{ + return 0; +} diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 43795a8415df..dfa9cd0ed557 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c @@ -1,6 +1,4 @@ /* - * arch/mips/pmc-sierra/yosemite/setup.c - * * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) * @@ -24,19 +22,18 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include #include -#include #include +#include #include #include #include #include -#include #include -#include + #include #include #include @@ -46,36 +43,46 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include "setup.h" +unsigned char titan_ge_mac_addr_base[6] = { + 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 +}; + unsigned long cpu_clock; unsigned long yosemite_base; -void __init bus_error_init(void) -{ - /* Do nothing */ +void __init bus_error_init(void) +{ + /* Do nothing */ } unsigned long m48t37y_get_time(void) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; + //unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + unsigned char *rtc_base = (unsigned char *) 0xfc000000UL; + unsigned int year, month, day, hour, min, sec; +return; /* Stop the update to the time */ rtc_base[0x7ff8] = 0x40; - year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); - year += CONV_BCD_TO_BIN(rtc_base[0x7fff1]) * 100; + year = BCD2BIN(rtc_base[0x7fff]); + year += BCD2BIN(rtc_base[0x7fff1]) * 100; - month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); - day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); - hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); - min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); - sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + month = BCD2BIN(rtc_base[0x7ffe]); + day = BCD2BIN(rtc_base[0x7ffd]); + hour = BCD2BIN(rtc_base[0x7ffb]); + min = BCD2BIN(rtc_base[0x7ffa]); + sec = BCD2BIN(rtc_base[0x7ff9]); /* Start the update to the time again */ rtc_base[0x7ff8] = 0x00; @@ -85,83 +92,119 @@ unsigned long m48t37y_get_time(void) int m48t37y_set_time(unsigned long sec) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; - - struct rtc_time tm; + unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + struct rtc_time tm; +return; - /* convert to a more useful format -- note months count from 0 */ - to_tm(sec, &tm); - tm.tm_mon += 1; + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; - /* enable writing */ - rtc_base[0x7ff8] = 0x80; + /* enable writing */ + rtc_base[0x7ff8] = 0x80; - /* year */ - rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + /* year */ + rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); - /* month */ - rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + /* month */ + rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); - /* day */ - rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + /* day */ + rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); - /* hour/min/sec */ - rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); - rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); - rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + /* hour/min/sec */ + rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); + rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); + rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); - /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); - /* disable writing */ - rtc_base[0x7ff8] = 0x00; + /* disable writing */ + rtc_base[0x7ff8] = 0x00; - return 0; + return 0; } void yosemite_timer_setup(struct irqaction *irq) { - setup_irq(6, irq); + setup_irq(7, irq); } void yosemite_time_init(void) { - mips_counter_frequency = cpu_clock / 2; board_timer_setup = yosemite_timer_setup; + mips_hpt_frequency = cpu_clock / 2; rtc_get_time = m48t37y_get_time; rtc_set_time = m48t37y_set_time; } +unsigned long uart_base = 0xfd000000L; + +/* No other usable initialization hook than this ... */ +extern void (*late_time_init)(void); + +unsigned long ocd_base; + +EXPORT_SYMBOL(ocd_base); + +/* + * Common setup before any secondaries are started + */ + +#define TITAN_UART_CLK 3686400 +#define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) +#define TITAN_SERIAL_IRQ 4 +#define TITAN_SERIAL_BASE 0xfd000008UL + +static void __init py_map_ocd(void) +{ + struct uart_port up; + + /* + * Not specifically interrupt stuff but in case of SMP core_send_ipi + * needs this first so I'm mapping it here ... + */ + ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); + if (!ocd_base) + panic("Mapping OCD failed - game over. Your score is 0."); + + /* + * Register to interrupt zero because we share the interrupt with + * the serial driver which we don't properly support yet. + */ + memset(&up, 0, sizeof(up)); + up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); + up.irq = TITAN_SERIAL_IRQ; + up.uartclk = TITAN_UART_CLK; + up.regshift = 0; + up.iotype = UPIO_MEM; + up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + up.line = 0; + + if (early_serial_setup(&up)) + printk(KERN_ERR "Early serial init of port 0 failed\n"); +} + static int __init pmc_yosemite_setup(void) { - unsigned long val = 0; + extern void pmon_smp_bootstrap(void); - printk("PMC-Sierra Yosemite Board Setup \n"); board_time_init = yosemite_time_init; + late_time_init = py_map_ocd; /* Add memory regions */ add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); - add_memory_region(0x10000000, 0x10000000, BOOT_MEM_RAM); - - /* Setup the HT controller */ - val = *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG); - val |= HYPERTRANSPORT_ENABLE; - *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG) = val; - - /* Set the BAR. Shifted mode */ - *(volatile uint32_t *)(HYPERTRANSPORT_BAR0_REG) = HYPERTRANSPORT_BAR0_ADDR; - *(volatile uint32_t *)(HYPERTRANSPORT_SIZE0_REG) = HYPERTRANSPORT_SIZE0; -#ifdef CONFIG_PCI - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; +#if 0 /* XXX Crash ... */ + OCD_WRITE(RM9000x2_OCD_HTSC, + OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); - pci_scan_bus(0, &titan_pci_ops, NULL); + /* Set the BAR. Shifted mode */ + OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); + OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); #endif return 0; diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h index d8193e11b69f..b3e24b4e6c12 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.h +++ b/arch/mips/pmc-sierra/yosemite/setup.h @@ -9,27 +9,13 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ - #ifndef __SETUP_H__ #define __SETUP_H__ -/* Real Time Clock base */ -#define YOSEMITE_RTC_BASE -#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) -#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) - /* NVRAM Base */ #define YOSEMITE_NVRAM_BASE_ADDR 0xbb000678 /* XXX Need change */ #define YOSEMITE_RTC_BASE 0xbb000679 /* XXX Need change */ -/* - * Hypertransport Specific - */ -#define HYPERTRANSPORT_CONFIG_REG 0xbb000604 -#define HYPERTRANSPORT_BAR0_REG 0xbb000610 -#define HYPERTRANSPORT_SIZE0_REG 0xbb000688 -#define HYPERTRANSPORT_BAR0_ATTR_REG 0xbb000680 - #define HYPERTRANSPORT_BAR0_ADDR 0x00000006 #define HYPERTRANSPORT_SIZE0 0x0fffffff #define HYPERTRANSPORT_BAR0_ATTR 0x00002000 @@ -37,11 +23,9 @@ #define HYPERTRANSPORT_ENABLE 0x6 /* - * EEPROM Size + * EEPROM Size */ #define TITAN_ATMEL_24C32_SIZE 32768 #define TITAN_ATMEL_24C64_SIZE 65536 - #endif /* __SETUP_H__ */ - diff --git a/arch/mips/ramdisk/Makefile b/arch/mips/ramdisk/Makefile index 5c75968273f2..66cce75c5845 100644 --- a/arch/mips/ramdisk/Makefile +++ b/arch/mips/ramdisk/Makefile @@ -12,7 +12,7 @@ img := $(subst $(src)//,/,$(src)/$(img)) quiet_cmd_ramdisk = LD $@ define cmd_ramdisk - $(LD) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) + $(LD) $(LDFLAGS) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) endef $(obj)/ramdisk.o: $(img) $(src)/ld.script diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 352a8495cc23..fe7f546d3283 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,8 @@ void ip22_do_break(void) ArcEnterInteractiveMode(); } +EXPORT_SYMBOL(ip22_do_break); + extern void ip22_be_init(void) __init; extern void ip22_time_init(void) __init; diff --git a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c index 2601296e2773..3613999a189a 100644 --- a/arch/mips/vr41xx/common/bcu.c +++ b/arch/mips/vr41xx/common/bcu.c @@ -1,34 +1,23 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/bcu.c + * bcu.c, Bus Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Bus Control Unit routines for the NEC VR4100 series. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * 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. * - * Copyright 2002 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 */ /* * Changes: @@ -40,12 +29,16 @@ * - Added support for NEC VR4133. */ #include +#include #include #include #include #include +#define IO_MEM_RESOURCE_START 0UL +#define IO_MEM_RESOURCE_END 0x1fffffffUL + #define CLKSPEEDREG_TYPE1 KSEG1ADDR(0x0b000014) #define CLKSPEEDREG_TYPE2 KSEG1ADDR(0x0f000014) #define CLKSP(x) ((x) & 0x001f) @@ -213,7 +206,7 @@ static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pc return tclock; } -void __init vr41xx_bcu_init(void) +static int __init vr41xx_bcu_init(void) { unsigned long pclock; uint16_t clkspeed; @@ -223,4 +216,11 @@ void __init vr41xx_bcu_init(void) pclock = calculate_pclock(clkspeed); vr41xx_vtclock = calculate_vtclock(clkspeed, pclock); vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock); + + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + + return 0; } + +early_initcall(vr41xx_bcu_init); diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c index f3665b404aed..fd33d005f463 100644 --- a/arch/mips/vr41xx/common/cmu.c +++ b/arch/mips/vr41xx/common/cmu.c @@ -200,7 +200,7 @@ void vr41xx_mask_clock(vr41xx_clock_t clock) spin_unlock_irq(&cmu_lock); } -void __init vr41xx_cmu_init(void) +static int __init vr41xx_cmu_init(void) { switch (current_cpu_data.cputype) { case CPU_VR4111: @@ -223,4 +223,8 @@ void __init vr41xx_cmu_init(void) cmuclkmsk = read_cmuclkmsk(); spin_lock_init(&cmu_lock); + + return 0; } + +early_initcall(vr41xx_cmu_init); diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c index 6ee189968e8b..bd2978fd510b 100644 --- a/arch/mips/vr41xx/common/giu.c +++ b/arch/mips/vr41xx/common/giu.c @@ -28,10 +28,12 @@ * - Added support for NEC VR4133. * - Removed board_irq_init. */ +#include #include #include #include #include +#include #include #include @@ -64,6 +66,8 @@ static uint32_t giu_base; #define read_giuint(offset) readw(giu_base + (offset)) #define write_giuint(val, offset) writew((val), giu_base + (offset)) +#define GIUINT_HIGH_OFFSET 16 + static inline uint16_t set_giuint(uint8_t offset, uint16_t set) { uint16_t res; @@ -86,35 +90,121 @@ static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear) return res; } -void vr41xx_enable_giuint(int pin) +static unsigned int startup_giuint_low_irq(unsigned int irq) { - if (pin < 16) - set_giuint(GIUINTENL, (uint16_t)1 << pin); - else - set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + set_giuint(GIUINTENL, (uint16_t)1 << pin); + + return 0; } -void vr41xx_disable_giuint(int pin) +static void shutdown_giuint_low_irq(unsigned int irq) { - if (pin < 16) - clear_giuint(GIUINTENL, (uint16_t)1 << pin); - else - clear_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); } -void vr41xx_clear_giuint(int pin) +static void enable_giuint_low_irq(unsigned int irq) { - if (pin < 16) - write_giuint((uint16_t)1 << pin, GIUINTSTATL); - else - write_giuint((uint16_t)1 << (pin - 16), GIUINTSTATH); + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +#define disable_giuint_low_irq shutdown_giuint_low_irq + +static void ack_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); +} + +static void end_giuint_low_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +static struct hw_interrupt_type giuint_low_irq_type = { + .typename = "GIUINTL", + .startup = startup_giuint_low_irq, + .shutdown = shutdown_giuint_low_irq, + .enable = enable_giuint_low_irq, + .disable = disable_giuint_low_irq, + .ack = ack_giuint_low_irq, + .end = end_giuint_low_irq, +}; + +static unsigned int startup_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + set_giuint(GIUINTENH, (uint16_t)1 << pin); + + return 0; +} + +static void shutdown_giuint_high_irq(unsigned int irq) +{ + clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static void enable_giuint_high_irq(unsigned int irq) +{ + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +#define disable_giuint_high_irq shutdown_giuint_high_irq + +static void ack_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); +} + +static void end_giuint_high_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static struct hw_interrupt_type giuint_high_irq_type = { + .typename = "GIUINTH", + .startup = startup_giuint_high_irq, + .shutdown = shutdown_giuint_high_irq, + .enable = enable_giuint_high_irq, + .disable = disable_giuint_high_irq, + .ack = ack_giuint_high_irq, + .end = end_giuint_high_irq, +}; + +void __init init_vr41xx_giuint_irq(void) +{ + int i; + + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET)) + irq_desc[i].handler = &giuint_low_irq_type; + else + irq_desc[i].handler = &giuint_high_irq_type; + } + + setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade); } void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPL, mask); @@ -142,8 +232,9 @@ void vr41xx_set_irq_trigger(int pin, int trigger, int hold) clear_giuint(GIUINTTYPL, mask); clear_giuint(GIUINTHTSELL, mask); } + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPH, mask); if (hold == SIGNAL_HOLD) @@ -170,32 +261,35 @@ void vr41xx_set_irq_trigger(int pin, int trigger, int hold) clear_giuint(GIUINTTYPH, mask); clear_giuint(GIUINTHTSELH, mask); } + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_trigger); + void vr41xx_set_irq_level(int pin, int level) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (level == LEVEL_HIGH) set_giuint(GIUINTALSELL, mask); else clear_giuint(GIUINTALSELL, mask); + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (level == LEVEL_HIGH) set_giuint(GIUINTALSELH, mask); else clear_giuint(GIUINTALSELH, mask); + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_level); + #define GIUINT_NR_IRQS 32 enum { @@ -232,7 +326,7 @@ int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) giuint_cascade[pin].get_irq_number = get_irq_number; retval = setup_irq(irq, &giu_cascade); - if (retval) { + if (retval != 0) { giuint_cascade[pin].flag = GIUINT_NO_CASCADE; giuint_cascade[pin].get_irq_number = no_irq_number; } @@ -240,29 +334,89 @@ int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) return retval; } -unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) +EXPORT_SYMBOL(vr41xx_cascade_irq); + +static inline int get_irq_pin_number(void) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = read_giuint(GIUINTSTATL); + pendh = read_giuint(GIUINTSTATH); + maskl = read_giuint(GIUINTENL); + maskh = read_giuint(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & ((uint16_t)1 << i)) + return i; + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & ((uint16_t)1 << i)) + return i + GIUINT_HIGH_OFFSET; + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -1; +} + +static inline void ack_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) { + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + } else { + pin -= GIUINT_HIGH_OFFSET; + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + } +} + +static inline void end_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) + set_giuint(GIUINTENL, (uint16_t)1 << pin); + else + set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET)); +} + +void giuint_irq_dispatch(struct pt_regs *regs) { struct vr41xx_giuint_cascade *cascade; - unsigned int retval = 0; - int giuint_irq, cascade_irq; + unsigned int giuint_irq; + int pin; + + pin = get_irq_pin_number(); + if (pin < 0) + return; disable_irq(GIUINT_CASCADE_IRQ); + cascade = &giuint_cascade[pin]; giuint_irq = GIU_IRQ(pin); if (cascade->flag == GIUINT_CASCADE) { - cascade_irq = cascade->get_irq_number(giuint_irq); - disable_irq(giuint_irq); - if (cascade_irq > 0) - retval = do_IRQ(cascade_irq, regs); - enable_irq(giuint_irq); - } else - retval = do_IRQ(giuint_irq, regs); - enable_irq(GIUINT_CASCADE_IRQ); + int irq = cascade->get_irq_number(giuint_irq); + ack_giuint_irq(pin); + if (irq >= 0) + do_IRQ(irq, regs); + end_giuint_irq(pin); + } else { + do_IRQ(giuint_irq, regs); + } - return retval; + enable_irq(GIUINT_CASCADE_IRQ); } -void __init vr41xx_giuint_init(void) +static int __init vr41xx_giu_init(void) { int i; @@ -277,16 +431,20 @@ void __init vr41xx_giuint_init(void) giu_base = GIUIOSELL_TYPE2; break; default: - panic("GIU: Unexpected CPU of NEC VR4100 series"); - break; + printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; } for (i = 0; i < GIUINT_NR_IRQS; i++) { - vr41xx_disable_giuint(i); + if (i < GIUINT_HIGH_OFFSET) + clear_giuint(GIUINTENL, (uint16_t)1 << i); + else + clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET)); giuint_cascade[i].flag = GIUINT_NO_CASCADE; giuint_cascade[i].get_irq_number = no_irq_number; } - if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade)) - printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ); + return 0; } + +early_initcall(vr41xx_giu_init); diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 1f223d70e4e6..4fd195bc9ad2 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -28,10 +28,12 @@ * Yoichi Yuasa * - Coped with INTASSIGN of NEC VR4133. */ +#include #include #include #include #include +#include #include #include @@ -43,11 +45,8 @@ extern asmlinkage void vr41xx_handle_interrupt(void); -extern void vr41xx_giuint_init(void); -extern void vr41xx_enable_giuint(int pin); -extern void vr41xx_disable_giuint(int pin); -extern void vr41xx_clear_giuint(int pin); -extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); +extern void init_vr41xx_giuint_irq(void); +extern void giuint_irq_dispatch(struct pt_regs *regs); static uint32_t icu1_base; static uint32_t icu2_base; @@ -64,11 +63,17 @@ static unsigned char sysint2_assign[16] = { #define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0) #define SYSINT1REG 0x00 +#define PIUINTREG 0x02 #define INTASSIGN0 0x04 #define INTASSIGN1 0x06 #define GIUINTLREG 0x08 +#define DSIUINTREG 0x0a #define MSYSINT1REG 0x0c +#define MPIUINTREG 0x0e +#define MAIUINTREG 0x10 +#define MKIUINTREG 0x12 #define MGIUINTLREG 0x14 +#define MDSIUINTREG 0x16 #define NMIREG 0x18 #define SOFTREG 0x1a #define INTASSIGN2 0x1c @@ -76,11 +81,21 @@ static unsigned char sysint2_assign[16] = { #define SYSINT2REG 0x00 #define GIUINTHREG 0x02 +#define FIRINTREG 0x04 #define MSYSINT2REG 0x06 #define MGIUINTHREG 0x08 - -#define MDSIUINTREG KSEG1ADDR(0x0f000096) - #define INTDSIU 0x0800 +#define MFIRINTREG 0x0a +#define PCIINTREG 0x0c + #define PCIINT0 0x0001 +#define SCUINTREG 0x0e + #define SCUINT0 0x0001 +#define CSIINTREG 0x10 +#define MPCIINTREG 0x12 +#define MSCUINTREG 0x14 +#define MCSIINTREG 0x16 +#define BCUINTREG 0x18 + #define BCUINTR 0x0001 +#define MBCUINTREG 0x1a #define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */ #define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */ @@ -140,212 +155,298 @@ static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear) /*=======================================================================*/ -void vr41xx_enable_dsiuint(void) +void vr41xx_enable_piuint(uint16_t mask) { - writew(INTDSIU, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val |= mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -void vr41xx_disable_dsiuint(void) +void vr41xx_disable_piuint(uint16_t mask) { - writew(0, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val &= ~mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -/*=======================================================================*/ - -static void enable_sysint1_irq(unsigned int irq) +void vr41xx_enable_aiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val |= mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint1_irq(unsigned int irq) +void vr41xx_disable_aiuint(uint16_t mask) { - clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val &= ~mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint1_irq(unsigned int irq) +void vr41xx_enable_kiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); - - return 0; /* never anything pending */ + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val |= mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint1_irq disable_sysint1_irq -#define ack_sysint1_irq disable_sysint1_irq - -static void end_sysint1_irq(unsigned int irq) +void vr41xx_disable_kiuint(uint16_t mask) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val &= ~mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint1_irq_type = { - .typename = "SYSINT1", - .startup = startup_sysint1_irq, - .shutdown = shutdown_sysint1_irq, - .enable = enable_sysint1_irq, - .disable = disable_sysint1_irq, - .ack = ack_sysint1_irq, - .end = end_sysint1_irq, -}; +void vr41xx_enable_dsiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val |= mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -/*=======================================================================*/ +void vr41xx_disable_dsiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val &= ~mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_sysint2_irq(unsigned int irq) +void vr41xx_enable_firint(uint16_t mask) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val |= mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint2_irq(unsigned int irq) +void vr41xx_disable_firint(uint16_t mask) { - clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val &= ~mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint2_irq(unsigned int irq) +void vr41xx_enable_pciint(void) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; - return 0; /* never anything pending */ + spin_lock_irqsave(&desc->lock, flags); + write_icu2(PCIINT0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint2_irq disable_sysint2_irq -#define ack_sysint2_irq disable_sysint2_irq +void vr41xx_disable_pciint(void) +{ + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; -static void end_sysint2_irq(unsigned int irq) + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +void vr41xx_enable_scuint(void) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + write_icu2(SCUINT0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint2_irq_type = { - .typename = "SYSINT2", - .startup = startup_sysint2_irq, - .shutdown = shutdown_sysint2_irq, - .enable = enable_sysint2_irq, - .disable = disable_sysint2_irq, - .ack = ack_sysint2_irq, - .end = end_sysint2_irq, -}; +void vr41xx_disable_scuint(void) +{ + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; -/*=======================================================================*/ + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_giuint_irq(unsigned int irq) +void vr41xx_enable_csiint(uint16_t mask) { - int pin; + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val |= mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} - pin = GIU_IRQ_TO_PIN(irq); - if (pin < 16) - set_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); - vr41xx_enable_giuint(pin); +void vr41xx_disable_csiint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val &= ~mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_giuint_irq(unsigned int irq) +void vr41xx_enable_bcuint(void) { - int pin; + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - pin = GIU_IRQ_TO_PIN(irq); - vr41xx_disable_giuint(pin); - if (pin < 16) - clear_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(BCUINTR, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_giuint_irq(unsigned int irq) +void vr41xx_disable_bcuint(void) { - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - enable_giuint_irq(irq); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +/*=======================================================================*/ + +static unsigned int startup_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } -#define shutdown_giuint_irq disable_giuint_irq - -static void ack_giuint_irq(unsigned int irq) +static void shutdown_sysint1_irq(unsigned int irq) { - disable_giuint_irq(irq); + clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); +} - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); +static void enable_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static void end_giuint_irq(unsigned int irq) +#define disable_sysint1_irq shutdown_sysint1_irq +#define ack_sysint1_irq shutdown_sysint1_irq + +static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_giuint_irq(irq); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static struct hw_interrupt_type giuint_irq_type = { - .typename = "GIUINT", - .startup = startup_giuint_irq, - .shutdown = shutdown_giuint_irq, - .enable = enable_giuint_irq, - .disable = disable_giuint_irq, - .ack = ack_giuint_irq, - .end = end_giuint_irq, +static struct hw_interrupt_type sysint1_irq_type = { + .typename = "SYSINT1", + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, + .end = end_sysint1_irq, }; /*=======================================================================*/ -static struct irqaction icu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; - -static void __init vr41xx_icu_init(void) +static unsigned int startup_sysint2_irq(unsigned int irq) { - int i; - - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - icu1_base = SYSINT1REG_TYPE1; - icu2_base = SYSINT2REG_TYPE1; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - icu1_base = SYSINT1REG_TYPE2; - icu2_base = SYSINT2REG_TYPE2; - break; - default: - panic("Unexpected CPU of NEC VR4100 series"); - break; - } - - write_icu1(0, MSYSINT1REG); - write_icu1(0, MGIUINTLREG); - - write_icu2(0, MSYSINT2REG); - write_icu2(0, MGIUINTHREG); - - for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) - irq_desc[i].handler = &sysint1_irq_type; - else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) - irq_desc[i].handler = &sysint2_irq_type; - else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) - irq_desc[i].handler = &giuint_irq_type; - } + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); - setup_irq(INT0_CASCADE_IRQ, &icu_cascade); - setup_irq(INT1_CASCADE_IRQ, &icu_cascade); - setup_irq(INT2_CASCADE_IRQ, &icu_cascade); - setup_irq(INT3_CASCADE_IRQ, &icu_cascade); - setup_irq(INT4_CASCADE_IRQ, &icu_cascade); + return 0; /* never anything pending */ } -void __init init_IRQ(void) +static void shutdown_sysint2_irq(unsigned int irq) { - memset(irq_desc, 0, sizeof(irq_desc)); + clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - init_generic_irq(); - mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); - vr41xx_icu_init(); +static void enable_sysint2_irq(unsigned int irq) +{ + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - vr41xx_giuint_init(); +#define disable_sysint2_irq shutdown_sysint2_irq +#define ack_sysint2_irq shutdown_sysint2_irq - set_except_vector(0, vr41xx_handle_interrupt); +static void end_sysint2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } +static struct hw_interrupt_type sysint2_irq_type = { + .typename = "SYSINT2", + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, + .end = end_sysint2_irq, +}; + /*=======================================================================*/ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) @@ -492,34 +593,14 @@ int vr41xx_set_intassign(unsigned int irq, unsigned char intassign) return retval; } -/*=======================================================================*/ +EXPORT_SYMBOL(vr41xx_set_intassign); -static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh, - struct pt_regs *regs) -{ - int i; - - if (pendl) { - for (i = 0; i < 16; i++) { - if (pendl & ((uint16_t)1 << i)) { - giuint_do_IRQ(i, regs); - return; - } - } - } else { - for (i = 0; i < 16; i++) { - if (pendh & ((uint16_t)1 << i)) { - giuint_do_IRQ(i + 16, regs); - return; - } - } - } -} +/*=======================================================================*/ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) { - uint16_t pend1, pend2, pendl, pendh; - uint16_t mask1, mask2, maskl, maskh; + uint16_t pend1, pend2; + uint16_t mask1, mask2; int i; pend1 = read_icu1(SYSINT1REG); @@ -528,28 +609,18 @@ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) pend2 = read_icu2(SYSINT2REG); mask2 = read_icu2(MSYSINT2REG); - pendl = read_icu1(GIUINTLREG); - maskl = read_icu1(MGIUINTLREG); - - pendh = read_icu2(GIUINTHREG); - maskh = read_icu2(MGIUINTHREG); - mask1 &= pend1; mask2 &= pend2; - maskl &= pendl; - maskh &= pendh; if (mask1) { for (i = 0; i < 16; i++) { if (intnum == sysint1_assign[i] && (mask1 & ((uint16_t)1 << i))) { - if (i == 8 && (maskl | maskh)) { - giuint_irq_dispatch(maskl, maskh, regs); - return; - } else { + if (i == 8) + giuint_irq_dispatch(regs); + else do_IRQ(SYSINT1_IRQ(i), regs); - return; - } + return; } } } @@ -564,6 +635,72 @@ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) } } - printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh); + printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); + atomic_inc(&irq_err_count); } + +/*=======================================================================*/ + +static int __init vr41xx_icu_init(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + icu1_base = SYSINT1REG_TYPE1; + icu2_base = SYSINT2REG_TYPE1; + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + icu1_base = SYSINT1REG_TYPE2; + icu2_base = SYSINT2REG_TYPE2; + break; + default: + printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; + } + + write_icu1(0, MSYSINT1REG); + write_icu1(0xffff, MGIUINTLREG); + + write_icu2(0, MSYSINT2REG); + write_icu2(0xffff, MGIUINTHREG); + + return 0; +} + +early_initcall(vr41xx_icu_init); + +/*=======================================================================*/ + +static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; + +static inline void init_vr41xx_icu_irq(void) +{ + int i; + + for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) + irq_desc[i].handler = &sysint1_irq_type; + + for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) + irq_desc[i].handler = &sysint2_irq_type; + + setup_irq(INT0_CASCADE_IRQ, &icu_cascade); + setup_irq(INT1_CASCADE_IRQ, &icu_cascade); + setup_irq(INT2_CASCADE_IRQ, &icu_cascade); + setup_irq(INT3_CASCADE_IRQ, &icu_cascade); + setup_irq(INT4_CASCADE_IRQ, &icu_cascade); +} + +void __init init_IRQ(void) +{ + memset(irq_desc, 0, sizeof(irq_desc)); + + init_generic_irq(); + mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); + init_vr41xx_icu_irq(); + init_vr41xx_giuint_irq(); + + set_except_vector(0, vr41xx_handle_interrupt); +} diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c index 6590850b312f..ffc8e1c36b67 100644 --- a/arch/mips/vr41xx/common/init.c +++ b/arch/mips/vr41xx/common/init.c @@ -18,16 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include -#include - -extern void vr41xx_bcu_init(void); -extern void vr41xx_cmu_init(void); -extern void vr41xx_pmu_init(void); -extern void vr41xx_rtc_init(void); void __init prom_init(void) { @@ -42,14 +35,6 @@ void __init prom_init(void) if (i < (argc - 1)) strcat(arcs_cmdline, " "); } - - iomem_resource.start = IO_MEM_RESOURCE_START; - iomem_resource.end = IO_MEM_RESOURCE_END; - - vr41xx_bcu_init(); - vr41xx_cmu_init(); - vr41xx_pmu_init(); - vr41xx_rtc_init(); } unsigned long __init prom_free_prom_memory (void) diff --git a/arch/mips/vr41xx/common/ksyms.c b/arch/mips/vr41xx/common/ksyms.c index ea5231de0916..cfaa0ecd1786 100644 --- a/arch/mips/vr41xx/common/ksyms.c +++ b/arch/mips/vr41xx/common/ksyms.c @@ -25,8 +25,6 @@ EXPORT_SYMBOL(vr41xx_get_vtclock_frequency); EXPORT_SYMBOL(vr41xx_get_tclock_frequency); -EXPORT_SYMBOL(vr41xx_set_intassign); - EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle); EXPORT_SYMBOL(vr41xx_read_rtclong1_counter); EXPORT_SYMBOL(vr41xx_set_rtclong2_cycle); diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index 9b5a82e63442..3e1079dfb6c1 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c @@ -1,7 +1,7 @@ /* * pmu.c, Power Management Unit routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * 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 @@ -68,9 +68,13 @@ static void vr41xx_power_off(void) while (1) ; } -void __init vr41xx_pmu_init(void) +static int __init vr41xx_pmu_init(void) { _machine_restart = vr41xx_restart; _machine_halt = vr41xx_halt; _machine_power_off = vr41xx_power_off; + + return 0; } + +early_initcall(vr41xx_pmu_init); diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c index 6fa5fdc28f4b..07173afe1faf 100644 --- a/arch/mips/vr41xx/common/rtc.c +++ b/arch/mips/vr41xx/common/rtc.c @@ -1,7 +1,7 @@ /* * rtc.c, RTC(has only timer function) routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * 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 @@ -310,8 +310,12 @@ static void __init vr41xx_timer_setup(struct irqaction *irq) setup_irq(ELAPSEDTIME_IRQ, irq); } -void __init vr41xx_rtc_init(void) +static int __init vr41xx_rtc_init(void) { board_time_init = vr41xx_time_init; board_timer_setup = vr41xx_timer_setup; + + return 0; } + +early_initcall(vr41xx_rtc_init); diff --git a/arch/mips/vr41xx/common/serial.c b/arch/mips/vr41xx/common/serial.c index b052a9548f39..cc445eeff22e 100644 --- a/arch/mips/vr41xx/common/serial.c +++ b/arch/mips/vr41xx/common/serial.c @@ -168,7 +168,7 @@ void __init vr41xx_dsiu_init(void) if (port.membase != NULL) { if (early_serial_setup(&port) == 0) { vr41xx_supply_clock(DSIU_CLOCK); - vr41xx_enable_dsiuint(); + vr41xx_enable_dsiuint(DSIUINT_ALL); vr41xx_serial_ports++; return; } diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c index cce22c1594cf..3b006358c5c1 100644 --- a/arch/mips/vr41xx/common/vrc4173.c +++ b/arch/mips/vr41xx/common/vrc4173.c @@ -1,143 +1,336 @@ /* - * FILE NAME - * drivers/char/vrc4173.c - * - * BRIEF MODULE DESCRIPTION - * NEC VRC4173 driver for NEC VR4122/VR4131. + * vrc4173.c, NEC VRC4173 base driver for NEC VR4122/VR4131. * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Copyright 2001,2002 MontaVista Software Inc. + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 */ +#include #include #include #include #include #include +#include #include #include #include -MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_DESCRIPTION("NEC VRC4173 base driver for NEC VR4122/4131"); MODULE_AUTHOR("Yoichi Yuasa "); MODULE_LICENSE("GPL"); #define VRC4173_CMUCLKMSK 0x040 + #define MSKPIU 0x0001 + #define MSKKIU 0x0002 + #define MSKAIU 0x0004 + #define MSKPS2CH1 0x0008 + #define MSKPS2CH2 0x0010 + #define MSKUSB 0x0020 + #define MSKCARD1 0x0040 + #define MSKCARD2 0x0080 + #define MSKAC97 0x0100 + #define MSK48MUSB 0x0400 + #define MSK48MPIN 0x0800 + #define MSK48MOSC 0x1000 #define VRC4173_CMUSRST 0x042 - -#define VRC4173_SELECTREG 0x09e + #define USBRST 0x0001 + #define CARD1RST 0x0002 + #define CARD2RST 0x0004 + #define AC97RST 0x0008 #define VRC4173_SYSINT1REG 0x060 #define VRC4173_MSYSINT1REG 0x06c -static struct pci_device_id vrc4173_table[] = { - {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0, } +#define VRC4173_SELECTREG 0x09e + #define SEL3 0x0008 + #define SEL2 0x0004 + #define SEL1 0x0002 + #define SEL0 0x0001 + +static struct pci_device_id vrc4173_id_table[] __devinitdata = { + { .vendor = PCI_VENDOR_ID_NEC, + .device = PCI_DEVICE_ID_NEC_VRC4173, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, + { .vendor = 0, }, }; unsigned long vrc4173_io_offset = 0; EXPORT_SYMBOL(vrc4173_io_offset); -static u16 vrc4173_cmuclkmsk; static int vrc4173_initialized; +static uint16_t vrc4173_cmuclkmsk; +static uint16_t vrc4173_selectreg; +static spinlock_t vrc4173_cmu_lock; +static spinlock_t vrc4173_giu_lock; -void vrc4173_clock_supply(u16 mask) +static inline void set_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst |= val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +static inline void clear_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst &= ~val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +void vrc4173_supply_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk |= mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk |= MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk |= MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk |= MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk |= MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk |= MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk |= MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + if (vrc4173_cmuclkmsk & MSK48MOSC) + vrc4173_cmuclkmsk |= MSK48MPIN; + else + printk(KERN_WARNING + "vrc4173_supply_clock: " + "Please supply VRC4173_48MHz_CLOCK first " + "rather than VRC4173_EXT_48MHz_CLOCK.\n"); + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk |= MSK48MOSC; + break; + default: + printk(KERN_WARNING + "vrc4173_supply_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } -void vrc4173_clock_mask(u16 mask) +EXPORT_SYMBOL(vrc4173_supply_clock); + +void vrc4173_mask_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk &= ~mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk &= ~MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk &= ~MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk &= ~MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MPIN; + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MOSC; + break; + default: + printk(KERN_WARNING "vrc4173_mask_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } +EXPORT_SYMBOL(vrc4173_mask_clock); + static inline void vrc4173_cmu_init(void) { vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); -} -EXPORT_SYMBOL(vrc4173_clock_supply); -EXPORT_SYMBOL(vrc4173_clock_mask); + spin_lock_init(&vrc4173_cmu_lock); +} -void vrc4173_select_function(int func) +void vrc4173_select_function(vrc4173_function_t function) { - u16 val; - if (vrc4173_initialized) { - val = vrc4173_inw(VRC4173_SELECTREG); - switch(func) { - case PS2CH1_SELECT: - val |= 0x0004; + spin_lock_irq(&vrc4173_giu_lock); + + switch(function) { + case PS2_CHANNEL1: + vrc4173_selectreg |= SEL2; break; - case PS2CH2_SELECT: - val |= 0x0002; + case PS2_CHANNEL2: + vrc4173_selectreg |= SEL1; break; - case TOUCHPANEL_SELECT: - val &= 0x0007; + case TOUCHPANEL: + vrc4173_selectreg &= SEL2 | SEL1 | SEL0; break; - case KIU8_SELECT: - val &= 0x000e; + case KEYBOARD_8SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2 | SEL1; break; - case KIU10_SELECT: - val &= 0x000c; + case KEYBOARD_10SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2; break; - case KIU12_SELECT: - val &= 0x0008; + case KEYBOARD_12SCANLINES: + vrc4173_selectreg &= SEL3; break; - case GPIO_SELECT: - val |= 0x0008; + case GPIO_0_15PINS: + vrc4173_selectreg |= SEL0; + break; + case GPIO_16_20PINS: + vrc4173_selectreg |= SEL3; break; } - vrc4173_outw(val, VRC4173_SELECTREG); + + vrc4173_outw(vrc4173_selectreg, VRC4173_SELECTREG); + + spin_unlock_irq(&vrc4173_giu_lock); } } EXPORT_SYMBOL(vrc4173_select_function); +static inline void vrc4173_giu_init(void) +{ + vrc4173_selectreg = vrc4173_inw(VRC4173_SELECTREG); + + spin_lock_init(&vrc4173_giu_lock); +} + static void enable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + val |= (uint16_t)1 << (irq - VRC4173_IRQ_BASE); vrc4173_outw(val, VRC4173_MSYSINT1REG); } static void disable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + val &= ~((uint16_t)1 << (irq - VRC4173_IRQ_BASE)); vrc4173_outw(val, VRC4173_MSYSINT1REG); } @@ -157,19 +350,18 @@ static void end_vrc4173_irq(unsigned int irq) } static struct hw_interrupt_type vrc4173_irq_type = { - "VRC4173", - startup_vrc4173_irq, - shutdown_vrc4173_irq, - enable_vrc4173_irq, - disable_vrc4173_irq, - ack_vrc4173_irq, - end_vrc4173_irq, - NULL + .typename = "VRC4173", + .startup = startup_vrc4173_irq, + .shutdown = shutdown_vrc4173_irq, + .enable = enable_vrc4173_irq, + .disable = disable_vrc4173_irq, + .ack = ack_vrc4173_irq, + .end = end_vrc4173_irq, }; static int vrc4173_get_irq_number(int irq) { - u16 status, mask; + uint16_t status, mask; int i; status = vrc4173_inw(VRC4173_SYSINT1REG); @@ -179,18 +371,18 @@ static int vrc4173_get_irq_number(int irq) if (status) { for (i = 0; i < 16; i++) if (status & (0x0001 << i)) - return VRC4173_IRQ_BASE + i; + return VRC4173_IRQ(i); } return -EINVAL; } -static inline void vrc4173_icu_init(int cascade_irq) +static inline int vrc4173_icu_init(int cascade_irq) { int i; if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) - return; + return -EINVAL; vrc4173_outw(0, VRC4173_MSYSINT1REG); @@ -199,33 +391,38 @@ static inline void vrc4173_icu_init(int cascade_irq) for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) irq_desc[i].handler = &vrc4173_irq_type; + + return 0; } -static int __devinit vrc4173_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit vrc4173_probe(struct pci_dev *dev, + const struct pci_device_id *id) { unsigned long start, flags; int err; - if ((err = pci_enable_device(pdev)) < 0) { - printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + err = pci_enable_device(dev); + if (err < 0) { + printk(KERN_ERR "vrc4173: Failed to enable PCI device, aborting\n"); return err; } - pci_set_master(pdev); + pci_set_master(dev); - start = pci_resource_start(pdev, 0); - if (!start) { - printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); - return -ENODEV; + start = pci_resource_start(dev, 0); + if (start == 0) { + printk(KERN_ERR "vrc4173:No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { - printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); - return -ENODEV; + flags = pci_resource_flags(dev, 0); + if ((flags & IORESOURCE_IO) == 0) { + printk(KERN_ERR "vrc4173: No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + err = pci_request_regions(dev, "NEC VRC4173"); + if (err < 0) { printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); return err; } @@ -233,33 +430,46 @@ static int __devinit vrc4173_probe(struct pci_dev *pdev, set_vrc4173_io_offset(start); vrc4173_cmu_init(); + vrc4173_giu_init(); - vrc4173_icu_init(pdev->irq); + err = vrc4173_icu_init(dev->irq); + if (err < 0) { + printk(KERN_ERR "vrc4173: Invalid IRQ %d, aborting\n", dev->irq); + return err; + } - if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { - printk(KERN_ERR - "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + err = vr41xx_cascade_irq(dev->irq, vrc4173_get_irq_number); + if (err < 0) { + printk(KERN_ERR "vrc4173: IRQ resource %d is busy, aborting\n", dev->irq); return err; } printk(KERN_INFO - "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, dev->irq); return 0; } +static void vrc4173_remove(struct pci_dev *dev) +{ + free_irq(dev->irq, NULL); + + pci_release_regions(dev); +} + static struct pci_driver vrc4173_driver = { .name = "NEC VRC4173", .probe = vrc4173_probe, - .remove = NULL, - .id_table = vrc4173_table, + .remove = vrc4173_remove, + .id_table = vrc4173_id_table, }; static int __devinit vrc4173_init(void) { int err; - if ((err = pci_module_init(&vrc4173_driver)) < 0) + err = pci_module_init(&vrc4173_driver); + if (err < 0) return err; vrc4173_initialized = 1; diff --git a/arch/mips/vr41xx/tanbac-tb0226/setup.c b/arch/mips/vr41xx/tanbac-tb0226/setup.c index 995a578e25f6..752c0e736920 100644 --- a/arch/mips/vr41xx/tanbac-tb0226/setup.c +++ b/arch/mips/vr41xx/tanbac-tb0226/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START, -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -79,19 +28,11 @@ const char *get_system_type(void) static int tanbac_tb0226_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/arch/mips/vr41xx/tanbac-tb0229/Makefile b/arch/mips/vr41xx/tanbac-tb0229/Makefile index ff7429e8174a..dd085394a876 100644 --- a/arch/mips/vr41xx/tanbac-tb0229/Makefile +++ b/arch/mips/vr41xx/tanbac-tb0229/Makefile @@ -4,4 +4,4 @@ obj-y := setup.o -obj-$(CONFIG_TANBAC_TB0219) += reboot.o +obj-$(CONFIG_TANBAC_TB0219) += tb0219.o diff --git a/arch/mips/vr41xx/tanbac-tb0229/reboot.c b/arch/mips/vr41xx/tanbac-tb0229/reboot.c deleted file mode 100644 index 02e837879b1c..000000000000 --- a/arch/mips/vr41xx/tanbac-tb0229/reboot.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/reboot.c - * - * BRIEF MODULE DESCRIPTION - * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * 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. - */ -#include -#include -#include - -#define tb0229_hard_reset() writew(0, TB0219_RESET_REGS) - -void tanbac_tb0229_restart(char *command) -{ - local_irq_disable(); - tb0229_hard_reset(); - while (1); -} diff --git a/arch/mips/vr41xx/tanbac-tb0229/setup.c b/arch/mips/vr41xx/tanbac-tb0229/setup.c index 971473e617a8..9209e3dc6db6 100644 --- a/arch/mips/vr41xx/tanbac-tb0229/setup.c +++ b/arch/mips/vr41xx/tanbac-tb0229/setup.c @@ -21,60 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -83,24 +31,12 @@ const char *get_system_type(void) static int tanbac_tb0229_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - -#ifdef CONFIG_TANBAC_TB0219 - _machine_restart = tanbac_tb0229_restart; -#endif - return 0; } diff --git a/arch/mips/vr41xx/tanbac-tb0229/tb0219.c b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c new file mode 100644 index 000000000000..a07d9fa454ab --- /dev/null +++ b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c @@ -0,0 +1,44 @@ +/* + * tb0219.c, Setup for the TANBAC TB0219 + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +#include + +#include +#include + +#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) + +#define tb0219_hard_reset() writew(0, TB0219_RESET_REGS) + +static void tanbac_tb0219_restart(char *command) +{ + local_irq_disable(); + tb0219_hard_reset(); + while (1); +} + +static int __init tanbac_tb0219_setup(void) +{ + _machine_restart = tanbac_tb0219_restart; + + return 0; +} + +early_initcall(tanbac_tb0219_setup); diff --git a/arch/mips/vr41xx/victor-mpc30x/setup.c b/arch/mips/vr41xx/victor-mpc30x/setup.c index 5fc2084962c4..169ac00a1531 100644 --- a/arch/mips/vr41xx/victor-mpc30x/setup.c +++ b/arch/mips/vr41xx/victor-mpc30x/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,19 +28,11 @@ const char *get_system_type(void) static int victor_mpc30x_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/arch/mips/vr41xx/zao-capcella/setup.c b/arch/mips/vr41xx/zao-capcella/setup.c index 8b1e178ae9df..35b3a0a92f3d 100644 --- a/arch/mips/vr41xx/zao-capcella/setup.c +++ b/arch/mips/vr41xx/zao-capcella/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,20 +28,12 @@ const char *get_system_type(void) static int zao_capcella_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index c70f00d83364..37a460aa0378 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h @@ -9,6 +9,7 @@ #define _ASM_ASMMACRO_H #include +#include #ifdef CONFIG_MIPS32 #include @@ -21,6 +22,7 @@ mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 mtc0 \reg, CP0_STATUS + irq_enable_hazard .endm .macro local_irq_disable reg=t0 @@ -28,7 +30,7 @@ ori \reg, \reg, 1 xori \reg, \reg, 1 mtc0 \reg, CP0_STATUS - SSNOP; SSNOP; SSNOP + irq_disable_hazard .endm #ifdef CONFIG_CPU_SB1 diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 1262c6eafb95..c8c6a5a8c5aa 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -9,7 +9,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 97, 99, 2000, 03 by Ralf Baechle + * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle */ /* @@ -127,6 +127,32 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) return result; } +/* + * atomic_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + "1: ll %1, %2 # atomic_sub_if_positive\n" + " subu %0, %1, %3 \n" + " bltz %0, 1f \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + " sync \n" + "1: \n" + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); + + return result; +} + #else /* @@ -192,6 +218,28 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) return temp; } +/* + * atomic_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +{ + unsigned long flags; + int temp; + + spin_lock_irqsave(&atomic_lock, flags); + temp = v->counter; + temp -= i; + if (temp >= 0) + v->counter = temp; + spin_unlock_irqrestore(&atomic_lock, flags); + + return temp; +} + #endif /* CONFIG_CPU_HAS_LLSC */ #define atomic_dec_return(v) atomic_sub_return(1,(v)) @@ -228,6 +276,12 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) */ #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +/* + * atomic_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic_t + */ +#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) + /* * atomic_inc - increment atomic variable * @v: pointer of type atomic_t @@ -284,7 +338,7 @@ typedef struct { volatile __s64 counter; } atomic64_t; * * Atomically adds @i to @v. */ -static __inline__ void atomic64_add(int i, atomic64_t * v) +static __inline__ void atomic64_add(long i, atomic64_t * v) { unsigned long temp; @@ -304,7 +358,7 @@ static __inline__ void atomic64_add(int i, atomic64_t * v) * * Atomically subtracts @i from @v. */ -static __inline__ void atomic64_sub(int i, atomic64_t * v) +static __inline__ void atomic64_sub(long i, atomic64_t * v) { unsigned long temp; @@ -320,7 +374,7 @@ static __inline__ void atomic64_sub(int i, atomic64_t * v) /* * Same as above, but return the result value */ -static __inline__ int atomic64_add_return(int i, atomic64_t * v) +static __inline__ long atomic64_add_return(long i, atomic64_t * v) { unsigned long temp, result; @@ -338,7 +392,7 @@ static __inline__ int atomic64_add_return(int i, atomic64_t * v) return result; } -static __inline__ int atomic64_sub_return(int i, atomic64_t * v) +static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { unsigned long temp, result; @@ -356,6 +410,32 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) return result; } +/* + * atomic64_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic64_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + "1: lld %1, %2 # atomic64_sub_if_positive\n" + " dsubu %0, %1, %3 \n" + " bltz %0, 1f \n" + " scd %0, %2 \n" + " beqz %0, 1b \n" + " sync \n" + "1: \n" + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); + + return result; +} + #else /* @@ -368,7 +448,7 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) * * Atomically adds @i to @v. */ -static __inline__ void atomic64_add(int i, atomic64_t * v) +static __inline__ void atomic64_add(long i, atomic64_t * v) { unsigned long flags; @@ -384,7 +464,7 @@ static __inline__ void atomic64_add(int i, atomic64_t * v) * * Atomically subtracts @i from @v. */ -static __inline__ void atomic64_sub(int i, atomic64_t * v) +static __inline__ void atomic64_sub(long i, atomic64_t * v) { unsigned long flags; @@ -393,10 +473,10 @@ static __inline__ void atomic64_sub(int i, atomic64_t * v) spin_unlock_irqrestore(&atomic_lock, flags); } -static __inline__ int atomic64_add_return(int i, atomic64_t * v) +static __inline__ long atomic64_add_return(long i, atomic64_t * v) { unsigned long flags; - int temp; + long temp; spin_lock_irqsave(&atomic_lock, flags); temp = v->counter; @@ -407,10 +487,10 @@ static __inline__ int atomic64_add_return(int i, atomic64_t * v) return temp; } -static __inline__ int atomic64_sub_return(int i, atomic64_t * v) +static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { unsigned long flags; - int temp; + long temp; spin_lock_irqsave(&atomic_lock, flags); temp = v->counter; @@ -421,6 +501,28 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) return temp; } +/* + * atomic64_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic64_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +{ + unsigned long flags; + long temp; + + spin_lock_irqsave(&atomic_lock, flags); + temp = v->counter; + temp -= i; + if (temp >= 0) + v->counter = temp; + spin_unlock_irqrestore(&atomic_lock, flags); + + return temp; +} + #endif /* CONFIG_CPU_HAS_LLDSCD */ #define atomic64_dec_return(v) atomic64_sub_return(1,(v)) @@ -457,6 +559,12 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) */ #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0) +/* + * atomic64_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic64_t + */ +#define atomic64_dec_if_positive(v) atomic64_sub_if_positive(1, v) + /* * atomic64_inc - increment atomic variable * @v: pointer of type atomic64_t diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h index fda57132db2c..4517bdf20953 100644 --- a/include/asm-mips/cache.h +++ b/include/asm-mips/cache.h @@ -18,4 +18,6 @@ #define SMP_CACHE_SHIFT L1_CACHE_SHIFT #define SMP_CACHE_BYTES L1_CACHE_BYTES +#define ARCH_KMALLOC_MINALIGN 8 + #endif /* _ASM_CACHE_H */ diff --git a/include/asm-mips/gt64240.h b/include/asm-mips/gt64240.h new file mode 100644 index 000000000000..12964c2c3e34 --- /dev/null +++ b/include/asm-mips/gt64240.h @@ -0,0 +1,1264 @@ +/* + * 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 - Galileo technology. + * Copyright (C) 2004 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MV64240_H +#define __ASM_MIPS_MV64240_H + +#include +#include + +/* + * CPU Control Registers + */ + +#define CPU_CONFIGURATION 0x000 +#define CPU_MODE 0x120 +#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 +#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 + +/* + * Processor Address Space + */ + +/* Sdram's BAR'S */ +#define SCS_0_LOW_DECODE_ADDRESS 0x008 +#define SCS_0_HIGH_DECODE_ADDRESS 0x010 +#define SCS_1_LOW_DECODE_ADDRESS 0x208 +#define SCS_1_HIGH_DECODE_ADDRESS 0x210 +#define SCS_2_LOW_DECODE_ADDRESS 0x018 +#define SCS_2_HIGH_DECODE_ADDRESS 0x020 +#define SCS_3_LOW_DECODE_ADDRESS 0x218 +#define SCS_3_HIGH_DECODE_ADDRESS 0x220 +/* Devices BAR'S */ +#define CS_0_LOW_DECODE_ADDRESS 0x028 +#define CS_0_HIGH_DECODE_ADDRESS 0x030 +#define CS_1_LOW_DECODE_ADDRESS 0x228 +#define CS_1_HIGH_DECODE_ADDRESS 0x230 +#define CS_2_LOW_DECODE_ADDRESS 0x248 +#define CS_2_HIGH_DECODE_ADDRESS 0x250 +#define CS_3_LOW_DECODE_ADDRESS 0x038 +#define CS_3_HIGH_DECODE_ADDRESS 0x040 +#define BOOTCS_LOW_DECODE_ADDRESS 0x238 +#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 + +#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 +#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 +#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 +#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 +#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 +#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 +#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 +#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 +#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 +#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 + +#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 +#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 +#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 +#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 +#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 +#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 +#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 +#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 +#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 +#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 + +#define INTERNAL_SPACE_DECODE 0x068 + +#define CPU_0_LOW_DECODE_ADDRESS 0x290 +#define CPU_0_HIGH_DECODE_ADDRESS 0x298 +#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 +#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 + +#define PCI_0I_O_ADDRESS_REMAP 0x0f0 +#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 +#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 +#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 +#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 +#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 +#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 +#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 +#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 + +#define PCI_1I_O_ADDRESS_REMAP 0x108 +#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 +#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 +#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 +#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 +#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 +#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 +#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 +#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 + +/* + * CPU Sync Barrier + */ + +#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 +#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 + + +/* + * CPU Access Protect + */ + +#define CPU_LOW_PROTECT_ADDRESS_0 0X180 +#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 +#define CPU_LOW_PROTECT_ADDRESS_1 0X190 +#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 +#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 +#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 +#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 +#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 +#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 +#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 +#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 +#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 +#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 +#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 +#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 +#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 + + +/* + * Snoop Control + */ + +#define SNOOP_BASE_ADDRESS_0 0x380 +#define SNOOP_TOP_ADDRESS_0 0x388 +#define SNOOP_BASE_ADDRESS_1 0x390 +#define SNOOP_TOP_ADDRESS_1 0x398 +#define SNOOP_BASE_ADDRESS_2 0x3a0 +#define SNOOP_TOP_ADDRESS_2 0x3a8 +#define SNOOP_BASE_ADDRESS_3 0x3b0 +#define SNOOP_TOP_ADDRESS_3 0x3b8 + +/* + * CPU Error Report + */ + +#define CPU_ERROR_ADDRESS_LOW 0x070 +#define CPU_ERROR_ADDRESS_HIGH 0x078 +#define CPU_ERROR_DATA_LOW 0x128 +#define CPU_ERROR_DATA_HIGH 0x130 +#define CPU_ERROR_PARITY 0x138 +#define CPU_ERROR_CAUSE 0x140 +#define CPU_ERROR_MASK 0x148 + +/* + * Pslave Debug + */ + +#define X_0_ADDRESS 0x360 +#define X_0_COMMAND_ID 0x368 +#define X_1_ADDRESS 0x370 +#define X_1_COMMAND_ID 0x378 +#define WRITE_DATA_LOW 0x3c0 +#define WRITE_DATA_HIGH 0x3c8 +#define WRITE_BYTE_ENABLE 0X3e0 +#define READ_DATA_LOW 0x3d0 +#define READ_DATA_HIGH 0x3d8 +#define READ_ID 0x3e8 + + +/* + * SDRAM and Device Address Space + */ + + +/* + * SDRAM Configuration + */ + +#define SDRAM_CONFIGURATION 0x448 +#define SDRAM_OPERATION_MODE 0x474 +#define SDRAM_ADDRESS_DECODE 0x47C +#define SDRAM_TIMING_PARAMETERS 0x4b4 +#define SDRAM_UMA_CONTROL 0x4a4 +#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 +#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac +#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 + + +/* + * SDRAM Parameters + */ + +#define SDRAM_BANK0PARAMETERS 0x44C +#define SDRAM_BANK1PARAMETERS 0x450 +#define SDRAM_BANK2PARAMETERS 0x454 +#define SDRAM_BANK3PARAMETERS 0x458 + + +/* + * SDRAM Error Report + */ + +#define SDRAM_ERROR_DATA_LOW 0x484 +#define SDRAM_ERROR_DATA_HIGH 0x480 +#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 +#define SDRAM_RECEIVED_ECC 0x488 +#define SDRAM_CALCULATED_ECC 0x48c +#define SDRAM_ECC_CONTROL 0x494 +#define SDRAM_ECC_ERROR_COUNTER 0x498 + + +/* + * SDunit Debug (for internal use) + */ + +#define X0_ADDRESS 0x500 +#define X0_COMMAND_AND_ID 0x504 +#define X0_WRITE_DATA_LOW 0x508 +#define X0_WRITE_DATA_HIGH 0x50c +#define X0_WRITE_BYTE_ENABLE 0x518 +#define X0_READ_DATA_LOW 0x510 +#define X0_READ_DATA_HIGH 0x514 +#define X0_READ_ID 0x51c +#define X1_ADDRESS 0x520 +#define X1_COMMAND_AND_ID 0x524 +#define X1_WRITE_DATA_LOW 0x528 +#define X1_WRITE_DATA_HIGH 0x52c +#define X1_WRITE_BYTE_ENABLE 0x538 +#define X1_READ_DATA_LOW 0x530 +#define X1_READ_DATA_HIGH 0x534 +#define X1_READ_ID 0x53c +#define X0_SNOOP_ADDRESS 0x540 +#define X0_SNOOP_COMMAND 0x544 +#define X1_SNOOP_ADDRESS 0x548 +#define X1_SNOOP_COMMAND 0x54c + + +/* + * Device Parameters + */ + +#define DEVICE_BANK0PARAMETERS 0x45c +#define DEVICE_BANK1PARAMETERS 0x460 +#define DEVICE_BANK2PARAMETERS 0x464 +#define DEVICE_BANK3PARAMETERS 0x468 +#define DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define DEVICE_CONTROL 0x4c0 +#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 + + +/* + * Device Interrupt + */ + +#define DEVICE_INTERRUPT_CAUSE 0x4d0 +#define DEVICE_INTERRUPT_MASK 0x4d4 +#define DEVICE_ERROR_ADDRESS 0x4d8 + +/* + * DMA Record + */ + +#define CHANNEL0_DMA_BYTE_COUNT 0x800 +#define CHANNEL1_DMA_BYTE_COUNT 0x804 +#define CHANNEL2_DMA_BYTE_COUNT 0x808 +#define CHANNEL3_DMA_BYTE_COUNT 0x80C +#define CHANNEL4_DMA_BYTE_COUNT 0x900 +#define CHANNEL5_DMA_BYTE_COUNT 0x904 +#define CHANNEL6_DMA_BYTE_COUNT 0x908 +#define CHANNEL7_DMA_BYTE_COUNT 0x90C +#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 +#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 +#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 +#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C +#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 +#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 +#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 +#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C +#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 +#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 +#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 +#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C +#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 +#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 +#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 +#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C +#define CHANNEL0NEXT_RECORD_POINTER 0x830 +#define CHANNEL1NEXT_RECORD_POINTER 0x834 +#define CHANNEL2NEXT_RECORD_POINTER 0x838 +#define CHANNEL3NEXT_RECORD_POINTER 0x83C +#define CHANNEL4NEXT_RECORD_POINTER 0x930 +#define CHANNEL5NEXT_RECORD_POINTER 0x934 +#define CHANNEL6NEXT_RECORD_POINTER 0x938 +#define CHANNEL7NEXT_RECORD_POINTER 0x93C +#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 +#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 +#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 +#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C +#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 +#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 +#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 +#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C +#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 +#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 +#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 +#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c +#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 +#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 +#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 +#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c +#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 +#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 +#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 +#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac +#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 +#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 +#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 +#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac +#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 +#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 +#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 +#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc +#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 +#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 +#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 +#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc + +/* + * DMA Channel Control + */ + +#define CHANNEL0CONTROL 0x840 +#define CHANNEL0CONTROL_HIGH 0x880 + +#define CHANNEL1CONTROL 0x844 +#define CHANNEL1CONTROL_HIGH 0x884 + +#define CHANNEL2CONTROL 0x848 +#define CHANNEL2CONTROL_HIGH 0x888 + +#define CHANNEL3CONTROL 0x84C +#define CHANNEL3CONTROL_HIGH 0x88C + +#define CHANNEL4CONTROL 0x940 +#define CHANNEL4CONTROL_HIGH 0x980 + +#define CHANNEL5CONTROL 0x944 +#define CHANNEL5CONTROL_HIGH 0x984 + +#define CHANNEL6CONTROL 0x948 +#define CHANNEL6CONTROL_HIGH 0x988 + +#define CHANNEL7CONTROL 0x94C +#define CHANNEL7CONTROL_HIGH 0x98C + + +/* + * DMA Arbiter + */ + +#define ARBITER_CONTROL_0_3 0x860 +#define ARBITER_CONTROL_4_7 0x960 + + +/* + * DMA Interrupt + */ + +#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 +#define CHANELS0_3_INTERRUPT_MASK 0x8c4 +#define CHANELS0_3_ERROR_ADDRESS 0x8c8 +#define CHANELS0_3_ERROR_SELECT 0x8cc +#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 +#define CHANELS4_7_INTERRUPT_MASK 0x9c4 +#define CHANELS4_7_ERROR_ADDRESS 0x9c8 +#define CHANELS4_7_ERROR_SELECT 0x9cc + + +/* + * DMA Debug (for internal use) + */ + +#define DMA_X0_ADDRESS 0x8e0 +#define DMA_X0_COMMAND_AND_ID 0x8e4 +#define DMA_X0_WRITE_DATA_LOW 0x8e8 +#define DMA_X0_WRITE_DATA_HIGH 0x8ec +#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 +#define DMA_X0_READ_DATA_LOW 0x8f0 +#define DMA_X0_READ_DATA_HIGH 0x8f4 +#define DMA_X0_READ_ID 0x8fc +#define DMA_X1_ADDRESS 0x9e0 +#define DMA_X1_COMMAND_AND_ID 0x9e4 +#define DMA_X1_WRITE_DATA_LOW 0x9e8 +#define DMA_X1_WRITE_DATA_HIGH 0x9ec +#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 +#define DMA_X1_READ_DATA_LOW 0x9f0 +#define DMA_X1_READ_DATA_HIGH 0x9f4 +#define DMA_X1_READ_ID 0x9fc + +/* + * Timer_Counter + */ + +#define TIMER_COUNTER0 0x850 +#define TIMER_COUNTER1 0x854 +#define TIMER_COUNTER2 0x858 +#define TIMER_COUNTER3 0x85C +#define TIMER_COUNTER_0_3_CONTROL 0x864 +#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c +#define TIMER_COUNTER4 0x950 +#define TIMER_COUNTER5 0x954 +#define TIMER_COUNTER6 0x958 +#define TIMER_COUNTER7 0x95C +#define TIMER_COUNTER_4_7_CONTROL 0x964 +#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 +#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c + +/* + * PCI Slave Address Decoding + */ + +#define PCI_0SCS_0_BANK_SIZE 0xc08 +#define PCI_1SCS_0_BANK_SIZE 0xc88 +#define PCI_0SCS_1_BANK_SIZE 0xd08 +#define PCI_1SCS_1_BANK_SIZE 0xd88 +#define PCI_0SCS_2_BANK_SIZE 0xc0c +#define PCI_1SCS_2_BANK_SIZE 0xc8c +#define PCI_0SCS_3_BANK_SIZE 0xd0c +#define PCI_1SCS_3_BANK_SIZE 0xd8c +#define PCI_0CS_0_BANK_SIZE 0xc10 +#define PCI_1CS_0_BANK_SIZE 0xc90 +#define PCI_0CS_1_BANK_SIZE 0xd10 +#define PCI_1CS_1_BANK_SIZE 0xd90 +#define PCI_0CS_2_BANK_SIZE 0xd18 +#define PCI_1CS_2_BANK_SIZE 0xd98 +#define PCI_0CS_3_BANK_SIZE 0xc14 +#define PCI_1CS_3_BANK_SIZE 0xc94 +#define PCI_0CS_BOOT_BANK_SIZE 0xd14 +#define PCI_1CS_BOOT_BANK_SIZE 0xd94 +#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c +#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c +#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 +#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 +#define PCI_0P2P_I_O_BAR_SIZE 0xd24 +#define PCI_1P2P_I_O_BAR_SIZE 0xda4 +#define PCI_0CPU_BAR_SIZE 0xd28 +#define PCI_1CPU_BAR_SIZE 0xda8 +#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 +#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 +#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 +#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 +#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 +#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 +#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c +#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c +#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 +#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 +#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 +#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 +#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 +#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 +#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c +#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c +#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 +#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 +#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 +#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 +#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 +#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 +#define PCI_0DAC_CPU_BAR_SIZE 0xe2c +#define PCI_1DAC_CPU_BAR_SIZE 0xeac +#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c +#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac +#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c +#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc +#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 +#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 +#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 +#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 +#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c +#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc +#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c +#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc +#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 +#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 +#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 +#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 +#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 +#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 +#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 +#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 +#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 +#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 +#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c +#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec +#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 +#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 +#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 +#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 +#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 +#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 +#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 +#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 +#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c +#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c +#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 +#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 +#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 +#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 +#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 +#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 +#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c +#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c +#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 +#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 +#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 +#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 +#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 +#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 +#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c +#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc + +/* + * PCI Control + */ + +#define PCI_0COMMAND 0xc00 +#define PCI_1COMMAND 0xc80 +#define PCI_0MODE 0xd00 +#define PCI_1MODE 0xd80 +#define PCI_0TIMEOUT_RETRY 0xc04 +#define PCI_1TIMEOUT_RETRY 0xc84 +#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 +#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 +#define MSI_0TRIGGER_TIMER 0xc38 +#define MSI_1TRIGGER_TIMER 0xcb8 +#define PCI_0ARBITER_CONTROL 0x1d00 +#define PCI_1ARBITER_CONTROL 0x1d80 +/* changing untill here */ +#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 +#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c +#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c +#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 +#define PCI_0P2P_CONFIGURATION 0x1d14 +#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 +#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 +#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 +#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 +#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 +#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 +#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 +#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 +#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 +#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 +#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 +#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 +#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 +#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 +#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 +#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 +#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 +#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 +#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c +#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c +#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 +#define PCI_1P2P_CONFIGURATION 0x1d94 +#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 +#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 +#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 +#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 +#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 +#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 +#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 +#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 +#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 +#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 +#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 +#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 +#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 +#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 +#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 +#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 +#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 + +/* + * PCI Snoop Control + */ + +#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 +#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 +#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 +#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 +#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 +#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 +#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 +#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 +#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 +#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 +#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 +#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 +#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 +#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 +#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 +#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 +#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 +#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 +#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 +#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 +#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 +#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 +#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 +#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 + +/* + * PCI Configuration Address + */ + +#define PCI_0CONFIGURATION_ADDRESS 0xcf8 +#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc +#define PCI_1CONFIGURATION_ADDRESS 0xc78 +#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c +#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 +#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 + +/* + * PCI Error Report + */ + +#define PCI_0SERR_MASK 0xc28 +#define PCI_0ERROR_ADDRESS_LOW 0x1d40 +#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 +#define PCI_0ERROR_DATA_LOW 0x1d48 +#define PCI_0ERROR_DATA_HIGH 0x1d4c +#define PCI_0ERROR_COMMAND 0x1d50 +#define PCI_0ERROR_CAUSE 0x1d58 +#define PCI_0ERROR_MASK 0x1d5c + +#define PCI_1SERR_MASK 0xca8 +#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 +#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 +#define PCI_1ERROR_DATA_LOW 0x1dc8 +#define PCI_1ERROR_DATA_HIGH 0x1dcc +#define PCI_1ERROR_COMMAND 0x1dd0 +#define PCI_1ERROR_CAUSE 0x1dd8 +#define PCI_1ERROR_MASK 0x1ddc + + +/* + * Lslave Debug (for internal use) + */ + +#define L_SLAVE_X0_ADDRESS 0x1d20 +#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 +#define L_SLAVE_X1_ADDRESS 0x1d28 +#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c +#define L_SLAVE_WRITE_DATA_LOW 0x1d30 +#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 +#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 +#define L_SLAVE_READ_DATA_LOW 0x1d38 +#define L_SLAVE_READ_DATA_HIGH 0x1d3c +#define L_SLAVE_READ_ID 0x1d64 + +#if 0 /* Disabled because PCI_* namespace belongs to PCI subsystem ... */ + +/* + * PCI Configuration Function 0 + */ + +#define PCI_DEVICE_AND_VENDOR_ID 0x000 +#define PCI_STATUS_AND_COMMAND 0x004 +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C +#define PCI_SCS_0_BASE_ADDRESS 0x010 +#define PCI_SCS_1_BASE_ADDRESS 0x014 +#define PCI_SCS_2_BASE_ADDRESS 0x018 +#define PCI_SCS_3_BASE_ADDRESS 0x01C +#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 +#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 +#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C +#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 +#define PCI_CAPABILTY_LIST_POINTER 0x034 +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C +#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define PCI_VPD_ADDRESS 0x048 +#define PCI_VPD_DATA 0X04c +#define PCI_MSI_MESSAGE_CONTROL 0x050 +#define PCI_MSI_MESSAGE_ADDRESS 0x054 +#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 +#define PCI_MSI_MESSAGE_DATA 0x05c +#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 + +/* + * PCI Configuration Function 1 + */ + +#define PCI_CS_0_BASE_ADDRESS 0x110 +#define PCI_CS_1_BASE_ADDRESS 0x114 +#define PCI_CS_2_BASE_ADDRESS 0x118 +#define PCI_CS_3_BASE_ADDRESS 0x11c +#define PCI_BOOTCS_BASE_ADDRESS 0x120 + +/* + * PCI Configuration Function 2 + */ + +#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 +#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 +#define PCI_P2P_I_O_BASE_ADDRESS 0x218 +#define PCI_CPU_BASE_ADDRESS 0x21c + +/* + * PCI Configuration Function 4 + */ + +#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 +#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 +#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 +#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 + + +/* + * PCI Configuration Function 5 + */ + +#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 +#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 +#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 +#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 + + +/* + * PCI Configuration Function 6 + */ + +#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 +#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 +#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 +#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c +#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 +#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 + +/* + * PCI Configuration Function 7 + */ + +#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 +#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c +#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 +#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 +#endif + +/* + * Interrupts + */ + +#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 +#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 +#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c +#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c +#define CPU_SELECT_CAUSE_REGISTER 0xc70 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 +#define PCI_0SELECT_CAUSE 0xc74 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 +#define PCI_1SELECT_CAUSE 0xcf4 +#define CPU_INT_0_MASK 0xe60 +#define CPU_INT_1_MASK 0xe64 +#define CPU_INT_2_MASK 0xe68 +#define CPU_INT_3_MASK 0xe6c + +/* + * I20 Support registers + */ + +#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 +#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 +#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 +#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C +#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 +#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 +#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC + +#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 +#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 +#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 +#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C +#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 +#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 +#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C + +#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 +#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 +#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 +#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C +#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 +#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 +#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC + +#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 +#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 +#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 +#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C +#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 +#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 +#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C + +/* + * Communication Unit Registers + */ + +#define ETHERNET_0_ADDRESS_CONTROL_LOW +#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 +#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 +#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c +#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 +#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 +#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 +#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 +#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 +#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 +#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c +#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 +#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 +#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 +#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 +#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 +#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 +#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c +#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 +#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 +#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 +#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 +#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 +#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 +#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c +#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 +#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 +#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 +#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 +#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 +#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac +#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 +#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 +#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 +#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 +#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 +#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc +#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 +#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 +#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 +#define SERIAL_INIT_LAST_DATA 0xf324 +#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 +#define COMM_UNIT_ARBITER_CONTROL 0xf300 +#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 +#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 +#define COMM_UNIT_INTERRUPT_MASK 0xf314 +#define COMM_UNIT_ERROR_ADDRESS 0xf314 + +/* + * Cunit Debug (for internal use) + */ + +#define CUNIT_ADDRESS 0xf340 +#define CUNIT_COMMAND_AND_ID 0xf344 +#define CUNIT_WRITE_DATA_LOW 0xf348 +#define CUNIT_WRITE_DATA_HIGH 0xf34c +#define CUNIT_WRITE_BYTE_ENABLE 0xf358 +#define CUNIT_READ_DATA_LOW 0xf350 +#define CUNIT_READ_DATA_HIGH 0xf354 +#define CUNIT_READ_ID 0xf35c + +/* + * Fast Ethernet Unit Registers + */ + +/* Ethernet */ + +#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 +#define ETHERNET_SMI_REGISTER 0x2010 + +/* Ethernet 0 */ + +#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 +#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 +#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 +#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 +#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 +#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 +#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 +#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 +#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 +#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 +#define ETHERNET0_MIB_COUNTER_BASE 0x2500 + +/* Ethernet 1 */ + +#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 +#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 +#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 +#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 +#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 +#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 +#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 +#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 +#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 +#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 +#define ETHERNET1_MIB_COUNTER_BASE 0x2900 + +/* Ethernet 2 */ + +#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 +#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 +#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 +#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 +#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 +#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 +#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 +#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 +#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 +#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 +#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 + +/* + * SDMA Registers + */ + +#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 +#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 +#define CHANNEL0_COMMAND_REGISTER 0x4008 +#define CHANNEL0_RX_CMD_STATUS 0x4800 +#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 +#define CHANNEL0_RX_BUFFER_POINTER 0x4808 +#define CHANNEL0_RX_NEXT_POINTER 0x480c +#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 +#define CHANNEL0_TX_CMD_STATUS 0x4C00 +#define CHANNEL0_TX_PACKET_SIZE 0x4C04 +#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 +#define CHANNEL0_TX_NEXT_POINTER 0x4C0c +#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 +#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 +#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 +#define CHANNEL1_COMMAND_REGISTER 0x6008 +#define CHANNEL1_RX_CMD_STATUS 0x6800 +#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 +#define CHANNEL1_RX_BUFFER_POINTER 0x6808 +#define CHANNEL1_RX_NEXT_POINTER 0x680c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_TX_CMD_STATUS 0x6C00 +#define CHANNEL1_TX_PACKET_SIZE 0x6C04 +#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 +#define CHANNEL1_TX_NEXT_POINTER 0x6C0c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 +#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 + +/* SDMA Interrupt */ + +#define SDMA_CAUSE 0xb820 +#define SDMA_MASK 0xb8a0 + + +/* + * Baude Rate Generators Registers + */ + +/* BRG 0 */ + +#define BRG0_CONFIGURATION_REGISTER 0xb200 +#define BRG0_BAUDE_TUNING_REGISTER 0xb204 + +/* BRG 1 */ + +#define BRG1_CONFIGURATION_REGISTER 0xb208 +#define BRG1_BAUDE_TUNING_REGISTER 0xb20c + +/* BRG 2 */ + +#define BRG2_CONFIGURATION_REGISTER 0xb210 +#define BRG2_BAUDE_TUNING_REGISTER 0xb214 + +/* BRG Interrupts */ + +#define BRG_CAUSE_REGISTER 0xb834 +#define BRG_MASK_REGISTER 0xb8b4 + +/* MISC */ + +#define MAIN_ROUTING_REGISTER 0xb400 +#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 +#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 +#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c +#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 +#define WATCHDOG_VALUE_REGISTER 0xb414 + + +/* + * Flex TDM Registers + */ + +/* FTDM Port */ + +#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 +#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 +#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 +#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c +#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 +#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 +#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 + +/* FTDM Interrupts */ + +#define FTDM_CAUSE_REGISTER 0xb830 +#define FTDM_MASK_REGISTER 0xb8b0 + + +/* + * GPP Interface Registers + */ + +#define GPP_IO_CONTROL 0xf100 +#define GPP_LEVEL_CONTROL 0xf110 +#define GPP_VALUE 0xf104 +#define GPP_INTERRUPT_CAUSE 0xf108 +#define GPP_INTERRUPT_MASK 0xf10c + +#define MPP_CONTROL0 0xf000 +#define MPP_CONTROL1 0xf004 +#define MPP_CONTROL2 0xf008 +#define MPP_CONTROL3 0xf00c +#define DEBUG_PORT_MULTIPLEX 0xf014 +#define SERIAL_PORT_MULTIPLEX 0xf010 + +/* + * I2C Registers + */ + +#define I2C_SLAVE_ADDRESS 0xc000 +#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 +#define I2C_DATA 0xc004 +#define I2C_CONTROL 0xc008 +#define I2C_STATUS_BAUDE_RATE 0xc00C +#define I2C_SOFT_RESET 0xc01c + +/* + * MPSC Registers + */ + +/* + * MPSC0 + */ + +#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 +#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 +#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 +#define CHANNEL0_REGISTER1 0x800c +#define CHANNEL0_REGISTER2 0x8010 +#define CHANNEL0_REGISTER3 0x8014 +#define CHANNEL0_REGISTER4 0x8018 +#define CHANNEL0_REGISTER5 0x801c +#define CHANNEL0_REGISTER6 0x8020 +#define CHANNEL0_REGISTER7 0x8024 +#define CHANNEL0_REGISTER8 0x8028 +#define CHANNEL0_REGISTER9 0x802c +#define CHANNEL0_REGISTER10 0x8030 +#define CHANNEL0_REGISTER11 0x8034 + +/* + * MPSC1 + */ + +#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 +#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 +#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 +#define CHANNEL1_REGISTER1 0x900c +#define CHANNEL1_REGISTER2 0x9010 +#define CHANNEL1_REGISTER3 0x9014 +#define CHANNEL1_REGISTER4 0x9018 +#define CHANNEL1_REGISTER5 0x901c +#define CHANNEL1_REGISTER6 0x9020 +#define CHANNEL1_REGISTER7 0x9024 +#define CHANNEL1_REGISTER8 0x9028 +#define CHANNEL1_REGISTER9 0x902c +#define CHANNEL1_REGISTER10 0x9030 +#define CHANNEL1_REGISTER11 0x9034 + +/* + * MPSCs Interupts + */ + +#define MPSC0_CAUSE 0xb804 +#define MPSC0_MASK 0xb884 +#define MPSC1_CAUSE 0xb80c +#define MPSC1_MASK 0xb88c + +extern unsigned long gt64240_base; + +#define GT64240_BASE (gt64240_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ +#define __GT_READ(ofs) \ + (*(volatile u32 *)(GT64240_BASE+(ofs))) +#define __GT_WRITE(ofs, data) \ + do { *(volatile u32 *)(GT64240_BASE+(ofs)) = (data); } while (0) + +#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs)) +#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data)) + +#define GT_READ_16(ofs, data) \ + le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) +#define GT_WRITE_16(ofs, data) \ + *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) + +#define GT_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) +#define GT_WRITE_8(ofs, data) \ + *(volatile u8 *)(GT64240_BASE+(ofs)) = data + +extern struct pci_ops gt_bus0_pci_ops; +extern struct pci_ops gt_bus1_pci_ops; + +#endif /* __ASM_MIPS_MV64240_H */ diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index 4a024fa727cc..f70b9362aa9f 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h @@ -12,22 +12,27 @@ #ifdef __ASSEMBLY__ + .macro _ssnop + sll $0, $2, 1 + .endm + /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use * for data translations should not occur for 3 cpu cycles. */ #ifdef CONFIG_CPU_RM9000 + #define mtc0_tlbw_hazard \ .set push; \ .set mips32; \ - ssnop; ssnop; ssnop; ssnop; \ + _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop #define tlbw_eret_hazard \ .set push; \ .set mips32; \ - ssnop; ssnop; ssnop; ssnop; \ + _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop #else @@ -43,6 +48,33 @@ #define tlbw_eret_hazard #endif +/* + * mtc0->mfc0 hazard + * The 24K has a 2 cycle mtc0/mfc0 execution hazard. + * It is a MIPS32R2 processor so ehb will clear the hazard. + */ + +#ifdef CONFIG_CPU_MIPSR2 +/* + * Use a macro for ehb unless explicit support for MIPSR2 is enabled + */ + .macro ehb + sll $0, $0, 3 + .endm + +#define irq_enable_hazard \ + ehb # irq_enable_hazard + +#define irq_disable_hazard \ + ehb # irq_disable_hazard + +#else + +#define irq_enable_hazard +#define irq_disable_hazard + +#endif + #else /* __ASSEMBLY__ */ /* @@ -55,13 +87,13 @@ #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ ".set\tmips32\n\t" \ - "ssnop; ssnop; ssnop; ssnop\n\t" \ + "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ ".set\tmips0") #define tlbw_use_hazard() \ __asm__ __volatile__( \ ".set\tmips32\n\t" \ - "ssnop; ssnop; ssnop; ssnop\n\t" \ + "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ ".set\tmips0") #else @@ -82,6 +114,83 @@ #endif +/* + * mtc0->mfc0 hazard + * The 24K has a 2 cycle mtc0/mfc0 execution hazard. + * It is a MIPS32R2 processor so ehb will clear the hazard. + */ + +#ifdef CONFIG_CPU_MIPSR2 +/* + * Use a macro for ehb unless explicit support for MIPSR2 is enabled + */ +__asm__( + " .macro ehb \n\t" + " sll $0, $0, 3 \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_enable_hazard \n\t" + " ehb \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " ehb \n\t" + " .endm"); + +#define irq_enable_hazard() \ + __asm__ __volatile__( \ + "ehb\t\t\t\t# irq_enable_hazard") + +#define irq_disable_hazard() \ + __asm__ __volatile__( \ + "ehb\t\t\t\t# irq_disable_hazard") + +#elif defined(CONFIG_CPU_R10000) + +/* + * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. + */ + +__asm__( + " .macro\tirq_enable_hazard \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " .endm"); + +#define irq_enable_hazard() do { } while (0) +#define irq_disable_hazard() do { } while (0) + +#else + +/* + * Default for classic MIPS processors. Assume worst case hazards but don't + * care about the irq_enable_hazard - sooner or later the hardware will + * enable it and we don't care when exactly. + */ + +__asm__( + " .macro _ssnop \n\t" + " sll $0, $2, 1 \n\t" + " .endm \n\t" + " \n\t" + " # \n\t" + " # There is a hazard but we do not care \n\t" + " # \n\t" + " .macro\tirq_enable_hazard \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " _ssnop; _ssnop; _ssnop \n\t" + " .endm"); + +#define irq_enable_hazard() do { } while (0) +#define irq_disable_hazard() \ + __asm__ __volatile__( \ + "_ssnop; _ssnop; _ssnop;\t\t# irq_disable_hazard") + +#endif + #endif /* __ASSEMBLY__ */ #endif /* _ASM_HAZARDS_H */ diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h new file mode 100644 index 000000000000..1de5c32a5884 --- /dev/null +++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h @@ -0,0 +1,38 @@ +/* + * 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) 2003, 2004 Ralf Baechle + */ +#ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H + +/* + * Momentum Jaguar ATX always has the RM9000 processor. + */ +#define cpu_has_watch 1 +#define cpu_has_mips16 0 +#define cpu_has_divec 0 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_prefetch 1 +#define cpu_has_mcheck 0 +#define cpu_has_ejtag 0 + +#define cpu_has_llsc 1 +#define cpu_has_vtag_icache 0 +#define cpu_has_dc_aliases 0 +#define cpu_has_ic_fills_f_dc 0 + +#define cpu_has_nofpuex 0 +#define cpu_has_64bits 1 + +#define cpu_has_subset_pcaches 0 + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 32 + +#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 8bdab9794feb..71198779fcd6 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -632,7 +632,7 @@ do { \ } while (0) /* - * On The RM7000 these are use to access cop0 set 1 registers + * On RM7000/RM9000 these are uses to access cop0 set 1 registers */ #define __read_32bit_c0_ctrl_register(source) \ ({ int __res; \ diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index e42794180211..dd7591b48ee1 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -45,12 +45,17 @@ extern unsigned long pgd_current[]; #define ASID_INC 0x40 #define ASID_MASK 0xfc0 +#elif defined(CONFIG_CPU_R8000) + +#define ASID_INC 0x10 +#define ASID_MASK 0xff0 + #elif defined(CONFIG_CPU_RM9000) #define ASID_INC 0x1 #define ASID_MASK 0xfff -#else /* FIXME: not correct for R6000, R8000 */ +#else /* FIXME: not correct for R6000 */ #define ASID_INC 0x1 #define ASID_MASK 0xff @@ -78,9 +83,8 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) unsigned long asid = asid_cache(cpu); if (! ((asid += ASID_INC) & ASID_MASK) ) { -#ifdef CONFIG_VTAG_ICACHE - flush_icache_all(); -#endif + if (cpu_has_vtag_icache) + flush_icache_all(); local_flush_tlb_all(); /* start new asid cycle */ if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h index 99635e6b610e..90ee24aad955 100644 --- a/include/asm-mips/module.h +++ b/include/asm-mips/module.h @@ -2,11 +2,14 @@ #define _ASM_MODULE_H #include +#include +#include struct mod_arch_specific { /* Data Bus Error exception tables */ - const struct exception_table_entry *dbe_table_start; - const struct exception_table_entry *dbe_table_end; + struct list_head dbe_list; + const struct exception_table_entry *dbe_start; + const struct exception_table_entry *dbe_end; }; typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ @@ -38,4 +41,16 @@ typedef struct #endif +#ifdef CONFIG_MODULES +/* Given an address, look for it in the exception tables. */ +const struct exception_table_entry*search_module_dbetables(unsigned long addr); +#else +/* Given an address, look for it in the exception tables. */ +static inline const struct exception_table_entry * +search_module_dbetables(unsigned long addr) +{ + return NULL; +} +#endif + #endif /* _ASM_MODULE_H */ diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 37de18f63b43..47ca67f25e54 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -10,16 +10,20 @@ #define _ASM_PAGE_H #include -#include #ifdef __KERNEL__ +#include + /* * PAGE_SHIFT determines the page size */ #ifdef CONFIG_PAGE_SIZE_4KB #define PAGE_SHIFT 12 #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define PAGE_SHIFT 13 +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define PAGE_SHIFT 14 #endif diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index ba29750e4f1c..1af4e5b600c6 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -87,6 +87,9 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction); +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, struct resource *res); + #endif /* __KERNEL__ */ /* implement the pci_ DMA API in terms of the generic device dma_ one */ diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index 51326d10b880..65bee143ebe3 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -141,35 +141,8 @@ static inline void pgd_clear(pgd_t *pgdp) { } #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - -/* - * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) - -#else - -/* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) - -#endif - #define __pgd_offset(address) pgd_index(address) -#define __pmd_offset(address) \ - (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) +#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -200,17 +173,46 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) #define pte_unmap(pte) ((void)(pte)) #define pte_unmap_nested(pte) ((void)(pte)) -/* Swap entries must have VALID and GLOBAL bits cleared. */ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define __swp_type(x) (((x).val >> 1) & 0x7f) -#define __swp_offset(x) ((x).val >> 10) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) }) +/* Swap entries must have VALID bit cleared. */ +#define __swp_type(x) (((x).val >> 10) & 0x1f) +#define __swp_offset(x) ((x).val >> 15) +#define __swp_entry(type,offset) \ + ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) + +/* + * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 27 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) + #else -#define __swp_type(x) (((x).val >> 1) & 0x1f) -#define __swp_offset(x) ((x).val >> 8) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) +/* Swap entries must have VALID and GLOBAL bits cleared. */ +#define __swp_type(x) (((x).val >> 8) & 0x1f) +#define __swp_offset(x) ((x).val >> 13) +#define __swp_entry(type,offset) \ + ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) + +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 27 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + #endif #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h index eba84a79efc9..333d9a8f585f 100644 --- a/include/asm-mips/pgtable-64.h +++ b/include/asm-mips/pgtable-64.h @@ -53,7 +53,11 @@ * We used to implement 41 bits by having an order 1 pmd level but that seemed * rather pointless. * - * For 16kB page size we use a 2 level page tree which permit a total of + * For 8kB page size we use a 3 level page tree which permits a total of + * 8TB of address space. Alternatively a 33-bit / 8GB organization using + * two levels would be easy to implement. + * + * For 16kB page size we use a 2 level page tree which permits a total of * 36 bits of virtual address space. We could add a third leve. but it seems * like at the moment there's no need for this. * @@ -65,6 +69,11 @@ #define PMD_ORDER 1 #define PTE_ORDER 0 #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define PGD_ORDER 0 +#define PMD_ORDER 0 +#define PTE_ORDER 0 +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define PGD_ORDER 0 #define PMD_ORDER 0 @@ -148,16 +157,6 @@ static inline void pgd_clear(pgd_t *pgdp) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif -/* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) - #define __pgd_offset(address) pgd_index(address) #define page_pte(page) page_pte_prot(page, __pgprot(0)) @@ -214,6 +213,18 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 32 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 32 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + /* * Used for the b0rked handling of kernel pagetables on the 64-bit kernel. */ diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h index 22d19833a4b4..76c1ae1c7dee 100644 --- a/include/asm-mips/pgtable-bits.h +++ b/include/asm-mips/pgtable-bits.h @@ -60,7 +60,7 @@ #define _PAGE_SILENT_WRITE (1<<8) #define _CACHE_MASK (7<<9) -#if defined(CONFIG_CPU_SB1) +#ifdef CONFIG_CPU_SB1 /* No penalty for being coherent on the SB1, so just use it for "noncoherent" spaces, too. Shouldn't hurt. */ @@ -70,6 +70,20 @@ #define _CACHE_CACHABLE_NONCOHERENT (5<<9) #define _CACHE_UNCACHED_ACCELERATED (7<<9) +#elif defined(CONFIG_CPU_RM9000) + +#define _CACHE_WT (0 << 9) +#define _CACHE_WTWA (1 << 9) +#define _CACHE_UC_B (2 << 9) +#define _CACHE_WB (3 << 9) +#define _CACHE_CWBEA (4 << 9) +#define _CACHE_CWB (5 << 9) +#define _CACHE_UCNB (6 << 9) +#define _CACHE_FPC (7 << 9) + +#define _CACHE_UNCACHED _CACHE_UC_B +#define _CACHE_CACHABLE_NONCOHERENT _CACHE_UC_B + #else #define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ @@ -93,6 +107,8 @@ #define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED #elif defined(CONFIG_DMA_NONCOHERENT) #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT +#elif defined(CONFIG_CPU_RM9000) +#define PAGE_CACHABLE_DEFAULT _CACHE_CWBEA #else #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW #endif diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 5b2aa070cfa2..9d5a8fad0949 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -125,8 +125,6 @@ static inline void pte_clear(pte_t *ptep) extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#define PTE_FILE_MAX_BITS 27 - /* * The following only work if pte_present() is true. * Undefined behaviour if not.. diff --git a/include/asm-mips/pmon.h b/include/asm-mips/pmon.h index 0162517854d4..7b4f990e152a 100644 --- a/include/asm-mips/pmon.h +++ b/include/asm-mips/pmon.h @@ -17,6 +17,9 @@ struct callvectors { int (*printf) (const char*, ...); /* 20 */ void (*cacheflush) (void); /* 24 */ char* (*gets) (char*); /* 28 */ + int (*cpustart) (int, void *, int, int); /* 32 */ }; +extern struct callvectors *debug_vectors; + #endif /* _ASM_PMON_H */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 70534af2a59c..8e38389a9915 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -280,15 +280,6 @@ unsigned long get_wchan(struct task_struct *p); */ #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) -/* - * For now. The 32-bit cycle counter is screwed up so solving this nicely takes a little - * brainwork ... - */ -static inline unsigned long long sched_clock(void) -{ - return 0ULL; -} - #ifdef CONFIG_CPU_HAS_PREFETCH #define ARCH_HAS_PREFETCH diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index bab913a90644..ed9a3d774c6a 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -4,61 +4,70 @@ * for more details. * * Copyright (C) 1996 Linus Torvalds - * Copyright (C) 1998, 99, 2000, 01 Ralf Baechle + * Copyright (C) 1998, 99, 2000, 01, 04 Ralf Baechle * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * + * In all honesty, little of the old MIPS code left - the PPC64 variant was + * just looking nice and portable so I ripped it. Credits to whoever wrote + * it. */ -#ifndef _ASM_SEMAPHORE_H -#define _ASM_SEMAPHORE_H +#ifndef __ASM_SEMAPHORE_H +#define __ASM_SEMAPHORE_H + +/* + * Remove spinlock-based RW semaphores; RW semaphore definitions are + * now in rwsem.h and we use the generic lib/rwsem.c implementation. + * Rework semaphores to use atomic_dec_if_positive. + * -- Paul Mackerras (paulus@samba.org) + */ + +#ifdef __KERNEL__ -#include -#include -#include +#include +#include #include #include -#include struct semaphore { -#ifdef __MIPSEB__ - atomic_t count; - atomic_t waking; -#else - atomic_t waking; + /* + * Note that any negative value of count is equivalent to 0, + * but additionally indicates that some process(es) might be + * sleeping on `wait'. + */ atomic_t count; -#endif wait_queue_head_t wait; -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG long __magic; #endif -} __attribute__((aligned(8))); +}; -#if WAITQUEUE_DEBUG -# define __SEM_DEBUG_INIT(name) , .__magic = (long)&(name).__magic +#ifdef WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (long)&(name).__magic #else # define __SEM_DEBUG_INIT(name) #endif -#define __SEMAPHORE_INITIALIZER(name,_count) { \ - .count = ATOMIC_INIT(_count), \ - .waking = ATOMIC_INIT(0), \ - .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ - __SEM_DEBUG_INIT(name) \ -} +#define __SEMAPHORE_INITIALIZER(name, count) \ + { ATOMIC_INIT(count), \ + __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } -#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INITIALIZER(name, 1) +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name, 1) -#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ - struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) +#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) -#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) static inline void sema_init (struct semaphore *sem, int val) { atomic_set(&sem->count, val); - atomic_set(&sem->waking, 0); init_waitqueue_head(&sem->wait); -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG sem->__magic = (long)&sem->__magic; #endif } @@ -73,211 +82,57 @@ static inline void init_MUTEX_LOCKED (struct semaphore *sem) sema_init(sem, 0); } -#ifndef CONFIG_CPU_HAS_LLDSCD -/* - * On machines without lld/scd we need a spinlock to make the manipulation of - * sem->count and sem->waking atomic. - */ -extern spinlock_t semaphore_lock; -#endif - -extern void __down_failed(struct semaphore * sem); -extern int __down_failed_interruptible(struct semaphore * sem); -extern void __up_wakeup(struct semaphore * sem); +extern void __down(struct semaphore * sem); +extern int __down_interruptible(struct semaphore * sem); +extern void __up(struct semaphore * sem); static inline void down(struct semaphore * sem) { - int count; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); - count = atomic_dec_return(&sem->count); - if (unlikely(count < 0)) - __down_failed(sem); + + /* + * Try to get the semaphore, take the slow path if we fail. + */ + if (unlikely(atomic_dec_return(&sem->count) < 0)) + __down(sem); } -/* - * Interruptible try to acquire a semaphore. If we obtained - * it, return zero. If we were interrupted, returns -EINTR - */ static inline int down_interruptible(struct semaphore * sem) { - int count; + int ret = 0; -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); - count = atomic_dec_return(&sem->count); - if (unlikely(count < 0)) - return __down_failed_interruptible(sem); - - return 0; -} - -#ifdef CONFIG_CPU_HAS_LLDSCD - -/* - * down_trylock returns 0 on success, 1 if we failed to get the lock. - * - * We must manipulate count and waking simultaneously and atomically. - * Here, we do this by using lld/scd on the pair of 32-bit words. - * - * Pseudocode: - * - * Decrement(sem->count) - * If(sem->count >=0) { - * Return(SUCCESS) // resource is free - * } else { - * If(sem->waking <= 0) { // if no wakeup pending - * Increment(sem->count) // undo decrement - * Return(FAILURE) - * } else { - * Decrement(sem->waking) // otherwise "steal" wakeup - * Return(SUCCESS) - * } - * } - */ -static inline int down_trylock(struct semaphore * sem) -{ - long ret, tmp, tmp2, sub; - -#if WAITQUEUE_DEBUG - CHECK_MAGIC(sem->__magic); -#endif - - __asm__ __volatile__( - " .set mips3 # down_trylock \n" - "0: lld %1, %4 \n" - " dli %3, 0x0000000100000000 # count -= 1 \n" - " dsubu %1, %3 \n" - " li %0, 0 # ret = 0 \n" - " bgez %1, 2f # if count >= 0 \n" - " sll %2, %1, 0 # extract waking \n" - " blez %2, 1f # if waking < 0 -> 1f \n" - " daddiu %1, %1, -1 # waking -= 1 \n" - " b 2f \n" - "1: daddu %1, %1, %3 # count += 1 \n" - " li %0, 1 # ret = 1 \n" - "2: scd %1, %4 \n" - " beqz %1, 0b \n" - " sync \n" - " .set mips0 \n" - : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) - : "m"(*sem) - : "memory"); + if (unlikely(atomic_dec_return(&sem->count) < 0)) + ret = __down_interruptible(sem); return ret; } -/* - * Note! This is subtle. We jump to wake people up only if - * the semaphore was negative (== somebody was waiting on it). - */ -static inline void up(struct semaphore * sem) -{ - unsigned long tmp, tmp2; - int count; - -#if WAITQUEUE_DEBUG - CHECK_MAGIC(sem->__magic); -#endif - /* - * We must manipulate count and waking simultaneously and atomically. - * Otherwise we have races between up and __down_failed_interruptible - * waking up on a signal. - */ - - __asm__ __volatile__( - " .set mips3 \n" - " sync # up \n" - "1: lld %1, %3 \n" - " dsra32 %0, %1, 0 # extract count to %0 \n" - " daddiu %0, 1 # count += 1 \n" - " slti %2, %0, 1 # %3 = (%0 <= 0) \n" - " daddu %1, %2 # waking += %3 \n" - " dsll32 %1, %1, 0 # zero-extend %1 \n" - " dsrl32 %1, %1, 0 \n" - " dsll32 %2, %0, 0 # Reassemble union \n" - " or %1, %2 # from count and waking \n" - " scd %1, %3 \n" - " beqz %1, 1b \n" - " .set mips0 \n" - : "=&r"(count), "=&r"(tmp), "=&r"(tmp2), "+m"(*sem) - : - : "memory"); - - if (unlikely(count <= 0)) - __up_wakeup(sem); -} - -#else - -/* - * Non-blockingly attempt to down() a semaphore. - * Returns zero if we acquired it - */ static inline int down_trylock(struct semaphore * sem) { - unsigned long flags; - int count, waking; - int ret = 0; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - spin_lock_irqsave(&semaphore_lock, flags); - count = atomic_read(&sem->count) - 1; - atomic_set(&sem->count, count); - if (unlikely(count < 0)) { - waking = atomic_read(&sem->waking); - if (waking <= 0) { - atomic_set(&sem->count, count + 1); - ret = 1; - } else { - atomic_set(&sem->waking, waking - 1); - ret = 0; - } - } - spin_unlock_irqrestore(&semaphore_lock, flags); - - return ret; + return atomic_dec_if_positive(&sem->count) < 0; } -/* - * Note! This is subtle. We jump to wake people up only if - * the semaphore was negative (== somebody was waiting on it). - */ static inline void up(struct semaphore * sem) { - unsigned long flags; - int count, waking; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - /* - * We must manipulate count and waking simultaneously and atomically. - * Otherwise we have races between up and __down_failed_interruptible - * waking up on a signal. - */ - - spin_lock_irqsave(&semaphore_lock, flags); - count = atomic_read(&sem->count) + 1; - waking = atomic_read(&sem->waking); - if (count <= 0) - waking++; - atomic_set(&sem->count, count); - atomic_set(&sem->waking, waking); - spin_unlock_irqrestore(&semaphore_lock, flags); - if (unlikely(count <= 0)) - __up_wakeup(sem); + if (unlikely(atomic_inc_return(&sem->count) <= 0)) + __up(sem); } -#endif /* CONFIG_CPU_HAS_LLDSCD */ +#endif /* __KERNEL__ */ -#endif /* _ASM_SEMAPHORE_H */ +#endif /* __ASM_SEMAPHORE_H */ diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index ae455b04b31a..83c735adef98 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -315,24 +315,6 @@ #define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS #endif -#ifdef CONFIG_TITAN_SERIAL -/* 16552 20 MHz crystal */ -#define TITAN_SERIAL_BASE_BAUD ( 20000000 / 16 ) -#define TITAN_SERIAL_IRQ XXX -#define TITAN_SERIAL_BASE 0xffffffff - -#define _TITAN_SERIAL_INIT(int, base) \ - { baud_base: TITAN_SERIAL_BASE_BAUD, irq: int, \ - flags: STD_COM_FLAGS, iomem_base: (u8 *) base, \ - iomem_reg_shift: 2, io_type: SERIAL_IO_MEM \ - } - -#define TITAN_SERIAL_PORT_DEFNS \ - _TITAN_SERIAL_INIT(TITAN_SERIAL_IRQ, TITAN_SERIAL_BASE) -#else -#define TITAN_SERIAL_PORT_DEFNS -#endif - #ifdef CONFIG_DDB5477 #include #define DDB5477_SERIAL_PORT_DEFNS \ @@ -371,7 +353,6 @@ MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ - TITAN_SERIAL_PORT_DEFNS \ TXX927_SERIAL_PORT_DEFNS \ AU1000_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 4146d42d48fe..f0ef26b43f7e 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -51,8 +51,6 @@ extern cpumask_t phys_cpu_present_map; extern cpumask_t cpu_online_map; #define cpu_possible_map phys_cpu_present_map -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - extern cpumask_t cpu_callout_map; /* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus(void) @@ -90,12 +88,6 @@ extern void prom_init_secondary(void); */ extern void prom_prepare_cpus(unsigned int max_cpus); -/* - * Do whatever setup needs to be done for SMP at the board level. Return - * the number of cpus in the system, including this one - */ -extern int prom_setup_smp(void); - /* * Last chance for the board code to finish SMP initialization before * the CPU is "online". diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 626a8ab288e1..53a441c3cb3b 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -302,6 +302,7 @@ or t0, t1 xori t0, 0x1f mtc0 t0, CP0_STATUS + irq_disable_hazard .endm /* @@ -314,6 +315,7 @@ or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS + irq_enable_hazard .endm /* @@ -326,6 +328,7 @@ or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS + irq_disable_hazard .endm #endif /* _ASM_STACKFRAME_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 9b7354b872f1..9bacd119796b 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -19,6 +19,7 @@ #include #include +#include __asm__ ( ".macro\tlocal_irq_enable\n\t" @@ -29,6 +30,7 @@ __asm__ ( "ori\t$1,0x1f\n\t" "xori\t$1,0x1e\n\t" "mtc0\t$1,$12\n\t" + "irq_enable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -57,9 +59,7 @@ __asm__ ( "xori\t$1,1\n\t" ".set\tnoreorder\n\t" "mtc0\t$1,$12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -80,7 +80,7 @@ __asm__ ( ".set\tpop\n\t" ".endm"); -#define local_save_flags(x) \ +#define local_save_flags(x) \ __asm__ __volatile__( \ "local_save_flags %0" \ : "=r" (x)) @@ -95,9 +95,7 @@ __asm__ ( "xori\t$1, 1\n\t" ".set\tnoreorder\n\t" "mtc0\t$1, $12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -108,7 +106,8 @@ __asm__ __volatile__( \ : /* no inputs */ \ : "memory") -__asm__(".macro\tlocal_irq_restore flags\n\t" +__asm__ ( + ".macro\tlocal_irq_restore flags\n\t" ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0\t$1, $12\n\t" @@ -117,14 +116,12 @@ __asm__(".macro\tlocal_irq_restore flags\n\t" "xori\t$1, 1\n\t" "or\t\\flags, $1\n\t" "mtc0\t\\flags, $12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tat\n\t" ".set\treorder\n\t" ".endm"); -#define local_irq_restore(flags) \ +#define local_irq_restore(flags) \ do { \ unsigned long __tmp1; \ \ diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index 11782520310b..508b32ad330a 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -68,6 +68,9 @@ register struct thread_info *__current_thread_info __asm__("$28"); #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_MIPS64) #define THREAD_SIZE_ORDER (2) #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define THREAD_SIZE_ORDER (1) +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define THREAD_SIZE_ORDER (0) #endif diff --git a/include/asm-mips/titan_dep.h b/include/asm-mips/titan_dep.h index e25423d39bb5..d820445e8ead 100644 --- a/include/asm-mips/titan_dep.h +++ b/include/asm-mips/titan_dep.h @@ -16,9 +16,6 @@ #include /* for KSEG1ADDR() */ #include /* for cpu_to_le32() */ -/* Turn on serial */ -#define CONFIG_TITAN_SERIAL - /* PCI */ #define TITAN_PCI_BASE 0xbb000000 @@ -50,8 +47,181 @@ */ #define RM9000x2_HTLINK_REG 0xbb000644 #define RM9000x2_BASE_ADDR 0xbb000000 -#define RM9000x2_OCD_HTCFGA 0x06f8 -#define RM9000x2_OCD_HTCFGD 0x06fc + +#define OCD_BASE 0xfb000000UL +#define OCD_SIZE 0x3000UL + +extern unsigned long ocd_base; + +/* + * OCD Registers + */ +#define RM9000x2_OCD_LKB5 0x0128 /* Ethernet */ +#define RM9000x2_OCD_LKM5 0x012c + +#define RM9000x2_OCD_LKB7 0x0138 /* HT Region 0 */ +#define RM9000x2_OCD_LKM7 0x013c +#define RM9000x2_OCD_LKB8 0x0140 /* HT Region 1 */ +#define RM9000x2_OCD_LKM8 0x0144 + +#define RM9000x2_OCD_LKB9 0x0148 /* Local Bus */ +#define RM9000x2_OCD_LKM9 0x014c +#define RM9000x2_OCD_LKB10 0x0150 +#define RM9000x2_OCD_LKM10 0x0154 +#define RM9000x2_OCD_LKB11 0x0158 +#define RM9000x2_OCD_LKM11 0x015c +#define RM9000x2_OCD_LKB12 0x0160 +#define RM9000x2_OCD_LKM12 0x0164 + +#define RM9000x2_OCD_LKB13 0x0168 /* Scratch RAM */ +#define RM9000x2_OCD_LKM13 0x016c + +#define RM9000x2_OCD_LPD0 0x0200 /* Local Bus */ +#define RM9000x2_OCD_LPD1 0x0210 +#define RM9000x2_OCD_LPD2 0x0220 +#define RM9000x2_OCD_LPD3 0x0230 + +#define RM9000x2_OCD_HTDVID 0x0600 /* HT Device Header */ +#define RM9000x2_OCD_HTSC 0x0604 +#define RM9000x2_OCD_HTCCR 0x0608 +#define RM9000x2_OCD_HTBHL 0x060c +#define RM9000x2_OCD_HTBAR0 0x0610 +#define RM9000x2_OCD_HTBAR1 0x0614 +#define RM9000x2_OCD_HTBAR2 0x0618 +#define RM9000x2_OCD_HTBAR3 0x061c +#define RM9000x2_OCD_HTBAR4 0x0620 +#define RM9000x2_OCD_HTBAR5 0x0624 +#define RM9000x2_OCD_HTCBCPT 0x0628 +#define RM9000x2_OCD_HTSDVID 0x062c +#define RM9000x2_OCD_HTXRA 0x0630 +#define RM9000x2_OCD_HTCAP1 0x0634 +#define RM9000x2_OCD_HTIL 0x063c + +#define RM9000x2_OCD_HTLCC 0x0640 /* HT Capability Block */ +#define RM9000x2_OCD_HTLINK 0x0644 +#define RM9000x2_OCD_HTFQREV 0x0648 + +#define RM9000x2_OCD_HTERCTL 0x0668 /* HT Controller */ +#define RM9000x2_OCD_HTRXDB 0x066c +#define RM9000x2_OCD_HTIMPED 0x0670 +#define RM9000x2_OCD_HTSWIMP 0x0674 +#define RM9000x2_OCD_HTCAL 0x0678 + +#define RM9000x2_OCD_HTBAA30 0x0680 +#define RM9000x2_OCD_HTBAA54 0x0684 +#define RM9000x2_OCD_HTMASK0 0x0688 +#define RM9000x2_OCD_HTMASK1 0x068c +#define RM9000x2_OCD_HTMASK2 0x0690 +#define RM9000x2_OCD_HTMASK3 0x0694 +#define RM9000x2_OCD_HTMASK4 0x0698 +#define RM9000x2_OCD_HTMASK5 0x069c + +#define RM9000x2_OCD_HTIFCTL 0x06a0 +#define RM9000x2_OCD_HTPLL 0x06a4 + +#define RM9000x2_OCD_HTSRI 0x06b0 +#define RM9000x2_OCD_HTRXNUM 0x06b4 +#define RM9000x2_OCD_HTTXNUM 0x06b8 + +#define RM9000x2_OCD_HTTXCNT 0x06c8 + +#define RM9000x2_OCD_HTERROR 0x06d8 +#define RM9000x2_OCD_HTRCRCE 0x06dc +#define RM9000x2_OCD_HTEOI 0x06e0 + +#define RM9000x2_OCD_CRCR 0x06f0 + +#define RM9000x2_OCD_HTCFGA 0x06f8 +#define RM9000x2_OCD_HTCFGD 0x06fc + +#define RM9000x2_OCD_INTMSG 0x0a00 + +#define RM9000x2_OCD_INTPIN0 0x0a40 +#define RM9000x2_OCD_INTPIN1 0x0a44 +#define RM9000x2_OCD_INTPIN2 0x0a48 +#define RM9000x2_OCD_INTPIN3 0x0a4c +#define RM9000x2_OCD_INTPIN4 0x0a50 +#define RM9000x2_OCD_INTPIN5 0x0a54 +#define RM9000x2_OCD_INTPIN6 0x0a58 +#define RM9000x2_OCD_INTPIN7 0x0a5c +#define RM9000x2_OCD_SEM 0x0a60 +#define RM9000x2_OCD_SEMSET 0x0a64 +#define RM9000x2_OCD_SEMCLR 0x0a68 + +#define RM9000x2_OCD_TKT 0x0a70 +#define RM9000x2_OCD_TKTINC 0x0a74 + +#define RM9000x2_OCD_NMICONFIG 0x0ac0 /* Interrupts */ +#define RM9000x2_OCD_INTP0PRI 0x1a80 +#define RM9000x2_OCD_INTP1PRI 0x1a80 +#define RM9000x2_OCD_INTP0STATUS0 0x1b00 +#define RM9000x2_OCD_INTP0MASK0 0x1b04 +#define RM9000x2_OCD_INTP0SET0 0x1b08 +#define RM9000x2_OCD_INTP0CLEAR0 0x1b0c +#define RM9000x2_OCD_INTP0STATUS1 0x1b10 +#define RM9000x2_OCD_INTP0MASK1 0x1b14 +#define RM9000x2_OCD_INTP0SET1 0x1b18 +#define RM9000x2_OCD_INTP0CLEAR1 0x1b1c +#define RM9000x2_OCD_INTP0STATUS2 0x1b20 +#define RM9000x2_OCD_INTP0MASK2 0x1b24 +#define RM9000x2_OCD_INTP0SET2 0x1b28 +#define RM9000x2_OCD_INTP0CLEAR2 0x1b2c +#define RM9000x2_OCD_INTP0STATUS3 0x1b30 +#define RM9000x2_OCD_INTP0MASK3 0x1b34 +#define RM9000x2_OCD_INTP0SET3 0x1b38 +#define RM9000x2_OCD_INTP0CLEAR3 0x1b3c +#define RM9000x2_OCD_INTP0STATUS4 0x1b40 +#define RM9000x2_OCD_INTP0MASK4 0x1b44 +#define RM9000x2_OCD_INTP0SET4 0x1b48 +#define RM9000x2_OCD_INTP0CLEAR4 0x1b4c +#define RM9000x2_OCD_INTP0STATUS5 0x1b50 +#define RM9000x2_OCD_INTP0MASK5 0x1b54 +#define RM9000x2_OCD_INTP0SET5 0x1b58 +#define RM9000x2_OCD_INTP0CLEAR5 0x1b5c +#define RM9000x2_OCD_INTP0STATUS6 0x1b60 +#define RM9000x2_OCD_INTP0MASK6 0x1b64 +#define RM9000x2_OCD_INTP0SET6 0x1b68 +#define RM9000x2_OCD_INTP0CLEAR6 0x1b6c +#define RM9000x2_OCD_INTP0STATUS7 0x1b70 +#define RM9000x2_OCD_INTP0MASK7 0x1b74 +#define RM9000x2_OCD_INTP0SET7 0x1b78 +#define RM9000x2_OCD_INTP0CLEAR7 0x1b7c +#define RM9000x2_OCD_INTP1STATUS0 0x2b00 +#define RM9000x2_OCD_INTP1MASK0 0x2b04 +#define RM9000x2_OCD_INTP1SET0 0x2b08 +#define RM9000x2_OCD_INTP1CLEAR0 0x2b0c +#define RM9000x2_OCD_INTP1STATUS1 0x2b10 +#define RM9000x2_OCD_INTP1MASK1 0x2b14 +#define RM9000x2_OCD_INTP1SET1 0x2b18 +#define RM9000x2_OCD_INTP1CLEAR1 0x2b1c +#define RM9000x2_OCD_INTP1STATUS2 0x2b20 +#define RM9000x2_OCD_INTP1MASK2 0x2b24 +#define RM9000x2_OCD_INTP1SET2 0x2b28 +#define RM9000x2_OCD_INTP1CLEAR2 0x2b2c +#define RM9000x2_OCD_INTP1STATUS3 0x2b30 +#define RM9000x2_OCD_INTP1MASK3 0x2b34 +#define RM9000x2_OCD_INTP1SET3 0x2b38 +#define RM9000x2_OCD_INTP1CLEAR3 0x2b3c +#define RM9000x2_OCD_INTP1STATUS4 0x2b40 +#define RM9000x2_OCD_INTP1MASK4 0x2b44 +#define RM9000x2_OCD_INTP1SET4 0x2b48 +#define RM9000x2_OCD_INTP1CLEAR4 0x2b4c +#define RM9000x2_OCD_INTP1STATUS5 0x2b50 +#define RM9000x2_OCD_INTP1MASK5 0x2b54 +#define RM9000x2_OCD_INTP1SET5 0x2b58 +#define RM9000x2_OCD_INTP1CLEAR5 0x2b5c +#define RM9000x2_OCD_INTP1STATUS6 0x2b60 +#define RM9000x2_OCD_INTP1MASK6 0x2b64 +#define RM9000x2_OCD_INTP1SET6 0x2b68 +#define RM9000x2_OCD_INTP1CLEAR6 0x2b6c +#define RM9000x2_OCD_INTP1STATUS7 0x2b70 +#define RM9000x2_OCD_INTP1MASK7 0x2b74 +#define RM9000x2_OCD_INTP1SET7 0x2b78 +#define RM9000x2_OCD_INTP1CLEAR7 0x2b7c + +#define OCD_READ(reg) (*(volatile unsigned int *)(ocd_base + (reg))) +#define OCD_WRITE(reg, val) \ + do { *(volatile unsigned int *)(ocd_base + (reg)) = (val); } while (0) /* * Hypertransport specific macros @@ -65,4 +235,3 @@ #define RM9K_READ_16(ofs, val) *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) #endif - diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 4dfc72bd1b98..7c5a30028776 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -297,16 +297,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 274) #define __NR_mq_notify (__NR_Linux + 275) #define __NR_mq_getsetattr (__NR_Linux + 276) +#define __NR_vserver (__NR_Linux + 277) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 276 +#define __NR_Linux_syscalls 277 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 276 +#define __NR_O32_Linux_syscalls 277 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -550,16 +551,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 233) #define __NR_mq_notify (__NR_Linux + 234) #define __NR_mq_getsetattr (__NR_Linux + 235) +#define __NR_vserver (__NR_Linux + 236) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 235 +#define __NR_Linux_syscalls 236 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 235 +#define __NR_64_Linux_syscalls 236 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -807,16 +809,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 237) #define __NR_mq_notify (__NR_Linux + 238) #define __NR_mq_getsetattr (__NR_Linux + 239) +#define __NR_vserver (__NR_Linux + 240) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 239 +#define __NR_Linux_syscalls 240 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 239 +#define __NR_N32_Linux_syscalls 240 #ifndef __ASSEMBLY__ diff --git a/include/asm-mips/vr41xx/capcella.h b/include/asm-mips/vr41xx/capcella.h index 82d9db6cb352..5b55083c5281 100644 --- a/include/asm-mips/vr41xx/capcella.h +++ b/include/asm-mips/vr41xx/capcella.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/capcella.h + * capcella.h, Include file for ZAO Networks Capcella. * - * BRIEF MODULE DESCRIPTION - * Include file for ZAO Networks Capcella. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 */ #ifndef __ZAO_CAPCELLA_H #define __ZAO_CAPCELLA_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/mpc30x.h b/include/asm-mips/vr41xx/mpc30x.h index bff9f0aafcce..e6ac3c8e8bae 100644 --- a/include/asm-mips/vr41xx/mpc30x.h +++ b/include/asm-mips/vr41xx/mpc30x.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/mpc30x.h + * mpc30x.h, Include file for Victor MP-C303/304. * - * BRIEF MODULE DESCRIPTION - * Include file for Victor MP-C303/304. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 */ #ifndef __VICTOR_MPC30X_H #define __VICTOR_MPC30X_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/tb0219.h b/include/asm-mips/vr41xx/tb0219.h new file mode 100644 index 000000000000..273c6392688f --- /dev/null +++ b/include/asm-mips/vr41xx/tb0219.h @@ -0,0 +1,42 @@ +/* + * tb0219.h, Include file for TANBAC TB0219. + * + * Copyright (C) 2002-2004 Yoichi Yuasa + * + * Modified for TANBAC TB0219: + * Copyright (C) 2003 Megasolution Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +#ifndef __TANBAC_TB0219_H +#define __TANBAC_TB0219_H + +#include + +/* + * General-Purpose I/O Pin Number + */ +#define TB0219_PCI_SLOT1_PIN 2 +#define TB0219_PCI_SLOT2_PIN 3 +#define TB0219_PCI_SLOT3_PIN 4 + +/* + * Interrupt Number + */ +#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN) +#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN) +#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN) + +#endif /* __TANBAC_TB0219_H */ diff --git a/include/asm-mips/vr41xx/tb0226.h b/include/asm-mips/vr41xx/tb0226.h index 97ca8898b763..0ff9a60ecacc 100644 --- a/include/asm-mips/vr41xx/tb0226.h +++ b/include/asm-mips/vr41xx/tb0226.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/tb0226.h + * tb0226.h, Include file for TANBAC TB0226. * - * BRIEF MODULE DESCRIPTION - * Include file for TANBAC TB0226. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * 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. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 */ #ifndef __TANBAC_TB0226_H #define __TANBAC_TB0226_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/tb0229.h b/include/asm-mips/vr41xx/tb0229.h deleted file mode 100644 index bd8cbc876e49..000000000000 --- a/include/asm-mips/vr41xx/tb0229.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * FILE NAME - * include/asm-mips/vr41xx/tb0229.h - * - * BRIEF MODULE DESCRIPTION - * Include file for TANBAC TB0229 and TB0219. - * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp - * - * Modified for TANBAC TB0229: - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * 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 __TANBAC_TB0229_H -#define __TANBAC_TB0229_H - -#include -#include - -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - -/* - * General-Purpose I/O Pin Number - */ -#define TB0219_PCI_SLOT1_PIN 2 -#define TB0219_PCI_SLOT2_PIN 3 -#define TB0219_PCI_SLOT3_PIN 4 - -/* - * Interrupt Number - */ -#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN) -#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN) -#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN) - -#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) - -extern void tanbac_tb0229_restart(char *command); - -#endif /* __TANBAC_TB0229_H */ diff --git a/include/asm-mips/vr41xx/vr41xx.h b/include/asm-mips/vr41xx/vr41xx.h index 53fe1162af7e..c57c8dca6117 100644 --- a/include/asm-mips/vr41xx/vr41xx.h +++ b/include/asm-mips/vr41xx/vr41xx.h @@ -42,12 +42,6 @@ /* VR4133 0x00000c84- */ #define PRID_VR4133 0x00000c84 -/* - * Memory resource - */ -#define IO_MEM_RESOURCE_START 0UL -#define IO_MEM_RESOURCE_END 0x1fffffffUL - /* * Bus Control Uint */ @@ -136,8 +130,71 @@ extern void vr41xx_mask_clock(vr41xx_clock_t clock); extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign); extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)); -extern void vr41xx_enable_dsiuint(void); -extern void vr41xx_disable_dsiuint(void); +#define PIUINT_COMMAND 0x0040 +#define PIUINT_DATA 0x0020 +#define PIUINT_PAGE1 0x0010 +#define PIUINT_PAGE0 0x0008 +#define PIUINT_DATALOST 0x0004 +#define PIUINT_STATUSCHANGE 0x0001 + +extern void vr41xx_enable_piuint(uint16_t mask); +extern void vr41xx_disable_piuint(uint16_t mask); + +#define AIUINT_INPUT_DMAEND 0x0800 +#define AIUINT_INPUT_DMAHALT 0x0400 +#define AIUINT_INPUT_DATALOST 0x0200 +#define AIUINT_INPUT_DATA 0x0100 +#define AIUINT_OUTPUT_DMAEND 0x0008 +#define AIUINT_OUTPUT_DMAHALT 0x0004 +#define AIUINT_OUTPUT_NODATA 0x0002 + +extern void vr41xx_enable_aiuint(uint16_t mask); +extern void vr41xx_disable_aiuint(uint16_t mask); + +#define KIUINT_DATALOST 0x0004 +#define KIUINT_DATAREADY 0x0002 +#define KIUINT_SCAN 0x0001 + +extern void vr41xx_enable_kiuint(uint16_t mask); +extern void vr41xx_disable_kiuint(uint16_t mask); + +#define DSIUINT_CTS 0x0800 +#define DSIUINT_RXERR 0x0400 +#define DSIUINT_RX 0x0200 +#define DSIUINT_TX 0x0100 +#define DSIUINT_ALL 0x0f00 + +extern void vr41xx_enable_dsiuint(uint16_t mask); +extern void vr41xx_disable_dsiuint(uint16_t mask); + +#define FIRINT_UNIT 0x0010 +#define FIRINT_RX_DMAEND 0x0008 +#define FIRINT_RX_DMAHALT 0x0004 +#define FIRINT_TX_DMAEND 0x0002 +#define FIRINT_TX_DMAHALT 0x0001 + +extern void vr41xx_enable_firint(uint16_t mask); +extern void vr41xx_disable_firint(uint16_t mask); + +extern void vr41xx_enable_pciint(void); +extern void vr41xx_disable_pciint(void); + +extern void vr41xx_enable_scuint(void); +extern void vr41xx_disable_scuint(void); + +#define CSIINT_TX_DMAEND 0x0040 +#define CSIINT_TX_DMAHALT 0x0020 +#define CSIINT_TX_DATA 0x0010 +#define CSIINT_TX_FIFOEMPTY 0x0008 +#define CSIINT_RX_DMAEND 0x0004 +#define CSIINT_RX_DMAHALT 0x0002 +#define CSIINT_RX_FIFOEMPTY 0x0001 + +extern void vr41xx_enable_csiint(uint16_t mask); +extern void vr41xx_disable_csiint(uint16_t mask); + +extern void vr41xx_enable_bcuint(void); +extern void vr41xx_disable_bcuint(void); /* * Power Management Unit @@ -220,18 +277,71 @@ extern void vr41xx_dsiu_init(void); /* * PCI Control Unit */ -struct vr41xx_pci_address_space { - u32 internal_base; - u32 address_mask; - u32 pci_base; +#define PCI_MASTER_ADDRESS_MASK 0x7fffffffU + +struct pci_master_address_conversion { + uint32_t bus_base_address; + uint32_t address_mask; + uint32_t pci_base_address; +}; + +struct pci_target_address_conversion { + uint32_t address_mask; + uint32_t bus_base_address; +}; + +typedef enum { + CANNOT_LOCK_FROM_DEVICE, + CAN_LOCK_FROM_DEVICE, +} pci_exclusive_access_t; + +struct pci_mailbox_address { + uint32_t base_address; }; -struct vr41xx_pci_address_map { - struct vr41xx_pci_address_space *mem1; - struct vr41xx_pci_address_space *mem2; - struct vr41xx_pci_address_space *io; +struct pci_target_address_window { + uint32_t base_address; +}; + +typedef enum { + PCI_ARBITRATION_MODE_FAIR, + PCI_ARBITRATION_MODE_ALTERNATE_0, + PCI_ARBITRATION_MODE_ALTERNATE_B, +} pci_arbiter_priority_control_t; + +typedef enum { + PCI_TAKE_AWAY_GNT_DISABLE, + PCI_TAKE_AWAY_GNT_ENABLE, +} pci_take_away_gnt_mode_t; + +struct pci_controller_unit_setup { + struct pci_master_address_conversion *master_memory1; + struct pci_master_address_conversion *master_memory2; + + struct pci_target_address_conversion *target_memory1; + struct pci_target_address_conversion *target_memory2; + + struct pci_master_address_conversion *master_io; + + pci_exclusive_access_t exclusive_access; + + uint32_t pci_clock_max; + uint8_t wait_time_limit_from_irdy_to_trdy; /* Only VR4122 is supported */ + + struct pci_mailbox_address *mailbox; + struct pci_target_address_window *target_window1; + struct pci_target_address_window *target_window2; + + uint8_t master_latency_timer; + uint8_t retry_limit; + + pci_arbiter_priority_control_t arbiter_priority_control; + pci_take_away_gnt_mode_t take_away_gnt_mode; + + struct resource *mem_resource; + struct resource *io_resource; }; -extern void vr41xx_pciu_init(struct vr41xx_pci_address_map *map); +extern void vr41xx_pciu_setup(struct pci_controller_unit_setup *setup); #endif /* __NEC_VR41XX_H */ diff --git a/include/asm-mips/vr41xx/vrc4173.h b/include/asm-mips/vr41xx/vrc4173.h index a8e873c06481..b14ef0377da1 100644 --- a/include/asm-mips/vr41xx/vrc4173.h +++ b/include/asm-mips/vr41xx/vrc4173.h @@ -1,19 +1,24 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/vrc4173.h + * vrc4173.h, Include file for NEC VRC4173. * - * BRIEF MODULE DESCRIPTION - * Include file for NEC VRC4173. + * Copyright (C) 2000 Michael R. McDonald + * Copyright (C) 2001-2003 Montavista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * 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. + * 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. * - * Copyright (C) 2000 by Michael R. McDonald + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Copyright 2001-2003 Montavista Software Inc. - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * 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 */ #ifndef __NEC_VRC4173_H #define __NEC_VRC4173_H @@ -72,35 +77,38 @@ extern unsigned long vrc4173_io_offset; /* * Clock Mask Unit */ -#define VRC4173_PIU_CLOCK 0x0001 -#define VRC4173_KIU_CLOCK 0x0002 -#define VRC4173_AIU_CLOCK 0x0004 -#define VRC4173_PS2CH1_CLOCK 0x0008 -#define VRC4173_PS2CH2_CLOCK 0x0010 -#define VRC4173_USBU_PCI_CLOCK 0x0020 -#define VRC4173_CARDU1_PCI_CLOCK 0x0040 -#define VRC4173_CARDU2_PCI_CLOCK 0x0080 -#define VRC4173_AC97U_PCI_CLOCK 0x0100 -#define VRC4173_USBU_48MHz_CLOCK 0x0400 -#define VRC4173_EXT_48MHz_CLOCK 0x0800 -#define VRC4173_48MHz_CLOCK 0x1000 +typedef enum vrc4173_clock { + VRC4173_PIU_CLOCK, + VRC4173_KIU_CLOCK, + VRC4173_AIU_CLOCK, + VRC4173_PS2_CH1_CLOCK, + VRC4173_PS2_CH2_CLOCK, + VRC4173_USBU_PCI_CLOCK, + VRC4173_CARDU1_PCI_CLOCK, + VRC4173_CARDU2_PCI_CLOCK, + VRC4173_AC97U_PCI_CLOCK, + VRC4173_USBU_48MHz_CLOCK, + VRC4173_EXT_48MHz_CLOCK, + VRC4173_48MHz_CLOCK, +} vrc4173_clock_t; -extern void vrc4173_clock_supply(u16 mask); -extern void vrc4173_clock_mask(u16 mask); +extern void vrc4173_supply_clock(vrc4173_clock_t clock); +extern void vrc4173_mask_clock(vrc4173_clock_t clock); /* * General-Purpose I/O Unit */ -enum { - PS2CH1_SELECT, - PS2CH2_SELECT, - TOUCHPANEL_SELECT, - KIU8_SELECT, - KIU10_SELECT, - KIU12_SELECT, - GPIO_SELECT -}; +typedef enum vrc4173_function { + PS2_CHANNEL1, + PS2_CHANNEL2, + TOUCHPANEL, + KEYBOARD_8SCANLINES, + KEYBOARD_10SCANLINES, + KEYBOARD_12SCANLINES, + GPIO_0_15PINS, + GPIO_16_20PINS, +} vrc4173_function_t; -extern void vrc4173_select_function(int func); +extern void vrc4173_select_function(vrc4173_function_t function); #endif /* __NEC_VRC4173_H */ -- cgit v1.2.3 From 77a5fdb07e54e8467aabdaf26cc5c31d2660a929 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:39 -0700 Subject: [PATCH] OProfile: allow normal user to trigger sample dumps From: John Levon In 2.4, OProfile allowed normal users to trigger sample dumps (useful under low sample load). The patch below, by Will Cohen, allows this for 2.6 too. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/oprofile/oprofile_files.c | 2 +- drivers/oprofile/oprofilefs.c | 25 +++++++++++++++++++------ include/linux/oprofile.h | 3 +++ 3 files changed, 23 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 381abef6fc07..b22d4ea3f9b5 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -90,7 +90,7 @@ static struct file_operations dump_fops = { void oprofile_create_files(struct super_block * sb, struct dentry * root) { oprofilefs_create_file(sb, root, "enable", &enable_fops); - oprofilefs_create_file(sb, root, "dump", &dump_fops); + oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 2824c24c7f49..4b394ac31435 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -165,7 +165,8 @@ static struct file_operations ulong_ro_fops = { static struct dentry * __oprofilefs_create_file(struct super_block * sb, - struct dentry * root, char const * name, struct file_operations * fops) + struct dentry * root, char const * name, struct file_operations * fops, + int perm) { struct dentry * dentry; struct inode * inode; @@ -176,7 +177,7 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, dentry = d_alloc(root, &qname); if (!dentry) return 0; - inode = oprofilefs_get_inode(sb, S_IFREG | 0644); + inode = oprofilefs_get_inode(sb, S_IFREG | perm); if (!inode) { dput(dentry); return 0; @@ -190,7 +191,8 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_fops, 0644); if (!d) return -EFAULT; @@ -202,7 +204,8 @@ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_ro_fops, 0444); if (!d) return -EFAULT; @@ -227,7 +230,8 @@ static struct file_operations atomic_ro_fops = { int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, char const * name, atomic_t * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &atomic_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &atomic_ro_fops, 0444); if (!d) return -EFAULT; @@ -239,7 +243,16 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, int oprofilefs_create_file(struct super_block * sb, struct dentry * root, char const * name, struct file_operations * fops) { - if (!__oprofilefs_create_file(sb, root, name, fops)) + if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) + return -EFAULT; + return 0; +} + + +int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, + char const * name, struct file_operations * fops, int perm) +{ + if (!__oprofilefs_create_file(sb, root, name, fops, perm)) return -EFAULT; return 0; } diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index 80cfea0fa65f..f17c89c37c72 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -65,6 +65,9 @@ extern void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, */ int oprofilefs_create_file(struct super_block * sb, struct dentry * root, char const * name, struct file_operations * fops); + +int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, + char const * name, struct file_operations * fops, int perm); /** Create a file for read/write access to an unsigned long. */ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, -- cgit v1.2.3 From 0a88d6091a146d1a25f3736f40c5d017a301f487 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:01 -0700 Subject: [PATCH] Core fbcon fixes From: "Antonino A. Daplas" This patch fixes the following bugs/regressions for fbcon: 1. Initialize and update global arrays used by fbcon during initialization and and by set_con2fbmap code. 2. Fixed screen corruption (white rectangle) at initial mode setting plaguing cards with VGA cores and with VGA console enabled. (vga16fb, however, still shows remnants of previous text if boot logo is enabled) 3. Improved fbcon_startup/fbcon_init code. 4. Fixed set_con2fbmap code -- should support multiple devices mapped to Signed-off-by: Antonino A. Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 332 +++++++++++++++++++++++++++++++++--------- drivers/video/fbmem.c | 16 +- include/linux/fb.h | 1 + 3 files changed, 272 insertions(+), 77 deletions(-) (limited to 'include') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index e928f4ed6ae4..f25e11b649ff 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -118,6 +118,9 @@ static int fbcon_is_default = 1; /* font data */ static char fontname[40]; +/* current fb_info */ +static int info_idx = -1; + #define REFCOUNT(fd) (((int *)(fd))[-1]) #define FNTSIZE(fd) (((int *)(fd))[-2]) #define FNTCHARCNT(fd) (((int *)(fd))[-3]) @@ -165,6 +168,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op); static int fbcon_set_palette(struct vc_data *vc, unsigned char *table); static int fbcon_scrolldelta(struct vc_data *vc, int lines); +void accel_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only); /* @@ -177,6 +182,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count); static __inline__ void ypan_down(struct vc_data *vc, int count); static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break); +static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc); #ifdef CONFIG_MAC /* @@ -194,9 +200,14 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) static void fb_flashcursor(void *private) { struct fb_info *info = (struct fb_info *) private; + struct vc_data *vc = NULL; + + if (info->currcon != -1) + vc = vc_cons[info->currcon].d; - if (!info || info->state != FBINFO_STATE_RUNNING || - info->cursor.rop == ROP_COPY) + if (info->state != FBINFO_STATE_RUNNING || + info->cursor.rop == ROP_COPY || !vc || !CON_IS_VISIBLE(vc) + || registered_fb[(int) con2fb_map[vc->vc_num]] != info) return; acquire_console_sem(); info->cursor.enable ^= 1; @@ -218,17 +229,12 @@ static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) } #endif -static void cursor_timer_handler(unsigned long dev_addr); - -static struct timer_list cursor_timer = - TIMER_INITIALIZER(cursor_timer_handler, 0, 0); - static void cursor_timer_handler(unsigned long dev_addr) { struct fb_info *info = (struct fb_info *) dev_addr; - schedule_work(&info->queue); - mod_timer(&cursor_timer, jiffies + HZ/5); + schedule_work(&info->queue); + mod_timer(&info->cursor_timer, jiffies + HZ/5); } int __init fb_console_setup(char *this_opt) @@ -285,6 +291,28 @@ int __init fb_console_setup(char *this_opt) __setup("fbcon=", fb_console_setup); +static int search_fb_in_map(int idx) +{ + int i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] == idx) + return 1; + } + return 0; +} + +static int search_for_mapped_con(void) +{ + int i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] != -1) + return 1; + } + return 0; +} + /** * set_con2fb_map - map console to frame buffer device * @unit: virtual console number to map @@ -296,12 +324,74 @@ __setup("fbcon=", fb_console_setup); int set_con2fb_map(int unit, int newidx) { struct vc_data *vc = vc_cons[unit].d; + int oldidx = con2fb_map[unit]; + struct fb_info *info = registered_fb[newidx]; + struct fb_info *oldinfo = registered_fb[oldidx]; + int found; + + if (!search_for_mapped_con()) { + info_idx = newidx; + fb_console_init(); + return 0; + } + if (oldidx == newidx) + return 0; if (!vc) - return -ENODEV; + return -ENODEV; + found = search_fb_in_map(newidx); + + acquire_console_sem(); con2fb_map[unit] = newidx; - fbcon_is_default = (vc->vc_sw == &fb_con) ? 1 : 0; - return take_over_console(&fb_con, unit, unit, fbcon_is_default); + if (!found) { + if (!try_module_get(info->fbops->owner)) { + release_console_sem(); + return -ENODEV; + } + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { + module_put(info->fbops->owner); + release_console_sem(); + return -ENODEV; + } + } + + /* + * If old fb is not mapped to any of the consoles, + * fbcon should release it. + */ + if (oldinfo && !search_fb_in_map(oldidx)) { + int err; + + if (info->queue.func == fb_flashcursor) + del_timer_sync(&oldinfo->cursor_timer); + if (oldinfo->fbops->fb_release) { + err = oldinfo->fbops->fb_release(oldinfo, 0); + if (err) { + con2fb_map[unit] = oldidx; + release_console_sem(); + return err; + } + } + module_put(oldinfo->fbops->owner); + } + info->currcon = -1; + if (!found) { + if (!info->queue.func || info->queue.func == fb_flashcursor) { + if (!info->queue.func) + INIT_WORK(&info->queue, fb_flashcursor, info); + + init_timer(&info->cursor_timer); + info->cursor_timer.function = cursor_timer_handler; + info->cursor_timer.expires = jiffies + HZ / 5; + info->cursor_timer.data = (unsigned long ) info; + add_timer(&info->cursor_timer); + } + } + if (info->fbops->fb_set_par) + info->fbops->fb_set_par(info); + fbcon_set_disp(info, vc); + release_console_sem(); + return 0; } /* @@ -443,9 +533,8 @@ static const char *fbcon_startup(void) struct vc_data *vc = vc_cons[fg_console].d; struct font_desc *font = NULL; struct module *owner; - struct fb_info *info; - static int done = 0; - int cols, rows; + struct fb_info *info = NULL; + int rows, cols; int irqres; irqres = 1; @@ -453,20 +542,24 @@ static const char *fbcon_startup(void) * If num_registered_fb is zero, this is a call for the dummy part. * The frame buffer devices weren't initialized yet. */ - if (!num_registered_fb || done) + if (!num_registered_fb || info_idx == -1) return display_desc; - done = 1; - - info = registered_fb[0]; - if (!info) return NULL; + /* + * Instead of blindly using registered_fb[0], we use info_idx, set by + * fb_console_init(); + */ + info = registered_fb[info_idx]; + if (!info) + return NULL; info->currcon = -1; owner = info->fbops->owner; if (!try_module_get(owner)) return NULL; - if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { module_put(owner); - + return NULL; + } if (info->fix.type != FB_TYPE_TEXT) { if (fbcon_softback_size) { if (!softback_buf) { @@ -503,15 +596,8 @@ static const char *fbcon_startup(void) vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ } - /* - * We must always set the mode. The mode of the previous console - * driver could be in the same resolution but we are using different - * hardware so we have to initialize the hardware. - */ - if (info->fbops->fb_set_par) - info->fbops->fb_set_par(info); - cols = info->var.xres/vc->vc_font.width; - rows = info->var.yres/vc->vc_font.height; + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; vc_resize(vc->vc_num, cols, rows); DPRINTK("mode: %s\n", info->fix.id); @@ -585,10 +671,12 @@ static const char *fbcon_startup(void) * default timer to flash the cursor. */ if (!info->queue.func) { INIT_WORK(&info->queue, fb_flashcursor, info); - - cursor_timer.expires = jiffies + HZ / 5; - cursor_timer.data = (unsigned long ) info; - add_timer(&cursor_timer); + + init_timer(&info->cursor_timer); + info->cursor_timer.function = cursor_timer_handler; + info->cursor_timer.expires = jiffies + HZ / 5; + info->cursor_timer.data = (unsigned long ) info; + add_timer(&info->cursor_timer); } return display_desc; } @@ -599,10 +687,12 @@ static void fbcon_init(struct vc_data *vc, int init) struct vc_data **default_mode = vc->vc_display_fg; struct display *t, *p = &fb_display[vc->vc_num]; int display_fg = (*default_mode)->vc_num; - int logo = 1, rows, cols, charcnt = 256; + int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; unsigned short *save = NULL, *r, *q; int cap = info->flags; + if (info_idx == -1 || info == NULL) + return; if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) || (info->fix.type == FB_TYPE_TEXT)) logo = 0; @@ -612,16 +702,17 @@ static void fbcon_init(struct vc_data *vc, int init) /* If we are not the first console on this fb, copy the font from that console */ t = &fb_display[display_fg]; - vc->vc_font.width = (*default_mode)->vc_font.width; - vc->vc_font.height = (*default_mode)->vc_font.height; - vc->vc_font.data = p->fontdata = t->fontdata; - p->userfont = t->userfont; - if (p->userfont) { - REFCOUNT(p->fontdata)++; - charcnt = FNTCHARCNT(p->fontdata); + if (!vc->vc_font.data) { + vc->vc_font.data = p->fontdata = t->fontdata; + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + con_copy_unimap(vc->vc_num, display_fg); } - con_copy_unimap(vc->vc_num, display_fg); - + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); vc->vc_can_do_color = info->var.bits_per_pixel != 1; vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -631,12 +722,24 @@ static void fbcon_init(struct vc_data *vc, int init) if (vc->vc_can_do_color) vc->vc_complement_mask <<= 1; } + cols = vc->vc_cols; + rows = vc->vc_rows; + new_cols = info->var.xres / vc->vc_font.width; + new_rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, new_cols, new_rows); + /* + * We must always set the mode. The mode of the previous console + * driver could be in the same resolution but we are using different + * hardware so we have to initialize the hardware. + * + * We need to do it in fbcon_init() to prevent screen corruption. + */ + if (CON_IS_VISIBLE(vc) && info->fbops->fb_set_par) + info->fbops->fb_set_par(info); - cols = info->var.xres / vc->vc_font.width; - rows = info->var.yres / vc->vc_font.height; - vc_resize(vc->vc_num, cols, rows); - if ((cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED)) + if ((cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED)) p->scrollmode = SCROLL_ACCEL; else /* default to something safe */ p->scrollmode = SCROLL_REDRAW; @@ -646,9 +749,9 @@ static void fbcon_init(struct vc_data *vc, int init) * vc_{cols,rows}, but we must not set those if we are only * resizing the console. */ - if (init) { - vc->vc_cols = cols; - vc->vc_rows = rows; + if (!init) { + vc->vc_cols = new_cols; + vc->vc_rows = new_rows; } if (logo) { @@ -665,14 +768,15 @@ static void fbcon_init(struct vc_data *vc, int init) for (r = q - logo_lines * cols; r < q; r++) if (scr_readw(r) != vc->vc_video_erase_char) break; - if (r != q && rows >= rows + logo_lines) { - save = kmalloc(logo_lines * cols * 2, GFP_KERNEL); + if (r != q && new_rows >= rows + logo_lines) { + save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); if (save) { + int i = cols < new_cols ? cols : new_cols; scr_memsetw(save, vc->vc_video_erase_char, - logo_lines * cols * 2); + logo_lines * new_cols * 2); r = q - step; - for (cnt = 0; cnt < logo_lines; cnt++, r += cols) - scr_memcpyw(save + cnt * cols, r, 2 * cols); + for (cnt = 0; cnt < logo_lines; cnt++, r += i) + scr_memcpyw(save + cnt * new_cols, r, 2 * i); r = q; } } @@ -688,19 +792,19 @@ static void fbcon_init(struct vc_data *vc, int init) vc->vc_pos += logo_lines * vc->vc_size_row; } } - scr_memsetw((unsigned short *) vc->vc_origin, - vc->vc_video_erase_char, - vc->vc_size_row * logo_lines); - if (CON_IS_VISIBLE(vc) && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) { accel_clear_margins(vc, info, 0); update_screen(vc->vc_num); } + scr_memsetw((unsigned short *) vc->vc_origin, + vc->vc_video_erase_char, + vc->vc_size_row * logo_lines); + if (save) { q = (unsigned short *) (vc->vc_origin + vc->vc_size_row * rows); - scr_memcpyw(q, save, logo_lines * cols * 2); + scr_memcpyw(q, save, logo_lines * new_cols * 2); vc->vc_y += logo_lines; vc->vc_pos += logo_lines * vc->vc_size_row; kfree(save); @@ -731,6 +835,8 @@ static void fbcon_deinit(struct vc_data *vc) { struct display *p = &fb_display[vc->vc_num]; + if (info_idx != -1) + return; fbcon_free_font(p); } @@ -925,7 +1031,8 @@ static void fbcon_cursor(struct vc_data *vc, int mode) cursor.set |= FB_CUR_SETHOT; } - if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) { + if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape) + || info->cursor.mask == NULL) { char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; @@ -984,6 +1091,57 @@ int update_var(int con, struct fb_info *info) return 0; } +static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc) +{ + struct display *p = &fb_display[vc->vc_num], *t; + struct vc_data **default_mode = vc->vc_display_fg; + int display_fg = (*default_mode)->vc_num; + int rows, cols, charcnt = 256; + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + t = &fb_display[display_fg]; + if (!vc->vc_font.data) { + vc->vc_font.data = p->fontdata = t->fontdata; + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + con_copy_unimap(vc->vc_num, display_fg); + } + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); + + vc->vc_can_do_color = info->var.bits_per_pixel != 1; + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + if (charcnt == 256) { + vc->vc_hi_font_mask = 0; + } else { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) + vc->vc_complement_mask <<= 1; + } + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, cols, rows); + if (CON_IS_VISIBLE(vc)) { + update_screen(vc->vc_num); + if (softback_buf) { + int l = fbcon_softback_size / vc->vc_size_row; + + if (l > 5) + softback_end = softback_buf + l * + vc->vc_size_row; + else { + /* Smaller scrollback makes no sense, and 0 + would screw the operation totally */ + softback_top = 0; + } + } + } + switch_screen(fg_console); +} + static __inline__ void ywrap_up(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; @@ -1537,6 +1695,7 @@ static int fbcon_switch(struct vc_data *vc) { struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; + int i; if (softback_top) { int l = fbcon_softback_size / vc->vc_size_row; @@ -1563,6 +1722,20 @@ static int fbcon_switch(struct vc_data *vc) } if (info) info->var.yoffset = p->yscroll = 0; + + /* + * FIXME: If we have multiple fbdev's loaded, we need to + * update all info->currcon. Perhaps, we can place this + * in a centralized structure, but this might break some + * drivers. + * + * info->currcon = vc->vc_num; + */ + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) + registered_fb[i]->currcon = vc->vc_num; + } + fbcon_resize(vc, vc->vc_cols, vc->vc_rows); switch (p->scrollmode) { case SCROLL_WRAP: @@ -1580,8 +1753,6 @@ static int fbcon_switch(struct vc_data *vc) scrollback_max = 0; scrollback_current = 0; - info->currcon = vc->vc_num; - update_var(vc->vc_num, info); fbcon_set_palette(vc, color_table); @@ -2186,6 +2357,7 @@ static void fbcon_resumed(struct fb_info *info) update_screen(vc->vc_num); } + static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { @@ -2199,6 +2371,7 @@ static int fbcon_event_notify(struct notifier_block *self, fbcon_resumed(info); break; } + return 0; } @@ -2229,27 +2402,42 @@ const struct consw fb_con = { .con_resize = fbcon_resize, }; -static struct notifier_block fbcon_event_notifer = { +static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; - static int fbcon_event_notifier_registered; int __init fb_console_init(void) { - int err; + int err, i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; if (!num_registered_fb) return -ENODEV; + if (info_idx == -1) { + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) { + info_idx = i; + break; + } + } + } + for (i = first_fb_vc; i <= last_fb_vc; i++) + con2fb_map[i] = info_idx; err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); - if (err) + if (err) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + con2fb_map[i] = -1; + } return err; - + } acquire_console_sem(); if (!fbcon_event_notifier_registered) { - fb_register_client(&fbcon_event_notifer); + fb_register_client(&fbcon_event_notifier); fbcon_event_notifier_registered = 1; } release_console_sem(); @@ -2262,7 +2450,7 @@ void __exit fb_console_exit(void) { acquire_console_sem(); if (fbcon_event_notifier_registered) { - fb_unregister_client(&fbcon_event_notifer); + fb_unregister_client(&fbcon_event_notifier); fbcon_event_notifier_registered = 0; } release_console_sem(); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 65a4021cece4..6162b5ab7c67 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -721,6 +721,7 @@ int fb_show_logo(struct fb_info *info) u32 *palette = NULL, *saved_pseudo_palette = NULL; unsigned char *logo_new = NULL; struct fb_image image; + struct fb_fillrect rect; int x; /* Return if the frame buffer is not mapped or suspended */ @@ -766,6 +767,12 @@ int fb_show_logo(struct fb_info *info) image.height = fb_logo.logo->height; image.dy = 0; + rect.dx = 0; + rect.dy = 0; + rect.color = 0; + rect.width = info->var.xres; + rect.height = fb_logo.logo->height; + info->fbops->fb_fillrect(info, &rect); for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { image.dx = x; @@ -1104,11 +1111,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, #endif /* CONFIG_KMOD */ if (!registered_fb[con2fb.framebuffer]) return -EINVAL; - if (con2fb.console != 0) - set_con2fb_map(con2fb.console-1, con2fb.framebuffer); - else - fb_console_init(); - return 0; + if (con2fb.console > 0 && con2fb.console < MAX_NR_CONSOLES) + return set_con2fb_map(con2fb.console-1, + con2fb.framebuffer); + return -EINVAL; #endif /* CONFIG_FRAMEBUFFER_CONSOLE */ case FBIOBLANK: acquire_console_sem(); diff --git a/include/linux/fb.h b/include/linux/fb.h index cc7f14febf7c..c2ff4024cc25 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -539,6 +539,7 @@ struct fb_info { struct fb_monspecs monspecs; /* Current Monitor specs */ struct fb_cursor cursor; /* Current cursor */ struct work_struct queue; /* Framebuffer event queue */ + struct timer_list cursor_timer; /* Cursor timer */ struct fb_pixmap pixmap; /* Image hardware mapper */ struct fb_pixmap sprite; /* Cursor hardware mapper */ struct fb_cmap cmap; /* Current cmap */ -- cgit v1.2.3 From 81d5fd846719a74a43ec5497ed469f88fb11cd85 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:13 -0700 Subject: [PATCH] fbdev: video mode change notify (fbset) From: "Antonino A. Daplas" This patch allows fbset to change the video mode and the console window size via the notifier call chain. It will only notify fbcon of mode changes from user space. Changes coming from upstream will be ignored. The code will only update the current console. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 53 +++++++++++++++++++++++++++++++++++++++++++ drivers/video/fbmem.c | 8 ++++++- include/linux/fb.h | 2 ++ 3 files changed, 62 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index f25e11b649ff..58a9b8a8b722 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2358,6 +2358,56 @@ static void fbcon_resumed(struct fb_info *info) update_screen(vc->vc_num); } +static void fbcon_modechanged(struct fb_info *info) +{ + struct vc_data *vc = vc_cons[info->currcon].d; + struct display *p; + int rows, cols; + + if (info->currcon < 0 || vt_cons[info->currcon]->vc_mode != + KD_TEXT) + return; + p = &fb_display[vc->vc_num]; + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + vc->vc_can_do_color = info->var.bits_per_pixel != 1; + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + + if (CON_IS_VISIBLE(vc)) { + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, cols, rows); + switch (p->scrollmode) { + case SCROLL_WRAP: + scrollback_phys_max = p->vrows - vc->vc_rows; + break; + case SCROLL_PAN: + scrollback_phys_max = p->vrows - 2 * vc->vc_rows; + if (scrollback_phys_max < 0) + scrollback_phys_max = 0; + break; + default: + scrollback_phys_max = 0; + break; + } + scrollback_max = 0; + scrollback_current = 0; + update_var(vc->vc_num, info); + fbcon_set_palette(vc, color_table); + update_screen(vc->vc_num); + if (softback_buf) { + int l = fbcon_softback_size / vc->vc_size_row; + if (l > 5) + softback_end = softback_buf + l * vc->vc_size_row; + else { + /* Smaller scrollback makes no sense, and 0 + would screw the operation totally */ + softback_top = 0; + } + } + } +} + static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { @@ -2370,6 +2420,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_RESUME: fbcon_resumed(info); break; + case FB_EVENT_MODE_CHANGE: + fbcon_modechanged(info); + break; } return 0; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6162b5ab7c67..bbdd131dbb34 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1005,7 +1005,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) fb_set_cmap(&info->cmap, 1, info); - notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info); + if (info->flags & FBINFO_MISC_MODECHANGEUSER) { + notifier_call_chain(&fb_notifier_list, + FB_EVENT_MODE_CHANGE, info); + info->flags &= ~FBINFO_MISC_MODECHANGEUSER; + } } } return 0; @@ -1056,7 +1060,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (copy_from_user(&var, (void *) arg, sizeof(var))) return -EFAULT; acquire_console_sem(); + info->flags |= FBINFO_MISC_MODECHANGEUSER; i = fb_set_var(info, &var); + info->flags &= ~FBINFO_MISC_MODECHANGEUSER; release_console_sem(); if (i) return i; if (copy_to_user((void *) arg, &var, sizeof(var))) diff --git a/include/linux/fb.h b/include/linux/fb.h index c2ff4024cc25..a25a0ae12656 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -530,6 +530,8 @@ struct fb_ops { #define FBINFO_HWACCEL_YPAN 0x2000 /* optional */ #define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */ +#define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request + from userspace */ struct fb_info { int node; -- cgit v1.2.3 From c8e8d619be317afcc416bb9216af01961c335ec6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:42 -0700 Subject: [PATCH] h8300: delete obsolute header From: Yoshinori Sato - delete obsolute(unused) header file Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-h8300/h8300_ne.h | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/asm-h8300/h8300_ne.h (limited to 'include') diff --git a/include/asm-h8300/h8300_ne.h b/include/asm-h8300/h8300_ne.h deleted file mode 100644 index c797603f3819..000000000000 --- a/include/asm-h8300/h8300_ne.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************/ - -/* - * h8300_ne.h -- NE2000 in H8/300H Evalution Board. - * - * (C) Copyright 2002, Yoshinori Sato - */ - -/****************************************************************************/ -#ifndef h8300ne_h -#define h8300ne_h -/****************************************************************************/ - -#define H8300_NE_DEFINE -#include -#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) -#undef H8300_NE_DEFINE - -/****************************************************************************/ -#endif /* h8300ne_h */ -- cgit v1.2.3 From 3bef362a0d884ad5e8d896f7d3bfac5e6e5b38f4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:24:55 -0700 Subject: [PATCH] sh: SH-3 On-Chip ADC support From: Paul Mundt This adds support for the SH-3's on-chip ADC (which is needed by things like the touchscreen, etc.). Signed-off-by: Andriy Skulysh Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/kernel/cpu/Makefile | 1 + arch/sh/kernel/cpu/adc.c | 36 ++++++++++++++++++++++++++++++++++++ include/asm-sh/adc.h | 12 ++++++++++++ include/asm-sh/cpu-sh3/adc.h | 28 ++++++++++++++++++++++++++++ include/asm-sh/hp6xx/hp6xx.h | 18 +++++++++++++++--- 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 arch/sh/kernel/cpu/adc.c create mode 100644 include/asm-sh/adc.h create mode 100644 include/asm-sh/cpu-sh3/adc.h (limited to 'include') diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index bf3a311c9f35..505115205661 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CPU_SH4) += sh4/ obj-$(CONFIG_SH_RTC) += rtc.o obj-$(CONFIG_UBC_WAKEUP) += ubc.o +obj-$(CONFIG_SH_ADC) += adc.o USE_STANDARD_AS_RULE := true diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c new file mode 100644 index 000000000000..da3d6877f93d --- /dev/null +++ b/arch/sh/kernel/cpu/adc.c @@ -0,0 +1,36 @@ +/* + * linux/arch/sh/kernel/adc.c -- SH3 on-chip ADC support + * + * Copyright (C) 2004 Andriy Skulysh + */ + +#include +#include +#include + + +int adc_single(unsigned int channel) +{ + int off; + unsigned char csr; + + if (channel >= 8) return -1; + + off = (channel & 0x03) << 2; + + csr = ctrl_inb(ADCSR); + csr = channel | ADCSR_ADST | ADCSR_CKS; + ctrl_outb(csr, ADCSR); + + do { + csr = ctrl_inb(ADCSR); + } while ((csr & ADCSR_ADF) == 0); + + csr &= ~(ADCSR_ADF | ADCSR_ADST); + ctrl_outb(csr, ADCSR); + + return (((ctrl_inb(ADDRAH + off) << 8) | + ctrl_inb(ADDRAL + off)) >> 6); +} + +EXPORT_SYMBOL(adc_single); diff --git a/include/asm-sh/adc.h b/include/asm-sh/adc.h new file mode 100644 index 000000000000..64747dc61899 --- /dev/null +++ b/include/asm-sh/adc.h @@ -0,0 +1,12 @@ +#ifndef __ASM_ADC_H +#define __ASM_ADC_H + +/* + * Copyright (C) 2004 Andriy Skulysh + */ + +#include + +int adc_single(unsigned int channel); + +#endif /* __ASM_ADC_H */ diff --git a/include/asm-sh/cpu-sh3/adc.h b/include/asm-sh/cpu-sh3/adc.h new file mode 100644 index 000000000000..b289e3ca19a6 --- /dev/null +++ b/include/asm-sh/cpu-sh3/adc.h @@ -0,0 +1,28 @@ +#ifndef __ASM_CPU_SH3_ADC_H +#define __ASM_CPU_SH3_ADC_H + +/* + * Copyright (C) 2004 Andriy Skulysh + */ + + +#define ADDRAH 0xa4000080 +#define ADDRAL 0xa4000082 +#define ADDRBH 0xa4000084 +#define ADDRBL 0xa4000086 +#define ADDRCH 0xa4000088 +#define ADDRCL 0xa400008a +#define ADDRDH 0xa400008c +#define ADDRDL 0xa400008e +#define ADCSR 0xa4000090 + +#define ADCSR_ADF 0x80 +#define ADCSR_ADIE 0x40 +#define ADCSR_ADST 0x20 +#define ADCSR_MULTI 0x10 +#define ADCSR_CKS 0x08 +#define ADCSR_CH_MASK 0x07 + +#define ADCR 0xa4000092 + +#endif /* __ASM_CPU_SH3_ADC_H */ diff --git a/include/asm-sh/hp6xx/hp6xx.h b/include/asm-sh/hp6xx/hp6xx.h index 53079d2954da..a26247fd3d87 100644 --- a/include/asm-sh/hp6xx/hp6xx.h +++ b/include/asm-sh/hp6xx/hp6xx.h @@ -5,9 +5,22 @@ * Copyright (C) 2003 Andriy Skulysh */ +#define HP680_TS_IRQ IRQ3_IRQ -#define DAC_LCD_BRIGHTNESS 0 -#define DAC_SPEAKER_VOLUME 1 +#define DAC_LCD_BRIGHTNESS 0 +#define DAC_SPEAKER_VOLUME 1 + +#define PHDR_TS_PEN_DOWN 0x08 + +#define SCPDR_TS_SCAN_ENABLE 0x20 +#define SCPDR_TS_SCAN_Y 0x02 +#define SCPDR_TS_SCAN_X 0x01 + +#define SCPCR_TS_ENABLE 0x405 +#define SCPCR_TS_MASK 0xc0f + +#define ADC_CHANNEL_TS_Y 1 +#define ADC_CHANNEL_TS_X 2 #define HD64461_GPADR_SPEAKER 0x01 #define HD64461_GPADR_PCMCIA0 (0x02|0x08) @@ -16,4 +29,3 @@ #endif /* __ASM_SH_HP6XX_H */ - -- cgit v1.2.3 From 1d7cddf956a9a4be550b7bd4fc282a1ca362c8e2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:25:06 -0700 Subject: [PATCH] sh: dma-mapping updates. From: Paul Mundt This updates the sh dma-mapping code, as well as doing some cleanup in the consistent API. We also add a consistent_{alloc,free} to the machvec for platforms that need special handling. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/consistent.c | 40 +++++++++++++++++++++------------------- include/asm-sh/dma-mapping.h | 32 ++++++++++++++++++++++++++++++++ include/asm-sh/machvec.h | 4 ++++ 3 files changed, 57 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index f988035c7c86..789bacf1a7aa 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -24,56 +24,58 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle) if (!page) return NULL; - ret = (void *)P2SEGADDR(page_to_bus(page)); + ret = page_address(page); + *handle = virt_to_phys(ret); /* * We must flush the cache before we pass it on to the device */ dma_cache_wback_inv(ret, size); - *handle = (unsigned long)ret; - + page = virt_to_page(ret); free = page + (size >> PAGE_SHIFT); end = page + (1 << order); - do { + while (++page < end) { set_page_count(page, 1); - page++; - } while (size -= PAGE_SIZE); - /* - * Free any unused pages - */ - while (page < end) { - set_page_count(page, 1); - __free_page(page); - page++; + /* Free any unused pages */ + if (page >= free) { + __free_page(page); + } } - return ret; + return P2SEGADDR(ret); } void consistent_free(void *vaddr, size_t size) { unsigned long addr = P1SEGADDR((unsigned long)vaddr); + struct page *page=virt_to_page(addr); + int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT; + int i; - free_pages(addr, get_order(size)); + for(i=0;ibus == &pci_bus_type) return __pci_alloc_consistent(NULL, size, dma_handle); #endif + if (sh_mv.mv_consistent_alloc) + return sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag); return consistent_alloc(flag, size, dma_handle); } @@ -61,6 +63,11 @@ static inline void dma_free_coherent(struct device *dev, size_t size, } #endif + if (sh_mv.mv_consistent_free) { + sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle); + return; + } + consistent_free(vaddr, size); } @@ -152,6 +159,26 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, } } +static inline void dma_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_single"))); + +static inline void dma_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_single"))); + +static inline void dma_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sg, int nelems, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_sg"))); + +static inline void dma_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nelems, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_sg"))); + static inline int dma_get_cache_alignment(void) { /* @@ -161,5 +188,10 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } +static inline int dma_mapping_error(dma_addr_t dma_addr) +{ + return dma_addr == 0; +} + #endif /* __ASM_SH_DMA_MAPPING_H */ diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index 4953570c961d..8a2e3dcd1779 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -17,6 +17,7 @@ #include #include +struct device; struct timeval; struct sh_machine_vector @@ -62,6 +63,9 @@ struct sh_machine_vector void (*mv_init_pci)(void); void (*mv_heartbeat)(void); + + void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int); + void (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t); }; extern struct sh_machine_vector sh_mv; -- cgit v1.2.3 From 4f226c11bb27fd52b674c88eb21a9d426135bacb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:25:17 -0700 Subject: [PATCH] sh: DMA driver updates. From: Paul Mundt This updates the SuperH DMA driver, as well as cleaning up the registration interface. We also drop the use of bitfields in dma-sh since things like the SH4-202, 7751R, 7760, etc. all have a completely different set of register definitions. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/drivers/dma/Makefile | 1 + arch/sh/drivers/dma/dma-api.c | 175 ++++++++++++++++++++++++++++++---------- arch/sh/drivers/dma/dma-isa.c | 29 +++++-- arch/sh/drivers/dma/dma-sh.c | 164 +++++++++++++++++++------------------ arch/sh/drivers/dma/dma-sysfs.c | 133 ++++++++++++++++++++++++++++++ include/asm-sh/cpu-sh4/dma.h | 10 +++ include/asm-sh/dma.h | 71 +++++++++++----- 7 files changed, 438 insertions(+), 145 deletions(-) create mode 100644 arch/sh/drivers/dma/dma-sysfs.c (limited to 'include') diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile index e8941854252c..065d4c90970e 100644 --- a/arch/sh/drivers/dma/Makefile +++ b/arch/sh/drivers/dma/Makefile @@ -3,6 +3,7 @@ # obj-y += dma-api.o dma-isa.o +obj-$(CONFIG_SYSFS) += dma-sysfs.o obj-$(CONFIG_SH_DMA) += dma-sh.o obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index f8b352d4b091..3fc34e1cf7df 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -3,23 +3,24 @@ * * SuperH-specific DMA management API * - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * 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. - */ + */ #include #include #include #include #include +#include #include -struct dma_info dma_info[MAX_DMA_CHANNELS] = { { 0, } }; spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(registered_dmac_list); -/* +/* * A brief note about the reasons for this API as it stands. * * For starters, the old ISA DMA API didn't work for us for a number of @@ -54,124 +55,213 @@ spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; struct dma_info *get_dma_info(unsigned int chan) { - return dma_info + chan; + struct list_head *pos, *tmp; + unsigned int total = 0; + + /* + * Look for each DMAC's range to determine who the owner of + * the channel is. + */ + list_for_each_safe(pos, tmp, ®istered_dmac_list) { + struct dma_info *info = list_entry(pos, struct dma_info, list); + + total += info->nr_channels; + if (chan > total) + continue; + + return info; + } + + return NULL; +} + +struct dma_channel *get_dma_channel(unsigned int chan) +{ + struct dma_info *info = get_dma_info(chan); + + if (!info) + return ERR_PTR(-EINVAL); + + return info->channels + chan; } int get_dma_residue(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->get_residue) - return info->ops->get_residue(info); - + return info->ops->get_residue(channel); + return 0; } int request_dma(unsigned int chan, const char *dev_id) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - down(&info->sem); + down(&channel->sem); if (!info->ops || chan >= MAX_DMA_CHANNELS) { - up(&info->sem); + up(&channel->sem); return -EINVAL; } - - atomic_set(&info->busy, 1); - info->dev_id = dev_id; + atomic_set(&channel->busy, 1); - up(&info->sem); + strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id)); + + up(&channel->sem); if (info->ops->request) - return info->ops->request(info); - + return info->ops->request(channel); + return 0; } void free_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->free) - info->ops->free(info); - - atomic_set(&info->busy, 0); + info->ops->free(channel); + + atomic_set(&channel->busy, 0); } void dma_wait_for_completion(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - if (info->tei_capable) { - wait_event(info->wait_queue, (info->ops->get_residue(info) == 0)); + if (channel->flags & DMA_TEI_CAPABLE) { + wait_event(channel->wait_queue, + (info->ops->get_residue(channel) == 0)); return; } - while (info->ops->get_residue(info)) + while (info->ops->get_residue(channel)) cpu_relax(); } void dma_configure_channel(unsigned int chan, unsigned long flags) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->configure) - info->ops->configure(info, flags); + info->ops->configure(channel, flags); } int dma_xfer(unsigned int chan, unsigned long from, unsigned long to, size_t size, unsigned int mode) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->sar = from; - info->dar = to; - info->count = size; - info->mode = mode; + channel->sar = from; + channel->dar = to; + channel->count = size; + channel->mode = mode; - return info->ops->xfer(info); + return info->ops->xfer(channel); } #ifdef CONFIG_PROC_FS static int dma_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data) { - struct dma_info *info; + struct list_head *pos, *tmp; char *p = buf; - int i; - for (i = 0, info = dma_info; i < MAX_DMA_CHANNELS; i++, info++) { - if (!atomic_read(&info->busy)) - continue; + if (list_empty(®istered_dmac_list)) + return 0; + + /* + * Iterate over each registered DMAC + */ + list_for_each_safe(pos, tmp, ®istered_dmac_list) { + struct dma_info *info = list_entry(pos, struct dma_info, list); + int i; - p += sprintf(p, "%2d: %14s %s\n", i, - info->ops->name, info->dev_id); + /* + * Iterate over each channel + */ + for (i = 0; i < info->nr_channels; i++) { + struct dma_channel *channel = info->channels + i; + + if (!(channel->flags & DMA_CONFIGURED)) + continue; + + p += sprintf(p, "%2d: %14s %s\n", i, + info->name, channel->dev_id); + } } return p - buf; } #endif -int __init register_dmac(struct dma_ops *ops) + +int __init register_dmac(struct dma_info *info) { int i; - printk("DMA: Registering %s handler.\n", ops->name); + INIT_LIST_HEAD(&info->list); + + printk(KERN_INFO "DMA: Registering %s handler (%d channels).\n", + info->name, info->nr_channels); + + BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); - for (i = 0; i < MAX_DMA_CHANNELS; i++) { - struct dma_info *info = get_dma_info(i); + /* + * Don't touch pre-configured channels + */ + if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) { + unsigned int size; - info->chan = i; + size = sizeof(struct dma_channel) * info->nr_channels; - init_MUTEX(&info->sem); - init_waitqueue_head(&info->wait_queue); + info->channels = kmalloc(size, GFP_KERNEL); + if (!info->channels) + return -ENOMEM; + + memset(info->channels, 0, size); } + for (i = 0; i < info->nr_channels; i++) { + struct dma_channel *chan = info->channels + i; + + chan->chan = i; + + memcpy(chan->dev_id, "Unused", 7); + + if (info->flags & DMAC_CHANNELS_TEI_CAPABLE) + chan->flags |= DMA_TEI_CAPABLE; + + init_MUTEX(&chan->sem); + init_waitqueue_head(&chan->wait_queue); + +#ifdef CONFIG_SYSFS + dma_create_sysfs_files(chan); +#endif + } + + list_add(&info->list, ®istered_dmac_list); + return 0; } +void __exit unregister_dmac(struct dma_info *info) +{ + if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) + kfree(info->channels); + + list_del(&info->list); +} + static int __init dma_api_init(void) { printk("DMA: Registering DMA API.\n"); @@ -191,8 +281,11 @@ MODULE_LICENSE("GPL"); EXPORT_SYMBOL(request_dma); EXPORT_SYMBOL(free_dma); +EXPORT_SYMBOL(register_dmac); +EXPORT_SYMBOL(unregister_dmac); EXPORT_SYMBOL(get_dma_residue); EXPORT_SYMBOL(get_dma_info); +EXPORT_SYMBOL(get_dma_channel); EXPORT_SYMBOL(dma_xfer); EXPORT_SYMBOL(dma_wait_for_completion); EXPORT_SYMBOL(dma_configure_channel); diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c index 01564983b967..1c9bc45b8bcb 100644 --- a/arch/sh/drivers/dma/dma-isa.c +++ b/arch/sh/drivers/dma/dma-isa.c @@ -3,13 +3,14 @@ * * Generic ISA DMA wrapper for SH DMA API * - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * 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. - */ + */ #include +#include #include /* @@ -39,55 +40,67 @@ unsigned long __deprecated claim_dma_lock(void) return flags; } +EXPORT_SYMBOL(claim_dma_lock); void __deprecated release_dma_lock(unsigned long flags) { spin_unlock_irqrestore(&dma_spin_lock, flags); } +EXPORT_SYMBOL(release_dma_lock); void __deprecated disable_dma(unsigned int chan) { /* Nothing */ } +EXPORT_SYMBOL(disable_dma); void __deprecated enable_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->ops->xfer(info); + info->ops->xfer(channel); } +EXPORT_SYMBOL(enable_dma); void clear_dma_ff(unsigned int chan) { /* Nothing */ } +EXPORT_SYMBOL(clear_dma_ff); void set_dma_mode(unsigned int chan, char mode) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->mode = mode; + channel->mode = mode; } +EXPORT_SYMBOL(set_dma_mode); void set_dma_addr(unsigned int chan, unsigned int addr) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; /* * Single address mode is the only thing supported through * this interface. */ - if ((info->mode & DMA_MODE_MASK) == DMA_MODE_READ) { - info->sar = addr; + if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) { + channel->sar = addr; } else { - info->dar = addr; + channel->dar = addr; } } +EXPORT_SYMBOL(set_dma_addr); void set_dma_count(unsigned int chan, unsigned int count) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->count = count; + channel->count = count; } +EXPORT_SYMBOL(set_dma_count); diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index ec3ff5044744..31dacd4444b2 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -1,10 +1,10 @@ /* - * arch/sh/kernel/cpu/dma.c + * arch/sh/drivers/dma/dma-sh.c * - * Copyright (C) 2000 Takashi YOSHII - * Copyright (C) 2003 Paul Mundt + * SuperH On-chip DMAC Support * - * PC like DMA API for SuperH's DMAC. + * Copyright (C) 2000 Takashi YOSHII + * Copyright (C) 2003, 2004 Paul Mundt * * 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 @@ -29,43 +29,29 @@ * Defaults to a 64-bit transfer size. */ enum { - XMIT_SZ_64BIT = 0, - XMIT_SZ_8BIT = 1, - XMIT_SZ_16BIT = 2, - XMIT_SZ_32BIT = 3, - XMIT_SZ_256BIT = 4, + XMIT_SZ_64BIT, + XMIT_SZ_8BIT, + XMIT_SZ_16BIT, + XMIT_SZ_32BIT, + XMIT_SZ_256BIT, }; /* * The DMA count is defined as the number of bytes to transfer. */ static unsigned int ts_shift[] = { - [XMIT_SZ_64BIT] 3, - [XMIT_SZ_8BIT] 0, - [XMIT_SZ_16BIT] 1, - [XMIT_SZ_32BIT] 2, - [XMIT_SZ_256BIT] 5, -}; - -struct sh_dmac_channel { - unsigned long sar; - unsigned long dar; - unsigned long dmatcr; - unsigned long chcr; -} __attribute__ ((aligned(16))); - -struct sh_dmac_info { - struct sh_dmac_channel channel[4]; - unsigned long dmaor; + [XMIT_SZ_64BIT] = 3, + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + [XMIT_SZ_256BIT] = 5, }; -static volatile struct sh_dmac_info *sh_dmac = (volatile struct sh_dmac_info *)SH_DMAC_BASE; - static inline unsigned int get_dmte_irq(unsigned int chan) { unsigned int irq; - /* + /* * Normally we could just do DMTE0_IRQ + chan outright, though in the * case of the 7751R, the DMTE IRQs for channels > 4 start right above * the SCIF @@ -84,13 +70,17 @@ static inline unsigned int get_dmte_irq(unsigned int chan) * We determine the correct shift size based off of the CHCR transmit size * for the given channel. Since we know that it will take: * - * info->count >> ts_shift[transmit_size] + * info->count >> ts_shift[transmit_size] * * iterations to complete the transfer. */ -static inline unsigned int calc_xmit_shift(struct dma_info *info) +static inline unsigned int calc_xmit_shift(struct dma_channel *chan) { - return ts_shift[(sh_dmac->channel[info->chan].chcr >> 4) & 0x0007]; + u32 chcr = ctrl_inl(CHCR[chan->chan]); + + chcr >>= 4; + + return ts_shift[chcr & 0x0007]; } /* @@ -101,68 +91,79 @@ static inline unsigned int calc_xmit_shift(struct dma_info *info) */ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) { - struct dma_info * info = (struct dma_info *)dev_id; - u32 chcr = sh_dmac->channel[info->chan].chcr; + struct dma_channel *chan = (struct dma_channel *)dev_id; + u32 chcr; + + chcr = ctrl_inl(CHCR[chan->chan]); if (!(chcr & CHCR_TE)) return IRQ_NONE; - sh_dmac->channel[info->chan].chcr = chcr & ~(CHCR_IE | CHCR_DE); + chcr &= ~(CHCR_IE | CHCR_DE); + ctrl_outl(chcr, CHCR[chan->chan]); - wake_up(&info->wait_queue); + wake_up(&chan->wait_queue); return IRQ_HANDLED; } -static int sh_dmac_request_dma(struct dma_info *info) +static int sh_dmac_request_dma(struct dma_channel *chan) { - return request_irq(get_dmte_irq(info->chan), dma_tei, - SA_INTERRUPT, "DMAC Transfer End", info); + return request_irq(get_dmte_irq(chan->chan), dma_tei, + SA_INTERRUPT, "DMAC Transfer End", chan); } -static void sh_dmac_free_dma(struct dma_info *info) +static void sh_dmac_free_dma(struct dma_channel *chan) { - free_irq(get_dmte_irq(info->chan), info); + free_irq(get_dmte_irq(chan->chan), chan); } -static void sh_dmac_configure_channel(struct dma_info *info, unsigned long chcr) +static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) { if (!chcr) chcr = RS_DUAL; - sh_dmac->channel[info->chan].chcr = chcr; + ctrl_outl(chcr, CHCR[chan->chan]); - info->configured = 1; + chan->flags |= DMA_CONFIGURED; } -static void sh_dmac_enable_dma(struct dma_info *info) +static void sh_dmac_enable_dma(struct dma_channel *chan) { - int irq = get_dmte_irq(info->chan); + int irq = get_dmte_irq(chan->chan); + u32 chcr; + + chcr = ctrl_inl(CHCR[chan->chan]); + chcr |= CHCR_DE | CHCR_IE; + ctrl_outl(chcr, CHCR[chan->chan]); - sh_dmac->channel[info->chan].chcr |= (CHCR_DE | CHCR_IE); enable_irq(irq); } -static void sh_dmac_disable_dma(struct dma_info *info) +static void sh_dmac_disable_dma(struct dma_channel *chan) { - int irq = get_dmte_irq(info->chan); + int irq = get_dmte_irq(chan->chan); + u32 chcr; disable_irq(irq); - sh_dmac->channel[info->chan].chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); + + chcr = ctrl_inl(CHCR[chan->chan]); + chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); + ctrl_outl(chcr, CHCR[chan->chan]); } -static int sh_dmac_xfer_dma(struct dma_info *info) +static int sh_dmac_xfer_dma(struct dma_channel *chan) { - /* + /* * If we haven't pre-configured the channel with special flags, use * the defaults. */ - if (!info->configured) - sh_dmac_configure_channel(info, 0); + if (!(chan->flags & DMA_CONFIGURED)) + sh_dmac_configure_channel(chan, 0); + + sh_dmac_disable_dma(chan); - sh_dmac_disable_dma(info); - - /* + /* * Single-address mode usage note! * * It's important that we don't accidentally write any value to SAR/DAR @@ -177,33 +178,36 @@ static int sh_dmac_xfer_dma(struct dma_info *info) * cascading to the PVR2 DMAC. In this case, we still need to write * SAR and DAR, regardless of value, in order for cascading to work. */ - if (info->sar || (mach_is_dreamcast() && info->chan == 2)) - sh_dmac->channel[info->chan].sar = info->sar; - if (info->dar || (mach_is_dreamcast() && info->chan == 2)) - sh_dmac->channel[info->chan].dar = info->dar; - - sh_dmac->channel[info->chan].dmatcr = info->count >> calc_xmit_shift(info); + if (chan->sar || (mach_is_dreamcast() && chan->chan == 2)) + ctrl_outl(chan->sar, SAR[chan->chan]); + if (chan->dar || (mach_is_dreamcast() && chan->chan == 2)) + ctrl_outl(chan->dar, DAR[chan->chan]); + + ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); - sh_dmac_enable_dma(info); + sh_dmac_enable_dma(chan); return 0; } -static int sh_dmac_get_dma_residue(struct dma_info *info) +static int sh_dmac_get_dma_residue(struct dma_channel *chan) { - if (!(sh_dmac->channel[info->chan].chcr & CHCR_DE)) + if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE)) return 0; - return sh_dmac->channel[info->chan].dmatcr << calc_xmit_shift(info); + return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); } #if defined(CONFIG_CPU_SH4) static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) { - printk("DMAE: DMAOR=%lx\n", sh_dmac->dmaor); + unsigned long dmaor = ctrl_inl(DMAOR); - sh_dmac->dmaor &= ~(DMAOR_NMIF | DMAOR_AE); - sh_dmac->dmaor |= DMAOR_DME; + printk("DMAE: DMAOR=%lx\n", dmaor); + + ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR); + ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR); + ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR); disable_irq(irq); @@ -212,16 +216,23 @@ static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) #endif static struct dma_ops sh_dmac_ops = { - .name = "SuperH DMAC", .request = sh_dmac_request_dma, .free = sh_dmac_free_dma, .get_residue = sh_dmac_get_dma_residue, .xfer = sh_dmac_xfer_dma, .configure = sh_dmac_configure_channel, }; - + +static struct dma_info sh_dmac_info = { + .name = "SuperH DMAC", + .nr_channels = 4, + .ops = &sh_dmac_ops, + .flags = DMAC_CHANNELS_TEI_CAPABLE, +}; + static int __init sh_dmac_init(void) { + struct dma_info *info = &sh_dmac_info; int i; #ifdef CONFIG_CPU_SH4 @@ -231,18 +242,15 @@ static int __init sh_dmac_init(void) return i; #endif - for (i = 0; i < MAX_DMAC_CHANNELS; i++) { + for (i = 0; i < info->nr_channels; i++) { int irq = get_dmte_irq(i); make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - - dma_info[i].ops = &sh_dmac_ops; - dma_info[i].tei_capable = 1; } - sh_dmac->dmaor |= 0x8000 | DMAOR_DME; + ctrl_outl(0x8000 | DMAOR_DME, DMAOR); - return register_dmac(&sh_dmac_ops); + return register_dmac(info); } static void __exit sh_dmac_exit(void) diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c new file mode 100644 index 000000000000..71a6d4e7809f --- /dev/null +++ b/arch/sh/drivers/dma/dma-sysfs.c @@ -0,0 +1,133 @@ +/* + * arch/sh/drivers/dma/dma-sysfs.c + * + * sysfs interface for SH DMA API + * + * Copyright (C) 2004 Paul Mundt + * + * 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. + */ +#include +#include +#include +#include +#include + +static struct sysdev_class dma_sysclass = { + set_kset_name("dma"), +}; + +EXPORT_SYMBOL(dma_sysclass); + +static ssize_t dma_show_devices(struct sys_device *dev, char *buf) +{ + ssize_t len = 0; + int i; + + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + struct dma_info *info = get_dma_info(i); + struct dma_channel *channel = &info->channels[i]; + + len += sprintf(buf + len, "%2d: %14s %s\n", + channel->chan, info->name, + channel->dev_id); + } + + return len; +} + +static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL); + +static int __init dma_sysclass_init(void) +{ + int ret; + + ret = sysdev_class_register(&dma_sysclass); + if (ret == 0) + sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr); + + return ret; +} + +postcore_initcall(dma_sysclass_init); + +static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf) +{ + struct dma_channel *channel = to_dma_channel(dev); + return sprintf(buf, "%s\n", channel->dev_id); +} + +static ssize_t dma_store_dev_id(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + strcpy(channel->dev_id, buf); + return count; +} + +static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); + +static ssize_t dma_store_config(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + unsigned long config; + + config = simple_strtoul(buf, NULL, 0); + dma_configure_channel(channel->chan, config); + + return count; +} + +static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config); + +static ssize_t dma_show_mode(struct sys_device *dev, char *buf) +{ + struct dma_channel *channel = to_dma_channel(dev); + return sprintf(buf, "0x%08x\n", channel->mode); +} + +static ssize_t dma_store_mode(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + channel->mode = simple_strtoul(buf, NULL, 0); + return count; +} + +static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); + +#define dma_ro_attr(field, fmt) \ +static ssize_t dma_show_##field(struct sys_device *dev, char *buf) \ +{ \ + struct dma_channel *channel = to_dma_channel(dev); \ + return sprintf(buf, fmt, channel->field); \ +} \ +static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); + +dma_ro_attr(count, "0x%08x\n"); +dma_ro_attr(flags, "0x%08lx\n"); + +int __init dma_create_sysfs_files(struct dma_channel *chan) +{ + struct sys_device *dev = &chan->dev; + int ret; + + dev->id = chan->chan; + dev->cls = &dma_sysclass; + + ret = sysdev_register(dev); + if (ret) + return ret; + + sysdev_create_file(dev, &attr_dev_id); + sysdev_create_file(dev, &attr_count); + sysdev_create_file(dev, &attr_mode); + sysdev_create_file(dev, &attr_flags); + sysdev_create_file(dev, &attr_config); + + return 0; +} + diff --git a/include/asm-sh/cpu-sh4/dma.h b/include/asm-sh/cpu-sh4/dma.h index 3ef2d0a54668..e2b91adf821a 100644 --- a/include/asm-sh/cpu-sh4/dma.h +++ b/include/asm-sh/cpu-sh4/dma.h @@ -3,5 +3,15 @@ #define SH_DMAC_BASE 0xffa00000 +#define SAR ((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \ + SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30}) +#define DAR ((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \ + SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34}) +#define DMATCR ((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \ + SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38}) +#define CHCR ((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \ + SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c}) +#define DMAOR (SH_DMAC_BASE + 0x40) + #endif /* __ASM_CPU_SH4_DMA_H */ diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h index bc5c3b6a215d..f9b95e2116f5 100644 --- a/include/asm-sh/dma.h +++ b/include/asm-sh/dma.h @@ -1,7 +1,7 @@ /* * include/asm-sh/dma.h * - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * 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 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,7 @@ # define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) #endif -/* +/* * Read and write modes can mean drastically different things depending on the * channel configuration. Consult your DMAC documentation and module * implementation for further clues. @@ -38,40 +39,69 @@ #define DMA_MODE_WRITE 0x01 #define DMA_MODE_MASK 0x01 +#define DMA_AUTOINIT 0x10 + +/* + * DMAC (dma_info) flags + */ +enum { + DMAC_CHANNELS_CONFIGURED = 0x00, + DMAC_CHANNELS_TEI_CAPABLE = 0x01, +}; + +/* + * DMA channel capabilities / flags + */ +enum { + DMA_CONFIGURED = 0x00, + DMA_TEI_CAPABLE = 0x01, +}; + extern spinlock_t dma_spin_lock; -struct dma_info; +struct dma_channel; struct dma_ops { - const char *name; - - int (*request)(struct dma_info *info); - void (*free)(struct dma_info *info); + int (*request)(struct dma_channel *chan); + void (*free)(struct dma_channel *chan); - int (*get_residue)(struct dma_info *info); - int (*xfer)(struct dma_info *info); - void (*configure)(struct dma_info *info, unsigned long flags); + int (*get_residue)(struct dma_channel *chan); + int (*xfer)(struct dma_channel *chan); + void (*configure)(struct dma_channel *chan, unsigned long flags); }; -struct dma_info { - const char *dev_id; +struct dma_channel { + char dev_id[16]; unsigned int chan; unsigned int mode; unsigned int count; - + unsigned long sar; unsigned long dar; - unsigned int configured:1; - unsigned int tei_capable:1; + unsigned long flags; atomic_t busy; struct semaphore sem; wait_queue_head_t wait_queue; + + struct sys_device dev; +}; + +struct dma_info { + const char *name; + unsigned int nr_channels; + unsigned long flags; + struct dma_ops *ops; + struct dma_channel *channels; + + struct list_head list; }; +#define to_dma_channel(channel) container_of(channel, struct dma_channel, dev) + /* arch/sh/drivers/dma/dma-api.c */ extern int dma_xfer(unsigned int chan, unsigned long from, unsigned long to, size_t size, unsigned int mode); @@ -90,17 +120,22 @@ extern int request_dma(unsigned int chan, const char *dev_id); extern void free_dma(unsigned int chan); extern int get_dma_residue(unsigned int chan); extern struct dma_info *get_dma_info(unsigned int chan); +extern struct dma_channel *get_dma_channel(unsigned int chan); extern void dma_wait_for_completion(unsigned int chan); extern void dma_configure_channel(unsigned int chan, unsigned long flags); -extern int register_dmac(struct dma_ops *ops); +extern int register_dmac(struct dma_info *info); +extern void unregister_dmac(struct dma_info *info); -extern struct dma_info dma_info[]; +#ifdef CONFIG_SYSFS +/* arch/sh/drivers/dma/dma-sysfs.c */ +extern int dma_create_sysfs_files(struct dma_channel *); +#endif #ifdef CONFIG_PCI extern int isa_dma_bridge_buggy; #else -#define isa_dma_bridge_buggy (0) +#define isa_dma_bridge_buggy (0) #endif #endif /* __ASM_SH_DMA_H */ -- cgit v1.2.3 From 6b5ed4ca427d6e2d4d3dc0cb0d347e790208ed45 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:25:41 -0700 Subject: [PATCH] sh: fixmap support. From: Paul Mundt This adds fixmap support for sh. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/init.c | 62 +++++++++++++++++++++++++- include/asm-sh/fixmap.h | 111 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-sh/pgtable.h | 5 ++- 3 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 include/asm-sh/fixmap.h (limited to 'include') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 7b2bcad145ca..7b49b6976e78 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -3,7 +3,7 @@ * linux/arch/sh/mm/init.c * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 Paul Mundt + * Copyright (C) 2002, 2004 Paul Mundt * * Based on linux/arch/i386/mm/init.c: * Copyright (C) 1995 Linus Torvalds @@ -83,6 +83,66 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + pgd = swapper_pg_dir + pgd_index(addr); + if (pgd_none(*pgd)) { + pgd_ERROR(*pgd); + return; + } + + pmd = pmd_offset(pgd, addr); + if (pmd_none(*pmd)) { + pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { + pmd_ERROR(*pmd); + return; + } + } + + pte = pte_offset_kernel(pmd, addr); + if (!pte_none(*pte)) { + pte_ERROR(*pte); + return; + } + + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); + + __flush_tlb_page(get_asid(), addr); +} + +/* + * As a performance optimization, other platforms preserve the fixmap mapping + * across a context switch, we don't presently do this, but this could be done + * in a similar fashion as to the wired TLB interface that sh64 uses (by way + * of the memorry mapped UTLB configuration) -- this unfortunately forces us to + * give up a TLB entry for each mapping we want to preserve. While this may be + * viable for a small number of fixmaps, it's not particularly useful for + * everything and needs to be carefully evaluated. (ie, we may want this for + * the vsyscall page). + * + * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass + * in at __set_fixmap() time to determine the appropriate behavior to follow. + * + * -- PFM. + */ +void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + BUG(); + return; + } + + set_pte_phys(address, phys, prot); +} + /* References to section boundaries */ extern char _text, _etext, _edata, __bss_start, _end; diff --git a/include/asm-sh/fixmap.h b/include/asm-sh/fixmap.h new file mode 100644 index 000000000000..509224bdba28 --- /dev/null +++ b/include/asm-sh/fixmap.h @@ -0,0 +1,111 @@ +/* + * fixmap.h: compile-time virtual memory allocation + * + * 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) 1998 Ingo Molnar + * + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + */ + +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +#include +#include +#include +#ifdef CONFIG_HIGHMEM +#include +#include +#endif + +/* + * Here we define all the compile-time 'special' virtual + * addresses. The point is to have a constant address at + * compile time, but to set the physical address only + * in the boot process. We allocate these special addresses + * from the end of virtual memory (0xfffff000) backwards. + * Also this lets us do fail-safe vmalloc(), we + * can guarantee that these special addresses and + * vmalloc()-ed addresses never overlap. + * + * these 'compile-time allocated' memory buffers are + * fixed-size 4k pages. (or larger if used with an increment + * highger than 1) use fixmap_set(idx,phys) to associate + * physical memory with fixmap indices. + * + * TLB entries of such buffers will not be flushed across + * task switches. + */ + +/* + * on UP currently we will have no trace of the fixmap mechanizm, + * no page table allocations, etc. This might change in the + * future, say framebuffers for the console driver(s) could be + * fix-mapped? + */ +enum fixed_addresses { +#ifdef CONFIG_HIGHMEM + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, +#endif + __end_of_fixed_addresses +}; + +extern void __set_fixmap (enum fixed_addresses idx, + unsigned long phys, pgprot_t flags); + +#define set_fixmap(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL) +/* + * Some hardware wants to get fixmapped without caching. + */ +#define set_fixmap_nocache(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) +/* + * used by vmalloc.c. + * + * Leave one empty page between vmalloc'ed areas and + * the start of the fixmap, and leave one page empty + * at the top of mem.. + */ +#define FIXADDR_TOP (P4SEG - PAGE_SIZE) +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) + +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) +#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) + +extern void __this_fixmap_does_not_exist(void); + +/* + * 'index to address' translation. If anyone tries to use the idx + * directly without tranlation, we catch the bug with a NULL-deference + * kernel oops. Illegal ranges of incoming indices are caught too. + */ +static inline unsigned long fix_to_virt(const unsigned int idx) +{ + /* + * this branch gets completely eliminated after inlining, + * except when someone tries to use fixaddr indices in an + * illegal way. (such as mixing up address types or using + * out-of-range indices). + * + * If it doesn't get removed, the linker will complain + * loudly with a reasonably clear error message.. + */ + if (idx >= __end_of_fixed_addresses) + __this_fixmap_does_not_exist(); + + return __fix_to_virt(idx); +} + +static inline unsigned long virt_to_fix(const unsigned long vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + return __virt_to_fix(vaddr); +} + +#endif diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index 292511404349..e768b7bcd1e8 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -3,7 +3,7 @@ /* * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002, 2003, 2004 Paul Mundt */ #include @@ -16,6 +16,7 @@ #ifndef __ASSEMBLY__ #include #include +#include #include extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; @@ -51,7 +52,7 @@ extern unsigned long empty_zero_page[1024]; * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c) */ #define VMALLOC_START (P3SEG+0x00100000) -#define VMALLOC_END P4SEG +#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) #define _PAGE_WT 0x001 /* WT-bit on SH-4, 0 on SH-3 */ #define _PAGE_HW_SHARED 0x002 /* SH-bit : page is shared among processes */ -- cgit v1.2.3 From 89a5c48b30d0155e5e2ba62c700d4a3e5ec60ff6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:25:52 -0700 Subject: [PATCH] sh: Renesas HS7751RVoIP board support. From: Paul Mundt This adds support for the Renesas Technology Sales HS7751RVoIP board. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/renesas/hs7751rvoip/Makefile | 12 ++ arch/sh/boards/renesas/hs7751rvoip/io.c | 310 ++++++++++++++++++++++++++++ arch/sh/boards/renesas/hs7751rvoip/irq.c | 122 +++++++++++ arch/sh/boards/renesas/hs7751rvoip/led.c | 27 +++ arch/sh/boards/renesas/hs7751rvoip/mach.c | 55 +++++ arch/sh/boards/renesas/hs7751rvoip/pci.c | 150 ++++++++++++++ arch/sh/boards/renesas/hs7751rvoip/setup.c | 89 ++++++++ include/asm-sh/hs7751rvoip/hs7751rvoip.h | 47 +++++ include/asm-sh/hs7751rvoip/ide.h | 8 + include/asm-sh/hs7751rvoip/io.h | 39 ++++ 10 files changed, 859 insertions(+) create mode 100644 arch/sh/boards/renesas/hs7751rvoip/Makefile create mode 100644 arch/sh/boards/renesas/hs7751rvoip/io.c create mode 100644 arch/sh/boards/renesas/hs7751rvoip/irq.c create mode 100644 arch/sh/boards/renesas/hs7751rvoip/led.c create mode 100644 arch/sh/boards/renesas/hs7751rvoip/mach.c create mode 100644 arch/sh/boards/renesas/hs7751rvoip/pci.c create mode 100644 arch/sh/boards/renesas/hs7751rvoip/setup.c create mode 100644 include/asm-sh/hs7751rvoip/hs7751rvoip.h create mode 100644 include/asm-sh/hs7751rvoip/ide.h create mode 100644 include/asm-sh/hs7751rvoip/io.h (limited to 'include') diff --git a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile new file mode 100644 index 000000000000..e8b4109ace11 --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the HS7751RVoIP specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := mach.o setup.o io.o irq.o led.o + +obj-$(CONFIG_PCI) += pci.o + diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c new file mode 100644 index 000000000000..a2ecd2d6af53 --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/io.c @@ -0,0 +1,310 @@ +/* + * linux/arch/sh/kernel/io_hs7751rvoip.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Renesas Technology sales HS7751RVoIP + * + * Initial version only to support LAN access; some + * placeholder code from io_hs7751rvoip.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + +extern void *area5_io8_base; /* Area 5 8bit I/O Base address */ +extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ +extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ +extern void *area6_io16_base; /* Area 6 16bit I/O Base address */ + +/* + * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC) + * of the 7751R processor, and has a SuperIO accessible via the PCI. + * The board also includes a PCMCIA controller on its memory bus, + * like the other Solution Engine boards. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#if defined(CONFIG_HS7751RVOIP_CODEC) +#define CODEC_IO_BASE 0x1000 +#endif + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return ((unsigned long)area5_io16_base + 0x0c); + else + return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1)); + else + maybebadio(port2adr, (unsigned long)port); + return port; +} + +/* The 7751R HS7751RVoIP seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +#if defined(CONFIG_HS7751RVOIP_CODEC) +static inline int +codec_port(unsigned long port) +{ + if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20)) + return 1; + else + return 0; +} +#endif + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char hs7751rvoip_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else + return (*(volatile unsigned short *)port2adr(port) & 0xff); +} + +unsigned char hs7751rvoip_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else + v = (*(volatile unsigned short *)port2adr(port) & 0xff); + delay(); + return v; +} + +unsigned short hs7751rvoip_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else + maybebadio(inw, port); + return 0; +} + +unsigned int hs7751rvoip_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); + else + maybebadio(inl, port); + return 0; +} + +void hs7751rvoip_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CIDEC) + else if (codec_port(port)) + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; +} + +void hs7751rvoip_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CIDEC) + else if (codec_port(port)) + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; + delay(); +} + +void hs7751rvoip_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned short *)PCI_IOMAP(port) = value; + else + maybebadio(outw, port); +} + +void hs7751rvoip_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *((unsigned long *)PCI_IOMAP(port)) = value; + else + maybebadio(outl, port); +} + +void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) +{ + if (PXSEG(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + + while (count--) *((volatile unsigned char *) addr)++ = *bp; + } else { + volatile __u16 *p = (volatile unsigned short *)port2adr(port); + + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } +} + +void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *((__u16 *) addr)++ = *p; +} + +void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count) +{ + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *((__u32 *) addr)++ = *p; + } else + maybebadio(insl, port); +} + +void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) +{ + if (PXSEG(port)) + while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + + while (count--) *bp = *((volatile unsigned char *) addr)++; + } else { + volatile __u16 *p = (volatile unsigned short *)port2adr(port); + + while (count--) *p = *((unsigned char *) addr)++; + } +} + +void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((__u16 *) addr)++; +} + +void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) +{ + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *p = *((__u32 *) addr)++; + } else + maybebadio(outsl, port); +} + +void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) +{ + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); +} +EXPORT_SYMBOL(hs7751rvoip_ioremap); + +unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) +{ + return port2adr(offset); +} diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c new file mode 100644 index 000000000000..a7921f67a35f --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -0,0 +1,122 @@ +/* + * linux/arch/sh/boards/renesas/hs7751rvoip/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include +#include +#include +#include + +static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7}; + +static void enable_hs7751rvoip_irq(unsigned int irq); +static void disable_hs7751rvoip_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_hs7751rvoip_irq disable_hs7751rvoip_irq + +static void ack_hs7751rvoip_irq(unsigned int irq); +static void end_hs7751rvoip_irq(unsigned int irq); + +static unsigned int startup_hs7751rvoip_irq(unsigned int irq) +{ + enable_hs7751rvoip_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_hs7751rvoip_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + + /* Set the priority in IPR to 0 */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR3); + val &= mask; + ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); +} + +static void enable_hs7751rvoip_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR3); + val |= value; + ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); +} + +static void ack_hs7751rvoip_irq(unsigned int irq) +{ + disable_hs7751rvoip_irq(irq); +} + +static void end_hs7751rvoip_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_hs7751rvoip_irq(irq); +} + +static struct hw_interrupt_type hs7751rvoip_irq_type = { + "HS7751RVoIP IRQ", + startup_hs7751rvoip_irq, + shutdown_hs7751rvoip_irq, + enable_hs7751rvoip_irq, + disable_hs7751rvoip_irq, + ack_hs7751rvoip_irq, + end_hs7751rvoip_irq, +}; + +static void make_hs7751rvoip_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &hs7751rvoip_irq_type; + disable_hs7751rvoip_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_hs7751rvoip_IRQ(void) +{ + int i; + + /* IRL0=ON HOOK1 + * IRL1=OFF HOOK1 + * IRL2=ON HOOK2 + * IRL3=OFF HOOK2 + * IRL4=Ringing Detection + * IRL5=CODEC + * IRL6=Ethernet + * IRL7=Ethernet Hub + * IRL8=USB Communication + * IRL9=USB Connection + * IRL10=USB DMA + * IRL11=CF Card + * IRL12=PCMCIA + * IRL13=PCI Slot + */ + ctrl_outw(0x9876, IRLCNTR1); + ctrl_outw(0xdcba, IRLCNTR2); + ctrl_outw(0x0050, IRLCNTR4); + ctrl_outw(0x4321, IRLCNTR5); + + for (i=0; i<14; i++) + make_hs7751rvoip_irq(i); +} diff --git a/arch/sh/boards/renesas/hs7751rvoip/led.c b/arch/sh/boards/renesas/hs7751rvoip/led.c new file mode 100644 index 000000000000..18a13c8da8a4 --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/led.c @@ -0,0 +1,27 @@ +/* + * linux/arch/sh/kernel/setup_hs7751rvoip.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include + +extern unsigned int debug_counter; + +void debug_led_disp(void) +{ + unsigned short value; + + value = (unsigned char)debug_counter++; + ctrl_outb((0xf0|value), PA_OUTPORTR); + if (value == 0x0f) + debug_counter = 0; +} diff --git a/arch/sh/boards/renesas/hs7751rvoip/mach.c b/arch/sh/boards/renesas/hs7751rvoip/mach.c new file mode 100644 index 000000000000..8bbed60220ca --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/mach.c @@ -0,0 +1,55 @@ +/* + * linux/arch/sh/kernel/mach_hs7751rvoip.c + * + * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Renesas Technology sales HS7751RVoIP + */ + +#include +#include + +#include +#include +#include +#include + +extern void init_hs7751rvoip_IRQ(void); +extern void *hs7751rvoip_ioremap(unsigned long, unsigned long); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_hs7751rvoip __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = hs7751rvoip_inb, + .mv_inw = hs7751rvoip_inw, + .mv_inl = hs7751rvoip_inl, + .mv_outb = hs7751rvoip_outb, + .mv_outw = hs7751rvoip_outw, + .mv_outl = hs7751rvoip_outl, + + .mv_inb_p = hs7751rvoip_inb_p, + .mv_inw_p = hs7751rvoip_inw, + .mv_inl_p = hs7751rvoip_inl, + .mv_outb_p = hs7751rvoip_outb_p, + .mv_outw_p = hs7751rvoip_outw, + .mv_outl_p = hs7751rvoip_outl, + + .mv_insb = hs7751rvoip_insb, + .mv_insw = hs7751rvoip_insw, + .mv_insl = hs7751rvoip_insl, + .mv_outsb = hs7751rvoip_outsb, + .mv_outsw = hs7751rvoip_outsw, + .mv_outsl = hs7751rvoip_outsl, + + .mv_ioremap = hs7751rvoip_ioremap, + .mv_isa_port2addr = hs7751rvoip_isa_port2addr, + .mv_init_irq = init_hs7751rvoip_IRQ, +}; +ALIAS_MV(hs7751rvoip) diff --git a/arch/sh/boards/renesas/hs7751rvoip/pci.c b/arch/sh/boards/renesas/hs7751rvoip/pci.c new file mode 100644 index 000000000000..7a442d1eca46 --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/pci.c @@ -0,0 +1,150 @@ +/* + * linux/arch/sh/kernel/pci-hs7751rvoip.c + * + * Author: Ian DaSilva (idasilva@mvista.com) + * + * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the Renesas SH7751R HS7751RVoIP board + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../../drivers/pci/pci-sh7751.h" +#include + +#define PCIMCR_MRSET_OFF 0xBFFFFFFF +#define PCIMCR_RFSH_OFF 0xFFFFFFFB + +/* + * Only long word accesses of the PCIC's internal local registers and the + * configuration registers from the CPU is supported. + */ +#define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) +#define PCIC_READ(x) readl(PCI_REG(x)) + +/* + * Description: This function sets up and initializes the pcic, sets + * up the BARS, maps the DRAM into the address space etc, etc. + */ +int __init pcibios_init_platform(void) +{ + unsigned long bcr1, wcr1, wcr2, wcr3, mcr; + unsigned short bcr2, bcr3; + + /* + * Initialize the slave bus controller on the pcic. The values used + * here should not be hardcoded, but they should be taken from the bsc + * on the processor, to make this function as generic as possible. + * (i.e. Another sbc may usr different SDRAM timing settings -- in order + * for the pcic to work, its settings need to be exactly the same.) + */ + bcr1 = (*(volatile unsigned long *)(SH7751_BCR1)); + bcr2 = (*(volatile unsigned short *)(SH7751_BCR2)); + bcr3 = (*(volatile unsigned short *)(SH7751_BCR3)); + wcr1 = (*(volatile unsigned long *)(SH7751_WCR1)); + wcr2 = (*(volatile unsigned long *)(SH7751_WCR2)); + wcr3 = (*(volatile unsigned long *)(SH7751_WCR3)); + mcr = (*(volatile unsigned long *)(SH7751_MCR)); + + bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ + (*(volatile unsigned long *)(SH7751_BCR1)) = bcr1; + + bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ + PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ + PCIC_WRITE(SH7751_PCIBCR3, bcr3); /* PCIC BCR3 */ + PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ + PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ + PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ + mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; + PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ + + /* Enable all interrupts, so we know what to fix */ + PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); + PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); + + /* Set up standard PCI config registers */ + PCIC_WRITE(SH7751_PCICONF1, 0xFB900047); /* Bus Master, Mem & I/O access */ + PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ + PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ + PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ + PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ + PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ + PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ + PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ + PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ + PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ + + /* Now turn it on... */ + PCIC_WRITE(SH7751_PCICR, 0xa5000001); + + /* + * Set PCIMBR and PCIIOBR here, assuming a single window + * (16M MEM, 256K IO) is enough. If a larger space is + * needed, the readx/writex and inx/outx functions will + * have to do more (e.g. setting registers for each call). + */ + + /* + * Set the MBR so PCI address is one-to-one with window, + * meaning all calls go straight through... use ifdef to + * catch erroneous assumption. + */ + BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); + + PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM); + + /* Set IOBR for window containing area specified in pci.h */ + PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); + + /* All done, may as well say so... */ + printk("SH7751R PCI: Finished initialization of the PCI controller\n"); + + return 1; +} + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + switch (slot) { + case 0: return IRQ_PCISLOT; /* PCI Extend slot */ + case 1: return IRQ_PCMCIA; /* PCI Cardbus Bridge */ + case 2: return IRQ_PCIETH; /* Realtek Ethernet controller */ + case 3: return IRQ_PCIHUB; /* Realtek Ethernet Hub controller */ + default: + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } +} + +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = 0x4000, + .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7751_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c new file mode 100644 index 000000000000..f1a78b6c714c --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -0,0 +1,89 @@ +/* + * linux/arch/sh/kernel/setup_hs7751rvoip.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* defined in mm/ioremap.c */ +extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); + +unsigned int debug_counter; + +const char *get_system_type(void) +{ + return "HS7751RVoIP"; +} + +/* + * Initialize the board + */ +void __init platform_setup(void) +{ + printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); + ctrl_outb(0xf0, PA_OUTPORTR); + debug_counter = 0; +} + +void *area5_io8_base; +void *area6_io8_base; +void *area5_io16_base; +void *area6_io16_base; + +int __init cf_init(void) +{ + pgprot_t prot; + unsigned long paddrbase, psize; + + /* open I/O area window */ + paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800)); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16); + area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area5_io16_base) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } + + /* XXX : do we need attribute and common-memory area also? */ + + paddrbase = virt_to_phys((void *)PA_AREA6_IO); + psize = PAGE_SIZE; +#if defined(CONFIG_HS7751RVOIP_CODEC) + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8); +#else + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8); +#endif + area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io8_base) { + printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n"); + return -ENOMEM; + } + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); + area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io16_base) { + printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); + return -ENOMEM; + } + + return 0; +} + +__initcall (cf_init); diff --git a/include/asm-sh/hs7751rvoip/hs7751rvoip.h b/include/asm-sh/hs7751rvoip/hs7751rvoip.h new file mode 100644 index 000000000000..5f995f937a44 --- /dev/null +++ b/include/asm-sh/hs7751rvoip/hs7751rvoip.h @@ -0,0 +1,47 @@ +#ifndef __ASM_SH_RENESAS_HS7751RVOIP_H +#define __ASM_SH_RENESAS_HS7751RVOIP_H + +/* + * linux/include/asm-sh/hs7751rvoip/hs7751rvoip.h + * + * Copyright (C) 2000 Atom Create Engineering Co., Ltd. + * + * Renesas Technology Sales HS7751RVoIP support + */ + +/* Box specific addresses. */ + +#define PA_BCR 0xa4000000 /* FPGA */ +#define PA_SLICCNTR1 0xa4000006 /* SLIC PIO Control 1 */ +#define PA_SLICCNTR2 0xa4000008 /* SLIC PIO Control 2 */ +#define PA_DMACNTR 0xa400000a /* USB DMA Control */ +#define PA_INPORTR 0xa400000c /* Input Port Register */ +#define PA_OUTPORTR 0xa400000e /* Output Port Reguster */ +#define PA_VERREG 0xa4000014 /* FPGA Version Register */ + +#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */ +#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */ +#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ + +#define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ +#define IRLCNTR2 (PA_BCR + 2) /* Interrupt Control Register2 */ +#define IRLCNTR3 (PA_BCR + 4) /* Interrupt Control Register3 */ +#define IRLCNTR4 (PA_BCR + 16) /* Interrupt Control Register4 */ +#define IRLCNTR5 (PA_BCR + 18) /* Interrupt Control Register5 */ + +#define IRQ_PCIETH 6 /* PCI Ethernet IRQ */ +#define IRQ_PCIHUB 7 /* PCI Ethernet Hub IRQ */ +#define IRQ_USBCOM 8 /* USB Comunication IRQ */ +#define IRQ_USBCON 9 /* USB Connect IRQ */ +#define IRQ_USBDMA 10 /* USB DMA IRQ */ +#define IRQ_CFCARD 11 /* CF Card IRQ */ +#define IRQ_PCMCIA 12 /* PCMCIA IRQ */ +#define IRQ_PCISLOT 13 /* PCI Slot #1 IRQ */ +#define IRQ_ONHOOK1 0 /* ON HOOK1 IRQ */ +#define IRQ_OFFHOOK1 1 /* OFF HOOK1 IRQ */ +#define IRQ_ONHOOK2 2 /* ON HOOK2 IRQ */ +#define IRQ_OFFHOOK2 3 /* OFF HOOK2 IRQ */ +#define IRQ_RINGING 4 /* Ringing IRQ */ +#define IRQ_CODEC 5 /* CODEC IRQ */ + +#endif /* __ASM_SH_RENESAS_HS7751RVOIP */ diff --git a/include/asm-sh/hs7751rvoip/ide.h b/include/asm-sh/hs7751rvoip/ide.h new file mode 100644 index 000000000000..65ad1d0f763b --- /dev/null +++ b/include/asm-sh/hs7751rvoip/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_HS7751RVOIP_IDE_H +#define __ASM_SH_HS7751RVOIP_IDE_H + +/* Nothing to see here.. */ +#include + +#endif /* __ASM_SH_HS7751RVOIP_IDE_H */ + diff --git a/include/asm-sh/hs7751rvoip/io.h b/include/asm-sh/hs7751rvoip/io.h new file mode 100644 index 000000000000..513c8514001b --- /dev/null +++ b/include/asm-sh/hs7751rvoip/io.h @@ -0,0 +1,39 @@ +/* + * include/asm-sh/hs7751rvoip/hs7751rvoip.h + * + * Modified version of io_se.h for the hs7751rvoip-specific functions. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * IO functions for an Renesas Technology sales HS7751RVOIP + */ + +#ifndef _ASM_SH_IO_HS7751RVOIP_H +#define _ASM_SH_IO_HS7751RVOIP_H + +#include + +extern unsigned char hs7751rvoip_inb(unsigned long port); +extern unsigned short hs7751rvoip_inw(unsigned long port); +extern unsigned int hs7751rvoip_inl(unsigned long port); + +extern void hs7751rvoip_outb(unsigned char value, unsigned long port); +extern void hs7751rvoip_outw(unsigned short value, unsigned long port); +extern void hs7751rvoip_outl(unsigned int value, unsigned long port); + +extern unsigned char hs7751rvoip_inb_p(unsigned long port); +extern void hs7751rvoip_outb_p(unsigned char value, unsigned long port); + +extern void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count); +extern void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count); +extern void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count); +extern void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count); +extern void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count); +extern void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count); + +extern void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size); + +extern unsigned long hs7751rvoip_isa_port2addr(unsigned long offset); + +#endif /* _ASM_SH_IO_HS7751RVOIP_H */ -- cgit v1.2.3 From 6cde659c716c7efb553e243c1994a84a24a72cc1 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:26:04 -0700 Subject: [PATCH] sh: IDE cleanup. From: Paul Mundt This does a bit of IDE cleanup (in preparation for the SuperH generic IDE host driver). This also adds SuperH to the list of platforms that are interested in CONFIG_IDE_MAX_HWIFS. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/Kconfig | 2 +- include/asm-sh/hp6xx/ide.h | 8 ++++++ include/asm-sh/ide.h | 65 ++-------------------------------------------- 3 files changed, 11 insertions(+), 64 deletions(-) create mode 100644 include/asm-sh/hp6xx/ide.h (limited to 'include') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 8b1d16b9c1ad..fc96b0db3c4c 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -54,7 +54,7 @@ if IDE config IDE_MAX_HWIFS int "Max IDE interfaces" - depends on ALPHA + depends on ALPHA || SUPERH default 4 help This is the maximum number of IDE hardware interfaces that will diff --git a/include/asm-sh/hp6xx/ide.h b/include/asm-sh/hp6xx/ide.h new file mode 100644 index 000000000000..570395a5ebe5 --- /dev/null +++ b/include/asm-sh/hp6xx/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_HP6XX_IDE_H +#define __ASM_SH_HP6XX_IDE_H + +#define IRQ_CFCARD 93 +#define IRQ_PCMCIA 94 + +#endif /* __ASM_SH_HP6XX_IDE_H */ + diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h index 7758b3ec3a47..f42cf3977a57 100644 --- a/include/asm-sh/ide.h +++ b/include/asm-sh/ide.h @@ -15,73 +15,12 @@ #ifdef __KERNEL__ #include -#include #ifndef MAX_HWIFS -/* Should never have less than 2, ide-pci.c(ide_match_hwif) requires it */ -#define MAX_HWIFS 2 +#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS #endif -#define IDE_ARCH_OBSOLETE_DEFAULTS - -static inline int ide_default_irq_hp600(unsigned long base) -{ - switch (base) { - case 0x01f0: return 93; - case 0x0170: return 94; - default: - return 0; - } -} - -static inline int ide_default_irq(unsigned long base) -{ - if (MACH_HP600) { - return ide_default_irq_hp600(base); - } - switch (base) { - case 0x01f0: return 14; - case 0x0170: return 15; - default: - return 0; - } -} - -static inline unsigned long ide_default_io_base_hp600(int index) -{ - switch (index) { - case 0: - return 0x01f0; - case 1: - return 0x0170; - default: - return 0; - } -} - -static inline unsigned long ide_default_io_base(int index) -{ - if (MACH_HP600) { - return ide_default_io_base_hp600(index); - } - switch (index) { - case 0: - return 0x1f0; - case 1: - return 0x170; - default: - return 0; - } -} - -#define IDE_ARCH_OBSOLETE_INIT -#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ - -#ifdef CONFIG_PCI -#define ide_init_default_irq(base) (0) -#else -#define ide_init_default_irq(base) ide_default_irq(base) -#endif +#define ide_default_io_ctl(base) (0) #include -- cgit v1.2.3 From 16450b81c7c8a94f7a6562371ae08fcd7bd10a9e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:26:14 -0700 Subject: [PATCH] sh: ptep_get_and_clear() compile fix. From: Paul Mundt This fixes up a compile error occuring with ptep_get_and_clear() existing in pgalloc.h. We move it to a somewhat more sensible location instead, and take this opportunity to make some cleanups for use of generic code in the SH-3 case, etc. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/pg-sh4.c | 27 ++++++++++++++++--- include/asm-sh/pgalloc.h | 67 +++--------------------------------------------- include/asm-sh/pgtable.h | 44 ++++++++++++++----------------- 3 files changed, 45 insertions(+), 93 deletions(-) (limited to 'include') diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index 07cbbd6c1a88..f6a76230872f 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -1,7 +1,5 @@ -/* - * $Id: pg-sh4.c,v 1.1.2.2 2002/11/17 17:56:18 lethal Exp $ - * - * arch/sh/mm/pg-sh4.c +/* + * arch/sh/mm/pg-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka * Copyright (C) 2002 Paul Mundt @@ -101,3 +99,24 @@ void copy_user_page(void *to, void *from, unsigned long address, up(&p3map_sem[(address & CACHE_ALIAS)>>12]); } } + +/* + * For SH-4, we have our own implementation for ptep_get_and_clear + */ +inline pte_t ptep_get_and_clear(pte_t *ptep) +{ + pte_t pte = *ptep; + + pte_clear(ptep); + if (!pte_not_present(pte)) { + unsigned long pfn = pte_pfn(pte); + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + struct address_space *mapping = page_mapping(page); + if (!mapping || !mapping_writably_mapped(mapping)) + __clear_bit(PG_mapped, &page->flags); + } + } + return pte; +} + diff --git a/include/asm-sh/pgalloc.h b/include/asm-sh/pgalloc.h index 9b7038442cd6..8a1b3597ff30 100644 --- a/include/asm-sh/pgalloc.h +++ b/include/asm-sh/pgalloc.h @@ -84,71 +84,10 @@ static inline void pte_free(struct page *pte) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() +#define check_pgt_cache() do { } while (0) -#if defined(CONFIG_CPU_SH4) -#define PG_mapped PG_arch_1 - -/* - * For SH-4, we have our own implementation for ptep_get_and_clear - */ -static inline pte_t ptep_get_and_clear(pte_t *ptep) -{ - pte_t pte = *ptep; - - pte_clear(ptep); - if (!pte_not_present(pte)) { - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - struct address_space *mapping = page_mapping(page); - if (!mapping || !mapping_writably_mapped(mapping)) - __clear_bit(PG_mapped, &page->flags); - } - } - return pte; -} -#else -static inline pte_t ptep_get_and_clear(pte_t *ptep) -{ - pte_t pte = *ptep; - pte_clear(ptep); - return pte; -} +#ifdef CONFIG_CPU_SH4 +#define PG_mapped PG_arch_1 #endif -/* - * Following functions are same as generic ones. - */ -static inline int ptep_test_and_clear_young(pte_t *ptep) -{ - pte_t pte = *ptep; - if (!pte_young(pte)) - return 0; - set_pte(ptep, pte_mkold(pte)); - return 1; -} - -static inline int ptep_test_and_clear_dirty(pte_t *ptep) -{ - pte_t pte = *ptep; - if (!pte_dirty(pte)) - return 0; - set_pte(ptep, pte_mkclean(pte)); - return 1; -} - -static inline void ptep_set_wrprotect(pte_t *ptep) -{ - pte_t old_pte = *ptep; - set_pte(ptep, pte_wrprotect(old_pte)); -} - -static inline void ptep_mkdirty(pte_t *ptep) -{ - pte_t old_pte = *ptep; - set_pte(ptep, pte_mkdirty(old_pte)); -} - -#define check_pgt_cache() do { } while (0) - #endif /* __ASM_SH_PGALLOC_H */ diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index e768b7bcd1e8..7cbe42971cfb 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -120,17 +120,20 @@ extern unsigned long empty_zero_page[1024]; #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) +#define PAGE_KERNEL_NOCACHE \ + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) #define PAGE_KERNEL_PCC(slot, type) \ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_FLAGS_HARD | (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | (type)) #else /* no mmu */ -#define PAGE_NONE __pgprot(0) -#define PAGE_SHARED __pgprot(0) -#define PAGE_COPY __pgprot(0) -#define PAGE_READONLY __pgprot(0) -#define PAGE_KERNEL __pgprot(0) -#define PAGE_KERNEL_RO __pgprot(0) -#define PAGE_KERNEL_PCC __pgprot(0) +#define PAGE_NONE __pgprot(0) +#define PAGE_SHARED __pgprot(0) +#define PAGE_COPY __pgprot(0) +#define PAGE_READONLY __pgprot(0) +#define PAGE_KERNEL __pgprot(0) +#define PAGE_KERNEL_NOCACHE __pgprot(0) +#define PAGE_KERNEL_RO __pgprot(0) +#define PAGE_KERNEL_PCC __pgprot(0) #endif /* @@ -255,25 +258,17 @@ extern void update_mmu_cache(struct vm_area_struct * vma, #define __swp_type(x) ((x).val & 0xff) #define __swp_offset(x) ((x).val >> 10) #define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 10) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 1 }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 1 }) /* * Encode and decode a nonlinear file mapping entry */ #define PTE_FILE_MAX_BITS 29 -#define pte_to_pgoff(pte) (pte_val(pte)) -#define pgoff_to_pte(off) ((pte_t) { (off) | _PAGE_FILE }) +#define pte_to_pgoff(pte) (pte_val(pte) >> 1) +#define pgoff_to_pte(off) ((pte_t) { ((off) << 1) | _PAGE_FILE }) -/* - * Routines for update of PTE - * - * We just can use generic implementation, as SuperH has no SMP feature. - * (We needed atomic implementation for SMP) - * - */ - -#define pte_same(A,B) (pte_val(A) == pte_val(B)) +typedef pte_t *pte_addr_t; #endif /* !__ASSEMBLY__ */ @@ -290,12 +285,11 @@ extern void update_mmu_cache(struct vm_area_struct * vma, extern unsigned int kobjsize(const void *objp); #endif /* !CONFIG_MMU */ -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY +#ifdef CONFIG_CPU_SH4 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR -#define __HAVE_ARCH_PTEP_SET_WRPROTECT -#define __HAVE_ARCH_PTEP_MKDIRTY -#define __HAVE_ARCH_PTE_SAME +extern inline pte_t ptep_get_and_clear(pte_t *ptep); +#endif + #include #endif /* __ASM_SH_PAGE_H */ -- cgit v1.2.3 From 6d2f01f1285f4b4a3658cbaeaef3033c0a58b812 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:26:37 -0700 Subject: [PATCH] sh: SolutionEngine 7300 board support. From: Paul Mundt This adds support for the SH7300 solution engine board (a forward port of the 2.4 code). Signed-off-by: Hiroshi DOYU Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/se/7300/Makefile | 7 + arch/sh/boards/se/7300/io.c | 261 ++++++++++++++++++++++ arch/sh/boards/se/7300/irq.c | 37 ++++ arch/sh/boards/se/7300/led.c | 69 ++++++ arch/sh/boards/se/7300/setup.c | 66 ++++++ arch/sh/configs/se7300_defconfig | 461 +++++++++++++++++++++++++++++++++++++++ include/asm-sh/se7300/io.h | 29 +++ include/asm-sh/se7300/se7300.h | 61 ++++++ 8 files changed, 991 insertions(+) create mode 100644 arch/sh/boards/se/7300/Makefile create mode 100644 arch/sh/boards/se/7300/io.c create mode 100644 arch/sh/boards/se/7300/irq.c create mode 100644 arch/sh/boards/se/7300/led.c create mode 100644 arch/sh/boards/se/7300/setup.c create mode 100644 arch/sh/configs/se7300_defconfig create mode 100644 include/asm-sh/se7300/io.h create mode 100644 include/asm-sh/se7300/se7300.h (limited to 'include') diff --git a/arch/sh/boards/se/7300/Makefile b/arch/sh/boards/se/7300/Makefile new file mode 100644 index 000000000000..0fbd4f47815c --- /dev/null +++ b/arch/sh/boards/se/7300/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the 7300 SolutionEngine specific parts of the kernel +# + +obj-y := setup.o io.o irq.o + +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c new file mode 100644 index 000000000000..4e8939197e20 --- /dev/null +++ b/arch/sh/boards/se/7300/io.c @@ -0,0 +1,261 @@ +/* + * linux/arch/sh/boards/se/7300/io.c + * + * Copyright (C) 2003 YOSHII Takashi + */ + +#include +#include +#include +#include + +#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) + +struct iop { + unsigned long start, end; + unsigned long base; + struct iop *(*check) (struct iop * p, unsigned long port); + unsigned char (*inb) (struct iop * p, unsigned long port); + unsigned short (*inw) (struct iop * p, unsigned long port); + void (*outb) (struct iop * p, unsigned char value, unsigned long port); + void (*outw) (struct iop * p, unsigned short value, unsigned long port); +}; + +struct iop * +simple_check(struct iop *p, unsigned long port) +{ + if ((p->start <= port) && (port <= p->end)) + return p; + else + badio(check, port); +} + +struct iop * +ide_check(struct iop *p, unsigned long port) +{ + if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) + return p; + return NULL; +} + +unsigned char +simple_inb(struct iop *p, unsigned long port) +{ + return *(unsigned char *) (p->base + port); +} + +unsigned short +simple_inw(struct iop *p, unsigned long port) +{ + return *(unsigned short *) (p->base + port); +} + +void +simple_outb(struct iop *p, unsigned char value, unsigned long port) +{ + *(unsigned char *) (p->base + port) = value; +} + +void +simple_outw(struct iop *p, unsigned short value, unsigned long port) +{ + *(unsigned short *) (p->base + port) = value; +} + +unsigned char +pcc_inb(struct iop *p, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + unsigned long v; + + if (port & 1) + addr += 0x00400000; + v = *(volatile unsigned char *) addr; + return v; +} + +void +pcc_outb(struct iop *p, unsigned char value, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + + if (port & 1) + addr += 0x00400000; + *(volatile unsigned char *) addr = value; +} + +unsigned char +bad_inb(struct iop *p, unsigned long port) +{ + badio(inb, port); +} + +void +bad_outb(struct iop *p, unsigned char value, unsigned long port) +{ + badio(inw, port); +} + +/* MSTLANEX01 LAN at 0xb400:0000 */ +static struct iop laniop = { + .start = 0x300, + .end = 0x30f, + .base = 0xb4000000, + .check = simple_check, + .inb = simple_inb, + .inw = simple_inw, + .outb = simple_outb, + .outw = simple_outw, +}; + +/* NE2000 pc card NIC */ +static struct iop neiop = { + .start = 0x280, + .end = 0x29f, + .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ + .check = simple_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; + +/* CF in CF slot */ +static struct iop cfiop = { + .base = 0xb0600000, + .check = ide_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; + +static __inline__ struct iop * +port2iop(unsigned long port) +{ + if (0) ; +#if defined(CONFIG_SMC91111) + else if (laniop.check(&laniop, port)) + return &laniop; +#endif +#if defined(CONFIG_NE2000) + else if (neiop.check(&neiop, port)) + return &neiop; +#endif +#if defined(CONFIG_IDE) + else if (cfiop.check(&cfiop, port)) + return &cfiop; +#endif + else + return &neiop; /* fallback */ +} + +static inline void +delay(void) +{ + ctrl_inw(0xac000000); + ctrl_inw(0xac000000); +} + +unsigned char +sh7300se_inb(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inb) (p, port); +} + +unsigned char +sh7300se_inb_p(unsigned long port) +{ + unsigned char v = sh7300se_inb(port); + delay(); + return v; +} + +unsigned short +sh7300se_inw(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inw) (p, port); +} + +unsigned int +sh7300se_inl(unsigned long port) +{ + badio(inl, port); +} + +void +sh7300se_outb(unsigned char value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outb) (p, value, port); +} + +void +sh7300se_outb_p(unsigned char value, unsigned long port) +{ + sh7300se_outb(value, port); + delay(); +} + +void +sh7300se_outw(unsigned short value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outw) (p, value, port); +} + +void +sh7300se_outl(unsigned int value, unsigned long port) +{ + badio(outl, port); +} + +void +sh7300se_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inb) (p, port); +} + +void +sh7300se_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inw) (p, port); +} + +void +sh7300se_insl(unsigned long port, void *addr, unsigned long count) +{ + badio(insl, port); +} + +void +sh7300se_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *a = (unsigned char *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outb) (p, *a++, port); +} + +void +sh7300se_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *a = (unsigned short *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outw) (p, *a++, port); +} + +void +sh7300se_outsl(unsigned long port, const void *addr, unsigned long count) +{ + badio(outsw, port); +} diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c new file mode 100644 index 000000000000..96c8c23d6c93 --- /dev/null +++ b/arch/sh/boards/se/7300/irq.c @@ -0,0 +1,37 @@ +/* + * linux/arch/sh/boards/se/7300/irq.c + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine 7300 Support. + * + */ + +#include +#include +#include +#include +#include +#include + +/* + * Initialize IRQ setting + */ +void __init +init_7300se_IRQ(void) +{ + ctrl_outw(0x0028, PA_EPLD_MODESET); /* mode set IRQ0,1 active low. */ + ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */ + ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */ + + /* PC_IRQ[0-3] -> IRQ0 (32) */ + make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ); + /* A_IRQ[0-3] -> IRQ1 (33) */ + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + + ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ +} diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c new file mode 100644 index 000000000000..02c7f846c84c --- /dev/null +++ b/arch/sh/boards/se/7300/led.c @@ -0,0 +1,69 @@ +/* + * linux/arch/sh/boards/se/7300/led.c + * + * Derived from linux/arch/sh/boards/se/770x/led.c + * + * Copyright (C) 2000 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Solution Engine specific LED code. + */ + +#include +#include +#include + +static void +mach_led(int position, int value) +{ + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + + if (value) { + *p |= (1 << 8); + } else { + *p &= ~(1 << 8); + } +} + + +/* Cycle the LED's in the clasic Knightrider/Sun pattern */ +void +heartbeat_7300se(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) { + return; + } + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); + + if (up) { + if (bit == 7) { + bit--; + up = 0; + } else { + bit++; + } + } else { + if (bit == 0) { + bit++; + up = 1; + } else { + bit--; + } + } + *p = 1 << (bit + 8); + +} + diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c new file mode 100644 index 000000000000..08536bc224dc --- /dev/null +++ b/arch/sh/boards/se/7300/setup.c @@ -0,0 +1,66 @@ +/* + * linux/arch/sh/boards/se/7300/setup.c + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine 7300 Support. + * + */ + +#include +#include +#include +#include +#include + +void heartbeat_7300se(void); +void init_7300se_IRQ(void); + +const char * +get_system_type(void) +{ + return "SolutionEngine 7300"; +} + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_7300se __initmv = { + .mv_nr_irqs = 109, + .mv_inb = sh7300se_inb, + .mv_inw = sh7300se_inw, + .mv_inl = sh7300se_inl, + .mv_outb = sh7300se_outb, + .mv_outw = sh7300se_outw, + .mv_outl = sh7300se_outl, + + .mv_inb_p = sh7300se_inb_p, + .mv_inw_p = sh7300se_inw, + .mv_inl_p = sh7300se_inl, + .mv_outb_p = sh7300se_outb_p, + .mv_outw_p = sh7300se_outw, + .mv_outl_p = sh7300se_outl, + + .mv_insb = sh7300se_insb, + .mv_insw = sh7300se_insw, + .mv_insl = sh7300se_insl, + .mv_outsb = sh7300se_outsb, + .mv_outsw = sh7300se_outsw, + .mv_outsl = sh7300se_outsl, + + .mv_init_irq = init_7300se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_7300se, +#endif +}; + +ALIAS_MV(7300se) +/* + * Initialize the board + */ +void __init +platform_setup(void) +{ + +} diff --git a/arch/sh/configs/se7300_defconfig b/arch/sh/configs/se7300_defconfig new file mode 100644 index 000000000000..842ca47a684e --- /dev/null +++ b/arch/sh/configs/se7300_defconfig @@ -0,0 +1,461 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +CONFIG_SH_7300_SOLUTION_ENGINE=y +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_STB1_HARP is not set +# CONFIG_SH_STB1_OVERDRIVE is not set +# CONFIG_SH_HP620 is not set +# CONFIG_SH_HP680 is not set +# CONFIG_SH_HP690 is not set +# CONFIG_SH_CQREEK is not set +# CONFIG_SH_DMIDA is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_CAT68701 is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_SH2000 is not set +# CONFIG_SH_ADX is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_UNKNOWN is not set +# CONFIG_CPU_SH2 is not set +CONFIG_CPU_SH3=y +# CONFIG_CPU_SH4 is not set +# CONFIG_CPU_SUBTYPE_SH7604 is not set +CONFIG_CPU_SUBTYPE_SH7300=y +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set +CONFIG_MMU=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0" +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +# CONFIG_MEMORY_OVERRIDE is not set +CONFIG_SH_DSP=y +# CONFIG_SH_ADC is not set +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00210000 +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_PREEMPT is not set +# CONFIG_UBC_WAKEUP is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +# CONFIG_SMP is not set +# CONFIG_SH_PCLK_CALC is not set +CONFIG_SH_PCLK_FREQ=33333333 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set +CONFIG_HEARTBEAT=y + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# SH initrd options +# +CONFIG_EMBEDDED_RAMDISK=y +CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz" + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_LBD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +CONFIG_IPMI_HANDLER=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=y +# CONFIG_IPMI_SI is not set +CONFIG_IPMI_WATCHDOG=y + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=y +# CONFIG_SH_WDT is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_SH_STANDARD_BIOS=y +CONFIG_EARLY_PRINTK=y +CONFIG_KGDB=y + +# +# KGDB configuration options +# +# CONFIG_MORE_COMPILE_OPTIONS is not set +# CONFIG_KGDB_NMI is not set +# CONFIG_KGDB_THREAD is not set +# CONFIG_SH_KGDB_CONSOLE is not set +# CONFIG_KGDB_SYSRQ is not set +# CONFIG_KGDB_KERNEL_ASSERTS is not set + +# +# Serial port setup +# +CONFIG_KGDB_DEFPORT=1 +CONFIG_KGDB_DEFBAUD=115200 +CONFIG_KGDB_DEFPARITY_N=y +# CONFIG_KGDB_DEFPARITY_E is not set +# CONFIG_KGDB_DEFPARITY_O is not set +CONFIG_KGDB_DEFBITS_8=y +# CONFIG_KGDB_DEFBITS_7 is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/include/asm-sh/se7300/io.h b/include/asm-sh/se7300/io.h new file mode 100644 index 000000000000..c6af85529714 --- /dev/null +++ b/include/asm-sh/se7300/io.h @@ -0,0 +1,29 @@ +/* + * include/asm-sh/se7300/io.h + * + * Copyright (C) 2003 Takashi Kusuda + * IO functions for SH-Mobile(SH7300) SolutionEngine + */ + +#ifndef _ASM_SH_IO_7300SE_H +#define _ASM_SH_IO_7300SE_H + +extern unsigned char sh7300se_inb(unsigned long port); +extern unsigned short sh7300se_inw(unsigned long port); +extern unsigned int sh7300se_inl(unsigned long port); + +extern void sh7300se_outb(unsigned char value, unsigned long port); +extern void sh7300se_outw(unsigned short value, unsigned long port); +extern void sh7300se_outl(unsigned int value, unsigned long port); + +extern unsigned char sh7300se_inb_p(unsigned long port); +extern void sh7300se_outb_p(unsigned char value, unsigned long port); + +extern void sh7300se_insb(unsigned long port, void *addr, unsigned long count); +extern void sh7300se_insw(unsigned long port, void *addr, unsigned long count); +extern void sh7300se_insl(unsigned long port, void *addr, unsigned long count); +extern void sh7300se_outsb(unsigned long port, const void *addr, unsigned long count); +extern void sh7300se_outsw(unsigned long port, const void *addr, unsigned long count); +extern void sh7300se_outsl(unsigned long port, const void *addr, unsigned long count); + +#endif /* _ASM_SH_IO_7300SE_H */ diff --git a/include/asm-sh/se7300/se7300.h b/include/asm-sh/se7300/se7300.h new file mode 100644 index 000000000000..3ec1ded86c97 --- /dev/null +++ b/include/asm-sh/se7300/se7300.h @@ -0,0 +1,61 @@ +#ifndef __ASM_SH_HITACHI_SE7300_H +#define __ASM_SH_HITACHI_SE7300_H + +/* + * linux/include/asm-sh/se/se7300.h + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine 7300 support + */ + +/* Box specific addresses. */ + +/* Area 0 */ +#define PA_ROM 0x00000000 /* EPROM */ +#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte(Actually 2MB) */ +#define PA_FROM 0x00400000 /* Flash ROM */ +#define PA_FROM_SIZE 0x00400000 /* Flash size 4M byte */ +#define PA_SRAM 0x00800000 /* SRAM */ +#define PA_FROM_SIZE 0x00400000 /* SRAM size 4M byte */ +/* Area 1 */ +#define PA_EXT1 0x04000000 +#define PA_EXT1_SIZE 0x04000000 +/* Area 2 */ +#define PA_EXT2 0x08000000 +#define PA_EXT2_SIZE 0x04000000 +/* Area 3 */ +#define PA_SDRAM 0x0c000000 +#define PA_SDRAM_SIZE 0x04000000 +/* Area 4 */ +#define PA_PCIC 0x10000000 /* MR-SHPC-01 PCMCIA */ +#define PA_MRSHPC 0xb03fffe0 /* MR-SHPC-01 PCMCIA controller */ +#define PA_MRSHPC_MW1 0xb0400000 /* MR-SHPC-01 memory window base */ +#define PA_MRSHPC_MW2 0xb0500000 /* MR-SHPC-01 attribute window base */ +#define PA_MRSHPC_IO 0xb0600000 /* MR-SHPC-01 I/O window base */ +#define MRSHPC_OPTION (PA_MRSHPC + 6) +#define MRSHPC_CSR (PA_MRSHPC + 8) +#define MRSHPC_ISR (PA_MRSHPC + 10) +#define MRSHPC_ICR (PA_MRSHPC + 12) +#define MRSHPC_CPWCR (PA_MRSHPC + 14) +#define MRSHPC_MW0CR1 (PA_MRSHPC + 16) +#define MRSHPC_MW1CR1 (PA_MRSHPC + 18) +#define MRSHPC_IOWCR1 (PA_MRSHPC + 20) +#define MRSHPC_MW0CR2 (PA_MRSHPC + 22) +#define MRSHPC_MW1CR2 (PA_MRSHPC + 24) +#define MRSHPC_IOWCR2 (PA_MRSHPC + 26) +#define MRSHPC_CDCR (PA_MRSHPC + 28) +#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) +#define PA_LED 0xb0800000 /* LED */ +#define PA_DIPSW 0xb0900000 /* Dip switch 31 */ +#define PA_EPLD_MODESET 0xb0a00000 /* FPGA Mode set register */ +#define PA_EPLD_ST1 0xb0a80000 /* FPGA Interrupt status register1 */ +#define PA_EPLD_ST2 0xb0ac0000 /* FPGA Interrupt status register2 */ +/* Area 5 */ +#define PA_EXT5 0x14000000 +#define PA_EXT5_SIZE 0x04000000 +/* Area 6 */ +#define PA_LCD1 0xb8000000 +#define PA_LCD2 0xb8800000 + +#endif /* __ASM_SH_HITACHI_SE7300_H */ -- cgit v1.2.3 From 125190efd98a565b4ec64868ba273da25616443c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:26:49 -0700 Subject: [PATCH] sh: Renesas RTS7751R2D board support. From: Paul Mundt This adds support for the Renesas Technology Sales RTS7751R2D board. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/renesas/rts7751r2d/Makefile | 10 + arch/sh/boards/renesas/rts7751r2d/io.c | 319 ++++++++++++ arch/sh/boards/renesas/rts7751r2d/irq.c | 135 +++++ arch/sh/boards/renesas/rts7751r2d/led.c | 67 +++ arch/sh/boards/renesas/rts7751r2d/mach.c | 68 +++ arch/sh/boards/renesas/rts7751r2d/setup.c | 31 ++ arch/sh/configs/rts7751r2d_defconfig | 809 +++++++++++++++++++++++++++++ include/asm-sh/rts7751r2d/ide.h | 8 + include/asm-sh/rts7751r2d/io.h | 37 ++ include/asm-sh/rts7751r2d/rts7751r2d.h | 73 +++ include/asm-sh/rts7751r2d/voyagergx_reg.h | 313 +++++++++++ 11 files changed, 1870 insertions(+) create mode 100644 arch/sh/boards/renesas/rts7751r2d/Makefile create mode 100644 arch/sh/boards/renesas/rts7751r2d/io.c create mode 100644 arch/sh/boards/renesas/rts7751r2d/irq.c create mode 100644 arch/sh/boards/renesas/rts7751r2d/led.c create mode 100644 arch/sh/boards/renesas/rts7751r2d/mach.c create mode 100644 arch/sh/boards/renesas/rts7751r2d/setup.c create mode 100644 arch/sh/configs/rts7751r2d_defconfig create mode 100644 include/asm-sh/rts7751r2d/ide.h create mode 100644 include/asm-sh/rts7751r2d/io.h create mode 100644 include/asm-sh/rts7751r2d/rts7751r2d.h create mode 100644 include/asm-sh/rts7751r2d/voyagergx_reg.h (limited to 'include') diff --git a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile new file mode 100644 index 000000000000..daa53334bdc3 --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the RTS7751R2D specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := mach.o setup.o io.o irq.o led.o + diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c new file mode 100644 index 000000000000..c46f9154cfd5 --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/io.c @@ -0,0 +1,319 @@ +/* + * linux/arch/sh/kernel/io_rts7751r2d.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Renesas Technology sales RTS7751R2D. + * + * Initial version only to support LAN access; some + * placeholder code from io_rts7751r2d.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + +/* + * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC) + * of the 7751R processor, and has a SuperIO accessible via the PCI. + * The board also includes a PCMCIA controller on its memory bus, + * like the other Solution Engine boards. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return (PA_AREA5_IO + 0x80c); + else + return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); + else + maybebadio(port2adr, (unsigned long)port); + + return port; +} + +static inline unsigned long port88796l(unsigned int port, int flag) +{ + unsigned long addr; + + if (flag) + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1); + else + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000; + + return addr; +} + +/* The 7751R RTS7751R2D seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) +#define CHECK_AX88796L_PORT(port) \ + ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) +#else +#define CHECK_AX88796L_PORT(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char rts7751r2d_inb(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + return *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else + return (*(volatile unsigned short *)port2adr(port) & 0xff); +} + +unsigned char rts7751r2d_inb_p(unsigned long port) +{ + unsigned char v; + + if (CHECK_AX88796L_PORT(port)) + v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else + v = (*(volatile unsigned short *)port2adr(port) & 0xff); + delay(); + + return v; +} + +unsigned short rts7751r2d_inw(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(inw, port); + else if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else + maybebadio(inw, port); + + return 0; +} + +unsigned int rts7751r2d_inl(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(inl, port); + else if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); + else + maybebadio(inl, port); + + return 0; +} + +void rts7751r2d_outb(unsigned char value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + *((volatile unsigned short *)port88796l(port, 0)) = value; + else if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; +} + +void rts7751r2d_outb_p(unsigned char value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + *((volatile unsigned short *)port88796l(port, 0)) = value; + else if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; + delay(); +} + +void rts7751r2d_outw(unsigned short value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outw, port); + else if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned short *)PCI_IOMAP(port) = value; + else + maybebadio(outw, port); +} + +void rts7751r2d_outl(unsigned int value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outl, port); + else if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned long *)PCI_IOMAP(port) = value; + else + maybebadio(outl, port); +} + +void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u8 *bp; + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile unsigned short *)port88796l(port, 0); + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } else if (PXSEG(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *((volatile unsigned char *) addr)++ = *bp; + } else { + p = (volatile unsigned short *)port2adr(port); + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } +} + +void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile unsigned short *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *((__u16 *) addr)++ = *p; +} + +void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(insl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *((__u32 *) addr)++ = *p; + } else + maybebadio(insl, port); +} + +void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u8 *bp; + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile unsigned short *)port88796l(port, 0); + while (count--) *p = *((unsigned char *) addr)++; + } else if (PXSEG(port)) + while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *bp = *((volatile unsigned char *) addr)++; + } else { + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((unsigned char *) addr)++; + } +} + +void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile unsigned short *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((__u16 *) addr)++; +} + +void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outsl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *p = *((__u32 *) addr)++; + } else + maybebadio(outsl, port); +} + +void *rts7751r2d_ioremap(unsigned long offset, unsigned long size) +{ + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); +} +EXPORT_SYMBOL(rts7751r2d_ioremap); + +unsigned long rts7751r2d_isa_port2addr(unsigned long offset) +{ + return port2adr(offset); +} diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c new file mode 100644 index 000000000000..95717f4f1e2d --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -0,0 +1,135 @@ +/* + * linux/arch/sh/boards/renesas/rts7751r2d/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales RTS7751R2D Support. + * + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_RTS7751R2D_REV11) +static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; +#else +static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; +#endif + +extern int voyagergx_irq_demux(int irq); +extern void setup_voyagergx_irq(void); + +static void enable_rts7751r2d_irq(unsigned int irq); +static void disable_rts7751r2d_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_rts7751r2d_irq disable_rts7751r2d_irq + +static void ack_rts7751r2d_irq(unsigned int irq); +static void end_rts7751r2d_irq(unsigned int irq); + +static unsigned int startup_rts7751r2d_irq(unsigned int irq) +{ + enable_rts7751r2d_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_rts7751r2d_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + + /* Set the priority in IPR to 0 */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR1); + val &= mask; + ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); +} + +static void enable_rts7751r2d_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR1); + val |= value; + ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); +} + +int rts7751r2d_irq_demux(int irq) +{ + int demux_irq; + + demux_irq = voyagergx_irq_demux(irq); + return demux_irq; +} + +static void ack_rts7751r2d_irq(unsigned int irq) +{ + disable_rts7751r2d_irq(irq); +} + +static void end_rts7751r2d_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_rts7751r2d_irq(irq); +} + +static struct hw_interrupt_type rts7751r2d_irq_type = { + "RTS7751R2D IRQ", + startup_rts7751r2d_irq, + shutdown_rts7751r2d_irq, + enable_rts7751r2d_irq, + disable_rts7751r2d_irq, + ack_rts7751r2d_irq, + end_rts7751r2d_irq, +}; + +static void make_rts7751r2d_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &rts7751r2d_irq_type; + disable_rts7751r2d_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_rts7751r2d_IRQ(void) +{ + int i; + + /* IRL0=KEY Input + * IRL1=Ethernet + * IRL2=CF Card + * IRL3=CF Card Insert + * IRL4=PCMCIA + * IRL5=VOYAGER + * IRL6=RTC Alarm + * IRL7=RTC Timer + * IRL8=SD Card + * IRL9=PCI Slot #1 + * IRL10=PCI Slot #2 + * IRL11=Extention #0 + * IRL12=Extention #1 + * IRL13=Extention #2 + * IRL14=Extention #3 + */ + + for (i=0; i<15; i++) + make_rts7751r2d_irq(i); + + setup_voyagergx_irq(); +} diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c new file mode 100644 index 000000000000..9993259a894f --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/led.c @@ -0,0 +1,67 @@ +/* + * linux/arch/sh/kernel/led_rts7751r2d.c + * + * Copyright (C) Atom Create Engineering Co., Ltd. + * + * May be copied or modified under the terms of GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Renesas Technology Sales RTS7751R2D specific LED code. + */ + +#include +#include +#include + +extern unsigned int debug_counter; + +#ifdef CONFIG_HEARTBEAT + +#include + +/* Cycle the LED's in the clasic Knightriger/Sun pattern */ +void heartbeat_rts7751r2d(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *)PA_OUTPORT; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) + return; + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110 + */ + period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3< +#include +#include + +#include +#include +#include +#include + +extern void heartbeat_rts7751r2d(void); +extern void init_rts7751r2d_IRQ(void); +extern void *rts7751r2d_ioremap(unsigned long, unsigned long); +extern int rts7751r2d_irq_demux(int irq); + +extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int); +extern void voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_rts7751r2d __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = rts7751r2d_inb, + .mv_inw = rts7751r2d_inw, + .mv_inl = rts7751r2d_inl, + .mv_outb = rts7751r2d_outb, + .mv_outw = rts7751r2d_outw, + .mv_outl = rts7751r2d_outl, + + .mv_inb_p = rts7751r2d_inb_p, + .mv_inw_p = rts7751r2d_inw, + .mv_inl_p = rts7751r2d_inl, + .mv_outb_p = rts7751r2d_outb_p, + .mv_outw_p = rts7751r2d_outw, + .mv_outl_p = rts7751r2d_outl, + + .mv_insb = rts7751r2d_insb, + .mv_insw = rts7751r2d_insw, + .mv_insl = rts7751r2d_insl, + .mv_outsb = rts7751r2d_outsb, + .mv_outsw = rts7751r2d_outsw, + .mv_outsl = rts7751r2d_outsl, + + .mv_ioremap = rts7751r2d_ioremap, + .mv_isa_port2addr = rts7751r2d_isa_port2addr, + .mv_init_irq = init_rts7751r2d_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_rts7751r2d, +#endif + .mv_irq_demux = rts7751r2d_irq_demux, + + .mv_consistent_alloc = voyagergx_consistent_alloc, + .mv_consistent_free = voyagergx_consistent_free, +}; +ALIAS_MV(rts7751r2d) diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c new file mode 100644 index 000000000000..2587fd1a0240 --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -0,0 +1,31 @@ +/* + * linux/arch/sh/kernel/setup_rts7751r2d.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales RTS7751R2D Support. + * + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. + */ + +#include +#include +#include + +unsigned int debug_counter; + +const char *get_system_type(void) +{ + return "RTS7751R2D"; +} + +/* + * Initialize the board + */ +void __init platform_setup(void) +{ + printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + ctrl_outw(0x0000, PA_OUTPORT); + debug_counter = 0; +} diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig new file mode 100644 index 000000000000..f9e1f7c5a657 --- /dev/null +++ b/arch/sh/configs/rts7751r2d_defconfig @@ -0,0 +1,809 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_STB1_HARP is not set +# CONFIG_SH_STB1_OVERDRIVE is not set +# CONFIG_SH_HP620 is not set +# CONFIG_SH_HP680 is not set +# CONFIG_SH_HP690 is not set +# CONFIG_SH_CQREEK is not set +# CONFIG_SH_DMIDA is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_CAT68701 is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_SH2000 is not set +# CONFIG_SH_ADX is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +CONFIG_SH_RTS7751R2D=y +# CONFIG_SH_UNKNOWN is not set +# CONFIG_CPU_SH2 is not set +# CONFIG_CPU_SH3 is not set +CONFIG_CPU_SH4=y +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +CONFIG_CPU_SUBTYPE_SH7751=y +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +CONFIG_MMU=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1" +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_MEMORY_SET=y +# CONFIG_MEMORY_OVERRIDE is not set +CONFIG_SH_RTC=y +CONFIG_ZERO_PAGE_OFFSET=0x00010000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_PREEMPT is not set +# CONFIG_UBC_WAKEUP is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +# CONFIG_SH_STORE_QUEUES is not set +# CONFIG_SMP is not set +CONFIG_VOYAGERGX=y +CONFIG_RTS7751R2D_REV11=y +CONFIG_SH_PCLK_FREQ=60000000 +# CONFIG_CPU_FREQ is not set +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=8 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set +# CONFIG_DMA_PAGE_OPS is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_ISA=y +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +CONFIG_PCI_DMA=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_YENTA=m +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PROBE=y + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_LBD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +CONFIG_NET_ISA=y +# CONFIG_E2100 is not set +# CONFIG_EWRK3 is not set +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set +CONFIG_NE2000=m +# CONFIG_ZNET is not set +# CONFIG_SEEQ8005 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_AIRO is not set +CONFIG_HERMES=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_ATMEL is not set +# CONFIG_PCMCIA_WL3501 is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +CONFIG_SH_SCI=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_RTC_9701JE=y + +# +# Unix 98 PTY support +# +# CONFIG_UNIX98_PTYS is not set +CONFIG_HEARTBEAT=y +# CONFIG_PSMOUSE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_SH_SCI is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Algorithms +# + +# +# I2C Hardware Bus support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_OSSEMUL is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ISA devices +# +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_YMFPCI=m +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_BT878 is not set +CONFIG_SOUND_CMPCI=m +# CONFIG_SOUND_CMPCI_FM is not set +# CONFIG_SOUND_CMPCI_MIDI is not set +# CONFIG_SOUND_CMPCI_JOYSTICK is not set +# CONFIG_SOUND_CMPCI_CM8738 is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set +CONFIG_SOUND_VOYAGERGX=m + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_KGDB is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y diff --git a/include/asm-sh/rts7751r2d/ide.h b/include/asm-sh/rts7751r2d/ide.h new file mode 100644 index 000000000000..416f96b407cb --- /dev/null +++ b/include/asm-sh/rts7751r2d/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_RTS7751R2D_IDE_H +#define __ASM_SH_RTS7751R2D_IDE_H + +/* Nothing to see here.. */ +#include + +#endif /* __ASM_SH_RTS7751R2D_IDE_H */ + diff --git a/include/asm-sh/rts7751r2d/io.h b/include/asm-sh/rts7751r2d/io.h new file mode 100644 index 000000000000..241094020567 --- /dev/null +++ b/include/asm-sh/rts7751r2d/io.h @@ -0,0 +1,37 @@ +/* + * include/asm-sh/io_rts7751r2d.h + * + * Modified version of io_se.h for the rts7751r2d-specific functions. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * IO functions for an Renesas Technology sales RTS7751R2D + */ + +#ifndef _ASM_SH_IO_RTS7751R2D_H +#define _ASM_SH_IO_RTS7751R2D_H + +extern unsigned char rts7751r2d_inb(unsigned long port); +extern unsigned short rts7751r2d_inw(unsigned long port); +extern unsigned int rts7751r2d_inl(unsigned long port); + +extern void rts7751r2d_outb(unsigned char value, unsigned long port); +extern void rts7751r2d_outw(unsigned short value, unsigned long port); +extern void rts7751r2d_outl(unsigned int value, unsigned long port); + +extern unsigned char rts7751r2d_inb_p(unsigned long port); +extern void rts7751r2d_outb_p(unsigned char value, unsigned long port); + +extern void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count); +extern void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count); +extern void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count); +extern void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count); +extern void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count); +extern void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count); + +extern void *rts7751r2d_ioremap(unsigned long offset, unsigned long size); + +extern unsigned long rts7751r2d_isa_port2addr(unsigned long offset); + +#endif /* _ASM_SH_IO_RTS7751R2D_H */ diff --git a/include/asm-sh/rts7751r2d/rts7751r2d.h b/include/asm-sh/rts7751r2d/rts7751r2d.h new file mode 100644 index 000000000000..4e09ba597e9a --- /dev/null +++ b/include/asm-sh/rts7751r2d/rts7751r2d.h @@ -0,0 +1,73 @@ +#ifndef __ASM_SH_RENESAS_RTS7751R2D_H +#define __ASM_SH_RENESAS_RTS7751R2D_H + +/* + * linux/include/asm-sh/renesas_rts7751r2d.h + * + * Copyright (C) 2000 Atom Create Engineering Co., Ltd. + * + * Renesas Technology Sales RTS7751R2D support + */ + +/* Box specific addresses. */ + +#define PA_BCR 0xa4000000 /* FPGA */ +#define PA_IRLMON 0xa4000002 /* Interrupt Status control */ +#define PA_CFCTL 0xa4000004 /* CF Timing control */ +#define PA_CFPOW 0xa4000006 /* CF Power control */ +#define PA_DISPCTL 0xa4000008 /* Display Timing control */ +#define PA_SDMPOW 0xa400000a /* SD Power control */ +#define PA_RTCCE 0xa400000c /* RTC(9701) Enable control */ +#define PA_PCICD 0xa400000e /* PCI Extention detect control */ +#define PA_VOYAGERRTS 0xa4000020 /* VOYAGER Reset control */ +#if defined(CONFIG_RTS7751R2D_REV11) +#define PA_AXRST 0xa4000022 /* AX_LAN Reset control */ +#define PA_CFRST 0xa4000024 /* CF Reset control */ +#define PA_ADMRTS 0xa4000026 /* SD Reset control */ +#define PA_EXTRST 0xa4000028 /* Extention Reset control */ +#define PA_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ +#else +#define PA_CFRST 0xa4000022 /* CF Reset control */ +#define PA_ADMRTS 0xa4000024 /* SD Reset control */ +#define PA_EXTRST 0xa4000026 /* Extention Reset control */ +#define PA_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ +#define PA_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ +#endif +#define PA_POWOFF 0xa4000030 /* Board Power OFF control */ +#define PA_VERREG 0xa4000032 /* FPGA Version Register */ +#define PA_INPORT 0xa4000034 /* KEY Input Port control */ +#define PA_OUTPORT 0xa4000036 /* LED control */ +#define PA_DMPORT 0xa4000038 /* DM270 Output Port control */ + +#define PA_AX88796L 0xaa000400 /* AX88796L Area */ +#define PA_VOYAGER 0xab000000 /* VOYAGER GX Area */ +#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */ +#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */ +#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ +#define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */ + +#define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ + +#if defined(CONFIG_RTS7751R2D_REV11) +#define IRQ_PCIETH 0 /* PCI Ethernet IRQ */ +#define IRQ_CFCARD 1 /* CF Card IRQ */ +#define IRQ_CFINST 2 /* CF Card Insert IRQ */ +#define IRQ_PCMCIA 3 /* PCMCIA IRQ */ +#define IRQ_VOYAGER 4 /* VOYAGER IRQ */ +#define IRQ_ONETH 5 /* On board Ethernet IRQ */ +#else +#define IRQ_KEYIN 0 /* Key Input IRQ */ +#define IRQ_PCIETH 1 /* PCI Ethernet IRQ */ +#define IRQ_CFCARD 2 /* CF Card IRQ */ +#define IRQ_CFINST 3 /* CF Card Insert IRQ */ +#define IRQ_PCMCIA 4 /* PCMCIA IRQ */ +#define IRQ_VOYAGER 5 /* VOYAGER IRQ */ +#endif +#define IRQ_RTCALM 6 /* RTC Alarm IRQ */ +#define IRQ_RTCTIME 7 /* RTC Timer IRQ */ +#define IRQ_SDCARD 8 /* SD Card IRQ */ +#define IRQ_PCISLOT1 9 /* PCI Slot #1 IRQ */ +#define IRQ_PCISLOT2 10 /* PCI Slot #2 IRQ */ +#define IRQ_EXTENTION 11 /* EXTn IRQ */ + +#endif /* __ASM_SH_RENESAS_RTS7751R2D */ diff --git a/include/asm-sh/rts7751r2d/voyagergx_reg.h b/include/asm-sh/rts7751r2d/voyagergx_reg.h new file mode 100644 index 000000000000..f031b5d6cf54 --- /dev/null +++ b/include/asm-sh/rts7751r2d/voyagergx_reg.h @@ -0,0 +1,313 @@ +/* -------------------------------------------------------------------- */ +/* voyagergx_reg.h */ +/* -------------------------------------------------------------------- */ +/* 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + Copyright 2003 (c) Lineo uSolutions,Inc. +*/ +/* -------------------------------------------------------------------- */ + +#ifndef _VOYAGER_GX_REG_H +#define _VOYAGER_GX_REG_H + +#define VOYAGER_BASE 0xb3e00000 +#define VOYAGER_USBH_BASE (0x40000 + VOYAGER_BASE) +#define VOYAGER_UART_BASE (0x30000 + VOYAGER_BASE) +#define VOYAGER_AC97_BASE (0xa0000 + VOYAGER_BASE) + +#define VOYAGER_IRQ_NUM 32 +#define VOYAGER_IRQ_BASE 50 +#define VOYAGER_USBH_IRQ VOYAGER_IRQ_BASE + 6 +#define VOYAGER_8051_IRQ VOYAGER_IRQ_BASE + 10 +#define VOYAGER_UART0_IRQ VOYAGER_IRQ_BASE + 12 +#define VOYAGER_UART1_IRQ VOYAGER_IRQ_BASE + 13 +#define VOYAGER_AC97_IRQ VOYAGER_IRQ_BASE + 17 + +/* ----- MISC controle register ------------------------------ */ +#define MISC_CTRL (0x000004 + VOYAGER_BASE) +#define MISC_CTRL_USBCLK_48 (3 << 28) +#define MISC_CTRL_USBCLK_96 (2 << 28) +#define MISC_CTRL_USBCLK_CRYSTAL (1 << 28) + +/* ----- GPIO[31:0] register --------------------------------- */ +#define GPIO_MUX_LOW (0x000008 + VOYAGER_BASE) +#define GPIO_MUX_LOW_AC97 0x1F000000 +#define GPIO_MUX_LOW_8051 0x0000ffff +#define GPIO_MUX_LOW_PWM (1 << 29) + +/* ----- GPIO[63:32] register --------------------------------- */ +#define GPIO_MUX_HIGH (0x00000C + VOYAGER_BASE) + +/* ----- DRAM controle register ------------------------------- */ +#define DRAM_CTRL (0x000010 + VOYAGER_BASE) +#define DRAM_CTRL_EMBEDDED (1 << 31) +#define DRAM_CTRL_CPU_BURST_1 (0 << 28) +#define DRAM_CTRL_CPU_BURST_2 (1 << 28) +#define DRAM_CTRL_CPU_BURST_4 (2 << 28) +#define DRAM_CTRL_CPU_BURST_8 (3 << 28) +#define DRAM_CTRL_CPU_CAS_LATENCY (1 << 27) +#define DRAM_CTRL_CPU_SIZE_2 (0 << 24) +#define DRAM_CTRL_CPU_SIZE_4 (1 << 24) +#define DRAM_CTRL_CPU_SIZE_64 (4 << 24) +#define DRAM_CTRL_CPU_SIZE_32 (5 << 24) +#define DRAM_CTRL_CPU_SIZE_16 (6 << 24) +#define DRAM_CTRL_CPU_SIZE_8 (7 << 24) +#define DRAM_CTRL_CPU_COLUMN_SIZE_1024 (0 << 22) +#define DRAM_CTRL_CPU_COLUMN_SIZE_512 (2 << 22) +#define DRAM_CTRL_CPU_COLUMN_SIZE_256 (3 << 22) +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE (1 << 21) +#define DRAM_CTRL_CPU_RESET (1 << 20) +#define DRAM_CTRL_CPU_BANKS (1 << 19) +#define DRAM_CTRL_CPU_WRITE_PRECHARGE (1 << 18) +#define DRAM_CTRL_BLOCK_WRITE (1 << 17) +#define DRAM_CTRL_REFRESH_COMMAND (1 << 16) +#define DRAM_CTRL_SIZE_4 (0 << 13) +#define DRAM_CTRL_SIZE_8 (1 << 13) +#define DRAM_CTRL_SIZE_16 (2 << 13) +#define DRAM_CTRL_SIZE_32 (3 << 13) +#define DRAM_CTRL_SIZE_64 (4 << 13) +#define DRAM_CTRL_SIZE_2 (5 << 13) +#define DRAM_CTRL_COLUMN_SIZE_256 (0 << 11) +#define DRAM_CTRL_COLUMN_SIZE_512 (2 << 11) +#define DRAM_CTRL_COLUMN_SIZE_1024 (3 << 11) +#define DRAM_CTRL_BLOCK_WRITE_TIME (1 << 10) +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE (1 << 9) +#define DRAM_CTRL_ACTIVE_PRECHARGE (1 << 8) +#define DRAM_CTRL_RESET (1 << 7) +#define DRAM_CTRL_REMAIN_ACTIVE (1 << 6) +#define DRAM_CTRL_BANKS (1 << 1) +#define DRAM_CTRL_WRITE_PRECHARGE (1 << 0) + +/* ----- Arvitration control register -------------------------- */ +#define ARBITRATION_CTRL (0x000014 + VOYAGER_BASE) +#define ARBITRATION_CTRL_CPUMEM (1 << 29) +#define ARBITRATION_CTRL_INTMEM (1 << 28) +#define ARBITRATION_CTRL_USB_OFF (0 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_1 (1 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_2 (2 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_3 (3 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_4 (4 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_5 (5 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_6 (6 << 24) +#define ARBITRATION_CTRL_USB_PRIORITY_7 (7 << 24) +#define ARBITRATION_CTRL_PANEL_OFF (0 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_1 (1 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_2 (2 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_3 (3 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_4 (4 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_5 (5 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_6 (6 << 20) +#define ARBITRATION_CTRL_PANEL_PRIORITY_7 (7 << 20) +#define ARBITRATION_CTRL_ZVPORT_OFF (0 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_1 (1 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_2 (2 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_3 (3 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_4 (4 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_5 (5 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_6 (6 << 16) +#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_7 (7 << 16) +#define ARBITRATION_CTRL_CMD_INTPR_OFF (0 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_1 (1 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_2 (2 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_3 (3 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_4 (4 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_5 (5 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_6 (6 << 12) +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_7 (7 << 12) +#define ARBITRATION_CTRL_DMA_OFF (0 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_1 (1 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_2 (2 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_3 (3 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_4 (4 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_5 (5 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_6 (6 << 8) +#define ARBITRATION_CTRL_DMA_PRIORITY_7 (7 << 8) +#define ARBITRATION_CTRL_VIDEO_OFF (0 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_1 (1 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_2 (2 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_3 (3 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_4 (4 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_5 (5 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_6 (6 << 4) +#define ARBITRATION_CTRL_VIDEO_PRIORITY_7 (7 << 4) +#define ARBITRATION_CTRL_CRT_OFF (0 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_1 (1 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_2 (2 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_3 (3 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_4 (4 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_5 (5 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_6 (6 << 0) +#define ARBITRATION_CTRL_CRT_PRIORITY_7 (7 << 0) + +/* ----- Command list status register -------------------------- */ +#define CMD_INTPR_STATUS (0x000024 + VOYAGER_BASE) + +/* ----- Interrupt status register ----------------------------- */ +#define INT_STATUS (0x00002c + VOYAGER_BASE) +#define INT_STATUS_UH (1 << 6) +#define INT_STATUS_MC (1 << 10) +#define INT_STATUS_U0 (1 << 12) +#define INT_STATUS_U1 (1 << 13) +#define INT_STATUS_AC (1 << 17) + +/* ----- Interrupt mask register ------------------------------ */ +#define VOYAGER_INT_MASK (0x000030 + VOYAGER_BASE) +#define VOYAGER_INT_MASK_AC (1 << 17) + +/* ----- Current Gate register ---------------------------------*/ +#define CURRENT_GATE (0x000038 + VOYAGER_BASE) + +/* ----- Power mode 0 gate register --------------------------- */ +#define POWER_MODE0_GATE (0x000040 + VOYAGER_BASE) +#define POWER_MODE0_GATE_G (1 << 6) +#define POWER_MODE0_GATE_U0 (1 << 7) +#define POWER_MODE0_GATE_U1 (1 << 8) +#define POWER_MODE0_GATE_UH (1 << 11) +#define POWER_MODE0_GATE_AC (1 << 18) + +/* ----- Power mode 1 gate register --------------------------- */ +#define POWER_MODE1_GATE (0x000048 + VOYAGER_BASE) +#define POWER_MODE1_GATE_G (1 << 6) +#define POWER_MODE1_GATE_U0 (1 << 7) +#define POWER_MODE1_GATE_U1 (1 << 8) +#define POWER_MODE1_GATE_UH (1 << 11) +#define POWER_MODE1_GATE_AC (1 << 18) + +/* ----- Power mode 0 clock register -------------------------- */ +#define POWER_MODE0_CLOCK (0x000044 + VOYAGER_BASE) + +/* ----- Power mode 1 clock register -------------------------- */ +#define POWER_MODE1_CLOCK (0x00004C + VOYAGER_BASE) + +/* ----- Power mode controll register ------------------------- */ +#define POWER_MODE_CTRL (0x000054 + VOYAGER_BASE) + +/* ----- Miscellaneous Timing register ------------------------ */ +#define SYSTEM_DRAM_CTRL (0x000068 + VOYAGER_BASE) + +/* ----- PWM register ------------------------------------------*/ +#define PWM_0 (0x010020 + VOYAGER_BASE) +#define PWM_0_HC(x) (((x)&0x0fff)<<20) +#define PWM_0_LC(x) (((x)&0x0fff)<<8 ) +#define PWM_0_CLK_DEV(x) (((x)&0x000f)<<4 ) +#define PWM_0_EN (1<<0) + +/* ----- I2C register ----------------------------------------- */ +#define I2C_BYTECOUNT (0x010040 + VOYAGER_BASE) +#define I2C_CONTROL (0x010041 + VOYAGER_BASE) +#define I2C_STATUS (0x010042 + VOYAGER_BASE) +#define I2C_RESET (0x010042 + VOYAGER_BASE) +#define I2C_SADDRESS (0x010043 + VOYAGER_BASE) +#define I2C_DATA (0x010044 + VOYAGER_BASE) + +/* ----- Controle register bits ----------------------------------------- */ +#define I2C_CONTROL_E (1 << 0) +#define I2C_CONTROL_MODE (1 << 1) +#define I2C_CONTROL_STATUS (1 << 2) +#define I2C_CONTROL_INT (1 << 4) +#define I2C_CONTROL_INTACK (1 << 5) +#define I2C_CONTROL_REPEAT (1 << 6) + +/* ----- Status register bits ----------------------------------------- */ +#define I2C_STATUS_BUSY (1 << 0) +#define I2C_STATUS_ACK (1 << 1) +#define I2C_STATUS_ERROR (1 << 2) +#define I2C_STATUS_COMPLETE (1 << 3) + +/* ----- Reset register ---------------------------------------------- */ +#define I2C_RESET_ERROR (1 << 2) + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_SADDRESS_SELECT (1 << 0) + +/* ----- Display Controll register ----------------------------------------- */ +#define PANEL_DISPLAY_CTRL (0x080000 + VOYAGER_BASE) +#define PANEL_DISPLAY_CTRL_BIAS (1<<26) +#define PANEL_PAN_CTRL (0x080004 + VOYAGER_BASE) +#define PANEL_COLOR_KEY (0x080008 + VOYAGER_BASE) +#define PANEL_FB_ADDRESS (0x08000C + VOYAGER_BASE) +#define PANEL_FB_WIDTH (0x080010 + VOYAGER_BASE) +#define PANEL_WINDOW_WIDTH (0x080014 + VOYAGER_BASE) +#define PANEL_WINDOW_HEIGHT (0x080018 + VOYAGER_BASE) +#define PANEL_PLANE_TL (0x08001C + VOYAGER_BASE) +#define PANEL_PLANE_BR (0x080020 + VOYAGER_BASE) +#define PANEL_HORIZONTAL_TOTAL (0x080024 + VOYAGER_BASE) +#define PANEL_HORIZONTAL_SYNC (0x080028 + VOYAGER_BASE) +#define PANEL_VERTICAL_TOTAL (0x08002C + VOYAGER_BASE) +#define PANEL_VERTICAL_SYNC (0x080030 + VOYAGER_BASE) +#define PANEL_CURRENT_LINE (0x080034 + VOYAGER_BASE) +#define VIDEO_DISPLAY_CTRL (0x080040 + VOYAGER_BASE) +#define VIDEO_FB_0_ADDRESS (0x080044 + VOYAGER_BASE) +#define VIDEO_FB_WIDTH (0x080048 + VOYAGER_BASE) +#define VIDEO_FB_0_LAST_ADDRESS (0x08004C + VOYAGER_BASE) +#define VIDEO_PLANE_TL (0x080050 + VOYAGER_BASE) +#define VIDEO_PLANE_BR (0x080054 + VOYAGER_BASE) +#define VIDEO_SCALE (0x080058 + VOYAGER_BASE) +#define VIDEO_INITIAL_SCALE (0x08005C + VOYAGER_BASE) +#define VIDEO_YUV_CONSTANTS (0x080060 + VOYAGER_BASE) +#define VIDEO_FB_1_ADDRESS (0x080064 + VOYAGER_BASE) +#define VIDEO_FB_1_LAST_ADDRESS (0x080068 + VOYAGER_BASE) +#define VIDEO_ALPHA_DISPLAY_CTRL (0x080080 + VOYAGER_BASE) +#define VIDEO_ALPHA_FB_ADDRESS (0x080084 + VOYAGER_BASE) +#define VIDEO_ALPHA_FB_WIDTH (0x080088 + VOYAGER_BASE) +#define VIDEO_ALPHA_FB_LAST_ADDRESS (0x08008C + VOYAGER_BASE) +#define VIDEO_ALPHA_PLANE_TL (0x080090 + VOYAGER_BASE) +#define VIDEO_ALPHA_PLANE_BR (0x080094 + VOYAGER_BASE) +#define VIDEO_ALPHA_SCALE (0x080098 + VOYAGER_BASE) +#define VIDEO_ALPHA_INITIAL_SCALE (0x08009C + VOYAGER_BASE) +#define VIDEO_ALPHA_CHROMA_KEY (0x0800A0 + VOYAGER_BASE) +#define PANEL_HWC_ADDRESS (0x0800F0 + VOYAGER_BASE) +#define PANEL_HWC_LOCATION (0x0800F4 + VOYAGER_BASE) +#define PANEL_HWC_COLOR_12 (0x0800F8 + VOYAGER_BASE) +#define PANEL_HWC_COLOR_3 (0x0800FC + VOYAGER_BASE) +#define ALPHA_DISPLAY_CTRL (0x080100 + VOYAGER_BASE) +#define ALPHA_FB_ADDRESS (0x080104 + VOYAGER_BASE) +#define ALPHA_FB_WIDTH (0x080108 + VOYAGER_BASE) +#define ALPHA_PLANE_TL (0x08010C + VOYAGER_BASE) +#define ALPHA_PLANE_BR (0x080110 + VOYAGER_BASE) +#define ALPHA_CHROMA_KEY (0x080114 + VOYAGER_BASE) +#define CRT_DISPLAY_CTRL (0x080200 + VOYAGER_BASE) +#define CRT_FB_ADDRESS (0x080204 + VOYAGER_BASE) +#define CRT_FB_WIDTH (0x080208 + VOYAGER_BASE) +#define CRT_HORIZONTAL_TOTAL (0x08020C + VOYAGER_BASE) +#define CRT_HORIZONTAL_SYNC (0x080210 + VOYAGER_BASE) +#define CRT_VERTICAL_TOTAL (0x080214 + VOYAGER_BASE) +#define CRT_VERTICAL_SYNC (0x080218 + VOYAGER_BASE) +#define CRT_SIGNATURE_ANALYZER (0x08021C + VOYAGER_BASE) +#define CRT_CURRENT_LINE (0x080220 + VOYAGER_BASE) +#define CRT_MONITOR_DETECT (0x080224 + VOYAGER_BASE) +#define CRT_HWC_ADDRESS (0x080230 + VOYAGER_BASE) +#define CRT_HWC_LOCATION (0x080234 + VOYAGER_BASE) +#define CRT_HWC_COLOR_12 (0x080238 + VOYAGER_BASE) +#define CRT_HWC_COLOR_3 (0x08023C + VOYAGER_BASE) +#define CRT_PALETTE_RAM (0x080400 + VOYAGER_BASE) +#define PANEL_PALETTE_RAM (0x080800 + VOYAGER_BASE) +#define VIDEO_PALETTE_RAM (0x080C00 + VOYAGER_BASE) + +/* ----- 8051 Controle register ----------------------------------------- */ +#define VOYAGER_8051_BASE (0x000c0000 + VOYAGER_BASE) +#define VOYAGER_8051_RESET (0x000b0000 + VOYAGER_BASE) +#define VOYAGER_8051_SELECT (0x000b0004 + VOYAGER_BASE) +#define VOYAGER_8051_CPU_INT (0x000b000c + VOYAGER_BASE) + +/* ----- AC97 Controle register ----------------------------------------- */ +#define AC97_TX_SLOT0 (0x00000000 + VOYAGER_AC97_BASE) +#define AC97_CONTROL_STATUS (0x00000080 + VOYAGER_AC97_BASE) +#define AC97C_READ (1 << 19) +#define AC97C_WD_BIT (1 << 2) +#define AC97C_INDEX_MASK 0x7f +/* -------------------------------------------------------------------- */ + +#endif /* _VOYAGER_GX_REG_H */ -- cgit v1.2.3 From 475552f50fc1a2bf5244e7c8e5fa17a3ab439a31 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:27:11 -0700 Subject: [PATCH] sh: SH7705/SH7300 subtype support, ST40 updates. From: Paul Mundt This adds support for the SH7705 and SH7300 subtypes and also updates some ST40-specific FRQCR handling code. Signed-off-by: Alex Bennee Signed-off-by: Hiroshi DOYU Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/kernel/cpu/irq_ipr.c | 39 ++++-- arch/sh/kernel/cpu/sh3/ex.S | 79 +++++++++++- arch/sh/kernel/entry.S | 5 +- arch/sh/kernel/time.c | 182 +++++++++++++++++++++++++-- include/asm-sh/bugs.h | 2 +- include/asm-sh/irq.h | 288 ++++++++++++++++++++++++++++++++++++++++--- include/asm-sh/processor.h | 4 +- include/asm-sh/ubc.h | 3 +- 8 files changed, 559 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq_ipr.c index c66d6227965a..daae02e6b56d 100644 --- a/arch/sh/kernel/cpu/irq_ipr.c +++ b/arch/sh/kernel/cpu/irq_ipr.c @@ -4,12 +4,13 @@ * * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Takashi Kusuda * * Interrupt handling for IPR-based IRQ. * * Supported system: * On-chip supporting modules (TMU, RTC, etc.). - * On-chip supporting modules for SH7709/SH7709A/SH7729. + * On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300. * Hitachi SolutionEngine external I/O: * MS7709SE01, MS7709ASE01, and MS7750SE01 * @@ -88,7 +89,8 @@ static void mask_and_ack_ipr(unsigned int irq) { disable_ipr_irq(irq); -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { @@ -117,7 +119,9 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) disable_ipr_irq(irq); } -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) static unsigned char pint_map[256]; static unsigned long portcr_mask = 0; @@ -131,7 +135,7 @@ static void mask_and_ack_pint(unsigned int); static void end_pint_irq(unsigned int irq); static unsigned int startup_pint_irq(unsigned int irq) -{ +{ enable_pint_irq(irq); return 0; /* never anything pending */ } @@ -191,13 +195,17 @@ void make_pint_irq(unsigned int irq) void __init init_IRQ(void) { -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) int i; #endif make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); +#if defined(CONFIG_SH_RTC) make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); +#endif #ifdef SCI_ERI_IRQ make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); @@ -212,6 +220,13 @@ void __init init_IRQ(void) make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); +#endif + #ifdef SCIF_ERI_IRQ make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); @@ -226,11 +241,12 @@ void __init init_IRQ(void) make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* * Initialize the Interrupt Controller (INTC) * registers to their power on values - */ + */ /* * Enable external irq (INTC IRQ mode). @@ -243,6 +259,7 @@ void __init init_IRQ(void) make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); enable_ipr_irq(PINT0_IRQ); @@ -261,16 +278,19 @@ void __init init_IRQ(void) else if(i & 0x40) pint_map[i] = 6; else if(i & 0x80) pint_map[i] = 7; } -#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ +#endif /* !CONFIG_CPU_SUBTYPE_SH7300 */ +#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 || CONFIG_CPU_SUBTYPE_SH7300*/ /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) { sh_mv.mv_init_irq(); } } -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) int ipr_irq_demux(int irq) { +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) unsigned long creg, dreg, d, sav; if(irq == PINT0_IRQ) @@ -305,6 +325,7 @@ int ipr_irq_demux(int irq) if(d == 0) return irq; return PINT_IRQ_BASE + 8 + pint_map[d]; } +#endif return irq; } #endif diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index 78df0d1bf060..966c0858b714 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -85,7 +85,8 @@ ENTRY(interrupt_table) .long do_IRQ ! rovi .long do_IRQ .long do_IRQ /* 5E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) .long do_IRQ ! 32 IRQ irq0 /* 600 */ .long do_IRQ ! 33 irq1 .long do_IRQ ! 34 irq2 @@ -115,10 +116,84 @@ ENTRY(interrupt_table) .long do_IRQ ! 58 bri2 .long do_IRQ ! 59 txi2 .long do_IRQ ! 60 ADC adi /* 980 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) + .long exception_none ! 61 /* 9A0 */ + .long exception_none ! 62 + .long exception_none ! 63 + .long exception_none ! 64 /* A00 */ + .long do_IRQ ! 65 USB usi0 + .long do_IRQ ! 66 usi1 + .long exception_none ! 67 + .long exception_none ! 68 + .long exception_none ! 69 + .long exception_none ! 70 + .long exception_none ! 71 + .long exception_none ! 72 /* B00 */ + .long exception_none ! 73 + .long exception_none ! 74 + .long exception_none ! 75 + .long exception_none ! 76 + .long exception_none ! 77 + .long exception_none ! 78 + .long exception_none ! 79 + .long do_IRQ ! 80 TPU0 tpi0 /* C00 */ + .long do_IRQ ! 81 TPU1 tpi1 + .long exception_none ! 82 + .long exception_none ! 83 + .long do_IRQ ! 84 TPU2 tpi2 + .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */ +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300) .long do_IRQ ! 61 LCDC lcdi /* 9A0 */ .long do_IRQ ! 62 PCC pcc0i .long do_IRQ ! 63 pcc1i /* 9E0 */ #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + .long do_IRQ ! 64 + .long do_IRQ ! 65 + .long do_IRQ ! 66 + .long do_IRQ ! 67 + .long do_IRQ ! 68 + .long do_IRQ ! 69 + .long do_IRQ ! 70 + .long do_IRQ ! 71 + .long do_IRQ ! 72 + .long do_IRQ ! 73 + .long do_IRQ ! 74 + .long do_IRQ ! 75 + .long do_IRQ ! 76 + .long do_IRQ ! 77 + .long do_IRQ ! 78 + .long do_IRQ ! 79 + .long do_IRQ ! 80 SCIF0(SH7300) + .long do_IRQ ! 81 + .long do_IRQ ! 82 + .long do_IRQ ! 83 + .long do_IRQ ! 84 + .long do_IRQ ! 85 + .long do_IRQ ! 86 + .long do_IRQ ! 87 + .long do_IRQ ! 88 + .long do_IRQ ! 89 + .long do_IRQ ! 90 + .long do_IRQ ! 91 + .long do_IRQ ! 92 + .long do_IRQ ! 93 + .long do_IRQ ! 94 + .long do_IRQ ! 95 + .long do_IRQ ! 96 + .long do_IRQ ! 97 + .long do_IRQ ! 98 + .long do_IRQ ! 99 + .long do_IRQ ! 100 + .long do_IRQ ! 101 + .long do_IRQ ! 102 + .long do_IRQ ! 103 + .long do_IRQ ! 104 + .long do_IRQ ! 105 + .long do_IRQ ! 106 + .long do_IRQ ! 107 + .long do_IRQ ! 108 +#endif #endif diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index dbc33d72656c..fb0d94dd67cf 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.35 2004/02/21 14:45:47 lethal Exp $ +/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ * * linux/arch/sh/entry.S * @@ -77,7 +77,8 @@ EINVAL = 22 #if defined(CONFIG_CPU_SH3) TRA = 0xffffffd0 EXPEVT = 0xffffffd4 -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000) #else INTEVT = 0xffffffd8 diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 37d66714edba..3bcdf4ca405d 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -1,10 +1,10 @@ -/* $Id: time.c,v 1.19 2004/02/27 00:40:48 lethal Exp $ +/* $Id: time.c,v 1.21 2004/04/21 00:09:15 lethal Exp $ * * linux/arch/sh/kernel/time.c * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002, 2003, 2004 Paul Mundt * Copyright (C) 2002 M. R. Brown * * Some code taken from i386 version. @@ -47,12 +47,26 @@ #define TMU0_TCR_CALIB 0x0000 #if defined(CONFIG_CPU_SH3) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define TMU_TSTR 0xA412FE92 /* Byte access */ + +#define TMU0_TCOR 0xA412FE94 /* Long access */ +#define TMU0_TCNT 0xA412FE98 /* Long access */ +#define TMU0_TCR 0xA412FE9C /* Word access */ + +#define TMU1_TCOR 0xA412FEA0 /* Long access */ +#define TMU1_TCNT 0xA412FEA4 /* Long access */ +#define TMU1_TCR 0xA412FEA8 /* Word access */ + +#define FRQCR 0xA415FF80 +#else #define TMU_TOCR 0xfffffe90 /* Byte access */ #define TMU_TSTR 0xfffffe92 /* Byte access */ #define TMU0_TCOR 0xfffffe94 /* Long access */ #define TMU0_TCNT 0xfffffe98 /* Long access */ #define TMU0_TCR 0xfffffe9c /* Word access */ +#endif #elif defined(CONFIG_CPU_SH4) #define TMU_TOCR 0xffd80000 /* Byte access */ #define TMU_TSTR 0xffd80004 /* Byte access */ @@ -85,6 +99,9 @@ void (*rtc_get_time)(struct timespec *) = 0; int (*rtc_set_time)(const time_t) = 0; #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; +#endif #if defined(CONFIG_CPU_SH3) static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; @@ -337,7 +354,9 @@ static unsigned int __init get_timer_frequency(void) * have it count down at its natural rate. */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); @@ -398,6 +417,15 @@ void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsign unsigned int frqcr = ctrl_inw(FRQCR); #if defined(CONFIG_CPU_SH3) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + *ifc = md_table[((frqcr & 0x0070) >> 4)]; + *bfc = md_table[((frqcr & 0x0700) >> 8)]; + *pfc = md_table[frqcr & 0x0007]; +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) + *bfc = stc_multipliers[(frqcr & 0x0300) >> 8]; + *ifc = ifc_divisors[(frqcr & 0x0030) >> 4]; + *pfc = pfc_divisors[frqcr & 0x0003]; +#else unsigned int tmp; tmp = (frqcr & 0x8000) >> 13; @@ -409,6 +437,7 @@ void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsign tmp = (frqcr & 0x2000) >> 11; tmp |= frqcr & 0x0003; *pfc = pfc_divisors[tmp]; +#endif #elif defined(CONFIG_CPU_SH4) *ifc = ifc_divisors[(frqcr >> 6) & 0x0007]; *bfc = bfc_divisors[(frqcr >> 3) & 0x0007]; @@ -431,26 +460,139 @@ _FREQ_TABLE(ifc); _FREQ_TABLE(bfc); _FREQ_TABLE(pfc); +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + +/* The ST40 divisors are totally different so we set the cpu data +** clocks using a different algorithm +** +** I've just plugged this from the 2.4 code - Alex Bennee +*/ +#define CCN_PVR_CHIP_SHIFT 24 +#define CCN_PVR_CHIP_MASK 0xff +#define CCN_PVR_CHIP_ST40STB1 0x4 + + +struct frqcr_data { + unsigned short frqcr; + struct { + unsigned char multiplier; + unsigned char divisor; + } factor[3]; +}; + +static struct frqcr_data st40_frqcr_table[] = { + { 0x000, {{1,1}, {1,1}, {1,2}}}, + { 0x002, {{1,1}, {1,1}, {1,4}}}, + { 0x004, {{1,1}, {1,1}, {1,8}}}, + { 0x008, {{1,1}, {1,2}, {1,2}}}, + { 0x00A, {{1,1}, {1,2}, {1,4}}}, + { 0x00C, {{1,1}, {1,2}, {1,8}}}, + { 0x011, {{1,1}, {2,3}, {1,6}}}, + { 0x013, {{1,1}, {2,3}, {1,3}}}, + { 0x01A, {{1,1}, {1,2}, {1,4}}}, + { 0x01C, {{1,1}, {1,2}, {1,8}}}, + { 0x023, {{1,1}, {2,3}, {1,3}}}, + { 0x02C, {{1,1}, {1,2}, {1,8}}}, + { 0x048, {{1,2}, {1,2}, {1,4}}}, + { 0x04A, {{1,2}, {1,2}, {1,6}}}, + { 0x04C, {{1,2}, {1,2}, {1,8}}}, + { 0x05A, {{1,2}, {1,3}, {1,6}}}, + { 0x05C, {{1,2}, {1,3}, {1,6}}}, + { 0x063, {{1,2}, {1,4}, {1,4}}}, + { 0x06C, {{1,2}, {1,4}, {1,8}}}, + { 0x091, {{1,3}, {1,3}, {1,6}}}, + { 0x093, {{1,3}, {1,3}, {1,6}}}, + { 0x0A3, {{1,3}, {1,6}, {1,6}}}, + { 0x0DA, {{1,4}, {1,4}, {1,8}}}, + { 0x0DC, {{1,4}, {1,4}, {1,8}}}, + { 0x0EC, {{1,4}, {1,8}, {1,8}}}, + { 0x123, {{1,4}, {1,4}, {1,8}}}, + { 0x16C, {{1,4}, {1,8}, {1,8}}}, +}; + +struct memclk_data { + unsigned char multiplier; + unsigned char divisor; +}; +static struct memclk_data st40_memclk_table[8] = { + {1,1}, // 000 + {1,2}, // 001 + {1,3}, // 010 + {2,3}, // 011 + {1,4}, // 100 + {1,6}, // 101 + {1,8}, // 110 + {1,8} // 111 +}; + +static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr) +{ + unsigned int cpu_clock, master_clock, bus_clock, memory_clock; + struct frqcr_data *d; + int a; + unsigned long memclkcr; + struct memclk_data *e; + + for (a=0; afrqcr == (frqcr & 0x1ff)) + break; + } + if (a == ARRAY_SIZE(st40_frqcr_table)) { + d = st40_frqcr_table; + printk("ERROR: Unrecognised FRQCR value (0x%x), using default multipliers\n",frqcr); + } + + memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR); + e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK]; + + printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n", + d->factor[0].multiplier, d->factor[0].divisor, + d->factor[1].multiplier, d->factor[1].divisor, + e->multiplier, e->divisor, + d->factor[2].multiplier, d->factor[2].divisor); + + master_clock = module_clock * d->factor[2].divisor / d->factor[2].multiplier; + bus_clock = master_clock * d->factor[1].multiplier / d->factor[1].divisor; + memory_clock = master_clock * e->multiplier / e->divisor; + cpu_clock = master_clock * d->factor[0].multiplier / d->factor[0].divisor; + + current_cpu_data.cpu_clock = cpu_clock; + current_cpu_data.master_clock = master_clock; + current_cpu_data.bus_clock = bus_clock; + current_cpu_data.memory_clock = memory_clock; + current_cpu_data.module_clock = module_clock; + +} + +#endif + void __init time_init(void) { unsigned int timer_freq = 0; unsigned int ifc, pfc, bfc; unsigned long interval; +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + unsigned long pvr; + unsigned short frqcr; +#endif if (board_time_init) board_time_init(); - get_current_frequency_divisors(&ifc, &bfc, &pfc); /* * If we don't have an RTC (such as with the SH7300), don't attempt to * probe the timer frequency. Rely on an either hardcoded peripheral - * clock value, or on the sh_pclk command line option. + * clock value, or on the sh_pclk command line option. Note that we + * still need to have CONFIG_SH_PCLK_FREQ set in order for things like + * CLOCK_TICK_RATE to be sane. */ current_cpu_data.module_clock = sh_pclk_freq; +#ifdef CONFIG_SH_PCLK_CALC /* XXX: Switch this over to a more generic test. */ - if (current_cpu_data.type != CPU_SH7300) { + { unsigned int freq; /* @@ -466,15 +608,31 @@ void __init time_init(void) timer_freq = get_timer_frequency(); freq = timer_freq * 4; - if (sh_pclk_freq && sh_pclk_freq != freq) { + if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) { printk(KERN_NOTICE "Calculated peripheral clock value " "%d differs from sh_pclk value %d, fixing..\n", freq, sh_pclk_freq); current_cpu_data.module_clock = freq; } } +#endif + +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + pvr = ctrl_inl(CCN_PVR); + frqcr = ctrl_inw(FRQCR); + printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr); + if (((pvr >>CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) + st40_specific_time_init(current_cpu_data.module_clock, frqcr); + else +#endif + get_current_frequency_divisors(&ifc, &bfc, &pfc); - rtc_get_time(&xtime); + if (rtc_get_time) + rtc_get_time(&xtime); + else { + xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); + xtime.tv_nsec = 0; + } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); @@ -485,6 +643,10 @@ void __init time_init(void) setup_irq(TIMER_IRQ, &irq0); } + /* + ** for ST40 chips the current_cpu_data should already be set + ** so not having valid pfc/bfc/ifc shouldn't be a problem + */ if (!current_cpu_data.master_clock) current_cpu_data.master_clock = current_cpu_data.module_clock * pfc; if (!current_cpu_data.bus_clock) @@ -506,13 +668,19 @@ void __init time_init(void) printk("Module clock: %d.%02dMHz\n", (current_cpu_data.module_clock / 1000000), (current_cpu_data.module_clock % 1000000)/10000); +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + interval = ((current_cpu_data.module_clock/4 + HZ/2) / HZ) - 1; +#else interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ; +#endif printk("Interval = %ld\n", interval); /* Start TMU0 */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index 9ceca407fe60..154d774f982f 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h @@ -26,7 +26,7 @@ static void __init check_bugs(void) case CPU_SH7604: *p++ = '2'; break; - case CPU_SH7708 ... CPU_SH7729: + case CPU_SH7705 ... CPU_SH7300: *p++ = '3'; break; case CPU_SH7750 ... CPU_ST40GX1: diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index 7dd2a5ae10b5..58bd8df7a53d 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h @@ -15,9 +15,15 @@ #include #include /* for pt_regs */ +#if defined(CONFIG_SH_HP600) || \ + defined(CONFIG_SH_RTS7751R2D) || \ + defined(CONFIG_SH_HS7751RVOIP) +#include +#endif + #if defined(CONFIG_CPU_SH3) -#define INTC_IPRA 0xfffffee2UL -#define INTC_IPRB 0xfffffee4UL +#define INTC_IPRA 0xfffffee2UL +#define INTC_IPRB 0xfffffee4UL #elif defined(CONFIG_CPU_SH4) #define INTC_IPRA 0xffd00004UL #define INTC_IPRB 0xffd00008UL @@ -25,6 +31,15 @@ #define INTC_IPRD 0xffd00010UL #endif +#ifdef CONFIG_IDE +# ifndef IRQ_CFCARD +# define IRQ_CFCARD 14 +# endif +# ifndef IRQ_PCMCIA +# define IRQ_PCMCIA 15 +# endif +#endif + #define TIMER_IRQ 16 #define TIMER_IPR_ADDR INTC_IPRA #define TIMER_IPR_POS 3 @@ -48,6 +63,111 @@ #define DMA_IPR_ADDR INTC_IPRE #define DMA_IPR_POS 3 #define DMA_PRIORITY 7 +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +/* TMU2 */ +#define TIMER2_IRQ 18 +#define TIMER2_IPR_ADDR INTC_IPRA +#define TIMER2_IPR_POS 1 +#define TIMER2_PRIORITY 2 + +/* WDT */ +#define WDT_IRQ 27 +#define WDT_IPR_ADDR INTC_IPRB +#define WDT_IPR_POS 3 +#define WDT_PRIORITY 2 + +/* SIM (SIM Card Module) */ +#define SIM_ERI_IRQ 23 +#define SIM_RXI_IRQ 24 +#define SIM_TXI_IRQ 25 +#define SIM_TEND_IRQ 26 +#define SIM_IPR_ADDR INTC_IPRB +#define SIM_IPR_POS 1 +#define SIM_PRIORITY 2 + +/* VIO (Video I/O) */ +#define VIO_IRQ 52 +#define VIO_IPR_ADDR INTC_IPRE +#define VIO_IPR_POS 2 +#define VIO_PRIORITY 2 + +/* MFI (Multi Functional Interface) */ +#define MFI_IRQ 56 +#define MFI_IPR_ADDR INTC_IPRE +#define MFI_IPR_POS 1 +#define MFI_PRIORITY 2 + +/* VPU (Video Processing Unit) */ +#define VPU_IRQ 60 +#define VPU_IPR_ADDR INTC_IPRE +#define VPU_IPR_POS 0 +#define VPU_PRIORITY 2 + +/* KEY (Key Scan Interface) */ +#define KEY_IRQ 79 +#define KEY_IPR_ADDR INTC_IPRF +#define KEY_IPR_POS 3 +#define KEY_PRIORITY 2 + +/* CMT (Compare Match Timer) */ +#define CMT_IRQ 104 +#define CMT_IPR_ADDR INTC_IPRF +#define CMT_IPR_POS 0 +#define CMT_PRIORITY 2 + +/* DMAC(1) */ +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMA1_IPR_ADDR INTC_IPRE +#define DMA1_IPR_POS 3 +#define DMA1_PRIORITY 7 + +/* DMAC(2) */ +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 +#define DMA2_IPR_ADDR INTC_IPRF +#define DMA2_IPR_POS 2 +#define DMA2_PRIORITY 7 + +/* SIOF0 */ +#define SIOF0_IRQ 84 +#define SIOF0_IPR_ADDR INTC_IPRH +#define SIOF0_IPR_POS 3 +#define SIOF0_PRIORITY 3 + +/* FLCTL (Flash Memory Controller) */ +#define FLSTE_IRQ 92 +#define FLTEND_IRQ 93 +#define FLTRQ0_IRQ 94 +#define FLTRQ1_IRQ 95 +#define FLCTL_IPR_ADDR INTC_IPRH +#define FLCTL_IPR_POS 1 +#define FLCTL_PRIORITY 3 + +/* IIC (IIC Bus Interface) */ +#define IIC_ALI_IRQ 96 +#define IIC_TACKI_IRQ 97 +#define IIC_WAITI_IRQ 98 +#define IIC_DTEI_IRQ 99 +#define IIC_IPR_ADDR INTC_IPRH +#define IIC_IPR_POS 0 +#define IIC_PRIORITY 3 + +/* SIO0 */ +#define SIO0_IRQ 88 +#define SIO0_IPR_ADDR INTC_IPRI +#define SIO0_IPR_POS 3 +#define SIO0_PRIORITY 3 + +/* SIU (Sound Interface Unit) */ +#define SIU_IRQ 108 +#define SIU_IPR_ADDR INTC_IPRJ +#define SIU_IPR_POS 1 +#define SIU_PRIORITY 3 + +#endif #elif defined(CONFIG_CPU_SH4) #define DMTE0_IRQ 34 #define DMTE1_IRQ 35 @@ -74,7 +194,14 @@ #define SCI_PRIORITY 3 #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF0_IRQ 80 +#define SCIF0_IPR_ADDR INTC_IPRG +#define SCIF0_IPR_POS 3 +#define SCIF0_PRIORITY 3 +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) #define SCIF_ERI_IRQ 56 #define SCIF_RXI_IRQ 57 #define SCIF_BRI_IRQ 58 @@ -127,7 +254,8 @@ # define PINT_NR_IRQS 16 # elif defined(CONFIG_CPU_SUBTYPE_SH7708) # define ONCHIP_NR_IRQS 32 -# elif defined(CONFIG_CPU_SUBTYPE_SH7709) +# elif defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7705) # define ONCHIP_NR_IRQS 64 // Actually 61 # define PINT_NR_IRQS 16 # elif defined(CONFIG_CPU_SUBTYPE_SH7750) @@ -138,6 +266,8 @@ # define ONCHIP_NR_IRQS 110 # elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) # define ONCHIP_NR_IRQS 144 +# elif defined(CONFIG_CPU_SUBTYPE_SH7300) +# define ONCHIP_NR_IRQS 109 # endif #endif @@ -207,7 +337,121 @@ extern void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority); extern void make_imask_irq(unsigned int irq); -#if defined(CONFIG_CPU_SUBTYPE_SH7604) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#undef INTC_IPRA +#undef INTC_IPRB +#define INTC_IPRA 0xA414FEE2UL +#define INTC_IPRB 0xA414FEE4UL +#define INTC_IPRC 0xA4140016UL +#define INTC_IPRD 0xA4140018UL +#define INTC_IPRE 0xA414001AUL +#define INTC_IPRF 0xA4080000UL +#define INTC_IPRG 0xA4080002UL +#define INTC_IPRH 0xA4080004UL +#define INTC_IPRI 0xA4080006UL +#define INTC_IPRJ 0xA4080008UL + +#define INTC_IMR0 0xA4080040UL +#define INTC_IMR1 0xA4080042UL +#define INTC_IMR2 0xA4080044UL +#define INTC_IMR3 0xA4080046UL +#define INTC_IMR4 0xA4080048UL +#define INTC_IMR5 0xA408004AUL +#define INTC_IMR6 0xA408004CUL +#define INTC_IMR7 0xA408004EUL +#define INTC_IMR8 0xA4080050UL +#define INTC_IMR9 0xA4080052UL +#define INTC_IMR10 0xA4080054UL + +#define INTC_IMCR0 0xA4080060UL +#define INTC_IMCR1 0xA4080062UL +#define INTC_IMCR2 0xA4080064UL +#define INTC_IMCR3 0xA4080066UL +#define INTC_IMCR4 0xA4080068UL +#define INTC_IMCR5 0xA408006AUL +#define INTC_IMCR6 0xA408006CUL +#define INTC_IMCR7 0xA408006EUL +#define INTC_IMCR8 0xA4080070UL +#define INTC_IMCR9 0xA4080072UL +#define INTC_IMCR10 0xA4080074UL + +#define INTC_ICR0 0xA414FEE0UL +#define INTC_ICR1 0xA4140010UL + +#define INTC_IRR0 0xA4140004UL + +#define PORT_PACR 0xA4050100UL +#define PORT_PBCR 0xA4050102UL +#define PORT_PCCR 0xA4050104UL +#define PORT_PDCR 0xA4050106UL +#define PORT_PECR 0xA4050108UL +#define PORT_PFCR 0xA405010AUL +#define PORT_PGCR 0xA405010CUL +#define PORT_PHCR 0xA405010EUL +#define PORT_PJCR 0xA4050110UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PLCR 0xA4050114UL +#define PORT_SCPCR 0xA4050116UL +#define PORT_PMCR 0xA4050118UL +#define PORT_PNCR 0xA405011AUL +#define PORT_PQCR 0xA405011CUL + +#define PORT_PSELA 0xA4050140UL +#define PORT_PSELB 0xA4050142UL +#define PORT_PSELC 0xA4050144UL + +#define PORT_HIZCRA 0xA4050146UL +#define PORT_HIZCRB 0xA4050148UL +#define PORT_DRVCR 0xA4050150UL + +#define PORT_PADR 0xA4050120UL +#define PORT_PBDR 0xA4050122UL +#define PORT_PCDR 0xA4050124UL +#define PORT_PDDR 0xA4050126UL +#define PORT_PEDR 0xA4050128UL +#define PORT_PFDR 0xA405012AUL +#define PORT_PGDR 0xA405012CUL +#define PORT_PHDR 0xA405012EUL +#define PORT_PJDR 0xA4050130UL +#define PORT_PKDR 0xA4050132UL +#define PORT_PLDR 0xA4050134UL +#define PORT_SCPDR 0xA4050136UL +#define PORT_PMDR 0xA4050138UL +#define PORT_PNDR 0xA405013AUL +#define PORT_PQDR 0xA405013CUL + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 + +#define IRQ0_IPR_ADDR INTC_IPRC +#define IRQ1_IPR_ADDR INTC_IPRC +#define IRQ2_IPR_ADDR INTC_IPRC +#define IRQ3_IPR_ADDR INTC_IPRC +#define IRQ4_IPR_ADDR INTC_IPRD +#define IRQ5_IPR_ADDR INTC_IPRD + +#define IRQ0_IPR_POS 0 +#define IRQ1_IPR_POS 1 +#define IRQ2_IPR_POS 2 +#define IRQ3_IPR_POS 3 +#define IRQ4_IPR_POS 0 +#define IRQ5_IPR_POS 1 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 + +extern int ipr_irq_demux(int irq); +#define __irq_demux(irq) ipr_irq_demux(irq) + +#elif defined(CONFIG_CPU_SUBTYPE_SH7604) #define INTC_IPRA 0xfffffee2UL #define INTC_IPRB 0xfffffe60UL @@ -222,21 +466,27 @@ extern void make_imask_irq(unsigned int irq); #define INTC_VCRDMA1 0xffffffa8UL #define INTC_ICR 0xfffffee0UL -#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) #define INTC_IRR0 0xa4000004UL #define INTC_IRR1 0xa4000006UL #define INTC_IRR2 0xa4000008UL -#define INTC_ICR0 0xfffffee0UL -#define INTC_ICR1 0xa4000010UL -#define INTC_ICR2 0xa4000012UL -#define INTC_INTER 0xa4000014UL +#define INTC_ICR0 0xfffffee0UL +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR2 0xa4000012UL +#define INTC_INTER 0xa4000014UL -#define INTC_IPRC 0xa4000016UL -#define INTC_IPRD 0xa4000018UL -#define INTC_IPRE 0xa400001aUL +#define INTC_IPRC 0xa4000016UL +#define INTC_IPRD 0xa4000018UL +#define INTC_IPRE 0xa400001aUL #if defined(CONFIG_CPU_SUBTYPE_SH7707) #define INTC_IPRF 0xa400001cUL +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) +#define INTC_IPRF 0xa4080000UL +#define INTC_IPRG 0xa4080002UL +#define INTC_IPRH 0xa4080004UL #endif #define PORT_PACR 0xa4000100UL @@ -307,20 +557,20 @@ extern int ipr_irq_demux(int irq); #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 #define INTC2_FIRST_IRQ 64 #define NR_INTC2_IRQS 25 - + #define INTC2_BASE0 0xfe080000 #define INTC2_INTC2MODE (INTC2_BASE0+0x80) - + #define INTC2_INTPRI_OFFSET 0x00 #define INTC2_INTREQ_OFFSET 0x20 #define INTC2_INTMSK_OFFSET 0x40 #define INTC2_INTMSKCLR_OFFSET 0x60 - + extern void make_intc2_irq(unsigned int irq,unsigned int addr, unsigned int group,int pos,int priority); - -#endif - + +#endif + static inline int generic_irq_demux(int irq) { return irq; diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 786d41c3663c..0eaf9d91b54d 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -37,8 +37,8 @@ enum cpu_type { CPU_SH7604, /* SH-3 types */ - CPU_SH7707, CPU_SH7708, CPU_SH7708S, CPU_SH7708R, CPU_SH7709, - CPU_SH7709A, CPU_SH7729, CPU_SH7300, + CPU_SH7705, CPU_SH7707, CPU_SH7708, CPU_SH7708S, CPU_SH7708R, + CPU_SH7709, CPU_SH7709A, CPU_SH7729, CPU_SH7300, /* SH-4 types */ CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R, diff --git a/include/asm-sh/ubc.h b/include/asm-sh/ubc.h index 412a6496ce95..a42dd7adfb4c 100644 --- a/include/asm-sh/ubc.h +++ b/include/asm-sh/ubc.h @@ -14,7 +14,8 @@ #include /* User Break Controller */ -#if defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) #define UBC_TYPE_SH7729 (cpu_data->type == CPU_SH7729) #else #define UBC_TYPE_SH7729 0 -- cgit v1.2.3 From 6bac468e24b8e3659377d43e9d1db57b3f405e35 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:27:35 -0700 Subject: [PATCH] sh: merge. From: Paul Mundt This merges the remaining sh changes, random bug fixes, added syscalls, cache fixups, etc. Nothing really eventful. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sh/new-machine.txt | 8 +- arch/sh/Kconfig | 126 ++++++++++++++++++++++--- arch/sh/Makefile | 28 ++++-- arch/sh/boot/compressed/Makefile | 4 + arch/sh/boot/compressed/misc.c | 34 +++---- arch/sh/kernel/cpu/Makefile | 2 +- arch/sh/kernel/cpu/bus.c | 195 +++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/init.c | 54 ++++++----- arch/sh/kernel/entry.S | 10 +- arch/sh/kernel/io_generic.c | 58 ++++++++++-- arch/sh/kernel/irq.c | 43 +++++++++ arch/sh/kernel/process.c | 35 ++++++- arch/sh/kernel/ptrace.c | 9 +- arch/sh/kernel/setup.c | 159 ++++--------------------------- arch/sh/kernel/sh_ksyms.c | 4 + arch/sh/kernel/traps.c | 6 +- arch/sh/kernel/vmlinux.lds.S | 8 ++ arch/sh/lib/delay.c | 6 ++ arch/sh/mm/cache-sh3.c | 14 +-- arch/sh/mm/cache-sh4.c | 56 +++++------ arch/sh/mm/tlb-sh3.c | 2 +- arch/sh/ramdisk/Makefile | 19 ++++ arch/sh/ramdisk/ld.script | 9 ++ arch/sh/tools/mach-types | 3 + include/asm-sh/bus-sh.h | 65 +++++++++++++ include/asm-sh/cache.h | 3 +- include/asm-sh/cpu-sh3/dac.h | 7 +- include/asm-sh/processor.h | 3 +- include/asm-sh/serial.h | 3 - include/asm-sh/sigcontext.h | 22 ++++- include/asm-sh/unistd.h | 12 ++- 31 files changed, 729 insertions(+), 278 deletions(-) create mode 100644 arch/sh/kernel/cpu/bus.c create mode 100644 arch/sh/ramdisk/Makefile create mode 100644 arch/sh/ramdisk/ld.script create mode 100644 include/asm-sh/bus-sh.h (limited to 'include') diff --git a/Documentation/sh/new-machine.txt b/Documentation/sh/new-machine.txt index 8bc5f21f890b..eb2dd2e6993b 100644 --- a/Documentation/sh/new-machine.txt +++ b/Documentation/sh/new-machine.txt @@ -188,13 +188,7 @@ adding a machine called vapor): - add a new file include/asm-sh/vapor/io.h which contains prototypes for any machine specific IO functions prefixed with the machine name, for example vapor_inb. These will be needed when filling out the machine - vector. In addition, a section is required which defines what to do when - building a machine specific version. For example: - - #ifdef __WANT_IO_DEF - #define inb vapor_inb - ... - #endif + vector. This is the minimum that is required, however there are ample opportunities to optimise this. In particular, by making the prototypes diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8efb8e02aaf7..ce61d06cae26 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -45,6 +45,12 @@ config SH_7751_SOLUTION_ENGINE Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evalutation board. +config SH_7300_SOLUTION_ENGINE + bool "SolutionEngine7300" + help + Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) + evalutation board. + config SH_7751_SYSTEMH bool "SystemH7751R" help @@ -138,6 +144,18 @@ config SH_SECUREEDGE5410 This includes both the OEM SecureEdge products as well as the SME product line. +config SH_HS7751RVOIP + bool "HS7751RVOIP" + help + Select HS7751RVOIP if configuring for a Renesas Technology + Sales VoIP board. + +config SH_RTS7751R2D + bool "RTS7751R2D" + help + Select RTS7751R2D if configuring for a Renesas Technology + Sales SH-Graphics board. + config SH_UNKNOWN bool "BareCPU" help @@ -186,7 +204,11 @@ config CPU_SUBTYPE_SH7604 config CPU_SUBTYPE_SH7300 bool "SH7300" depends on CPU_SH3 - + +config CPU_SUBTYPE_SH7705 + bool "SH7705" + depends on CPU_SH3 + config CPU_SUBTYPE_SH7707 bool "SH7707" depends on CPU_SH3 @@ -224,10 +246,17 @@ config CPU_SUBTYPE_SH7760 depends on CPU_SH4 config CPU_SUBTYPE_ST40STB1 - bool "ST40STB1" - depends on CPU_SH4 - help - Select ST40STB1 if you have a ST40STB1 CPU. + bool "ST40STB1 / ST40RA" + depends on CPU_SH4 + help + Select ST40STB1 if you have a ST40RA CPU. + This was previously called the ST40STB1, hence the option name. + +config CPU_SUBTYPE_ST40GX1 + bool "ST40GX1" + depends on CPU_SH4 + help + Select ST40GX1 if you have a ST40GX1 CPU. endchoice @@ -268,7 +297,7 @@ config CMDLINE config MEMORY_START hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SECUREEDGE5410 - default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE) + default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D) ---help--- Computers built with Hitachi SuperH processors always map the ROM starting at address zero. But the processor @@ -287,7 +316,7 @@ config MEMORY_SIZE hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000) default "0x01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST || SH_SECUREEDGE5410 - default "0x04000000" if !MEMORY_OVERRIDE && SH_7751_SOLUTION_ENGINE + default "0x04000000" if !MEMORY_OVERRIDE && (SH_7751_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D) default "0x02000000" if !MEMORY_OVERRIDE && SH_SOLUTION_ENGINE default "0x08000000" if SH_MPC1211 help @@ -299,7 +328,7 @@ config MEMORY_SIZE config MEMORY_SET bool - depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410) + depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410 || SH_HS7751RVOIP || SH_RTS7751R2D) default y help This is an option about which you will never be asked a question. @@ -358,7 +387,7 @@ config CF_BASE_ADDR # The SH7750 RTC module is disabled in the Dreamcast config SH_RTC bool - depends on !SH_DREAMCAST && !SH_SATURN + depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE default y help Selecting this option will allow the Linux kernel to emulate @@ -377,11 +406,26 @@ config SH_DSP This option must be set in order to enable the DSP. +config SH_ADC + bool "ADC support" + depends on CPU_SH3 + default y + help + Selecting this option will allow the Linux kernel to use SH3 on-chip + ADC module. + + If unsure, say N. + config SH_HP600 bool depends on SH_HP620 || SH_HP680 || SH_HP690 default y +config CPU_SUBTYPE_ST40 + bool + depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 + default y + config DISCONTIGMEM bool depends on SH_HP690 @@ -514,10 +558,32 @@ config NR_CPUS This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. +config HS7751RVOIP_CODEC + bool "Support VoIP Codec section" + depends on SH_HS7751RVOIP + help + Selecting this option will support CODEC section. + +config RTS7751R2D_REV11 + bool "RTS7751R2D Rev. 1.1 board support" + depends on SH_RTS7751R2D + help + Selecting this option will support version rev. 1.1. + +config SH_PCLK_CALC + bool + default n if CPU_SUBTYPE_SH7300 + default y + help + This option will cause the PCLK value to be probed at run-time. It + will display a notification if the probed value has greater than a + 1% variance of the hardcoded CONFIG_SH_PCLK_FREQ. + config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "49876504" if CPU_SUBTYPE_SH7750 default "60013568" if CPU_SUBTYPE_SH7751 + default "33333333" if CPU_SUBTYPE_SH7300 default "1193182" help This option is used to specify the peripheral clock frequency. This @@ -570,12 +636,18 @@ source "arch/sh/cchips/Kconfig" config HEARTBEAT bool "Heartbeat LED" - depends on SH_MPC1211 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE + depends on SH_MPC1211 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_RTS7751R2D help Use the power-on LED on your machine as a load meter. The exact behavior is platform-dependent, but normally the flash frequency is a hyperbolic function of the 5-minute load average. +config RTC_9701JE + tristate "EPSON RTC-9701JE support" + depends on SH_RTS7751R2D + help + Selecting this option will support EPSON RTC-9701JE. + endmenu @@ -646,6 +718,24 @@ source "fs/Kconfig.binfmt" endmenu +menu "SH initrd options" + depends on BLK_DEV_INITRD + +config EMBEDDED_RAMDISK + bool "Embed root filesystem ramdisk into the kernel" + +config EMBEDDED_RAMDISK_IMAGE + string "Filename of gziped ramdisk image" + depends on EMBEDDED_RAMDISK + default "ramdisk.gz" + help + This is the filename of the ramdisk image to be built into the + kernel. Relative pathnames are relative to arch/mips/ramdisk/. + The ramdisk image is not part of the kernel distribution; you must + provide one yourself. + +endmenu + source "drivers/Kconfig" source "fs/Kconfig" @@ -675,6 +765,14 @@ config DEBUG_SPINLOCK best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +config DEBUG_INFO + bool "Compile the kernel with debug info" + help + If you say Y here the resulting kernel image will include + debugging info resulting in a larger kernel image. + Say Y here only if you plan to use gdb to debug the kernel. + If you don't debug the kernel, you can say N. + config SH_STANDARD_BIOS bool "Use LinuxSH standard BIOS" help @@ -688,9 +786,13 @@ config SH_STANDARD_BIOS mask ROM and no flash (WindowsCE machines fall in this category). If unsure, say N. -config SH_EARLY_PRINTK +config EARLY_SCIF_CONSOLE + bool "Use early SCIF console" + depends on CPU_SH4 + +config EARLY_PRINTK bool "Early printk support" - depends on SH_STANDARD_BIOS + depends on SH_STANDARD_BIOS || EARLY_SCIF_CONSOLE help Say Y here to redirect kernel printk messages to the serial port used by the SH-IPL bootloader, starting very early in the boot diff --git a/arch/sh/Makefile b/arch/sh/Makefile index ea63935f1a9e..7e0087146eb2 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -1,11 +1,11 @@ -# $Id: Makefile,v 1.34 2004/03/21 17:31:06 lethal Exp $ +# $Id: Makefile,v 1.35 2004/04/15 03:39:20 sugioka Exp $ # # 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) 1999 Kaz Kojima -# Copyright (C) 2002, 2003 Paul Mundt +# Copyright (C) 2002, 2003, 2004 Paul Mundt # Copyright (C) 2002 M. R. Brown # # This file is included by the global makefile so that you can add your own @@ -64,10 +64,18 @@ LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) core-y += arch/sh/kernel/ arch/sh/mm/ +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named +# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames +# are relative to arch/sh/ramdisk/. +# +core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/ + # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 -machdir-$(CONFIG_SH_7751_SYSTEMH) := systemh +machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 machdir-$(CONFIG_SH_STB1_HARP) := harp machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive machdir-$(CONFIG_SH_HP620) := hp6xx/hp620 @@ -84,19 +92,24 @@ machdir-$(CONFIG_SH_SH2000) := sh2000 machdir-$(CONFIG_SH_ADX) := adx machdir-$(CONFIG_SH_MPC1211) := mpc1211 machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear +machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip +machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d +machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh machdir-$(CONFIG_SH_UNKNOWN) := unknown -incdir-y := $(machdir-y) +incdir-y := $(notdir $(machdir-y)) incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751 +incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300 incdir-$(CONFIG_SH_HP600) := hp6xx core-y += arch/sh/boards/$(machdir-y)/ # Companion chips -core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ -core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ +core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ +core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ +core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 @@ -114,6 +127,9 @@ AFLAGS_vmlinux.lds.o := -traditional prepare: target_links .PHONY: target_links FORCE + +all: zImage + target_links: @echo ' Making asm-sh/cpu -> asm-sh/$(cpuincdir-y) link' @rm -f include/asm-sh/cpu diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 04489a938105..05ca14dfafb8 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -15,7 +15,11 @@ endif # # IMAGE_OFFSET is the load offset of the compression loader +# Assign dummy values if these 2 variables are not defined, +# in order to suppress error message. # +CONFIG_MEMORY_START ?= 0x0c000000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds.s diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 1ed7425a4467..211e9110074f 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -1,7 +1,7 @@ /* * arch/sh/boot/compressed/misc.c - * - * This is a collection of several routines from gzip-1.0.3 + * + * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. * * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 @@ -52,7 +52,7 @@ static unsigned outcnt = 0; /* bytes in output buffer */ #define RESERVED 0xC0 /* bit 6,7: reserved */ #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - + /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -75,7 +75,7 @@ static void flush_window(void); static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); - + extern char input_data[]; extern int input_len; @@ -83,20 +83,19 @@ static long bytes_out = 0; static uch *output_data; static unsigned long output_ptr = 0; - static void *malloc(int size); static void free(void *where); static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); - -static void puts(const char *); - + +int puts(const char *); + extern int _text; /* Defined in vmlinux.lds.S */ extern int _end; static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; - + #define HEAP_SIZE 0x10000 #include "../../../../lib/inflate.c" @@ -134,7 +133,7 @@ static void gzip_release(void **ptr) } #ifdef CONFIG_SH_STANDARD_BIOS -static int strlen(const char *s) +size_t strlen(const char *s) { int i = 0; @@ -143,14 +142,17 @@ static int strlen(const char *s) return i; } -void puts(const char *s) +int puts(const char *s) { - sh_bios_console_write(s, strlen(s)); + int len = strlen(s); + sh_bios_console_write(s, len); + return len; } #else -void puts(const char *s) +int puts(const char *s) { - /* This should be updated to use the sh-sci routines */ + /* This should be updated to use the sh-sci routines */ + return 0; } #endif @@ -198,9 +200,9 @@ static void flush_window(void) ulg c = crc; /* temporary variable */ unsigned n; uch *in, *out, ch; - + in = window; - out = &output_data[output_ptr]; + out = &output_data[output_ptr]; for (n = 0; n < outcnt; n++) { ch = *out++ = *in++; c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 505115205661..cd43714df61a 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH CPU-specifc backends. # -obj-y := irq_ipr.o irq_imask.o init.o +obj-y := irq_ipr.o irq_imask.o init.o bus.o obj-$(CONFIG_CPU_SH2) += sh2/ obj-$(CONFIG_CPU_SH3) += sh3/ diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c new file mode 100644 index 000000000000..ace82f4b4a59 --- /dev/null +++ b/arch/sh/kernel/cpu/bus.c @@ -0,0 +1,195 @@ +/* + * arch/sh/kernel/cpu/bus.c + * + * Virtual bus for SuperH. + * + * Copyright (C) 2004 Paul Mundt + * + * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written + * by: + * + * Copyright (C) 2003 - 2004 Nokia Corporation + * Written by Tony Lindgren + * Portions of code based on sa1111.c. + * + * 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. + */ +#include +#include +#include +#include +#include + +static int sh_bus_match(struct device *dev, struct device_driver *drv) +{ + struct sh_driver *shdrv = to_sh_driver(drv); + struct sh_dev *shdev = to_sh_dev(dev); + + return shdev->dev_id == shdrv->dev_id; +} + +static int sh_bus_suspend(struct device *dev, u32 state) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->suspend) + return shdrv->suspend(shdev, state); + + return 0; +} + +static int sh_bus_resume(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->resume) + return shdrv->resume(shdev); + + return 0; +} + +static struct device sh_bus_devices[SH_NR_BUSES] = { + { + .bus_id = SH_BUS_NAME_VIRT, + }, +}; + +struct bus_type sh_bus_types[SH_NR_BUSES] = { + { + .name = SH_BUS_NAME_VIRT, + .match = sh_bus_match, + .suspend = sh_bus_suspend, + .resume = sh_bus_resume, + }, +}; + +static int sh_device_probe(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->probe) + return shdrv->probe(shdev); + + return -ENODEV; +} + +static int sh_device_remove(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->remove) + return shdrv->remove(shdev); + + return 0; +} + +int sh_device_register(struct sh_dev *dev) +{ + if (!dev) + return -EINVAL; + + if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) { + printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n", + __FUNCTION__, dev->name, dev->bus_id); + return -EINVAL; + } + + dev->dev.parent = &sh_bus_devices[dev->bus_id]; + dev->dev.bus = &sh_bus_types[dev->bus_id]; + + /* This is needed for USB OHCI to work */ + if (dev->dma_mask) + dev->dev.dma_mask = dev->dma_mask; + + snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", + dev->name, dev->dev_id); + + printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n", + dev->dev.bus_id, dev->dev.parent->bus_id); + + return device_register(&dev->dev); +} + +void sh_device_unregister(struct sh_dev *dev) +{ + device_unregister(&dev->dev); +} + +int sh_driver_register(struct sh_driver *drv) +{ + if (!drv) + return -EINVAL; + + if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) { + printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n", + __FUNCTION__, drv->bus_id, drv->dev_id); + return -EINVAL; + } + + drv->drv.probe = sh_device_probe; + drv->drv.remove = sh_device_remove; + drv->drv.bus = &sh_bus_types[drv->bus_id]; + + return driver_register(&drv->drv); +} + +void sh_driver_unregister(struct sh_driver *drv) +{ + driver_unregister(&drv->drv); +} + +static int __init sh_bus_init(void) +{ + int i, ret = 0; + + for (i = 0; i < SH_NR_BUSES; i++) { + ret = device_register(&sh_bus_devices[i]); + if (ret != 0) { + printk(KERN_ERR "Unable to register bus device %s\n", + sh_bus_devices[i].bus_id); + continue; + } + + ret = bus_register(&sh_bus_types[i]); + if (ret != 0) { + printk(KERN_ERR "Unable to register bus %s\n", + sh_bus_types[i].name); + device_unregister(&sh_bus_devices[i]); + } + } + + printk(KERN_INFO "SH Virtual Bus initialized\n"); + + return ret; +} + +static void __exit sh_bus_exit(void) +{ + int i; + + for (i = 0; i < SH_NR_BUSES; i++) { + bus_unregister(&sh_bus_types[i]); + device_unregister(&sh_bus_devices[i]); + } +} + +module_init(sh_bus_init); +module_exit(sh_bus_exit); + +MODULE_AUTHOR("Paul Mundt "); +MODULE_DESCRIPTION("SH Virtual Bus"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(sh_bus_types); +EXPORT_SYMBOL(sh_device_register); +EXPORT_SYMBOL(sh_device_unregister); +EXPORT_SYMBOL(sh_driver_register); +EXPORT_SYMBOL(sh_driver_unregister); + diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index a81b3401f7fa..975103f34653 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -42,7 +42,7 @@ onchip_setup(dsp); */ static void __init cache_init(void) { - unsigned long ccr, flags = 0; + unsigned long ccr, flags; if (cpu_data->type == CPU_SH_NONE) panic("Unknown CPU"); @@ -54,42 +54,50 @@ static void __init cache_init(void) * If the cache is already enabled .. flush it. */ if (ccr & CCR_CACHE_ENABLE) { - unsigned long entries, i, j; + unsigned long ways, waysize, addrstart; - entries = cpu_data->dcache.sets; + waysize = cpu_data->dcache.sets; /* * If the OC is already in RAM mode, we only have * half of the entries to flush.. */ if (ccr & CCR_CACHE_ORA) - entries >>= 1; + waysize >>= 1; - for (i = 0; i < entries; i++) { - for (j = 0; j < cpu_data->dcache.ways; j++) { - unsigned long data, addr; + waysize <<= cpu_data->dcache.entry_shift; - addr = CACHE_OC_ADDRESS_ARRAY | - (j << cpu_data->dcache.way_shift) | - (i << cpu_data->dcache.entry_shift); +#ifdef CCR_CACHE_EMODE + /* If EMODE is not set, we only have 1 way to flush. */ + if (!(ccr & CCR_CACHE_EMODE)) + ways = 1; + else +#endif + ways = cpu_data->dcache.ways; - data = ctrl_inl(addr); + addrstart = CACHE_OC_ADDRESS_ARRAY; + do { + unsigned long addr; - if ((data & (SH_CACHE_UPDATED | SH_CACHE_VALID)) - == (SH_CACHE_UPDATED | SH_CACHE_VALID)) - ctrl_outl(data & ~SH_CACHE_UPDATED, addr); - } - } + for (addr = addrstart; + addr < addrstart + waysize; + addr += cpu_data->dcache.linesz) + ctrl_outl(0, addr); + + addrstart += cpu_data->dcache.way_incr; + } while (--ways); } /* * Default CCR values .. enable the caches - * and flush them immediately.. + * and invalidate them immediately.. */ - flags |= CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE; - + flags = CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE; + #ifdef CCR_CACHE_EMODE - flags |= (ccr & CCR_CACHE_EMODE); + /* Force EMODE if possible */ + if (cpu_data->dcache.ways > 1) + flags |= CCR_CACHE_EMODE; #endif #ifdef CONFIG_SH_WRITETHROUGH @@ -145,8 +153,8 @@ static void __init dsp_init(void) /* If the DSP bit is still set, this CPU has a DSP */ if (sr & SR_DSP) - set_bit(CPU_HAS_DSP, &(cpu_data->flags)); - + cpu_data->flags |= CPU_HAS_DSP; + /* Now that we've determined the DSP status, clear the DSP bit. */ release_dsp(); } @@ -184,7 +192,7 @@ asmlinkage void __init sh_cpu_init(void) } /* FPU initialization */ - if (test_bit(CPU_HAS_FPU, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_FPU)) { clear_thread_flag(TIF_USEDFPU); current->used_math = 0; } diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index fb0d94dd67cf..05dcc2e01fc1 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1130,6 +1130,14 @@ ENTRY(sys_call_table) .long sys_utimes .long sys_fadvise64_64_wrapper .long sys_ni_syscall /* Reserved for vserver */ - .long sys_ni_syscall + .long sys_ni_syscall /* Reserved for mbind */ + .long sys_ni_syscall /* 275 - get_mempolicy */ + .long sys_ni_syscall /* set_mempolicy */ + .long sys_mq_open + .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive /* 280 */ + .long sys_mq_notify + .long sys_mq_getsetattr /* End of entry.S */ diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index e920a5954788..a911b0149d1f 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c @@ -1,4 +1,4 @@ -/* $Id: io_generic.c,v 1.1.1.1.4.2.2.1 2003/01/10 17:26:56 lethal Exp $ +/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $ * * linux/arch/sh/kernel/io_generic.c * @@ -71,16 +71,32 @@ unsigned int generic_inl_p(unsigned long port) return v; } +/* + * insb/w/l all read a series of bytes/words/longs from a fixed port + * address. However as the port address doesn't change we only need to + * convert the port address to real address once. + */ + void generic_insb(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned char *port_addr; unsigned char *buf=buffer; - while(count--) *buf++=inb(port); + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; } void generic_insw(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned short *port_addr; unsigned short *buf=buffer; - while(count--) *buf++=inw(port); + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -88,8 +104,13 @@ void generic_insw(unsigned long port, void *buffer, unsigned long count) void generic_insl(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned long *port_addr; unsigned long *buf=buffer; - while(count--) *buf++=inl(port); + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -128,16 +149,33 @@ void generic_outl_p(unsigned int b, unsigned long port) delay(); } +/* + * outsb/w/l all write a series of bytes/words/longs to a fixed port + * address. However as the port address doesn't change we only need to + * convert the port address to real address once. + */ + void generic_outsb(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned char *port_addr; const unsigned char *buf=buffer; - while(count--) outb(*buf++, port); + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; } void generic_outsw(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned short *port_addr; const unsigned short *buf=buffer; - while(count--) outw(*buf++, port); + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; + #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -145,8 +183,14 @@ void generic_outsw(unsigned long port, const void *buffer, unsigned long count) void generic_outsl(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned long *port_addr; const unsigned long *buf=buffer; - while(count--) outl(*buf++, port); + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; + #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 18f056b15b74..d78503dd22da 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -575,6 +575,49 @@ unsigned long probe_irq_on(void) EXPORT_SYMBOL(probe_irq_on); +/* Return a mask of triggered interrupts (this + * can handle only legacy ISA interrupts). + */ + +/* + * probe_irq_mask - scan a bitmap of interrupt lines + * @val: mask of interrupts to consider + * + * Scan the ISA bus interrupt lines and return a bitmap of + * active interrupts. The interrupt probe logic state is then + * returned to its previous value. + * + * Note: we need to scan all the irq's even though we will + * only return ISA irq numbers - just so that we reset them + * all to a known state. + */ +unsigned int probe_irq_mask(unsigned long val) +{ + int i; + unsigned int mask; + + mask = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + if (i < 16 && !(status & IRQ_WAITING)) + mask |= 1 << i; + + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + up(&probe_sem); + + return mask & val; +} + int probe_irq_off(unsigned long val) { int i, irq_found, nr_irqs; diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 6b4cb096b11c..8ba6dd300957 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.26 2004/02/06 14:14:14 kkojima Exp $ +/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $ * * linux/arch/sh/kernel/process.c * @@ -25,6 +25,11 @@ #include #include #include +#if defined(CONFIG_SH_HS7751RVOIP) +#include +#elif defined(CONFIG_SH_RTS7751R2D) +#include +#endif static int hlt_counter=0; @@ -50,8 +55,14 @@ void default_idle(void) { /* endless idle loop with no priority at all */ while (1) { - while (!need_resched()) - cpu_relax(); + if (hlt_counter) { + while (1) + if (need_resched()) + break; + } else { + while (!need_resched()) + cpu_sleep(); + } schedule(); } @@ -73,14 +84,30 @@ EXPORT_SYMBOL(machine_restart); void machine_halt(void) { +#if defined(CONFIG_SH_HS7751RVOIP) + unsigned short value; + + value = ctrl_inw(PA_OUTPORTR); + ctrl_outw((value & 0xffdf), PA_OUTPORTR); +#elif defined(CONFIG_SH_RTS7751R2D) + ctrl_outw(0x0001, PA_POWOFF); +#endif while (1) - cpu_relax(); + cpu_sleep(); } EXPORT_SYMBOL(machine_halt); void machine_power_off(void) { +#if defined(CONFIG_SH_HS7751RVOIP) + unsigned short value; + + value = ctrl_inw(PA_OUTPORTR); + ctrl_outw((value & 0xffdf), PA_OUTPORTR); +#elif defined(CONFIG_SH_RTS7751R2D) + ctrl_outw(0x0001, PA_POWOFF); +#endif } EXPORT_SYMBOL(machine_power_off); diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 602f6c570be6..017826912cc5 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -1,4 +1,4 @@ -/* $Id: ptrace.c,v 1.14 2003/11/28 23:05:43 kkojima Exp $ +/* $Id: ptrace.c,v 1.15 2004/05/07 05:32:05 sugioka Exp $ * * linux/arch/sh/kernel/ptrace.c * @@ -255,13 +255,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = ptrace_detach(child, data); break; - case PTRACE_SETOPTIONS: - if (data & PTRACE_O_TRACESYSGOOD) - child->ptrace |= PT_TRACESYSGOOD; - else - child->ptrace &= ~PT_TRACESYSGOOD; - ret = 0; - break; #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 3c1b4c799e62..7746f7c5e714 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -25,15 +25,12 @@ #include #include #include -#ifdef CONFIG_SH_EARLY_PRINTK -#include -#endif #ifdef CONFIG_SH_KGDB #include static int kgdb_parse_options(char *options); #endif - +extern void * __rd_start, * __rd_end; /* * Machine setup.. */ @@ -118,130 +115,6 @@ static struct resource ram_resources[] = { unsigned long memory_start, memory_end; -/* XXX: MRB-remove - blatant hack */ -#if 1 -#define SCIF_REG 0xffe80000 - -static void scif_sercon_putc(int c) -{ - while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; - - ctrl_outb(c, SCIF_REG + 12); - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); - - if (c == '\n') - scif_sercon_putc('\r'); -} - -static void scif_sercon_flush(void) -{ - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); - - while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ; - - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); -} - -static void scif_sercon_write(struct console *con, const char *s, unsigned count) -{ - while (count-- > 0) - scif_sercon_putc(*s++); - - scif_sercon_flush(); -} - -static int __init scif_sercon_setup(struct console *con, char *options) -{ - con->cflag = CREAD | HUPCL | CLOCAL | B57600 | CS8; - - return 0; -} - -static struct console scif_sercon = { - .name = "sercon", - .write = scif_sercon_write, - .setup = scif_sercon_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -void scif_sercon_init(int baud) -{ - ctrl_outw(0, SCIF_REG + 8); - ctrl_outw(0, SCIF_REG); - - /* Set baud rate */ - ctrl_outb((50000000 / (32 * baud)) - 1, SCIF_REG + 4); - - ctrl_outw(12, SCIF_REG + 24); - ctrl_outw(8, SCIF_REG + 24); - ctrl_outw(0, SCIF_REG + 32); - ctrl_outw(0x60, SCIF_REG + 16); - ctrl_outw(0, SCIF_REG + 36); - ctrl_outw(0x30, SCIF_REG + 8); - - register_console(&scif_sercon); -} - -void scif_sercon_unregister(void) -{ - unregister_console(&scif_sercon); -} -#endif - -#ifdef CONFIG_SH_EARLY_PRINTK -/* - * Print a string through the BIOS - */ -static void sh_console_write(struct console *co, const char *s, - unsigned count) -{ - sh_bios_console_write(s, count); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init sh_console_setup(struct console *co, char *options) -{ - int cflag = CREAD | HUPCL | CLOCAL; - - /* - * Now construct a cflag setting. - * TODO: this is a totally bogus cflag, as we have - * no idea what serial settings the BIOS is using, or - * even if its using the serial port at all. - */ - cflag |= B115200 | CS8 | /*no parity*/0; - - co->cflag = cflag; - - return 0; -} - -static struct console sh_console = { - .name = "bios", - .write = sh_console_write, - .setup = sh_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -void sh_console_init(void) -{ - register_console(&sh_console); -} - -void sh_console_unregister(void) -{ - unregister_console(&sh_console); -} - -#endif - static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], struct sh_machine_vector** mvp, unsigned long *mv_io_base, @@ -323,10 +196,6 @@ static int __init sh_mv_setup(char **cmdline_p) parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); -#ifdef CONFIG_CMDLINE_BOOL - sprintf(*cmdline_p, CONFIG_CMDLINE); -#endif - #ifdef CONFIG_SH_GENERIC if (mv == NULL) { mv = &mv_unknown; @@ -380,14 +249,15 @@ void __init setup_arch(char **cmdline_p) unsigned long bootmap_size; unsigned long start_pfn, max_pfn, max_low_pfn; -/* XXX: MRB-remove */ -#if 0 - scif_sercon_init(57600); +#ifdef CONFIG_EARLY_PRINTK + extern void enable_early_printk(void); + + enable_early_printk(); #endif -#ifdef CONFIG_SH_EARLY_PRINTK - sh_console_init(); +#ifdef CONFIG_CMDLINE_BOOL + strcpy(COMMAND_LINE, CONFIG_CMDLINE); #endif - + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); #ifdef CONFIG_BLK_DEV_RAM @@ -490,6 +360,13 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + if (&__rd_start != &__rd_end) { + LOADER_TYPE = 1; + INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; + INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; + } + if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); @@ -555,8 +432,10 @@ subsys_initcall(topology_init); static const char *cpu_name[] = { [CPU_SH7604] = "SH7604", + [CPU_SH7705] = "SH7705", [CPU_SH7708] = "SH7708", [CPU_SH7729] = "SH7729", + [CPU_SH7300] = "SH7300", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", @@ -593,8 +472,8 @@ static void show_cpuflags(struct seq_file *m) for (i = 0; i < cpu_data->flags; i++) if ((cpu_data->flags & (1 << i))) - seq_printf(m, " %s", cpu_flags[i]); - + seq_printf(m, " %s", cpu_flags[i+1]); + seq_printf(m, "\n"); } diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index abe649077f7b..42868fca481a 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -33,6 +33,7 @@ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); @@ -83,6 +84,7 @@ EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__const_udelay); #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name) @@ -100,6 +102,7 @@ DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); +DECLARE_EXPORT(__movstrSI12_i4); /* needed by some modules */ EXPORT_SYMBOL(flush_cache_all); @@ -115,3 +118,4 @@ EXPORT_SYMBOL(synchronize_irq); #endif EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(consistent_sync); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 3e63d8a70ed3..da5721f4aab7 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.16 2004/03/16 00:10:54 lethal Exp $ +/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $ * * linux/arch/sh/traps.c * @@ -559,7 +559,7 @@ int is_dsp_inst(struct pt_regs *regs) * Safe guard if DSP mode is already enabled or we're lacking * the DSP altogether. */ - if (!test_bit(CPU_HAS_DSP, &(cpu_data->flags)) || (regs->sr & SR_DSP)) + if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) return 0; get_user(inst, ((unsigned short *) regs->pc)); @@ -636,7 +636,7 @@ void __init trap_init(void) = (void *)do_illegal_slot_inst; #ifdef CONFIG_CPU_SH4 - if (!test_bit(CPU_HAS_FPU, &(cpu_data->flags))) { + if (!(cpu_data->flags & CPU_HAS_FPU)) { /* For SH-4 lacking an FPU, treat floating point instructions as reserved. */ /* entry 64 corresponds to EXPEVT=0x800 */ diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index da0f5d728b3e..92398074128c 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -38,6 +38,14 @@ SECTIONS .data : { /* Data */ *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index e1fcc970f0e2..5504546494c8 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c @@ -33,3 +33,9 @@ void __udelay(unsigned long usecs) { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00000005); +} + diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c index cb6c0c0c7d56..b03d5e441029 100644 --- a/arch/sh/mm/cache-sh3.c +++ b/arch/sh/mm/cache-sh3.c @@ -1,4 +1,4 @@ -/* $Id: cache-sh3.c,v 1.8 2004/02/01 16:26:27 lethal Exp $ +/* $Id: cache-sh3.c,v 1.9 2004/05/02 01:46:30 sugioka Exp $ * * linux/arch/sh/mm/cache-sh3.c * @@ -65,14 +65,14 @@ int __init detect_cpu_and_cache_system(void) * 2K(direct) 7702 is not supported (yet) */ if (data0 == data1 && data2 == data3) { /* Shadow */ - cpu_data->dcache.way_shift = 11; + cpu_data->dcache.way_incr = (1 << 11); cpu_data->dcache.entry_mask = 0x7f0; cpu_data->dcache.sets = 128; cpu_data->type = CPU_SH7708; - set_bit(CPU_HAS_MMU_PAGE_ASSOC, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC; } else { /* 7709A or 7729 */ - cpu_data->dcache.way_shift = 12; + cpu_data->dcache.way_incr = (1 << 12); cpu_data->dcache.entry_mask = 0xff0; cpu_data->dcache.sets = 256; cpu_data->type = CPU_SH7729; @@ -108,13 +108,12 @@ void __flush_wback_region(void *start, int size) & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) { + unsigned long addrstart = CACHE_OC_ADDRESS_ARRAY; for (j = 0; j < cpu_data->dcache.ways; j++) { unsigned long data, addr, p; p = __pa(v); - addr = CACHE_OC_ADDRESS_ARRAY | - (j << cpu_data->dcache.way_shift)| - (v & cpu_data->dcache.entry_mask); + addr = addrstart | (v & cpu_data->dcache.entry_mask); local_irq_save(flags); data = ctrl_inl(addr); @@ -126,6 +125,7 @@ void __flush_wback_region(void *start, int size) break; } local_irq_restore(flags); + addrstart += cpu_data->dcache.way_incr; } } } diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index dde3de346fab..adb99d833d23 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -30,7 +30,7 @@ static void __flush_dcache_all_ex(void); int __init detect_cpu_and_cache_system(void) { - unsigned long pvr, prr, ccr, cvr; + unsigned long pvr, prr, cvr; unsigned long size; static unsigned long sizes[16] = { @@ -48,7 +48,7 @@ int __init detect_cpu_and_cache_system(void) /* * Setup some sane SH-4 defaults for the icache */ - cpu_data->icache.way_shift = 13; + cpu_data->icache.way_incr = (1 << 13); cpu_data->icache.entry_shift = 5; cpu_data->icache.entry_mask = 0x1fe0; cpu_data->icache.sets = 256; @@ -58,7 +58,7 @@ int __init detect_cpu_and_cache_system(void) /* * And again for the dcache .. */ - cpu_data->dcache.way_shift = 14; + cpu_data->dcache.way_incr = (1 << 14); cpu_data->dcache.entry_shift = 5; cpu_data->dcache.entry_mask = 0x3fe0; cpu_data->dcache.sets = 512; @@ -66,7 +66,7 @@ int __init detect_cpu_and_cache_system(void) cpu_data->dcache.linesz = L1_CACHE_BYTES; /* Set the FPU flag, virtually all SH-4's have one */ - set_bit(CPU_HAS_FPU, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_FPU; /* * Probe the underlying processor version/revision and @@ -75,7 +75,7 @@ int __init detect_cpu_and_cache_system(void) switch (pvr) { case 0x205: cpu_data->type = CPU_SH7750; - set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG; break; case 0x206: cpu_data->type = CPU_SH7750S; @@ -84,7 +84,7 @@ int __init detect_cpu_and_cache_system(void) * FIXME: This is needed for 7750, but do we need it for the * 7750S too? For now, assume we do.. -- PFM */ - set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG; break; case 0x1100: @@ -102,7 +102,7 @@ int __init detect_cpu_and_cache_system(void) cpu_data->dcache.ways = 2; /* No FPU on the SH4-500 series.. */ - clear_bit(CPU_HAS_FPU, &(cpu_data->flags)); + cpu_data->flags &= ~CPU_HAS_FPU; break; case 0x600: cpu_data->type = CPU_SH4_202; @@ -129,27 +129,20 @@ int __init detect_cpu_and_cache_system(void) * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. */ - if (cpu_data->dcache.ways > 1) { - jump_to_P2(); - ccr = ctrl_inl(CCR); - - /* Force EMODE */ - if (!(ccr & CCR_CACHE_EMODE)) { - ccr |= CCR_CACHE_EMODE; - ctrl_outl(ccr, CCR); - } - - back_to_P1(); - + if (cpu_data->icache.ways > 1) { size = sizes[(cvr >> 20) & 0xf]; - cpu_data->icache.way_shift = (size >> 1); - cpu_data->icache.entry_mask = ((size >> 2) - (1 << 5)); - cpu_data->icache.sets = (size >> 6); + cpu_data->icache.way_incr = size / cpu_data->icache.ways; + cpu_data->icache.sets = (size >> 6); + cpu_data->icache.entry_mask = + ((size / cpu_data->icache.ways) - (1 << 5)); + } + if (cpu_data->dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; - cpu_data->dcache.way_shift = (size >> 1); - cpu_data->dcache.entry_mask = ((size >> 2) - (1 << 5)); - cpu_data->dcache.sets = (size >> 6); + cpu_data->dcache.way_incr = size / cpu_data->dcache.ways; + cpu_data->dcache.sets = (size >> 6); + cpu_data->dcache.entry_mask = + ((size / cpu_data->dcache.ways) - (1 << 5)); } return 0; @@ -250,7 +243,7 @@ static void __flush_cache_4096_all_ex(unsigned long start) int i; entry_offset = 1 << cpu_data->dcache.entry_shift; - for (i = 0; i < cpu_data->dcache.ways; i++, start += (1 << cpu_data->dcache.way_shift)) { + for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) { for (addr = CACHE_OC_ADDRESS_ARRAY + start; addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start; addr += entry_offset) { @@ -297,7 +290,7 @@ void flush_cache_sigtramp(unsigned long addr) local_irq_save(flags); jump_to_P2(); - for(i = 0; i < cpu_data->icache.ways; i++, index += (1 << cpu_data->icache.way_shift)) + for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr) ctrl_outl(0, index); /* Clear out Valid-bit */ back_to_P1(); local_irq_restore(flags); @@ -313,12 +306,13 @@ static inline void flush_cache_4096(unsigned long start, * SH7751, SH7751R, and ST40 have no restriction to handle cache. * (While SH7750 must do that at P2 area.) */ - if (test_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) + || start < CACHE_OC_ADDRESS_ARRAY) { local_irq_save(flags); - __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0x20000000); + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000); local_irq_restore(flags); - } else if (start >= CACHE_OC_ADDRESS_ARRAY) { - __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0); + } else { + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0); } } diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index 88213cef3dea..318d1a529b49 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -72,7 +72,7 @@ void __flush_tlb_page(unsigned long asid, unsigned long page) addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000); data = (page & 0xfffe0000) | asid; /* VALID bit is off */ - if (test_bit(CPU_HAS_MMU_PAGE_ASSOC, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) { addr |= MMU_PAGE_ASSOC_BIT; ways = 1; /* we already know the way .. */ } diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile new file mode 100644 index 000000000000..a22d86bf0c45 --- /dev/null +++ b/arch/sh/ramdisk/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for a ramdisk image +# + +obj-y += ramdisk.o + + +O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32) +img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE)) +# add $(src) when $(img) is relative +img := $(subst $(src)//,/,$(src)/$(img)) + +quiet_cmd_ramdisk = LD $@ +define cmd_ramdisk + $(LD) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) +endef + +$(obj)/ramdisk.o: $(img) $(src)/ld.script + $(call cmd,ramdisk) diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script new file mode 100644 index 000000000000..94beee248c04 --- /dev/null +++ b/arch/sh/ramdisk/ld.script @@ -0,0 +1,9 @@ +OUTPUT_ARCH(sh) +SECTIONS +{ + .initrd : + { + *(.data) + } +} + diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index be54d527dc30..faf6d9e38bff 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -7,6 +7,7 @@ # SE SH_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE +7300SE SH_7300_SOLUTION_ENGINE 7751SYSTEMH SH_7751_SYSTEMH HP600 SH_HP600 HP620 SH_HP620 @@ -21,4 +22,6 @@ BIGSUR SH_BIGSUR ADX SH_ADX MPC1211 SH_MPC1211 SNAPGEAR SH_SECUREEDGE5410 +HS7751RVOIP SH_HS7751RVOIP +RTS7751R2D SH_RTS7751R2D diff --git a/include/asm-sh/bus-sh.h b/include/asm-sh/bus-sh.h new file mode 100644 index 000000000000..f782a33a98fa --- /dev/null +++ b/include/asm-sh/bus-sh.h @@ -0,0 +1,65 @@ +/* + * include/asm-sh/bus-sh.h + * + * Copyright (C) 2004 Paul Mundt + * + * 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. + */ +#ifndef __ASM_SH_BUS_SH_H +#define __ASM_SH_BUS_SH_H + +extern struct bus_type sh_bus_types[]; + +struct sh_dev { + struct device dev; + char *name; + unsigned int dev_id; + unsigned int bus_id; + struct resource res; + void *mapbase; + unsigned int irq[6]; + u64 *dma_mask; +}; + +#define to_sh_dev(d) container_of((d), struct sh_dev, dev) + +#define sh_get_drvdata(d) dev_get_drvdata(&(d)->dev) +#define sh_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p)) + +struct sh_driver { + struct device_driver drv; + unsigned int dev_id; + unsigned int bus_id; + int (*probe)(struct sh_dev *); + int (*remove)(struct sh_dev *); + int (*suspend)(struct sh_dev *, u32); + int (*resume)(struct sh_dev *); +}; + +#define to_sh_driver(d) container_of((d), struct sh_driver, drv) +#define sh_name(d) ((d)->dev.driver->name) + +/* + * Device ID numbers for bus types + */ +enum { + SH_DEV_ID_USB_OHCI, +}; + +#define SH_NR_BUSES 1 +#define SH_BUS_NAME_VIRT "shbus" + +enum { + SH_BUS_VIRT, +}; + +/* arch/sh/kernel/cpu/bus.c */ +extern int sh_device_register(struct sh_dev *dev); +extern void sh_device_unregister(struct sh_dev *dev); +extern int sh_driver_register(struct sh_driver *drv); +extern void sh_driver_unregister(struct sh_driver *drv); + +#endif /* __ASM_SH_BUS_SH_H */ + diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h index 9decb1ced217..62b2f50fb20b 100644 --- a/include/asm-sh/cache.h +++ b/include/asm-sh/cache.h @@ -28,7 +28,8 @@ struct cache_info { unsigned int sets; unsigned int linesz; - unsigned int way_shift; + unsigned int way_incr; + unsigned int entry_shift; unsigned int entry_mask; diff --git a/include/asm-sh/cpu-sh3/dac.h b/include/asm-sh/cpu-sh3/dac.h index 7f4129d25632..05fda8316ebc 100644 --- a/include/asm-sh/cpu-sh3/dac.h +++ b/include/asm-sh/cpu-sh3/dac.h @@ -1,5 +1,5 @@ -#ifndef __ASM_SH_DAC_H -#define __ASM_SH_DAC_H +#ifndef __ASM_CPU_SH3_DAC_H +#define __ASM_CPU_SH3_DAC_H /* * Copyright (C) 2003 Andriy Skulysh @@ -38,5 +38,4 @@ static __inline__ void sh_dac_output(u8 value, int channel) else ctrl_outb(value,DADR0); } -#endif /* __ASM_SH_DAC_H */ - +#endif /* __ASM_CPU_SH3_DAC_H */ diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 0eaf9d91b54d..922c927478c1 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -271,6 +271,7 @@ extern unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.pc) #define KSTK_ESP(tsk) ((tsk)->thread.sp) -#define cpu_relax() __asm__ __volatile__ ("sleep" : : : "memory") +#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory") +#define cpu_relax() do { } while (0) #endif /* __ASM_SH_PROCESSOR_H */ diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h index 012649927fc5..5474dbdbaa86 100644 --- a/include/asm-sh/serial.h +++ b/include/asm-sh/serial.h @@ -44,8 +44,5 @@ #define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS -/* XXX: This should be moved ino irq.h */ -#define irq_canonicalize(x) (x) - #endif #endif /* _ASM_SERIAL_H */ diff --git a/include/asm-sh/sigcontext.h b/include/asm-sh/sigcontext.h index 46fbc6feddd4..eb8effba2e80 100644 --- a/include/asm-sh/sigcontext.h +++ b/include/asm-sh/sigcontext.h @@ -1,6 +1,26 @@ #ifndef __ASM_SH_SIGCONTEXT_H #define __ASM_SH_SIGCONTEXT_H -#include +struct sigcontext { + unsigned long oldmask; + + /* CPU registers */ + unsigned long sc_regs[16]; + unsigned long sc_pc; + unsigned long sc_pr; + unsigned long sc_sr; + unsigned long sc_gbr; + unsigned long sc_mach; + unsigned long sc_macl; + +#if defined(__SH4__) || defined(CONFIG_CPU_SH4) + /* FPU registers */ + unsigned long sc_fpregs[16]; + unsigned long sc_xfpregs[16]; + unsigned int sc_fpscr; + unsigned int sc_fpul; + unsigned int sc_ownedfp; +#endif +}; #endif /* __ASM_SH_SIGCONTEXT_H */ diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index 26ad6dd928ec..a20677454ca9 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h @@ -281,8 +281,17 @@ #define __NR_utimes 271 #define __NR_fadvise64_64 272 #define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) -#define NR_syscalls 274 +#define NR_syscalls 283 /* user-visible error numbers are in the range -1 - -124: see */ @@ -429,6 +438,7 @@ __syscall_return(type,__sc0); \ #include #include +#include #include /* -- cgit v1.2.3 From d35fd13a8f5629b5b46ac0f546ac18e6f2831e29 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:37:38 -0700 Subject: [PATCH] fix broken alpha build ptrace.c error From: Darren Williams include/asm/checksum.h:75: warning: `struct in6_addr' declared inside parameter list include/asm/checksum.h:75 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/checksum.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-alpha/checksum.h b/include/asm-alpha/checksum.h index f3e379787ecd..a5c9f08447fb 100644 --- a/include/asm-alpha/checksum.h +++ b/include/asm-alpha/checksum.h @@ -1,6 +1,7 @@ #ifndef _ALPHA_CHECKSUM_H #define _ALPHA_CHECKSUM_H +#include /* * This is a version of ip_compute_csum() optimized for IP headers, -- cgit v1.2.3 From fe3a3a65fe579af9f94bcd2f9bd5416177293ce0 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 23 Jun 2004 19:50:13 -0700 Subject: [PATCH] ppc64: clean up prom.c and related files Somebody back in the mists of time decided that call_prom and rtas_call should return longs even though both of those bits of firmware run in 32-bit mode and produce a 32-bit result. To make life more interesting, the 32-bit result gets zero-extended to 64 bits, which makes checking for a -1 return value more complicated than it should be. This patch changes call_prom and rtas_call to return an int, and makes the corresponding changes to use ints for the variables used to hold those return values. While I was doing this I finally got annoyed enough with the strings of prom_print() and prom_print_hex() calls that we do to write a simple prom_printf. I deliberately didn't use snprintf because the execution environment is weird at this point - we aren't running at the address we are linked at just yet - and I didn't want to inflict that on any code outside this file. I also did a prom_debug() macro, which eliminated a few ifdefs. There are also a bunch of other minor cleanups. This patch makes very few algorithmic changes but does get rid of a lot of casts. :) I have been running with this patch for a couple of weeks, and Anton has tested it too. Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/eeh.c | 7 +- arch/ppc64/kernel/pSeries_nvram.c | 6 +- arch/ppc64/kernel/pSeries_pci.c | 5 +- arch/ppc64/kernel/prom.c | 882 +++++++++++++++----------------------- arch/ppc64/kernel/rtas-proc.c | 7 +- arch/ppc64/kernel/rtas.c | 52 +-- arch/ppc64/kernel/rtas_flash.c | 12 +- arch/ppc64/kernel/rtc.c | 8 +- arch/ppc64/kernel/scanlog.c | 12 +- arch/ppc64/kernel/setup.c | 9 +- arch/ppc64/kernel/smp.c | 2 +- arch/ppc64/kernel/traps.c | 4 +- arch/ppc64/kernel/xics.c | 37 +- include/asm-ppc64/prom.h | 2 +- include/asm-ppc64/rtas.h | 4 +- 15 files changed, 420 insertions(+), 629 deletions(-) (limited to 'include') diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index dc83803db216..6f2d189d44c9 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -365,7 +365,8 @@ unsigned long eeh_check_failure(void *token, unsigned long val) unsigned long addr; struct pci_dev *dev; struct device_node *dn; - unsigned long ret, rets[2]; + unsigned long ret; + int rets[2]; static spinlock_t lock = SPIN_LOCK_UNLOCKED; /* dont want this on the stack */ static unsigned char slot_err_buf[RTAS_ERROR_LOG_MAX]; @@ -444,11 +445,11 @@ unsigned long eeh_check_failure(void *token, unsigned long val) * can use it here. */ if (panic_on_oops) { - panic("EEH: MMIO failure (%ld) on device:%s %s\n", + panic("EEH: MMIO failure (%d) on device:%s %s\n", rets[0], pci_name(dev), pci_pretty_name(dev)); } else { __get_cpu_var(ignored_failures)++; - printk(KERN_INFO "EEH: MMIO failure (%ld) on device:%s %s\n", + printk(KERN_INFO "EEH: MMIO failure (%d) on device:%s %s\n", rets[0], pci_name(dev), pci_pretty_name(dev)); } } else { diff --git a/arch/ppc64/kernel/pSeries_nvram.c b/arch/ppc64/kernel/pSeries_nvram.c index ebccb1663381..5d74028d512f 100644 --- a/arch/ppc64/kernel/pSeries_nvram.c +++ b/arch/ppc64/kernel/pSeries_nvram.c @@ -37,7 +37,8 @@ static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { unsigned int i; - unsigned long len, done; + unsigned long len; + int done; unsigned long flags; char *p = buf; @@ -80,7 +81,8 @@ static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index) { unsigned int i; - unsigned long len, done; + unsigned long len; + int done; unsigned long flags; const char *p = buf; diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c index 4014ccd9fb60..3a88ae49a2a7 100644 --- a/arch/ppc64/kernel/pSeries_pci.c +++ b/arch/ppc64/kernel/pSeries_pci.c @@ -62,7 +62,7 @@ extern unsigned long pci_probe_only; static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) { - unsigned long returnval = ~0L; + int returnval = -1; unsigned long buid, addr; int ret; @@ -72,7 +72,8 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va addr = (dn->busno << 16) | (dn->devfn << 8) | where; buid = dn->phb->buid; if (buid) { - ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, size); + ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, + addr, buid >> 32, buid & 0xffffffff, size); } else { ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); } diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index a5f8f241895a..d9c8703572ba 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -15,9 +15,7 @@ * 2 of the License, or (at your option) any later version. */ -#if 0 -#define DEBUG_PROM -#endif +#undef DEBUG_PROM #include #include @@ -91,15 +89,17 @@ extern const struct linux_logo logo_linux_clut224; */ -#define PROM_BUG() do { \ - prom_print(RELOC("kernel BUG at ")); \ - prom_print(RELOC(__FILE__)); \ - prom_print(RELOC(":")); \ - prom_print_hex(__LINE__); \ - prom_print(RELOC("!\n")); \ - __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ +#define PROM_BUG() do { \ + prom_printf("kernel BUG at %s line 0x%x!\n", \ + RELOC(__FILE__), __LINE__); \ + __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ } while (0) +#ifdef DEBUG_PROM +#define prom_debug(x...) prom_printf(x) +#else +#define prom_debug(x...) +#endif struct pci_reg_property { @@ -178,29 +178,36 @@ struct { char testString[] = "LINUX\n"; +/* + * This are used in calls to call_prom. The 4th and following + * arguments to call_prom should be 32-bit values. 64 bit values + * are truncated to 32 bits (and fortunately don't get interpreted + * as two arguments). + */ +#define ADDR(x) (u32) ((unsigned long)(x) - offset) /* This is the one and *ONLY* place where we actually call open * firmware from, since we need to make sure we're running in 32b * mode when we do. We switch back to 64b mode upon return. */ -#define PROM_ERROR (0x00000000fffffffful) +#define PROM_ERROR (-1) -static unsigned long __init call_prom(const char *service, int nargs, int nret, ...) +static int __init call_prom(const char *service, int nargs, int nret, ...) { int i; unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); va_list list; - _prom->args.service = (u32)LONG_LSW(service); + _prom->args.service = ADDR(service); _prom->args.nargs = nargs; _prom->args.nret = nret; _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]); va_start(list, nret); - for (i=0; i < nargs ;i++) - _prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long)); + for (i=0; i < nargs; i++) + _prom->args.args[i] = va_arg(list, prom_arg_t); va_end(list); for (i=0; i < nret ;i++) @@ -208,7 +215,7 @@ static unsigned long __init call_prom(const char *service, int nargs, int nret, enter_prom(&_prom->args); - return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0); + return (nret > 0)? _prom->args.rets[0]: 0; } @@ -225,21 +232,21 @@ static void __init prom_print(const char *msg) for (q = p; *q != 0 && *q != '\n'; ++q) ; if (q > p) - call_prom(RELOC("write"), 3, 1, _prom->stdout, - p, q - p); - if (*q != 0) { - ++q; - call_prom(RELOC("write"), 3, 1, _prom->stdout, - RELOC("\r\n"), 2); - } + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + ++q; + call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2); } } static void __init prom_print_hex(unsigned long val) { + unsigned long offset = reloc_offset(); int i, nibbles = sizeof(val)*2; char buf[sizeof(val)*2+1]; + struct prom_t *_prom = PTRRELOC(&prom); for (i = nibbles-1; i >= 0; i--) { buf[i] = (val & 0xf) + '0'; @@ -248,24 +255,58 @@ static void __init prom_print_hex(unsigned long val) val >>= 4; } buf[nibbles] = '\0'; - prom_print(buf); + call_prom("write", 3, 1, _prom->stdout, buf, nibbles); } -static void __init prom_print_nl(void) +static void __init prom_printf(const char *format, ...) { unsigned long offset = reloc_offset(); - prom_print(RELOC("\n")); + const char *p, *q, *s; + va_list args; + unsigned long v; + struct prom_t *_prom = PTRRELOC(&prom); + + va_start(args, format); + for (p = PTRRELOC(format); *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + if (*q == '\n') { + ++q; + call_prom("write", 3, 1, _prom->stdout, + ADDR("\r\n"), 2); + continue; + } + ++q; + if (*q == 0) + break; + switch (*q) { + case 's': + ++q; + s = va_arg(args, const char *); + prom_print(s); + break; + case 'x': + ++q; + v = va_arg(args, unsigned long); + prom_print_hex(v); + break; + } + } } -static void __init prom_panic(const char *reason) +static void __init __attribute__((noreturn)) prom_panic(const char *reason) { unsigned long offset = reloc_offset(); - prom_print(reason); + prom_print(PTRRELOC(reason)); /* ToDo: should put up an SRC here */ - call_prom(RELOC("exit"), 0, 0); + call_prom("exit", 0, 0); for (;;) /* should never get here */ ; @@ -275,21 +316,28 @@ static void __init prom_panic(const char *reason) static int __init prom_next_node(phandle *nodep) { phandle node; - unsigned long offset = reloc_offset(); if ((node = *nodep) != 0 - && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0) + && (*nodep = call_prom("child", 1, 1, node)) != 0) return 1; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) return 1; for (;;) { - if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0) + if ((node = call_prom("parent", 1, 1, node)) == 0) return 0; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) return 1; } } +static int __init prom_getprop(phandle node, const char *pname, + void *value, size_t valuelen) +{ + unsigned long offset = reloc_offset(); + + return call_prom("getprop", 4, 1, node, ADDR(pname), + (u32)(unsigned long) value, (u32) valuelen); +} static void __init prom_initialize_naca(void) { @@ -302,16 +350,13 @@ static void __init prom_initialize_naca(void) struct systemcfg *_systemcfg = RELOC(systemcfg); /* NOTE: _naca->debug_switch is already initialized. */ -#ifdef DEBUG_PROM - prom_print(RELOC("prom_initialize_naca: start...\n")); -#endif + prom_debug("prom_initialize_naca: start...\n"); _naca->pftSize = 0; /* ilog2 of htab size. computed below. */ for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (!strcmp(type, RELOC("cpu"))) { num_cpus += 1; @@ -321,37 +366,30 @@ static void __init prom_initialize_naca(void) */ if ( num_cpus == 1 ) { u32 size, lsize; + const char *dc, *ic; + + if (_systemcfg->platform == PLATFORM_POWERMAC){ + dc = "d-cache-block-size"; + ic = "i-cache-block-size"; + } else { + dc = "d-cache-line-size"; + ic = "i-cache-line-size"; + } - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-size"), - &size, sizeof(size)); + prom_getprop(node, "d-cache-size", + &size, sizeof(size)); - if (_systemcfg->platform == PLATFORM_POWERMAC) - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-block-size"), - &lsize, sizeof(lsize)); - else - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-line-size"), - &lsize, sizeof(lsize)); + prom_getprop(node, dc, &lsize, sizeof(lsize)); _systemcfg->dCacheL1Size = size; _systemcfg->dCacheL1LineSize = lsize; _naca->dCacheL1LogLineSize = __ilog2(lsize); _naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-size"), - &size, sizeof(size)); + prom_getprop(node, "i-cache-size", + &size, sizeof(size)); - if (_systemcfg->platform == PLATFORM_POWERMAC) - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-block-size"), - &lsize, sizeof(lsize)); - else - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-line-size"), - &lsize, sizeof(lsize)); + prom_getprop(node, ic, &lsize, sizeof(lsize)); _systemcfg->iCacheL1Size = size; _systemcfg->iCacheL1LineSize = lsize; @@ -360,9 +398,8 @@ static void __init prom_initialize_naca(void) if (_systemcfg->platform == PLATFORM_PSERIES_LPAR) { u32 pft_size[2]; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,pft-size"), - &pft_size, sizeof(pft_size)); + prom_getprop(node, "ibm,pft-size", + &pft_size, sizeof(pft_size)); /* pft_size[0] is the NUMA CEC cookie */ _naca->pftSize = pft_size[1]; } @@ -375,24 +412,21 @@ static void __init prom_initialize_naca(void) if (_systemcfg->platform == PLATFORM_POWERMAC) continue; type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,aix-loc"), type, sizeof(type)); + prom_getprop(node, "ibm,aix-loc", type, sizeof(type)); if (strcmp(type, RELOC("S1"))) continue; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); - isa = call_prom(RELOC("parent"), 1, 1, node); + isa = call_prom("parent", 1, 1, node); if (!isa) PROM_BUG(); - pci = call_prom(RELOC("parent"), 1, 1, isa); + pci = call_prom("parent", 1, 1, isa); if (!pci) PROM_BUG(); - call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"), - &ranges, sizeof(ranges)); + prom_getprop(pci, "ranges", &ranges, sizeof(ranges)); if ( _prom->encode_phys_size == 32 ) _naca->serialPortAddr = ranges.pci32.phys+reg.address; @@ -410,25 +444,23 @@ static void __init prom_initialize_naca(void) _naca->interrupt_controller = IC_INVALID; for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"), - type, sizeof(type)); + prom_getprop(node, "name", type, sizeof(type)); if (strcmp(type, RELOC("interrupt-controller"))) continue; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"), - type, sizeof(type)); + prom_getprop(node, "compatible", type, sizeof(type)); if (strstr(type, RELOC("open-pic"))) _naca->interrupt_controller = IC_OPEN_PIC; else if (strstr(type, RELOC("ppc-xicp"))) _naca->interrupt_controller = IC_PPC_XIC; else - prom_print(RELOC("prom: failed to recognize" - " interrupt-controller\n")); + prom_printf("prom: failed to recognize" + " interrupt-controller\n"); break; } } if (_naca->interrupt_controller == IC_INVALID) { - prom_print(RELOC("prom: failed to find interrupt-controller\n")); + prom_printf("prom: failed to find interrupt-controller\n"); PROM_BUG(); } @@ -454,7 +486,7 @@ static void __init prom_initialize_naca(void) } if (_naca->pftSize == 0) { - prom_print(RELOC("prom: failed to compute pftSize!\n")); + prom_printf("prom: failed to compute pftSize!\n"); PROM_BUG(); } @@ -464,41 +496,23 @@ static void __init prom_initialize_naca(void) _systemcfg->version.minor = SYSTEMCFG_MINOR; _systemcfg->processor = _get_PVR(); -#ifdef DEBUG_PROM - prom_print(RELOC("systemcfg->processorCount = 0x")); - prom_print_hex(_systemcfg->processorCount); - prom_print_nl(); - - prom_print(RELOC("systemcfg->physicalMemorySize = 0x")); - prom_print_hex(_systemcfg->physicalMemorySize); - prom_print_nl(); - - prom_print(RELOC("naca->pftSize = 0x")); - prom_print_hex(_naca->pftSize); - prom_print_nl(); - - prom_print(RELOC("systemcfg->dCacheL1LineSize = 0x")); - prom_print_hex(_systemcfg->dCacheL1LineSize); - prom_print_nl(); - - prom_print(RELOC("systemcfg->iCacheL1LineSize = 0x")); - prom_print_hex(_systemcfg->iCacheL1LineSize); - prom_print_nl(); - - prom_print(RELOC("naca->serialPortAddr = 0x")); - prom_print_hex(_naca->serialPortAddr); - prom_print_nl(); - - prom_print(RELOC("naca->interrupt_controller = 0x")); - prom_print_hex(_naca->interrupt_controller); - prom_print_nl(); - - prom_print(RELOC("systemcfg->platform = 0x")); - prom_print_hex(_systemcfg->platform); - prom_print_nl(); - - prom_print(RELOC("prom_initialize_naca: end...\n")); -#endif + prom_debug("systemcfg->processorCount = 0x%x\n", + _systemcfg->processorCount); + prom_debug("systemcfg->physicalMemorySize = 0x%x\n", + _systemcfg->physicalMemorySize); + prom_debug("naca->pftSize = 0x%x\n", + _naca->pftSize); + prom_debug("systemcfg->dCacheL1LineSize = 0x%x\n", + _systemcfg->dCacheL1LineSize); + prom_debug("systemcfg->iCacheL1LineSize = 0x%x\n", + _systemcfg->iCacheL1LineSize); + prom_debug("naca->serialPortAddr = 0x%x\n", + _naca->serialPortAddr); + prom_debug("naca->interrupt_controller = 0x%x\n", + _naca->interrupt_controller); + prom_debug("systemcfg->platform = 0x%x\n", + _systemcfg->platform); + prom_debug("prom_initialize_naca: end...\n"); } @@ -512,9 +526,7 @@ static void __init early_cmdline_parse(void) opt = strstr(RELOC(cmd_line), RELOC("iommu=")); if (opt) { - prom_print(RELOC("opt is:")); - prom_print(opt); - prom_print(RELOC("\n")); + prom_printf("opt is:%s\n", opt); opt += 6; while (*opt && *opt == ' ') opt++; @@ -527,7 +539,7 @@ static void __init early_cmdline_parse(void) #ifndef CONFIG_PMAC_DART if (_systemcfg->platform == PLATFORM_POWERMAC) { RELOC(ppc64_iommu_off) = 1; - prom_print(RELOC("DART disabled on PowerMac !\n")); + prom_printf("DART disabled on PowerMac !\n"); } #endif } @@ -539,46 +551,31 @@ void prom_dump_lmb(void) unsigned long offset = reloc_offset(); struct lmb *_lmb = PTRRELOC(&lmb); - prom_print(RELOC("\nprom_dump_lmb:\n")); - prom_print(RELOC(" memory.cnt = 0x")); - prom_print_hex(_lmb->memory.cnt); - prom_print_nl(); - prom_print(RELOC(" memory.size = 0x")); - prom_print_hex(_lmb->memory.size); - prom_print_nl(); + prom_printf("\nprom_dump_lmb:\n"); + prom_printf(" memory.cnt = 0x%x\n", + _lmb->memory.cnt); + prom_printf(" memory.size = 0x%x\n", + _lmb->memory.size); for (i=0; i < _lmb->memory.cnt ;i++) { - prom_print(RELOC(" memory.region[0x")); - prom_print_hex(i); - prom_print(RELOC("].base = 0x")); - prom_print_hex(_lmb->memory.region[i].base); - prom_print_nl(); - prom_print(RELOC(" .physbase = 0x")); - prom_print_hex(_lmb->memory.region[i].physbase); - prom_print_nl(); - prom_print(RELOC(" .size = 0x")); - prom_print_hex(_lmb->memory.region[i].size); - prom_print_nl(); + prom_printf(" memory.region[0x%x].base = 0x%x\n", + i, _lmb->memory.region[i].base); + prom_printf(" .physbase = 0x%x\n", + _lmb->memory.region[i].physbase); + prom_printf(" .size = 0x%x\n", + _lmb->memory.region[i].size); } - prom_print_nl(); - prom_print(RELOC(" reserved.cnt = 0x")); - prom_print_hex(_lmb->reserved.cnt); - prom_print_nl(); - prom_print(RELOC(" reserved.size = 0x")); - prom_print_hex(_lmb->reserved.size); - prom_print_nl(); + prom_printf("\n reserved.cnt = 0x%x\n", + _lmb->reserved.cnt); + prom_printf(" reserved.size = 0x%x\n", + _lmb->reserved.size); for (i=0; i < _lmb->reserved.cnt ;i++) { - prom_print(RELOC(" reserved.region[0x")); - prom_print_hex(i); - prom_print(RELOC("].base = 0x")); - prom_print_hex(_lmb->reserved.region[i].base); - prom_print_nl(); - prom_print(RELOC(" .physbase = 0x")); - prom_print_hex(_lmb->reserved.region[i].physbase); - prom_print_nl(); - prom_print(RELOC(" .size = 0x")); - prom_print_hex(_lmb->reserved.region[i].size); - prom_print_nl(); + prom_printf(" reserved.region[0x%x\n].base = 0x%x\n", + i, _lmb->reserved.region[i].base); + prom_printf(" .physbase = 0x%x\n", + _lmb->reserved.region[i].physbase); + prom_printf(" .size = 0x%x\n", + _lmb->reserved.region[i].size); } } #endif /* DEBUG_PROM */ @@ -604,14 +601,13 @@ static void __init prom_initialize_lmb(void) for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("memory"))) continue; - num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)) / bytes_per_reg; + num_regs = prom_getprop(node, "reg", ®, sizeof(reg)) + / bytes_per_reg; for (i=0; i < num_regs ;i++) { if (_systemcfg->platform == PLATFORM_POWERMAC) { @@ -636,7 +632,7 @@ static void __init prom_initialize_lmb(void) } if (lmb_add(lmb_base, lmb_size) < 0) - prom_print(RELOC("Too many LMB's, discarding this one...\n")); + prom_printf("Too many LMB's, discarding this one...\n"); } } @@ -658,30 +654,23 @@ prom_instantiate_rtas(void) u32 getprop_rval; char hypertas_funcs[4]; -#ifdef DEBUG_PROM - prom_print(RELOC("prom_instantiate_rtas: start...\n")); -#endif - prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); + prom_debug("prom_instantiate_rtas: start...\n"); + + prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); if (prom_rtas != (ihandle) -1) { unsigned long x; - x = call_prom(RELOC("getprop"), - 4, 1, prom_rtas, - RELOC("ibm,hypertas-functions"), - hypertas_funcs, - sizeof(hypertas_funcs)); + x = prom_getprop(prom_rtas, "ibm,hypertas-functions", + hypertas_funcs, sizeof(hypertas_funcs)); if (x != PROM_ERROR) { - prom_print(RELOC("Hypertas detected, assuming LPAR !\n")); + prom_printf("Hypertas detected, assuming LPAR !\n"); _systemcfg->platform = PLATFORM_PSERIES_LPAR; } - call_prom(RELOC("getprop"), - 4, 1, prom_rtas, - RELOC("rtas-size"), - &getprop_rval, - sizeof(getprop_rval)); + prom_getprop(prom_rtas, "rtas-size", + &getprop_rval, sizeof(getprop_rval)); _rtas->size = getprop_rval; - prom_print(RELOC("instantiating rtas")); + prom_printf("instantiating rtas"); if (_rtas->size != 0) { unsigned long rtas_region = RTAS_INSTANTIATE_MAX; @@ -696,17 +685,15 @@ prom_instantiate_rtas(void) _rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region); - prom_print(RELOC(" at 0x")); - prom_print_hex(_rtas->base); + prom_printf(" at 0x%x", _rtas->base); - prom_rtas = (ihandle)call_prom(RELOC("open"), - 1, 1, RELOC("/rtas")); - prom_print(RELOC("...")); + prom_rtas = call_prom("open", 1, 1, ADDR("/rtas")); + prom_printf("..."); - if (call_prom(RELOC("call-method"), 3, 2, - RELOC("instantiate-rtas"), - prom_rtas, - _rtas->base) != PROM_ERROR) { + if (call_prom("call-method", 3, 2, + ADDR("instantiate-rtas"), + prom_rtas, + _rtas->base) != PROM_ERROR) { _rtas->entry = (long)_prom->args.rets[1]; } RELOC(rtas_rmo_buf) @@ -715,26 +702,16 @@ prom_instantiate_rtas(void) } if (_rtas->entry <= 0) { - prom_print(RELOC(" failed\n")); + prom_printf(" failed\n"); } else { - prom_print(RELOC(" done\n")); + prom_printf(" done\n"); } -#ifdef DEBUG_PROM - prom_print(RELOC("rtas->base = 0x")); - prom_print_hex(_rtas->base); - prom_print_nl(); - prom_print(RELOC("rtas->entry = 0x")); - prom_print_hex(_rtas->entry); - prom_print_nl(); - prom_print(RELOC("rtas->size = 0x")); - prom_print_hex(_rtas->size); - prom_print_nl(); -#endif + prom_debug("rtas->base = 0x%x\n", _rtas->base); + prom_debug("rtas->entry = 0x%x\n", _rtas->entry); + prom_debug("rtas->size = 0x%x\n", _rtas->size); } -#ifdef DEBUG_PROM - prom_print(RELOC("prom_instantiate_rtas: end...\n")); -#endif + prom_debug("prom_instantiate_rtas: end...\n"); } @@ -759,9 +736,7 @@ static void __init prom_initialize_dart_table(void) RELOC(dart_tablebase) = (unsigned long) abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); - prom_print(RELOC("Dart at: ")); - prom_print_hex(RELOC(dart_tablebase)); - prom_print(RELOC("\n")); + prom_printf("Dart at: %x\n", RELOC(dart_tablebase)); } #endif /* CONFIG_PMAC_DART */ @@ -780,27 +755,23 @@ static void __init prom_initialize_tce_table(void) if (RELOC(ppc64_iommu_off)) return; -#ifdef DEBUG_PROM - prom_print(RELOC("starting prom_initialize_tce_table\n")); -#endif + prom_debug("starting prom_initialize_tce_table\n"); /* Search all nodes looking for PHBs. */ for (node = 0; prom_next_node(&node); ) { if (table == MAX_PHB) { - prom_print(RELOC("WARNING: PCI host bridge ignored, " - "need to increase MAX_PHB\n")); + prom_printf("WARNING: PCI host bridge ignored, " + "need to increase MAX_PHB\n"); continue; } compatible[0] = 0; type[0] = 0; model[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"), - compatible, sizeof(compatible)); - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); - call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"), - model, sizeof(model)); + prom_getprop(node, "compatible", + compatible, sizeof(compatible)); + prom_getprop(node, "device_type", type, sizeof(type)); + prom_getprop(node, "model", model, sizeof(model)); /* Keep the old logic in tack to avoid regression. */ if (compatible[0] != 0) { @@ -819,15 +790,13 @@ static void __init prom_initialize_tce_table(void) continue; } - if (call_prom(RELOC("getprop"), 4, 1, node, - RELOC("tce-table-minalign"), &minalign, - sizeof(minalign)) == PROM_ERROR) { + if (prom_getprop(node, "tce-table-minalign", &minalign, + sizeof(minalign)) == PROM_ERROR) { minalign = 0; } - if (call_prom(RELOC("getprop"), 4, 1, node, - RELOC("tce-table-minsize"), &minsize, - sizeof(minsize)) == PROM_ERROR) { + if (prom_getprop(node, "tce-table-minsize", &minsize, + sizeof(minsize)) == PROM_ERROR) { minsize = 4UL << 20; } @@ -854,7 +823,7 @@ static void __init prom_initialize_tce_table(void) base = lmb_alloc(minsize, align); if ( !base ) { - prom_panic(RELOC("ERROR, cannot find space for TCE table.\n")); + prom_panic("ERROR, cannot find space for TCE table.\n"); } vbase = (unsigned long)abs_to_virt(base); @@ -864,23 +833,10 @@ static void __init prom_initialize_tce_table(void) prom_tce_table[table].base = vbase; prom_tce_table[table].size = minsize; -#ifdef DEBUG_PROM - prom_print(RELOC("TCE table: 0x")); - prom_print_hex(table); - prom_print_nl(); - - prom_print(RELOC("\tnode = 0x")); - prom_print_hex(node); - prom_print_nl(); - - prom_print(RELOC("\tbase = 0x")); - prom_print_hex(vbase); - prom_print_nl(); - - prom_print(RELOC("\tsize = 0x")); - prom_print_hex(minsize); - prom_print_nl(); -#endif + prom_debug("TCE table: 0x%x\n", table); + prom_debug("\tnode = 0x%x\n", node); + prom_debug("\tbase = 0x%x\n", vbase); + prom_debug("\tsize = 0x%x\n", minsize); /* Initialize the table to have a one-to-one mapping * over the allocated size. @@ -895,37 +851,30 @@ static void __init prom_initialize_tce_table(void) /* It seems OF doesn't null-terminate the path :-( */ memset(path, 0, sizeof(path)); /* Call OF to setup the TCE hardware */ - if (call_prom(RELOC("package-to-path"), 3, 1, node, - path, sizeof(path)-1) == PROM_ERROR) { - prom_print(RELOC("package-to-path failed\n")); + if (call_prom("package-to-path", 3, 1, node, + path, sizeof(path)-1) == PROM_ERROR) { + prom_printf("package-to-path failed\n"); } else { - prom_print(RELOC("opening PHB ")); - prom_print(path); + prom_printf("opening PHB %s", path); } - phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path); + phb_node = call_prom("open", 1, 1, path); if ( (long)phb_node <= 0) { - prom_print(RELOC("... failed\n")); + prom_printf("... failed\n"); } else { - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); } - call_prom(RELOC("call-method"), 6, 0, - RELOC("set-64-bit-addressing"), - phb_node, - -1, - minsize, - base & 0xffffffff, - (base >> 32) & 0xffffffff); - call_prom(RELOC("close"), 1, 0, phb_node); + call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"), + phb_node, -1, minsize, + (u32) base, (u32) (base >> 32)); + call_prom("close", 1, 0, phb_node); table++; } /* Flag the first invalid entry */ prom_tce_table[table].node = 0; -#ifdef DEBUG_PROM - prom_print(RELOC("ending prom_initialize_tce_table\n")); -#endif + prom_debug("ending prom_initialize_tce_table\n"); } /* @@ -983,13 +932,11 @@ static void __init prom_hold_cpus(unsigned long mem) if (_systemcfg->platform == PLATFORM_POWERMAC) { for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("cpu")) != 0) continue; reg = -1; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); _xPaca[cpuid].xHwProcNum = reg; #ifdef CONFIG_SMP @@ -1007,24 +954,13 @@ static void __init prom_hold_cpus(unsigned long mem) /* Initially, we must have one active CPU. */ _systemcfg->processorCount = 1; -#ifdef DEBUG_PROM - prom_print(RELOC("prom_hold_cpus: start...\n")); - prom_print(RELOC(" 1) spinloop = 0x")); - prom_print_hex((unsigned long)spinloop); - prom_print_nl(); - prom_print(RELOC(" 1) *spinloop = 0x")); - prom_print_hex(*spinloop); - prom_print_nl(); - prom_print(RELOC(" 1) acknowledge = 0x")); - prom_print_hex((unsigned long)acknowledge); - prom_print_nl(); - prom_print(RELOC(" 1) *acknowledge = 0x")); - prom_print_hex(*acknowledge); - prom_print_nl(); - prom_print(RELOC(" 1) secondary_hold = 0x")); - prom_print_hex(secondary_hold); - prom_print_nl(); -#endif + prom_debug("prom_hold_cpus: start...\n"); + prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); + prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); + prom_debug(" 1) acknowledge = 0x%x\n", + (unsigned long)acknowledge); + prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge); + prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold); /* Set the common spinloop variable, so all of the secondary cpus * will block when they are awakened from their OF spinloop. @@ -1041,36 +977,26 @@ static void __init prom_hold_cpus(unsigned long mem) /* look for cpus */ for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("cpu")) != 0) continue; /* Skip non-configured cpus. */ - call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"), - type, sizeof(type)); + prom_getprop(node, "status", type, sizeof(type)); if (strcmp(type, RELOC("okay")) != 0) continue; reg = -1; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); path = (char *) mem; memset(path, 0, 256); - if ((long) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 255) == PROM_ERROR) + if (call_prom("package-to-path", 3, 1, + node, path, 255) == PROM_ERROR) continue; -#ifdef DEBUG_PROM - prom_print_nl(); - prom_print(RELOC("cpuid = 0x")); - prom_print_hex(cpuid); - prom_print_nl(); - prom_print(RELOC("cpu hw idx = 0x")); - prom_print_hex(reg); - prom_print_nl(); -#endif + prom_debug("\ncpuid = 0x%x\n", cpuid); + prom_debug("cpu hw idx = 0x%x\n", reg); _xPaca[cpuid].xHwProcNum = reg; /* Init the acknowledge var which will be reset by @@ -1079,10 +1005,9 @@ static void __init prom_hold_cpus(unsigned long mem) */ *acknowledge = (unsigned long)-1; - propsize = call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,ppc-interrupt-server#s"), - &interrupt_server, - sizeof(interrupt_server)); + propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s", + &interrupt_server, + sizeof(interrupt_server)); if (propsize < 0) { /* no property. old hardware has no SMT */ cpu_threads = 1; @@ -1091,11 +1016,9 @@ static void __init prom_hold_cpus(unsigned long mem) /* We have a threaded processor */ cpu_threads = propsize / sizeof(u32); if (cpu_threads > MAX_CPU_THREADS) { - prom_print(RELOC("SMT: too many threads!\nSMT: found ")); - prom_print_hex(cpu_threads); - prom_print(RELOC(", max is ")); - prom_print_hex(MAX_CPU_THREADS); - prom_print_nl(); + prom_printf("SMT: too many threads!\n" + "SMT: found %x, max is %x\n", + cpu_threads, MAX_CPU_THREADS); cpu_threads = 1; /* ToDo: panic? */ } } @@ -1103,18 +1026,15 @@ static void __init prom_hold_cpus(unsigned long mem) hw_cpu_num = interrupt_server[0]; if (hw_cpu_num != _prom->cpu) { /* Primary Thread of non-boot cpu */ - prom_print_hex(cpuid); - prom_print(RELOC(" : starting cpu ")); - prom_print(path); - prom_print(RELOC("... ")); - call_prom(RELOC("start-cpu"), 3, 0, node, + prom_printf("%x : starting cpu %s... ", cpuid, path); + call_prom("start-cpu", 3, 0, node, secondary_hold, cpuid); for ( i = 0 ; (i < 100000000) && (*acknowledge == ((unsigned long)-1)); i++ ) ; if (*acknowledge == cpuid) { - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); /* We have to get every CPU out of OF, * even if we never start it. */ if (cpuid >= NR_CPUS) @@ -1127,17 +1047,12 @@ static void __init prom_hold_cpus(unsigned long mem) cpu_set(cpuid, RELOC(cpu_present_at_boot)); #endif } else { - prom_print(RELOC("... failed: ")); - prom_print_hex(*acknowledge); - prom_print_nl(); + prom_printf("... failed: %x\n", *acknowledge); } } #ifdef CONFIG_SMP else { - prom_print_hex(cpuid); - prom_print(RELOC(" : booting cpu ")); - prom_print(path); - prom_print_nl(); + prom_printf("%x : booting cpu %s\n", cpuid, path); cpu_set(cpuid, RELOC(cpu_available_map)); cpu_set(cpuid, RELOC(cpu_possible_map)); cpu_set(cpuid, RELOC(cpu_online_map)); @@ -1152,16 +1067,15 @@ next: if (cpuid >= NR_CPUS) continue; _xPaca[cpuid].xHwProcNum = interrupt_server[i]; - prom_print_hex(interrupt_server[i]); - prom_print(RELOC(" : preparing thread ... ")); + prom_printf("%x : preparing thread ... ", + interrupt_server[i]); if (_naca->smt_state) { cpu_set(cpuid, RELOC(cpu_available_map)); cpu_set(cpuid, RELOC(cpu_present_at_boot)); - prom_print(RELOC("available")); + prom_printf("available\n"); } else { - prom_print(RELOC("not available")); + prom_printf("not available\n"); } - prom_print_nl(); } #endif cpuid++; @@ -1171,7 +1085,7 @@ next: if (__is_processor(PV_PULSAR) || __is_processor(PV_ICESTAR) || __is_processor(PV_SSTAR)) { - prom_print(RELOC(" starting secondary threads\n")); + prom_printf(" starting secondary threads\n"); for (i = 0; i < NR_CPUS; i += 2) { if (!cpu_online(i)) @@ -1192,24 +1106,22 @@ next: } _systemcfg->processorCount *= 2; } else { - prom_print(RELOC("Processor is not HMT capable\n")); + prom_printf("Processor is not HMT capable\n"); } #endif - if (cpuid >= NR_CPUS) - prom_print(RELOC("WARNING: maximum CPUs (" __stringify(NR_CPUS) - ") exceeded: ignoring extras\n")); + if (cpuid > NR_CPUS) + prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS) + ") exceeded: ignoring extras\n"); -#ifdef DEBUG_PROM - prom_print(RELOC("prom_hold_cpus: end...\n")); -#endif + prom_debug("prom_hold_cpus: end...\n"); } static void __init smt_setup(void) { char *p, *q; char my_smt_enabled = SMT_DYNAMIC; - ihandle prom_options = NULL; + ihandle prom_options = 0; char option[9]; unsigned long offset = reloc_offset(); struct naca_struct *_naca = RELOC(naca); @@ -1233,13 +1145,10 @@ static void __init smt_setup(void) } } if (!found) { - prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + prom_options = call_prom("finddevice", 1, 1, ADDR("/options")); if (prom_options != (ihandle) -1) { - call_prom(RELOC("getprop"), - 4, 1, prom_options, - RELOC("ibm,smt-enabled"), - option, - sizeof(option)); + prom_getprop(prom_options, "ibm,smt-enabled", + option, sizeof(option)); if (option[0] != 0) { found = 1; if (!strcmp(option, RELOC("off"))) @@ -1272,43 +1181,29 @@ static void __init setup_disp_fake_bi(ihandle dp) int i, naddrs; char name[64]; unsigned long offset = reloc_offset(); - char *getprop = RELOC("getprop"); - - prom_print(RELOC("Initializing fake screen: ")); memset(name, 0, sizeof(name)); - call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name)); + prom_getprop(dp, "name", name, sizeof(name)); name[sizeof(name)-1] = 0; - prom_print(name); - prom_print(RELOC("\n")); - call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width)); - call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height)); - call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth)); + prom_printf("Initializing fake screen: %s\n", name); + + prom_getprop(dp, "width", &width, sizeof(width)); + prom_getprop(dp, "height", &height, sizeof(height)); + prom_getprop(dp, "depth", &depth, sizeof(depth)); pitch = width * ((depth + 7) / 8); - call_prom(getprop, 4, 1, dp, RELOC("linebytes"), - &pitch, sizeof(pitch)); + prom_getprop(dp, "linebytes", &pitch, sizeof(pitch)); if (pitch == 1) pitch = 0x1000; /* for strange IBM display */ address = 0; - prom_print(RELOC("width ")); - prom_print_hex(width); - prom_print(RELOC(" height ")); - prom_print_hex(height); - prom_print(RELOC(" depth ")); - prom_print_hex(depth); - prom_print(RELOC(" linebytes ")); - prom_print_hex(pitch); - prom_print(RELOC("\n")); - + prom_printf("width %x height %x depth %x linebytes %x\n", + width, height, depth, depth); - call_prom(getprop, 4, 1, dp, RELOC("address"), - &address, sizeof(address)); + prom_getprop(dp, "address", &address, sizeof(address)); if (address == 0) { /* look for an assigned address with a size of >= 1MB */ - naddrs = (int) call_prom(getprop, 4, 1, dp, - RELOC("assigned-addresses"), - addrs, sizeof(addrs)); + naddrs = prom_getprop(dp, "assigned-addresses", + addrs, sizeof(addrs)); naddrs /= sizeof(struct pci_reg_property); for (i = 0; i < naddrs; ++i) { if (addrs[i].size_lo >= (1 << 20)) { @@ -1320,14 +1215,12 @@ static void __init setup_disp_fake_bi(ihandle dp) } } if (address == 0) { - prom_print(RELOC("Failed to get address of frame buffer\n")); + prom_printf("Failed to get address of frame buffer\n"); return; } } btext_setup_display(width, height, depth, pitch, address); - prom_print(RELOC("Addr of fb: ")); - prom_print_hex(address); - prom_print_nl(); + prom_printf("Addr of fb: %x\n", address); RELOC(boot_text_mapped) = 0; } #endif /* CONFIG_BOOTX_TEXT */ @@ -1344,15 +1237,14 @@ static void __init prom_init_client_services(unsigned long pp) _prom->encode_phys_size = 32; /* get a handle for the stdout device */ - _prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1, - RELOC("/chosen")); + _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); if ((long)_prom->chosen <= 0) - prom_panic(RELOC("cannot find chosen")); /* msg won't be printed :( */ + prom_panic("cannot find chosen"); /* msg won't be printed :( */ /* get device tree root */ - _prom->root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/")); + _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); if ((long)_prom->root <= 0) - prom_panic(RELOC("cannot find device tree root")); /* msg won't be printed :( */ + prom_panic("cannot find device tree root"); /* msg won't be printed :( */ } static void __init prom_init_stdout(void) @@ -1361,12 +1253,10 @@ static void __init prom_init_stdout(void) struct prom_t *_prom = PTRRELOC(&prom); u32 val; - if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("stdout"), &val, - sizeof(val)) <= 0) - prom_panic(RELOC("cannot find stdout")); + if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0) + prom_panic("cannot find stdout"); - _prom->stdout = (ihandle)(unsigned long)val; + _prom->stdout = val; } static int __init prom_find_machine_type(void) @@ -1376,9 +1266,8 @@ static int __init prom_find_machine_type(void) char compat[256]; int len, i = 0; - len = (int)(long)call_prom(RELOC("getprop"), 4, 1, _prom->root, - RELOC("compatible"), - compat, sizeof(compat)-1); + len = prom_getprop(_prom->root, "compatible", + compat, sizeof(compat)-1); if (len > 0) { compat[len] = 0; while (i < len) { @@ -1400,13 +1289,7 @@ static int __init prom_set_color(ihandle ih, int i, int r, int g, int b) { unsigned long offset = reloc_offset(); - return (int)(long)call_prom(RELOC("call-method"), 6, 1, - RELOC("color!"), - ih, - (void *)(long) i, - (void *)(long) b, - (void *)(long) g, - (void *)(long) r ); + return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r); } /* @@ -1447,16 +1330,13 @@ static unsigned long __init check_display(unsigned long mem) _prom->disp_node = 0; - prom_print(RELOC("Looking for displays\n")); - if (RELOC(of_stdout_device) != 0) { - prom_print(RELOC("OF stdout is : ")); - prom_print(PTRRELOC(RELOC(of_stdout_device))); - prom_print(RELOC("\n")); - } + prom_printf("Looking for displays\n"); + if (RELOC(of_stdout_device) != 0) + prom_printf("OF stdout is : %s\n", + PTRRELOC(RELOC(of_stdout_device))); for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("display")) != 0) continue; /* It seems OF doesn't null-terminate the path :-( */ @@ -1467,12 +1347,9 @@ static unsigned long __init check_display(unsigned long mem) * leave some room at the end of the path for appending extra * arguments */ - if ((long) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 250) < 0) + if (call_prom("package-to-path", 3, 1, node, path, 250) < 0) continue; - prom_print(RELOC("found display : ")); - prom_print(path); - prom_print(RELOC("\n")); + prom_printf("found display : %s\n", path); /* * If this display is the device that OF is using for stdout, @@ -1489,27 +1366,26 @@ static unsigned long __init check_display(unsigned long mem) RELOC(prom_display_nodes[i]) = RELOC(prom_display_nodes[i-1]); } - _prom->disp_node = (ihandle)(unsigned long)node; + _prom->disp_node = node; } RELOC(prom_display_paths[i]) = PTRUNRELOC(path); RELOC(prom_display_nodes[i]) = node; if (_prom->disp_node == 0) - _prom->disp_node = (ihandle)(unsigned long)node; + _prom->disp_node = node; if (RELOC(prom_num_displays) >= FB_MAX) break; } - prom_print(RELOC("Opening displays...\n")); + prom_printf("Opening displays...\n"); for (j = RELOC(prom_num_displays) - 1; j >= 0; j--) { path = PTRRELOC(RELOC(prom_display_paths[j])); - prom_print(RELOC("opening display : ")); - prom_print(path); - ih = (ihandle)call_prom(RELOC("open"), 1, 1, path); + prom_printf("opening display : %s", path); + ih = call_prom("open", 1, 1, path); if (ih == (ihandle)0 || ih == (ihandle)-1) { - prom_print(RELOC("... failed\n")); + prom_printf("... failed\n"); continue; } - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); /* Setup a useable color table when the appropriate * method is available. Should update this to set-colors */ @@ -1546,9 +1422,9 @@ static void __init *__make_room(unsigned long *mem_start, unsigned long *mem_end unsigned long initrd_len; if (*mem_end != RELOC(initrd_start)) - prom_panic(RELOC("No memory for copy_device_tree")); + prom_panic("No memory for copy_device_tree"); - prom_print(RELOC("Huge device_tree: moving initrd\n")); + prom_printf("Huge device_tree: moving initrd\n"); /* Move by 4M. */ initrd_len = RELOC(initrd_end) - RELOC(initrd_start); *mem_end = RELOC(initrd_start) + 4 * 1024 * 1024; @@ -1557,7 +1433,7 @@ static void __init *__make_room(unsigned long *mem_start, unsigned long *mem_end RELOC(initrd_start) = *mem_end; RELOC(initrd_end) = RELOC(initrd_start) + initrd_len; #else - prom_panic(RELOC("No memory for copy_device_tree")); + prom_panic("No memory for copy_device_tree"); #endif } @@ -1606,8 +1482,7 @@ inspect_node(phandle node, struct device_node *dad, for (;;) { /* 32 is max len of name including nul. */ namep = make_room(mem_start, mem_end, char[32]); - if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name, - namep) <= 0) { + if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { /* No more nodes: unwind alloc */ *mem_start = (unsigned long)namep; break; @@ -1619,28 +1494,24 @@ inspect_node(phandle node, struct device_node *dad, pp->name = PTRUNRELOC(namep); prev_name = namep; - pp->length = call_prom(RELOC("getproplen"), 2, 1, node, namep); + pp->length = call_prom("getproplen", 2, 1, node, namep); if (pp->length < 0) continue; if (pp->length > MAX_PROPERTY_LENGTH) { char path[128]; - prom_print(RELOC("WARNING: ignoring large property ")); + prom_printf("WARNING: ignoring large property "); /* It seems OF doesn't null-terminate the path :-( */ memset(path, 0, sizeof(path)); - if (call_prom(RELOC("package-to-path"), 3, 1, node, - path, sizeof(path)-1) > 0) - prom_print(path); - prom_print(namep); - prom_print(RELOC(" length 0x")); - prom_print_hex(pp->length); - prom_print_nl(); - + if (call_prom("package-to-path", 3, 1, node, + path, sizeof(path)-1) > 0) + prom_printf("[%s] ", path); + prom_printf("%s length 0x%x\n", namep, pp->length); continue; } valp = __make_room(mem_start, mem_end, pp->length, 1); pp->value = PTRUNRELOC(valp); - call_prom(RELOC("getprop"), 4, 1, node, namep,valp,pp->length); + call_prom("getprop", 4, 1, node, namep, valp, pp->length); *prev_propp = PTRUNRELOC(pp); prev_propp = &pp->next; } @@ -1660,19 +1531,19 @@ inspect_node(phandle node, struct device_node *dad, /* Set np->linux_phandle to the value of the ibm,phandle property if it exists, otherwise to the phandle for this node. */ np->linux_phandle = node; - if ((int)call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"), - &ibm_phandle, sizeof(ibm_phandle)) > 0) + if (prom_getprop(node, "ibm,phandle", + &ibm_phandle, sizeof(ibm_phandle)) > 0) np->linux_phandle = ibm_phandle; /* get the node's full name */ namep = (char *)*mem_start; - l = (long) call_prom(RELOC("package-to-path"), 3, 1, node, - namep, *mem_end - *mem_start); + l = call_prom("package-to-path", 3, 1, node, + namep, *mem_end - *mem_start); if (l >= 0) { /* Didn't fit? Get more room. */ if (l+1 > *mem_end - *mem_start) { namep = __make_room(mem_start, mem_end, l+1, 1); - call_prom(RELOC("package-to-path"),3,1,node,namep,l); + call_prom("package-to-path", 3, 1, node, namep, l); } np->full_name = PTRUNRELOC(namep); namep[l] = '\0'; @@ -1680,11 +1551,11 @@ inspect_node(phandle node, struct device_node *dad, } /* do all our children */ - child = call_prom(RELOC("child"), 1, 1, node); + child = call_prom("child", 1, 1, node); while (child != (phandle)0) { inspect_node(child, np, mem_start, mem_end, allnextpp); - child = call_prom(RELOC("peer"), 1, 1, child); + child = call_prom("peer", 1, 1, child); } } @@ -1706,9 +1577,9 @@ copy_device_tree(unsigned long mem_start) mem_end = RELOC(initrd_start); #endif /* CONFIG_BLK_DEV_INITRD */ - root = call_prom(RELOC("peer"), 1, 1, (phandle)0); + root = call_prom("peer", 1, 1, (phandle)0); if (root == (phandle)0) { - prom_panic(RELOC("couldn't get device tree root\n")); + prom_panic("couldn't get device tree root\n"); } allnextp = &RELOC(allnodes); inspect_node(root, 0, &mem_start, &mem_end, &allnextp); @@ -1720,44 +1591,25 @@ copy_device_tree(unsigned long mem_start) static struct bi_record * __init prom_bi_rec_verify(struct bi_record *bi_recs) { struct bi_record *first, *last; -#ifdef DEBUG_PROM - unsigned long offset = reloc_offset(); - prom_print(RELOC("birec_verify: r6=0x")); - prom_print_hex((unsigned long)bi_recs); - prom_print_nl(); - if (bi_recs != NULL) { - prom_print(RELOC(" tag=0x")); - prom_print_hex(bi_recs->tag); - prom_print_nl(); - } -#endif /* DEBUG_PROM */ + prom_debug("birec_verify: r6=0x%x\n", (unsigned long)bi_recs); + if (bi_recs != NULL) + prom_debug(" tag=0x%x\n", bi_recs->tag); if ( bi_recs == NULL || bi_recs->tag != BI_FIRST ) return NULL; last = (struct bi_record *)(long)bi_recs->data[0]; -#ifdef DEBUG_PROM - prom_print(RELOC(" last=0x")); - prom_print_hex((unsigned long)last); - prom_print_nl(); - if (last != NULL) { - prom_print(RELOC(" last_tag=0x")); - prom_print_hex(last->tag); - prom_print_nl(); - } -#endif /* DEBUG_PROM */ + prom_debug(" last=0x%x\n", (unsigned long)last); + if (last != NULL) + prom_debug(" last_tag=0x%x\n", last->tag); if ( last == NULL || last->tag != BI_LAST ) return NULL; first = (struct bi_record *)(long)last->data[0]; -#ifdef DEBUG_PROM - prom_print(RELOC(" first=0x")); - prom_print_hex((unsigned long)first); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug(" first=0x%x\n", (unsigned long)first); if ( first == NULL || first != bi_recs ) return NULL; @@ -1776,11 +1628,7 @@ static void __init prom_bi_rec_reserve(void) for ( rec=_prom->bi_recs; rec->tag != BI_LAST; rec=bi_rec_next(rec) ) { -#ifdef DEBUG_PROM - prom_print(RELOC("bi: 0x")); - prom_print_hex(rec->tag); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("bi: 0x%x\n", rec->tag); switch (rec->tag) { #ifdef CONFIG_BLK_DEV_INITRD case BI_INITRD: @@ -1833,31 +1681,17 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, /* Init prom stdout device */ prom_init_stdout(); -#ifdef DEBUG_PROM - prom_print(RELOC("klimit=0x")); - prom_print_hex(RELOC(klimit)); - prom_print_nl(); - prom_print(RELOC("offset=0x")); - prom_print_hex(offset); - prom_print_nl(); - prom_print(RELOC("->mem=0x")); - prom_print_hex(RELOC(klimit) - offset); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("klimit=0x%x\n", RELOC(klimit)); + prom_debug("offset=0x%x\n", offset); + prom_debug("->mem=0x%x\n", RELOC(klimit) - offset); /* check out if we have bi_recs */ _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6); if ( _prom->bi_recs != NULL ) { RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]); -#ifdef DEBUG_PROM - prom_print(RELOC("bi_recs=0x")); - prom_print_hex((unsigned long)_prom->bi_recs); - prom_print_nl(); - prom_print(RELOC("new mem=0x")); - prom_print_hex(RELOC(klimit) - offset); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("bi_recs=0x%x\n", (unsigned long)_prom->bi_recs); + prom_debug("new mem=0x%x\n", RELOC(klimit) - offset); } /* If we don't have birec's or didn't find them, check for an initrd @@ -1884,57 +1718,46 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, /* Get the full OF pathname of the stdout device */ p = (char *) mem; memset(p, 0, 256); - call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255); + call_prom("instance-to-path", 3, 1, _prom->stdout, p, 255); RELOC(of_stdout_device) = PTRUNRELOC(p); mem += strlen(p) + 1; getprop_rval = 1; - call_prom(RELOC("getprop"), 4, 1, - _prom->root, RELOC("#size-cells"), - &getprop_rval, sizeof(getprop_rval)); + prom_getprop(_prom->root, "#size-cells", + &getprop_rval, sizeof(getprop_rval)); _prom->encode_phys_size = (getprop_rval == 1) ? 32 : 64; /* Determine which cpu is actually running right _now_ */ - if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("cpu"), &getprop_rval, - sizeof(getprop_rval)) <= 0) - prom_panic(RELOC("cannot find boot cpu")); - - prom_cpu = (ihandle)(unsigned long)getprop_rval; - cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu); - call_prom(RELOC("getprop"), 4, 1, - cpu_pkg, RELOC("reg"), - &getprop_rval, sizeof(getprop_rval)); - _prom->cpu = (int)(unsigned long)getprop_rval; + if (prom_getprop(_prom->chosen, "cpu", + &prom_cpu, sizeof(prom_cpu)) <= 0) + prom_panic("cannot find boot cpu"); + + cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); + prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); + _prom->cpu = getprop_rval; _xPaca[0].xHwProcNum = _prom->cpu; RELOC(boot_cpuid) = 0; -#ifdef DEBUG_PROM - prom_print(RELOC("Booting CPU hw index = 0x")); - prom_print_hex(_prom->cpu); - prom_print_nl(); -#endif + prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); /* Get the boot device and translate it to a full OF pathname. */ p = (char *) mem; - l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("bootpath"), p, 1<<20); + l = prom_getprop(_prom->chosen, "bootpath", p, 1<<20); if (l > 0) { p[l] = 0; /* should already be null-terminated */ RELOC(bootpath) = PTRUNRELOC(p); mem += l + 1; d = (char *) mem; *d = 0; - call_prom(RELOC("canon"), 3, 1, p, d, 1<<20); + call_prom("canon", 3, 1, p, d, 1<<20); RELOC(bootdevice) = PTRUNRELOC(d); mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1); } RELOC(cmd_line[0]) = 0; if ((long)_prom->chosen > 0) { - call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("bootargs"), p, sizeof(cmd_line)); + prom_getprop(_prom->chosen, "bootargs", p, sizeof(cmd_line)); if (p != NULL && p[0] != 0) strlcpy(RELOC(cmd_line), p, sizeof(cmd_line)); } @@ -1961,33 +1784,20 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, */ prom_hold_cpus(mem); -#ifdef DEBUG_PROM - prom_print(RELOC("after basic inits, mem=0x")); - prom_print_hex(mem); - prom_print_nl(); + prom_debug("after basic inits, mem=0x%x\n", mem); #ifdef CONFIG_BLK_DEV_INITRD - prom_print(RELOC("initrd_start=0x")); - prom_print_hex(RELOC(initrd_start)); - prom_print_nl(); - prom_print(RELOC("initrd_end=0x")); - prom_print_hex(RELOC(initrd_end)); - prom_print_nl(); + prom_debug("initrd_start=0x%x\n", RELOC(initrd_start)); + prom_debug("initrd_end=0x%x\n", RELOC(initrd_end)); #endif /* CONFIG_BLK_DEV_INITRD */ - prom_print(RELOC("copying OF device tree...\n")); -#endif /* DEBUG_PROM */ + prom_debug("copying OF device tree...\n"); + mem = copy_device_tree(mem); RELOC(klimit) = mem + offset; -#ifdef DEBUG_PROM - prom_print(RELOC("new klimit is\n")); - prom_print(RELOC("klimit=0x")); - prom_print_hex(RELOC(klimit)); - prom_print(RELOC(" ->mem=0x\n")); - prom_print(RELOC("klimit=0x")); - prom_print_hex(mem); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("new klimit is\n"); + prom_debug("klimit=0x%x\n", RELOC(klimit)); + prom_debug(" ->mem=0x%x\n", mem); lmb_reserve(0, __pa(RELOC(klimit))); @@ -2017,14 +1827,14 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, #endif #ifdef CONFIG_BOOTX_TEXT - if(_prom->disp_node) { - prom_print(RELOC("Setting up bi display...\n")); + if (_prom->disp_node) { + prom_printf("Setting up bi display...\n"); setup_disp_fake_bi(_prom->disp_node); } #endif /* CONFIG_BOOTX_TEXT */ - prom_print(RELOC("Calling quiesce ...\n")); - call_prom(RELOC("quiesce"), 0, 0); + prom_printf("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); phys = KERNELBASE - offset; #ifdef CONFIG_BLK_DEV_INITRD @@ -2035,7 +1845,7 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, } #endif /* CONFIG_BLK_DEV_INITRD */ - prom_print(RELOC("returning from prom_init\n")); + prom_printf("returning from prom_init\n"); return phys; } diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c index 338f6608444a..b7d1c940cd5a 100644 --- a/arch/ppc64/kernel/rtas-proc.c +++ b/arch/ppc64/kernel/rtas-proc.c @@ -394,7 +394,7 @@ static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned int year, mon, day, hour, min, sec; - unsigned long *ret = kmalloc(4*8, GFP_KERNEL); + int ret[8]; int n, sn, error; char stkbuf[40]; /* its small, its on stack */ @@ -411,7 +411,6 @@ static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, n = scnprintf (stkbuf, sizeof(stkbuf), "%lu\n", mktime(year, mon, day, hour, min, sec)); } - kfree(ret); sn = strlen (stkbuf) +1; if (*ppos >= sn) @@ -434,7 +433,6 @@ static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, int count, int *eof, void *data) { int i,j,n; - unsigned long ret; int state, error; char *buffer; int get_sensor_state = rtas_token("get-sensor-state"); @@ -464,11 +462,10 @@ static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, /* A sensor may have multiple instances */ while (j >= 0) { - error = rtas_call(get_sensor_state, 2, 2, &ret, + error = rtas_call(get_sensor_state, 2, 2, &state, sensors.sensor[i].token, sensors.sensor[i].quant - j); - state = (int) ret; n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); n += sprintf (buffer+n, "\n"); diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c index efc1f75797a4..5199c0261b73 100644 --- a/arch/ppc64/kernel/rtas.c +++ b/arch/ppc64/kernel/rtas.c @@ -139,15 +139,13 @@ log_rtas_error(struct rtas_args *rtas_args) log_error(rtas_err_buf, ERR_TYPE_RTAS_LOG, 0); } -long -rtas_call(int token, int nargs, int nret, - unsigned long *outputs, ...) +int rtas_call(int token, int nargs, int nret, int *outputs, ...) { va_list list; int i, logit = 0; unsigned long s; struct rtas_args *rtas_args; - long ret; + int ret; PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n"); PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token); @@ -167,8 +165,8 @@ rtas_call(int token, int nargs, int nret, rtas_args->rets = (rtas_arg_t *)&(rtas_args->args[nargs]); va_start(list, outputs); for (i = 0; i < nargs; ++i) { - rtas_args->args[i] = (rtas_arg_t)LONG_LSW(va_arg(list, ulong)); - PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%lx\n", i, rtas_args->args[i]); + rtas_args->args[i] = va_arg(list, rtas_arg_t); + PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]); } va_end(list); @@ -191,7 +189,7 @@ rtas_call(int token, int nargs, int nret, if (nret > 1 && outputs != NULL) for (i = 0; i < nret-1; ++i) outputs[i] = rtas_args->rets[i+1]; - ret = (ulong)((nret > 0) ? rtas_args->rets[0] : 0); + ret = (nret > 0)? rtas_args->rets[0]: 0; /* Gotta do something different here, use global lock for now... */ spin_unlock_irqrestore(&rtas.lock, s); @@ -227,20 +225,13 @@ int rtas_get_power_level(int powerdomain, int *level) { int token = rtas_token("get-power-level"); - long powerlevel; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; - while(1) { - rc = (int) rtas_call(token, 1, 2, &powerlevel, powerdomain); - if (rc == RTAS_BUSY) - udelay(1); - else - break; - } - *level = (int) powerlevel; + while ((rc = rtas_call(token, 1, 2, level, powerdomain)) == RTAS_BUSY) + udelay(1); return rc; } @@ -249,25 +240,21 @@ rtas_set_power_level(int powerdomain, int level, int *setlevel) { int token = rtas_token("set-power-level"); unsigned int wait_time; - long returned_level; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 2, 2, &returned_level, powerdomain, - level); + rc = rtas_call(token, 2, 2, setlevel, powerdomain, level); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { wait_time = rtas_extended_busy_delay_time(rc); udelay(wait_time * 1000); - } - else + } else break; } - *setlevel = (int) returned_level; return rc; } @@ -276,25 +263,21 @@ rtas_get_sensor(int sensor, int index, int *state) { int token = rtas_token("get-sensor-state"); unsigned int wait_time; - long returned_state; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 2, 2, &returned_state, sensor, - index); + rc = rtas_call(token, 2, 2, state, sensor, index); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { wait_time = rtas_extended_busy_delay_time(rc); udelay(wait_time * 1000); - } - else + } else break; } - *state = (int) returned_state; return rc; } @@ -309,8 +292,7 @@ rtas_set_indicator(int indicator, int index, int new_value) return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 3, 1, NULL, indicator, index, - new_value); + rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { @@ -409,7 +391,7 @@ rtas_restart(char *cmd) if (rtas_firmware_flash_list.next) rtas_flash_firmware(); - printk("RTAS system-reboot returned %ld\n", + printk("RTAS system-reboot returned %d\n", rtas_call(rtas_token("system-reboot"), 0, 1, NULL)); for (;;); } @@ -420,8 +402,8 @@ rtas_power_off(void) if (rtas_firmware_flash_list.next) rtas_flash_bypass_warning(); /* allow power on only with power button press */ - printk("RTAS power-off returned %ld\n", - rtas_call(rtas_token("power-off"), 2, 1, NULL,0xffffffff,0xffffffff)); + printk("RTAS power-off returned %d\n", + rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); for (;;); } @@ -438,7 +420,7 @@ static char rtas_os_term_buf[2048]; void rtas_os_term(char *str) { - long status; + int status; snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str); @@ -449,7 +431,7 @@ void rtas_os_term(char *str) if (status == RTAS_BUSY) udelay(1); else if (status != 0) - printk(KERN_EMERG "ibm,os-term call failed %ld\n", + printk(KERN_EMERG "ibm,os-term call failed %d\n", status); } while (status == RTAS_BUSY); } diff --git a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c index e9d21eb4edd3..aac9e96096f6 100644 --- a/arch/ppc64/kernel/rtas_flash.c +++ b/arch/ppc64/kernel/rtas_flash.c @@ -344,8 +344,8 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) s32 rc; while (1) { - rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1, - 1, NULL, (long) args_buf->op); + rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, + 1, NULL, args_buf->op); if (rc == RTAS_RC_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { @@ -429,15 +429,15 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf) { int token = rtas_token("ibm,validate-flash-image"); unsigned int wait_time; - long update_results; + int update_results; s32 rc; rc = 0; while(1) { spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); - rc = (s32) rtas_call(token, 2, 2, &update_results, - __pa(rtas_data_buf), args_buf->buf_size); + rc = rtas_call(token, 2, 2, &update_results, + (u32) __pa(rtas_data_buf), args_buf->buf_size); memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); @@ -451,7 +451,7 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf) } args_buf->status = rc; - args_buf->update_results = (u32) update_results; + args_buf->update_results = update_results; } static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index eff800053c34..a08da09ed1a5 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -346,13 +346,13 @@ void iSeries_get_boot_time(struct rtc_time *tm) #define RTAS_CLOCK_BUSY (-2) void pSeries_get_boot_time(struct rtc_time *rtc_tm) { - unsigned long ret[8]; + int ret[8]; int error, wait_time; unsigned long max_wait_tb; max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { wait_time = rtas_extended_busy_delay_time(error); /* This is boot time so we spin. */ @@ -381,13 +381,13 @@ void pSeries_get_boot_time(struct rtc_time *rtc_tm) */ void pSeries_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long ret[8]; + int ret[8]; int error, wait_time; unsigned long max_wait_tb; max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { if (in_interrupt()) { printk(KERN_WARNING "error: reading clock would delay interrupt\n"); diff --git a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c index 60e755132685..8f61669ad61a 100644 --- a/arch/ppc64/kernel/scanlog.c +++ b/arch/ppc64/kernel/scanlog.c @@ -49,7 +49,7 @@ static ssize_t scanlog_read(struct file *file, char *buf, struct inode * inode = file->f_dentry->d_inode; struct proc_dir_entry *dp; unsigned int *data; - unsigned long status; + int status; unsigned long len, off; unsigned int wait_time; @@ -81,11 +81,11 @@ static ssize_t scanlog_read(struct file *file, char *buf, spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, - __pa(rtas_data_buf), count); + (u32) __pa(rtas_data_buf), (u32) count); memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); - DEBUG("status=%ld, data[0]=%x, data[1]=%x, data[2]=%x\n", + DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n", status, data[0], data[1], data[2]); switch (status) { case SCANLOG_COMPLETE: @@ -133,7 +133,7 @@ static ssize_t scanlog_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { char stkbuf[20]; - unsigned long status; + int status; if (count > 19) count = 19; if (copy_from_user (stkbuf, buf, count)) { @@ -144,8 +144,8 @@ static ssize_t scanlog_write(struct file * file, const char * buf, if (buf) { if (strncmp(stkbuf, "reset", 5) == 0) { DEBUG("reset scanlog\n"); - status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, NULL, 0); - DEBUG("rtas returns %ld\n", status); + status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0); + DEBUG("rtas returns %d\n", status); } else if (strncmp(stkbuf, "debugon", 7) == 0) { printk(KERN_ERR "scanlog: debug on\n"); scanlog_debug = 1; diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index aec2d763e9f9..32b4db84bf19 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -164,7 +164,7 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { #if defined(CONFIG_SMP) && defined(CONFIG_PPC_PSERIES) - unsigned int ret, i; + int ret, i; #endif #ifdef CONFIG_XMON_DEFAULT @@ -232,12 +232,11 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_SMP /* Start secondary threads on SMT systems */ for (i = 0; i < NR_CPUS; i++) { - if(cpu_available(i) && !cpu_possible(i)) { + if (cpu_available(i) && !cpu_possible(i)) { printk("%16.16x : starting thread\n", i); - rtas_call(rtas_token("start-cpu"), 3, 1, - (void *)&ret, + rtas_call(rtas_token("start-cpu"), 3, 1, &ret, get_hard_smp_processor_id(i), - *((unsigned long *)pseries_secondary_smp_init), + (u32)*((unsigned long *)pseries_secondary_smp_init), i); cpu_set(i, cpu_possible_map); systemcfg->processorCount++; diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 7fa0e5a105b2..0a341cf1e75c 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -241,7 +241,7 @@ static void __devinit smp_openpic_setup_cpu(int cpu) */ static int query_cpu_stopped(unsigned int pcpu) { - long cpu_status; + int cpu_status; int status, qcss_tok; qcss_tok = rtas_token("query-cpu-stopped-state"); diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index 4de4982f58f3..15d38c53cd64 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c @@ -172,9 +172,9 @@ static struct rtas_error_log *FWNMI_get_errinfo(struct pt_regs *regs) */ static void FWNMI_release_errinfo(void) { - unsigned long ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL); + int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL); if (ret != 0) - printk("FWNMI: nmi-interlock failed: %ld\n", ret); + printk("FWNMI: nmi-interlock failed: %d\n", ret); } #endif diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 32adc8c22953..35785ac01f06 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -275,7 +275,7 @@ static int get_irq_server(unsigned int irq) static void xics_enable_irq(unsigned int virq) { unsigned int irq; - long call_status; + int call_status; unsigned int server; irq = virt_irq_to_real(irq_offset_down(virq)); @@ -287,7 +287,7 @@ static void xics_enable_irq(unsigned int virq) DEFAULT_PRIORITY); if (call_status != 0) { printk(KERN_ERR "xics_enable_irq: irq=%x: ibm_set_xive " - "returned %lx\n", irq, call_status); + "returned %x\n", irq, call_status); return; } @@ -295,14 +295,14 @@ static void xics_enable_irq(unsigned int virq) call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); if (call_status != 0) { printk(KERN_ERR "xics_enable_irq: irq=%x: ibm_int_on " - "returned %lx\n", irq, call_status); + "returned %x\n", irq, call_status); return; } } static void xics_disable_real_irq(unsigned int irq) { - long call_status; + int call_status; unsigned int server; if (irq == XICS_IPI) @@ -311,7 +311,7 @@ static void xics_disable_real_irq(unsigned int irq) call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if (call_status != 0) { printk(KERN_ERR "xics_disable_real_irq: irq=%x: " - "ibm_int_off returned %lx\n", irq, call_status); + "ibm_int_off returned %x\n", irq, call_status); return; } @@ -320,7 +320,7 @@ static void xics_disable_real_irq(unsigned int irq) call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff); if (call_status != 0) { printk(KERN_ERR "xics_disable_irq: irq=%x: ibm_set_xive(0xff)" - " returned %lx\n", irq, call_status); + " returned %x\n", irq, call_status); return; } } @@ -612,8 +612,8 @@ void xics_request_IPIs(void) static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) { unsigned int irq; - long status; - unsigned long xics_status[2]; + int status; + int xics_status[2]; unsigned long newmask; cpumask_t tmp = CPU_MASK_NONE; @@ -621,11 +621,11 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) if (irq == XICS_IPI || irq == NO_IRQ) return; - status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { printk(KERN_ERR "xics_set_affinity: irq=%d ibm,get-xive " - "returns %ld\n", irq, status); + "returns %d\n", irq, status); return; } @@ -644,7 +644,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) if (status) { printk(KERN_ERR "xics_set_affinity irq=%d ibm,set-xive " - "returns %ld\n", irq, status); + "returns %d\n", irq, status); return; } } @@ -655,10 +655,10 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) void xics_migrate_irqs_away(void) { int set_indicator = rtas_token("set-indicator"); - const unsigned long giqs = 9005UL; /* Global Interrupt Queue Server */ - unsigned long status = 0; + const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */ + int status = 0; unsigned int irq, cpu = smp_processor_id(); - unsigned long xics_status[2]; + int xics_status[2]; unsigned long flags; BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE); @@ -669,7 +669,7 @@ void xics_migrate_irqs_away(void) /* Refuse any new interrupts... */ rtas_call(set_indicator, 3, 1, &status, giqs, - hard_smp_processor_id(), 0UL); + hard_smp_processor_id(), 0); WARN_ON(status != 0); /* Allow IPIs again... */ @@ -692,11 +692,10 @@ void xics_migrate_irqs_away(void) spin_lock_irqsave(&desc->lock, flags); - status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, - irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { printk(KERN_ERR "migrate_irqs_away: irq=%d " - "ibm,get-xive returns %ld\n", + "ibm,get-xive returns %d\n", irq, status); goto unlock; } @@ -719,7 +718,7 @@ void xics_migrate_irqs_away(void) irq, xics_status[0], xics_status[1]); if (status) printk(KERN_ERR "migrate_irqs_away irq=%d " - "ibm,set-xive returns %ld\n", + "ibm,set-xive returns %d\n", irq, status); unlock: diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index c39e115975c0..fdc158a0c658 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h @@ -25,7 +25,7 @@ #define LONG_MSW(X) (((unsigned long)X) >> 32) typedef u32 phandle; -typedef void *ihandle; +typedef u32 ihandle; typedef u32 phandle32; typedef u32 ihandle32; diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h index e51ebb166d12..4ce9bddc62a2 100644 --- a/include/asm-ppc64/rtas.h +++ b/include/asm-ppc64/rtas.h @@ -37,7 +37,7 @@ * Where n_in is the number of input parameters and * n_out is the number of output parameters * - * If the "string" is invalid on this system, RTAS_UNKOWN_SERVICE + * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE * will be returned as a token. rtas_call() does look for this * token and error out gracefully so rtas_call(rtas_token("str"), ...) * may be safely used for one-shot calls to RTAS. @@ -168,7 +168,7 @@ extern struct rtas_t rtas; extern void enter_rtas(unsigned long); extern int rtas_token(const char *service); -extern long rtas_call(int token, int, int, unsigned long *, ...); +extern int rtas_call(int token, int, int, int *, ...); extern void call_rtas_display_status(char); extern void rtas_restart(char *cmd); extern void rtas_power_off(void); -- cgit v1.2.3 From a7834704c546ba087b5bf20f993b8083488bc595 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 23 Jun 2004 19:55:09 -0700 Subject: [PATCH] sparse: trivial drivers/char/* annotation and format fixes - trivial annotation in several places in drivers/mtd - a bunch of debugging printks switched from %x to %llx (they get 64bit values) - in doc200[01].c fixed type of (unused) last argument in their doc_read_ecc(). --- drivers/mtd/chips/cfi_cmdset_0001.c | 4 ++-- drivers/mtd/chips/cfi_cmdset_0002.c | 8 +++---- drivers/mtd/chips/cfi_cmdset_0020.c | 8 +++---- drivers/mtd/devices/doc2000.c | 12 +++++++---- drivers/mtd/devices/doc2001.c | 13 ++++++++---- drivers/mtd/mtd_blkdevs.c | 2 +- drivers/mtd/mtdchar.c | 42 +++++++++++++++++-------------------- include/linux/mtd/mtd.h | 2 +- 8 files changed, 48 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 18cc31d39752..e1be7178b70e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -378,7 +378,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr chip->state = FL_ERASING; chip->oldstate = FL_READY; printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%x\n", status); + "suspended: status = 0x%llx\n", status); return -EIO; } @@ -963,7 +963,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, So we must check here and reset those bits if they're set. Otherwise we're just pissing in the wind */ if (status & CMD(0x30)) { - printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %x). Clearing.\n", status); + printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %llx). Clearing.\n", status); cfi_write(map, CMD(0x50), cmd_adr); cfi_write(map, CMD(0x70), cmd_adr); } diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index df3309048290..cb5fcfcac9f5 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -509,7 +509,7 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned chip->state = FL_WRITING; adr += chip->start; - DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n", + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8llx)\n", __func__, adr, datum ); ENABLE_VPP(map); @@ -645,7 +645,7 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, datum, prev_oldstatus, prev_status, oldstatus, status); @@ -971,7 +971,7 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip) __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, ones, prev_oldstatus, prev_status, oldstatus, status); @@ -1151,7 +1151,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, ones, prev_oldstatus, prev_status, oldstatus, status); diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 98e58b426140..074f6905991d 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -489,7 +489,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, /* Urgh. Chip not yet ready to talk to us. */ if (time_after(jiffies, timeo)) { spin_unlock_bh(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %x, status = %x\n", + printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %x, status = %llx\n", status, cfi_read(map, cmd_adr)); return -EIO; } @@ -859,7 +859,7 @@ retry: if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1145,7 +1145,7 @@ retry: if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1294,7 +1294,7 @@ retry: if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 5cb921d2197a..ee961c661f9d 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -53,9 +53,11 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -601,7 +603,8 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, } static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel) + size_t * retlen, u_char * buf, u_char * eccbuf, + struct nand_oobinfo *unused) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; unsigned long docptr; @@ -750,7 +753,8 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf, - u_char * eccbuf, int oobsel) + u_char * eccbuf, + struct nand_oobinfo *unused) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 25eea68ad774..223e29189050 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -37,9 +37,12 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); + static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -407,7 +410,8 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, } static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused) { int i, ret; volatile char dummy; @@ -533,7 +537,8 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, } static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused) { int i,ret = 0; volatile char dummy; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 4a0f2ea7c286..e45b3fc99fde 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -220,7 +220,7 @@ static int blktrans_ioctl(struct inode *inode, struct file *file, return ret; g.start = get_start_sect(inode->i_bdev); - if (copy_to_user((void *)arg, &g, sizeof(g))) + if (copy_to_user((void __user *)arg, &g, sizeof(g))) return -EFAULT; return 0; } /* else */ diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 801bcc8f08d4..b1a9257b9b75 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -116,7 +116,7 @@ static int mtd_close(struct inode *inode, struct file *file) */ #define MAX_KMALLOC_SIZE 0x20000 -static ssize_t mtd_read(struct file *file, char *buf, size_t count,loff_t *ppos) +static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; size_t retlen=0; @@ -169,7 +169,7 @@ static ssize_t mtd_read(struct file *file, char *buf, size_t count,loff_t *ppos) return total_retlen; } /* mtd_read */ -static ssize_t mtd_write(struct file *file, const char *buf, size_t count,loff_t *ppos) +static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; char *kbuf; @@ -238,6 +238,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; + void __user *argp = (void __user *)arg; int ret = 0; u_long size; @@ -245,17 +246,17 @@ static int mtd_ioctl(struct inode *inode, struct file *file, size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (cmd & IOC_IN) { - ret = verify_area(VERIFY_READ, (char *)arg, size); + ret = verify_area(VERIFY_READ, argp, size); if (ret) return ret; } if (cmd & IOC_OUT) { - ret = verify_area(VERIFY_WRITE, (char *)arg, size); + ret = verify_area(VERIFY_WRITE, argp, size); if (ret) return ret; } switch (cmd) { case MEMGETREGIONCOUNT: - if (copy_to_user((int *) arg, &(mtd->numeraseregions), sizeof(int))) + if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) return -EFAULT; break; @@ -263,24 +264,19 @@ static int mtd_ioctl(struct inode *inode, struct file *file, { struct region_info_user ur; - if (copy_from_user( &ur, - (struct region_info_user *)arg, - sizeof(struct region_info_user))) { + if (copy_from_user(&ur, argp, sizeof(struct region_info_user))) return -EFAULT; - } if (ur.regionindex >= mtd->numeraseregions) return -EINVAL; - if (copy_to_user((struct mtd_erase_region_info *) arg, - &(mtd->eraseregions[ur.regionindex]), + if (copy_to_user(argp, &(mtd->eraseregions[ur.regionindex]), sizeof(struct mtd_erase_region_info))) return -EFAULT; break; } case MEMGETINFO: - if (copy_to_user((struct mtd_info *)arg, mtd, - sizeof(struct mtd_info_user))) + if (copy_to_user(argp, mtd, sizeof(struct mtd_info_user))) return -EFAULT; break; @@ -301,7 +297,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, init_waitqueue_head(&waitq); memset (erase,0,sizeof(struct erase_info)); - if (copy_from_user(&erase->addr, (u_long *)arg, + if (copy_from_user(&erase->addr, argp, 2 * sizeof(u_long))) { kfree(erase); return -EFAULT; @@ -345,7 +341,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, if(!(file->f_mode & 2)) return -EPERM; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) @@ -354,7 +350,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, if (!mtd->write_oob) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length); + ret = verify_area(VERIFY_READ, buf.ptr, buf.length); if (ret) return ret; @@ -370,7 +366,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf); - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) + if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; kfree(databuf); @@ -384,7 +380,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, void *databuf; ssize_t retlen; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) @@ -393,7 +389,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, if (!mtd->read_oob) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length); + ret = verify_area(VERIFY_WRITE, buf.ptr, buf.length); if (ret) return ret; @@ -404,7 +400,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) + if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) ret = -EFAULT; @@ -417,7 +413,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, { unsigned long adrs[2]; - if (copy_from_user(adrs ,(void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(adrs, argp, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->lock) @@ -431,7 +427,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, { unsigned long adrs[2]; - if (copy_from_user(adrs, (void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(adrs, argp, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->unlock) @@ -443,7 +439,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, case MEMSETOOBSEL: { - if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo))) + if (copy_from_user(&mtd->oobinfo, argp, sizeof(struct nand_oobinfo))) return -EFAULT; break; } diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9ac94aaabd3f..d186585b73a4 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -22,7 +22,7 @@ struct erase_info_user { struct mtd_oob_buf { u_int32_t start; u_int32_t length; - unsigned char *ptr; + unsigned char __user *ptr; }; #define MTD_CHAR_MAJOR 90 -- cgit v1.2.3 From 02bf2dff8319319fc93e199c5df5997c28addf6d Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 23 Jun 2004 19:56:05 -0700 Subject: [PATCH] sparse: trivial i2o annotations --- drivers/message/i2o/i2o_block.c | 7 +++--- drivers/message/i2o/i2o_config.c | 49 ++++++++++++++++++++-------------------- include/linux/i2o-dev.h | 26 ++++++++++----------- 3 files changed, 42 insertions(+), 40 deletions(-) (limited to 'include') diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 63e67b3b19be..36dc0e9d1b4a 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -861,6 +861,7 @@ static int i2ob_ioctl(struct inode *inode, struct file *file, { struct gendisk *disk = inode->i_bdev->bd_disk; struct i2ob_device *dev = disk->private_data; + void __user *argp = (void __user *)arg; /* Anyone capable of this syscall can do *real bad* things */ @@ -873,13 +874,13 @@ static int i2ob_ioctl(struct inode *inode, struct file *file, i2o_block_biosparam(get_capacity(disk), &g.cylinders, &g.heads, &g.sectors); g.start = get_start_sect(inode->i_bdev); - return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0; + return copy_to_user(argp, &g, sizeof(g))?-EFAULT:0; } case BLKI2OGRSTRAT: - return put_user(dev->rcache, (int *)arg); + return put_user(dev->rcache, (int __user *)argp); case BLKI2OGWSTRAT: - return put_user(dev->wcache, (int *)arg); + return put_user(dev->wcache, (int __user *)argp); case BLKI2OSRSTRAT: if(arg<0||arg>CACHE_SMARTFETCH) return -EINVAL; diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index aabfddbf278e..773096305b2f 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -194,7 +194,7 @@ struct i2o_handler cfg_handler= 0xffffffff // All classes }; -static ssize_t cfg_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t cfg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { printk(KERN_INFO "i2o_config write not yet supported\n"); @@ -202,7 +202,7 @@ static ssize_t cfg_write(struct file *file, const char *buf, size_t count, loff_ } -static ssize_t cfg_read(struct file *file, char *buf, size_t count, loff_t *ptr) +static ssize_t cfg_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { return 0; } @@ -278,7 +278,7 @@ static int cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, int ioctl_getiops(unsigned long arg) { - u8 *user_iop_table = (u8*)arg; + u8 __user *user_iop_table = (void __user *)arg; struct i2o_controller *c = NULL; int i; u8 foo[MAX_I2O_CONTROLLERS]; @@ -314,7 +314,7 @@ int ioctl_getiops(unsigned long arg) int ioctl_gethrt(unsigned long arg) { struct i2o_controller *c; - struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; + struct i2o_cmd_hrtlct __user *cmd = (void __user *)arg; struct i2o_cmd_hrtlct kcmd; i2o_hrt *hrt; int len; @@ -353,7 +353,7 @@ int ioctl_gethrt(unsigned long arg) int ioctl_getlct(unsigned long arg) { struct i2o_controller *c; - struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; + struct i2o_cmd_hrtlct __user *cmd = (void __user *)arg; struct i2o_cmd_hrtlct kcmd; i2o_lct *lct; int len; @@ -390,7 +390,7 @@ static int ioctl_parms(unsigned long arg, unsigned int type) { int ret = 0; struct i2o_controller *c; - struct i2o_cmd_psetget *cmd = (struct i2o_cmd_psetget*)arg; + struct i2o_cmd_psetget __user *cmd = (void __user *)arg; struct i2o_cmd_psetget kcmd; u32 reslen; u8 *ops; @@ -460,7 +460,7 @@ static int ioctl_parms(unsigned long arg, unsigned int type) int ioctl_html(unsigned long arg) { - struct i2o_html *cmd = (struct i2o_html*)arg; + struct i2o_html __user *cmd = (void __user *)arg; struct i2o_html kcmd; struct i2o_controller *c; u8 *res = NULL; @@ -573,7 +573,7 @@ int ioctl_html(unsigned long arg) int ioctl_swdl(unsigned long arg) { struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; unsigned char maxfrag = 0, curfrag = 1; unsigned char *buffer; u32 msg[9]; @@ -642,7 +642,7 @@ int ioctl_swdl(unsigned long arg) int ioctl_swul(unsigned long arg) { struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; unsigned char maxfrag = 0, curfrag = 1; unsigned char *buffer; u32 msg[9]; @@ -709,7 +709,8 @@ int ioctl_swul(unsigned long arg) int ioctl_swdel(unsigned long arg) { struct i2o_controller *c; - struct i2o_sw_xfer kxfer, *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer kxfer; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; u32 msg[7]; unsigned int swlen; int token; @@ -776,7 +777,7 @@ int ioctl_validate(unsigned long arg) static int ioctl_evt_reg(unsigned long arg, struct file *fp) { u32 msg[5]; - struct i2o_evt_id *pdesc = (struct i2o_evt_id *)arg; + struct i2o_evt_id __user *pdesc = (void __user *)arg; struct i2o_evt_id kdesc; struct i2o_controller *iop; struct i2o_device *d; @@ -813,7 +814,7 @@ static int ioctl_evt_get(unsigned long arg, struct file *fp) { u32 id = (u32)fp->private_data; struct i2o_cfg_info *p = NULL; - struct i2o_evt_get *uget = (struct i2o_evt_get*)arg; + struct i2o_evt_get __user *uget = (void __user *)arg; struct i2o_evt_get kget; unsigned long flags; @@ -842,21 +843,21 @@ static int ioctl_evt_get(unsigned long arg, struct file *fp) static int ioctl_passthru(unsigned long arg) { - struct i2o_cmd_passthru *cmd = (struct i2o_cmd_passthru *) arg; + struct i2o_cmd_passthru __user *cmd = (void __user *) arg; struct i2o_controller *c; u32 msg[MSG_FRAME_SIZE]; - u32 *user_msg = (u32*)cmd->msg; + u32 __user *user_msg; u32 *reply = NULL; - u32 *user_reply = NULL; + u32 __user *user_reply = NULL; u32 size = 0; u32 reply_size = 0; u32 rcode = 0; - ulong sg_list[SG_TABLESIZE]; + void *sg_list[SG_TABLESIZE]; u32 sg_offset = 0; u32 sg_count = 0; int sg_index = 0; u32 i = 0; - ulong p = 0; + void *p = 0; unsigned int iop; if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) @@ -877,7 +878,7 @@ static int ioctl_passthru(unsigned long arg) size *= 4; // Convert to bytes /* Copy in the user's I2O command */ - if(copy_from_user((void*)msg, (void*)user_msg, size)) + if(copy_from_user(msg, user_msg, size)) return -EFAULT; if(get_user(reply_size, &user_reply[0]) < 0) return -EFAULT; @@ -920,7 +921,7 @@ static int ioctl_passthru(unsigned long arg) } sg_size = sg[i].flag_count & 0xffffff; /* Allocate memory for the transfer */ - p = (ulong)kmalloc(sg_size, GFP_KERNEL); + p = kmalloc(sg_size, GFP_KERNEL); if (!p) { printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", c->name,sg_size,i,sg_count); rcode = -ENOMEM; @@ -930,14 +931,14 @@ static int ioctl_passthru(unsigned long arg) /* Copy in the user's SG buffer if necessary */ if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { // TODO 64bit fix - if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) { + if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) { printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",c->name,i); rcode = -EFAULT; goto cleanup; } } //TODO 64bit fix - sg[i].addr_bus = (u32)virt_to_bus((void*)p); + sg[i].addr_bus = (u32)virt_to_bus(p); } } @@ -962,7 +963,7 @@ static int ioctl_passthru(unsigned long arg) size = size>>16; size *= 4; /* Copy in the user's I2O command */ - if (copy_from_user ((void*)msg, (void*)user_msg, size)) { + if (copy_from_user (msg, user_msg, size)) { rcode = -EFAULT; goto cleanup; } @@ -975,8 +976,8 @@ static int ioctl_passthru(unsigned long arg) if (!(sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { sg_size = sg[j].flag_count & 0xffffff; // TODO 64bit fix - if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) { - printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",c->name, sg_list[j], sg[j].addr_bus); + if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) { + printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",c->name, sg_list[j], sg[j].addr_bus); rcode = -EFAULT; goto cleanup; } diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h index c79f39745b6d..9ef82bf1a45d 100644 --- a/include/linux/i2o-dev.h +++ b/include/linux/i2o-dev.h @@ -46,24 +46,24 @@ struct i2o_cmd_passthru { unsigned int iop; /* IOP unit number */ - void *msg; /* message */ + void __user *msg; /* message */ }; struct i2o_cmd_hrtlct { unsigned int iop; /* IOP unit number */ - void *resbuf; /* Buffer for result */ - unsigned int *reslen; /* Buffer length in bytes */ + void __user *resbuf; /* Buffer for result */ + unsigned int __user *reslen; /* Buffer length in bytes */ }; struct i2o_cmd_psetget { unsigned int iop; /* IOP unit number */ unsigned int tid; /* Target device TID */ - void *opbuf; /* Operation List buffer */ + void __user *opbuf; /* Operation List buffer */ unsigned int oplen; /* Operation List buffer length in bytes */ - void *resbuf; /* Result List buffer */ - unsigned int *reslen; /* Result List buffer length in bytes */ + void __user *resbuf; /* Result List buffer */ + unsigned int __user *reslen; /* Result List buffer length in bytes */ }; struct i2o_sw_xfer @@ -72,10 +72,10 @@ struct i2o_sw_xfer unsigned char flags; /* Flags field */ unsigned char sw_type; /* Software type */ unsigned int sw_id; /* Software ID */ - void *buf; /* Pointer to software buffer */ - unsigned int *swlen; /* Length of software data */ - unsigned int *maxfrag; /* Maximum fragment count */ - unsigned int *curfrag; /* Current fragment count */ + void __user *buf; /* Pointer to software buffer */ + unsigned int __user *swlen; /* Length of software data */ + unsigned int __user *maxfrag; /* Maximum fragment count */ + unsigned int __user *curfrag; /* Current fragment count */ }; struct i2o_html @@ -83,9 +83,9 @@ struct i2o_html unsigned int iop; /* IOP unit number */ unsigned int tid; /* Target device ID */ unsigned int page; /* HTML page */ - void *resbuf; /* Buffer for reply HTML page */ - unsigned int *reslen; /* Length in bytes of reply buffer */ - void *qbuf; /* Pointer to HTTP query string */ + void __user *resbuf; /* Buffer for reply HTML page */ + unsigned int __user *reslen; /* Length in bytes of reply buffer */ + void __user *qbuf; /* Pointer to HTTP query string */ unsigned int qlen; /* Length in bytes of query string buffer */ }; -- cgit v1.2.3 From 37dfe554fba17e8e1f156a26a231a393a11adcc9 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 23 Jun 2004 19:56:16 -0700 Subject: [PATCH] sparse: scsi ->ioctl() annotation Low-level drivers' ->ioctl() gets a userland pointer from scsi_ioctl(); prototype annotated, so is scsi_debug instance. --- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/scsi_debug.h | 2 +- include/scsi/scsi_host.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 4067ba593d9c..b9509840a87e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -484,7 +484,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); } -static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void *arg) +static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) { if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd); diff --git a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h index a6c6ec91216a..965dd5e760c1 100644 --- a/drivers/scsi/scsi_debug.h +++ b/drivers/scsi/scsi_debug.h @@ -7,7 +7,7 @@ static int scsi_debug_slave_configure(struct scsi_device *); static void scsi_debug_slave_destroy(struct scsi_device *); static int scsi_debug_queuecommand(struct scsi_cmnd *, void (*done) (struct scsi_cmnd *)); -static int scsi_debug_ioctl(struct scsi_device *, int, void *); +static int scsi_debug_ioctl(struct scsi_device *, int, void __user *); static int scsi_debug_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]); static int scsi_debug_abort(struct scsi_cmnd *); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index abba7b4194b7..21af949cfa58 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -64,7 +64,7 @@ struct scsi_host_template { * * Status: OPTIONAL */ - int (* ioctl)(struct scsi_device *dev, int cmd, void *arg); + int (* ioctl)(struct scsi_device *dev, int cmd, void __user *arg); /* * The queuecommand function is used to queue up a scsi -- cgit v1.2.3 From e0db58edac3f394d910ec43fc1bcc3cc530ddc45 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 23 Jun 2004 20:02:51 -0700 Subject: [PATCH] ide: split task_sectors() and task_multi_sectors() - split __task_sectors() out of task_sectors() - add bio and buffer versions of task[_multi]_sectors() - use task_bio_sectors() instead of task_sectors() in pdc4030.c - move task[_buffer]_sectors() to ide-taskfile.c - uninline task[_multi]_sectors() Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Linus Torvalds --- drivers/ide/ide-taskfile.c | 45 +++++++++++++++++++++++++++++++++++++++++--- drivers/ide/legacy/pdc4030.c | 4 ++-- include/linux/ide.h | 36 +++++++++++++---------------------- 3 files changed, 57 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 93c62856244c..bc085c017cee 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -288,6 +288,27 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive) EXPORT_SYMBOL(task_no_data_intr); +static inline void task_buffer_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) +{ + char *buf = rq->buffer + blk_rq_offset(rq); + + process_that_request_first(rq, nsect); + __task_sectors(drive, buf, nsect, rw); +} + +static inline void task_buffer_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) +{ + unsigned int msect = drive->mult_count, nsect; + + nsect = rq->current_nr_sectors; + if (nsect > msect) + nsect = msect; + + task_buffer_sectors(drive, rq, nsect, rw); +} + /* * old taskfile PIO handlers, to be killed as soon as possible. */ @@ -512,8 +533,17 @@ EXPORT_SYMBOL(task_mulout_intr); #else /* !CONFIG_IDE_TASKFILE_IO */ -static inline void task_multi_sectors(ide_drive_t *drive, - struct request *rq, int rw) +static void task_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) +{ + if (rq->cbio) /* fs request */ + task_bio_sectors(drive, rq, nsect, rw); + else /* task request */ + task_buffer_sectors(drive, rq, nsect, rw); +} + +static inline void task_bio_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) { unsigned int nsect, msect = drive->mult_count; @@ -523,7 +553,7 @@ static inline void task_multi_sectors(ide_drive_t *drive, if (nsect > msect) nsect = msect; - task_sectors(drive, rq, nsect, rw); + task_bio_sectors(drive, rq, nsect, rw); if (!rq->nr_sectors) msect = 0; @@ -532,6 +562,15 @@ static inline void task_multi_sectors(ide_drive_t *drive, } while (msect); } +static void task_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) +{ + if (rq->cbio) /* fs request */ + task_bio_multi_sectors(drive, rq, rw); + else /* task request */ + task_buffer_multi_sectors(drive, rq, rw); +} + static u8 wait_drive_not_busy(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); diff --git a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c index 73e833d0f9b0..c07d341d1c74 100644 --- a/drivers/ide/legacy/pdc4030.c +++ b/drivers/ide/legacy/pdc4030.c @@ -355,7 +355,7 @@ read_next: #endif /* DEBUG_READ */ #ifdef CONFIG_IDE_TASKFILE_IO - task_sectors(drive, rq, nsect, IDE_PIO_IN); + task_bio_sectors(drive, rq, nsect, IDE_PIO_IN); /* FIXME: can we check status after transfer on pdc4030? */ /* Complete previously submitted bios. */ @@ -478,7 +478,7 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int msect) if (nsect > msect) nsect = msect; - task_sectors(drive, rq, nsect, IDE_PIO_OUT); + task_bio_sectors(drive, rq, nsect, IDE_PIO_OUT); if (!rq->nr_sectors) msect = 0; diff --git a/include/linux/ide.h b/include/linux/ide.h index 5ae165606a7c..cddbcdd99479 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1415,42 +1415,32 @@ extern void atapi_output_bytes(ide_drive_t *, void *, u32); extern void taskfile_input_data(ide_drive_t *, void *, u32); extern void taskfile_output_data(ide_drive_t *, void *, u32); -#ifdef CONFIG_IDE_TASKFILE_IO - #define IDE_PIO_IN 0 #define IDE_PIO_OUT 1 -static inline void task_sectors(ide_drive_t *drive, struct request *rq, - unsigned nsect, int rw) +static inline void __task_sectors(ide_drive_t *drive, char *buf, + unsigned nsect, unsigned rw) { - unsigned long flags; - unsigned int bio_rq; - char *buf; - - /* - * bio_rq flag is needed because we can call - * rq_unmap_buffer() with rq->cbio == NULL - */ - bio_rq = rq->cbio ? 1 : 0; - - if (bio_rq) - buf = rq_map_buffer(rq, &flags); /* fs request */ - else - buf = rq->buffer + blk_rq_offset(rq); /* task request */ - /* * IRQ can happen instantly after reading/writing * last sector of the datablock. */ - process_that_request_first(rq, nsect); - if (rw == IDE_PIO_OUT) taskfile_output_data(drive, buf, nsect * SECTOR_WORDS); else taskfile_input_data(drive, buf, nsect * SECTOR_WORDS); +} + +#ifdef CONFIG_IDE_TASKFILE_IO +static inline void task_bio_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) +{ + unsigned long flags; + char *buf = rq_map_buffer(rq, &flags); - if (bio_rq) - rq_unmap_buffer(buf, &flags); + process_that_request_first(rq, nsect); + __task_sectors(drive, buf, nsect, rw); + rq_unmap_buffer(buf, &flags); } #endif /* CONFIG_IDE_TASKFILE_IO */ -- cgit v1.2.3 From 2677a4df4899708b3b886ce155ee86553716fd9c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 23 Jun 2004 20:03:13 -0700 Subject: [PATCH] ide: use task_buffer[_multi]_sectors() in ide-taskfile.c - update rq counters directly in task_buffer_sectors() - use task_buffer[_multi]_sectors() in taskfile PIO handlers (CONFIG_IDE_TASKFILE_IO=n and flagged ones) so: (a) rq->hard_cur_sectors is used for rq mapping (b) in case of error valid rq->sector is reported (c) we can s/rq->current_nr_sectors/rq->nr_sectors/ later - uninline task_buffer_sectors() - remove not needed !rq->bio code from ide_[un]map_buffer() (it is used only for fs requests which are always bio based) - remove no longer needed task_rq_offset() Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Linus Torvalds --- drivers/ide/ide-taskfile.c | 102 +++++++++++---------------------------------- include/linux/ide.h | 20 +-------- 2 files changed, 26 insertions(+), 96 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 71adc04289b8..bc5f4530f963 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -288,12 +288,14 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive) EXPORT_SYMBOL(task_no_data_intr); -static inline void task_buffer_sectors(ide_drive_t *drive, struct request *rq, - unsigned nsect, unsigned rw) +static void task_buffer_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) { char *buf = rq->buffer + blk_rq_offset(rq); - process_that_request_first(rq, nsect); + rq->sector += nsect; + rq->current_nr_sectors -= nsect; + rq->nr_sectors -= nsect; __task_sectors(drive, buf, nsect, rw); } @@ -321,7 +323,6 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); - char *pBuf = NULL; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { @@ -334,11 +335,10 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) } } - pBuf = rq->buffer + task_rq_offset(rq); - taskfile_input_data(drive, pBuf, SECTOR_WORDS); + task_buffer_sectors(drive, rq, 1, IDE_PIO_IN); /* FIXME: check drive status */ - if (--rq->current_nr_sectors <= 0) + if (!rq->current_nr_sectors) if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); @@ -354,9 +354,6 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect = drive->mult_count; - unsigned int nsect; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { @@ -368,21 +365,14 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive) return ide_started; } - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - pBuf = rq->buffer + task_rq_offset(rq); - taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->current_nr_sectors -= nsect; - msect -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_IN); + + /* FIXME: check drive status */ + if (!rq->current_nr_sectors) { + DRIVER(drive)->end_request(drive, 1, 0); + return ide_stopped; + } - /* FIXME: check drive status */ - if (!rq->current_nr_sectors) { - if (!DRIVER(drive)->end_request(drive, 1, 0)) - return ide_stopped; - } - } while (msect); ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); return ide_started; } @@ -405,8 +395,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) return startstop; } /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, rq->buffer + task_rq_offset(rq), SECTOR_WORDS); - rq->current_nr_sectors--; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); return ide_started; } @@ -421,7 +410,6 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) { @@ -435,10 +423,7 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { - rq = HWGROUP(drive)->rq; - pBuf = rq->buffer + task_rq_offset(rq); - taskfile_output_data(drive, pBuf, SECTOR_WORDS); - rq->current_nr_sectors--; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); } ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); return ide_started; @@ -485,9 +470,6 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect = drive->mult_count; - unsigned int nsect; if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) { if (stat & (ERR_STAT|DRQ_STAT)) { @@ -512,15 +494,7 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive) spin_unlock_irqrestore(&ide_lock, lflags); } - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - pBuf = rq->buffer + task_rq_offset(rq); - msect -= nsect; - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->current_nr_sectors -= nsect; - } while (msect); + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); return ide_started; @@ -1327,7 +1301,6 @@ ide_startstop_t flagged_task_in_intr (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; int retries = 5; if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { @@ -1343,10 +1316,9 @@ ide_startstop_t flagged_task_in_intr (ide_drive_t *drive) return DRIVER(drive)->error(drive, "flagged_task_in_intr (unexpected data phase)", stat); } - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - taskfile_input_data(drive, pBuf, SECTOR_WORDS); + task_buffer_sectors(drive, rq, 1, IDE_PIO_IN); - if (--rq->current_nr_sectors != 0) { + if (rq->current_nr_sectors) { /* * (ks) We don't know which command was executed. * So, we wait the 'WORSTCASE' value. @@ -1370,11 +1342,7 @@ ide_startstop_t flagged_task_mulin_intr (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; int retries = 5; - unsigned int msect, nsect; - - msect = drive->mult_count; if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (stat & ERR_STAT) { @@ -1389,11 +1357,8 @@ ide_startstop_t flagged_task_mulin_intr (ide_drive_t *drive) return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (unexpected data phase)", stat); } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); + task_buffer_multi_sectors(drive, rq, IDE_PIO_IN); - rq->current_nr_sectors -= nsect; if (rq->current_nr_sectors != 0) { /* * (ks) We don't know which command was executed. @@ -1427,8 +1392,7 @@ ide_startstop_t flagged_pre_task_out_intr (ide_drive_t *drive, struct request *r return startstop; } - taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); - --rq->current_nr_sectors; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); return ide_started; } @@ -1438,7 +1402,6 @@ ide_startstop_t flagged_task_out_intr (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) return DRIVER(drive)->error(drive, "flagged_task_out_intr", stat); @@ -1458,9 +1421,7 @@ ide_startstop_t flagged_task_out_intr (ide_drive_t *drive) return DRIVER(drive)->error(drive, "flagged_task_out_intr (unexpected data phase)", stat); } - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - taskfile_output_data(drive, pBuf, SECTOR_WORDS); - --rq->current_nr_sectors; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); /* * (ks) We don't know which command was executed. @@ -1473,11 +1434,7 @@ ide_startstop_t flagged_task_out_intr (ide_drive_t *drive) ide_startstop_t flagged_pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) { - char *pBuf = NULL; ide_startstop_t startstop; - unsigned int msect, nsect; - - msect = drive->mult_count; if (ide_wait_stat(&startstop, drive, DATA_READY, BAD_W_STAT, WAIT_DRQ)) { @@ -1485,11 +1442,7 @@ ide_startstop_t flagged_pre_task_mulout_intr (ide_drive_t *drive, struct request return startstop; } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - - rq->current_nr_sectors -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); return ide_started; } @@ -1499,10 +1452,6 @@ ide_startstop_t flagged_task_mulout_intr (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect, nsect; - - msect = drive->mult_count; if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) return DRIVER(drive)->error(drive, "flagged_task_mulout_intr", stat); @@ -1522,10 +1471,7 @@ ide_startstop_t flagged_task_mulout_intr (ide_drive_t *drive) return DRIVER(drive)->error(drive, "flagged_task_mulout_intr (unexpected data phase)", stat); } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->current_nr_sectors -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); /* * (ks) We don't know which command was executed. diff --git a/include/linux/ide.h b/include/linux/ide.h index cddbcdd99479..fe54e41439c8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -833,30 +833,14 @@ typedef struct ide_dma_ops_s { #define ide_rq_offset(rq) \ (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) -/* - * taskfiles really should use hard_cur_sectors as well! - */ -#define task_rq_offset(rq) \ - (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE) - static inline void *ide_map_buffer(struct request *rq, unsigned long *flags) { - /* - * fs request - */ - if (rq->bio) - return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); - - /* - * task request - */ - return rq->buffer + task_rq_offset(rq); + return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); } static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags) { - if (rq->bio) - bio_kunmap_irq(buffer, flags); + bio_kunmap_irq(buffer, flags); } #endif /* !CONFIG_IDE_TASKFILE_IO */ -- cgit v1.2.3 From e6a9fb1e419766d81102ae3be8afae9b8cf8f91e Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 23 Jun 2004 20:17:59 -0700 Subject: [PATCH] symlink 1/9: infrastructure and explanation This patch-kit gets past the limit on nested symlinks, without incompatible API changes _and_ with killing code duplication in most of the readlink/follow_link pairs. And no, it's not the old ->getlink() crap - procfs et.al. are not special-cased there. Here's how it works: * ->follow_link() still does what it used to do - replaces vfsmount/dentry in the nameidata it got from caller. However, it can also leave a pathname to be resolved by caller. * we add an array of char * into nameidata; we always work with nd->saved_names[current->link_count]. nd_set_link() sets it, nd_get_link() returns it. * callers of ->follow_link() (all two of them) check if ->follow_link() had left us something to do. If it had (return value was zero and nd_get_link() is non-NULL), they do __vfs_follow_link() on that name. Then they call a new method (->put_link()) that frees whatever has to be freed, etc. Note that absolute majority of symlinks have "resolve a pathname" as part of their ->follow_link(); they can do something else and some don't do that at all, but having that pathname resolution is very, very common. With that change we allow them to shift pathname resolution part to caller. They don't have to - it's perfectly OK to do all work in ->follow_link(). However, leaving the pathname resolution to caller will a) exclude foo_follow_link() stack frame from the picture b) kill 2 stack frames - all callers are in fs/namei.c and they can use inlined variant of vfs_follow_link(). That reduction of stack use is enough to push the limit on nested symlinks from 5 to 8 (actually, even beyond that, but since 8 is common for other Unices it will do fine). For those who have "pure" ->follow_link() (i.e. "find a string that would be symlink contents and say nd_set_link(nd, string)") we also get a common helper implementing ->readlink() - it just calls ->follow_link() on a dummy nameidata, calls vfs_readlink() on result of nd_get_link() and does ->put_link(). Using (or not using) it is up to filesystem; it's a helper that can be used as a ->readlink() for many filesystems, not a reimplementation of sys_readlink(). However, that's _MANY_ filesystems - practically all of them. Note that we don't put any crap like "if this is a normal symlink, do this; otherwise call ->follow_link() and let it do its magic" into callers - all symlinks are handled the same way. Which was the main problem with getlink proposal back then. That covers almost everything; the only cases left are nfs, ncpfs and cifs. Those will go later - we are backwards compatible, so it's not a problem. First patch: infrastructure - helpers allowing ->follow_link() to leave a pathname to be traversed by caller + corresponding code in callers. --- fs/namei.c | 29 ++++++++++++++++++++++++++--- include/linux/fs.h | 1 + include/linux/namei.h | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/fs/namei.c b/fs/namei.c index efaaf1dd1d7d..a46fa1526812 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -395,6 +395,8 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s return result; } +static inline int __vfs_follow_link(struct nameidata *, const char *); + /* * This limits recursive symlink follows to 8, while * limiting consecutive symlinks to 40. @@ -405,19 +407,30 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) { int err = -ELOOP; - if (current->link_count >= 5) + if (current->link_count >= MAX_NESTED_LINKS) goto loop; if (current->total_link_count >= 40) goto loop; + BUG_ON(nd->depth >= MAX_NESTED_LINKS); cond_resched(); err = security_inode_follow_link(dentry, nd); if (err) goto loop; current->link_count++; current->total_link_count++; + nd->depth++; touch_atime(nd->mnt, dentry); + nd_set_link(nd, NULL); err = dentry->d_inode->i_op->follow_link(dentry, nd); + if (!err) { + char *s = nd_get_link(nd); + if (s) + err = __vfs_follow_link(nd, s); + if (dentry->d_inode->i_op->put_link) + dentry->d_inode->i_op->put_link(dentry, nd); + } current->link_count--; + nd->depth--; return err; loop: path_release(nd); @@ -587,7 +600,7 @@ int fastcall link_path_walk(const char * name, struct nameidata *nd) goto return_reval; inode = nd->dentry->d_inode; - if (current->link_count) + if (nd->depth) lookup_flags = LOOKUP_FOLLOW; /* At this point we know we have a real path component. */ @@ -795,6 +808,7 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) */ nd_root.last_type = LAST_ROOT; nd_root.flags = nd->flags; + nd_root.depth = 0; memcpy(&nd_root.intent, &nd->intent, sizeof(nd_root.intent)); read_lock(¤t->fs->lock); nd_root.mnt = mntget(current->fs->rootmnt); @@ -867,6 +881,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags; + nd->depth = 0; read_lock(¤t->fs->lock); if (*name=='/') { @@ -1385,7 +1400,15 @@ do_link: if (error) goto exit_dput; touch_atime(nd->mnt, dentry); + nd_set_link(nd, NULL); error = dentry->d_inode->i_op->follow_link(dentry, nd); + if (!error) { + char *s = nd_get_link(nd); + if (s) + error = __vfs_follow_link(nd, s); + if (dentry->d_inode->i_op->put_link) + dentry->d_inode->i_op->put_link(dentry, nd); + } dput(dentry); if (error) return error; @@ -2182,7 +2205,7 @@ __vfs_follow_link(struct nameidata *nd, const char *link) } res = link_path_walk(link, nd); out: - if (current->link_count || res || nd->last_type!=LAST_NORM) + if (nd->depth || res || nd->last_type!=LAST_NORM) return res; /* * If it is an iterative symlinks resolution in open_namei() we diff --git a/include/linux/fs.h b/include/linux/fs.h index 88337ed4f4f2..3ba1ac6cbb37 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -902,6 +902,7 @@ struct inode_operations { struct inode *, struct dentry *); int (*readlink) (struct dentry *, char __user *,int); int (*follow_link) (struct dentry *, struct nameidata *); + void (*put_link) (struct dentry *, struct nameidata *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int, struct nameidata *); int (*setattr) (struct dentry *, struct iattr *); diff --git a/include/linux/namei.h b/include/linux/namei.h index 4117cd90a345..adcafdec8ee7 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -10,12 +10,16 @@ struct open_intent { int create_mode; }; +enum { MAX_NESTED_LINKS = 5 }; + struct nameidata { struct dentry *dentry; struct vfsmount *mnt; struct qstr last; unsigned int flags; int last_type; + unsigned depth; + char *saved_names[MAX_NESTED_LINKS + 1]; /* Intent data */ union { @@ -67,4 +71,14 @@ extern int follow_up(struct vfsmount **, struct dentry **); extern struct dentry *lock_rename(struct dentry *, struct dentry *); extern void unlock_rename(struct dentry *, struct dentry *); +static inline void nd_set_link(struct nameidata *nd, char *path) +{ + nd->saved_names[nd->depth] = path; +} + +static inline char *nd_get_link(struct nameidata *nd) +{ + return nd->saved_names[nd->depth]; +} + #endif /* _LINUX_NAMEI_H */ -- cgit v1.2.3 From 6143b9ad6105471618c195a888b82108f85eeb49 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Wed, 23 Jun 2004 20:18:10 -0700 Subject: [PATCH] symlink 2/9: ext2 conversion and helper functions ext2 conversion (helper functions for that one will be actually used a lot by other filesystems, so to fs/namei.c they go) --- fs/ext2/symlink.c | 18 +++++++----------- fs/namei.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/fs.h | 3 +++ 3 files changed, 57 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index b282670a54bc..4680ea7ecc12 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -19,23 +19,19 @@ #include "ext2.h" #include "xattr.h" - -static int -ext2_readlink(struct dentry *dentry, char __user *buffer, int buflen) -{ - struct ext2_inode_info *ei = EXT2_I(dentry->d_inode); - return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data); -} +#include static int ext2_follow_link(struct dentry *dentry, struct nameidata *nd) { struct ext2_inode_info *ei = EXT2_I(dentry->d_inode); - return vfs_follow_link(nd, (char *)ei->i_data); + nd_set_link(nd, (char *)ei->i_data); + return 0; } struct inode_operations ext2_symlink_inode_operations = { - .readlink = page_readlink, - .follow_link = page_follow_link, + .readlink = generic_readlink, + .follow_link = page_follow_link_light, + .put_link = page_put_link, .setxattr = ext2_setxattr, .getxattr = ext2_getxattr, .listxattr = ext2_listxattr, @@ -43,7 +39,7 @@ struct inode_operations ext2_symlink_inode_operations = { }; struct inode_operations ext2_fast_symlink_inode_operations = { - .readlink = ext2_readlink, + .readlink = generic_readlink, .follow_link = ext2_follow_link, .setxattr = ext2_setxattr, .getxattr = ext2_getxattr, diff --git a/fs/namei.c b/fs/namei.c index a46fa1526812..d75f455ca772 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2189,6 +2189,23 @@ out: return len; } +/* + * A helper for ->readlink(). This should be used *ONLY* for symlinks that + * have ->follow_link() touching nd only in nd_set_link(). Using (or not + * using) it for any given inode is up to filesystem. + */ +int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) +{ + struct nameidata nd; + int res = dentry->d_inode->i_op->follow_link(dentry, &nd); + if (!res) { + res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); + if (dentry->d_inode->i_op->put_link) + dentry->d_inode->i_op->put_link(dentry, &nd); + } + return res; +} + static inline int __vfs_follow_link(struct nameidata *nd, const char *link) { @@ -2265,6 +2282,30 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) return res; } +int page_follow_link_light(struct dentry *dentry, struct nameidata *nd) +{ + struct page *page; + char *s = page_getlink(dentry, &page); + if (!IS_ERR(s)) { + nd_set_link(nd, s); + s = NULL; + } + return PTR_ERR(s); +} + +void page_put_link(struct dentry *dentry, struct nameidata *nd) +{ + if (!IS_ERR(nd_get_link(nd))) { + struct page *page; + page = find_get_page(dentry->d_inode->i_mapping, 0); + if (!page) + BUG(); + kunmap(page); + page_cache_release(page); + page_cache_release(page); + } +} + int page_follow_link(struct dentry *dentry, struct nameidata *nd) { struct page *page = NULL; @@ -2319,8 +2360,9 @@ fail: } struct inode_operations page_symlink_inode_operations = { - .readlink = page_readlink, - .follow_link = page_follow_link, + .readlink = generic_readlink, + .follow_link = page_follow_link_light, + .put_link = page_put_link, }; EXPORT_SYMBOL(__user_walk); @@ -2333,6 +2375,8 @@ EXPORT_SYMBOL(lookup_create); EXPORT_SYMBOL(lookup_hash); EXPORT_SYMBOL(lookup_one_len); EXPORT_SYMBOL(page_follow_link); +EXPORT_SYMBOL(page_follow_link_light); +EXPORT_SYMBOL(page_put_link); EXPORT_SYMBOL(page_readlink); EXPORT_SYMBOL(page_symlink); EXPORT_SYMBOL(page_symlink_inode_operations); @@ -2352,3 +2396,4 @@ EXPORT_SYMBOL(vfs_rename); EXPORT_SYMBOL(vfs_rmdir); EXPORT_SYMBOL(vfs_symlink); EXPORT_SYMBOL(vfs_unlink); +EXPORT_SYMBOL(generic_readlink); diff --git a/include/linux/fs.h b/include/linux/fs.h index 3ba1ac6cbb37..27dda18def71 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1468,8 +1468,11 @@ extern int vfs_readlink(struct dentry *, char __user *, int, const char *); extern int vfs_follow_link(struct nameidata *, const char *); extern int page_readlink(struct dentry *, char __user *, int); extern int page_follow_link(struct dentry *, struct nameidata *); +extern int page_follow_link_light(struct dentry *, struct nameidata *); +extern void page_put_link(struct dentry *, struct nameidata *); extern int page_symlink(struct inode *inode, const char *symname, int len); extern struct inode_operations page_symlink_inode_operations; +extern int generic_readlink(struct dentry *, char __user *, int); extern void generic_fillattr(struct inode *, struct kstat *); extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); void inode_add_bytes(struct inode *inode, loff_t bytes); -- cgit v1.2.3 From a7993279fb7a54aa0beb4159bb1d1ea214372420 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 23 Jun 2004 21:57:36 -0700 Subject: Make bitops/cpumask functions be "const" where appropriate. --- arch/ppc64/kernel/bitops.c | 12 ++++++------ include/asm-ppc64/bitops.h | 6 +++--- include/asm-s390/byteorder.h | 6 +++--- include/linux/byteorder/swab.h | 6 +++--- include/linux/cpumask.h | 14 +++++++------- 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/arch/ppc64/kernel/bitops.c b/arch/ppc64/kernel/bitops.c index 941a3c9bc302..6b24b0219090 100644 --- a/arch/ppc64/kernel/bitops.c +++ b/arch/ppc64/kernel/bitops.c @@ -7,10 +7,10 @@ #include #include -unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; @@ -48,10 +48,10 @@ found_middle: EXPORT_SYMBOL(find_next_zero_bit); -unsigned long find_next_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; @@ -106,10 +106,10 @@ static inline unsigned int ext2_ffz(unsigned int x) return rc; } -unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned int *p = ((unsigned int *)addr) + (offset >> 5); + const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5); unsigned int result = offset & ~31; unsigned int tmp; diff --git a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h index feeeb9b77b29..6d820e7ea772 100644 --- a/include/asm-ppc64/bitops.h +++ b/include/asm-ppc64/bitops.h @@ -288,15 +288,15 @@ static __inline__ int ffs(int x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) -extern unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset); +extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset); #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) -extern unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset); +extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset); #define find_first_bit(addr, size) \ find_next_bit((addr), (size), 0) -extern unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset); +extern unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset); #define find_first_zero_le_bit(addr, size) \ find_next_zero_le_bit((addr), (size), 0) diff --git a/include/asm-s390/byteorder.h b/include/asm-s390/byteorder.h index 91a6f3893bcd..2cc35a0e188e 100644 --- a/include/asm-s390/byteorder.h +++ b/include/asm-s390/byteorder.h @@ -14,7 +14,7 @@ #ifdef __GNUC__ #ifdef __s390x__ -static __inline__ __u64 ___arch__swab64p(__u64 *x) +static __inline__ __u64 ___arch__swab64p(const __u64 *x) { __u64 result; @@ -40,7 +40,7 @@ static __inline__ void ___arch__swab64s(__u64 *x) } #endif /* __s390x__ */ -static __inline__ __u32 ___arch__swab32p(__u32 *x) +static __inline__ __u32 ___arch__swab32p(const __u32 *x) { __u32 result; @@ -77,7 +77,7 @@ static __inline__ void ___arch__swab32s(__u32 *x) *x = ___arch__swab32p(x); } -static __inline__ __u16 ___arch__swab16p(__u16 *x) +static __inline__ __u16 ___arch__swab16p(const __u16 *x) { __u16 result; diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h index 02ad0b5246e9..2f1cb775125a 100644 --- a/include/linux/byteorder/swab.h +++ b/include/linux/byteorder/swab.h @@ -134,7 +134,7 @@ static __inline__ __attribute_const__ __u16 __fswab16(__u16 x) { return __arch__swab16(x); } -static __inline__ __u16 __swab16p(__u16 *x) +static __inline__ __u16 __swab16p(const __u16 *x) { return __arch__swab16p(x); } @@ -147,7 +147,7 @@ static __inline__ __attribute_const__ __u32 __fswab32(__u32 x) { return __arch__swab32(x); } -static __inline__ __u32 __swab32p(__u32 *x) +static __inline__ __u32 __swab32p(const __u32 *x) { return __arch__swab32p(x); } @@ -167,7 +167,7 @@ static __inline__ __attribute_const__ __u64 __fswab64(__u64 x) return __arch__swab64(x); # endif } -static __inline__ __u64 __swab64p(__u64 *x) +static __inline__ __u64 __swab64p(const __u64 *x) { return __arch__swab64p(x); } diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 1d06e38480f7..ecca23548b64 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -171,19 +171,19 @@ static inline int __cpus_subset(cpumask_t *src1p, } #define cpus_empty(src) __cpus_empty(&(src), NR_CPUS) -static inline int __cpus_empty(cpumask_t *srcp, int nbits) +static inline int __cpus_empty(const cpumask_t *srcp, int nbits) { return bitmap_empty(srcp->bits, nbits); } #define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS) -static inline int __cpus_full(cpumask_t *srcp, int nbits) +static inline int __cpus_full(const cpumask_t *srcp, int nbits) { return bitmap_full(srcp->bits, nbits); } #define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS) -static inline int __cpus_weight(cpumask_t *srcp, int nbits) +static inline int __cpus_weight(const cpumask_t *srcp, int nbits) { return bitmap_weight(srcp->bits, nbits); } @@ -191,7 +191,7 @@ static inline int __cpus_weight(cpumask_t *srcp, int nbits) #define cpus_shift_right(dst, src, n) \ __cpus_shift_right(&(dst), &(src), (n), NR_CPUS) static inline void __cpus_shift_right(cpumask_t *dstp, - cpumask_t *srcp, int n, int nbits) + const cpumask_t *srcp, int n, int nbits) { bitmap_shift_right(dstp->bits, srcp->bits, n, nbits); } @@ -199,19 +199,19 @@ static inline void __cpus_shift_right(cpumask_t *dstp, #define cpus_shift_left(dst, src, n) \ __cpus_shift_left(&(dst), &(src), (n), NR_CPUS) static inline void __cpus_shift_left(cpumask_t *dstp, - cpumask_t *srcp, int n, int nbits) + const cpumask_t *srcp, int n, int nbits) { bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); } #define first_cpu(src) __first_cpu(&(src), NR_CPUS) -static inline int __first_cpu(cpumask_t *srcp, int nbits) +static inline int __first_cpu(const cpumask_t *srcp, int nbits) { return find_first_bit(srcp->bits, nbits); } #define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS) -static inline int __next_cpu(int n, cpumask_t *srcp, int nbits) +static inline int __next_cpu(int n, const cpumask_t *srcp, int nbits) { return find_next_bit(srcp->bits, nbits, n+1); } -- cgit v1.2.3 From 5de575871da0837cfa80fbbad6a7624a783000d3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 24 Jun 2004 20:26:12 -0700 Subject: [SPARC64]: Make find_next_bit take a const pointer. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- arch/sparc64/lib/find_bit.c | 5 +++-- include/asm-sparc64/bitops.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/arch/sparc64/lib/find_bit.c b/arch/sparc64/lib/find_bit.c index 420dfbafdfa4..5852614492bb 100644 --- a/arch/sparc64/lib/find_bit.c +++ b/arch/sparc64/lib/find_bit.c @@ -6,9 +6,10 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset) +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h index d32c138437c3..f13765454689 100644 --- a/include/asm-sparc64/bitops.h +++ b/include/asm-sparc64/bitops.h @@ -204,7 +204,8 @@ static __inline__ unsigned int hweight8(unsigned int w) * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -extern unsigned long find_next_bit(unsigned long *, unsigned long, unsigned long); +extern unsigned long find_next_bit(const unsigned long *, unsigned long, + unsigned long); /** * find_first_bit - find the first set bit in a memory region -- cgit v1.2.3 From b0101c19f4bad6a0406ca061944a68dd453ac20f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 24 Jun 2004 20:27:24 -0700 Subject: [SPARC64]: Make ___arch_swapXp() take a const pointer. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/asm-sparc64/byteorder.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/byteorder.h b/include/asm-sparc64/byteorder.h index f8c370d26b3a..c69b08af5fe0 100644 --- a/include/asm-sparc64/byteorder.h +++ b/include/asm-sparc64/byteorder.h @@ -7,7 +7,7 @@ #ifdef __GNUC__ -static __inline__ __u16 ___arch__swab16p(__u16 *addr) +static __inline__ __u16 ___arch__swab16p(const __u16 *addr) { __u16 ret; @@ -17,7 +17,7 @@ static __inline__ __u16 ___arch__swab16p(__u16 *addr) return ret; } -static __inline__ __u32 ___arch__swab32p(__u32 *addr) +static __inline__ __u32 ___arch__swab32p(const __u32 *addr) { __u32 ret; @@ -27,7 +27,7 @@ static __inline__ __u32 ___arch__swab32p(__u32 *addr) return ret; } -static __inline__ __u64 ___arch__swab64p(__u64 *addr) +static __inline__ __u64 ___arch__swab64p(const __u64 *addr) { __u64 ret; -- cgit v1.2.3 From 953a66b9fb5126a0e310506d45563b145cbae692 Mon Sep 17 00:00:00 2001 From: "Andries E. Brouwer" Date: Thu, 24 Jun 2004 21:06:18 -0700 Subject: [PATCH] isofs fixes This fixes two things. On the one hand we have the old "cruft" mount option, that sometimes was enabled automatically, for ridiculously large files or CDROMs. But what was ridiculous ten years ago, no longer is. So, only decide that something is cruft when the user said so. On the other hand, sometimes we get negative sizes. That is caused by assignments inode->i_size = isonum_733(), where the latter was declared integer. I made it unsigned int, as the standard also does. (Someone with problems replied: >> Could you test the below? > Ok I did, the patch seems to work great! Thanks! ) --- fs/isofs/inode.c | 23 +++-------------------- include/linux/iso_fs.h | 12 ++++++------ 2 files changed, 9 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 9d498e25107f..491dcde30a0e 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1265,31 +1265,14 @@ static void isofs_read_inode(struct inode * inode) inode->i_size = isonum_733 (de->size); } - /* - * The ISO-9660 filesystem only stores 32 bits for file size. - * mkisofs handles files up to 2GB-2 = 2147483646 = 0x7FFFFFFE bytes - * in size. This is according to the large file summit paper from 1996. - * WARNING: ISO-9660 filesystems > 1 GB and even > 2 GB are fully - * legal. Do not prevent to use DVD's schilling@fokus.gmd.de - */ - if ((inode->i_size < 0 || inode->i_size > 0x7FFFFFFE) && - sbi->s_cruft == 'n') { - printk(KERN_WARNING "Warning: defective CD-ROM. " - "Enabling \"cruft\" mount option.\n"); - sbi->s_cruft = 'y'; - } - /* * Some dipshit decided to store some other bit of information - * in the high byte of the file length. Catch this and holler. - * WARNING: this will make it impossible for a file to be > 16MB - * on the CDROM. + * in the high byte of the file length. Truncate size in case + * this CDROM was mounted with the cruft option. */ - if (sbi->s_cruft == 'y' && - inode->i_size & 0xff000000) { + if (sbi->s_cruft == 'y') inode->i_size &= 0x00ffffff; - } if (de->interleave[0]) { printk("Interleaved files not (yet) supported.\n"); diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h index 15b07d37e2e5..23cdbf83cb16 100644 --- a/include/linux/iso_fs.h +++ b/include/linux/iso_fs.h @@ -190,28 +190,28 @@ static inline int isonum_712(char *p) { return *(s8 *)p; } -static inline int isonum_721(char *p) +static inline unsigned int isonum_721(char *p) { return le16_to_cpu(get_unaligned((u16 *)p)); } -static inline int isonum_722(char *p) +static inline unsigned int isonum_722(char *p) { return be16_to_cpu(get_unaligned((u16 *)p)); } -static inline int isonum_723(char *p) +static inline unsigned int isonum_723(char *p) { /* Ignore bigendian datum due to broken mastering programs */ return le16_to_cpu(get_unaligned((u16 *)p)); } -static inline int isonum_731(char *p) +static inline unsigned int isonum_731(char *p) { return le32_to_cpu(get_unaligned((u32 *)p)); } -static inline int isonum_732(char *p) +static inline unsigned int isonum_732(char *p) { return be32_to_cpu(get_unaligned((u32 *)p)); } -static inline int isonum_733(char *p) +static inline unsigned int isonum_733(char *p) { /* Ignore bigendian datum due to broken mastering programs */ return le32_to_cpu(get_unaligned((u32 *)p)); -- cgit v1.2.3 From 5eca30da4874cfed2c8acdf7aa031a72c5a5b1eb Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 25 Jun 2004 00:54:20 -0700 Subject: [PATCH] v850: guard declaration of handle_IRQ_event with #ifdef !__ASSEMBLY__ Signed-off-by: Miles Bader Signed-off-by: Linus Torvalds --- include/asm-v850/irq.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-v850/irq.h b/include/asm-v850/irq.h index 90c83aa053c8..44431152b36d 100644 --- a/include/asm-v850/irq.h +++ b/include/asm-v850/irq.h @@ -1,8 +1,8 @@ /* * include/asm-v850/irq.h -- Machine interrupt handling * - * Copyright (C) 2001,02 NEC Corporation - * Copyright (C) 2001,02 Miles Bader + * Copyright (C) 2001,02,04 NEC Electronics Corporation + * Copyright (C) 2001,02,04 Miles Bader * * 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 @@ -62,11 +62,8 @@ extern void disable_irq (unsigned int irq); /* Disable an irq without waiting. */ extern void disable_irq_nosync (unsigned int irq); +extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); #endif /* !__ASSEMBLY__ */ -struct irqaction; -struct pt_regs; -int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); - #endif /* __V850_IRQ_H__ */ -- cgit v1.2.3 From 10d8131a70773fd9e0fbfb67822c8fba4d14c829 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 25 Jun 2004 00:54:42 -0700 Subject: [PATCH] v850: add find_next_bit [Since many archs use the same implementation of find_next_bit, it might be nice to have `generic_find_next_bit' or something.] Signed-off-by: Miles Bader Signed-off-by: Linus Torvalds --- include/asm-v850/bitops.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'include') diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h index c837ea08c611..5ca65390186b 100644 --- a/include/asm-v850/bitops.h +++ b/include/asm-v850/bitops.h @@ -193,10 +193,86 @@ extern __inline__ int find_next_zero_bit (void *addr, int size, int offset) return result + ffz (tmp); } + +/* This is the same as generic_ffs, but we can't use that because it's + inline and the #include order mucks things up. */ +static inline int generic_ffs_for_find_next_bit(int x) +{ + int r = 1; + + if (!x) + return 0; + if (!(x & 0xffff)) { + x >>= 16; + r += 16; + } + if (!(x & 0xff)) { + x >>= 8; + r += 8; + } + if (!(x & 0xf)) { + x >>= 4; + r += 4; + } + if (!(x & 3)) { + x >>= 2; + r += 2; + } + if (!(x & 1)) { + x >>= 1; + r += 1; + } + return r; +} + +/* + * Find next one bit in a bitmap reasonably efficiently. + */ +static __inline__ unsigned long find_next_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31UL; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *p++; + tmp &= ~0UL << offset; + if (size < 32) + goto found_first; + if (tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = *p++) != 0) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (32 - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + generic_ffs_for_find_next_bit(tmp); +} + + #define ffs(x) generic_ffs (x) #define fls(x) generic_fls (x) #define __ffs(x) ffs(x) + /* * This is just `generic_ffs' from , except that it assumes * that at least one bit is set, and returns the real index of the bit -- cgit v1.2.3 From d53d6fe42d30d6882bdc1f0dfd27e8f026a85167 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 25 Jun 2004 00:54:53 -0700 Subject: [PATCH] v850: remove bogus __ARCH_WANT_ macro defs Signed-off-by: Miles Bader Signed-off-by: Linus Torvalds --- include/asm-v850/unistd.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h index f8163e806b59..9517031d8fd1 100644 --- a/include/asm-v850/unistd.h +++ b/include/asm-v850/unistd.h @@ -1,8 +1,8 @@ /* * include/asm-v850/unistd.h -- System call numbers and invocation mechanism * - * Copyright (C) 2001,02,03 NEC Electronics Corporation - * Copyright (C) 2001,02,03 Miles Bader + * Copyright (C) 2001,02,03,04 NEC Electronics Corporation + * Copyright (C) 2001,02,03,04 Miles Bader * * 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 @@ -389,7 +389,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ #ifdef __KERNEL__ #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME @@ -404,7 +403,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ #define __ARCH_WANT_SYS_GETPGRP #define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK -- cgit v1.2.3 From f6a7507c1714f5cb4faaebc76a1d02260830be01 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 25 Jun 2004 19:06:27 -0700 Subject: [PATCH] ppc32: fix compilation PPC has an out of line and exported abs() that gives lots of nice and wierd compilation erorrs. Also kill the duplicate cpu_online() in asm-ppc/smp.h. --- arch/ppc/kernel/ppc_ksyms.c | 3 --- include/asm-ppc/smp.h | 2 -- include/asm-ppc/system.h | 1 - 3 files changed, 6 deletions(-) (limited to 'include') diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 9bd46c140822..2d3e630a702d 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -68,7 +68,6 @@ extern int sys_sigreturn(struct pt_regs *regs); long long __ashrdi3(long long, int); long long __ashldi3(long long, int); long long __lshrdi3(long long, int); -int abs(int); extern unsigned long mm_ptov (unsigned long paddr); @@ -276,8 +275,6 @@ EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memchr); -EXPORT_SYMBOL(abs); - #if defined(CONFIG_FB_VGA16_MODULE) EXPORT_SYMBOL(screen_info); #endif diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 803fdb583348..4bd15cbdcfaf 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -47,8 +47,6 @@ extern void smp_local_timer_interrupt(struct pt_regs *); #define smp_processor_id() (current_thread_info()->cpu) -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - extern int __cpu_up(unsigned int cpu); extern int smp_hw_index[]; diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index fdccd739c2d7..e49964652b50 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -82,7 +82,6 @@ extern int fix_alignment(struct pt_regs *); extern void cvt_fd(float *from, double *to, unsigned long *fpscr); extern void cvt_df(double *from, float *to, unsigned long *fpscr); extern int call_rtas(const char *, int, int, unsigned long *, ...); -extern int abs(int); extern void cacheable_memzero(void *p, unsigned int nb); extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); -- cgit v1.2.3