diff options
Diffstat (limited to 'arch/mips')
68 files changed, 1251 insertions, 844 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 14af6cce2fa2..1443024b1c7c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -425,9 +425,8 @@ config MOMENCO_OCELOT_G | |||
| 425 | select SWAP_IO_SPACE | 425 | select SWAP_IO_SPACE |
| 426 | select SYS_HAS_CPU_RM7000 | 426 | select SYS_HAS_CPU_RM7000 |
| 427 | select SYS_SUPPORTS_32BIT_KERNEL | 427 | select SYS_SUPPORTS_32BIT_KERNEL |
| 428 | select SYS_SUPPORTS_64BIT_KERNEL | 428 | select SYS_SUPPORTS_64BIT_KERNEL if BROKEN |
| 429 | select SYS_SUPPORTS_BIG_ENDIAN | 429 | select SYS_SUPPORTS_BIG_ENDIAN |
| 430 | select ARCH_SPARSEMEM_ENABLE | ||
| 431 | help | 430 | help |
| 432 | The Ocelot is a MIPS-based Single Board Computer (SBC) made by | 431 | The Ocelot is a MIPS-based Single Board Computer (SBC) made by |
| 433 | Momentum Computer <http://www.momenco.com/>. | 432 | Momentum Computer <http://www.momenco.com/>. |
| @@ -560,6 +559,7 @@ config SGI_IP27 | |||
| 560 | select SYS_SUPPORTS_64BIT_KERNEL | 559 | select SYS_SUPPORTS_64BIT_KERNEL |
| 561 | select SYS_SUPPORTS_BIG_ENDIAN | 560 | select SYS_SUPPORTS_BIG_ENDIAN |
| 562 | select SYS_SUPPORTS_NUMA | 561 | select SYS_SUPPORTS_NUMA |
| 562 | select SYS_SUPPORTS_SMP | ||
| 563 | help | 563 | help |
| 564 | This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics | 564 | This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics |
| 565 | workstations. To compile a Linux kernel that runs on these, say Y | 565 | workstations. To compile a Linux kernel that runs on these, say Y |
| @@ -1633,9 +1633,6 @@ config ARCH_DISCONTIGMEM_ENABLE | |||
| 1633 | 1633 | ||
| 1634 | config ARCH_SPARSEMEM_ENABLE | 1634 | config ARCH_SPARSEMEM_ENABLE |
| 1635 | bool | 1635 | bool |
| 1636 | |||
| 1637 | config ARCH_SPARSEMEM_ENABLE | ||
| 1638 | bool | ||
| 1639 | select SPARSEMEM_STATIC | 1636 | select SPARSEMEM_STATIC |
| 1640 | 1637 | ||
| 1641 | config NUMA | 1638 | config NUMA |
| @@ -1690,6 +1687,7 @@ config NR_CPUS | |||
| 1690 | depends on SMP | 1687 | depends on SMP |
| 1691 | default "64" if SGI_IP27 | 1688 | default "64" if SGI_IP27 |
| 1692 | default "2" | 1689 | default "2" |
| 1690 | default "8" if MIPS_MT_SMTC | ||
| 1693 | help | 1691 | help |
| 1694 | This allows you to specify the maximum number of CPUs which this | 1692 | This allows you to specify the maximum number of CPUs which this |
| 1695 | kernel will support. The maximum supported value is 32 for 32-bit | 1693 | kernel will support. The maximum supported value is 32 for 32-bit |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 641aa30b3638..d580d46f967b 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -63,7 +63,9 @@ cflags-y += -mabi=64 | |||
| 63 | ifdef CONFIG_BUILD_ELF64 | 63 | ifdef CONFIG_BUILD_ELF64 |
| 64 | cflags-y += $(call cc-option,-mno-explicit-relocs) | 64 | cflags-y += $(call cc-option,-mno-explicit-relocs) |
| 65 | else | 65 | else |
| 66 | cflags-y += $(call cc-option,-msym32) | 66 | # -msym32 can not be used for modules since they are loaded into XKSEG |
| 67 | CFLAGS_MODULE += $(call cc-option,-mno-explicit-relocs) | ||
| 68 | CFLAGS_KERNEL += $(call cc-option,-msym32) | ||
| 67 | endif | 69 | endif |
| 68 | endif | 70 | endif |
| 69 | 71 | ||
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index b4b010a2fe36..6fce60af005d 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c | |||
| @@ -47,7 +47,7 @@ extern int prom_argc; | |||
| 47 | extern char **prom_argv, **prom_envp; | 47 | extern char **prom_argv, **prom_envp; |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | char * prom_getcmdline(void) | 50 | char * __init_or_module prom_getcmdline(void) |
| 51 | { | 51 | { |
| 52 | return &(arcs_cmdline[0]); | 52 | return &(arcs_cmdline[0]); |
| 53 | } | 53 | } |
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 377ae0d8ff00..919172db560c 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | #include <asm/mach-au1x00/au1000.h> | 43 | #include <asm/mach-au1x00/au1000.h> |
| 44 | #include <asm/time.h> | 44 | #include <asm/time.h> |
| 45 | 45 | ||
| 46 | extern char * __init prom_getcmdline(void); | 46 | extern char * prom_getcmdline(void); |
| 47 | extern void __init board_setup(void); | 47 | extern void __init board_setup(void); |
| 48 | extern void au1000_restart(char *); | 48 | extern void au1000_restart(char *); |
| 49 | extern void au1000_halt(void); | 49 | extern void au1000_halt(void); |
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 94f09194d63d..fa1c62f05515 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c | |||
| @@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ | |||
| 53 | int no_au1xxx_32khz; | 53 | int no_au1xxx_32khz; |
| 54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ | 54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ |
| 55 | 55 | ||
| 56 | /* Cycle counter value at the previous timer interrupt.. */ | ||
| 57 | static unsigned int timerhi = 0, timerlo = 0; | ||
| 58 | |||
| 59 | #ifdef CONFIG_PM | 56 | #ifdef CONFIG_PM |
| 60 | #if HZ < 100 || HZ > 1000 | 57 | #if HZ < 100 || HZ > 1000 |
| 61 | #error "unsupported HZ value! Must be in [100,1000]" | 58 | #error "unsupported HZ value! Must be in [100,1000]" |
| @@ -82,7 +79,6 @@ unsigned long wtimer; | |||
| 82 | void mips_timer_interrupt(void) | 79 | void mips_timer_interrupt(void) |
| 83 | { | 80 | { |
| 84 | int irq = 63; | 81 | int irq = 63; |
| 85 | unsigned long count; | ||
| 86 | 82 | ||
| 87 | irq_enter(); | 83 | irq_enter(); |
| 88 | kstat_this_cpu.irqs[irq]++; | 84 | kstat_this_cpu.irqs[irq]++; |
| @@ -91,10 +87,6 @@ void mips_timer_interrupt(void) | |||
| 91 | goto null; | 87 | goto null; |
| 92 | 88 | ||
| 93 | do { | 89 | do { |
| 94 | count = read_c0_count(); | ||
| 95 | timerhi += (count < timerlo); /* Wrap around */ | ||
| 96 | timerlo = count; | ||
| 97 | |||
| 98 | kstat_this_cpu.irqs[irq]++; | 90 | kstat_this_cpu.irqs[irq]++; |
| 99 | do_timer(1); | 91 | do_timer(1); |
| 100 | #ifndef CONFIG_SMP | 92 | #ifndef CONFIG_SMP |
| @@ -231,7 +223,6 @@ wakeup_counter0_set(int ticks) | |||
| 231 | */ | 223 | */ |
| 232 | unsigned long cal_r4koff(void) | 224 | unsigned long cal_r4koff(void) |
| 233 | { | 225 | { |
| 234 | unsigned long count; | ||
| 235 | unsigned long cpu_speed; | 226 | unsigned long cpu_speed; |
| 236 | unsigned long flags; | 227 | unsigned long flags; |
| 237 | unsigned long counter; | 228 | unsigned long counter; |
| @@ -258,7 +249,7 @@ unsigned long cal_r4koff(void) | |||
| 258 | 249 | ||
| 259 | #if defined(CONFIG_AU1000_USE32K) | 250 | #if defined(CONFIG_AU1000_USE32K) |
| 260 | { | 251 | { |
| 261 | unsigned long start, end; | 252 | unsigned long start, end, count; |
| 262 | 253 | ||
| 263 | start = au_readl(SYS_RTCREAD); | 254 | start = au_readl(SYS_RTCREAD); |
| 264 | start += 2; | 255 | start += 2; |
| @@ -282,7 +273,6 @@ unsigned long cal_r4koff(void) | |||
| 282 | #else | 273 | #else |
| 283 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * | 274 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * |
| 284 | AU1000_SRC_CLK; | 275 | AU1000_SRC_CLK; |
| 285 | count = cpu_speed / 2; | ||
| 286 | #endif | 276 | #endif |
| 287 | } | 277 | } |
| 288 | else { | 278 | else { |
| @@ -291,98 +281,15 @@ unsigned long cal_r4koff(void) | |||
| 291 | * NOTE: some old silicon doesn't allow reading the PLL. | 281 | * NOTE: some old silicon doesn't allow reading the PLL. |
| 292 | */ | 282 | */ |
| 293 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; | 283 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; |
| 294 | count = cpu_speed / 2; | ||
| 295 | no_au1xxx_32khz = 1; | 284 | no_au1xxx_32khz = 1; |
| 296 | } | 285 | } |
| 297 | mips_hpt_frequency = count; | 286 | mips_hpt_frequency = cpu_speed; |
| 298 | // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) | 287 | // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) |
| 299 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); | 288 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); |
| 300 | spin_unlock_irqrestore(&time_lock, flags); | 289 | spin_unlock_irqrestore(&time_lock, flags); |
| 301 | return (cpu_speed / HZ); | 290 | return (cpu_speed / HZ); |
| 302 | } | 291 | } |
| 303 | 292 | ||
| 304 | /* This is for machines which generate the exact clock. */ | ||
| 305 | #define USECS_PER_JIFFY (1000000/HZ) | ||
| 306 | #define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) | ||
| 307 | |||
| 308 | static unsigned long | ||
| 309 | div64_32(unsigned long v1, unsigned long v2, unsigned long v3) | ||
| 310 | { | ||
| 311 | unsigned long r0; | ||
| 312 | do_div64_32(r0, v1, v2, v3); | ||
| 313 | return r0; | ||
| 314 | } | ||
| 315 | |||
| 316 | static unsigned long do_fast_cp0_gettimeoffset(void) | ||
| 317 | { | ||
| 318 | u32 count; | ||
| 319 | unsigned long res, tmp; | ||
| 320 | unsigned long r0; | ||
| 321 | |||
| 322 | /* Last jiffy when do_fast_gettimeoffset() was called. */ | ||
| 323 | static unsigned long last_jiffies=0; | ||
| 324 | unsigned long quotient; | ||
| 325 | |||
| 326 | /* | ||
| 327 | * Cached "1/(clocks per usec)*2^32" value. | ||
| 328 | * It has to be recalculated once each jiffy. | ||
| 329 | */ | ||
| 330 | static unsigned long cached_quotient=0; | ||
| 331 | |||
| 332 | tmp = jiffies; | ||
| 333 | |||
| 334 | quotient = cached_quotient; | ||
| 335 | |||
| 336 | if (tmp && last_jiffies != tmp) { | ||
| 337 | last_jiffies = tmp; | ||
| 338 | if (last_jiffies != 0) { | ||
| 339 | r0 = div64_32(timerhi, timerlo, tmp); | ||
| 340 | quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); | ||
| 341 | cached_quotient = quotient; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | |||
| 345 | /* Get last timer tick in absolute kernel time */ | ||
| 346 | count = read_c0_count(); | ||
| 347 | |||
| 348 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
| 349 | count -= timerlo; | ||
| 350 | |||
| 351 | __asm__("multu\t%1,%2\n\t" | ||
| 352 | "mfhi\t%0" | ||
| 353 | : "=r" (res) | ||
| 354 | : "r" (count), "r" (quotient) | ||
| 355 | : "hi", "lo", GCC_REG_ACCUM); | ||
| 356 | |||
| 357 | /* | ||
| 358 | * Due to possible jiffies inconsistencies, we need to check | ||
| 359 | * the result so that we'll get a timer that is monotonic. | ||
| 360 | */ | ||
| 361 | if (res >= USECS_PER_JIFFY) | ||
| 362 | res = USECS_PER_JIFFY-1; | ||
| 363 | |||
| 364 | return res; | ||
| 365 | } | ||
| 366 | |||
| 367 | #ifdef CONFIG_PM | ||
| 368 | static unsigned long do_fast_pm_gettimeoffset(void) | ||
| 369 | { | ||
| 370 | unsigned long pc0; | ||
| 371 | unsigned long offset; | ||
| 372 | |||
| 373 | pc0 = au_readl(SYS_TOYREAD); | ||
| 374 | au_sync(); | ||
| 375 | offset = pc0 - last_pc0; | ||
| 376 | if (offset > 2*MATCH20_INC) { | ||
| 377 | printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", | ||
| 378 | (unsigned)offset, (unsigned)last_pc0, | ||
| 379 | (unsigned)last_match20, (unsigned)pc0); | ||
| 380 | } | ||
| 381 | offset = (unsigned long)((offset * 305) / 10); | ||
| 382 | return offset; | ||
| 383 | } | ||
| 384 | #endif | ||
| 385 | |||
| 386 | void __init plat_timer_setup(struct irqaction *irq) | 293 | void __init plat_timer_setup(struct irqaction *irq) |
| 387 | { | 294 | { |
| 388 | unsigned int est_freq; | 295 | unsigned int est_freq; |
| @@ -420,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
| 420 | unsigned int c0_status; | 327 | unsigned int c0_status; |
| 421 | 328 | ||
| 422 | printk("WARNING: no 32KHz clock found.\n"); | 329 | printk("WARNING: no 32KHz clock found.\n"); |
| 423 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
| 424 | 330 | ||
| 425 | /* Ensure we get CPO_COUNTER interrupts. | 331 | /* Ensure we get CPO_COUNTER interrupts. |
| 426 | */ | 332 | */ |
| @@ -445,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
| 445 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | 351 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); |
| 446 | startup_match20_interrupt(counter0_irq); | 352 | startup_match20_interrupt(counter0_irq); |
| 447 | 353 | ||
| 448 | do_gettimeoffset = do_fast_pm_gettimeoffset; | ||
| 449 | |||
| 450 | /* We can use the real 'wait' instruction. | 354 | /* We can use the real 'wait' instruction. |
| 451 | */ | 355 | */ |
| 452 | allow_au1k_wait = 1; | 356 | allow_au1k_wait = 1; |
| 453 | } | 357 | } |
| 454 | 358 | ||
| 455 | #else | ||
| 456 | /* We have to do this here instead of in timer_init because | ||
| 457 | * the generic code in arch/mips/kernel/time.c will write | ||
| 458 | * over our function pointer. | ||
| 459 | */ | ||
| 460 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
| 461 | #endif | 359 | #endif |
| 462 | } | 360 | } |
| 463 | 361 | ||
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 4cf0c06e2414..69e424e9ab6f 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c | |||
| @@ -160,11 +160,6 @@ static unsigned int dec_ioasic_hpt_read(void) | |||
| 160 | return ioasic_read(IO_REG_FCTR); | 160 | return ioasic_read(IO_REG_FCTR); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | static void dec_ioasic_hpt_init(unsigned int count) | ||
| 164 | { | ||
| 165 | ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); | ||
| 166 | } | ||
| 167 | |||
| 168 | 163 | ||
| 169 | void __init dec_time_init(void) | 164 | void __init dec_time_init(void) |
| 170 | { | 165 | { |
| @@ -174,11 +169,9 @@ void __init dec_time_init(void) | |||
| 174 | mips_timer_state = dec_timer_state; | 169 | mips_timer_state = dec_timer_state; |
| 175 | mips_timer_ack = dec_timer_ack; | 170 | mips_timer_ack = dec_timer_ack; |
| 176 | 171 | ||
| 177 | if (!cpu_has_counter && IOASIC) { | 172 | if (!cpu_has_counter && IOASIC) |
| 178 | /* For pre-R4k systems we use the I/O ASIC's counter. */ | 173 | /* For pre-R4k systems we use the I/O ASIC's counter. */ |
| 179 | mips_hpt_read = dec_ioasic_hpt_read; | 174 | mips_hpt_read = dec_ioasic_hpt_read; |
| 180 | mips_hpt_init = dec_ioasic_hpt_init; | ||
| 181 | } | ||
| 182 | 175 | ||
| 183 | /* Set up the rate of periodic DS1287 interrupts. */ | 176 | /* Set up the rate of periodic DS1287 interrupts. */ |
| 184 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); | 177 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); |
diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c index 7c930860c921..197ed4c2ba04 100644 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/arch/mips/emma2rh/common/irq_emma2rh.c | |||
| @@ -97,7 +97,7 @@ void emma2rh_irq_init(u32 irq_base) | |||
| 97 | irq_desc[i].status = IRQ_DISABLED; | 97 | irq_desc[i].status = IRQ_DISABLED; |
| 98 | irq_desc[i].action = NULL; | 98 | irq_desc[i].action = NULL; |
| 99 | irq_desc[i].depth = 1; | 99 | irq_desc[i].depth = 1; |
| 100 | irq_desc[i].handler = &emma2rh_irq_controller; | 100 | irq_desc[i].chip = &emma2rh_irq_controller; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | emma2rh_irq_base = irq_base; | 103 | emma2rh_irq_base = irq_base; |
diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c index f23ae9fcffa0..0b36eb001e62 100644 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/arch/mips/emma2rh/markeins/irq_markeins.c | |||
| @@ -86,7 +86,7 @@ void emma2rh_sw_irq_init(u32 irq_base) | |||
| 86 | irq_desc[i].status = IRQ_DISABLED; | 86 | irq_desc[i].status = IRQ_DISABLED; |
| 87 | irq_desc[i].action = NULL; | 87 | irq_desc[i].action = NULL; |
| 88 | irq_desc[i].depth = 2; | 88 | irq_desc[i].depth = 2; |
| 89 | irq_desc[i].handler = &emma2rh_sw_irq_controller; | 89 | irq_desc[i].chip = &emma2rh_sw_irq_controller; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | emma2rh_sw_irq_base = irq_base; | 92 | emma2rh_sw_irq_base = irq_base; |
| @@ -166,7 +166,7 @@ void emma2rh_gpio_irq_init(u32 irq_base) | |||
| 166 | irq_desc[i].status = IRQ_DISABLED; | 166 | irq_desc[i].status = IRQ_DISABLED; |
| 167 | irq_desc[i].action = NULL; | 167 | irq_desc[i].action = NULL; |
| 168 | irq_desc[i].depth = 2; | 168 | irq_desc[i].depth = 2; |
| 169 | irq_desc[i].handler = &emma2rh_gpio_irq_controller; | 169 | irq_desc[i].chip = &emma2rh_gpio_irq_controller; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | emma2rh_gpio_irq_base = irq_base; | 172 | emma2rh_gpio_irq_base = irq_base; |
diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c index 15cc61df3622..11567702b155 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma2rh/markeins/platform.c | |||
| @@ -44,18 +44,45 @@ | |||
| 44 | #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */ | 44 | #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */ |
| 45 | 45 | ||
| 46 | static struct resource i2c_emma_resources_0[] = { | 46 | static struct resource i2c_emma_resources_0[] = { |
| 47 | { NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ }, | 47 | { |
| 48 | { NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 }, | 48 | .name = NULL, |
| 49 | .start = EMMA2RH_IRQ_PIIC0, | ||
| 50 | .end = EMMA2RH_IRQ_PIIC0, | ||
| 51 | .flags = IORESOURCE_IRQ | ||
| 52 | }, { | ||
| 53 | .name = NULL, | ||
| 54 | .start = EMMA2RH_PIIC0_BASE, | ||
| 55 | .end = EMMA2RH_PIIC0_BASE + 0x1000, | ||
| 56 | .flags = 0 | ||
| 57 | }, | ||
| 49 | }; | 58 | }; |
| 50 | 59 | ||
| 51 | struct resource i2c_emma_resources_1[] = { | 60 | struct resource i2c_emma_resources_1[] = { |
| 52 | { NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ }, | 61 | { |
| 53 | { NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 }, | 62 | .name = NULL, |
| 63 | .start = EMMA2RH_IRQ_PIIC1, | ||
| 64 | .end = EMMA2RH_IRQ_PIIC1, | ||
| 65 | .flags = IORESOURCE_IRQ | ||
| 66 | }, { | ||
| 67 | .name = NULL, | ||
| 68 | .start = EMMA2RH_PIIC1_BASE, | ||
| 69 | .end = EMMA2RH_PIIC1_BASE + 0x1000, | ||
| 70 | .flags = 0 | ||
| 71 | }, | ||
| 54 | }; | 72 | }; |
| 55 | 73 | ||
| 56 | struct resource i2c_emma_resources_2[] = { | 74 | struct resource i2c_emma_resources_2[] = { |
| 57 | { NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ }, | 75 | { |
| 58 | { NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 }, | 76 | .name = NULL, |
| 77 | .start = EMMA2RH_IRQ_PIIC2, | ||
| 78 | .end = EMMA2RH_IRQ_PIIC2, | ||
| 79 | .flags = IORESOURCE_IRQ | ||
| 80 | }, { | ||
| 81 | .name = NULL, | ||
| 82 | .start = EMMA2RH_PIIC2_BASE, | ||
| 83 | .end = EMMA2RH_PIIC2_BASE + 0x1000, | ||
| 84 | .flags = 0 | ||
| 85 | }, | ||
| 59 | }; | 86 | }; |
| 60 | 87 | ||
| 61 | struct platform_device i2c_emma_devices[] = { | 88 | struct platform_device i2c_emma_devices[] = { |
| @@ -83,32 +110,29 @@ struct platform_device i2c_emma_devices[] = { | |||
| 83 | #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | 110 | #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
| 84 | 111 | ||
| 85 | static struct plat_serial8250_port platform_serial_ports[] = { | 112 | static struct plat_serial8250_port platform_serial_ports[] = { |
| 86 | [0] = { | 113 | [0] = { |
| 87 | .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), | 114 | .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), |
| 88 | .irq = EMMA2RH_IRQ_PFUR0, | 115 | .irq = EMMA2RH_IRQ_PFUR0, |
| 89 | .uartclk = EMMA2RH_SERIAL_CLOCK, | 116 | .uartclk = EMMA2RH_SERIAL_CLOCK, |
| 90 | .regshift = 4, | 117 | .regshift = 4, |
| 91 | .iotype = UPIO_MEM, | 118 | .iotype = UPIO_MEM, |
| 92 | .flags = EMMA2RH_SERIAL_FLAGS, | 119 | .flags = EMMA2RH_SERIAL_FLAGS, |
| 93 | }, | 120 | }, [1] = { |
| 94 | [1] = { | 121 | .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), |
| 95 | .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), | 122 | .irq = EMMA2RH_IRQ_PFUR1, |
| 96 | .irq = EMMA2RH_IRQ_PFUR1, | 123 | .uartclk = EMMA2RH_SERIAL_CLOCK, |
| 97 | .uartclk = EMMA2RH_SERIAL_CLOCK, | 124 | .regshift = 4, |
| 98 | .regshift = 4, | 125 | .iotype = UPIO_MEM, |
| 99 | .iotype = UPIO_MEM, | 126 | .flags = EMMA2RH_SERIAL_FLAGS, |
| 100 | .flags = EMMA2RH_SERIAL_FLAGS, | 127 | }, [2] = { |
| 101 | }, | 128 | .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), |
| 102 | [2] = { | 129 | .irq = EMMA2RH_IRQ_PFUR2, |
| 103 | .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), | 130 | .uartclk = EMMA2RH_SERIAL_CLOCK, |
| 104 | .irq = EMMA2RH_IRQ_PFUR2, | 131 | .regshift = 4, |
| 105 | .uartclk = EMMA2RH_SERIAL_CLOCK, | 132 | .iotype = UPIO_MEM, |
| 106 | .regshift = 4, | 133 | .flags = EMMA2RH_SERIAL_FLAGS, |
| 107 | .iotype = UPIO_MEM, | 134 | }, [3] = { |
| 108 | .flags = EMMA2RH_SERIAL_FLAGS, | 135 | .flags = 0, |
| 109 | }, | ||
| 110 | [3] = { | ||
| 111 | .flags = 0, | ||
| 112 | }, | 136 | }, |
| 113 | }; | 137 | }; |
| 114 | 138 | ||
diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index c83ae6acd601..c47eeb768192 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c | |||
| @@ -64,14 +64,14 @@ static irqreturn_t gt64120_irq(int irq, void *dev_id) | |||
| 64 | * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt | 64 | * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt |
| 65 | * handling. | 65 | * handling. |
| 66 | */ | 66 | */ |
| 67 | void gt64120_time_init(void) | 67 | void __init plat_timer_setup(struct irqaction *irq) |
| 68 | { | 68 | { |
| 69 | static struct irqaction timer; | 69 | static struct irqaction timer; |
| 70 | 70 | ||
| 71 | /* Disable timer first */ | 71 | /* Disable timer first */ |
| 72 | GT_WRITE(GT_TC_CONTROL_OFS, 0); | 72 | GT_WRITE(GT_TC_CONTROL_OFS, 0); |
| 73 | /* Load timer value for 100 Hz */ | 73 | /* Load timer value for 100 Hz */ |
| 74 | GT_WRITE(GT_TC3_OFS, Sys_clock / 100); | 74 | GT_WRITE(GT_TC3_OFS, Sys_clock / HZ); |
| 75 | 75 | ||
| 76 | /* | 76 | /* |
| 77 | * Create the IRQ structure entry for the timer. Since we're too early | 77 | * Create the IRQ structure entry for the timer. Since we're too early |
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c index 91c2d3f41617..99c8d42212e2 100644 --- a/arch/mips/gt64120/ev64120/setup.c +++ b/arch/mips/gt64120/ev64120/setup.c | |||
| @@ -68,7 +68,6 @@ unsigned long __init prom_free_prom_memory(void) | |||
| 68 | * Initializes basic routines and structures pointers, memory size (as | 68 | * Initializes basic routines and structures pointers, memory size (as |
| 69 | * given by the bios and saves the command line. | 69 | * given by the bios and saves the command line. |
| 70 | */ | 70 | */ |
| 71 | extern void gt64120_time_init(void); | ||
| 72 | 71 | ||
| 73 | void __init plat_mem_setup(void) | 72 | void __init plat_mem_setup(void) |
| 74 | { | 73 | { |
| @@ -76,7 +75,6 @@ void __init plat_mem_setup(void) | |||
| 76 | _machine_halt = galileo_machine_halt; | 75 | _machine_halt = galileo_machine_halt; |
| 77 | pm_power_off = galileo_machine_power_off; | 76 | pm_power_off = galileo_machine_power_off; |
| 78 | 77 | ||
| 79 | board_time_init = gt64120_time_init; | ||
| 80 | set_io_port_base(KSEG1); | 78 | set_io_port_base(KSEG1); |
| 81 | } | 79 | } |
| 82 | 80 | ||
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c index 0e5bbee2d5b7..94f94ebbda6c 100644 --- a/arch/mips/gt64120/momenco_ocelot/setup.c +++ b/arch/mips/gt64120/momenco_ocelot/setup.c | |||
| @@ -70,7 +70,6 @@ extern void momenco_ocelot_restart(char *command); | |||
| 70 | extern void momenco_ocelot_halt(void); | 70 | extern void momenco_ocelot_halt(void); |
| 71 | extern void momenco_ocelot_power_off(void); | 71 | extern void momenco_ocelot_power_off(void); |
| 72 | 72 | ||
| 73 | extern void gt64120_time_init(void); | ||
| 74 | extern void momenco_ocelot_irq_setup(void); | 73 | extern void momenco_ocelot_irq_setup(void); |
| 75 | 74 | ||
| 76 | static char reset_reason; | 75 | static char reset_reason; |
| @@ -156,8 +155,6 @@ void __init plat_mem_setup(void) | |||
| 156 | void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); | 155 | void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); |
| 157 | unsigned int tmpword; | 156 | unsigned int tmpword; |
| 158 | 157 | ||
| 159 | board_time_init = gt64120_time_init; | ||
| 160 | |||
| 161 | _machine_restart = momenco_ocelot_restart; | 158 | _machine_restart = momenco_ocelot_restart; |
| 162 | _machine_halt = momenco_ocelot_halt; | 159 | _machine_halt = momenco_ocelot_halt; |
| 163 | pm_power_off = momenco_ocelot_power_off; | 160 | pm_power_off = momenco_ocelot_power_off; |
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 39a0243bed9a..de4a238c28be 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c | |||
| @@ -288,6 +288,8 @@ static void tx_branch_likely_bug_fixup(void) | |||
| 288 | 288 | ||
| 289 | static void jmr3927_spurious(void) | 289 | static void jmr3927_spurious(void) |
| 290 | { | 290 | { |
| 291 | struct pt_regs * regs = get_irq_regs(); | ||
| 292 | |||
| 291 | #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND | 293 | #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND |
| 292 | tx_branch_likely_bug_fixup(); | 294 | tx_branch_likely_bug_fixup(); |
| 293 | #endif | 295 | #endif |
| @@ -297,6 +299,7 @@ static void jmr3927_spurious(void) | |||
| 297 | 299 | ||
| 298 | asmlinkage void plat_irq_dispatch(void) | 300 | asmlinkage void plat_irq_dispatch(void) |
| 299 | { | 301 | { |
| 302 | struct pt_regs * regs = get_irq_regs(); | ||
| 300 | int irq; | 303 | int irq; |
| 301 | 304 | ||
| 302 | #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND | 305 | #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND |
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 025434054ed0..16e5dfe7aa8a 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c | |||
| @@ -170,12 +170,20 @@ static void jmr3927_machine_power_off(void) | |||
| 170 | while (1); | 170 | while (1); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | static unsigned int jmr3927_hpt_read(void) | ||
| 174 | { | ||
| 175 | /* We assume this function is called xtime_lock held. */ | ||
| 176 | return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; | ||
| 177 | } | ||
| 178 | |||
| 173 | #define USE_RTC_DS1742 | 179 | #define USE_RTC_DS1742 |
| 174 | #ifdef USE_RTC_DS1742 | 180 | #ifdef USE_RTC_DS1742 |
| 175 | extern void rtc_ds1742_init(unsigned long base); | 181 | extern void rtc_ds1742_init(unsigned long base); |
| 176 | #endif | 182 | #endif |
| 177 | static void __init jmr3927_time_init(void) | 183 | static void __init jmr3927_time_init(void) |
| 178 | { | 184 | { |
| 185 | mips_hpt_read = jmr3927_hpt_read; | ||
| 186 | mips_hpt_frequency = JMR3927_TIMER_CLK; | ||
| 179 | #ifdef USE_RTC_DS1742 | 187 | #ifdef USE_RTC_DS1742 |
| 180 | if (jmr3927_have_nvram()) { | 188 | if (jmr3927_have_nvram()) { |
| 181 | rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); | 189 | rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); |
| @@ -183,12 +191,8 @@ static void __init jmr3927_time_init(void) | |||
| 183 | #endif | 191 | #endif |
| 184 | } | 192 | } |
| 185 | 193 | ||
| 186 | unsigned long jmr3927_do_gettimeoffset(void); | ||
| 187 | |||
| 188 | void __init plat_timer_setup(struct irqaction *irq) | 194 | void __init plat_timer_setup(struct irqaction *irq) |
| 189 | { | 195 | { |
| 190 | do_gettimeoffset = jmr3927_do_gettimeoffset; | ||
| 191 | |||
| 192 | jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; | 196 | jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; |
| 193 | jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; | 197 | jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; |
| 194 | jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; | 198 | jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; |
| @@ -200,34 +204,6 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
| 200 | 204 | ||
| 201 | #define USECS_PER_JIFFY (1000000/HZ) | 205 | #define USECS_PER_JIFFY (1000000/HZ) |
| 202 | 206 | ||
| 203 | unsigned long jmr3927_do_gettimeoffset(void) | ||
| 204 | { | ||
| 205 | unsigned long count; | ||
| 206 | unsigned long res = 0; | ||
| 207 | |||
| 208 | /* MUST read TRR before TISR. */ | ||
| 209 | count = jmr3927_tmrptr->trr; | ||
| 210 | |||
| 211 | if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { | ||
| 212 | /* timer interrupt is pending. use Max value. */ | ||
| 213 | res = USECS_PER_JIFFY - 1; | ||
| 214 | } else { | ||
| 215 | /* convert to usec */ | ||
| 216 | /* res = count / (JMR3927_TIMER_CLK / 1000000); */ | ||
| 217 | res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); | ||
| 218 | |||
| 219 | /* | ||
| 220 | * Due to possible jiffies inconsistencies, we need to check | ||
| 221 | * the result so that we'll get a timer that is monotonic. | ||
| 222 | */ | ||
| 223 | if (res >= USECS_PER_JIFFY) | ||
| 224 | res = USECS_PER_JIFFY-1; | ||
| 225 | } | ||
| 226 | |||
| 227 | return res; | ||
| 228 | } | ||
| 229 | |||
| 230 | |||
| 231 | //#undef DO_WRITE_THROUGH | 207 | //#undef DO_WRITE_THROUGH |
| 232 | #define DO_WRITE_THROUGH | 208 | #define DO_WRITE_THROUGH |
| 233 | #define DO_ENABLE_CACHE | 209 | #define DO_ENABLE_CACHE |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index e9ce5b3721af..ff88b06f89df 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define offset(string, ptr, member) \ | 22 | #define offset(string, ptr, member) \ |
| 23 | __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) | 23 | __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) |
| 24 | #define constant(string, member) \ | 24 | #define constant(string, member) \ |
| 25 | __asm__("\n@@@" string "%x0" : : "ri" (member)) | 25 | __asm__("\n@@@" string "%X0" : : "ri" (member)) |
| 26 | #define size(string, size) \ | 26 | #define size(string, size) \ |
| 27 | __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) | 27 | __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) |
| 28 | #define linefeed text("") | 28 | #define linefeed text("") |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 417c08ac76eb..f10b6a19f8bf 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
| @@ -83,7 +83,10 @@ FEXPORT(syscall_exit) | |||
| 83 | FEXPORT(restore_all) # restore full frame | 83 | FEXPORT(restore_all) # restore full frame |
| 84 | #ifdef CONFIG_MIPS_MT_SMTC | 84 | #ifdef CONFIG_MIPS_MT_SMTC |
| 85 | /* Detect and execute deferred IPI "interrupts" */ | 85 | /* Detect and execute deferred IPI "interrupts" */ |
| 86 | LONG_L s0, TI_REGS($28) | ||
| 87 | LONG_S sp, TI_REGS($28) | ||
| 86 | jal deferred_smtc_ipi | 88 | jal deferred_smtc_ipi |
| 89 | LONG_S s0, TI_REGS($28) | ||
| 87 | /* Re-arm any temporarily masked interrupts not explicitly "acked" */ | 90 | /* Re-arm any temporarily masked interrupts not explicitly "acked" */ |
| 88 | mfc0 v0, CP0_TCSTATUS | 91 | mfc0 v0, CP0_TCSTATUS |
| 89 | ori v1, v0, TCSTATUS_IXMT | 92 | ori v1, v0, TCSTATUS_IXMT |
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 8c6db0fc72f0..ddc1b71c9378 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S | |||
| @@ -189,7 +189,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
| 189 | 189 | ||
| 190 | MTC0 zero, CP0_CONTEXT # clear context register | 190 | MTC0 zero, CP0_CONTEXT # clear context register |
| 191 | PTR_LA $28, init_thread_union | 191 | PTR_LA $28, init_thread_union |
| 192 | PTR_ADDIU sp, $28, _THREAD_SIZE - 32 | 192 | PTR_LI sp, _THREAD_SIZE - 32 |
| 193 | PTR_ADDU sp, $28 | ||
| 193 | set_saved_sp sp, t0, t1 | 194 | set_saved_sp sp, t0, t1 |
| 194 | PTR_SUBU sp, 4 * SZREG # init stack pointer | 195 | PTR_SUBU sp, 4 * SZREG # init stack pointer |
| 195 | 196 | ||
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index dd24434392b6..9b0e49d63d7b 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
| @@ -26,6 +26,48 @@ | |||
| 26 | #include <asm/system.h> | 26 | #include <asm/system.h> |
| 27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
| 28 | 28 | ||
| 29 | static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; | ||
| 30 | |||
| 31 | int __devinit allocate_irqno(void) | ||
| 32 | { | ||
| 33 | int irq; | ||
| 34 | |||
| 35 | again: | ||
| 36 | irq = find_first_zero_bit(irq_map, NR_IRQS); | ||
| 37 | |||
| 38 | if (irq >= NR_IRQS) | ||
| 39 | return -ENOSPC; | ||
| 40 | |||
| 41 | if (test_and_set_bit(irq, irq_map)) | ||
| 42 | goto again; | ||
| 43 | |||
| 44 | return irq; | ||
| 45 | } | ||
| 46 | |||
| 47 | EXPORT_SYMBOL_GPL(allocate_irqno); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Allocate the 16 legacy interrupts for i8259 devices. This happens early | ||
| 51 | * in the kernel initialization so treating allocation failure as BUG() is | ||
| 52 | * ok. | ||
| 53 | */ | ||
| 54 | void __init alloc_legacy_irqno(void) | ||
| 55 | { | ||
| 56 | int i; | ||
| 57 | |||
| 58 | for (i = 0; i <= 16; i++) | ||
| 59 | BUG_ON(test_and_set_bit(i, irq_map)); | ||
| 60 | } | ||
| 61 | |||
| 62 | void __devinit free_irqno(unsigned int irq) | ||
| 63 | { | ||
| 64 | smp_mb__before_clear_bit(); | ||
| 65 | clear_bit(irq, irq_map); | ||
| 66 | smp_mb__after_clear_bit(); | ||
| 67 | } | ||
| 68 | |||
| 69 | EXPORT_SYMBOL_GPL(free_irqno); | ||
| 70 | |||
| 29 | /* | 71 | /* |
| 30 | * 'what should we do if we get a hw irq event on an illegal vector'. | 72 | * 'what should we do if we get a hw irq event on an illegal vector'. |
| 31 | * each architecture has to answer this themselves. | 73 | * each architecture has to answer this themselves. |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d5c8b82fed72..cc566cf12246 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
| @@ -85,7 +85,12 @@ | |||
| 85 | move $28, a2 | 85 | move $28, a2 |
| 86 | cpu_restore_nonscratch a1 | 86 | cpu_restore_nonscratch a1 |
| 87 | 87 | ||
| 88 | #if (_THREAD_SIZE - 32) < 0x10000 | ||
| 88 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 | 89 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 |
| 90 | #else | ||
| 91 | PTR_LI t0, _THREAD_SIZE - 32 | ||
| 92 | PTR_ADDU t0, $28 | ||
| 93 | #endif | ||
| 89 | set_saved_sp t0, t1, t2 | 94 | set_saved_sp t0, t1, t2 |
| 90 | #ifdef CONFIG_MIPS_MT_SMTC | 95 | #ifdef CONFIG_MIPS_MT_SMTC |
| 91 | /* Read-modify-writes of Status must be atomic on a VPE */ | 96 | /* Read-modify-writes of Status must be atomic on a VPE */ |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 720fac3435d5..a95f37de080e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
| @@ -654,6 +654,8 @@ einval: li v0, -EINVAL | |||
| 654 | sys sys_set_robust_list 2 | 654 | sys sys_set_robust_list 2 |
| 655 | sys sys_get_robust_list 3 /* 4310 */ | 655 | sys sys_get_robust_list 3 /* 4310 */ |
| 656 | sys sys_ni_syscall 0 | 656 | sys sys_ni_syscall 0 |
| 657 | sys sys_getcpu 3 | ||
| 658 | sys sys_epoll_pwait 6 | ||
| 657 | .endm | 659 | .endm |
| 658 | 660 | ||
| 659 | /* We pre-compute the number of _instruction_ bytes needed to | 661 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3a34f62c8b1b..8fb0f60f657b 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
| @@ -469,3 +469,5 @@ sys_call_table: | |||
| 469 | PTR sys_set_robust_list | 469 | PTR sys_set_robust_list |
| 470 | PTR sys_get_robust_list | 470 | PTR sys_get_robust_list |
| 471 | PTR sys_ni_syscall /* 5270 */ | 471 | PTR sys_ni_syscall /* 5270 */ |
| 472 | PTR sys_getcpu | ||
| 473 | PTR sys_epoll_pwait | ||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 67b92a1d6c72..0da5ca2040ff 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
| @@ -395,3 +395,5 @@ EXPORT(sysn32_call_table) | |||
| 395 | PTR compat_sys_set_robust_list | 395 | PTR compat_sys_set_robust_list |
| 396 | PTR compat_sys_get_robust_list | 396 | PTR compat_sys_get_robust_list |
| 397 | PTR sys_ni_syscall | 397 | PTR sys_ni_syscall |
| 398 | PTR sys_getcpu | ||
| 399 | PTR sys_epoll_pwait | ||
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2875c4a3fa58..b9d00cae8b5f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
| @@ -517,4 +517,6 @@ sys_call_table: | |||
| 517 | PTR compat_sys_set_robust_list | 517 | PTR compat_sys_set_robust_list |
| 518 | PTR compat_sys_get_robust_list /* 4310 */ | 518 | PTR compat_sys_get_robust_list /* 4310 */ |
| 519 | PTR sys_ni_syscall | 519 | PTR sys_ni_syscall |
| 520 | PTR sys_getcpu | ||
| 521 | PTR sys_epoll_pwait | ||
| 520 | .size sys_call_table,.-sys_call_table | 522 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index fdbb508661c5..8f6e89697ccf 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
| @@ -223,7 +223,11 @@ disable: | |||
| 223 | 223 | ||
| 224 | #else /* !CONFIG_BLK_DEV_INITRD */ | 224 | #else /* !CONFIG_BLK_DEV_INITRD */ |
| 225 | 225 | ||
| 226 | #define init_initrd() 0 | 226 | static unsigned long __init init_initrd(void) |
| 227 | { | ||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 227 | #define finalize_initrd() do {} while (0) | 231 | #define finalize_initrd() do {} while (0) |
| 228 | 232 | ||
| 229 | #endif | 233 | #endif |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 3b5f3b632622..2ac19a6cbf68 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
| @@ -140,15 +140,90 @@ static struct irqaction irq_call = { | |||
| 140 | .name = "IPI_call" | 140 | .name = "IPI_call" |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| 143 | static void __init smp_copy_vpe_config(void) | ||
| 144 | { | ||
| 145 | write_vpe_c0_status( | ||
| 146 | (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); | ||
| 147 | |||
| 148 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | ||
| 149 | write_vpe_c0_config( read_c0_config()); | ||
| 150 | |||
| 151 | /* make sure there are no software interrupts pending */ | ||
| 152 | write_vpe_c0_cause(0); | ||
| 153 | |||
| 154 | /* Propagate Config7 */ | ||
| 155 | write_vpe_c0_config7(read_c0_config7()); | ||
| 156 | |||
| 157 | write_vpe_c0_count(read_c0_count()); | ||
| 158 | } | ||
| 159 | |||
| 160 | static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, | ||
| 161 | unsigned int ncpu) | ||
| 162 | { | ||
| 163 | if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) | ||
| 164 | return ncpu; | ||
| 165 | |||
| 166 | /* Deactivate all but VPE 0 */ | ||
| 167 | if (tc != 0) { | ||
| 168 | unsigned long tmp = read_vpe_c0_vpeconf0(); | ||
| 169 | |||
| 170 | tmp &= ~VPECONF0_VPA; | ||
| 171 | |||
| 172 | /* master VPE */ | ||
| 173 | tmp |= VPECONF0_MVP; | ||
| 174 | write_vpe_c0_vpeconf0(tmp); | ||
| 175 | |||
| 176 | /* Record this as available CPU */ | ||
| 177 | cpu_set(tc, phys_cpu_present_map); | ||
| 178 | __cpu_number_map[tc] = ++ncpu; | ||
| 179 | __cpu_logical_map[ncpu] = tc; | ||
| 180 | } | ||
| 181 | |||
| 182 | /* Disable multi-threading with TC's */ | ||
| 183 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); | ||
| 184 | |||
| 185 | if (tc != 0) | ||
| 186 | smp_copy_vpe_config(); | ||
| 187 | |||
| 188 | return ncpu; | ||
| 189 | } | ||
| 190 | |||
| 191 | static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) | ||
| 192 | { | ||
| 193 | unsigned long tmp; | ||
| 194 | |||
| 195 | if (!tc) | ||
| 196 | return; | ||
| 197 | |||
| 198 | /* bind a TC to each VPE, May as well put all excess TC's | ||
| 199 | on the last VPE */ | ||
| 200 | if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1)) | ||
| 201 | write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); | ||
| 202 | else { | ||
| 203 | write_tc_c0_tcbind(read_tc_c0_tcbind() | tc); | ||
| 204 | |||
| 205 | /* and set XTC */ | ||
| 206 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT)); | ||
| 207 | } | ||
| 208 | |||
| 209 | tmp = read_tc_c0_tcstatus(); | ||
| 210 | |||
| 211 | /* mark not allocated and not dynamically allocatable */ | ||
| 212 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
| 213 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
| 214 | write_tc_c0_tcstatus(tmp); | ||
| 215 | |||
| 216 | write_tc_c0_tchalt(TCHALT_H); | ||
| 217 | } | ||
| 218 | |||
| 143 | /* | 219 | /* |
| 144 | * Common setup before any secondaries are started | 220 | * Common setup before any secondaries are started |
| 145 | * Make sure all CPU's are in a sensible state before we boot any of the | 221 | * Make sure all CPU's are in a sensible state before we boot any of the |
| 146 | * secondarys | 222 | * secondarys |
| 147 | */ | 223 | */ |
| 148 | void plat_smp_setup(void) | 224 | void __init plat_smp_setup(void) |
| 149 | { | 225 | { |
| 150 | unsigned long val; | 226 | unsigned int mvpconf0, ntc, tc, ncpu = 0; |
| 151 | int i, num; | ||
| 152 | 227 | ||
| 153 | #ifdef CONFIG_MIPS_MT_FPAFF | 228 | #ifdef CONFIG_MIPS_MT_FPAFF |
| 154 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | 229 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ |
| @@ -167,75 +242,16 @@ void plat_smp_setup(void) | |||
| 167 | /* Put MVPE's into 'configuration state' */ | 242 | /* Put MVPE's into 'configuration state' */ |
| 168 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 243 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
| 169 | 244 | ||
| 170 | val = read_c0_mvpconf0(); | 245 | mvpconf0 = read_c0_mvpconf0(); |
| 246 | ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; | ||
| 171 | 247 | ||
| 172 | /* we'll always have more TC's than VPE's, so loop setting everything | 248 | /* we'll always have more TC's than VPE's, so loop setting everything |
| 173 | to a sensible state */ | 249 | to a sensible state */ |
| 174 | for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) { | 250 | for (tc = 0; tc <= ntc; tc++) { |
| 175 | settc(i); | 251 | settc(tc); |
| 176 | |||
| 177 | /* VPE's */ | ||
| 178 | if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) { | ||
| 179 | |||
| 180 | /* deactivate all but vpe0 */ | ||
| 181 | if (i != 0) { | ||
| 182 | unsigned long tmp = read_vpe_c0_vpeconf0(); | ||
| 183 | |||
| 184 | tmp &= ~VPECONF0_VPA; | ||
| 185 | |||
| 186 | /* master VPE */ | ||
| 187 | tmp |= VPECONF0_MVP; | ||
| 188 | write_vpe_c0_vpeconf0(tmp); | ||
| 189 | |||
| 190 | /* Record this as available CPU */ | ||
| 191 | cpu_set(i, phys_cpu_present_map); | ||
| 192 | __cpu_number_map[i] = ++num; | ||
| 193 | __cpu_logical_map[num] = i; | ||
| 194 | } | ||
| 195 | |||
| 196 | /* disable multi-threading with TC's */ | ||
| 197 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); | ||
| 198 | |||
| 199 | if (i != 0) { | ||
| 200 | write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); | ||
| 201 | 252 | ||
| 202 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 253 | smp_tc_init(tc, mvpconf0); |
| 203 | write_vpe_c0_config( read_c0_config()); | 254 | ncpu = smp_vpe_init(tc, mvpconf0, ncpu); |
| 204 | |||
| 205 | /* make sure there are no software interrupts pending */ | ||
| 206 | write_vpe_c0_cause(0); | ||
| 207 | |||
| 208 | /* Propagate Config7 */ | ||
| 209 | write_vpe_c0_config7(read_c0_config7()); | ||
| 210 | } | ||
| 211 | |||
| 212 | } | ||
| 213 | |||
| 214 | /* TC's */ | ||
| 215 | |||
| 216 | if (i != 0) { | ||
| 217 | unsigned long tmp; | ||
| 218 | |||
| 219 | /* bind a TC to each VPE, May as well put all excess TC's | ||
| 220 | on the last VPE */ | ||
| 221 | if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) ) | ||
| 222 | write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) ); | ||
| 223 | else { | ||
| 224 | write_tc_c0_tcbind( read_tc_c0_tcbind() | i); | ||
| 225 | |||
| 226 | /* and set XTC */ | ||
| 227 | write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT)); | ||
| 228 | } | ||
| 229 | |||
| 230 | tmp = read_tc_c0_tcstatus(); | ||
| 231 | |||
| 232 | /* mark not allocated and not dynamically allocatable */ | ||
| 233 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
| 234 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
| 235 | write_tc_c0_tcstatus(tmp); | ||
| 236 | |||
| 237 | write_tc_c0_tchalt(TCHALT_H); | ||
| 238 | } | ||
| 239 | } | 255 | } |
| 240 | 256 | ||
| 241 | /* Release config state */ | 257 | /* Release config state */ |
| @@ -243,7 +259,7 @@ void plat_smp_setup(void) | |||
| 243 | 259 | ||
| 244 | /* We'll wait until starting the secondaries before starting MVPE */ | 260 | /* We'll wait until starting the secondaries before starting MVPE */ |
| 245 | 261 | ||
| 246 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); | 262 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); |
| 247 | } | 263 | } |
| 248 | 264 | ||
| 249 | void __init plat_prepare_cpus(unsigned int max_cpus) | 265 | void __init plat_prepare_cpus(unsigned int max_cpus) |
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 1cb9441f1474..921207c4a83c 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/arch/mips/kernel/smtc-asm.S | |||
| @@ -101,7 +101,9 @@ FEXPORT(__smtc_ipi_vector) | |||
| 101 | lw t0,PT_PADSLOT5(sp) | 101 | lw t0,PT_PADSLOT5(sp) |
| 102 | /* Argument from sender passed in stack pad slot 4 */ | 102 | /* Argument from sender passed in stack pad slot 4 */ |
| 103 | lw a0,PT_PADSLOT4(sp) | 103 | lw a0,PT_PADSLOT4(sp) |
| 104 | PTR_LA ra, _ret_from_irq | 104 | LONG_L s0, TI_REGS($28) |
| 105 | LONG_S sp, TI_REGS($28) | ||
| 106 | PTR_LA ra, ret_from_irq | ||
| 105 | jr t0 | 107 | jr t0 |
| 106 | 108 | ||
| 107 | /* | 109 | /* |
| @@ -119,7 +121,10 @@ LEAF(self_ipi) | |||
| 119 | subu t1,sp,PT_SIZE | 121 | subu t1,sp,PT_SIZE |
| 120 | sw ra,PT_EPC(t1) | 122 | sw ra,PT_EPC(t1) |
| 121 | sw a0,PT_PADSLOT4(t1) | 123 | sw a0,PT_PADSLOT4(t1) |
| 124 | LONG_L s0, TI_REGS($28) | ||
| 125 | LONG_S sp, TI_REGS($28) | ||
| 122 | la t2,ipi_decode | 126 | la t2,ipi_decode |
| 127 | LONG_S s0, TI_REGS($28) | ||
| 123 | sw t2,PT_PADSLOT5(t1) | 128 | sw t2,PT_PADSLOT5(t1) |
| 124 | /* Save pre-disable value of TCStatus */ | 129 | /* Save pre-disable value of TCStatus */ |
| 125 | sw t0,PT_TCSTATUS(t1) | 130 | sw t0,PT_TCSTATUS(t1) |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index cc1f7474f7d7..3b78caf112f5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
| @@ -476,6 +476,7 @@ void mipsmt_prepare_cpus(void) | |||
| 476 | write_vpe_c0_compare(0); | 476 | write_vpe_c0_compare(0); |
| 477 | /* Propagate Config7 */ | 477 | /* Propagate Config7 */ |
| 478 | write_vpe_c0_config7(read_c0_config7()); | 478 | write_vpe_c0_config7(read_c0_config7()); |
| 479 | write_vpe_c0_count(read_c0_count()); | ||
| 479 | } | 480 | } |
| 480 | /* enable multi-threading within VPE */ | 481 | /* enable multi-threading within VPE */ |
| 481 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); | 482 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); |
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index debe86c2f691..e535f86efa2f 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
| 12 | * option) any later version. | 12 | * option) any later version. |
| 13 | */ | 13 | */ |
| 14 | #include <linux/clocksource.h> | ||
| 14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| @@ -67,15 +68,9 @@ int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; | |||
| 67 | int (*rtc_mips_set_mmss)(unsigned long); | 68 | int (*rtc_mips_set_mmss)(unsigned long); |
| 68 | 69 | ||
| 69 | 70 | ||
| 70 | /* usecs per counter cycle, shifted to left by 32 bits */ | ||
| 71 | static unsigned int sll32_usecs_per_cycle; | ||
| 72 | |||
| 73 | /* how many counter cycles in a jiffy */ | 71 | /* how many counter cycles in a jiffy */ |
| 74 | static unsigned long cycles_per_jiffy __read_mostly; | 72 | static unsigned long cycles_per_jiffy __read_mostly; |
| 75 | 73 | ||
| 76 | /* Cycle counter value at the previous timer interrupt.. */ | ||
| 77 | static unsigned int timerhi, timerlo; | ||
| 78 | |||
| 79 | /* expirelo is the count value for next CPU timer interrupt */ | 74 | /* expirelo is the count value for next CPU timer interrupt */ |
| 80 | static unsigned int expirelo; | 75 | static unsigned int expirelo; |
| 81 | 76 | ||
| @@ -93,7 +88,7 @@ static unsigned int null_hpt_read(void) | |||
| 93 | return 0; | 88 | return 0; |
| 94 | } | 89 | } |
| 95 | 90 | ||
| 96 | static void null_hpt_init(unsigned int count) | 91 | static void __init null_hpt_init(void) |
| 97 | { | 92 | { |
| 98 | /* nothing */ | 93 | /* nothing */ |
| 99 | } | 94 | } |
| @@ -128,186 +123,18 @@ static unsigned int c0_hpt_read(void) | |||
| 128 | return read_c0_count(); | 123 | return read_c0_count(); |
| 129 | } | 124 | } |
| 130 | 125 | ||
| 131 | /* For use solely as a high precision timer. */ | ||
| 132 | static void c0_hpt_init(unsigned int count) | ||
| 133 | { | ||
| 134 | write_c0_count(read_c0_count() - count); | ||
| 135 | } | ||
| 136 | |||
| 137 | /* For use both as a high precision timer and an interrupt source. */ | 126 | /* For use both as a high precision timer and an interrupt source. */ |
| 138 | static void c0_hpt_timer_init(unsigned int count) | 127 | static void __init c0_hpt_timer_init(void) |
| 139 | { | 128 | { |
| 140 | count = read_c0_count() - count; | 129 | expirelo = read_c0_count() + cycles_per_jiffy; |
| 141 | expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; | ||
| 142 | write_c0_count(expirelo - cycles_per_jiffy); | ||
| 143 | write_c0_compare(expirelo); | 130 | write_c0_compare(expirelo); |
| 144 | write_c0_count(count); | ||
| 145 | } | 131 | } |
| 146 | 132 | ||
| 147 | int (*mips_timer_state)(void); | 133 | int (*mips_timer_state)(void); |
| 148 | void (*mips_timer_ack)(void); | 134 | void (*mips_timer_ack)(void); |
| 149 | unsigned int (*mips_hpt_read)(void); | 135 | unsigned int (*mips_hpt_read)(void); |
| 150 | void (*mips_hpt_init)(unsigned int); | 136 | void (*mips_hpt_init)(void) __initdata = null_hpt_init; |
| 151 | 137 | unsigned int mips_hpt_mask = 0xffffffff; | |
| 152 | /* | ||
| 153 | * Gettimeoffset routines. These routines returns the time duration | ||
| 154 | * since last timer interrupt in usecs. | ||
| 155 | * | ||
| 156 | * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. | ||
| 157 | * Otherwise use calibrate_gettimeoffset() | ||
| 158 | * | ||
| 159 | * If the CPU does not have the counter register, you can either supply | ||
| 160 | * your own gettimeoffset() routine, or use null_gettimeoffset(), which | ||
| 161 | * gives the same resolution as HZ. | ||
| 162 | */ | ||
| 163 | |||
| 164 | static unsigned long null_gettimeoffset(void) | ||
| 165 | { | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | |||
| 170 | /* The function pointer to one of the gettimeoffset funcs. */ | ||
| 171 | unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; | ||
| 172 | |||
| 173 | |||
| 174 | static unsigned long fixed_rate_gettimeoffset(void) | ||
| 175 | { | ||
| 176 | u32 count; | ||
| 177 | unsigned long res; | ||
| 178 | |||
| 179 | /* Get last timer tick in absolute kernel time */ | ||
| 180 | count = mips_hpt_read(); | ||
| 181 | |||
| 182 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
| 183 | count -= timerlo; | ||
| 184 | |||
| 185 | __asm__("multu %1,%2" | ||
| 186 | : "=h" (res) | ||
| 187 | : "r" (count), "r" (sll32_usecs_per_cycle) | ||
| 188 | : "lo", GCC_REG_ACCUM); | ||
| 189 | |||
| 190 | /* | ||
| 191 | * Due to possible jiffies inconsistencies, we need to check | ||
| 192 | * the result so that we'll get a timer that is monotonic. | ||
| 193 | */ | ||
| 194 | if (res >= USECS_PER_JIFFY) | ||
| 195 | res = USECS_PER_JIFFY - 1; | ||
| 196 | |||
| 197 | return res; | ||
| 198 | } | ||
| 199 | |||
| 200 | |||
| 201 | /* | ||
| 202 | * Cached "1/(clocks per usec) * 2^32" value. | ||
| 203 | * It has to be recalculated once each jiffy. | ||
| 204 | */ | ||
| 205 | static unsigned long cached_quotient; | ||
| 206 | |||
| 207 | /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ | ||
| 208 | static unsigned long last_jiffies; | ||
| 209 | |||
| 210 | /* | ||
| 211 | * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. | ||
| 212 | */ | ||
| 213 | static unsigned long calibrate_div32_gettimeoffset(void) | ||
| 214 | { | ||
| 215 | u32 count; | ||
| 216 | unsigned long res, tmp; | ||
| 217 | unsigned long quotient; | ||
| 218 | |||
| 219 | tmp = jiffies; | ||
| 220 | |||
| 221 | quotient = cached_quotient; | ||
| 222 | |||
| 223 | if (last_jiffies != tmp) { | ||
| 224 | last_jiffies = tmp; | ||
| 225 | if (last_jiffies != 0) { | ||
| 226 | unsigned long r0; | ||
| 227 | do_div64_32(r0, timerhi, timerlo, tmp); | ||
| 228 | do_div64_32(quotient, USECS_PER_JIFFY, | ||
| 229 | USECS_PER_JIFFY_FRAC, r0); | ||
| 230 | cached_quotient = quotient; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | /* Get last timer tick in absolute kernel time */ | ||
| 235 | count = mips_hpt_read(); | ||
| 236 | |||
| 237 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
| 238 | count -= timerlo; | ||
| 239 | |||
| 240 | __asm__("multu %1,%2" | ||
| 241 | : "=h" (res) | ||
| 242 | : "r" (count), "r" (quotient) | ||
| 243 | : "lo", GCC_REG_ACCUM); | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Due to possible jiffies inconsistencies, we need to check | ||
| 247 | * the result so that we'll get a timer that is monotonic. | ||
| 248 | */ | ||
| 249 | if (res >= USECS_PER_JIFFY) | ||
| 250 | res = USECS_PER_JIFFY - 1; | ||
| 251 | |||
| 252 | return res; | ||
| 253 | } | ||
| 254 | |||
| 255 | static unsigned long calibrate_div64_gettimeoffset(void) | ||
| 256 | { | ||
| 257 | u32 count; | ||
| 258 | unsigned long res, tmp; | ||
| 259 | unsigned long quotient; | ||
| 260 | |||
| 261 | tmp = jiffies; | ||
| 262 | |||
| 263 | quotient = cached_quotient; | ||
| 264 | |||
| 265 | if (last_jiffies != tmp) { | ||
| 266 | last_jiffies = tmp; | ||
| 267 | if (last_jiffies) { | ||
| 268 | unsigned long r0; | ||
| 269 | __asm__(".set push\n\t" | ||
| 270 | ".set mips3\n\t" | ||
| 271 | "lwu %0,%3\n\t" | ||
| 272 | "dsll32 %1,%2,0\n\t" | ||
| 273 | "or %1,%1,%0\n\t" | ||
| 274 | "ddivu $0,%1,%4\n\t" | ||
| 275 | "mflo %1\n\t" | ||
| 276 | "dsll32 %0,%5,0\n\t" | ||
| 277 | "or %0,%0,%6\n\t" | ||
| 278 | "ddivu $0,%0,%1\n\t" | ||
| 279 | "mflo %0\n\t" | ||
| 280 | ".set pop" | ||
| 281 | : "=&r" (quotient), "=&r" (r0) | ||
| 282 | : "r" (timerhi), "m" (timerlo), | ||
| 283 | "r" (tmp), "r" (USECS_PER_JIFFY), | ||
| 284 | "r" (USECS_PER_JIFFY_FRAC) | ||
| 285 | : "hi", "lo", GCC_REG_ACCUM); | ||
| 286 | cached_quotient = quotient; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /* Get last timer tick in absolute kernel time */ | ||
| 291 | count = mips_hpt_read(); | ||
| 292 | |||
| 293 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
| 294 | count -= timerlo; | ||
| 295 | |||
| 296 | __asm__("multu %1,%2" | ||
| 297 | : "=h" (res) | ||
| 298 | : "r" (count), "r" (quotient) | ||
| 299 | : "lo", GCC_REG_ACCUM); | ||
| 300 | |||
| 301 | /* | ||
| 302 | * Due to possible jiffies inconsistencies, we need to check | ||
| 303 | * the result so that we'll get a timer that is monotonic. | ||
| 304 | */ | ||
| 305 | if (res >= USECS_PER_JIFFY) | ||
| 306 | res = USECS_PER_JIFFY - 1; | ||
| 307 | |||
| 308 | return res; | ||
| 309 | } | ||
| 310 | |||
| 311 | 138 | ||
| 312 | /* last time when xtime and rtc are sync'ed up */ | 139 | /* last time when xtime and rtc are sync'ed up */ |
| 313 | static long last_rtc_update; | 140 | static long last_rtc_update; |
| @@ -334,18 +161,10 @@ void local_timer_interrupt(int irq, void *dev_id) | |||
| 334 | */ | 161 | */ |
| 335 | irqreturn_t timer_interrupt(int irq, void *dev_id) | 162 | irqreturn_t timer_interrupt(int irq, void *dev_id) |
| 336 | { | 163 | { |
| 337 | unsigned long j; | ||
| 338 | unsigned int count; | ||
| 339 | |||
| 340 | write_seqlock(&xtime_lock); | 164 | write_seqlock(&xtime_lock); |
| 341 | 165 | ||
| 342 | count = mips_hpt_read(); | ||
| 343 | mips_timer_ack(); | 166 | mips_timer_ack(); |
| 344 | 167 | ||
| 345 | /* Update timerhi/timerlo for intra-jiffy calibration. */ | ||
| 346 | timerhi += count < timerlo; /* Wrap around */ | ||
| 347 | timerlo = count; | ||
| 348 | |||
| 349 | /* | 168 | /* |
| 350 | * call the generic timer interrupt handling | 169 | * call the generic timer interrupt handling |
| 351 | */ | 170 | */ |
| @@ -368,47 +187,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
| 368 | } | 187 | } |
| 369 | } | 188 | } |
| 370 | 189 | ||
| 371 | /* | ||
| 372 | * If jiffies has overflown in this timer_interrupt, we must | ||
| 373 | * update the timer[hi]/[lo] to make fast gettimeoffset funcs | ||
| 374 | * quotient calc still valid. -arca | ||
| 375 | * | ||
| 376 | * The first timer interrupt comes late as interrupts are | ||
| 377 | * enabled long after timers are initialized. Therefore the | ||
| 378 | * high precision timer is fast, leading to wrong gettimeoffset() | ||
| 379 | * calculations. We deal with it by setting it based on the | ||
| 380 | * number of its ticks between the second and the third interrupt. | ||
| 381 | * That is still somewhat imprecise, but it's a good estimate. | ||
| 382 | * --macro | ||
| 383 | */ | ||
| 384 | j = jiffies; | ||
| 385 | if (j < 4) { | ||
| 386 | static unsigned int prev_count; | ||
| 387 | static int hpt_initialized; | ||
| 388 | |||
| 389 | switch (j) { | ||
| 390 | case 0: | ||
| 391 | timerhi = timerlo = 0; | ||
| 392 | mips_hpt_init(count); | ||
| 393 | break; | ||
| 394 | case 2: | ||
| 395 | prev_count = count; | ||
| 396 | break; | ||
| 397 | case 3: | ||
| 398 | if (!hpt_initialized) { | ||
| 399 | unsigned int c3 = 3 * (count - prev_count); | ||
| 400 | |||
| 401 | timerhi = 0; | ||
| 402 | timerlo = c3; | ||
| 403 | mips_hpt_init(count - c3); | ||
| 404 | hpt_initialized = 1; | ||
| 405 | } | ||
| 406 | break; | ||
| 407 | default: | ||
| 408 | break; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | write_sequnlock(&xtime_lock); | 190 | write_sequnlock(&xtime_lock); |
| 413 | 191 | ||
| 414 | /* | 192 | /* |
| @@ -476,12 +254,11 @@ asmlinkage void ll_local_timer_interrupt(int irq) | |||
| 476 | * 1) board_time_init() - | 254 | * 1) board_time_init() - |
| 477 | * a) (optional) set up RTC routines, | 255 | * a) (optional) set up RTC routines, |
| 478 | * b) (optional) calibrate and set the mips_hpt_frequency | 256 | * b) (optional) calibrate and set the mips_hpt_frequency |
| 479 | * (only needed if you intended to use fixed_rate_gettimeoffset | 257 | * (only needed if you intended to use cpu counter as timer interrupt |
| 480 | * or use cpu counter as timer interrupt source) | 258 | * source) |
| 481 | * 2) setup xtime based on rtc_mips_get_time(). | 259 | * 2) setup xtime based on rtc_mips_get_time(). |
| 482 | * 3) choose a appropriate gettimeoffset routine. | 260 | * 3) calculate a couple of cached variables for later usage |
| 483 | * 4) calculate a couple of cached variables for later usage | 261 | * 4) plat_timer_setup() - |
| 484 | * 5) plat_timer_setup() - | ||
| 485 | * a) (optional) over-write any choices made above by time_init(). | 262 | * a) (optional) over-write any choices made above by time_init(). |
| 486 | * b) machine specific code should setup the timer irqaction. | 263 | * b) machine specific code should setup the timer irqaction. |
| 487 | * c) enable the timer interrupt | 264 | * c) enable the timer interrupt |
| @@ -533,13 +310,48 @@ static unsigned int __init calibrate_hpt(void) | |||
| 533 | } while (--i); | 310 | } while (--i); |
| 534 | hpt_end = mips_hpt_read(); | 311 | hpt_end = mips_hpt_read(); |
| 535 | 312 | ||
| 536 | hpt_count = hpt_end - hpt_start; | 313 | hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; |
| 537 | hz = HZ; | 314 | hz = HZ; |
| 538 | frequency = (u64)hpt_count * (u64)hz; | 315 | frequency = (u64)hpt_count * (u64)hz; |
| 539 | 316 | ||
| 540 | return frequency >> log_2_loops; | 317 | return frequency >> log_2_loops; |
| 541 | } | 318 | } |
| 542 | 319 | ||
| 320 | static cycle_t read_mips_hpt(void) | ||
| 321 | { | ||
| 322 | return (cycle_t)mips_hpt_read(); | ||
| 323 | } | ||
| 324 | |||
| 325 | static struct clocksource clocksource_mips = { | ||
| 326 | .name = "MIPS", | ||
| 327 | .read = read_mips_hpt, | ||
| 328 | .is_continuous = 1, | ||
| 329 | }; | ||
| 330 | |||
| 331 | static void __init init_mips_clocksource(void) | ||
| 332 | { | ||
| 333 | u64 temp; | ||
| 334 | u32 shift; | ||
| 335 | |||
| 336 | if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) | ||
| 337 | return; | ||
| 338 | |||
| 339 | /* Calclate a somewhat reasonable rating value */ | ||
| 340 | clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; | ||
| 341 | /* Find a shift value */ | ||
| 342 | for (shift = 32; shift > 0; shift--) { | ||
| 343 | temp = (u64) NSEC_PER_SEC << shift; | ||
| 344 | do_div(temp, mips_hpt_frequency); | ||
| 345 | if ((temp >> 32) == 0) | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | clocksource_mips.shift = shift; | ||
| 349 | clocksource_mips.mult = (u32)temp; | ||
| 350 | clocksource_mips.mask = mips_hpt_mask; | ||
| 351 | |||
| 352 | clocksource_register(&clocksource_mips); | ||
| 353 | } | ||
| 354 | |||
| 543 | void __init time_init(void) | 355 | void __init time_init(void) |
| 544 | { | 356 | { |
| 545 | if (board_time_init) | 357 | if (board_time_init) |
| @@ -555,41 +367,21 @@ void __init time_init(void) | |||
| 555 | -xtime.tv_sec, -xtime.tv_nsec); | 367 | -xtime.tv_sec, -xtime.tv_nsec); |
| 556 | 368 | ||
| 557 | /* Choose appropriate high precision timer routines. */ | 369 | /* Choose appropriate high precision timer routines. */ |
| 558 | if (!cpu_has_counter && !mips_hpt_read) { | 370 | if (!cpu_has_counter && !mips_hpt_read) |
| 559 | /* No high precision timer -- sorry. */ | 371 | /* No high precision timer -- sorry. */ |
| 560 | mips_hpt_read = null_hpt_read; | 372 | mips_hpt_read = null_hpt_read; |
| 561 | mips_hpt_init = null_hpt_init; | 373 | else if (!mips_hpt_frequency && !mips_timer_state) { |
| 562 | } else if (!mips_hpt_frequency && !mips_timer_state) { | ||
| 563 | /* A high precision timer of unknown frequency. */ | 374 | /* A high precision timer of unknown frequency. */ |
| 564 | if (!mips_hpt_read) { | 375 | if (!mips_hpt_read) |
| 565 | /* No external high precision timer -- use R4k. */ | 376 | /* No external high precision timer -- use R4k. */ |
| 566 | mips_hpt_read = c0_hpt_read; | 377 | mips_hpt_read = c0_hpt_read; |
| 567 | mips_hpt_init = c0_hpt_init; | ||
| 568 | } | ||
| 569 | |||
| 570 | if (cpu_has_mips32r1 || cpu_has_mips32r2 || | ||
| 571 | (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || | ||
| 572 | (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) | ||
| 573 | /* | ||
| 574 | * We need to calibrate the counter but we don't have | ||
| 575 | * 64-bit division. | ||
| 576 | */ | ||
| 577 | do_gettimeoffset = calibrate_div32_gettimeoffset; | ||
| 578 | else | ||
| 579 | /* | ||
| 580 | * We need to calibrate the counter but we *do* have | ||
| 581 | * 64-bit division. | ||
| 582 | */ | ||
| 583 | do_gettimeoffset = calibrate_div64_gettimeoffset; | ||
| 584 | } else { | 378 | } else { |
| 585 | /* We know counter frequency. Or we can get it. */ | 379 | /* We know counter frequency. Or we can get it. */ |
| 586 | if (!mips_hpt_read) { | 380 | if (!mips_hpt_read) { |
| 587 | /* No external high precision timer -- use R4k. */ | 381 | /* No external high precision timer -- use R4k. */ |
| 588 | mips_hpt_read = c0_hpt_read; | 382 | mips_hpt_read = c0_hpt_read; |
| 589 | 383 | ||
| 590 | if (mips_timer_state) | 384 | if (!mips_timer_state) { |
| 591 | mips_hpt_init = c0_hpt_init; | ||
| 592 | else { | ||
| 593 | /* No external timer interrupt -- use R4k. */ | 385 | /* No external timer interrupt -- use R4k. */ |
| 594 | mips_hpt_init = c0_hpt_timer_init; | 386 | mips_hpt_init = c0_hpt_timer_init; |
| 595 | mips_timer_ack = c0_timer_ack; | 387 | mips_timer_ack = c0_timer_ack; |
| @@ -598,16 +390,9 @@ void __init time_init(void) | |||
| 598 | if (!mips_hpt_frequency) | 390 | if (!mips_hpt_frequency) |
| 599 | mips_hpt_frequency = calibrate_hpt(); | 391 | mips_hpt_frequency = calibrate_hpt(); |
| 600 | 392 | ||
| 601 | do_gettimeoffset = fixed_rate_gettimeoffset; | ||
| 602 | |||
| 603 | /* Calculate cache parameters. */ | 393 | /* Calculate cache parameters. */ |
| 604 | cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; | 394 | cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; |
| 605 | 395 | ||
| 606 | /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ | ||
| 607 | do_div64_32(sll32_usecs_per_cycle, | ||
| 608 | 1000000, mips_hpt_frequency / 2, | ||
| 609 | mips_hpt_frequency); | ||
| 610 | |||
| 611 | /* Report the high precision timer rate for a reference. */ | 396 | /* Report the high precision timer rate for a reference. */ |
| 612 | printk("Using %u.%03u MHz high precision timer.\n", | 397 | printk("Using %u.%03u MHz high precision timer.\n", |
| 613 | ((mips_hpt_frequency + 500) / 1000) / 1000, | 398 | ((mips_hpt_frequency + 500) / 1000) / 1000, |
| @@ -619,7 +404,7 @@ void __init time_init(void) | |||
| 619 | mips_timer_ack = null_timer_ack; | 404 | mips_timer_ack = null_timer_ack; |
| 620 | 405 | ||
| 621 | /* This sets up the high precision timer for the first interrupt. */ | 406 | /* This sets up the high precision timer for the first interrupt. */ |
| 622 | mips_hpt_init(mips_hpt_read()); | 407 | mips_hpt_init(); |
| 623 | 408 | ||
| 624 | /* | 409 | /* |
| 625 | * Call board specific timer interrupt setup. | 410 | * Call board specific timer interrupt setup. |
| @@ -633,6 +418,8 @@ void __init time_init(void) | |||
| 633 | * is not invoked accidentally. | 418 | * is not invoked accidentally. |
| 634 | */ | 419 | */ |
| 635 | plat_timer_setup(&timer_irqaction); | 420 | plat_timer_setup(&timer_irqaction); |
| 421 | |||
| 422 | init_mips_clocksource(); | ||
| 636 | } | 423 | } |
| 637 | 424 | ||
| 638 | #define FEBRUARY 2 | 425 | #define FEBRUARY 2 |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cce8313ec27d..9fda1b8be3a7 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -1111,7 +1111,7 @@ static struct shadow_registers { | |||
| 1111 | static void mips_srs_init(void) | 1111 | static void mips_srs_init(void) |
| 1112 | { | 1112 | { |
| 1113 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | 1113 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; |
| 1114 | printk(KERN_INFO "%d MIPSR2 register sets available\n", | 1114 | printk(KERN_INFO "%ld MIPSR2 register sets available\n", |
| 1115 | shadow_registers.sr_supported); | 1115 | shadow_registers.sr_supported); |
| 1116 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ | 1116 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ |
| 1117 | } | 1117 | } |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0bb9cd889456..79f0317d84ac 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
| @@ -50,6 +50,16 @@ SECTIONS | |||
| 50 | /* writeable */ | 50 | /* writeable */ |
| 51 | .data : { /* Data */ | 51 | .data : { /* Data */ |
| 52 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ | 52 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ |
| 53 | /* | ||
| 54 | * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which | ||
| 55 | * limits the maximum alignment to at most 32kB and results in the following | ||
| 56 | * warning: | ||
| 57 | * | ||
| 58 | * CC arch/mips/kernel/init_task.o | ||
| 59 | * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ | ||
| 60 | * is greater than maximum object file alignment. Using 32768 | ||
| 61 | */ | ||
| 62 | . = ALIGN(_PAGE_SIZE); | ||
| 53 | *(.data.init_task) | 63 | *(.data.init_task) |
| 54 | 64 | ||
| 55 | *(.data) | 65 | *(.data) |
| @@ -91,13 +101,7 @@ SECTIONS | |||
| 91 | 101 | ||
| 92 | __initcall_start = .; | 102 | __initcall_start = .; |
| 93 | .initcall.init : { | 103 | .initcall.init : { |
| 94 | *(.initcall1.init) | 104 | INITCALLS |
| 95 | *(.initcall2.init) | ||
| 96 | *(.initcall3.init) | ||
| 97 | *(.initcall4.init) | ||
| 98 | *(.initcall5.init) | ||
| 99 | *(.initcall6.init) | ||
| 100 | *(.initcall7.init) | ||
| 101 | } | 105 | } |
| 102 | __initcall_end = .; | 106 | __initcall_end = .; |
| 103 | 107 | ||
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c index be8261be679b..594df1a05ecc 100644 --- a/arch/mips/lib-64/dump_tlb.c +++ b/arch/mips/lib-64/dump_tlb.c | |||
| @@ -149,7 +149,7 @@ void dump_list_process(struct task_struct *t, void *address) | |||
| 149 | printk("Addr == %08lx\n", addr); | 149 | printk("Addr == %08lx\n", addr); |
| 150 | printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); | 150 | printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); |
| 151 | 151 | ||
| 152 | page_dir = pgd_offset(t->mm, 0); | 152 | page_dir = pgd_offset(t->mm, 0UL); |
| 153 | printk("page_dir == %016lx\n", (unsigned long) page_dir); | 153 | printk("page_dir == %016lx\n", (unsigned long) page_dir); |
| 154 | 154 | ||
| 155 | pgd = pgd_offset(t->mm, addr); | 155 | pgd = pgd_offset(t->mm, addr); |
| @@ -184,13 +184,13 @@ void dump_list_current(void *address) | |||
| 184 | dump_list_process(current, address); | 184 | dump_list_process(current, address); |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | unsigned int vtop(void *address) | 187 | unsigned long vtop(void *address) |
| 188 | { | 188 | { |
| 189 | pgd_t *pgd; | 189 | pgd_t *pgd; |
| 190 | pud_t *pud; | 190 | pud_t *pud; |
| 191 | pmd_t *pmd; | 191 | pmd_t *pmd; |
| 192 | pte_t *pte; | 192 | pte_t *pte; |
| 193 | unsigned int addr, paddr; | 193 | unsigned long addr, paddr; |
| 194 | 194 | ||
| 195 | addr = (unsigned long) address; | 195 | addr = (unsigned long) address; |
| 196 | pgd = pgd_offset(current->mm, addr); | 196 | pgd = pgd_offset(current->mm, addr); |
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index be80c5dd4a0c..eeed944e0f83 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c | |||
| @@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memory(void) | |||
| 176 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | 176 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) |
| 177 | continue; | 177 | continue; |
| 178 | 178 | ||
| 179 | addr = boot_mem_map.map[i].addr; | 179 | addr = PAGE_ALIGN(boot_mem_map.map[i].addr); |
| 180 | while (addr < boot_mem_map.map[i].addr | 180 | while (addr < boot_mem_map.map[i].addr |
| 181 | + boot_mem_map.map[i].size) { | 181 | + boot_mem_map.map[i].size) { |
| 182 | ClearPageReserved(virt_to_page(__va(addr))); | 182 | ClearPageReserved(virt_to_page(__va(addr))); |
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c index 9337f6c8873a..3192a14698c8 100644 --- a/arch/mips/mips-boards/generic/pci.c +++ b/arch/mips/mips-boards/generic/pci.c | |||
| @@ -90,7 +90,7 @@ static struct pci_controller msc_controller = { | |||
| 90 | void __init mips_pcibios_init(void) | 90 | void __init mips_pcibios_init(void) |
| 91 | { | 91 | { |
| 92 | struct pci_controller *controller; | 92 | struct pci_controller *controller; |
| 93 | unsigned long start, end, map, start1, end1, map1, map2, map3, mask; | 93 | resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; |
| 94 | 94 | ||
| 95 | switch (mips_revision_corid) { | 95 | switch (mips_revision_corid) { |
| 96 | case MIPS_REVISION_CORID_QED_RM5261: | 96 | case MIPS_REVISION_CORID_QED_RM5261: |
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 6f8a9fe7c1e3..d817c60c5ca5 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
| @@ -187,7 +187,7 @@ out: | |||
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* | 189 | /* |
| 190 | * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect | 190 | * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect |
| 191 | */ | 191 | */ |
| 192 | static unsigned int __init estimate_cpu_frequency(void) | 192 | static unsigned int __init estimate_cpu_frequency(void) |
| 193 | { | 193 | { |
| @@ -208,7 +208,8 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
| 208 | count = 6000000; | 208 | count = 6000000; |
| 209 | #endif | 209 | #endif |
| 210 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | 210 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) |
| 211 | unsigned int flags; | 211 | unsigned long flags; |
| 212 | unsigned int start; | ||
| 212 | 213 | ||
| 213 | local_irq_save(flags); | 214 | local_irq_save(flags); |
| 214 | 215 | ||
| @@ -217,13 +218,13 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
| 217 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 218 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
| 218 | 219 | ||
| 219 | /* Start r4k counter. */ | 220 | /* Start r4k counter. */ |
| 220 | write_c0_count(0); | 221 | start = read_c0_count(); |
| 221 | 222 | ||
| 222 | /* Read counter exactly on falling edge of update flag */ | 223 | /* Read counter exactly on falling edge of update flag */ |
| 223 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 224 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
| 224 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 225 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
| 225 | 226 | ||
| 226 | count = read_c0_count(); | 227 | count = read_c0_count() - start; |
| 227 | 228 | ||
| 228 | /* restore interrupts */ | 229 | /* restore interrupts */ |
| 229 | local_irq_restore(flags); | 230 | local_irq_restore(flags); |
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c index c566b9bd0427..24a4ed00cc0a 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mips-boards/sim/sim_time.c | |||
| @@ -102,7 +102,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) | |||
| 102 | 102 | ||
| 103 | 103 | ||
| 104 | /* | 104 | /* |
| 105 | * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect | 105 | * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect |
| 106 | */ | 106 | */ |
| 107 | static unsigned int __init estimate_cpu_frequency(void) | 107 | static unsigned int __init estimate_cpu_frequency(void) |
| 108 | { | 108 | { |
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 5537558f19f7..d0ddb4a768a5 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c | |||
| @@ -49,6 +49,15 @@ static unsigned short dcache_sets; | |||
| 49 | static unsigned int icache_range_cutoff; | 49 | static unsigned int icache_range_cutoff; |
| 50 | static unsigned int dcache_range_cutoff; | 50 | static unsigned int dcache_range_cutoff; |
| 51 | 51 | ||
| 52 | static inline void sb1_on_each_cpu(void (*func) (void *info), void *info, | ||
| 53 | int retry, int wait) | ||
| 54 | { | ||
| 55 | preempt_disable(); | ||
| 56 | smp_call_function(func, info, retry, wait); | ||
| 57 | func(info); | ||
| 58 | preempt_enable(); | ||
| 59 | } | ||
| 60 | |||
| 52 | /* | 61 | /* |
| 53 | * The dcache is fully coherent to the system, with one | 62 | * The dcache is fully coherent to the system, with one |
| 54 | * big caveat: the instruction stream. In other words, | 63 | * big caveat: the instruction stream. In other words, |
| @@ -226,7 +235,7 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, | |||
| 226 | args.vma = vma; | 235 | args.vma = vma; |
| 227 | args.addr = addr; | 236 | args.addr = addr; |
| 228 | args.pfn = pfn; | 237 | args.pfn = pfn; |
| 229 | on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); | 238 | sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); |
| 230 | } | 239 | } |
| 231 | #else | 240 | #else |
| 232 | void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) | 241 | void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) |
| @@ -249,7 +258,7 @@ void sb1___flush_cache_all_ipi(void *ignored) | |||
| 249 | 258 | ||
| 250 | static void sb1___flush_cache_all(void) | 259 | static void sb1___flush_cache_all(void) |
| 251 | { | 260 | { |
| 252 | on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); | 261 | sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); |
| 253 | } | 262 | } |
| 254 | #else | 263 | #else |
| 255 | void sb1___flush_cache_all(void) | 264 | void sb1___flush_cache_all(void) |
| @@ -299,7 +308,7 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) | |||
| 299 | 308 | ||
| 300 | args.start = start; | 309 | args.start = start; |
| 301 | args.end = end; | 310 | args.end = end; |
| 302 | on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); | 311 | sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); |
| 303 | } | 312 | } |
| 304 | #else | 313 | #else |
| 305 | void sb1_flush_icache_range(unsigned long start, unsigned long end) | 314 | void sb1_flush_icache_range(unsigned long start, unsigned long end) |
| @@ -326,7 +335,7 @@ static void sb1_flush_cache_sigtramp_ipi(void *info) | |||
| 326 | 335 | ||
| 327 | static void sb1_flush_cache_sigtramp(unsigned long addr) | 336 | static void sb1_flush_cache_sigtramp(unsigned long addr) |
| 328 | { | 337 | { |
| 329 | on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); | 338 | sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); |
| 330 | } | 339 | } |
| 331 | #else | 340 | #else |
| 332 | void sb1_flush_cache_sigtramp(unsigned long addr) | 341 | void sb1_flush_cache_sigtramp(unsigned long addr) |
| @@ -444,7 +453,6 @@ static __init void probe_cache_sizes(void) | |||
| 444 | void sb1_cache_init(void) | 453 | void sb1_cache_init(void) |
| 445 | { | 454 | { |
| 446 | extern char except_vec2_sb1; | 455 | extern char except_vec2_sb1; |
| 447 | extern char handle_vec2_sb1; | ||
| 448 | 456 | ||
| 449 | /* Special cache error handler for SB1 */ | 457 | /* Special cache error handler for SB1 */ |
| 450 | set_uncached_handler (0x100, &except_vec2_sb1, 0x80); | 458 | set_uncached_handler (0x100, &except_vec2_sb1, 0x80); |
| @@ -497,5 +505,5 @@ void sb1_cache_init(void) | |||
| 497 | : | 505 | : |
| 498 | : "memory"); | 506 | : "memory"); |
| 499 | 507 | ||
| 500 | flush_cache_all(); | 508 | local_sb1___flush_cache_all(); |
| 501 | } | 509 | } |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 88b72c9a8495..2de4d3c367a2 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
| @@ -30,11 +30,34 @@ | |||
| 30 | #include <asm/cachectl.h> | 30 | #include <asm/cachectl.h> |
| 31 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
| 32 | #include <asm/dma.h> | 32 | #include <asm/dma.h> |
| 33 | #include <asm/kmap_types.h> | ||
| 33 | #include <asm/mmu_context.h> | 34 | #include <asm/mmu_context.h> |
| 34 | #include <asm/sections.h> | 35 | #include <asm/sections.h> |
| 35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
| 36 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
| 37 | #include <asm/tlb.h> | 38 | #include <asm/tlb.h> |
| 39 | #include <asm/fixmap.h> | ||
| 40 | |||
| 41 | /* Atomicity and interruptability */ | ||
| 42 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 43 | |||
| 44 | #include <asm/mipsmtregs.h> | ||
| 45 | |||
| 46 | #define ENTER_CRITICAL(flags) \ | ||
| 47 | { \ | ||
| 48 | unsigned int mvpflags; \ | ||
| 49 | local_irq_save(flags);\ | ||
| 50 | mvpflags = dvpe() | ||
| 51 | #define EXIT_CRITICAL(flags) \ | ||
| 52 | evpe(mvpflags); \ | ||
| 53 | local_irq_restore(flags); \ | ||
| 54 | } | ||
| 55 | #else | ||
| 56 | |||
| 57 | #define ENTER_CRITICAL(flags) local_irq_save(flags) | ||
| 58 | #define EXIT_CRITICAL(flags) local_irq_restore(flags) | ||
| 59 | |||
| 60 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
| 38 | 61 | ||
| 39 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 62 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
| 40 | 63 | ||
| @@ -80,13 +103,142 @@ unsigned long setup_zero_pages(void) | |||
| 80 | return 1UL << order; | 103 | return 1UL << order; |
| 81 | } | 104 | } |
| 82 | 105 | ||
| 83 | #ifdef CONFIG_HIGHMEM | 106 | /* |
| 84 | pte_t *kmap_pte; | 107 | * These are almost like kmap_atomic / kunmap_atmic except they take an |
| 85 | pgprot_t kmap_prot; | 108 | * additional address argument as the hint. |
| 109 | */ | ||
| 86 | 110 | ||
| 87 | #define kmap_get_fixmap_pte(vaddr) \ | 111 | #define kmap_get_fixmap_pte(vaddr) \ |
| 88 | pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) | 112 | pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) |
| 89 | 113 | ||
| 114 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 115 | static pte_t *kmap_coherent_pte; | ||
| 116 | static void __init kmap_coherent_init(void) | ||
| 117 | { | ||
| 118 | unsigned long vaddr; | ||
| 119 | |||
| 120 | /* cache the first coherent kmap pte */ | ||
| 121 | vaddr = __fix_to_virt(FIX_CMAP_BEGIN); | ||
| 122 | kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); | ||
| 123 | } | ||
| 124 | #else | ||
| 125 | static inline void kmap_coherent_init(void) {} | ||
| 126 | #endif | ||
| 127 | |||
| 128 | static inline void *kmap_coherent(struct page *page, unsigned long addr) | ||
| 129 | { | ||
| 130 | enum fixed_addresses idx; | ||
| 131 | unsigned long vaddr, flags, entrylo; | ||
| 132 | unsigned long old_ctx; | ||
| 133 | pte_t pte; | ||
| 134 | int tlbidx; | ||
| 135 | |||
| 136 | inc_preempt_count(); | ||
| 137 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); | ||
| 138 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 139 | idx += FIX_N_COLOURS * smp_processor_id(); | ||
| 140 | #endif | ||
| 141 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | ||
| 142 | pte = mk_pte(page, PAGE_KERNEL); | ||
| 143 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) | ||
| 144 | entrylo = pte.pte_high; | ||
| 145 | #else | ||
| 146 | entrylo = pte_val(pte) >> 6; | ||
| 147 | #endif | ||
| 148 | |||
| 149 | ENTER_CRITICAL(flags); | ||
| 150 | old_ctx = read_c0_entryhi(); | ||
| 151 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); | ||
| 152 | write_c0_entrylo0(entrylo); | ||
| 153 | write_c0_entrylo1(entrylo); | ||
| 154 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 155 | set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); | ||
| 156 | /* preload TLB instead of local_flush_tlb_one() */ | ||
| 157 | mtc0_tlbw_hazard(); | ||
| 158 | tlb_probe(); | ||
| 159 | tlb_probe_hazard(); | ||
| 160 | tlbidx = read_c0_index(); | ||
| 161 | mtc0_tlbw_hazard(); | ||
| 162 | if (tlbidx < 0) | ||
| 163 | tlb_write_random(); | ||
| 164 | else | ||
| 165 | tlb_write_indexed(); | ||
| 166 | #else | ||
| 167 | tlbidx = read_c0_wired(); | ||
| 168 | write_c0_wired(tlbidx + 1); | ||
| 169 | write_c0_index(tlbidx); | ||
| 170 | mtc0_tlbw_hazard(); | ||
| 171 | tlb_write_indexed(); | ||
| 172 | #endif | ||
| 173 | tlbw_use_hazard(); | ||
| 174 | write_c0_entryhi(old_ctx); | ||
| 175 | EXIT_CRITICAL(flags); | ||
| 176 | |||
| 177 | return (void*) vaddr; | ||
| 178 | } | ||
| 179 | |||
| 180 | #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) | ||
| 181 | |||
| 182 | static inline void kunmap_coherent(struct page *page) | ||
| 183 | { | ||
| 184 | #ifndef CONFIG_MIPS_MT_SMTC | ||
| 185 | unsigned int wired; | ||
| 186 | unsigned long flags, old_ctx; | ||
| 187 | |||
| 188 | ENTER_CRITICAL(flags); | ||
| 189 | old_ctx = read_c0_entryhi(); | ||
| 190 | wired = read_c0_wired() - 1; | ||
| 191 | write_c0_wired(wired); | ||
| 192 | write_c0_index(wired); | ||
| 193 | write_c0_entryhi(UNIQUE_ENTRYHI(wired)); | ||
| 194 | write_c0_entrylo0(0); | ||
| 195 | write_c0_entrylo1(0); | ||
| 196 | mtc0_tlbw_hazard(); | ||
| 197 | tlb_write_indexed(); | ||
| 198 | tlbw_use_hazard(); | ||
| 199 | write_c0_entryhi(old_ctx); | ||
| 200 | EXIT_CRITICAL(flags); | ||
| 201 | #endif | ||
| 202 | dec_preempt_count(); | ||
| 203 | preempt_check_resched(); | ||
| 204 | } | ||
| 205 | |||
| 206 | void copy_to_user_page(struct vm_area_struct *vma, | ||
| 207 | struct page *page, unsigned long vaddr, void *dst, const void *src, | ||
| 208 | unsigned long len) | ||
| 209 | { | ||
| 210 | if (cpu_has_dc_aliases) { | ||
| 211 | void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); | ||
| 212 | memcpy(vto, src, len); | ||
| 213 | kunmap_coherent(page); | ||
| 214 | } else | ||
| 215 | memcpy(dst, src, len); | ||
| 216 | if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) | ||
| 217 | flush_cache_page(vma, vaddr, page_to_pfn(page)); | ||
| 218 | } | ||
| 219 | |||
| 220 | EXPORT_SYMBOL(copy_to_user_page); | ||
| 221 | |||
| 222 | void copy_from_user_page(struct vm_area_struct *vma, | ||
| 223 | struct page *page, unsigned long vaddr, void *dst, const void *src, | ||
| 224 | unsigned long len) | ||
| 225 | { | ||
| 226 | if (cpu_has_dc_aliases) { | ||
| 227 | void *vfrom = | ||
| 228 | kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); | ||
| 229 | memcpy(dst, vfrom, len); | ||
| 230 | kunmap_coherent(page); | ||
| 231 | } else | ||
| 232 | memcpy(dst, src, len); | ||
| 233 | } | ||
| 234 | |||
| 235 | EXPORT_SYMBOL(copy_from_user_page); | ||
| 236 | |||
| 237 | |||
| 238 | #ifdef CONFIG_HIGHMEM | ||
| 239 | pte_t *kmap_pte; | ||
| 240 | pgprot_t kmap_prot; | ||
| 241 | |||
| 90 | static void __init kmap_init(void) | 242 | static void __init kmap_init(void) |
| 91 | { | 243 | { |
| 92 | unsigned long kmap_vstart; | 244 | unsigned long kmap_vstart; |
| @@ -97,11 +249,12 @@ static void __init kmap_init(void) | |||
| 97 | 249 | ||
| 98 | kmap_prot = PAGE_KERNEL; | 250 | kmap_prot = PAGE_KERNEL; |
| 99 | } | 251 | } |
| 252 | #endif /* CONFIG_HIGHMEM */ | ||
| 100 | 253 | ||
| 101 | #ifdef CONFIG_32BIT | ||
| 102 | void __init fixrange_init(unsigned long start, unsigned long end, | 254 | void __init fixrange_init(unsigned long start, unsigned long end, |
| 103 | pgd_t *pgd_base) | 255 | pgd_t *pgd_base) |
| 104 | { | 256 | { |
| 257 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC) | ||
| 105 | pgd_t *pgd; | 258 | pgd_t *pgd; |
| 106 | pud_t *pud; | 259 | pud_t *pud; |
| 107 | pmd_t *pmd; | 260 | pmd_t *pmd; |
| @@ -122,7 +275,7 @@ void __init fixrange_init(unsigned long start, unsigned long end, | |||
| 122 | for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { | 275 | for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { |
| 123 | if (pmd_none(*pmd)) { | 276 | if (pmd_none(*pmd)) { |
| 124 | pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); | 277 | pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); |
| 125 | set_pmd(pmd, __pmd(pte)); | 278 | set_pmd(pmd, __pmd((unsigned long)pte)); |
| 126 | if (pte != pte_offset_kernel(pmd, 0)) | 279 | if (pte != pte_offset_kernel(pmd, 0)) |
| 127 | BUG(); | 280 | BUG(); |
| 128 | } | 281 | } |
| @@ -132,9 +285,8 @@ void __init fixrange_init(unsigned long start, unsigned long end, | |||
| 132 | } | 285 | } |
| 133 | j = 0; | 286 | j = 0; |
| 134 | } | 287 | } |
| 288 | #endif | ||
| 135 | } | 289 | } |
| 136 | #endif /* CONFIG_32BIT */ | ||
| 137 | #endif /* CONFIG_HIGHMEM */ | ||
| 138 | 290 | ||
| 139 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 291 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
| 140 | extern void pagetable_init(void); | 292 | extern void pagetable_init(void); |
| @@ -175,6 +327,7 @@ void __init paging_init(void) | |||
| 175 | #ifdef CONFIG_HIGHMEM | 327 | #ifdef CONFIG_HIGHMEM |
| 176 | kmap_init(); | 328 | kmap_init(); |
| 177 | #endif | 329 | #endif |
| 330 | kmap_coherent_init(); | ||
| 178 | 331 | ||
| 179 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 332 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
| 180 | low = max_low_pfn; | 333 | low = max_low_pfn; |
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index b7c749232ffe..d41fc5885e87 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c | |||
| @@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsigned long offset) | |||
| 270 | emit_instruction(mi); | 270 | emit_instruction(mi); |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | static inline void build_addiu_a2(unsigned long offset) | ||
| 274 | { | ||
| 275 | union mips_instruction mi; | ||
| 276 | |||
| 277 | BUG_ON(offset > 0x7fff); | ||
| 278 | |||
| 279 | mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; | ||
| 280 | mi.i_format.rs = 6; /* $a2 */ | ||
| 281 | mi.i_format.rt = 6; /* $a2 */ | ||
| 282 | mi.i_format.simmediate = offset; | ||
| 283 | |||
| 284 | emit_instruction(mi); | ||
| 285 | } | ||
| 286 | |||
| 273 | static inline void build_addiu_a1(unsigned long offset) | 287 | static inline void build_addiu_a1(unsigned long offset) |
| 274 | { | 288 | { |
| 275 | union mips_instruction mi; | 289 | union mips_instruction mi; |
| @@ -333,6 +347,7 @@ static inline void build_jr_ra(void) | |||
| 333 | void __init build_clear_page(void) | 347 | void __init build_clear_page(void) |
| 334 | { | 348 | { |
| 335 | unsigned int loop_start; | 349 | unsigned int loop_start; |
| 350 | unsigned long off; | ||
| 336 | 351 | ||
| 337 | epc = (unsigned int *) &clear_page_array; | 352 | epc = (unsigned int *) &clear_page_array; |
| 338 | instruction_pending = 0; | 353 | instruction_pending = 0; |
| @@ -369,7 +384,12 @@ void __init build_clear_page(void) | |||
| 369 | } | 384 | } |
| 370 | } | 385 | } |
| 371 | 386 | ||
| 372 | build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); | 387 | off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0); |
| 388 | if (off > 0x7fff) { | ||
| 389 | build_addiu_a2_a0(off >> 1); | ||
| 390 | build_addiu_a2(off >> 1); | ||
| 391 | } else | ||
| 392 | build_addiu_a2_a0(off); | ||
| 373 | 393 | ||
| 374 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) | 394 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) |
| 375 | build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ | 395 | build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ |
| @@ -420,12 +440,18 @@ dest = label(); | |||
| 420 | void __init build_copy_page(void) | 440 | void __init build_copy_page(void) |
| 421 | { | 441 | { |
| 422 | unsigned int loop_start; | 442 | unsigned int loop_start; |
| 443 | unsigned long off; | ||
| 423 | 444 | ||
| 424 | epc = (unsigned int *) ©_page_array; | 445 | epc = (unsigned int *) ©_page_array; |
| 425 | store_offset = load_offset = 0; | 446 | store_offset = load_offset = 0; |
| 426 | instruction_pending = 0; | 447 | instruction_pending = 0; |
| 427 | 448 | ||
| 428 | build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); | 449 | off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0); |
| 450 | if (off > 0x7fff) { | ||
| 451 | build_addiu_a2_a0(off >> 1); | ||
| 452 | build_addiu_a2(off >> 1); | ||
| 453 | } else | ||
| 454 | build_addiu_a2_a0(off); | ||
| 429 | 455 | ||
| 430 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) | 456 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) |
| 431 | build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ | 457 | build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ |
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index 4bdaa05f485b..4a61e624b0ec 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c | |||
| @@ -31,9 +31,10 @@ void pgd_init(unsigned long page) | |||
| 31 | 31 | ||
| 32 | void __init pagetable_init(void) | 32 | void __init pagetable_init(void) |
| 33 | { | 33 | { |
| 34 | #ifdef CONFIG_HIGHMEM | ||
| 35 | unsigned long vaddr; | 34 | unsigned long vaddr; |
| 36 | pgd_t *pgd, *pgd_base; | 35 | pgd_t *pgd_base; |
| 36 | #ifdef CONFIG_HIGHMEM | ||
| 37 | pgd_t *pgd; | ||
| 37 | pud_t *pud; | 38 | pud_t *pud; |
| 38 | pmd_t *pmd; | 39 | pmd_t *pmd; |
| 39 | pte_t *pte; | 40 | pte_t *pte; |
| @@ -44,7 +45,6 @@ void __init pagetable_init(void) | |||
| 44 | pgd_init((unsigned long)swapper_pg_dir | 45 | pgd_init((unsigned long)swapper_pg_dir |
| 45 | + sizeof(pgd_t) * USER_PTRS_PER_PGD); | 46 | + sizeof(pgd_t) * USER_PTRS_PER_PGD); |
| 46 | 47 | ||
| 47 | #ifdef CONFIG_HIGHMEM | ||
| 48 | pgd_base = swapper_pg_dir; | 48 | pgd_base = swapper_pg_dir; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| @@ -53,6 +53,7 @@ void __init pagetable_init(void) | |||
| 53 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; | 53 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; |
| 54 | fixrange_init(vaddr, 0, pgd_base); | 54 | fixrange_init(vaddr, 0, pgd_base); |
| 55 | 55 | ||
| 56 | #ifdef CONFIG_HIGHMEM | ||
| 56 | /* | 57 | /* |
| 57 | * Permanent kmaps: | 58 | * Permanent kmaps: |
| 58 | */ | 59 | */ |
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 44b5e97fff65..8d600d307d5d 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
| 11 | #include <asm/fixmap.h> | ||
| 11 | #include <asm/pgtable.h> | 12 | #include <asm/pgtable.h> |
| 12 | 13 | ||
| 13 | void pgd_init(unsigned long page) | 14 | void pgd_init(unsigned long page) |
| @@ -52,7 +53,17 @@ void pmd_init(unsigned long addr, unsigned long pagetable) | |||
| 52 | 53 | ||
| 53 | void __init pagetable_init(void) | 54 | void __init pagetable_init(void) |
| 54 | { | 55 | { |
| 56 | unsigned long vaddr; | ||
| 57 | pgd_t *pgd_base; | ||
| 58 | |||
| 55 | /* Initialize the entire pgd. */ | 59 | /* Initialize the entire pgd. */ |
| 56 | pgd_init((unsigned long)swapper_pg_dir); | 60 | pgd_init((unsigned long)swapper_pg_dir); |
| 57 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); | 61 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); |
| 62 | |||
| 63 | pgd_base = swapper_pg_dir; | ||
| 64 | /* | ||
| 65 | * Fixed mappings: | ||
| 66 | */ | ||
| 67 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; | ||
| 68 | fixrange_init(vaddr, 0, pgd_base); | ||
| 58 | } | 69 | } |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 6f8b25cfa6f0..fec318a1c8c5 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
| @@ -102,7 +102,7 @@ enum opcode { | |||
| 102 | insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, | 102 | insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, |
| 103 | insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, | 103 | insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, |
| 104 | insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, | 104 | insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, |
| 105 | insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, | 105 | insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, |
| 106 | insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, | 106 | insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, |
| 107 | insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, | 107 | insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, |
| 108 | insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, | 108 | insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, |
| @@ -145,6 +145,7 @@ static __initdata struct insn insn_table[] = { | |||
| 145 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, | 145 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, |
| 146 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, | 146 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, |
| 147 | { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, | 147 | { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, |
| 148 | { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE }, | ||
| 148 | { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, | 149 | { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, |
| 149 | { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, | 150 | { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, |
| 150 | { insn_j, M(j_op,0,0,0,0,0), JIMM }, | 151 | { insn_j, M(j_op,0,0,0,0,0), JIMM }, |
| @@ -385,6 +386,7 @@ I_u2u1u3(_dsll); | |||
| 385 | I_u2u1u3(_dsll32); | 386 | I_u2u1u3(_dsll32); |
| 386 | I_u2u1u3(_dsra); | 387 | I_u2u1u3(_dsra); |
| 387 | I_u2u1u3(_dsrl); | 388 | I_u2u1u3(_dsrl); |
| 389 | I_u2u1u3(_dsrl32); | ||
| 388 | I_u3u1u2(_dsubu); | 390 | I_u3u1u2(_dsubu); |
| 389 | I_0(_eret); | 391 | I_0(_eret); |
| 390 | I_u1(_j); | 392 | I_u1(_j); |
| @@ -996,7 +998,12 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, | |||
| 996 | #endif | 998 | #endif |
| 997 | 999 | ||
| 998 | l_vmalloc_done(l, *p); | 1000 | l_vmalloc_done(l, *p); |
| 999 | i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ | 1001 | |
| 1002 | if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */ | ||
| 1003 | i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); | ||
| 1004 | else | ||
| 1005 | i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32); | ||
| 1006 | |||
| 1000 | i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); | 1007 | i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); |
| 1001 | i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ | 1008 | i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ |
| 1002 | i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ | 1009 | i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ |
| @@ -1073,7 +1080,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) | |||
| 1073 | 1080 | ||
| 1074 | static __init void build_adjust_context(u32 **p, unsigned int ctx) | 1081 | static __init void build_adjust_context(u32 **p, unsigned int ctx) |
| 1075 | { | 1082 | { |
| 1076 | unsigned int shift = 4 - (PTE_T_LOG2 + 1); | 1083 | unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; |
| 1077 | unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); | 1084 | unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); |
| 1078 | 1085 | ||
| 1079 | switch (current_cpu_data.cputype) { | 1086 | switch (current_cpu_data.cputype) { |
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile index 8bcea64dd27b..d5a090a85a15 100644 --- a/arch/mips/momentum/ocelot_3/Makefile +++ b/arch/mips/momentum/ocelot_3/Makefile | |||
| @@ -5,4 +5,4 @@ | |||
| 5 | # removes any old dependencies. DON'T put your own dependencies here | 5 | # removes any old dependencies. DON'T put your own dependencies here |
| 6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
| 7 | # | 7 | # |
| 8 | obj-y += irq.o prom.o reset.o setup.o | 8 | obj-y += irq.o platform.o prom.o reset.o setup.o |
diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h index 227e429fe720..5710a9029f1c 100644 --- a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h +++ b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h | |||
| @@ -51,7 +51,9 @@ | |||
| 51 | 51 | ||
| 52 | extern unsigned long ocelot_fpga_base; | 52 | extern unsigned long ocelot_fpga_base; |
| 53 | 53 | ||
| 54 | #define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y) | 54 | #define __FPGA_REG_TO_ADDR(reg) \ |
| 55 | #define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x) | 55 | ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg) |
| 56 | #define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) | ||
| 57 | #define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) | ||
| 56 | 58 | ||
| 57 | #endif | 59 | #endif |
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c new file mode 100644 index 000000000000..eefe5841fbb2 --- /dev/null +++ b/arch/mips/momentum/ocelot_3/platform.c | |||
| @@ -0,0 +1,235 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/if_ether.h> | ||
| 3 | #include <linux/ioport.h> | ||
| 4 | #include <linux/mv643xx.h> | ||
| 5 | #include <linux/platform_device.h> | ||
| 6 | |||
| 7 | #include "ocelot_3_fpga.h" | ||
| 8 | |||
| 9 | #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) | ||
| 10 | |||
| 11 | static struct resource mv643xx_eth_shared_resources[] = { | ||
| 12 | [0] = { | ||
| 13 | .name = "ethernet shared base", | ||
| 14 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, | ||
| 15 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + | ||
| 16 | MV643XX_ETH_SHARED_REGS_SIZE - 1, | ||
| 17 | .flags = IORESOURCE_MEM, | ||
| 18 | }, | ||
| 19 | }; | ||
| 20 | |||
| 21 | static struct platform_device mv643xx_eth_shared_device = { | ||
| 22 | .name = MV643XX_ETH_SHARED_NAME, | ||
| 23 | .id = 0, | ||
| 24 | .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), | ||
| 25 | .resource = mv643xx_eth_shared_resources, | ||
| 26 | }; | ||
| 27 | |||
| 28 | #define MV_SRAM_BASE 0xfe000000UL | ||
| 29 | #define MV_SRAM_SIZE (256 * 1024) | ||
| 30 | |||
| 31 | #define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 32 | #define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 33 | |||
| 34 | #define MV_SRAM_BASE_ETH0 MV_SRAM_BASE | ||
| 35 | #define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) | ||
| 36 | |||
| 37 | #define MV64x60_IRQ_ETH_0 48 | ||
| 38 | #define MV64x60_IRQ_ETH_1 49 | ||
| 39 | #define MV64x60_IRQ_ETH_2 50 | ||
| 40 | |||
| 41 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 42 | |||
| 43 | static struct resource mv64x60_eth0_resources[] = { | ||
| 44 | [0] = { | ||
| 45 | .name = "eth0 irq", | ||
| 46 | .start = MV64x60_IRQ_ETH_0, | ||
| 47 | .end = MV64x60_IRQ_ETH_0, | ||
| 48 | .flags = IORESOURCE_IRQ, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static char eth0_mac_addr[ETH_ALEN]; | ||
| 53 | |||
| 54 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
| 55 | .mac_addr = eth0_mac_addr, | ||
| 56 | |||
| 57 | .tx_sram_addr = MV_SRAM_BASE_ETH0, | ||
| 58 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 59 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 60 | |||
| 61 | .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, | ||
| 62 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 63 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct platform_device eth0_device = { | ||
| 67 | .name = MV643XX_ETH_NAME, | ||
| 68 | .id = 0, | ||
| 69 | .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), | ||
| 70 | .resource = mv64x60_eth0_resources, | ||
| 71 | .dev = { | ||
| 72 | .platform_data = ð0_pd, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | #endif /* CONFIG_MV643XX_ETH_0 */ | ||
| 76 | |||
| 77 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 78 | |||
| 79 | static struct resource mv64x60_eth1_resources[] = { | ||
| 80 | [0] = { | ||
| 81 | .name = "eth1 irq", | ||
| 82 | .start = MV64x60_IRQ_ETH_1, | ||
| 83 | .end = MV64x60_IRQ_ETH_1, | ||
| 84 | .flags = IORESOURCE_IRQ, | ||
| 85 | }, | ||
| 86 | }; | ||
| 87 | |||
| 88 | static char eth1_mac_addr[ETH_ALEN]; | ||
| 89 | |||
| 90 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
| 91 | .mac_addr = eth1_mac_addr, | ||
| 92 | |||
| 93 | .tx_sram_addr = MV_SRAM_BASE_ETH1, | ||
| 94 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 95 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 96 | |||
| 97 | .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, | ||
| 98 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 99 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct platform_device eth1_device = { | ||
| 103 | .name = MV643XX_ETH_NAME, | ||
| 104 | .id = 1, | ||
| 105 | .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), | ||
| 106 | .resource = mv64x60_eth1_resources, | ||
| 107 | .dev = { | ||
| 108 | .platform_data = ð1_pd, | ||
| 109 | }, | ||
| 110 | }; | ||
| 111 | #endif /* CONFIG_MV643XX_ETH_1 */ | ||
| 112 | |||
| 113 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 114 | |||
| 115 | static struct resource mv64x60_eth2_resources[] = { | ||
| 116 | [0] = { | ||
| 117 | .name = "eth2 irq", | ||
| 118 | .start = MV64x60_IRQ_ETH_2, | ||
| 119 | .end = MV64x60_IRQ_ETH_2, | ||
| 120 | .flags = IORESOURCE_IRQ, | ||
| 121 | }, | ||
| 122 | }; | ||
| 123 | |||
| 124 | static char eth2_mac_addr[ETH_ALEN]; | ||
| 125 | |||
| 126 | static struct mv643xx_eth_platform_data eth2_pd = { | ||
| 127 | .mac_addr = eth2_mac_addr, | ||
| 128 | }; | ||
| 129 | |||
| 130 | static struct platform_device eth2_device = { | ||
| 131 | .name = MV643XX_ETH_NAME, | ||
| 132 | .id = 1, | ||
| 133 | .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), | ||
| 134 | .resource = mv64x60_eth2_resources, | ||
| 135 | .dev = { | ||
| 136 | .platform_data = ð2_pd, | ||
| 137 | }, | ||
| 138 | }; | ||
| 139 | #endif /* CONFIG_MV643XX_ETH_2 */ | ||
| 140 | |||
| 141 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | ||
| 142 | &mv643xx_eth_shared_device, | ||
| 143 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 144 | ð0_device, | ||
| 145 | #endif | ||
| 146 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 147 | ð1_device, | ||
| 148 | #endif | ||
| 149 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 150 | ð2_device, | ||
| 151 | #endif | ||
| 152 | }; | ||
| 153 | |||
| 154 | static u8 __init exchange_bit(u8 val, u8 cs) | ||
| 155 | { | ||
| 156 | /* place the data */ | ||
| 157 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 158 | udelay(1); | ||
| 159 | |||
| 160 | /* turn the clock on */ | ||
| 161 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 162 | udelay(1); | ||
| 163 | |||
| 164 | /* turn the clock off and read-strobe */ | ||
| 165 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 166 | |||
| 167 | /* return the data */ | ||
| 168 | return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; | ||
| 169 | } | ||
| 170 | |||
| 171 | static void __init get_mac(char dest[6]) | ||
| 172 | { | ||
| 173 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 174 | int i,j; | ||
| 175 | |||
| 176 | for (i = 0; i < 12; i++) | ||
| 177 | exchange_bit(read_opcode[i], 1); | ||
| 178 | |||
| 179 | for (j = 0; j < 6; j++) { | ||
| 180 | dest[j] = 0; | ||
| 181 | for (i = 0; i < 8; i++) { | ||
| 182 | dest[j] <<= 1; | ||
| 183 | dest[j] |= exchange_bit(0, 1); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | /* turn off CS */ | ||
| 188 | exchange_bit(0,0); | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | * Copy and increment ethernet MAC address by a small value. | ||
| 193 | * | ||
| 194 | * This is useful for systems where the only one MAC address is stored in | ||
| 195 | * non-volatile memory for multiple ports. | ||
| 196 | */ | ||
| 197 | static inline void eth_mac_add(unsigned char *dst, unsigned char *src, | ||
| 198 | unsigned int add) | ||
| 199 | { | ||
| 200 | int i; | ||
| 201 | |||
| 202 | BUG_ON(add >= 256); | ||
| 203 | |||
| 204 | for (i = ETH_ALEN; i >= 0; i--) { | ||
| 205 | dst[i] = src[i] + add; | ||
| 206 | add = dst[i] < src[i]; /* compute carry */ | ||
| 207 | } | ||
| 208 | |||
| 209 | WARN_ON(add); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int __init mv643xx_eth_add_pds(void) | ||
| 213 | { | ||
| 214 | unsigned char mac[ETH_ALEN]; | ||
| 215 | int ret; | ||
| 216 | |||
| 217 | get_mac(mac); | ||
| 218 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 219 | eth_mac_add(eth1_mac_addr, mac, 0); | ||
| 220 | #endif | ||
| 221 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 222 | eth_mac_add(eth1_mac_addr, mac, 1); | ||
| 223 | #endif | ||
| 224 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 225 | eth_mac_add(eth2_mac_addr, mac, 2); | ||
| 226 | #endif | ||
| 227 | ret = platform_add_devices(mv643xx_eth_pd_devs, | ||
| 228 | ARRAY_SIZE(mv643xx_eth_pd_devs)); | ||
| 229 | |||
| 230 | return ret; | ||
| 231 | } | ||
| 232 | |||
| 233 | device_initcall(mv643xx_eth_add_pds); | ||
| 234 | |||
| 235 | #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ | ||
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c index 296d945bc248..6ce9b7fdb824 100644 --- a/arch/mips/momentum/ocelot_3/prom.c +++ b/arch/mips/momentum/ocelot_3/prom.c | |||
| @@ -34,64 +34,11 @@ struct callvectors* debug_vectors; | |||
| 34 | extern unsigned long marvell_base; | 34 | extern unsigned long marvell_base; |
| 35 | extern unsigned long cpu_clock; | 35 | extern unsigned long cpu_clock; |
| 36 | 36 | ||
| 37 | #ifdef CONFIG_MV643XX_ETH | ||
| 38 | extern unsigned char prom_mac_addr_base[6]; | ||
| 39 | #endif | ||
| 40 | |||
| 41 | const char *get_system_type(void) | 37 | const char *get_system_type(void) |
| 42 | { | 38 | { |
| 43 | return "Momentum Ocelot-3"; | 39 | return "Momentum Ocelot-3"; |
| 44 | } | 40 | } |
| 45 | 41 | ||
| 46 | #ifdef CONFIG_MV643XX_ETH | ||
| 47 | void burn_clocks(void) | ||
| 48 | { | ||
| 49 | int i; | ||
| 50 | |||
| 51 | /* this loop should burn at least 1us -- this should be plenty */ | ||
| 52 | for (i = 0; i < 0x10000; i++) | ||
| 53 | ; | ||
| 54 | } | ||
| 55 | |||
| 56 | u8 exchange_bit(u8 val, u8 cs) | ||
| 57 | { | ||
| 58 | /* place the data */ | ||
| 59 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 60 | burn_clocks(); | ||
| 61 | |||
| 62 | /* turn the clock on */ | ||
| 63 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 64 | burn_clocks(); | ||
| 65 | |||
| 66 | /* turn the clock off and read-strobe */ | ||
| 67 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 68 | |||
| 69 | /* return the data */ | ||
| 70 | return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); | ||
| 71 | } | ||
| 72 | |||
| 73 | void get_mac(char dest[6]) | ||
| 74 | { | ||
| 75 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 76 | int i,j; | ||
| 77 | |||
| 78 | for (i = 0; i < 12; i++) | ||
| 79 | exchange_bit(read_opcode[i], 1); | ||
| 80 | |||
| 81 | for (j = 0; j < 6; j++) { | ||
| 82 | dest[j] = 0; | ||
| 83 | for (i = 0; i < 8; i++) { | ||
| 84 | dest[j] <<= 1; | ||
| 85 | dest[j] |= exchange_bit(0, 1); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /* turn off CS */ | ||
| 90 | exchange_bit(0,0); | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | |||
| 94 | |||
| 95 | #ifdef CONFIG_64BIT | 42 | #ifdef CONFIG_64BIT |
| 96 | 43 | ||
| 97 | unsigned long signext(unsigned long addr) | 44 | unsigned long signext(unsigned long addr) |
| @@ -228,11 +175,6 @@ void __init prom_init(void) | |||
| 228 | mips_machgroup = MACH_GROUP_MOMENCO; | 175 | mips_machgroup = MACH_GROUP_MOMENCO; |
| 229 | mips_machtype = MACH_MOMENCO_OCELOT_3; | 176 | mips_machtype = MACH_MOMENCO_OCELOT_3; |
| 230 | 177 | ||
| 231 | #ifdef CONFIG_MV643XX_ETH | ||
| 232 | /* get the base MAC address for on-board ethernet ports */ | ||
| 233 | get_mac(prom_mac_addr_base); | ||
| 234 | #endif | ||
| 235 | |||
| 236 | #ifndef CONFIG_64BIT | 178 | #ifndef CONFIG_64BIT |
| 237 | debug_vectors->printf("Booting Linux kernel...\n"); | 179 | debug_vectors->printf("Booting Linux kernel...\n"); |
| 238 | #endif | 180 | #endif |
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index 7d74f8c54129..ff0829f81116 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * BRIEF MODULE DESCRIPTION | 4 | * BRIEF MODULE DESCRIPTION |
| 5 | * Momentum Computer Ocelot-3 board dependent boot routines | 5 | * Momentum Computer Ocelot-3 board dependent boot routines |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 1996, 1997, 01, 05 Ralf Baechle | 7 | * Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle |
| 8 | * Copyright (C) 2000 RidgeRun, Inc. | 8 | * Copyright (C) 2000 RidgeRun, Inc. |
| 9 | * Copyright (C) 2001 Red Hat, Inc. | 9 | * Copyright (C) 2001 Red Hat, Inc. |
| 10 | * Copyright (C) 2002 Momentum Computer | 10 | * Copyright (C) 2002 Momentum Computer |
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 94802b4db472..d69161aa1675 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. | 2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y += cpci-irq.o irq.o prom.o reset.o \ | 5 | obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \ |
| 6 | setup.o uart-irq.o | 6 | setup.o uart-irq.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_KGDB) += dbg_io.o | 8 | obj-$(CONFIG_KGDB) += dbg_io.o |
diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h index 7228cd19e5ea..f0f5581dcb50 100644 --- a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h +++ b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h | |||
| @@ -53,7 +53,9 @@ | |||
| 53 | #define OCELOT_C_REG_INTSET 0xe | 53 | #define OCELOT_C_REG_INTSET 0xe |
| 54 | #define OCELOT_C_REG_INTCLR 0xf | 54 | #define OCELOT_C_REG_INTCLR 0xf |
| 55 | 55 | ||
| 56 | #define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) | 56 | #define __FPGA_REG_TO_ADDR(reg) \ |
| 57 | #define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) | 57 | ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg) |
| 58 | #define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) | ||
| 59 | #define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) | ||
| 58 | 60 | ||
| 59 | #endif | 61 | #endif |
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c new file mode 100644 index 000000000000..6c495b2f1560 --- /dev/null +++ b/arch/mips/momentum/ocelot_c/platform.c | |||
| @@ -0,0 +1,201 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/if_ether.h> | ||
| 3 | #include <linux/ioport.h> | ||
| 4 | #include <linux/mv643xx.h> | ||
| 5 | #include <linux/platform_device.h> | ||
| 6 | |||
| 7 | #include "ocelot_c_fpga.h" | ||
| 8 | |||
| 9 | #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) | ||
| 10 | |||
| 11 | static struct resource mv643xx_eth_shared_resources[] = { | ||
| 12 | [0] = { | ||
| 13 | .name = "ethernet shared base", | ||
| 14 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, | ||
| 15 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + | ||
| 16 | MV643XX_ETH_SHARED_REGS_SIZE - 1, | ||
| 17 | .flags = IORESOURCE_MEM, | ||
| 18 | }, | ||
| 19 | }; | ||
| 20 | |||
| 21 | static struct platform_device mv643xx_eth_shared_device = { | ||
| 22 | .name = MV643XX_ETH_SHARED_NAME, | ||
| 23 | .id = 0, | ||
| 24 | .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), | ||
| 25 | .resource = mv643xx_eth_shared_resources, | ||
| 26 | }; | ||
| 27 | |||
| 28 | #define MV_SRAM_BASE 0xfe000000UL | ||
| 29 | #define MV_SRAM_SIZE (256 * 1024) | ||
| 30 | |||
| 31 | #define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 32 | #define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 33 | |||
| 34 | #define MV_SRAM_BASE_ETH0 MV_SRAM_BASE | ||
| 35 | #define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) | ||
| 36 | |||
| 37 | #define MV64x60_IRQ_ETH_0 48 | ||
| 38 | #define MV64x60_IRQ_ETH_1 49 | ||
| 39 | |||
| 40 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 41 | |||
| 42 | static struct resource mv64x60_eth0_resources[] = { | ||
| 43 | [0] = { | ||
| 44 | .name = "eth0 irq", | ||
| 45 | .start = MV64x60_IRQ_ETH_0, | ||
| 46 | .end = MV64x60_IRQ_ETH_0, | ||
| 47 | .flags = IORESOURCE_IRQ, | ||
| 48 | }, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static char eth0_mac_addr[ETH_ALEN]; | ||
| 52 | |||
| 53 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
| 54 | .mac_addr = eth0_mac_addr, | ||
| 55 | |||
| 56 | .tx_sram_addr = MV_SRAM_BASE_ETH0, | ||
| 57 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 58 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 59 | |||
| 60 | .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, | ||
| 61 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 62 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct platform_device eth0_device = { | ||
| 66 | .name = MV643XX_ETH_NAME, | ||
| 67 | .id = 0, | ||
| 68 | .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), | ||
| 69 | .resource = mv64x60_eth0_resources, | ||
| 70 | .dev = { | ||
| 71 | .platform_data = ð0_pd, | ||
| 72 | }, | ||
| 73 | }; | ||
| 74 | #endif /* CONFIG_MV643XX_ETH_0 */ | ||
| 75 | |||
| 76 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 77 | |||
| 78 | static struct resource mv64x60_eth1_resources[] = { | ||
| 79 | [0] = { | ||
| 80 | .name = "eth1 irq", | ||
| 81 | .start = MV64x60_IRQ_ETH_1, | ||
| 82 | .end = MV64x60_IRQ_ETH_1, | ||
| 83 | .flags = IORESOURCE_IRQ, | ||
| 84 | }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static char eth1_mac_addr[ETH_ALEN]; | ||
| 88 | |||
| 89 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
| 90 | .mac_addr = eth1_mac_addr, | ||
| 91 | |||
| 92 | .tx_sram_addr = MV_SRAM_BASE_ETH1, | ||
| 93 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 94 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 95 | |||
| 96 | .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, | ||
| 97 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 98 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct platform_device eth1_device = { | ||
| 102 | .name = MV643XX_ETH_NAME, | ||
| 103 | .id = 1, | ||
| 104 | .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), | ||
| 105 | .resource = mv64x60_eth1_resources, | ||
| 106 | .dev = { | ||
| 107 | .platform_data = ð1_pd, | ||
| 108 | }, | ||
| 109 | }; | ||
| 110 | #endif /* CONFIG_MV643XX_ETH_1 */ | ||
| 111 | |||
| 112 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | ||
| 113 | &mv643xx_eth_shared_device, | ||
| 114 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 115 | ð0_device, | ||
| 116 | #endif | ||
| 117 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 118 | ð1_device, | ||
| 119 | #endif | ||
| 120 | /* The third port is not wired up on the Ocelot C */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | static u8 __init exchange_bit(u8 val, u8 cs) | ||
| 124 | { | ||
| 125 | /* place the data */ | ||
| 126 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 127 | udelay(1); | ||
| 128 | |||
| 129 | /* turn the clock on */ | ||
| 130 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 131 | udelay(1); | ||
| 132 | |||
| 133 | /* turn the clock off and read-strobe */ | ||
| 134 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 135 | |||
| 136 | /* return the data */ | ||
| 137 | return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; | ||
| 138 | } | ||
| 139 | |||
| 140 | static void __init get_mac(char dest[6]) | ||
| 141 | { | ||
| 142 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 143 | int i,j; | ||
| 144 | |||
| 145 | for (i = 0; i < 12; i++) | ||
| 146 | exchange_bit(read_opcode[i], 1); | ||
| 147 | |||
| 148 | for (j = 0; j < 6; j++) { | ||
| 149 | dest[j] = 0; | ||
| 150 | for (i = 0; i < 8; i++) { | ||
| 151 | dest[j] <<= 1; | ||
| 152 | dest[j] |= exchange_bit(0, 1); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | /* turn off CS */ | ||
| 157 | exchange_bit(0,0); | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Copy and increment ethernet MAC address by a small value. | ||
| 162 | * | ||
| 163 | * This is useful for systems where the only one MAC address is stored in | ||
| 164 | * non-volatile memory for multiple ports. | ||
| 165 | */ | ||
| 166 | static inline void eth_mac_add(unsigned char *dst, unsigned char *src, | ||
| 167 | unsigned int add) | ||
| 168 | { | ||
| 169 | int i; | ||
| 170 | |||
| 171 | BUG_ON(add >= 256); | ||
| 172 | |||
| 173 | for (i = ETH_ALEN; i >= 0; i--) { | ||
| 174 | dst[i] = src[i] + add; | ||
| 175 | add = dst[i] < src[i]; /* compute carry */ | ||
| 176 | } | ||
| 177 | |||
| 178 | WARN_ON(add); | ||
| 179 | } | ||
| 180 | |||
| 181 | static int __init mv643xx_eth_add_pds(void) | ||
| 182 | { | ||
| 183 | unsigned char mac[ETH_ALEN]; | ||
| 184 | int ret; | ||
| 185 | |||
| 186 | get_mac(mac); | ||
| 187 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 188 | eth_mac_add(eth1_mac_addr, mac, 0); | ||
| 189 | #endif | ||
| 190 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 191 | eth_mac_add(eth1_mac_addr, mac, 1); | ||
| 192 | #endif | ||
| 193 | ret = platform_add_devices(mv643xx_eth_pd_devs, | ||
| 194 | ARRAY_SIZE(mv643xx_eth_pd_devs)); | ||
| 195 | |||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | device_initcall(mv643xx_eth_add_pds); | ||
| 200 | |||
| 201 | #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ | ||
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 4c50a147f429..d0b77e101d74 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c | |||
| @@ -29,11 +29,7 @@ | |||
| 29 | struct callvectors* debug_vectors; | 29 | struct callvectors* debug_vectors; |
| 30 | 30 | ||
| 31 | extern unsigned long marvell_base; | 31 | extern unsigned long marvell_base; |
| 32 | extern unsigned long cpu_clock; | 32 | extern unsigned int cpu_clock; |
| 33 | |||
| 34 | #ifdef CONFIG_MV643XX_ETH | ||
| 35 | extern unsigned char prom_mac_addr_base[6]; | ||
| 36 | #endif | ||
| 37 | 33 | ||
| 38 | const char *get_system_type(void) | 34 | const char *get_system_type(void) |
| 39 | { | 35 | { |
| @@ -44,55 +40,6 @@ const char *get_system_type(void) | |||
| 44 | #endif | 40 | #endif |
| 45 | } | 41 | } |
| 46 | 42 | ||
| 47 | #ifdef CONFIG_MV643XX_ETH | ||
| 48 | static void burn_clocks(void) | ||
| 49 | { | ||
| 50 | int i; | ||
| 51 | |||
| 52 | /* this loop should burn at least 1us -- this should be plenty */ | ||
| 53 | for (i = 0; i < 0x10000; i++) | ||
| 54 | ; | ||
| 55 | } | ||
| 56 | |||
| 57 | static u8 exchange_bit(u8 val, u8 cs) | ||
| 58 | { | ||
| 59 | /* place the data */ | ||
| 60 | OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 61 | burn_clocks(); | ||
| 62 | |||
| 63 | /* turn the clock on */ | ||
| 64 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 65 | burn_clocks(); | ||
| 66 | |||
| 67 | /* turn the clock off and read-strobe */ | ||
| 68 | OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 69 | |||
| 70 | /* return the data */ | ||
| 71 | return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); | ||
| 72 | } | ||
| 73 | |||
| 74 | void get_mac(char dest[6]) | ||
| 75 | { | ||
| 76 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 77 | int i,j; | ||
| 78 | |||
| 79 | for (i = 0; i < 12; i++) | ||
| 80 | exchange_bit(read_opcode[i], 1); | ||
| 81 | |||
| 82 | for (j = 0; j < 6; j++) { | ||
| 83 | dest[j] = 0; | ||
| 84 | for (i = 0; i < 8; i++) { | ||
| 85 | dest[j] <<= 1; | ||
| 86 | dest[j] |= exchange_bit(0, 1); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | /* turn off CS */ | ||
| 91 | exchange_bit(0,0); | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | |||
| 95 | |||
| 96 | #ifdef CONFIG_64BIT | 43 | #ifdef CONFIG_64BIT |
| 97 | 44 | ||
| 98 | unsigned long signext(unsigned long addr) | 45 | unsigned long signext(unsigned long addr) |
| @@ -226,11 +173,6 @@ void __init prom_init(void) | |||
| 226 | mips_machgroup = MACH_GROUP_MOMENCO; | 173 | mips_machgroup = MACH_GROUP_MOMENCO; |
| 227 | mips_machtype = MACH_MOMENCO_OCELOT_C; | 174 | mips_machtype = MACH_MOMENCO_OCELOT_C; |
| 228 | 175 | ||
| 229 | #ifdef CONFIG_MV643XX_ETH | ||
| 230 | /* get the base MAC address for on-board ethernet ports */ | ||
| 231 | get_mac(prom_mac_addr_base); | ||
| 232 | #endif | ||
| 233 | |||
| 234 | #ifndef CONFIG_64BIT | 176 | #ifndef CONFIG_64BIT |
| 235 | debug_vectors->printf("Booting Linux kernel...\n"); | 177 | debug_vectors->printf("Booting Linux kernel...\n"); |
| 236 | #endif | 178 | #endif |
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 9c0c462af650..0b6b2338cfb4 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c | |||
| @@ -69,8 +69,7 @@ | |||
| 69 | #include "ocelot_c_fpga.h" | 69 | #include "ocelot_c_fpga.h" |
| 70 | 70 | ||
| 71 | unsigned long marvell_base; | 71 | unsigned long marvell_base; |
| 72 | extern unsigned long mv64340_sram_base; | 72 | unsigned int cpu_clock; |
| 73 | unsigned long cpu_clock; | ||
| 74 | 73 | ||
| 75 | /* These functions are used for rebooting or halting the machine*/ | 74 | /* These functions are used for rebooting or halting the machine*/ |
| 76 | extern void momenco_ocelot_restart(char *command); | 75 | extern void momenco_ocelot_restart(char *command); |
| @@ -119,7 +118,6 @@ void PMON_v2_setup(void) | |||
| 119 | add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); | 118 | add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); |
| 120 | 119 | ||
| 121 | marvell_base = 0xfffffffff4000000; | 120 | marvell_base = 0xfffffffff4000000; |
| 122 | mv64340_sram_base = 0xfffffffffe000000; | ||
| 123 | #else | 121 | #else |
| 124 | /* marvell and extra space */ | 122 | /* marvell and extra space */ |
| 125 | add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); | 123 | add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); |
| @@ -129,7 +127,6 @@ void PMON_v2_setup(void) | |||
| 129 | add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); | 127 | add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); |
| 130 | 128 | ||
| 131 | marvell_base = 0xf4000000; | 129 | marvell_base = 0xf4000000; |
| 132 | mv64340_sram_base = 0xfe000000; | ||
| 133 | #endif | 130 | #endif |
| 134 | } | 131 | } |
| 135 | 132 | ||
| @@ -346,22 +343,20 @@ void __init plat_mem_setup(void) | |||
| 346 | } | 343 | } |
| 347 | } | 344 | } |
| 348 | 345 | ||
| 349 | #ifndef CONFIG_64BIT | 346 | /* |
| 350 | /* This needs to be one of the first initcalls, because no I/O port access | 347 | * This needs to be one of the first initcalls, because no I/O port access |
| 351 | can work before this */ | 348 | * can work before this |
| 349 | */ | ||
| 352 | static int io_base_ioremap(void) | 350 | static int io_base_ioremap(void) |
| 353 | { | 351 | { |
| 354 | /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ | 352 | void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000); |
| 355 | void *io_remap_range = ioremap(0xc0000000, 0x30000000); | ||
| 356 | 353 | ||
| 357 | if (!io_remap_range) { | 354 | if (!io_remap_range) |
| 358 | panic("Could not ioremap I/O port range"); | 355 | panic("Could not ioremap I/O port range"); |
| 359 | } | 356 | |
| 360 | printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); | 357 | set_io_port_base((unsigned long) io_remap_range); |
| 361 | set_io_port_base(io_remap_range - 0xc0000000); | ||
| 362 | 358 | ||
| 363 | return 0; | 359 | return 0; |
| 364 | } | 360 | } |
| 365 | 361 | ||
| 366 | module_init(io_base_ioremap); | 362 | module_init(io_base_ioremap); |
| 367 | #endif | ||
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c index 7b5cc6648f7e..e5576bd50fa9 100644 --- a/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/arch/mips/momentum/ocelot_g/gt-irq.c | |||
| @@ -27,7 +27,7 @@ unsigned long bus_clock; | |||
| 27 | * be handled and ack'ed differently than other MIPS interrupts. | 27 | * be handled and ack'ed differently than other MIPS interrupts. |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #if CURRENTLY_UNUSED | 30 | #if 0 |
| 31 | 31 | ||
| 32 | struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; | 32 | struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; |
| 33 | void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); | 33 | void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); |
| @@ -95,7 +95,7 @@ int disable_galileo_irq(int int_cause, int bit_num) | |||
| 95 | return 0; | 95 | return 0; |
| 96 | return 1; | 96 | return 1; |
| 97 | } | 97 | } |
| 98 | #endif /* UNUSED */ | 98 | #endif /* 0 */ |
| 99 | 99 | ||
| 100 | /* | 100 | /* |
| 101 | * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#. | 101 | * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#. |
| @@ -196,7 +196,7 @@ void gt64240_time_init(void) | |||
| 196 | 196 | ||
| 197 | void gt64240_irq_init(void) | 197 | void gt64240_irq_init(void) |
| 198 | { | 198 | { |
| 199 | #if CURRENTLY_UNUSED | 199 | #if 0 |
| 200 | int i, j; | 200 | int i, j; |
| 201 | 201 | ||
| 202 | /* Reset irq handlers pointers to NULL */ | 202 | /* Reset irq handlers pointers to NULL */ |
| @@ -208,5 +208,5 @@ void gt64240_irq_init(void) | |||
| 208 | irq_handlers[i][j].data = NULL; | 208 | irq_handlers[i][j].data = NULL; |
| 209 | } | 209 | } |
| 210 | } | 210 | } |
| 211 | #endif | 211 | #endif /* 0 */ |
| 212 | } | 212 | } |
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h index fcb8275e219d..95e0534026d0 100644 --- a/arch/mips/momentum/ocelot_g/ocelot_pld.h +++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h | |||
| @@ -23,8 +23,8 @@ | |||
| 23 | #define OCELOT_REG_INTSET (12) | 23 | #define OCELOT_REG_INTSET (12) |
| 24 | #define OCELOT_REG_INTCLR (13) | 24 | #define OCELOT_REG_INTCLR (13) |
| 25 | 25 | ||
| 26 | #define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y) | 26 | #define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg) |
| 27 | #define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x) | 27 | #define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg)) |
| 28 | 28 | #define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg)) | |
| 29 | 29 | ||
| 30 | #endif /* __MOMENCO_OCELOT_PLD_H__ */ | 30 | #endif /* __MOMENCO_OCELOT_PLD_H__ */ |
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c index 56ec47039c16..d288f7b01842 100644 --- a/arch/mips/momentum/ocelot_g/setup.c +++ b/arch/mips/momentum/ocelot_g/setup.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include <asm/gt64240.h> | 57 | #include <asm/gt64240.h> |
| 58 | #include <asm/irq.h> | 58 | #include <asm/irq.h> |
| 59 | #include <asm/pci.h> | 59 | #include <asm/pci.h> |
| 60 | #include <asm/pgtable.h> | ||
| 60 | #include <asm/processor.h> | 61 | #include <asm/processor.h> |
| 61 | #include <asm/reboot.h> | 62 | #include <asm/reboot.h> |
| 62 | #include <linux/bootmem.h> | 63 | #include <linux/bootmem.h> |
| @@ -160,6 +161,10 @@ static void __init setup_l3cache(unsigned long size) | |||
| 160 | printk("Done\n"); | 161 | printk("Done\n"); |
| 161 | } | 162 | } |
| 162 | 163 | ||
| 164 | void __init plat_timer_setup(struct irqaction *irq) | ||
| 165 | { | ||
| 166 | } | ||
| 167 | |||
| 163 | void __init plat_mem_setup(void) | 168 | void __init plat_mem_setup(void) |
| 164 | { | 169 | { |
| 165 | void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); | 170 | void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index dd0aec9c3ce1..1fb240c57bac 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
| @@ -31,16 +31,18 @@ | |||
| 31 | #define M_COUNTER_OVERFLOW (1UL << 31) | 31 | #define M_COUNTER_OVERFLOW (1UL << 31) |
| 32 | 32 | ||
| 33 | #ifdef CONFIG_MIPS_MT_SMP | 33 | #ifdef CONFIG_MIPS_MT_SMP |
| 34 | #define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) | 34 | #define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) |
| 35 | #define vpe_id() smp_processor_id() | ||
| 35 | #else | 36 | #else |
| 36 | #define WHAT 0 | 37 | #define WHAT 0 |
| 38 | #define vpe_id() smp_processor_id() | ||
| 37 | #endif | 39 | #endif |
| 38 | 40 | ||
| 39 | #define __define_perf_accessors(r, n, np) \ | 41 | #define __define_perf_accessors(r, n, np) \ |
| 40 | \ | 42 | \ |
| 41 | static inline unsigned int r_c0_ ## r ## n(void) \ | 43 | static inline unsigned int r_c0_ ## r ## n(void) \ |
| 42 | { \ | 44 | { \ |
| 43 | unsigned int cpu = smp_processor_id(); \ | 45 | unsigned int cpu = vpe_id(); \ |
| 44 | \ | 46 | \ |
| 45 | switch (cpu) { \ | 47 | switch (cpu) { \ |
| 46 | case 0: \ | 48 | case 0: \ |
| @@ -55,7 +57,7 @@ static inline unsigned int r_c0_ ## r ## n(void) \ | |||
| 55 | \ | 57 | \ |
| 56 | static inline void w_c0_ ## r ## n(unsigned int value) \ | 58 | static inline void w_c0_ ## r ## n(unsigned int value) \ |
| 57 | { \ | 59 | { \ |
| 58 | unsigned int cpu = smp_processor_id(); \ | 60 | unsigned int cpu = vpe_id(); \ |
| 59 | \ | 61 | \ |
| 60 | switch (cpu) { \ | 62 | switch (cpu) { \ |
| 61 | case 0: \ | 63 | case 0: \ |
| @@ -218,7 +220,7 @@ static inline int n_counters(void) | |||
| 218 | { | 220 | { |
| 219 | int counters = __n_counters(); | 221 | int counters = __n_counters(); |
| 220 | 222 | ||
| 221 | #ifndef CONFIG_SMP | 223 | #ifdef CONFIG_MIPS_MT_SMP |
| 222 | if (current_cpu_data.cputype == CPU_34K) | 224 | if (current_cpu_data.cputype == CPU_34K) |
| 223 | return counters >> 1; | 225 | return counters >> 1; |
| 224 | #endif | 226 | #endif |
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 3cf0dd4ba548..70cb55b89df6 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
| @@ -26,7 +26,7 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o | |||
| 26 | obj-$(CONFIG_LASAT) += pci-lasat.o | 26 | obj-$(CONFIG_LASAT) += pci-lasat.o |
| 27 | obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o | 27 | obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o |
| 28 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o | 28 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o |
| 29 | obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o | 29 | obj-$(CONFIG_MIPS_EV64120) += pci-ev64120.o |
| 30 | obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o | 30 | obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o |
| 31 | obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o | 31 | obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o |
| 32 | obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o | 32 | obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o |
diff --git a/arch/mips/pci/fixup-ev64120.c b/arch/mips/pci/fixup-ev64120.c deleted file mode 100644 index 8dbb90d63f0a..000000000000 --- a/arch/mips/pci/fixup-ev64120.c +++ /dev/null | |||
| @@ -1,34 +0,0 @@ | |||
| 1 | #include <linux/pci.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | |||
| 4 | int pci_range_ck(unsigned char bus, unsigned char dev) | ||
| 5 | { | ||
| 6 | if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) | ||
| 7 | return 0; | ||
| 8 | |||
| 9 | return -1; | ||
| 10 | } | ||
| 11 | |||
| 12 | /* | ||
| 13 | * After detecting all agents over the PCI , this function is called | ||
| 14 | * in order to give an interrupt number for each PCI device starting | ||
| 15 | * from IRQ 20. It does also enables master for each device. | ||
| 16 | */ | ||
| 17 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | ||
| 18 | { | ||
| 19 | unsigned int irq = 20; | ||
| 20 | struct pci_bus *current_bus = bus; | ||
| 21 | struct pci_dev *dev; | ||
| 22 | struct list_head *devices_link; | ||
| 23 | |||
| 24 | list_for_each(devices_link, &(current_bus->devices)) { | ||
| 25 | dev = pci_dev_b(devices_link); | ||
| 26 | if (dev != NULL) { | ||
| 27 | dev->irq = irq++; | ||
| 28 | |||
| 29 | /* Assign an interrupt number for the device */ | ||
| 30 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
| 31 | pcibios_set_master(dev); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c new file mode 100644 index 000000000000..9cd859ef1842 --- /dev/null +++ b/arch/mips/pci/pci-ev64120.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include <linux/pci.h> | ||
| 2 | |||
| 3 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
| 4 | { | ||
| 5 | int irq; | ||
| 6 | |||
| 7 | if (!pin) | ||
| 8 | return 0; | ||
| 9 | |||
| 10 | irq = allocate_irqno(); | ||
| 11 | if (irq < 0) | ||
| 12 | return 0; | ||
| 13 | |||
| 14 | return irq; | ||
| 15 | } | ||
| 16 | |||
| 17 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
| 18 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 19 | { | ||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index 0af655b1f330..65c440e8480b 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c | |||
| @@ -41,8 +41,8 @@ extern unsigned int mips_hpt_frequency; | |||
| 41 | * 1) board_time_init() - | 41 | * 1) board_time_init() - |
| 42 | * a) (optional) set up RTC routines, | 42 | * a) (optional) set up RTC routines, |
| 43 | * b) (optional) calibrate and set the mips_hpt_frequency | 43 | * b) (optional) calibrate and set the mips_hpt_frequency |
| 44 | * (only needed if you intended to use fixed_rate_gettimeoffset | 44 | * (only needed if you intended to use cpu counter as timer interrupt |
| 45 | * or use cpu counter as timer interrupt source) | 45 | * source) |
| 46 | */ | 46 | */ |
| 47 | 47 | ||
| 48 | void pnx8550_time_init(void) | 48 | void pnx8550_time_init(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c index 416da22b3bf4..85b14c73c226 100644 --- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c | |||
| @@ -74,7 +74,7 @@ static int titan_i2c_poll(void) | |||
| 74 | int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, | 74 | int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, |
| 75 | int size, unsigned int *addr) | 75 | int size, unsigned int *addr) |
| 76 | { | 76 | { |
| 77 | int loop = 0, bytes, i; | 77 | int loop, bytes = 0, i; |
| 78 | unsigned int *write_data, data, *read_data; | 78 | unsigned int *write_data, data, *read_data; |
| 79 | unsigned long reg_val, val; | 79 | unsigned long reg_val, val; |
| 80 | 80 | ||
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 65fa3a23ea5e..3cc0436db6cf 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c | |||
| @@ -3,9 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <asm/pmon.h> | 4 | #include <asm/pmon.h> |
| 5 | #include <asm/titan_dep.h> | 5 | #include <asm/titan_dep.h> |
| 6 | 6 | #include <asm/time.h> | |
| 7 | extern unsigned int (*mips_hpt_read)(void); | ||
| 8 | extern void (*mips_hpt_init)(unsigned int); | ||
| 9 | 7 | ||
| 10 | #define LAUNCHSTACK_SIZE 256 | 8 | #define LAUNCHSTACK_SIZE 256 |
| 11 | 9 | ||
| @@ -101,7 +99,7 @@ void prom_cpus_done(void) | |||
| 101 | */ | 99 | */ |
| 102 | void prom_init_secondary(void) | 100 | void prom_init_secondary(void) |
| 103 | { | 101 | { |
| 104 | mips_hpt_init(mips_hpt_read()); | 102 | mips_hpt_init(); |
| 105 | 103 | ||
| 106 | set_c0_status(ST0_CO | ST0_IE | ST0_IM); | 104 | set_c0_status(ST0_CO | ST0_IE | ST0_IM); |
| 107 | } | 105 | } |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index f01ba1f90770..270ecd3e6b4a 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
| @@ -354,29 +354,6 @@ static struct irq_chip bridge_irq_type = { | |||
| 354 | .end = end_bridge_irq, | 354 | .end = end_bridge_irq, |
| 355 | }; | 355 | }; |
| 356 | 356 | ||
| 357 | static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; | ||
| 358 | |||
| 359 | int allocate_irqno(void) | ||
| 360 | { | ||
| 361 | int irq; | ||
| 362 | |||
| 363 | again: | ||
| 364 | irq = find_first_zero_bit(irq_map, NR_IRQS); | ||
| 365 | |||
| 366 | if (irq >= NR_IRQS) | ||
| 367 | return -ENOSPC; | ||
| 368 | |||
| 369 | if (test_and_set_bit(irq, irq_map)) | ||
| 370 | goto again; | ||
| 371 | |||
| 372 | return irq; | ||
| 373 | } | ||
| 374 | |||
| 375 | void free_irqno(unsigned int irq) | ||
| 376 | { | ||
| 377 | clear_bit(irq, irq_map); | ||
| 378 | } | ||
| 379 | |||
| 380 | void __devinit register_bridge_irq(unsigned int irq) | 357 | void __devinit register_bridge_irq(unsigned int irq) |
| 381 | { | 358 | { |
| 382 | irq_desc[irq].status = IRQ_DISABLED; | 359 | irq_desc[irq].status = IRQ_DISABLED; |
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 4e870fc4469b..5e82a268e3c9 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c | |||
| @@ -134,13 +134,6 @@ again: | |||
| 134 | irq_exit(); | 134 | irq_exit(); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | unsigned long ip27_do_gettimeoffset(void) | ||
| 138 | { | ||
| 139 | unsigned long ct_cur1; | ||
| 140 | ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; | ||
| 141 | return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; | ||
| 142 | } | ||
| 143 | |||
| 144 | /* Includes for ioc3_init(). */ | 137 | /* Includes for ioc3_init(). */ |
| 145 | #include <asm/sn/types.h> | 138 | #include <asm/sn/types.h> |
| 146 | #include <asm/sn/sn0/addrs.h> | 139 | #include <asm/sn/sn0/addrs.h> |
| @@ -221,8 +214,6 @@ static struct irqaction rt_irqaction = { | |||
| 221 | .name = "timer" | 214 | .name = "timer" |
| 222 | }; | 215 | }; |
| 223 | 216 | ||
| 224 | extern int allocate_irqno(void); | ||
| 225 | |||
| 226 | void __init plat_timer_setup(struct irqaction *irq) | 217 | void __init plat_timer_setup(struct irqaction *irq) |
| 227 | { | 218 | { |
| 228 | int irqno = allocate_irqno(); | 219 | int irqno = allocate_irqno(); |
| @@ -248,12 +239,17 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
| 248 | setup_irq(irqno, &rt_irqaction); | 239 | setup_irq(irqno, &rt_irqaction); |
| 249 | } | 240 | } |
| 250 | 241 | ||
| 242 | static unsigned int ip27_hpt_read(void) | ||
| 243 | { | ||
| 244 | return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); | ||
| 245 | } | ||
| 246 | |||
| 251 | void __init ip27_time_init(void) | 247 | void __init ip27_time_init(void) |
| 252 | { | 248 | { |
| 249 | mips_hpt_read = ip27_hpt_read; | ||
| 250 | mips_hpt_frequency = CYCLES_PER_SEC; | ||
| 253 | xtime.tv_sec = get_m48t35_time(); | 251 | xtime.tv_sec = get_m48t35_time(); |
| 254 | xtime.tv_nsec = 0; | 252 | xtime.tv_nsec = 0; |
| 255 | |||
| 256 | do_gettimeoffset = ip27_do_gettimeoffset; | ||
| 257 | } | 253 | } |
| 258 | 254 | ||
| 259 | void __init cpu_time_init(void) | 255 | void __init cpu_time_init(void) |
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index bf12af46132e..e136bde5248e 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c | |||
| @@ -47,6 +47,12 @@ | |||
| 47 | #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 | 47 | #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 |
| 48 | #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 | 48 | #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_SIMULATION | ||
| 51 | #define BCM1480_HPT_VALUE 50000 | ||
| 52 | #else | ||
| 53 | #define BCM1480_HPT_VALUE 1000000 | ||
| 54 | #endif | ||
| 55 | |||
| 50 | extern int bcm1480_steal_irq(int irq); | 56 | extern int bcm1480_steal_irq(int irq); |
| 51 | 57 | ||
| 52 | void bcm1480_time_init(void) | 58 | void bcm1480_time_init(void) |
| @@ -59,11 +65,6 @@ void bcm1480_time_init(void) | |||
| 59 | BUG(); | 65 | BUG(); |
| 60 | } | 66 | } |
| 61 | 67 | ||
| 62 | if (!cpu) { | ||
| 63 | /* Use our own gettimeoffset() routine */ | ||
| 64 | do_gettimeoffset = bcm1480_gettimeoffset; | ||
| 65 | } | ||
| 66 | |||
| 67 | bcm1480_mask_irq(cpu, irq); | 68 | bcm1480_mask_irq(cpu, irq); |
| 68 | 69 | ||
| 69 | /* Map the timer interrupt to ip[4] of this cpu */ | 70 | /* Map the timer interrupt to ip[4] of this cpu */ |
| @@ -74,11 +75,7 @@ void bcm1480_time_init(void) | |||
| 74 | /* Disable the timer and set up the count */ | 75 | /* Disable the timer and set up the count */ |
| 75 | __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | 76 | __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); |
| 76 | __raw_writeq( | 77 | __raw_writeq( |
| 77 | #ifndef CONFIG_SIMULATION | 78 | BCM1480_HPT_VALUE/HZ |
| 78 | 1000000/HZ | ||
| 79 | #else | ||
| 80 | 50000/HZ | ||
| 81 | #endif | ||
| 82 | , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); | 79 | , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); |
| 83 | 80 | ||
| 84 | /* Set the timer running */ | 81 | /* Set the timer running */ |
| @@ -122,16 +119,16 @@ void bcm1480_timer_interrupt(void) | |||
| 122 | } | 119 | } |
| 123 | } | 120 | } |
| 124 | 121 | ||
| 125 | /* | 122 | static unsigned int bcm1480_hpt_read(void) |
| 126 | * We use our own do_gettimeoffset() instead of the generic one, | ||
| 127 | * because the generic one does not work for SMP case. | ||
| 128 | * In addition, since we use general timer 0 for system time, | ||
| 129 | * we can get accurate intra-jiffy offset without calibration. | ||
| 130 | */ | ||
| 131 | unsigned long bcm1480_gettimeoffset(void) | ||
| 132 | { | 123 | { |
| 124 | /* We assume this function is called xtime_lock held. */ | ||
| 133 | unsigned long count = | 125 | unsigned long count = |
| 134 | __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); | 126 | __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); |
| 127 | return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; | ||
| 128 | } | ||
| 135 | 129 | ||
| 136 | return 1000000/HZ - count; | 130 | void __init bcm1480_hpt_setup(void) |
| 131 | { | ||
| 132 | mips_hpt_read = bcm1480_hpt_read; | ||
| 133 | mips_hpt_frequency = BCM1480_HPT_VALUE; | ||
| 137 | } | 134 | } |
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 0ccf1796dd78..bcb74f2c1948 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c | |||
| @@ -47,15 +47,11 @@ | |||
| 47 | 47 | ||
| 48 | #define SB1250_HPT_NUM 3 | 48 | #define SB1250_HPT_NUM 3 |
| 49 | #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ | 49 | #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ |
| 50 | #define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) | ||
| 51 | 50 | ||
| 52 | 51 | ||
| 53 | extern int sb1250_steal_irq(int irq); | 52 | extern int sb1250_steal_irq(int irq); |
| 54 | 53 | ||
| 55 | static unsigned int sb1250_hpt_read(void); | 54 | static unsigned int sb1250_hpt_read(void); |
| 56 | static void sb1250_hpt_init(unsigned int); | ||
| 57 | |||
| 58 | static unsigned int hpt_offset; | ||
| 59 | 55 | ||
| 60 | void __init sb1250_hpt_setup(void) | 56 | void __init sb1250_hpt_setup(void) |
| 61 | { | 57 | { |
| @@ -69,13 +65,9 @@ void __init sb1250_hpt_setup(void) | |||
| 69 | __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, | 65 | __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, |
| 70 | IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); | 66 | IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); |
| 71 | 67 | ||
| 72 | /* | 68 | mips_hpt_frequency = V_SCD_TIMER_FREQ; |
| 73 | * we need to fill 32 bits, so just use the upper 23 bits and pretend | ||
| 74 | * the timer is going 512Mhz instead of 1Mhz | ||
| 75 | */ | ||
| 76 | mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; | ||
| 77 | mips_hpt_init = sb1250_hpt_init; | ||
| 78 | mips_hpt_read = sb1250_hpt_read; | 69 | mips_hpt_read = sb1250_hpt_read; |
| 70 | mips_hpt_mask = M_SCD_TIMER_INIT; | ||
| 79 | } | 71 | } |
| 80 | } | 72 | } |
| 81 | 73 | ||
| @@ -149,11 +141,7 @@ void sb1250_timer_interrupt(void) | |||
| 149 | 141 | ||
| 150 | /* | 142 | /* |
| 151 | * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over | 143 | * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over |
| 152 | * again. There's no easy way to set to a specific value so store init value | 144 | * again. |
| 153 | * in hpt_offset and subtract each time. | ||
| 154 | * | ||
| 155 | * Note: Timer isn't full 32bits so shift it into the upper part making | ||
| 156 | * it appear to run at a higher frequency. | ||
| 157 | */ | 145 | */ |
| 158 | static unsigned int sb1250_hpt_read(void) | 146 | static unsigned int sb1250_hpt_read(void) |
| 159 | { | 147 | { |
| @@ -161,13 +149,5 @@ static unsigned int sb1250_hpt_read(void) | |||
| 161 | 149 | ||
| 162 | count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); | 150 | count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); |
| 163 | 151 | ||
| 164 | count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; | 152 | return SB1250_HPT_VALUE - count; |
| 165 | |||
| 166 | return count - hpt_offset; | ||
| 167 | } | ||
| 168 | |||
| 169 | static void sb1250_hpt_init(unsigned int count) | ||
| 170 | { | ||
| 171 | hpt_offset = count; | ||
| 172 | return; | ||
| 173 | } | 153 | } |
diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/tx4927/common/smsc_fdc37m81x.c new file mode 100644 index 000000000000..33f517bc9a08 --- /dev/null +++ b/arch/mips/tx4927/common/smsc_fdc37m81x.c | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* | ||
| 2 | * Interface for smsc fdc48m81x Super IO chip | ||
| 3 | * | ||
| 4 | * Author: MontaVista Software, Inc. source@mvista.com | ||
| 5 | * | ||
| 6 | * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under | ||
| 7 | * the terms of the GNU General Public License version 2. This program | ||
| 8 | * is licensed "as is" without any warranty of any kind, whether express | ||
| 9 | * or implied. | ||
| 10 | * | ||
| 11 | * Copyright 2004 (c) MontaVista Software, Inc. | ||
| 12 | */ | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/types.h> | ||
| 15 | #include <asm/io.h> | ||
| 16 | #include <asm/tx4927/smsc_fdc37m81x.h> | ||
| 17 | |||
| 18 | #define DEBUG | ||
| 19 | |||
| 20 | /* Common Registers */ | ||
| 21 | #define SMSC_FDC37M81X_CONFIG_INDEX 0x00 | ||
| 22 | #define SMSC_FDC37M81X_CONFIG_DATA 0x01 | ||
| 23 | #define SMSC_FDC37M81X_CONF 0x02 | ||
| 24 | #define SMSC_FDC37M81X_INDEX 0x03 | ||
| 25 | #define SMSC_FDC37M81X_DNUM 0x07 | ||
| 26 | #define SMSC_FDC37M81X_DID 0x20 | ||
| 27 | #define SMSC_FDC37M81X_DREV 0x21 | ||
| 28 | #define SMSC_FDC37M81X_PCNT 0x22 | ||
| 29 | #define SMSC_FDC37M81X_PMGT 0x23 | ||
| 30 | #define SMSC_FDC37M81X_OSC 0x24 | ||
| 31 | #define SMSC_FDC37M81X_CONFPA0 0x26 | ||
| 32 | #define SMSC_FDC37M81X_CONFPA1 0x27 | ||
| 33 | #define SMSC_FDC37M81X_TEST4 0x2B | ||
| 34 | #define SMSC_FDC37M81X_TEST5 0x2C | ||
| 35 | #define SMSC_FDC37M81X_TEST1 0x2D | ||
| 36 | #define SMSC_FDC37M81X_TEST2 0x2E | ||
| 37 | #define SMSC_FDC37M81X_TEST3 0x2F | ||
| 38 | |||
| 39 | /* Logical device numbers */ | ||
| 40 | #define SMSC_FDC37M81X_FDD 0x00 | ||
| 41 | #define SMSC_FDC37M81X_SERIAL1 0x04 | ||
| 42 | #define SMSC_FDC37M81X_SERIAL2 0x05 | ||
| 43 | #define SMSC_FDC37M81X_KBD 0x07 | ||
| 44 | |||
| 45 | /* Logical device Config Registers */ | ||
| 46 | #define SMSC_FDC37M81X_ACTIVE 0x30 | ||
| 47 | #define SMSC_FDC37M81X_BASEADDR0 0x60 | ||
| 48 | #define SMSC_FDC37M81X_BASEADDR1 0x61 | ||
| 49 | #define SMSC_FDC37M81X_INT 0x70 | ||
| 50 | #define SMSC_FDC37M81X_INT2 0x72 | ||
| 51 | #define SMSC_FDC37M81X_MODE 0xF0 | ||
| 52 | |||
| 53 | /* Chip Config Values */ | ||
| 54 | #define SMSC_FDC37M81X_CONFIG_ENTER 0x55 | ||
| 55 | #define SMSC_FDC37M81X_CONFIG_EXIT 0xaa | ||
| 56 | #define SMSC_FDC37M81X_CHIP_ID 0x4d | ||
| 57 | |||
| 58 | static unsigned long g_smsc_fdc37m81x_base = 0; | ||
| 59 | |||
| 60 | static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) | ||
| 61 | { | ||
| 62 | outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
| 63 | |||
| 64 | return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) | ||
| 68 | { | ||
| 69 | outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
| 70 | outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); | ||
| 71 | } | ||
| 72 | |||
| 73 | void smsc_fdc37m81x_config_beg(void) | ||
| 74 | { | ||
| 75 | if (g_smsc_fdc37m81x_base) { | ||
| 76 | outb(SMSC_FDC37M81X_CONFIG_ENTER, | ||
| 77 | g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | void smsc_fdc37m81x_config_end(void) | ||
| 82 | { | ||
| 83 | if (g_smsc_fdc37m81x_base) | ||
| 84 | outb(SMSC_FDC37M81X_CONFIG_EXIT, | ||
| 85 | g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
| 86 | } | ||
| 87 | |||
| 88 | u8 smsc_fdc37m81x_config_get(u8 reg) | ||
| 89 | { | ||
| 90 | u8 val = 0; | ||
| 91 | |||
| 92 | if (g_smsc_fdc37m81x_base) | ||
| 93 | val = smsc_fdc37m81x_rd(reg); | ||
| 94 | |||
| 95 | return val; | ||
| 96 | } | ||
| 97 | |||
| 98 | void smsc_fdc37m81x_config_set(u8 reg, u8 val) | ||
| 99 | { | ||
| 100 | if (g_smsc_fdc37m81x_base) | ||
| 101 | smsc_dc37m81x_wr(reg, val); | ||
| 102 | } | ||
| 103 | |||
| 104 | unsigned long __init smsc_fdc37m81x_init(unsigned long port) | ||
| 105 | { | ||
| 106 | const int field = sizeof(unsigned long) * 2; | ||
| 107 | u8 chip_id; | ||
| 108 | |||
| 109 | if (g_smsc_fdc37m81x_base) | ||
| 110 | printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n", | ||
| 111 | field, g_smsc_fdc37m81x_base); | ||
| 112 | |||
| 113 | g_smsc_fdc37m81x_base = port; | ||
| 114 | |||
| 115 | smsc_fdc37m81x_config_beg(); | ||
| 116 | |||
| 117 | chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); | ||
| 118 | if (chip_id == SMSC_FDC37M81X_CHIP_ID) | ||
| 119 | smsc_fdc37m81x_config_end(); | ||
| 120 | else { | ||
| 121 | printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n", | ||
| 122 | chip_id); | ||
| 123 | g_smsc_fdc37m81x_base = 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | return g_smsc_fdc37m81x_base; | ||
| 127 | } | ||
| 128 | |||
| 129 | #ifdef DEBUG | ||
| 130 | void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg) | ||
| 131 | { | ||
| 132 | printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, | ||
| 133 | smsc_fdc37m81x_rd(reg)); | ||
| 134 | } | ||
| 135 | |||
| 136 | void smsc_fdc37m81x_config_dump(void) | ||
| 137 | { | ||
| 138 | u8 orig; | ||
| 139 | char *fname = "smsc_fdc37m81x_config_dump()"; | ||
| 140 | |||
| 141 | smsc_fdc37m81x_config_beg(); | ||
| 142 | |||
| 143 | orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); | ||
| 144 | |||
| 145 | printk("%s: common\n", fname); | ||
| 146 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
| 147 | SMSC_FDC37M81X_DNUM); | ||
| 148 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
| 149 | SMSC_FDC37M81X_DID); | ||
| 150 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
| 151 | SMSC_FDC37M81X_DREV); | ||
| 152 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
| 153 | SMSC_FDC37M81X_PCNT); | ||
| 154 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
| 155 | SMSC_FDC37M81X_PMGT); | ||
| 156 | |||
| 157 | printk("%s: keyboard\n", fname); | ||
| 158 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); | ||
| 159 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
| 160 | SMSC_FDC37M81X_ACTIVE); | ||
| 161 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
| 162 | SMSC_FDC37M81X_INT); | ||
| 163 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
| 164 | SMSC_FDC37M81X_INT2); | ||
| 165 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
| 166 | SMSC_FDC37M81X_LDCR_F0); | ||
| 167 | |||
| 168 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); | ||
| 169 | |||
| 170 | smsc_fdc37m81x_config_end(); | ||
| 171 | } | ||
| 172 | #endif | ||
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c index 4658b2ae4833..941c441729b0 100644 --- a/arch/mips/tx4927/common/tx4927_setup.c +++ b/arch/mips/tx4927/common/tx4927_setup.c | |||
| @@ -112,8 +112,6 @@ void print_cp0(char *key, int num, char *name, u32 val) | |||
| 112 | return; | 112 | return; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | indent: Standard input:25: Error:Unexpected end of file | ||
| 116 | |||
| 117 | void | 115 | void |
| 118 | dump_cp0(char *key) | 116 | dump_cp0(char *key) |
| 119 | { | 117 | { |
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c index b926e6a75c29..08b20cdfd7b3 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c | |||
| @@ -36,14 +36,18 @@ void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on) | |||
| 36 | 36 | ||
| 37 | static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait); | 37 | static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait); |
| 38 | 38 | ||
| 39 | static void txx9_spi_interrupt(int irq, void *dev_id) | 39 | static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id) |
| 40 | { | 40 | { |
| 41 | /* disable rx intr */ | 41 | /* disable rx intr */ |
| 42 | tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE; | 42 | tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE; |
| 43 | wake_up(&txx9_spi_wait); | 43 | wake_up(&txx9_spi_wait); |
| 44 | |||
| 45 | return IRQ_HANDLED; | ||
| 44 | } | 46 | } |
| 47 | |||
| 45 | static struct irqaction txx9_spi_action = { | 48 | static struct irqaction txx9_spi_action = { |
| 46 | txx9_spi_interrupt, 0, 0, "spi", NULL, NULL, | 49 | .handler = txx9_spi_interrupt, |
| 50 | .name = "spi", | ||
| 47 | }; | 51 | }; |
| 48 | 52 | ||
| 49 | void __init txx9_spi_irqinit(int irc_irq) | 53 | void __init txx9_spi_irqinit(int irc_irq) |
