Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7491eb9b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (22 commits)
  MIPS: Return after handling coprocessor 2 exception
  MIPS: BCM47xx: Add NVRAM support devices
  MIPS: Loongson: Define rtc device on MC146818-equipped systems
  MIPS: MT: Fix FPU affinity.
  MIPS: Oprofile: Fixup of loongson2_exit()
  MIPS: Alchemy: sleepcode without compile-time cputype dependencies
  MIPS: Tracing: Cleanup of address space checking
  MIPS: Tracing: Cleanup of function graph tracer
  MIPS: Tracing: Reduce the overhead of dynamic Function Tracer
  MIPS: Tracing: Cleanup of instructions used
  MIPS: Tracing: Fix 32-bit support with -mmcount-ra-address
  MIPS: Tracing: Fix argument passing of the 32bit support with gcc 4.5
  MIPS: Tracing: Cleanup comments
  MIPS: Tracing: Cleanup the arguments passing of prepare_ftrace_return
  MIPS: Tracing: Merge adjacent #ifdefs with same condition.
  MIPS: AR7, BCM63xx: fix gpio_to_irq() return value
  MIPS: Restore signalling NaN behaviour for abs.[sd]
  MIPS: Loongson: CS5536: Fix ISA support
  MIPS: Loongson: Add a missing break statement in CS5536 IDE code
  MIPS: Loongson: CS5536: Add missing RDMSRs for IDE and USB
  ...
parents 7263e715 55dc9d51
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -193,9 +193,15 @@ static void restore_core_regs(void)

void au_sleep(void)
{
	int cpuid = alchemy_get_cputype();
	if (cpuid != ALCHEMY_CPU_UNKNOWN) {
		save_core_regs();
	au1xxx_save_and_sleep();
		if (cpuid <= ALCHEMY_CPU_AU1500)
			alchemy_sleep_au1000();
		else if (cpuid <= ALCHEMY_CPU_AU1200)
			alchemy_sleep_au1550();
		restore_core_regs();
	}
}

#endif	/* CONFIG_PM */
+53 −28
Original line number Diff line number Diff line
@@ -22,10 +22,9 @@
	.set noat
	.align	5

/* Save all of the processor general registers and go to sleep.
 * A wakeup condition will get us back here to restore the registers.
 */
LEAF(au1xxx_save_and_sleep)

/* preparatory stuff */
.macro	SETUP_SLEEP
	subu	sp, PT_SIZE
	sw	$1, PT_R1(sp)
	sw	$2, PT_R2(sp)
@@ -69,12 +68,32 @@ LEAF(au1xxx_save_and_sleep)
	 */
	lui	t3, 0xb190		/* sys_xxx */
	sw	sp, 0x0018(t3)
	la	k0, 3f			/* resume path */
	la	k0, alchemy_sleep_wakeup	/* resume path */
	sw	k0, 0x001c(t3)
.endm

	/* Put SDRAM into self refresh:  Preload instructions into cache,
	 * issue a precharge, auto/self refresh, then sleep commands to it.
	 */
.macro	DO_SLEEP
	/* put power supply and processor to sleep */
	sw	zero, 0x0078(t3)	/* sys_slppwr */
	sync
	sw	zero, 0x007c(t3)	/* sys_sleep */
	sync
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
.endm

/* sleep code for Au1000/Au1100/Au1500 memory controller type */
LEAF(alchemy_sleep_au1000)

	SETUP_SLEEP

	/* cache following instructions, as memory gets put to sleep */
	la	t0, 1f
	.set	mips3
	cache	0x14, 0(t0)
@@ -84,17 +103,32 @@ LEAF(au1xxx_save_and_sleep)
	.set	mips0

1:	lui 	a0, 0xb400		/* mem_xxx */
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) ||	\
    defined(CONFIG_SOC_AU1500)
	sw	zero, 0x001c(a0) 	/* Precharge */
	sync
	sw	zero, 0x0020(a0)	/* Auto Refresh */
	sync
	sw	zero, 0x0030(a0)  	/* Sleep */
	sync
#endif

#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
	DO_SLEEP

END(alchemy_sleep_au1000)

/* sleep code for Au1550/Au1200 memory controller type */
LEAF(alchemy_sleep_au1550)

	SETUP_SLEEP

	/* cache following instructions, as memory gets put to sleep */
	la	t0, 1f
	.set	mips3
	cache	0x14, 0(t0)
	cache	0x14, 32(t0)
	cache	0x14, 64(t0)
	cache	0x14, 96(t0)
	.set	mips0

1:	lui 	a0, 0xb400		/* mem_xxx */
	sw	zero, 0x08c0(a0) 	/* Precharge */
	sync
	sw	zero, 0x08d0(a0)	/* Self Refresh */
@@ -114,26 +148,17 @@ LEAF(au1xxx_save_and_sleep)
	and 	t1, t0, t1		/* clear CE[1:0] */
	sw 	t1, 0x0840(a0)		/* mem_sdconfiga */
	sync
#endif

	/* put power supply and processor to sleep */
	sw	zero, 0x0078(t3)	/* sys_slppwr */
	sync
	sw	zero, 0x007c(t3)	/* sys_sleep */
	sync
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	DO_SLEEP

END(alchemy_sleep_au1550)


	/* This is where we return upon wakeup.
	 * Reload all of the registers and return.
	 */
3:	lw	k0, 0x20(sp)
LEAF(alchemy_sleep_wakeup)
	lw	k0, 0x20(sp)
	mtc0	k0, CP0_STATUS
	lw	k0, 0x1c(sp)
	mtc0	k0, CP0_CONTEXT
@@ -169,4 +194,4 @@ LEAF(au1xxx_save_and_sleep)
	lw	$31, PT_R31(sp)
	jr	ra
	 addiu	sp, PT_SIZE
END(au1xxx_save_and_sleep)
END(alchemy_sleep_wakeup)
+1 −1
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ static int __init ar7_register_uarts(void)
	if (IS_ERR(bus_clk))
		panic("unable to get bus clk\n");

	uart_port.type		= PORT_16550A;
	uart_port.type		= PORT_AR7;
	uart_port.uartclk	= clk_get_rate(bus_clk) / 2;
	uart_port.iotype	= UPIO_MEM32;
	uart_port.regshift	= 2;
+1 −1
Original line number Diff line number Diff line
@@ -3,4 +3,4 @@
# under Linux.
#

obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
+94 −0
Original line number Diff line number Diff line
/*
 * BCM947xx nvram variable access
 *
 * Copyright (C) 2005 Broadcom Corporation
 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/init.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/ssb/ssb.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/addrspace.h>
#include <asm/mach-bcm47xx/nvram.h>
#include <asm/mach-bcm47xx/bcm47xx.h>

static char nvram_buf[NVRAM_SPACE];

/* Probe for NVRAM header */
static void __init early_nvram_init(void)
{
	struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
	struct nvram_header *header;
	int i;
	u32 base, lim, off;
	u32 *src, *dst;

	base = mcore->flash_window;
	lim = mcore->flash_window_size;

	off = FLASH_MIN;
	while (off <= lim) {
		/* Windowed flash access */
		header = (struct nvram_header *)
			KSEG1ADDR(base + off - NVRAM_SPACE);
		if (header->magic == NVRAM_HEADER)
			goto found;
		off <<= 1;
	}

	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
	header = (struct nvram_header *) KSEG1ADDR(base + 4096);
	if (header->magic == NVRAM_HEADER)
		goto found;

	header = (struct nvram_header *) KSEG1ADDR(base + 1024);
	if (header->magic == NVRAM_HEADER)
		goto found;

	return;

found:
	src = (u32 *) header;
	dst = (u32 *) nvram_buf;
	for (i = 0; i < sizeof(struct nvram_header); i += 4)
		*dst++ = *src++;
	for (; i < header->len && i < NVRAM_SPACE; i += 4)
		*dst++ = le32_to_cpu(*src++);
}

int nvram_getenv(char *name, char *val, size_t val_len)
{
	char *var, *value, *end, *eq;

	if (!name)
		return 1;

	if (!nvram_buf[0])
		early_nvram_init();

	/* Look for name=value and return value */
	var = &nvram_buf[sizeof(struct nvram_header)];
	end = nvram_buf + sizeof(nvram_buf) - 2;
	end[0] = end[1] = '\0';
	for (; *var; var = value + strlen(value) + 1) {
		eq = strchr(var, '=');
		if (!eq)
			break;
		value = eq + 1;
		if ((eq - var) == strlen(name) &&
			strncmp(var, name, (eq - var)) == 0) {
			snprintf(val, val_len, "%s", value);
			return 0;
		}
	}
	return 1;
}
EXPORT_SYMBOL(nvram_getenv);
Loading