Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for 3.17.  It contains:

   - misc Cavium Octeon, BCM47xx, BCM63xx and Alchemy  updates
   - MIPS ptrace updates and cleanups
   - various fixes that will also go to -stable
   - a number of cleanups and small non-critical fixes.
   - NUMA support for the Loongson 3.
   - more support for MSA
   - support for MAAR
   - various FP enhancements and fixes"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
  MIPS: jz4740: remove unnecessary null test before debugfs_remove
  MIPS: Octeon: remove unnecessary null test before debugfs_remove_recursive
  MIPS: ZBOOT: implement stack protector in compressed boot phase
  MIPS: mipsreg: remove duplicate MIPS_CONF4_FTLBSETS_SHIFT
  MIPS: Bonito64: remove a duplicate define
  MIPS: Malta: initialise MAARs
  MIPS: Initialise MAARs
  MIPS: detect presence of MAARs
  MIPS: define MAAR register accessors & bits
  MIPS: mark MSA experimental
  MIPS: Don't build MSA support unless it can be used
  MIPS: consistently clear MSA flags when starting & copying threads
  MIPS: 16 byte align MSA vector context
  MIPS: disable preemption whilst initialising MSA
  MIPS: ensure MSA gets disabled during boot
  MIPS: fix read_msa_* & write_msa_* functions on non-MSA toolchains
  MIPS: fix MSA context for tasks which don't use FP first
  MIPS: init upper 64b of vector registers when MSA is first used
  MIPS: save/disable MSA in lose_fpu
  MIPS: preserve scalar FP CSR when switching vector context
  ...
This commit is contained in:
Linus Torvalds 2014-08-07 08:47:00 -07:00
commit e669830526
156 changed files with 5487 additions and 3037 deletions

View File

@ -571,6 +571,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
trust validation.
format: { id:<keyid> | builtin }
cca= [MIPS] Override the kernel pages' cache coherency
algorithm. Accepted values range from 0 to 7
inclusive. See arch/mips/include/asm/pgtable-bits.h
for platform specific values (SB1, Loongson3 and
others).
ccw_timeout_log [S390]
See Documentation/s390/CommonIO for details.

View File

@ -71,6 +71,7 @@ config MIPS_ALCHEMY
select SYS_SUPPORTS_APM_EMULATION
select ARCH_REQUIRE_GPIOLIB
select SYS_SUPPORTS_ZBOOT
select COMMON_CLK
config AR7
bool "Texas Instruments AR7"
@ -129,6 +130,8 @@ config BCM47XX
select SYS_SUPPORTS_MIPS16
select SYS_HAS_EARLY_PRINTK
select USE_GENERIC_EARLY_PRINTK_8250
select GPIOLIB
select LEDS_GPIO_REGISTER
help
Support for BCM47XX based boards
@ -137,6 +140,7 @@ config BCM63XX
select BOOT_RAW
select CEVT_R4K
select CSRC_R4K
select SYNC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select SYS_SUPPORTS_32BIT_KERNEL
@ -2056,6 +2060,7 @@ config MIPS_CPS
support is unavailable.
config MIPS_CPS_PM
select MIPS_CPC
bool
config MIPS_GIC_IPI
@ -2109,9 +2114,9 @@ config CPU_MICROMIPS
microMIPS ISA
config CPU_HAS_MSA
bool "Support for the MIPS SIMD Architecture"
bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)"
depends on CPU_SUPPORTS_MSA
default y
depends on 64BIT || MIPS_O32_FP64_SUPPORT
help
MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
and a set of SIMD instructions to operate on them. When this option

View File

@ -151,8 +151,10 @@ cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \
-Wa,--trap
cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \
-Wa,--trap
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1 -mno-mdmx -mno-mips3d,-march=r5000) \
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
-Wa,--trap
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx)
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d)
cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
-Wa,--trap

View File

@ -85,10 +85,10 @@ void __init board_setup(void)
#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
alchemy_wrsys(SYS_PF_NI2, AU1000_SYS_PINFUNC);
/* Initialize GPIO */
au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
alchemy_wrsys(~0, AU1000_SYS_TRIOUTCLR);
alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */

View File

@ -87,9 +87,9 @@ void __init board_setup(void)
alchemy_gpio2_enable();
/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func |= SYS_PF_UR3;
au_writel(pin_func, SYS_PINFUNC);
alchemy_wrsys(pin_func, AU1000_SYS_PINFUNC);
/* Enable UART */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);

View File

@ -5,8 +5,8 @@
# Makefile for the Alchemy Au1xx0 CPUs, generic files.
#
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
sleeper.o dma.o dbdma.o vss.o irq.o usb.o
obj-y += prom.o time.o clock.o platform.o power.o \
setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o
# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Simple Au1xx0 clocks routines.
*
* Copyright 2001, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/time.h>
#include <asm/mach-au1x00/au1000.h>
/*
* I haven't found anyone that doesn't use a 12 MHz source clock,
* but just in case.....
*/
#define AU1000_SRC_CLK 12000000
static unsigned int au1x00_clock; /* Hz */
static unsigned long uart_baud_base;
/*
* Set the au1000_clock
*/
void set_au1x00_speed(unsigned int new_freq)
{
au1x00_clock = new_freq;
}
unsigned int get_au1x00_speed(void)
{
return au1x00_clock;
}
EXPORT_SYMBOL(get_au1x00_speed);
/*
* The UART baud base is not known at compile time ... if
* we want to be able to use the same code on different
* speed CPUs.
*/
unsigned long get_au1x00_uart_baud_base(void)
{
return uart_baud_base;
}
void set_au1x00_uart_baud_base(unsigned long new_baud_base)
{
uart_baud_base = new_baud_base;
}
/*
* We read the real processor speed from the PLL. This is important
* because it is more accurate than computing it from the 32 KHz
* counter, if it exists. If we don't have an accurate processor
* speed, all of the peripherals that derive their clocks based on
* this advertised speed will introduce error and sometimes not work
* properly. This function is further convoluted to still allow configurations
* to do that in case they have really, really old silicon with a
* write-only PLL register. -- Dan
*/
unsigned long au1xxx_calc_clock(void)
{
unsigned long cpu_speed;
/*
* On early Au1000, sys_cpupll was write-only. Since these
* silicon versions of Au1000 are not sold by AMD, we don't bend
* over backwards trying to determine the frequency.
*/
if (au1xxx_cpu_has_pll_wo())
cpu_speed = 396000000;
else
cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
/* On Alchemy CPU:counter ratio is 1:1 */
mips_hpt_frequency = cpu_speed;
/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
& 0x03) + 2) * 16));
set_au1x00_speed(cpu_speed);
return cpu_speed;
}

View File

@ -341,7 +341,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
(dtp->dev_flags & DEV_FLAGS_SYNC))
i |= DDMA_CFG_SYNC;
cp->ddma_cfg = i;
au_sync();
wmb(); /* drain writebuffer */
/*
* Return a non-zero value that can be used to find the channel
@ -631,7 +631,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
*/
dma_cache_wback_inv((unsigned long)buf, nbytes);
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
au_sync();
wmb(); /* drain writebuffer */
dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
ctp->chan_ptr->ddma_dbell = 0;
@ -693,7 +693,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
*/
dma_cache_inv((unsigned long)buf, nbytes);
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
au_sync();
wmb(); /* drain writebuffer */
dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
ctp->chan_ptr->ddma_dbell = 0;
@ -760,7 +760,7 @@ void au1xxx_dbdma_stop(u32 chanid)
cp = ctp->chan_ptr;
cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */
au_sync();
wmb(); /* drain writebuffer */
while (!(cp->ddma_stat & DDMA_STAT_H)) {
udelay(1);
halt_timeout++;
@ -771,7 +771,7 @@ void au1xxx_dbdma_stop(u32 chanid)
}
/* clear current desc valid and doorbell */
cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
au_sync();
wmb(); /* drain writebuffer */
}
EXPORT_SYMBOL(au1xxx_dbdma_stop);
@ -789,9 +789,9 @@ void au1xxx_dbdma_start(u32 chanid)
cp = ctp->chan_ptr;
cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
au_sync();
wmb(); /* drain writebuffer */
cp->ddma_dbell = 0;
au_sync();
wmb(); /* drain writebuffer */
}
EXPORT_SYMBOL(au1xxx_dbdma_start);
@ -832,7 +832,7 @@ u32 au1xxx_get_dma_residue(u32 chanid)
/* This is only valid if the channel is stopped. */
rv = cp->ddma_bytecnt;
au_sync();
wmb(); /* drain writebuffer */
return rv;
}
@ -868,7 +868,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
au1x_dma_chan_t *cp;
intstat = dbdma_gptr->ddma_intstat;
au_sync();
wmb(); /* drain writebuffer */
chan_index = __ffs(intstat);
ctp = chan_tab_ptr[chan_index];
@ -877,7 +877,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
/* Reset interrupt. */
cp->ddma_irq = 0;
au_sync();
wmb(); /* drain writebuffer */
if (ctp->chan_callback)
ctp->chan_callback(irq, ctp->chan_callparam);
@ -1061,7 +1061,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable)
dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
wmb(); /* drain writebuffer */
ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr);
if (ret)

View File

@ -141,17 +141,17 @@ void dump_au1000_dma_channel(unsigned int dmanr)
printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
printk(KERN_INFO " mode = 0x%08x\n",
au_readl(chan->io + DMA_MODE_SET));
__raw_readl(chan->io + DMA_MODE_SET));
printk(KERN_INFO " addr = 0x%08x\n",
au_readl(chan->io + DMA_PERIPHERAL_ADDR));
__raw_readl(chan->io + DMA_PERIPHERAL_ADDR));
printk(KERN_INFO " start0 = 0x%08x\n",
au_readl(chan->io + DMA_BUFFER0_START));
__raw_readl(chan->io + DMA_BUFFER0_START));
printk(KERN_INFO " start1 = 0x%08x\n",
au_readl(chan->io + DMA_BUFFER1_START));
__raw_readl(chan->io + DMA_BUFFER1_START));
printk(KERN_INFO " count0 = 0x%08x\n",
au_readl(chan->io + DMA_BUFFER0_COUNT));
__raw_readl(chan->io + DMA_BUFFER0_COUNT));
printk(KERN_INFO " count1 = 0x%08x\n",
au_readl(chan->io + DMA_BUFFER1_COUNT));
__raw_readl(chan->io + DMA_BUFFER1_COUNT));
}
/*
@ -204,7 +204,8 @@ int request_au1000_dma(int dev_id, const char *dev_str,
}
/* fill it in */
chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN;
chan->io = (void __iomem *)(KSEG1ADDR(AU1000_DMA_PHYS_ADDR) +
i * DMA_CHANNEL_LEN);
chan->dev_id = dev_id;
chan->dev_str = dev_str;
chan->fifo_addr = dev->fifo_addr;

View File

@ -389,13 +389,12 @@ static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
return -EINVAL;
local_irq_save(flags);
wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK);
wakemsk = alchemy_rdsys(AU1000_SYS_WAKEMSK);
if (on)
wakemsk |= 1 << bit;
else
wakemsk &= ~(1 << bit);
__raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK);
wmb();
alchemy_wrsys(wakemsk, AU1000_SYS_WAKEMSK);
local_irq_restore(flags);
return 0;

View File

@ -11,6 +11,7 @@
* warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
@ -99,10 +100,20 @@ static struct platform_device au1xx0_uart_device = {
static void __init alchemy_setup_uarts(int ctype)
{
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
long uartclk;
int s = sizeof(struct plat_serial8250_port);
int c = alchemy_get_uarts(ctype);
struct plat_serial8250_port *ports;
struct clk *clk = clk_get(NULL, ALCHEMY_PERIPH_CLK);
if (IS_ERR(clk))
return;
if (clk_prepare_enable(clk)) {
clk_put(clk);
return;
}
uartclk = clk_get_rate(clk);
clk_put(clk);
ports = kzalloc(s * (c + 1), GFP_KERNEL);
if (!ports) {
@ -420,7 +431,7 @@ static void __init alchemy_setup_macs(int ctype)
memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
/* Register second MAC if enabled in pinfunc */
if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
if (!(alchemy_rdsys(AU1000_SYS_PINFUNC) & SYS_PF_NI2)) {
ret = platform_device_register(&au1xxx_eth1_device);
if (ret)
printk(KERN_INFO "Alchemy: failed to register MAC1\n");

View File

@ -54,28 +54,28 @@ static unsigned int sleep_static_memctlr[4][3];
static void save_core_regs(void)
{
/* Clocks and PLLs. */
sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);
sleep_sys_clocks[0] = alchemy_rdsys(AU1000_SYS_FREQCTRL0);
sleep_sys_clocks[1] = alchemy_rdsys(AU1000_SYS_FREQCTRL1);
sleep_sys_clocks[2] = alchemy_rdsys(AU1000_SYS_CLKSRC);
sleep_sys_clocks[3] = alchemy_rdsys(AU1000_SYS_CPUPLL);
sleep_sys_clocks[4] = alchemy_rdsys(AU1000_SYS_AUXPLL);
/* pin mux config */
sleep_sys_pinfunc = au_readl(SYS_PINFUNC);
sleep_sys_pinfunc = alchemy_rdsys(AU1000_SYS_PINFUNC);
/* Save the static memory controller configuration. */
sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
sleep_static_memctlr[0][0] = alchemy_rdsmem(AU1000_MEM_STCFG0);
sleep_static_memctlr[0][1] = alchemy_rdsmem(AU1000_MEM_STTIME0);
sleep_static_memctlr[0][2] = alchemy_rdsmem(AU1000_MEM_STADDR0);
sleep_static_memctlr[1][0] = alchemy_rdsmem(AU1000_MEM_STCFG1);
sleep_static_memctlr[1][1] = alchemy_rdsmem(AU1000_MEM_STTIME1);
sleep_static_memctlr[1][2] = alchemy_rdsmem(AU1000_MEM_STADDR1);
sleep_static_memctlr[2][0] = alchemy_rdsmem(AU1000_MEM_STCFG2);
sleep_static_memctlr[2][1] = alchemy_rdsmem(AU1000_MEM_STTIME2);
sleep_static_memctlr[2][2] = alchemy_rdsmem(AU1000_MEM_STADDR2);
sleep_static_memctlr[3][0] = alchemy_rdsmem(AU1000_MEM_STCFG3);
sleep_static_memctlr[3][1] = alchemy_rdsmem(AU1000_MEM_STTIME3);
sleep_static_memctlr[3][2] = alchemy_rdsmem(AU1000_MEM_STADDR3);
}
static void restore_core_regs(void)
@ -85,30 +85,28 @@ static void restore_core_regs(void)
* one of those Au1000 with a write-only PLL, where we dont
* have a valid value)
*/
au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
alchemy_wrsys(sleep_sys_clocks[0], AU1000_SYS_FREQCTRL0);
alchemy_wrsys(sleep_sys_clocks[1], AU1000_SYS_FREQCTRL1);
alchemy_wrsys(sleep_sys_clocks[2], AU1000_SYS_CLKSRC);
alchemy_wrsys(sleep_sys_clocks[4], AU1000_SYS_AUXPLL);
if (!au1xxx_cpu_has_pll_wo())
au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
au_sync();
alchemy_wrsys(sleep_sys_clocks[3], AU1000_SYS_CPUPLL);
au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
au_sync();
alchemy_wrsys(sleep_sys_pinfunc, AU1000_SYS_PINFUNC);
/* Restore the static memory controller configuration. */
au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
au_writel(sleep_static_memctlr[1][0], MEM_STCFG1);
au_writel(sleep_static_memctlr[1][1], MEM_STTIME1);
au_writel(sleep_static_memctlr[1][2], MEM_STADDR1);
au_writel(sleep_static_memctlr[2][0], MEM_STCFG2);
au_writel(sleep_static_memctlr[2][1], MEM_STTIME2);
au_writel(sleep_static_memctlr[2][2], MEM_STADDR2);
au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
alchemy_wrsmem(sleep_static_memctlr[0][0], AU1000_MEM_STCFG0);
alchemy_wrsmem(sleep_static_memctlr[0][1], AU1000_MEM_STTIME0);
alchemy_wrsmem(sleep_static_memctlr[0][2], AU1000_MEM_STADDR0);
alchemy_wrsmem(sleep_static_memctlr[1][0], AU1000_MEM_STCFG1);
alchemy_wrsmem(sleep_static_memctlr[1][1], AU1000_MEM_STTIME1);
alchemy_wrsmem(sleep_static_memctlr[1][2], AU1000_MEM_STADDR1);
alchemy_wrsmem(sleep_static_memctlr[2][0], AU1000_MEM_STCFG2);
alchemy_wrsmem(sleep_static_memctlr[2][1], AU1000_MEM_STTIME2);
alchemy_wrsmem(sleep_static_memctlr[2][2], AU1000_MEM_STADDR2);
alchemy_wrsmem(sleep_static_memctlr[3][0], AU1000_MEM_STCFG3);
alchemy_wrsmem(sleep_static_memctlr[3][1], AU1000_MEM_STTIME3);
alchemy_wrsmem(sleep_static_memctlr[3][2], AU1000_MEM_STADDR3);
}
void au_sleep(void)

View File

@ -27,12 +27,9 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <asm/dma-coherence.h>
#include <asm/mipsregs.h>
#include <asm/time.h>
#include <au1000.h>
@ -41,18 +38,6 @@ extern void set_cpuspec(void);
void __init plat_mem_setup(void)
{
unsigned long est_freq;
/* determine core clock */
est_freq = au1xxx_calc_clock();
est_freq += 5000; /* round */
est_freq -= est_freq % 10000;
printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
/* this is faster than wasting cycles trying to approximate it */
preset_lpj = (est_freq >> 1) / HZ;
if (au1xxx_cpu_needs_config_od())
/* Various early Au1xx0 errata corrected by this */
set_c0_config(1 << 19); /* Set Config[OD] */

View File

@ -46,7 +46,7 @@
static cycle_t au1x_counter1_read(struct clocksource *cs)
{
return au_readl(SYS_RTCREAD);
return alchemy_rdsys(AU1000_SYS_RTCREAD);
}
static struct clocksource au1x_counter1_clocksource = {
@ -60,12 +60,11 @@ static struct clocksource au1x_counter1_clocksource = {
static int au1x_rtcmatch2_set_next_event(unsigned long delta,
struct clock_event_device *cd)
{
delta += au_readl(SYS_RTCREAD);
delta += alchemy_rdsys(AU1000_SYS_RTCREAD);
/* wait for register access */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21)
while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M21)
;
au_writel(delta, SYS_RTCMATCH2);
au_sync();
alchemy_wrsys(delta, AU1000_SYS_RTCMATCH2);
return 0;
}
@ -112,31 +111,29 @@ static int __init alchemy_time_init(unsigned int m2int)
* (the 32S bit seems to be stuck set to 1 once a single clock-
* edge is detected, hence the timeouts).
*/
if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK))
if (CNTR_OK != (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & CNTR_OK))
goto cntr_err;
/*
* setup counter 1 (RTC) to tick at full speed
*/
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t)
while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T1S) && --t)
asm volatile ("nop");
if (!t)
goto cntr_err;
au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */
au_sync();
alchemy_wrsys(0, AU1000_SYS_RTCTRIM); /* 32.768 kHz */
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t)
asm volatile ("nop");
if (!t)
goto cntr_err;
au_writel(0, SYS_RTCWRITE);
au_sync();
alchemy_wrsys(0, AU1000_SYS_RTCWRITE);
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t)
asm volatile ("nop");
if (!t)
goto cntr_err;

View File

@ -9,6 +9,7 @@
*
*/
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
@ -387,10 +388,25 @@ static inline void au1200_usb_init(void)
udelay(1000);
}
static inline void au1000_usb_init(unsigned long rb, int reg)
static inline int au1000_usb_init(unsigned long rb, int reg)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
unsigned long r = __raw_readl(base);
struct clk *c;
/* 48MHz check. Don't init if no one can provide it */
c = clk_get(NULL, "usbh_clk");
if (IS_ERR(c))
return -ENODEV;
if (clk_round_rate(c, 48000000) != 48000000) {
clk_put(c);
return -ENODEV;
}
if (clk_set_rate(c, 48000000)) {
clk_put(c);
return -ENODEV;
}
clk_put(c);
#if defined(__BIG_ENDIAN)
r |= USBHEN_BE;
@ -400,6 +416,8 @@ static inline void au1000_usb_init(unsigned long rb, int reg)
__raw_writel(r, base);
wmb();
udelay(1000);
return 0;
}
@ -407,8 +425,15 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
unsigned long r = __raw_readl(base + creg);
struct clk *c = clk_get(NULL, "usbh_clk");
if (IS_ERR(c))
return;
if (enable) {
if (clk_prepare_enable(c))
goto out;
__raw_writel(r | USBHEN_CE, base + creg);
wmb();
udelay(1000);
@ -423,7 +448,10 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
} else {
__raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
wmb();
clk_disable_unprepare(c);
}
out:
clk_put(c);
}
static inline int au1000_usb_control(int block, int enable, unsigned long rb,
@ -457,11 +485,11 @@ int alchemy_usb_control(int block, int enable)
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1100:
ret = au1000_usb_control(block, enable,
AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
break;
case ALCHEMY_CPU_AU1550:
ret = au1000_usb_control(block, enable,
AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
break;
case ALCHEMY_CPU_AU1200:
ret = au1200_usb_control(block, enable);
@ -569,14 +597,18 @@ static struct syscore_ops alchemy_usb_pm_ops = {
static int __init alchemy_usb_init(void)
{
int ret = 0;
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1100:
au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
ret = au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR,
AU1000_OHCICFG);
break;
case ALCHEMY_CPU_AU1550:
au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
ret = au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR,
AU1550_OHCICFG);
break;
case ALCHEMY_CPU_AU1200:
au1200_usb_init();
@ -586,8 +618,9 @@ static int __init alchemy_usb_init(void)
break;
}
register_syscore_ops(&alchemy_usb_pm_ops);
if (!ret)
register_syscore_ops(&alchemy_usb_pm_ops);
return 0;
return ret;
}
arch_initcall(alchemy_usb_init);

View File

@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/init.h>
@ -496,6 +497,7 @@ int __init db1000_dev_setup(void)
int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1;
unsigned long pfc;
struct clk *c, *p;
if (board == BCSR_WHOAMI_DB1500) {
c0 = AU1500_GPIO2_INT;
@ -518,14 +520,25 @@ int __init db1000_dev_setup(void)
gpio_direction_input(20); /* sd1 cd# */
/* spi_gpio on SSI0 pins */
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
pfc = alchemy_rdsys(AU1000_SYS_PINFUNC);
pfc |= (1 << 0); /* SSI0 pins as GPIOs */
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
spi_register_board_info(db1100_spi_info,
ARRAY_SIZE(db1100_spi_info));
/* link LCD clock to AUXPLL */
p = clk_get(NULL, "auxpll_clk");
c = clk_get(NULL, "lcd_intclk");
if (!IS_ERR(c) && !IS_ERR(p)) {
clk_set_parent(c, p);
clk_set_rate(c, clk_get_rate(p));
}
if (!IS_ERR(c))
clk_put(c);
if (!IS_ERR(p))
clk_put(p);
platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
platform_device_register(&db1100_spi_dev);
} else if (board == BCSR_WHOAMI_DB1000) {

View File

@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
@ -129,7 +130,6 @@ static int __init db1200_detect_board(void)
int __init db1200_board_setup(void)
{
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
if (db1200_detect_board())
@ -149,34 +149,6 @@ int __init db1200_board_setup(void)
" Board-ID %d Daughtercard ID %d\n", get_system_type(),
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
/* SMBus/SPI on PSC0, Audio on PSC1 */
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
/* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
* CPU clock; all other clock generators off/unused.
*/
div = (get_au1x00_speed() + 25000000) / 50000000;
if (div & 1)
div++;
div = ((div >> 1) - 1) & 0xff;
freq0 = div << SYS_FC_FRDIV0_BIT;
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
freq0 |= SYS_FC_FE0; /* enable F0 */
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
/* psc0_intclk comes 1:1 from F0 */
clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
wmb();
return 0;
}
@ -250,7 +222,7 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static int au1200_nand_device_ready(struct mtd_info *mtd)
{
return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}
static struct mtd_partition db1200_nand_parts[] = {
@ -847,6 +819,7 @@ int __init db1200_dev_setup(void)
unsigned long pfc;
unsigned short sw;
int swapped, bid;
struct clk *c;
bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
@ -859,6 +832,24 @@ int __init db1200_dev_setup(void)
irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
/* SMBus/SPI on PSC0, Audio on PSC1 */
pfc = alchemy_rdsys(AU1000_SYS_PINFUNC);
pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
/* get 50MHz for I2C driver on PSC0 */
c = clk_get(NULL, "psc0_intclk");
if (!IS_ERR(c)) {
pfc = clk_round_rate(c, 50000000);
if ((pfc < 1) || (abs(50000000 - pfc) > 2500000))
pr_warn("DB1200: cant get I2C close to 50MHz\n");
else
clk_set_rate(c, pfc);
clk_put(c);
}
/* insert/eject pairs: one of both is always screaming. To avoid
* issues they must not be automatically enabled when initially
* requested.
@ -886,7 +877,7 @@ int __init db1200_dev_setup(void)
* As a result, in SPI mode, OTG simply won't work (PSC0 uses
* it as an input pin which is pulled high on the boards).
*/
pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
pfc = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
/* switch off OTG VBUS supply */
gpio_request(215, "otg-vbus");
@ -912,8 +903,7 @@ int __init db1200_dev_setup(void)
printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
printk(KERN_INFO " OTG port VBUS supply disabled\n");
}
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
/* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
* so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
@ -932,6 +922,11 @@ int __init db1200_dev_setup(void)
}
/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
c = clk_get(NULL, "psc1_intclk");
if (!IS_ERR(c)) {
clk_prepare_enable(c);
clk_put(c);
}
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();

View File

@ -4,6 +4,7 @@
* (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com>
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
@ -169,7 +170,7 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static int au1300_nand_device_ready(struct mtd_info *mtd)
{
return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}
static struct mtd_partition db1300_nand_parts[] = {
@ -731,6 +732,7 @@ static struct platform_device *db1300_dev[] __initdata = {
int __init db1300_dev_setup(void)
{
int swapped, cpldirq;
struct clk *c;
/* setup CPLD IRQ muxer */
cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1);
@ -761,6 +763,11 @@ int __init db1300_dev_setup(void)
(void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
/* I2C uses internal 48MHz EXTCLK1 */
c = clk_get(NULL, "psc3_intclk");
if (!IS_ERR(c)) {
clk_prepare_enable(c);
clk_put(c);
}
__raw_writel(PSC_SEL_CLK_INTCLK,
(void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();

View File

@ -4,6 +4,7 @@
* (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
@ -31,16 +32,16 @@
static void __init db1550_hw_setup(void)
{
void __iomem *base;
unsigned long v;
/* complete SPI setup: link psc0_intclk to a 48MHz source,
* and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC
* for AC97 on PB1550.
*/
base = (void __iomem *)SYS_CLKSRC;
__raw_writel(__raw_readl(base) | 0x000001e0, base);
base = (void __iomem *)SYS_PINFUNC;
__raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base);
wmb();
v = alchemy_rdsys(AU1000_SYS_CLKSRC);
alchemy_wrsys(v | 0x000001e0, AU1000_SYS_CLKSRC);
v = alchemy_rdsys(AU1000_SYS_PINFUNC);
alchemy_wrsys(v | 1 | SYS_PF_PSC1_S1, AU1000_SYS_PINFUNC);
/* reset the AC97 codec now, the reset time in the psc-ac97 driver
* is apparently too short although it's ridiculous as it is.
@ -151,7 +152,7 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static int au1550_nand_device_ready(struct mtd_info *mtd)
{
return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}
static struct mtd_partition db1550_nand_parts[] = {
@ -217,7 +218,7 @@ static struct platform_device pb1550_nand_dev = {
static void __init pb1550_nand_setup(void)
{
int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
int boot_swapboot = (alchemy_rdsmem(AU1000_MEM_STSTAT) & (0x7 << 1)) |
((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
gpio_direction_input(206); /* de-assert NAND CS# */
@ -574,6 +575,7 @@ static void __init pb1550_devices(void)
int __init db1550_dev_setup(void)
{
int swapped, id;
struct clk *c;
id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550);
@ -582,6 +584,17 @@ int __init db1550_dev_setup(void)
spi_register_board_info(db1550_spi_devs,
ARRAY_SIZE(db1550_i2c_devs));
c = clk_get(NULL, "psc0_intclk");
if (!IS_ERR(c)) {
clk_prepare_enable(c);
clk_put(c);
}
c = clk_get(NULL, "psc2_intclk");
if (!IS_ERR(c)) {
clk_prepare_enable(c);
clk_put(c);
}
/* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);

View File

@ -45,23 +45,20 @@ static int db1x_pm_enter(suspend_state_t state)
alchemy_gpio1_input_enable();
/* clear and setup wake cause and source */
au_writel(0, SYS_WAKEMSK);
au_sync();
au_writel(0, SYS_WAKESRC);
au_sync();
alchemy_wrsys(0, AU1000_SYS_WAKEMSK);
alchemy_wrsys(0, AU1000_SYS_WAKESRC);
au_writel(db1x_pm_wakemsk, SYS_WAKEMSK);
au_sync();
alchemy_wrsys(db1x_pm_wakemsk, AU1000_SYS_WAKEMSK);
/* setup 1Hz-timer-based wakeup: wait for reg access */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20)
asm volatile ("nop");
au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2);
au_sync();
alchemy_wrsys(alchemy_rdsys(AU1000_SYS_TOYREAD) + db1x_pm_sleep_secs,
AU1000_SYS_TOYMATCH2);
/* wait for value to really hit the register */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20)
asm volatile ("nop");
/* ...and now the sandman can come! */
@ -102,12 +99,10 @@ static void db1x_pm_end(void)
/* read and store wakeup source, the clear the register. To
* be able to clear it, WAKEMSK must be cleared first.
*/
db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
au_writel(0, SYS_WAKEMSK);
au_writel(0, SYS_WAKESRC);
au_sync();
db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC);
alchemy_wrsys(0, AU1000_SYS_WAKEMSK);
alchemy_wrsys(0, AU1000_SYS_WAKESRC);
}
static const struct platform_suspend_ops db1x_pm_ops = {
@ -242,17 +237,13 @@ static int __init pm_init(void)
* for confirmation since there's plenty of time from here to
* the next suspend cycle.
*/
if (au_readl(SYS_TOYTRIM) != 32767) {
au_writel(32767, SYS_TOYTRIM);
au_sync();
}
if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767)
alchemy_wrsys(32767, AU1000_SYS_TOYTRIM);
db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC);
au_writel(0, SYS_WAKESRC);
au_sync();
au_writel(0, SYS_WAKEMSK);
au_sync();
alchemy_wrsys(0, AU1000_SYS_WAKESRC);
alchemy_wrsys(0, AU1000_SYS_WAKEMSK);
suspend_set_ops(&db1x_pm_ops);

View File

@ -11,8 +11,6 @@ config BCM47XX_SSB
select SSB_DRIVER_PCICORE if PCI
select SSB_PCICORE_HOSTMODE if PCI
select SSB_DRIVER_GPIO
select GPIOLIB
select LEDS_GPIO_REGISTER
default y
help
Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@ -22,6 +20,7 @@ config BCM47XX_SSB
config BCM47XX_BCMA
bool "BCMA Support for Broadcom BCM47XX"
select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_HIGHMEM
select CPU_MIPSR2_IRQ_VI
select BCMA
select BCMA_HOST_SOC
@ -29,8 +28,6 @@ config BCM47XX_BCMA
select BCMA_HOST_PCI if PCI
select BCMA_DRIVER_PCI_HOSTMODE if PCI
select BCMA_DRIVER_GPIO
select GPIOLIB
select LEDS_GPIO_REGISTER
default y
help
Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.

View File

@ -3,6 +3,9 @@
#include <linux/kernel.h>
/* prom.c */
void __init bcm47xx_prom_highmem_init(void);
/* buttons.c */
int __init bcm47xx_buttons_register(void);

View File

@ -58,6 +58,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst =
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
{{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"},
{{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"},
{{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
{{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"},
{{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"},
@ -80,6 +81,14 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons
{ {0}, NULL},
};
/* hardware_version, boardnum */
static const
struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = {
{{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"},
{{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"},
{ {0}, NULL},
};
/* productid */
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
@ -98,7 +107,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
/* ModelId */
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
{{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"},
{{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"},
{{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
{{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
{{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
@ -180,9 +189,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
{{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
{{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
{{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
{ {0}, NULL},
};
@ -237,6 +246,15 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
}
}
if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 &&
bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) {
for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
if (!strstarts(buf1, e2->value1) &&
!strcmp(buf2, e2->value2))
return &e2->board;
}
}
if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
if (!strcmp(buf1, e1->value1))

View File

@ -55,6 +55,11 @@ bcm47xx_buttons_asus_wl330ge[] __initconst = {
BCM47XX_GPIO_KEY(2, KEY_RESTART),
};
static const struct gpio_keys_button
bcm47xx_buttons_asus_wl500g[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
static const struct gpio_keys_button
bcm47xx_buttons_asus_wl500gd[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
@ -265,7 +270,7 @@ bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
};
static const struct gpio_keys_button
bcm47xx_buttons_linksys_wrt54gsv1[] __initconst = {
bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = {
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
@ -288,6 +293,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
/* Microsoft */
static const struct gpio_keys_button
bcm47xx_buttons_microsoft_nm700[] __initconst = {
BCM47XX_GPIO_KEY(7, KEY_RESTART),
};
/* Motorola */
static const struct gpio_keys_button
@ -328,6 +340,12 @@ bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
static const struct gpio_keys_button
bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = {
BCM47XX_GPIO_KEY(4, KEY_RESTART),
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
};
static const struct gpio_keys_button
bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
@ -395,6 +413,9 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_ASUS_WL330GE:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
break;
case BCM47XX_BOARD_ASUS_WL500G:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g);
break;
case BCM47XX_BOARD_ASUS_WL500GD:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
break;
@ -501,12 +522,14 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54gsv1);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic);
break;
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
break;
@ -517,6 +540,10 @@ int __init bcm47xx_buttons_register(void)
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs);
break;
case BCM47XX_BOARD_MICROSOFT_MN700:
err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700);
break;
case BCM47XX_BOARD_MOTOROLA_WE800G:
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
break;
@ -536,6 +563,9 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
break;
case BCM47XX_BOARD_NETGEAR_WNR3500L:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1);
break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
break;

View File

@ -34,6 +34,15 @@ bcm47xx_leds_asus_rtn12[] __initconst = {
BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
bcm47xx_leds_asus_rtn15u[] __initconst = {
/* TODO: Add "wlan" LED */
BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
bcm47xx_leds_asus_rtn16[] __initconst = {
BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
@ -42,8 +51,8 @@ bcm47xx_leds_asus_rtn16[] __initconst = {
static const struct gpio_led
bcm47xx_leds_asus_rtn66u[] __initconst = {
BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
@ -63,6 +72,11 @@ bcm47xx_leds_asus_wl330ge[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
};
static const struct gpio_led
bcm47xx_leds_asus_wl500g[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
};
static const struct gpio_led
bcm47xx_leds_asus_wl500gd[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
@ -216,8 +230,8 @@ bcm47xx_leds_linksys_e1000v1[] __initconst = {
static const struct gpio_led
bcm47xx_leds_linksys_e1000v21[] __initconst = {
BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
};
@ -292,7 +306,7 @@ bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
};
static const struct gpio_led
bcm47xx_leds_linksys_wrt54gsv1[] __initconst = {
bcm47xx_leds_linksys_wrt54g_generic[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
@ -306,6 +320,24 @@ bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = {
BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
};
/* Verified on: WRT54GS V1.0 */
static const struct gpio_led
bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = {
BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
};
/* Verified on: WRT54GL V1.1 */
static const struct gpio_led
bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = {
BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
@ -325,11 +357,17 @@ bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
static const struct gpio_led
bcm47xx_leds_linksys_wrtsl54gs[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(7, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
};
/* Microsoft */
static const struct gpio_led
bcm47xx_leds_microsoft_nm700[] __initconst = {
BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
};
/* Motorola */
@ -376,6 +414,15 @@ bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
bcm47xx_leds_netgear_wnr3500lv1[] __initconst = {
BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
@ -417,6 +464,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_ASUS_RTN12:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
break;
case BCM47XX_BOARD_ASUS_RTN15U:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u);
break;
case BCM47XX_BOARD_ASUS_RTN16:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
break;
@ -432,6 +482,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_ASUS_WL330GE:
bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
break;
case BCM47XX_BOARD_ASUS_WL500G:
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g);
break;
case BCM47XX_BOARD_ASUS_WL500GD:
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
break;
@ -538,12 +591,18 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54gsv1);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467);
break;
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic);
break;
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
break;
@ -554,6 +613,10 @@ void __init bcm47xx_leds_register(void)
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs);
break;
case BCM47XX_BOARD_MICROSOFT_MN700:
bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700);
break;
case BCM47XX_BOARD_MOTOROLA_WE800G:
bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
break;
@ -570,6 +633,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
break;
case BCM47XX_BOARD_NETGEAR_WNR3500L:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1);
break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
break;

View File

@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id)
chip_id);
}
static unsigned long lowmem __initdata;
static __init void prom_init_mem(void)
{
unsigned long mem;
@ -87,6 +89,7 @@ static __init void prom_init_mem(void)
if (!memcmp(prom_init, prom_init + mem, 32))
break;
}
lowmem = mem;
/* Ignoring the last page when ddr size is 128M. Cached
* accesses to last page is causing the processor to prefetch
@ -95,7 +98,6 @@ static __init void prom_init_mem(void)
*/
if (c->cputype == CPU_74K && (mem == (128 << 20)))
mem -= 0x1000;
add_memory_region(0, mem, BOOT_MEM_RAM);
}
@ -114,3 +116,67 @@ void __init prom_init(void)
void __init prom_free_prom_memory(void)
{
}
#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)
#define EXTVBASE 0xc0000000
#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)
#include <asm/tlbflush.h>
/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
* dropped. Calling it at this stage causes a hang.
*/
void __cpuinit early_tlb_init(void)
{
write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_wired(0);
temp_tlb_entry = current_cpu_data.tlbsize - 1;
local_flush_tlb_all();
}
void __init bcm47xx_prom_highmem_init(void)
{
unsigned long off = (unsigned long)prom_init;
unsigned long extmem = 0;
bool highmem_region = false;
if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
return;
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
highmem_region = true;
if (lowmem != 128 << 20 || !highmem_region)
return;
early_tlb_init();
/* Add one temporary TLB entry to map SDRAM Region 2.
* Physical Virtual
* 0x80000000 0xc0000000 (1st: 256MB)
* 0x90000000 0xd0000000 (2nd: 256MB)
*/
add_temporary_entry(ENTRYLO(0x80000000),
ENTRYLO(0x80000000 + (256 << 20)),
EXTVBASE, PM_256M);
off = EXTVBASE + __pa(off);
for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
if (!memcmp(prom_init, (void *)(off + extmem), 16))
break;
}
extmem -= lowmem;
early_tlb_init();
if (!extmem)
return;
pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n",
extmem >> 20);
/* TODO: Register extra memory */
}
#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */

View File

@ -59,12 +59,12 @@ static void bcm47xx_machine_restart(char *command)
switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
case BCM47XX_BUS_TYPE_SSB:
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 3);
break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
case BCM47XX_BUS_TYPE_BCMA:
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 3);
break;
#endif
}
@ -218,6 +218,9 @@ void __init plat_mem_setup(void)
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
bcm47xx_register_bcma();
bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
#ifdef CONFIG_HIGHMEM
bcm47xx_prom_highmem_init();
#endif
#endif
} else {
printk(KERN_INFO "bcm47xx: using ssb bus\n");

View File

@ -28,6 +28,8 @@
#include <bcm47xx.h>
#include <bcm47xx_nvram.h>
#include <linux/if_ether.h>
#include <linux/etherdevice.h>
static void create_key(const char *prefix, const char *postfix,
const char *name, char *buf, int len)
@ -631,6 +633,33 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
}
}
static bool bcm47xx_is_valid_mac(u8 *mac)
{
return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
}
static int bcm47xx_increase_mac_addr(u8 *mac, u8 num)
{
u8 *oui = mac + ETH_ALEN/2 - 1;
u8 *p = mac + ETH_ALEN - 1;
do {
(*p) += num;
if (*p > num)
break;
p--;
num = 1;
} while (p != oui);
if (p == oui) {
pr_err("unable to fetch mac address\n");
return -ENOENT;
}
return 0;
}
static int mac_addr_used = 2;
static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
const char *prefix, bool fallback)
{
@ -648,6 +677,25 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
/* The address prefix 00:90:4C is used by Broadcom in their initial
configuration. When a mac address with the prefix 00:90:4C is used
all devices from the same series are sharing the same mac address.
To prevent mac address collisions we replace them with a mac address
based on the base address. */
if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
u8 mac[6];
nvram_read_macaddr(NULL, "et0macaddr", mac, false);
if (bcm47xx_is_valid_mac(mac)) {
int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
if (!err) {
ether_addr_copy(sprom->il0mac, mac);
mac_addr_used++;
}
}
}
}
static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,

View File

@ -24,7 +24,9 @@ EXPORT_SYMBOL(bcm63xx_regs_base);
const int *bcm63xx_irqs;
EXPORT_SYMBOL(bcm63xx_irqs);
static u16 bcm63xx_cpu_id;
u16 bcm63xx_cpu_id __read_mostly;
EXPORT_SYMBOL(bcm63xx_cpu_id);
static u8 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;
@ -97,13 +99,6 @@ static const int bcm6368_irqs[] = {
};
u16 __bcm63xx_get_cpu_id(void)
{
return bcm63xx_cpu_id;
}
EXPORT_SYMBOL(__bcm63xx_get_cpu_id);
u8 bcm63xx_get_cpu_rev(void)
{
return bcm63xx_cpu_rev;

View File

@ -14,7 +14,6 @@
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
#ifdef BCMCPU_RUNTIME_DETECT
static const unsigned long bcm6348_regs_enetdmac[] = {
[ENETDMAC_CHANCFG] = ENETDMAC_CHANCFG_REG,
[ENETDMAC_IR] = ENETDMAC_IR_REG,
@ -43,9 +42,6 @@ static __init void bcm63xx_enetdmac_regs_init(void)
else
bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac;
}
#else
static __init void bcm63xx_enetdmac_regs_init(void) { }
#endif
static struct resource shared_res[] = {
{

View File

@ -18,7 +18,6 @@
#include <bcm63xx_dev_spi.h>
#include <bcm63xx_regs.h>
#ifdef BCMCPU_RUNTIME_DETECT
/*
* register offsets
*/
@ -41,9 +40,6 @@ static __init void bcm63xx_spi_regs_init(void)
BCMCPU_IS_6362() || BCMCPU_IS_6368())
bcm63xx_regs_spi = bcm6358_regs_spi;
}
#else
static __init void bcm63xx_spi_regs_init(void) { }
#endif
static struct resource spi_resources[] = {
{

View File

@ -18,19 +18,6 @@
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
#ifndef BCMCPU_RUNTIME_DETECT
#define gpio_out_low_reg GPIO_DATA_LO_REG
#ifdef CONFIG_BCM63XX_CPU_6345
#ifdef gpio_out_low_reg
#undef gpio_out_low_reg
#define gpio_out_low_reg GPIO_DATA_LO_REG_6345
#endif /* gpio_out_low_reg */
#endif /* CONFIG_BCM63XX_CPU_6345 */
static inline void bcm63xx_gpio_out_low_reg_init(void)
{
}
#else /* ! BCMCPU_RUNTIME_DETECT */
static u32 gpio_out_low_reg;
static void bcm63xx_gpio_out_low_reg_init(void)
@ -44,7 +31,6 @@ static void bcm63xx_gpio_out_low_reg_init(void)
break;
}
}
#endif /* ! BCMCPU_RUNTIME_DETECT */
static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
static u32 gpio_out_low, gpio_out_high;

View File

@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
@ -19,222 +20,20 @@
#include <bcm63xx_io.h>
#include <bcm63xx_irq.h>
static void __dispatch_internal(void) __maybe_unused;
static void __dispatch_internal_64(void) __maybe_unused;
static void __internal_irq_mask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_mask_64(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#ifndef BCMCPU_RUNTIME_DETECT
#ifdef CONFIG_BCM63XX_CPU_3368
#define irq_stat_reg PERF_IRQSTAT_3368_REG
#define irq_mask_reg PERF_IRQMASK_3368_REG
#define irq_bits 32
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_3368
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6328
#define irq_stat_reg PERF_IRQSTAT_6328_REG
#define irq_mask_reg PERF_IRQMASK_6328_REG
#define irq_bits 64
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
#define irq_bits 32
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6338
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
#define irq_stat_reg PERF_IRQSTAT_6345_REG
#define irq_mask_reg PERF_IRQMASK_6345_REG
#define irq_bits 32
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
#define irq_stat_reg PERF_IRQSTAT_6348_REG
#define irq_mask_reg PERF_IRQMASK_6348_REG
#define irq_bits 32
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6348
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
#define irq_stat_reg PERF_IRQSTAT_6358_REG
#define irq_mask_reg PERF_IRQMASK_6358_REG
#define irq_bits 32
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6362
#define irq_stat_reg PERF_IRQSTAT_6362_REG
#define irq_mask_reg PERF_IRQMASK_6362_REG
#define irq_bits 64
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6362
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6368
#define irq_stat_reg PERF_IRQSTAT_6368_REG
#define irq_mask_reg PERF_IRQMASK_6368_REG
#define irq_bits 64
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE)
#define ext_irq_count 6
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368
#define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368
#endif
static DEFINE_SPINLOCK(ipic_lock);
static DEFINE_SPINLOCK(epic_lock);
#if irq_bits == 32
#define dispatch_internal __dispatch_internal
#define internal_irq_mask __internal_irq_mask_32
#define internal_irq_unmask __internal_irq_unmask_32
#else
#define dispatch_internal __dispatch_internal_64
#define internal_irq_mask __internal_irq_mask_64
#define internal_irq_unmask __internal_irq_unmask_64
#endif
#define irq_stat_addr (bcm63xx_regset_address(RSET_PERF) + irq_stat_reg)
#define irq_mask_addr (bcm63xx_regset_address(RSET_PERF) + irq_mask_reg)
static inline void bcm63xx_init_irq(void)
{
}
#else /* ! BCMCPU_RUNTIME_DETECT */
static u32 irq_stat_addr, irq_mask_addr;
static void (*dispatch_internal)(void);
static u32 irq_stat_addr[2];
static u32 irq_mask_addr[2];
static void (*dispatch_internal)(int cpu);
static int is_ext_irq_cascaded;
static unsigned int ext_irq_count;
static unsigned int ext_irq_start, ext_irq_end;
static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2;
static void (*internal_irq_mask)(unsigned int irq);
static void (*internal_irq_unmask)(unsigned int irq);
static void (*internal_irq_mask)(struct irq_data *d);
static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m);
static void bcm63xx_init_irq(void)
{
int irq_bits;
irq_stat_addr = bcm63xx_regset_address(RSET_PERF);
irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_3368_REG;
irq_mask_addr += PERF_IRQMASK_3368_REG;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
break;
case BCM6328_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6328_REG;
irq_mask_addr += PERF_IRQMASK_6328_REG;
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
break;
case BCM6345_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6345_REG;
irq_mask_addr += PERF_IRQMASK_6345_REG;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
break;
case BCM6348_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6348_REG;
irq_mask_addr += PERF_IRQMASK_6348_REG;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
break;
case BCM6358_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6358_REG;
irq_mask_addr += PERF_IRQMASK_6358_REG;
irq_bits = 32;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
break;
case BCM6362_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6362_REG;
irq_mask_addr += PERF_IRQMASK_6362_REG;
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
break;
case BCM6368_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6368_REG;
irq_mask_addr += PERF_IRQMASK_6368_REG;
irq_bits = 64;
ext_irq_count = 6;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
break;
default:
BUG();
}
if (irq_bits == 32) {
dispatch_internal = __dispatch_internal;
internal_irq_mask = __internal_irq_mask_32;
internal_irq_unmask = __internal_irq_unmask_32;
} else {
dispatch_internal = __dispatch_internal_64;
internal_irq_mask = __internal_irq_mask_64;
internal_irq_unmask = __internal_irq_unmask_64;
}
}
#endif /* ! BCMCPU_RUNTIME_DETECT */
static inline u32 get_ext_irq_perf_reg(int irq)
{
@ -252,53 +51,113 @@ static inline void handle_internal(int intbit)
do_IRQ(intbit + IRQ_INTERNAL_BASE);
}
static inline int enable_irq_for_cpu(int cpu, struct irq_data *d,
const struct cpumask *m)
{
bool enable = cpu_online(cpu);
#ifdef CONFIG_SMP
if (m)
enable &= cpu_isset(cpu, *m);
else if (irqd_affinity_was_set(d))
enable &= cpu_isset(cpu, *d->affinity);
#endif
return enable;
}
/*
* dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
* prioritize any interrupt relatively to another. the static counter
* will resume the loop where it ended the last time we left this
* function.
*/
static void __dispatch_internal(void)
{
u32 pending;
static int i;
pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr);
if (!pending)
return ;
while (1) {
int to_call = i;
i = (i + 1) & 0x1f;
if (pending & (1 << to_call)) {
handle_internal(to_call);
break;
}
}
#define BUILD_IPIC_INTERNAL(width) \
void __dispatch_internal_##width(int cpu) \
{ \
u32 pending[width / 32]; \
unsigned int src, tgt; \
bool irqs_pending = false; \
static unsigned int i[2]; \
unsigned int *next = &i[cpu]; \
unsigned long flags; \
\
/* read registers in reverse order */ \
spin_lock_irqsave(&ipic_lock, flags); \
for (src = 0, tgt = (width / 32); src < (width / 32); src++) { \
u32 val; \
\
val = bcm_readl(irq_stat_addr[cpu] + src * sizeof(u32)); \
val &= bcm_readl(irq_mask_addr[cpu] + src * sizeof(u32)); \
pending[--tgt] = val; \
\
if (val) \
irqs_pending = true; \
} \
spin_unlock_irqrestore(&ipic_lock, flags); \
\
if (!irqs_pending) \
return; \
\
while (1) { \
unsigned int to_call = *next; \
\
*next = (*next + 1) & (width - 1); \
if (pending[to_call / 32] & (1 << (to_call & 0x1f))) { \
handle_internal(to_call); \
break; \
} \
} \
} \
\
static void __internal_irq_mask_##width(struct irq_data *d) \
{ \
u32 val; \
unsigned irq = d->irq - IRQ_INTERNAL_BASE; \
unsigned reg = (irq / 32) ^ (width/32 - 1); \
unsigned bit = irq & 0x1f; \
unsigned long flags; \
int cpu; \
\
spin_lock_irqsave(&ipic_lock, flags); \
for_each_present_cpu(cpu) { \
if (!irq_mask_addr[cpu]) \
break; \
\
val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
val &= ~(1 << bit); \
bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
} \
spin_unlock_irqrestore(&ipic_lock, flags); \
} \
\
static void __internal_irq_unmask_##width(struct irq_data *d, \
const struct cpumask *m) \
{ \
u32 val; \
unsigned irq = d->irq - IRQ_INTERNAL_BASE; \
unsigned reg = (irq / 32) ^ (width/32 - 1); \
unsigned bit = irq & 0x1f; \
unsigned long flags; \
int cpu; \
\
spin_lock_irqsave(&ipic_lock, flags); \
for_each_present_cpu(cpu) { \
if (!irq_mask_addr[cpu]) \
break; \
\
val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
if (enable_irq_for_cpu(cpu, d, m)) \
val |= (1 << bit); \
else \
val &= ~(1 << bit); \
bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
} \
spin_unlock_irqrestore(&ipic_lock, flags); \
}
static void __dispatch_internal_64(void)
{
u64 pending;
static int i;
pending = bcm_readq(irq_stat_addr) & bcm_readq(irq_mask_addr);
if (!pending)
return ;
while (1) {
int to_call = i;
i = (i + 1) & 0x3f;
if (pending & (1ull << to_call)) {
handle_internal(to_call);
break;
}
}
}
BUILD_IPIC_INTERNAL(32);
BUILD_IPIC_INTERNAL(64);
asmlinkage void plat_irq_dispatch(void)
{
@ -317,8 +176,11 @@ asmlinkage void plat_irq_dispatch(void)
if (cause & CAUSEF_IP1)
do_IRQ(1);
if (cause & CAUSEF_IP2)
dispatch_internal();
if (!is_ext_irq_cascaded) {
dispatch_internal(0);
if (is_ext_irq_cascaded) {
if (cause & CAUSEF_IP3)
dispatch_internal(1);
} else {
if (cause & CAUSEF_IP3)
do_IRQ(IRQ_EXT_0);
if (cause & CAUSEF_IP4)
@ -335,50 +197,14 @@ asmlinkage void plat_irq_dispatch(void)
* internal IRQs operations: only mask/unmask on PERF irq mask
* register.
*/
static void __internal_irq_mask_32(unsigned int irq)
{
u32 mask;
mask = bcm_readl(irq_mask_addr);
mask &= ~(1 << irq);
bcm_writel(mask, irq_mask_addr);
}
static void __internal_irq_mask_64(unsigned int irq)
{
u64 mask;
mask = bcm_readq(irq_mask_addr);
mask &= ~(1ull << irq);
bcm_writeq(mask, irq_mask_addr);
}
static void __internal_irq_unmask_32(unsigned int irq)
{
u32 mask;
mask = bcm_readl(irq_mask_addr);
mask |= (1 << irq);
bcm_writel(mask, irq_mask_addr);
}
static void __internal_irq_unmask_64(unsigned int irq)
{
u64 mask;
mask = bcm_readq(irq_mask_addr);
mask |= (1ull << irq);
bcm_writeq(mask, irq_mask_addr);
}
static void bcm63xx_internal_irq_mask(struct irq_data *d)
{
internal_irq_mask(d->irq - IRQ_INTERNAL_BASE);
internal_irq_mask(d);
}
static void bcm63xx_internal_irq_unmask(struct irq_data *d)
{
internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE);
internal_irq_unmask(d, NULL);
}
/*
@ -389,8 +215,10 @@ static void bcm63xx_external_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg, regaddr;
unsigned long flags;
regaddr = get_ext_irq_perf_reg(irq);
spin_lock_irqsave(&epic_lock, flags);
reg = bcm_perf_readl(regaddr);
if (BCMCPU_IS_6348())
@ -399,16 +227,20 @@ static void bcm63xx_external_irq_mask(struct irq_data *d)
reg &= ~EXTIRQ_CFG_MASK(irq % 4);
bcm_perf_writel(reg, regaddr);
spin_unlock_irqrestore(&epic_lock, flags);
if (is_ext_irq_cascaded)
internal_irq_mask(irq + ext_irq_start);
internal_irq_mask(irq_get_irq_data(irq + ext_irq_start));
}
static void bcm63xx_external_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg, regaddr;
unsigned long flags;
regaddr = get_ext_irq_perf_reg(irq);
spin_lock_irqsave(&epic_lock, flags);
reg = bcm_perf_readl(regaddr);
if (BCMCPU_IS_6348())
@ -417,17 +249,21 @@ static void bcm63xx_external_irq_unmask(struct irq_data *d)
reg |= EXTIRQ_CFG_MASK(irq % 4);
bcm_perf_writel(reg, regaddr);
spin_unlock_irqrestore(&epic_lock, flags);
if (is_ext_irq_cascaded)
internal_irq_unmask(irq + ext_irq_start);
internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start),
NULL);
}
static void bcm63xx_external_irq_clear(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg, regaddr;
unsigned long flags;
regaddr = get_ext_irq_perf_reg(irq);
spin_lock_irqsave(&epic_lock, flags);
reg = bcm_perf_readl(regaddr);
if (BCMCPU_IS_6348())
@ -436,6 +272,7 @@ static void bcm63xx_external_irq_clear(struct irq_data *d)
reg |= EXTIRQ_CFG_CLEAR(irq % 4);
bcm_perf_writel(reg, regaddr);
spin_unlock_irqrestore(&epic_lock, flags);
}
static int bcm63xx_external_irq_set_type(struct irq_data *d,
@ -444,6 +281,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg, regaddr;
int levelsense, sense, bothedge;
unsigned long flags;
flow_type &= IRQ_TYPE_SENSE_MASK;
@ -478,6 +316,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
}
regaddr = get_ext_irq_perf_reg(irq);
spin_lock_irqsave(&epic_lock, flags);
reg = bcm_perf_readl(regaddr);
irq %= 4;
@ -522,6 +361,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
}
bcm_perf_writel(reg, regaddr);
spin_unlock_irqrestore(&epic_lock, flags);
irqd_set_trigger_type(d, flow_type);
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@ -532,6 +372,18 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
return IRQ_SET_MASK_OK_NOCOPY;
}
#ifdef CONFIG_SMP
static int bcm63xx_internal_set_affinity(struct irq_data *data,
const struct cpumask *dest,
bool force)
{
if (!irqd_irq_disabled(data))
internal_irq_unmask(data, dest);
return 0;
}
#endif
static struct irq_chip bcm63xx_internal_irq_chip = {
.name = "bcm63xx_ipic",
.irq_mask = bcm63xx_internal_irq_mask,
@ -554,12 +406,130 @@ static struct irqaction cpu_ip2_cascade_action = {
.flags = IRQF_NO_THREAD,
};
#ifdef CONFIG_SMP
static struct irqaction cpu_ip3_cascade_action = {
.handler = no_action,
.name = "cascade_ip3",
.flags = IRQF_NO_THREAD,
};
#endif
static struct irqaction cpu_ext_cascade_action = {
.handler = no_action,
.name = "cascade_extirq",
.flags = IRQF_NO_THREAD,
};
static void bcm63xx_init_irq(void)
{
int irq_bits;
irq_stat_addr[0] = bcm63xx_regset_address(RSET_PERF);
irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_3368_REG;
irq_mask_addr[0] += PERF_IRQMASK_3368_REG;
irq_stat_addr[1] = 0;
irq_stat_addr[1] = 0;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
break;
case BCM6328_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6328_REG(0);
irq_mask_addr[0] += PERF_IRQMASK_6328_REG(0);
irq_stat_addr[1] += PERF_IRQSTAT_6328_REG(1);
irq_stat_addr[1] += PERF_IRQMASK_6328_REG(1);
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6338_REG;
irq_mask_addr[0] += PERF_IRQMASK_6338_REG;
irq_stat_addr[1] = 0;
irq_mask_addr[1] = 0;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
break;
case BCM6345_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6345_REG;
irq_mask_addr[0] += PERF_IRQMASK_6345_REG;
irq_stat_addr[1] = 0;
irq_mask_addr[1] = 0;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
break;
case BCM6348_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6348_REG;
irq_mask_addr[0] += PERF_IRQMASK_6348_REG;
irq_stat_addr[1] = 0;
irq_mask_addr[1] = 0;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
break;
case BCM6358_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6358_REG(0);
irq_mask_addr[0] += PERF_IRQMASK_6358_REG(0);
irq_stat_addr[1] += PERF_IRQSTAT_6358_REG(1);
irq_mask_addr[1] += PERF_IRQMASK_6358_REG(1);
irq_bits = 32;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
break;
case BCM6362_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6362_REG(0);
irq_mask_addr[0] += PERF_IRQMASK_6362_REG(0);
irq_stat_addr[1] += PERF_IRQSTAT_6362_REG(1);
irq_mask_addr[1] += PERF_IRQMASK_6362_REG(1);
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
break;
case BCM6368_CPU_ID:
irq_stat_addr[0] += PERF_IRQSTAT_6368_REG(0);
irq_mask_addr[0] += PERF_IRQMASK_6368_REG(0);
irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
irq_bits = 64;
ext_irq_count = 6;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
break;
default:
BUG();
}
if (irq_bits == 32) {
dispatch_internal = __dispatch_internal_32;
internal_irq_mask = __internal_irq_mask_32;
internal_irq_unmask = __internal_irq_unmask_32;
} else {
dispatch_internal = __dispatch_internal_64;
internal_irq_mask = __internal_irq_mask_64;
internal_irq_unmask = __internal_irq_unmask_64;
}
}
void __init arch_init_irq(void)
{
int i;
@ -580,4 +550,14 @@ void __init arch_init_irq(void)
}
setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
#ifdef CONFIG_SMP
if (is_ext_irq_cascaded) {
setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action);
bcm63xx_internal_irq_chip.irq_set_affinity =
bcm63xx_internal_set_affinity;
cpumask_clear(irq_default_affinity);
cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
}
#endif
}

View File

@ -125,8 +125,6 @@
#define BCM6368_RESET_PCIE 0
#define BCM6368_RESET_PCIE_EXT 0
#ifdef BCMCPU_RUNTIME_DETECT
/*
* core reset bits
*/
@ -188,64 +186,6 @@ static int __init bcm63xx_reset_bits_init(void)
return 0;
}
#else
#ifdef CONFIG_BCM63XX_CPU_3368
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(3368)
};
#define reset_reg PERF_SOFTRESET_6358_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6328
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6328)
};
#define reset_reg PERF_SOFTRESET_6328_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6338)
};
#define reset_reg PERF_SOFTRESET_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
static const u32 bcm63xx_reset_bits[] = { };
#define reset_reg 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6348)
};
#define reset_reg PERF_SOFTRESET_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6358)
};
#define reset_reg PERF_SOFTRESET_6358_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6362
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6362)
};
#define reset_reg PERF_SOFTRESET_6362_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6368
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6368)
};
#define reset_reg PERF_SOFTRESET_6368_REG
#endif
static int __init bcm63xx_reset_bits_init(void) { return 0; }
#endif
static DEFINE_SPINLOCK(reset_mutex);

View File

@ -67,10 +67,24 @@ void error(char *x)
#include "../../../../lib/decompress_unxz.c"
#endif
unsigned long __stack_chk_guard;
void __stack_chk_guard_setup(void)
{
__stack_chk_guard = 0x000a0dff;
}
void __stack_chk_fail(void)
{
error("stack-protector: Kernel stack is corrupted\n");
}
void decompress_kernel(unsigned long boot_heap_start)
{
unsigned long zimage_start, zimage_size;
__stack_chk_guard_setup();
zimage_start = (unsigned long)(&__image_begin);
zimage_size = (unsigned long)(&__image_end) -
(unsigned long)(&__image_begin);

View File

@ -186,6 +186,15 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
return 7 - ipd_port;
else
return -1;
case CVMX_BOARD_TYPE_CUST_DSR1000N:
/*
* Port 2 connects to Broadcom PHY (B5081). Other ports (0-1)
* connect to a switch (BCM53115).
*/
if (ipd_port == 2)
return 8;
else
return -1;
}
/* Some unknown board. Somebody forgot to update this function... */
@ -274,6 +283,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
return result;
}
break;
case CVMX_BOARD_TYPE_CUST_DSR1000N:
if (ipd_port == 0 || ipd_port == 1) {
/* Ports 0 and 1 connect to a switch (BCM53115). */
result.s.link_up = 1;
result.s.full_duplex = 1;
result.s.speed = 1000;
return result;
} else {
/* Port 2 uses a Broadcom PHY (B5081). */
is_broadcom_phy = 1;
}
break;
}
phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
@ -738,6 +759,7 @@ enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(vo
case CVMX_BOARD_TYPE_LANAI2_G:
case CVMX_BOARD_TYPE_NIC10E_66:
case CVMX_BOARD_TYPE_UBNT_E100:
case CVMX_BOARD_TYPE_CUST_DSR1000N:
return USB_CLOCK_TYPE_CRYSTAL_12;
case CVMX_BOARD_TYPE_NIC10E:
return USB_CLOCK_TYPE_REF_12;

View File

@ -194,8 +194,7 @@ err_irq:
static __exit void oct_ilm_module_exit(void)
{
disable_timer(TIMER_NUM);
if (dir)
debugfs_remove_recursive(dir);
debugfs_remove_recursive(dir);
free_irq(OCTEON_IRQ_TIMER0 + TIMER_NUM, 0);
}

View File

@ -84,9 +84,14 @@ static void octeon_smp_hotplug_setup(void)
#ifdef CONFIG_HOTPLUG_CPU
struct linux_app_boot_info *labi;
if (!setup_max_cpus)
return;
labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
if (labi->labi_signature != LABI_SIGNATURE)
panic("The bootloader version on this board is incorrect.");
if (labi->labi_signature != LABI_SIGNATURE) {
pr_info("The bootloader on this board does not support HOTPLUG_CPU.");
return;
}
octeon_bootloader_entry_addr = labi->InitTLBStart_addr;
#endif
@ -129,7 +134,8 @@ static void octeon_smp_setup(void)
* will assign CPU numbers for possible cores as well. Cores
* are always consecutively numberd from 0.
*/
for (id = 0; id < num_cores && id < NR_CPUS; id++) {
for (id = 0; setup_max_cpus && octeon_bootloader_entry_addr &&
id < num_cores && id < NR_CPUS; id++) {
if (!(core_mask & (1 << id))) {
set_cpu_possible(cpus, true);
__cpu_number_map[id] = cpus;
@ -192,14 +198,6 @@ static void octeon_init_secondary(void)
*/
void octeon_prepare_cpus(unsigned int max_cpus)
{
#ifdef CONFIG_HOTPLUG_CPU
struct linux_app_boot_info *labi;
labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
if (labi->labi_signature != LABI_SIGNATURE)
panic("The bootloader version on this board is incorrect.");
#endif
/*
* Only the low order mailbox bits are used for IPIs, leave
* the other bits alone.
@ -237,6 +235,9 @@ static int octeon_cpu_disable(void)
if (cpu == 0)
return -EBUSY;
if (!octeon_bootloader_entry_addr)
return -ENOTSUPP;
set_cpu_online(cpu, false);
cpu_clear(cpu, cpu_callin_map);
local_irq_disable();

View File

@ -1,6 +1,6 @@
CONFIG_MACH_LOONGSON=y
CONFIG_SWIOTLB=y
CONFIG_LEMOTE_MACH3A=y
CONFIG_LOONGSON_MACH3X=y
CONFIG_CPU_LOONGSON3=y
CONFIG_64BIT=y
CONFIG_PAGE_SIZE_16KB=y

View File

@ -15,4 +15,5 @@ generic-y += segment.h
generic-y += serial.h
generic-y += trace_clock.h
generic-y += ucontext.h
generic-y += user.h
generic-y += xor.h

View File

@ -52,7 +52,7 @@
*/
#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
#define XPHYSADDR(a) ((_ACAST64_(a)) & \
_CONST64_(0x000000ffffffffff))
_CONST64_(0x0000ffffffffffff))
#ifdef CONFIG_64BIT

View File

@ -10,6 +10,7 @@
#include <asm/hazards.h>
#include <asm/asm-offsets.h>
#include <asm/msa.h>
#ifdef CONFIG_32BIT
#include <asm/asmmacro-32.h>
@ -378,9 +379,19 @@
st_d 29, THREAD_FPR29, \thread
st_d 30, THREAD_FPR30, \thread
st_d 31, THREAD_FPR31, \thread
.set push
.set noat
cfcmsa $1, MSA_CSR
sw $1, THREAD_MSA_CSR(\thread)
.set pop
.endm
.macro msa_restore_all thread
.set push
.set noat
lw $1, THREAD_MSA_CSR(\thread)
ctcmsa MSA_CSR, $1
.set pop
ld_d 0, THREAD_FPR0, \thread
ld_d 1, THREAD_FPR1, \thread
ld_d 2, THREAD_FPR2, \thread
@ -415,4 +426,24 @@
ld_d 31, THREAD_FPR31, \thread
.endm
.macro msa_init_upper wd
#ifdef CONFIG_64BIT
insert_d \wd, 1
#else
insert_w \wd, 2
insert_w \wd, 3
#endif
.if 31-\wd
msa_init_upper (\wd+1)
.endif
.endm
.macro msa_init_all_upper
.set push
.set noat
not $1, zero
msa_init_upper 0
.set pop
.endm
#endif /* _ASM_ASMMACRO_H */

View File

@ -559,7 +559,13 @@ static inline int fls(int x)
int r;
if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
__asm__("clz %0, %1" : "=r" (x) : "r" (x));
__asm__(
" .set push \n"
" .set mips32 \n"
" clz %0, %1 \n"
" .set pop \n"
: "=r" (x)
: "r" (x));
return 32 - x;
}

View File

@ -32,6 +32,14 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *);
#define cop2_present 1
#define cop2_lazy_restore 0
#elif defined(CONFIG_CPU_LOONGSON3)
#define cop2_save(r)
#define cop2_restore(r)
#define cop2_present 1
#define cop2_lazy_restore 1
#else
#define cop2_present 0

View File

@ -29,6 +29,15 @@
#ifndef cpu_has_eva
#define cpu_has_eva (cpu_data[0].options & MIPS_CPU_EVA)
#endif
#ifndef cpu_has_htw
#define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW)
#endif
#ifndef cpu_has_rixiex
#define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX)
#endif
#ifndef cpu_has_maar
#define cpu_has_maar (cpu_data[0].options & MIPS_CPU_MAAR)
#endif
/*
* For the moment we don't consider R6000 and R8000 so we can assume that

View File

@ -44,8 +44,8 @@ struct cpuinfo_mips {
/*
* Capability and feature descriptor structure for MIPS CPU
*/
unsigned long options;
unsigned long ases;
unsigned long long options;
unsigned int udelay_val;
unsigned int processor_id;
unsigned int fpu_id;
@ -61,6 +61,7 @@ struct cpuinfo_mips {
struct cache_desc scache; /* Secondary cache */
struct cache_desc tcache; /* Tertiary/split secondary cache */
int srsets; /* Shadow register sets */
int package;/* physical package number */
int core; /* physical core number */
#ifdef CONFIG_64BIT
int vmbits; /* Virtual memory size in bits */
@ -115,7 +116,7 @@ struct proc_cpuinfo_notifier_args {
#ifdef CONFIG_MIPS_MT_SMP
# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id)
#else
# define cpu_vpe_id(cpuinfo) 0
# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; })
#endif
#endif /* __ASM_CPU_INFO_H */

View File

@ -233,6 +233,8 @@
#define PRID_REV_LOONGSON2E 0x0002
#define PRID_REV_LOONGSON2F 0x0003
#define PRID_REV_LOONGSON3A 0x0005
#define PRID_REV_LOONGSON3B_R1 0x0006
#define PRID_REV_LOONGSON3B_R2 0x0007
/*
* Older processors used to encode processor version and revision in two
@ -335,34 +337,37 @@ enum cpu_type_enum {
/*
* CPU Option encodings
*/
#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */
#define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */
#define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */
#define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */
#define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */
#define MIPS_CPU_FPU 0x00000020 /* CPU has FPU */
#define MIPS_CPU_32FPR 0x00000040 /* 32 dbl. prec. FP registers */
#define MIPS_CPU_COUNTER 0x00000080 /* Cycle count/compare */
#define MIPS_CPU_WATCH 0x00000100 /* watchpoint registers */
#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */
#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */
#define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */
#define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */
#define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */
#define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */
#define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */
#define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */
#define MIPS_CPU_INCLUSIVE_CACHES 0x00020000 /* P-cache subset enforced */
#define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */
#define MIPS_CPU_VINT 0x00080000 /* CPU supports MIPSR2 vectored interrupts */
#define MIPS_CPU_VEIC 0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */
#define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */
#define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */
#define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */
#define MIPS_CPU_MICROMIPS 0x01000000 /* CPU has microMIPS capability */
#define MIPS_CPU_TLBINV 0x02000000 /* CPU supports TLBINV/F */
#define MIPS_CPU_SEGMENTS 0x04000000 /* CPU supports Segmentation Control registers */
#define MIPS_CPU_EVA 0x80000000 /* CPU supports Enhanced Virtual Addressing */
#define MIPS_CPU_TLB 0x00000001ull /* CPU has TLB */
#define MIPS_CPU_4KEX 0x00000002ull /* "R4K" exception model */
#define MIPS_CPU_3K_CACHE 0x00000004ull /* R3000-style caches */
#define MIPS_CPU_4K_CACHE 0x00000008ull /* R4000-style caches */
#define MIPS_CPU_TX39_CACHE 0x00000010ull /* TX3900-style caches */
#define MIPS_CPU_FPU 0x00000020ull /* CPU has FPU */
#define MIPS_CPU_32FPR 0x00000040ull /* 32 dbl. prec. FP registers */
#define MIPS_CPU_COUNTER 0x00000080ull /* Cycle count/compare */
#define MIPS_CPU_WATCH 0x00000100ull /* watchpoint registers */
#define MIPS_CPU_DIVEC 0x00000200ull /* dedicated interrupt vector */
#define MIPS_CPU_VCE 0x00000400ull /* virt. coherence conflict possible */
#define MIPS_CPU_CACHE_CDEX_P 0x00000800ull /* Create_Dirty_Exclusive CACHE op */
#define MIPS_CPU_CACHE_CDEX_S 0x00001000ull /* ... same for seconary cache ... */
#define MIPS_CPU_MCHECK 0x00002000ull /* Machine check exception */
#define MIPS_CPU_EJTAG 0x00004000ull /* EJTAG exception */
#define MIPS_CPU_NOFPUEX 0x00008000ull /* no FPU exception */
#define MIPS_CPU_LLSC 0x00010000ull /* CPU has ll/sc instructions */
#define MIPS_CPU_INCLUSIVE_CACHES 0x00020000ull /* P-cache subset enforced */
#define MIPS_CPU_PREFETCH 0x00040000ull /* CPU has usable prefetch */
#define MIPS_CPU_VINT 0x00080000ull /* CPU supports MIPSR2 vectored interrupts */
#define MIPS_CPU_VEIC 0x00100000ull /* CPU supports MIPSR2 external interrupt controller mode */
#define MIPS_CPU_ULRI 0x00200000ull /* CPU has ULRI feature */
#define MIPS_CPU_PCI 0x00400000ull /* CPU has Perf Ctr Int indicator */
#define MIPS_CPU_RIXI 0x00800000ull /* CPU has TLB Read/eXec Inhibit */
#define MIPS_CPU_MICROMIPS 0x01000000ull /* CPU has microMIPS capability */
#define MIPS_CPU_TLBINV 0x02000000ull /* CPU supports TLBINV/F */
#define MIPS_CPU_SEGMENTS 0x04000000ull /* CPU supports Segmentation Control registers */
#define MIPS_CPU_EVA 0x80000000ull /* CPU supports Enhanced Virtual Addressing */
#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */
#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */
#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */
/*
* CPU ASE encodings

View File

@ -339,23 +339,6 @@ do { \
#endif /* CONFIG_64BIT */
struct pt_regs;
struct task_struct;
extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#ifndef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(elf_regs, regs) \
elf_dump_regs((elf_greg_t *)&(elf_regs), regs);
#endif
#ifndef ELF_CORE_COPY_TASK_REGS
#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
#endif
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \
dump_task_fpu(tsk, elf_fpregs)
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE PAGE_SIZE

View File

@ -21,6 +21,7 @@
#include <asm/hazards.h>
#include <asm/processor.h>
#include <asm/current.h>
#include <asm/msa.h>
#ifdef CONFIG_MIPS_MT_FPAFF
#include <asm/mips_mt.h>
@ -141,13 +142,21 @@ static inline int own_fpu(int restore)
static inline void lose_fpu(int save)
{
preempt_disable();
if (is_fpu_owner()) {
if (is_msa_enabled()) {
if (save) {
save_msa(current);
asm volatile("cfc1 %0, $31"
: "=r"(current->thread.fpu.fcr31));
}
disable_msa();
clear_thread_flag(TIF_USEDMSA);
} else if (is_fpu_owner()) {
if (save)
_save_fp(current);
KSTK_STATUS(current) &= ~ST0_CU1;
clear_thread_flag(TIF_USEDFPU);
__disable_fpu();
}
KSTK_STATUS(current) &= ~ST0_CU1;
clear_thread_flag(TIF_USEDFPU);
preempt_enable();
}
@ -155,8 +164,6 @@ static inline int init_fpu(void)
{
int ret = 0;
preempt_disable();
if (cpu_has_fpu) {
ret = __own_fpu();
if (!ret)
@ -164,8 +171,6 @@ static inline int init_fpu(void)
} else
fpu_emulator_init_fpu();
preempt_enable();
return ret;
}

View File

@ -14,6 +14,8 @@
#include <linux/bitmap.h>
#include <linux/threads.h>
#include <irq.h>
#undef GICISBYTELITTLEENDIAN
/* Constants */
@ -22,8 +24,6 @@
#define GIC_TRIG_EDGE 1
#define GIC_TRIG_LEVEL 0
#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
#define MSK(n) ((1 << (n)) - 1)
#define REG32(addr) (*(volatile unsigned int *) (addr))
#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS)
@ -43,18 +43,17 @@
#ifdef GICISBYTELITTLEENDIAN
#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
#define GICBIS(reg, bits) \
({unsigned int data; \
GICREAD(reg, data); \
data |= bits; \
GICWRITE(reg, data); \
})
#else
#define GICREAD(reg, data) ((data) = (reg))
#define GICWRITE(reg, data) ((reg) = (data))
#define GICBIS(reg, bits) ((reg) |= (bits))
#endif
#define GICBIS(reg, mask, bits) \
do { u32 data; \
GICREAD((reg), data); \
data &= ~(mask); \
data |= ((bits) & (mask)); \
GICWRITE((reg), data); \
} while (0)
/* GIC Address Space */
@ -170,13 +169,15 @@
#define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr))
GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
(pol) << GIC_INTR_BIT(intr))
/* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr))
GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
(trig) << GIC_INTR_BIT(intr))
/* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380
@ -306,18 +307,6 @@
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
struct gic_pcpu_mask {
DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
};
struct gic_pending_regs {
DECLARE_BITMAP(pending, GIC_NUM_INTRS);
};
struct gic_intrmask_regs {
DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
};
/*
* Interrupt Meta-data specification. The ipiflag helps
* in building ipi_map.
@ -329,8 +318,7 @@ struct gic_intr_map {
unsigned int polarity; /* Polarity : +/- */
unsigned int trigtype; /* Trigger : Edge/Levl */
unsigned int flags; /* Misc flags */
#define GIC_FLAG_IPI 0x01
#define GIC_FLAG_TRANSPARENT 0x02
#define GIC_FLAG_TRANSPARENT 0x01
};
/*
@ -386,6 +374,7 @@ extern unsigned int plat_ipi_call_int_xlate(unsigned int);
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
extern void gic_bind_eic_interrupt(int irq, int set);
extern unsigned int gic_get_timer_pending(void);
extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src);
extern unsigned int gic_get_int(void);
extern void gic_enable_interrupt(int irq_vec);
extern void gic_disable_interrupt(int irq_vec);

View File

@ -0,0 +1,109 @@
/*
* Copyright (C) 2014 Imagination Technologies
* Author: Paul Burton <paul.burton@imgtec.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __MIPS_ASM_MIPS_MAAR_H__
#define __MIPS_ASM_MIPS_MAAR_H__
#include <asm/hazards.h>
#include <asm/mipsregs.h>
/**
* platform_maar_init() - perform platform-level MAAR configuration
* @num_pairs: The number of MAAR pairs present in the system.
*
* Platforms should implement this function such that it configures as many
* MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns
* the number that were used. Any further MAARs will be configured to be
* invalid. The default implementation of this function will simply indicate
* that it has configured 0 MAAR pairs.
*
* Return: The number of MAAR pairs configured.
*/
unsigned __weak platform_maar_init(unsigned num_pairs);
/**
* write_maar_pair() - write to a pair of MAARs
* @idx: The index of the pair (ie. use MAARs idx*2 & (idx*2)+1).
* @lower: The lowest address that the MAAR pair will affect. Must be
* aligned to a 2^16 byte boundary.
* @upper: The highest address that the MAAR pair will affect. Must be
* aligned to one byte before a 2^16 byte boundary.
* @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The
* MIPS_MAAR_V attribute will automatically be set.
*
* Program the pair of MAAR registers specified by idx to apply the attributes
* specified by attrs to the range of addresses from lower to higher.
*/
static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
phys_addr_t upper, unsigned attrs)
{
/* Addresses begin at bit 16, but are shifted right 4 bits */
BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4)));
BUG_ON(((upper & 0xffff) != 0xffff)
|| ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4)));
/* Automatically set MIPS_MAAR_V */
attrs |= MIPS_MAAR_V;
/* Write the upper address & attributes (only MIPS_MAAR_V matters) */
write_c0_maari(idx << 1);
back_to_back_c0_hazard();
write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs);
back_to_back_c0_hazard();
/* Write the lower address & attributes */
write_c0_maari((idx << 1) | 0x1);
back_to_back_c0_hazard();
write_c0_maar((lower >> 4) | attrs);
back_to_back_c0_hazard();
}
/**
* struct maar_config - MAAR configuration data
* @lower: The lowest address that the MAAR pair will affect. Must be
* aligned to a 2^16 byte boundary.
* @upper: The highest address that the MAAR pair will affect. Must be
* aligned to one byte before a 2^16 byte boundary.
* @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The
* MIPS_MAAR_V attribute will automatically be set.
*
* Describes the configuration of a pair of Memory Accessibility Attribute
* Registers - applying attributes from attrs to the range of physical
* addresses from lower to upper inclusive.
*/
struct maar_config {
phys_addr_t lower;
phys_addr_t upper;
unsigned attrs;
};
/**
* maar_config() - configure MAARs according to provided data
* @cfg: Pointer to an array of struct maar_config.
* @num_cfg: The number of structs in the cfg array.
* @num_pairs: The number of MAAR pairs present in the system.
*
* Configures as many MAARs as are present and specified in the cfg
* array with the values taken from the cfg array.
*
* Return: The number of MAAR pairs configured.
*/
static inline unsigned maar_config(const struct maar_config *cfg,
unsigned num_cfg, unsigned num_pairs)
{
unsigned i;
for (i = 0; i < min(num_cfg, num_pairs); i++)
write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
return i;
}
#endif /* __MIPS_ASM_MIPS_MAAR_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@ enum {
struct dma_chan {
int dev_id; /* this channel is allocated if >= 0, */
/* free otherwise */
unsigned int io;
void __iomem *io;
const char *dev_str;
int irq;
void *irq_dev;
@ -157,7 +157,7 @@ static inline void enable_dma_buffer0(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
__raw_writel(DMA_BE0, chan->io + DMA_MODE_SET);
}
static inline void enable_dma_buffer1(unsigned int dmanr)
@ -166,7 +166,7 @@ static inline void enable_dma_buffer1(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
__raw_writel(DMA_BE1, chan->io + DMA_MODE_SET);
}
static inline void enable_dma_buffers(unsigned int dmanr)
{
@ -174,7 +174,7 @@ static inline void enable_dma_buffers(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
__raw_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
}
static inline void start_dma(unsigned int dmanr)
@ -183,7 +183,7 @@ static inline void start_dma(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_GO, chan->io + DMA_MODE_SET);
__raw_writel(DMA_GO, chan->io + DMA_MODE_SET);
}
#define DMA_HALT_POLL 0x5000
@ -195,11 +195,11 @@ static inline void halt_dma(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
__raw_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
/* Poll the halt bit */
for (i = 0; i < DMA_HALT_POLL; i++)
if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
if (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
break;
if (i == DMA_HALT_POLL)
printk(KERN_INFO "halt_dma: HALT poll expired!\n");
@ -215,7 +215,7 @@ static inline void disable_dma(unsigned int dmanr)
halt_dma(dmanr);
/* Now we can disable the buffers */
au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
__raw_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
}
static inline int dma_halted(unsigned int dmanr)
@ -224,7 +224,7 @@ static inline int dma_halted(unsigned int dmanr)
if (!chan)
return 1;
return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
}
/* Initialize a DMA channel. */
@ -239,14 +239,14 @@ static inline void init_dma(unsigned int dmanr)
disable_dma(dmanr);
/* Set device FIFO address */
au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
__raw_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
if (chan->irq)
mode |= DMA_IE;
au_writel(~mode, chan->io + DMA_MODE_CLEAR);
au_writel(mode, chan->io + DMA_MODE_SET);
__raw_writel(~mode, chan->io + DMA_MODE_CLEAR);
__raw_writel(mode, chan->io + DMA_MODE_SET);
}
/*
@ -283,7 +283,7 @@ static inline int get_dma_active_buffer(unsigned int dmanr)
if (!chan)
return -1;
return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
}
/*
@ -304,7 +304,7 @@ static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
return;
au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR);
__raw_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR);
}
/*
@ -316,7 +316,7 @@ static inline void clear_dma_done0(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
__raw_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
}
static inline void clear_dma_done1(unsigned int dmanr)
@ -325,7 +325,7 @@ static inline void clear_dma_done1(unsigned int dmanr)
if (!chan)
return;
au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
__raw_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
}
/*
@ -344,7 +344,7 @@ static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
if (!chan)
return;
au_writel(a, chan->io + DMA_BUFFER0_START);
__raw_writel(a, chan->io + DMA_BUFFER0_START);
}
/*
@ -356,7 +356,7 @@ static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
if (!chan)
return;
au_writel(a, chan->io + DMA_BUFFER1_START);
__raw_writel(a, chan->io + DMA_BUFFER1_START);
}
@ -370,7 +370,7 @@ static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
if (!chan)
return;
count &= DMA_COUNT_MASK;
au_writel(count, chan->io + DMA_BUFFER0_COUNT);
__raw_writel(count, chan->io + DMA_BUFFER0_COUNT);
}
/*
@ -383,7 +383,7 @@ static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
if (!chan)
return;
count &= DMA_COUNT_MASK;
au_writel(count, chan->io + DMA_BUFFER1_COUNT);
__raw_writel(count, chan->io + DMA_BUFFER1_COUNT);
}
/*
@ -396,8 +396,8 @@ static inline void set_dma_count(unsigned int dmanr, unsigned int count)
if (!chan)
return;
count &= DMA_COUNT_MASK;
au_writel(count, chan->io + DMA_BUFFER0_COUNT);
au_writel(count, chan->io + DMA_BUFFER1_COUNT);
__raw_writel(count, chan->io + DMA_BUFFER0_COUNT);
__raw_writel(count, chan->io + DMA_BUFFER1_COUNT);
}
/*
@ -410,7 +410,7 @@ static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
if (!chan)
return 0;
return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
return __raw_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
}
@ -437,10 +437,10 @@ static inline int get_dma_residue(unsigned int dmanr)
if (!chan)
return 0;
curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
curBufCntReg = (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
count = __raw_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
if ((chan->mode & DMA_DW_MASK) == DMA_DW16)
count <<= 1;

View File

@ -25,20 +25,20 @@
#define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off))
/* GPIO1 registers within SYS_ area */
#define SYS_TRIOUTRD 0x100
#define SYS_TRIOUTCLR 0x100
#define SYS_OUTPUTRD 0x108
#define SYS_OUTPUTSET 0x108
#define SYS_OUTPUTCLR 0x10C
#define SYS_PINSTATERD 0x110
#define SYS_PININPUTEN 0x110
#define AU1000_SYS_TRIOUTRD 0x100
#define AU1000_SYS_TRIOUTCLR 0x100
#define AU1000_SYS_OUTPUTRD 0x108
#define AU1000_SYS_OUTPUTSET 0x108
#define AU1000_SYS_OUTPUTCLR 0x10C
#define AU1000_SYS_PINSTATERD 0x110
#define AU1000_SYS_PININPUTEN 0x110
/* register offsets within GPIO2 block */
#define GPIO2_DIR 0x00
#define GPIO2_OUTPUT 0x08
#define GPIO2_PINSTATE 0x0C
#define GPIO2_INTENABLE 0x10
#define GPIO2_ENABLE 0x14
#define AU1000_GPIO2_DIR 0x00
#define AU1000_GPIO2_OUTPUT 0x08
#define AU1000_GPIO2_PINSTATE 0x0C
#define AU1000_GPIO2_INTENABLE 0x10
#define AU1000_GPIO2_ENABLE 0x14
struct gpio;
@ -217,26 +217,21 @@ static inline int au1200_irq_to_gpio(int irq)
*/
static inline void alchemy_gpio1_set_value(int gpio, int v)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
__raw_writel(mask, base + r);
wmb();
unsigned long r = v ? AU1000_SYS_OUTPUTSET : AU1000_SYS_OUTPUTCLR;
alchemy_wrsys(mask, r);
}
static inline int alchemy_gpio1_get_value(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
return __raw_readl(base + SYS_PINSTATERD) & mask;
return alchemy_rdsys(AU1000_SYS_PINSTATERD) & mask;
}
static inline int alchemy_gpio1_direction_input(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
__raw_writel(mask, base + SYS_TRIOUTCLR);
wmb();
alchemy_wrsys(mask, AU1000_SYS_TRIOUTCLR);
return 0;
}
@ -279,13 +274,13 @@ static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
unsigned long d = __raw_readl(base + GPIO2_DIR);
unsigned long d = __raw_readl(base + AU1000_GPIO2_DIR);
if (to_out)
d |= mask;
else
d &= ~mask;
__raw_writel(d, base + GPIO2_DIR);
__raw_writel(d, base + AU1000_GPIO2_DIR);
wmb();
}
@ -294,14 +289,15 @@ static inline void alchemy_gpio2_set_value(int gpio, int v)
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask;
mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
__raw_writel(mask, base + GPIO2_OUTPUT);
__raw_writel(mask, base + AU1000_GPIO2_OUTPUT);
wmb();
}
static inline int alchemy_gpio2_get_value(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
return __raw_readl(base + AU1000_GPIO2_PINSTATE) &
(1 << (gpio - ALCHEMY_GPIO2_BASE));
}
static inline int alchemy_gpio2_direction_input(int gpio)
@ -352,12 +348,12 @@ static inline int alchemy_gpio2_to_irq(int gpio)
static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long r = __raw_readl(base + GPIO2_INTENABLE);
unsigned long r = __raw_readl(base + AU1000_GPIO2_INTENABLE);
if (en)
r |= 1 << gpio2;
else
r &= ~(1 << gpio2);
__raw_writel(r, base + GPIO2_INTENABLE);
__raw_writel(r, base + AU1000_GPIO2_INTENABLE);
wmb();
}
@ -434,9 +430,9 @@ static inline void alchemy_gpio2_disable_int(int gpio2)
static inline void alchemy_gpio2_enable(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */
__raw_writel(3, base + AU1000_GPIO2_ENABLE); /* reset, clock enabled */
wmb();
__raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */
__raw_writel(1, base + AU1000_GPIO2_ENABLE); /* clock enabled */
wmb();
}
@ -448,7 +444,7 @@ static inline void alchemy_gpio2_enable(void)
static inline void alchemy_gpio2_disable(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */
__raw_writel(2, base + AU1000_GPIO2_ENABLE); /* reset, clock disabled */
wmb();
}

View File

@ -18,6 +18,7 @@ enum bcm47xx_board {
BCM47XX_BOARD_ASUS_WL300G,
BCM47XX_BOARD_ASUS_WL320GE,
BCM47XX_BOARD_ASUS_WL330GE,
BCM47XX_BOARD_ASUS_WL500G,
BCM47XX_BOARD_ASUS_WL500GD,
BCM47XX_BOARD_ASUS_WL500GPV1,
BCM47XX_BOARD_ASUS_WL500GPV2,
@ -70,11 +71,15 @@ enum bcm47xx_board {
BCM47XX_BOARD_LINKSYS_WRT310NV1,
BCM47XX_BOARD_LINKSYS_WRT310NV2,
BCM47XX_BOARD_LINKSYS_WRT54G3GV2,
BCM47XX_BOARD_LINKSYS_WRT54G,
BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101,
BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467,
BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708,
BCM47XX_BOARD_LINKSYS_WRT610NV1,
BCM47XX_BOARD_LINKSYS_WRT610NV2,
BCM47XX_BOARD_LINKSYS_WRTSL54GS,
BCM47XX_BOARD_MICROSOFT_MN700,
BCM47XX_BOARD_MOTOROLA_WE800G,
BCM47XX_BOARD_MOTOROLA_WR850GP,
BCM47XX_BOARD_MOTOROLA_WR850GV2V3,

View File

@ -19,118 +19,68 @@
#define BCM6368_CPU_ID 0x6368
void __init bcm63xx_cpu_init(void);
u16 __bcm63xx_get_cpu_id(void);
u8 bcm63xx_get_cpu_rev(void);
unsigned int bcm63xx_get_cpu_freq(void);
static inline u16 __pure __bcm63xx_get_cpu_id(const u16 cpu_id)
{
switch (cpu_id) {
#ifdef CONFIG_BCM63XX_CPU_3368
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM3368_CPU_ID
# endif
# define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID)
#else
# define BCMCPU_IS_3368() (0)
case BCM3368_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6328
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6328_CPU_ID
# endif
# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID)
#else
# define BCMCPU_IS_6328() (0)
case BCM6328_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6338_CPU_ID
# endif
# define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID)
#else
# define BCMCPU_IS_6338() (0)
case BCM6338_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6345_CPU_ID
# endif
# define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID)
#else
# define BCMCPU_IS_6345() (0)
case BCM6345_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6348_CPU_ID
# endif
# define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID)
#else
# define BCMCPU_IS_6348() (0)
case BCM6348_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6358_CPU_ID
# endif
# define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID)
#else
# define BCMCPU_IS_6358() (0)
case BCM6358_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6362
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6362_CPU_ID
# endif
# define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID)
#else
# define BCMCPU_IS_6362() (0)
case BCM6362_CPU_ID:
#endif
#ifdef CONFIG_BCM63XX_CPU_6368
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM6368_CPU_ID
# endif
# define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID)
#else
# define BCMCPU_IS_6368() (0)
case BCM6368_CPU_ID:
#endif
break;
default:
unreachable();
}
#ifndef bcm63xx_get_cpu_id
#error "No CPU support configured"
#endif
return cpu_id;
}
extern u16 bcm63xx_cpu_id;
static inline u16 __pure bcm63xx_get_cpu_id(void)
{
const u16 cpu_id = bcm63xx_cpu_id;
return __bcm63xx_get_cpu_id(cpu_id);
}
#define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID)
#define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID)
#define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID)
#define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID)
#define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID)
#define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID)
#define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID)
#define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID)
/*
* While registers sets are (mostly) the same across 63xx CPU, base
@ -598,55 +548,6 @@ enum bcm63xx_regs_set {
extern const unsigned long *bcm63xx_regs_base;
#define __GEN_RSET_BASE(__cpu, __rset) \
case RSET_## __rset : \
return BCM_## __cpu ##_## __rset ##_BASE;
#define __GEN_RSET(__cpu) \
switch (set) { \
__GEN_RSET_BASE(__cpu, DSL_LMEM) \
__GEN_RSET_BASE(__cpu, PERF) \
__GEN_RSET_BASE(__cpu, TIMER) \
__GEN_RSET_BASE(__cpu, WDT) \
__GEN_RSET_BASE(__cpu, UART0) \
__GEN_RSET_BASE(__cpu, UART1) \
__GEN_RSET_BASE(__cpu, GPIO) \
__GEN_RSET_BASE(__cpu, SPI) \
__GEN_RSET_BASE(__cpu, HSSPI) \
__GEN_RSET_BASE(__cpu, UDC0) \
__GEN_RSET_BASE(__cpu, OHCI0) \
__GEN_RSET_BASE(__cpu, OHCI_PRIV) \
__GEN_RSET_BASE(__cpu, USBH_PRIV) \
__GEN_RSET_BASE(__cpu, USBD) \
__GEN_RSET_BASE(__cpu, USBDMA) \
__GEN_RSET_BASE(__cpu, MPI) \
__GEN_RSET_BASE(__cpu, PCMCIA) \
__GEN_RSET_BASE(__cpu, PCIE) \
__GEN_RSET_BASE(__cpu, DSL) \
__GEN_RSET_BASE(__cpu, ENET0) \
__GEN_RSET_BASE(__cpu, ENET1) \
__GEN_RSET_BASE(__cpu, ENETDMA) \
__GEN_RSET_BASE(__cpu, ENETDMAC) \
__GEN_RSET_BASE(__cpu, ENETDMAS) \
__GEN_RSET_BASE(__cpu, ENETSW) \
__GEN_RSET_BASE(__cpu, EHCI0) \
__GEN_RSET_BASE(__cpu, SDRAM) \
__GEN_RSET_BASE(__cpu, MEMC) \
__GEN_RSET_BASE(__cpu, DDR) \
__GEN_RSET_BASE(__cpu, M2M) \
__GEN_RSET_BASE(__cpu, ATM) \
__GEN_RSET_BASE(__cpu, XTM) \
__GEN_RSET_BASE(__cpu, XTMDMA) \
__GEN_RSET_BASE(__cpu, XTMDMAC) \
__GEN_RSET_BASE(__cpu, XTMDMAS) \
__GEN_RSET_BASE(__cpu, PCM) \
__GEN_RSET_BASE(__cpu, PCMDMA) \
__GEN_RSET_BASE(__cpu, PCMDMAC) \
__GEN_RSET_BASE(__cpu, PCMDMAS) \
__GEN_RSET_BASE(__cpu, RNG) \
__GEN_RSET_BASE(__cpu, MISC) \
}
#define __GEN_CPU_REGS_TABLE(__cpu) \
[RSET_DSL_LMEM] = BCM_## __cpu ##_DSL_LMEM_BASE, \
[RSET_PERF] = BCM_## __cpu ##_PERF_BASE, \
@ -693,36 +594,7 @@ extern const unsigned long *bcm63xx_regs_base;
static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
{
#ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set];
#else
#ifdef CONFIG_BCM63XX_CPU_3368
__GEN_RSET(3368)
#endif
#ifdef CONFIG_BCM63XX_CPU_6328
__GEN_RSET(6328)
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
__GEN_RSET(6338)
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
__GEN_RSET(6345)
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
__GEN_RSET(6348)
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
__GEN_RSET(6358)
#endif
#ifdef CONFIG_BCM63XX_CPU_6362
__GEN_RSET(6362)
#endif
#ifdef CONFIG_BCM63XX_CPU_6368
__GEN_RSET(6368)
#endif
#endif
/* unreached */
return 0;
}
/*

View File

@ -112,55 +112,9 @@ enum bcm63xx_regs_enetdmac {
static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg)
{
#ifdef BCMCPU_RUNTIME_DETECT
extern const unsigned long *bcm63xx_regs_enetdmac;
return bcm63xx_regs_enetdmac[reg];
#else
#ifdef CONFIG_BCM63XX_CPU_6345
switch (reg) {
case ENETDMAC_CHANCFG:
return ENETDMA_6345_CHANCFG_REG;
case ENETDMAC_IR:
return ENETDMA_6345_IR_REG;
case ENETDMAC_IRMASK:
return ENETDMA_6345_IRMASK_REG;
case ENETDMAC_MAXBURST:
return ENETDMA_6345_MAXBURST_REG;
case ENETDMAC_BUFALLOC:
return ENETDMA_6345_BUFALLOC_REG;
case ENETDMAC_RSTART:
return ENETDMA_6345_RSTART_REG;
case ENETDMAC_FC:
return ENETDMA_6345_FC_REG;
case ENETDMAC_LEN:
return ENETDMA_6345_LEN_REG;
}
#endif
#if defined(CONFIG_BCM63XX_CPU_6328) || \
defined(CONFIG_BCM63XX_CPU_6338) || \
defined(CONFIG_BCM63XX_CPU_6348) || \
defined(CONFIG_BCM63XX_CPU_6358) || \
defined(CONFIG_BCM63XX_CPU_6362) || \
defined(CONFIG_BCM63XX_CPU_6368)
switch (reg) {
case ENETDMAC_CHANCFG:
return ENETDMAC_CHANCFG_REG;
case ENETDMAC_IR:
return ENETDMAC_IR_REG;
case ENETDMAC_IRMASK:
return ENETDMAC_IRMASK_REG;
case ENETDMAC_MAXBURST:
return ENETDMAC_MAXBURST_REG;
case ENETDMAC_BUFALLOC:
case ENETDMAC_RSTART:
case ENETDMAC_FC:
case ENETDMAC_LEN:
return 0;
}
#endif
#endif
return 0;
}

View File

@ -30,26 +30,6 @@ enum bcm63xx_regs_spi {
SPI_RX_DATA,
};
#define __GEN_SPI_RSET_BASE(__cpu, __rset) \
case SPI_## __rset: \
return SPI_## __cpu ##_## __rset;
#define __GEN_SPI_RSET(__cpu) \
switch (reg) { \
__GEN_SPI_RSET_BASE(__cpu, CMD) \
__GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \
__GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \
__GEN_SPI_RSET_BASE(__cpu, INT_MASK) \
__GEN_SPI_RSET_BASE(__cpu, ST) \
__GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \
__GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \
__GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \
__GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \
__GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \
__GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \
__GEN_SPI_RSET_BASE(__cpu, RX_DATA) \
}
#define __GEN_SPI_REGS_TABLE(__cpu) \
[SPI_CMD] = SPI_## __cpu ##_CMD, \
[SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \
@ -66,20 +46,9 @@ enum bcm63xx_regs_spi {
static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
{
#ifdef BCMCPU_RUNTIME_DETECT
extern const unsigned long *bcm63xx_regs_spi;
return bcm63xx_regs_spi[reg];
#else
#if defined(CONFIG_BCM63XX_CPU_6338) || defined(CONFIG_BCM63XX_CPU_6348)
__GEN_SPI_RSET(6348)
#endif
#if defined(CONFIG_BCM63XX_CPU_6358) || defined(CONFIG_BCM63XX_CPU_6362) || \
defined(CONFIG_BCM63XX_CPU_6368)
__GEN_SPI_RSET(6358)
#endif
#endif
return 0;
}
#endif /* BCM63XX_DEV_SPI_H */

View File

@ -215,23 +215,23 @@
/* Interrupt Mask register */
#define PERF_IRQMASK_3368_REG 0xc
#define PERF_IRQMASK_6328_REG 0x20
#define PERF_IRQMASK_6328_REG(x) (0x20 + (x) * 0x10)
#define PERF_IRQMASK_6338_REG 0xc
#define PERF_IRQMASK_6345_REG 0xc
#define PERF_IRQMASK_6348_REG 0xc
#define PERF_IRQMASK_6358_REG 0xc
#define PERF_IRQMASK_6362_REG 0x20
#define PERF_IRQMASK_6368_REG 0x20
#define PERF_IRQMASK_6358_REG(x) (0xc + (x) * 0x2c)
#define PERF_IRQMASK_6362_REG(x) (0x20 + (x) * 0x10)
#define PERF_IRQMASK_6368_REG(x) (0x20 + (x) * 0x10)
/* Interrupt Status register */
#define PERF_IRQSTAT_3368_REG 0x10
#define PERF_IRQSTAT_6328_REG 0x28
#define PERF_IRQSTAT_6328_REG(x) (0x28 + (x) * 0x10)
#define PERF_IRQSTAT_6338_REG 0x10
#define PERF_IRQSTAT_6345_REG 0x10
#define PERF_IRQSTAT_6348_REG 0x10
#define PERF_IRQSTAT_6358_REG 0x10
#define PERF_IRQSTAT_6362_REG 0x28
#define PERF_IRQSTAT_6368_REG 0x28
#define PERF_IRQSTAT_6358_REG(x) (0x10 + (x) * 0x2c)
#define PERF_IRQSTAT_6362_REG(x) (0x28 + (x) * 0x10)
#define PERF_IRQSTAT_6368_REG(x) (0x28 + (x) * 0x10)
/* External Interrupt Configuration register */
#define PERF_EXTIRQ_CFG_REG_3368 0x14

View File

@ -24,7 +24,7 @@
#define cpu_has_smartmips 0
#define cpu_has_vtag_icache 0
#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
#if !defined(CONFIG_SYS_HAS_CPU_BMIPS4350)
#define cpu_has_dc_aliases 0
#endif

View File

@ -146,6 +146,9 @@ struct boot_params {
struct loongson_system_configuration {
u32 nr_cpus;
u32 nr_nodes;
int cores_per_node;
int cores_per_package;
enum loongson_cpu_type cputype;
u64 ht_control_base;
u64 pci_mem_start_addr;
@ -160,4 +163,5 @@ struct loongson_system_configuration {
extern struct efi_memory_map_loongson *loongson_memmap;
extern struct loongson_system_configuration loongson_sysconf;
extern int cpuhotplug_workaround;
#endif

View File

@ -0,0 +1,52 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2005 Embedded Alley Solutions, Inc
* Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn)
* Copyright (C) 2012 Huacai Chen (chenhc@lemote.com)
*/
#ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
/*
* Override macros used in arch/mips/kernel/head.S.
*/
.macro kernel_entry_setup
#ifdef CONFIG_CPU_LOONGSON3
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
mfc0 t0, $16, 3
or t0, (0x1 << 7)
mtc0 t0, $16, 3
/* Set ELPA on LOONGSON3 pagegrain */
li t0, (0x1 << 29)
mtc0 t0, $5, 1
_ehb
.set pop
#endif
.endm
/*
* Do SMP slave processor setup.
*/
.macro smp_slave_setup
#ifdef CONFIG_CPU_LOONGSON3
.set push
.set mips64
/* Set LPA on LOONGSON3 config3 */
mfc0 t0, $16, 3
or t0, (0x1 << 7)
mtc0 t0, $16, 3
/* Set ELPA on LOONGSON3 pagegrain */
li t0, (0x1 << 29)
mtc0 t0, $5, 1
_ehb
.set pop
#endif
.endm
#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */

View File

@ -249,8 +249,15 @@ static inline void do_perfcnt_IRQ(void)
#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68)
#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
/* Chip Config */
#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80)
#define MAX_PACKAGES 4
/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */
extern u64 loongson_chipcfg[MAX_PACKAGES];
#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id]))
/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */
extern u64 loongson_freqctrl[MAX_PACKAGES];
#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id]))
/* pcimap */

View File

@ -24,10 +24,10 @@
#endif
#ifdef CONFIG_LEMOTE_MACH3A
#ifdef CONFIG_LOONGSON_MACH3X
#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101
#endif /* CONFIG_LEMOTE_MACH3A */
#endif /* CONFIG_LOONGSON_MACH3X */
#endif /* __ASM_MACH_LOONGSON_MACHINE_H */

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2010 Loongson Inc. & Lemote Inc. &
* Insititute of Computing Technology
* Author: Xiang Gao, gaoxiang@ict.ac.cn
* Huacai Chen, chenhc@lemote.com
* Xiaofu Meng, Shuangshuang Zhang
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _ASM_MACH_MMZONE_H
#define _ASM_MACH_MMZONE_H
#include <boot_param.h>
#define NODE_ADDRSPACE_SHIFT 44
#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL
#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL
#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL
#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT)
#define LEVELS_PER_SLICE 128
struct slice_data {
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};
struct hub_data {
cpumask_t h_cpus;
unsigned long slice_map;
unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};
struct node_data {
struct pglist_data pglist;
struct hub_data hub;
cpumask_t cpumask;
};
extern struct node_data *__node_data[];
#define NODE_DATA(n) (&__node_data[(n)]->pglist)
#define hub_data(n) (&__node_data[(n)]->hub)
extern void setup_zero_pages(void);
extern void __init prom_init_numa_memory(void);
#endif /* _ASM_MACH_MMZONE_H */

View File

@ -0,0 +1,23 @@
#ifndef _ASM_MACH_TOPOLOGY_H
#define _ASM_MACH_TOPOLOGY_H
#ifdef CONFIG_NUMA
#define cpu_to_node(cpu) ((cpu) >> 2)
#define parent_node(node) (node)
#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
struct pci_bus;
extern int pcibus_to_node(struct pci_bus *);
#define cpumask_of_pcibus(bus) (cpu_online_mask)
extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
#define node_distance(from, to) (__node_distances[(from)][(to)])
#endif
#include <asm-generic/topology.h>
#endif /* _ASM_MACH_TOPOLOGY_H */

View File

@ -2,6 +2,7 @@
#define __ASM_MACH_MIPS_IRQ_H
#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
#define NR_IRQS 256
#include_next <irq.h>

View File

@ -1,6 +1,7 @@
#ifndef __ASM_MACH_MIPS_IRQ_H
#define __ASM_MACH_MIPS_IRQ_H
#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
#define NR_IRQS 256

View File

@ -413,7 +413,6 @@ extern unsigned long _pcictrl_bonito_pcicfg;
#define BONITO_PCIMEMBASECFG_SIZE(WIN, CFG) (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK)
#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)

View File

@ -265,6 +265,7 @@
#define PG_XIE (_ULCAST_(1) << 30)
#define PG_ELPA (_ULCAST_(1) << 29)
#define PG_ESP (_ULCAST_(1) << 28)
#define PG_IEC (_ULCAST_(1) << 27)
/*
* R4x00 interrupt enable / cause bits
@ -630,7 +631,6 @@
#define MIPS_CONF4_MMUSIZEEXT_SHIFT (0)
#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
#define MIPS_CONF4_FTLBSETS_SHIFT (0)
#define MIPS_CONF4_FTLBSETS_SHIFT (0)
#define MIPS_CONF4_FTLBSETS (_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT)
#define MIPS_CONF4_FTLBWAYS_SHIFT (4)
#define MIPS_CONF4_FTLBWAYS (_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT)
@ -652,6 +652,7 @@
#define MIPS_CONF5_NF (_ULCAST_(1) << 0)
#define MIPS_CONF5_UFR (_ULCAST_(1) << 2)
#define MIPS_CONF5_MRP (_ULCAST_(1) << 3)
#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
#define MIPS_CONF5_CV (_ULCAST_(1) << 29)
@ -668,6 +669,12 @@
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
/* MAAR bit definitions */
#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
#define MIPS_MAAR_ADDR_SHIFT 12
#define MIPS_MAAR_S (_ULCAST_(1) << 1)
#define MIPS_MAAR_V (_ULCAST_(1) << 0)
/* EntryHI bit definition */
#define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10)
@ -706,6 +713,37 @@
#define MIPS_SEGCFG_MK _ULCAST_(1)
#define MIPS_SEGCFG_UK _ULCAST_(0)
#define MIPS_PWFIELD_GDI_SHIFT 24
#define MIPS_PWFIELD_GDI_MASK 0x3f000000
#define MIPS_PWFIELD_UDI_SHIFT 18
#define MIPS_PWFIELD_UDI_MASK 0x00fc0000
#define MIPS_PWFIELD_MDI_SHIFT 12
#define MIPS_PWFIELD_MDI_MASK 0x0003f000
#define MIPS_PWFIELD_PTI_SHIFT 6
#define MIPS_PWFIELD_PTI_MASK 0x00000fc0
#define MIPS_PWFIELD_PTEI_SHIFT 0
#define MIPS_PWFIELD_PTEI_MASK 0x0000003f
#define MIPS_PWSIZE_GDW_SHIFT 24
#define MIPS_PWSIZE_GDW_MASK 0x3f000000
#define MIPS_PWSIZE_UDW_SHIFT 18
#define MIPS_PWSIZE_UDW_MASK 0x00fc0000
#define MIPS_PWSIZE_MDW_SHIFT 12
#define MIPS_PWSIZE_MDW_MASK 0x0003f000
#define MIPS_PWSIZE_PTW_SHIFT 6
#define MIPS_PWSIZE_PTW_MASK 0x00000fc0
#define MIPS_PWSIZE_PTEW_SHIFT 0
#define MIPS_PWSIZE_PTEW_MASK 0x0000003f
#define MIPS_PWCTL_PWEN_SHIFT 31
#define MIPS_PWCTL_PWEN_MASK 0x80000000
#define MIPS_PWCTL_DPH_SHIFT 7
#define MIPS_PWCTL_DPH_MASK 0x00000080
#define MIPS_PWCTL_HUGEPG_SHIFT 6
#define MIPS_PWCTL_HUGEPG_MASK 0x00000060
#define MIPS_PWCTL_PSN_SHIFT 0
#define MIPS_PWCTL_PSN_MASK 0x0000003f
#ifndef __ASSEMBLY__
/*
@ -1044,6 +1082,11 @@ do { \
#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
#define read_c0_maar() __read_ulong_c0_register($17, 1)
#define write_c0_maar(val) __write_ulong_c0_register($17, 1, val)
#define read_c0_maari() __read_32bit_c0_register($17, 2)
#define write_c0_maari(val) __write_32bit_c0_register($17, 2, val)
/*
* The WatchLo register. There may be up to 8 of them.
*/
@ -1201,6 +1244,19 @@ do { \
#define read_c0_segctl2() __read_32bit_c0_register($5, 4)
#define write_c0_segctl2(val) __write_32bit_c0_register($5, 4, val)
/* Hardware Page Table Walker */
#define read_c0_pwbase() __read_ulong_c0_register($5, 5)
#define write_c0_pwbase(val) __write_ulong_c0_register($5, 5, val)
#define read_c0_pwfield() __read_ulong_c0_register($5, 6)
#define write_c0_pwfield(val) __write_ulong_c0_register($5, 6, val)
#define read_c0_pwsize() __read_ulong_c0_register($5, 7)
#define write_c0_pwsize(val) __write_ulong_c0_register($5, 7, val)
#define read_c0_pwctl() __read_32bit_c0_register($6, 6)
#define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val)
/* Cavium OCTEON (cnMIPS) */
#define read_c0_cvmcount() __read_ulong_c0_register($9, 6)
#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val)

View File

@ -20,10 +20,20 @@
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
#define htw_set_pwbase(pgd) \
do { \
if (cpu_has_htw) { \
write_c0_pwbase(pgd); \
back_to_back_c0_hazard(); \
htw_reset(); \
} \
} while (0)
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
do { \
extern void tlbmiss_handler_setup_pgd(unsigned long); \
tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \
htw_set_pwbase((unsigned long)pgd); \
} while (0)
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT

View File

@ -12,8 +12,11 @@
#include <asm/mipsregs.h>
#ifndef __ASSEMBLY__
extern void _save_msa(struct task_struct *);
extern void _restore_msa(struct task_struct *);
extern void _init_msa_upper(void);
static inline void enable_msa(void)
{
@ -112,10 +115,10 @@ static inline unsigned int read_msa_##name(void) \
" .set push\n" \
" .set noat\n" \
" .insn\n" \
" .word #CFC_MSA_INSN | (" #cs " << 11)\n" \
" .word %1 | (" #cs " << 11)\n" \
" move %0, $1\n" \
" .set pop\n" \
: "=r"(reg)); \
: "=r"(reg) : "i"(CFC_MSA_INSN)); \
return reg; \
} \
\
@ -126,22 +129,13 @@ static inline void write_msa_##name(unsigned int val) \
" .set noat\n" \
" move $1, %0\n" \
" .insn\n" \
" .word #CTC_MSA_INSN | (" #cs " << 6)\n" \
" .word %1 | (" #cs " << 6)\n" \
" .set pop\n" \
: : "r"(val)); \
: : "r"(val), "i"(CTC_MSA_INSN)); \
}
#endif /* !TOOLCHAIN_SUPPORTS_MSA */
#define MSA_IR 0
#define MSA_CSR 1
#define MSA_ACCESS 2
#define MSA_SAVE 3
#define MSA_MODIFY 4
#define MSA_REQUEST 5
#define MSA_MAP 6
#define MSA_UNMAP 7
__BUILD_MSA_CTL_REG(ir, 0)
__BUILD_MSA_CTL_REG(csr, 1)
__BUILD_MSA_CTL_REG(access, 2)
@ -151,6 +145,17 @@ __BUILD_MSA_CTL_REG(request, 5)
__BUILD_MSA_CTL_REG(map, 6)
__BUILD_MSA_CTL_REG(unmap, 7)
#endif /* !__ASSEMBLY__ */
#define MSA_IR 0
#define MSA_CSR 1
#define MSA_ACCESS 2
#define MSA_SAVE 3
#define MSA_MODIFY 4
#define MSA_REQUEST 5
#define MSA_MAP 6
#define MSA_UNMAP 7
/* MSA Implementation Register (MSAIR) */
#define MSA_IR_REVB 0
#define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB)

View File

@ -228,6 +228,7 @@ enum cvmx_board_types_enum {
*/
CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
CVMX_BOARD_TYPE_UBNT_E100 = 20002,
CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
/* The remaining range is reserved for future use. */
@ -327,6 +328,7 @@ static inline const char *cvmx_board_type_to_string(enum
/* Customer private range */
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
}
return "Unsupported Board";

View File

@ -18,6 +18,18 @@
#include <asm-generic/pgtable-nopmd.h>
extern int temp_tlb_entry __cpuinitdata;
/*
* - add_temporary_entry() add a temporary TLB entry. We use TLB entries
* starting at the top and working down. This is for populating the
* TLB before trap_init() puts the TLB miss handler in place. It
* should be used only for entries matching the actual page tables,
* to prevent inconsistencies.
*/
extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
unsigned long entryhi, unsigned long pagemask);
/*
* Basically we have the same two-level (which is the logical three level
* Linux page table layout folded) page tables as the i386. Some day

View File

@ -97,6 +97,31 @@ extern void paging_init(void);
#define pmd_page_vaddr(pmd) pmd_val(pmd)
#define htw_stop() \
do { \
if (cpu_has_htw) \
write_c0_pwctl(read_c0_pwctl() & \
~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
} while(0)
#define htw_start() \
do { \
if (cpu_has_htw) \
write_c0_pwctl(read_c0_pwctl() | \
(1 << MIPS_PWCTL_PWEN_SHIFT)); \
} while(0)
#define htw_reset() \
do { \
if (cpu_has_htw) { \
htw_stop(); \
back_to_back_c0_hazard(); \
htw_start(); \
back_to_back_c0_hazard(); \
} \
} while(0)
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
@ -131,6 +156,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
null.pte_low = null.pte_high = _PAGE_GLOBAL;
set_pte_at(mm, addr, ptep, null);
htw_reset();
}
#else
@ -168,6 +194,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
else
#endif
set_pte_at(mm, addr, ptep, __pte(0));
htw_reset();
}
#endif

View File

@ -238,7 +238,13 @@ typedef struct {
unsigned long seg;
} mm_segment_t;
#define ARCH_MIN_TASKALIGN 8
#ifdef CONFIG_CPU_HAS_MSA
# define ARCH_MIN_TASKALIGN 16
# define FPU_ALIGN __aligned(16)
#else
# define ARCH_MIN_TASKALIGN 8
# define FPU_ALIGN
#endif
struct mips_abi;
@ -255,7 +261,7 @@ struct thread_struct {
unsigned long cp0_status;
/* Saved fpu/fpu emulator stuff. */
struct mips_fpu_struct fpu;
struct mips_fpu_struct fpu FPU_ALIGN;
#ifdef CONFIG_MIPS_MT_FPAFF
/* Emulated instruction count */
unsigned long emulated_fp;

View File

@ -23,7 +23,7 @@
struct pt_regs {
#ifdef CONFIG_32BIT
/* Pad bytes for argument save space on the stack. */
unsigned long pad0[6];
unsigned long pad0[8];
#endif
/* Saved main processor registers. */
@ -47,8 +47,10 @@ struct pt_regs {
struct task_struct;
extern int ptrace_getregs(struct task_struct *child, __s64 __user *data);
extern int ptrace_setregs(struct task_struct *child, __s64 __user *data);
extern int ptrace_getregs(struct task_struct *child,
struct user_pt_regs __user *data);
extern int ptrace_setregs(struct task_struct *child,
struct user_pt_regs __user *data);
extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data);
extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data);

View File

@ -1,128 +1 @@
/*
* Various register offset definitions for debuggers, core file
* examiners and whatnot.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1995, 1999 Ralf Baechle
* Copyright (C) 1995, 1999 Silicon Graphics
*/
#ifndef __ASM_MIPS_REG_H
#define __ASM_MIPS_REG_H
#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H)
#define EF_R0 6
#define EF_R1 7
#define EF_R2 8
#define EF_R3 9
#define EF_R4 10
#define EF_R5 11
#define EF_R6 12
#define EF_R7 13
#define EF_R8 14
#define EF_R9 15
#define EF_R10 16
#define EF_R11 17
#define EF_R12 18
#define EF_R13 19
#define EF_R14 20
#define EF_R15 21
#define EF_R16 22
#define EF_R17 23
#define EF_R18 24
#define EF_R19 25
#define EF_R20 26
#define EF_R21 27
#define EF_R22 28
#define EF_R23 29
#define EF_R24 30
#define EF_R25 31
/*
* k0/k1 unsaved
*/
#define EF_R26 32
#define EF_R27 33
#define EF_R28 34
#define EF_R29 35
#define EF_R30 36
#define EF_R31 37
/*
* Saved special registers
*/
#define EF_LO 38
#define EF_HI 39
#define EF_CP0_EPC 40
#define EF_CP0_BADVADDR 41
#define EF_CP0_STATUS 42
#define EF_CP0_CAUSE 43
#define EF_UNUSED0 44
#define EF_SIZE 180
#endif
#if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H)
#define EF_R0 0
#define EF_R1 1
#define EF_R2 2
#define EF_R3 3
#define EF_R4 4
#define EF_R5 5
#define EF_R6 6
#define EF_R7 7
#define EF_R8 8
#define EF_R9 9
#define EF_R10 10
#define EF_R11 11
#define EF_R12 12
#define EF_R13 13
#define EF_R14 14
#define EF_R15 15
#define EF_R16 16
#define EF_R17 17
#define EF_R18 18
#define EF_R19 19
#define EF_R20 20
#define EF_R21 21
#define EF_R22 22
#define EF_R23 23
#define EF_R24 24
#define EF_R25 25
/*
* k0/k1 unsaved
*/
#define EF_R26 26
#define EF_R27 27
#define EF_R28 28
#define EF_R29 29
#define EF_R30 30
#define EF_R31 31
/*
* Saved special registers
*/
#define EF_LO 32
#define EF_HI 33
#define EF_CP0_EPC 34
#define EF_CP0_BADVADDR 35
#define EF_CP0_STATUS 36
#define EF_CP0_CAUSE 37
#define EF_SIZE 304 /* size in bytes */
#endif /* CONFIG_64BIT */
#endif /* __ASM_MIPS_REG_H */
#include <uapi/asm/reg.h>

View File

@ -31,11 +31,19 @@ extern void mips_cps_core_init(void);
extern struct vpe_boot_config *mips_cps_boot_vpes(void);
extern bool mips_cps_smp_in_use(void);
extern void mips_cps_pm_save(void);
extern void mips_cps_pm_restore(void);
#ifdef CONFIG_MIPS_CPS
extern bool mips_cps_smp_in_use(void);
#else /* !CONFIG_MIPS_CPS */
static inline bool mips_cps_smp_in_use(void) { return false; }
#endif /* !CONFIG_MIPS_CPS */
#else /* __ASSEMBLY__ */
.extern mips_cps_bootcfg;

View File

@ -22,6 +22,7 @@
extern int smp_num_siblings;
extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[];
#define raw_smp_processor_id() (current_thread_info()->cpu)
@ -36,6 +37,11 @@ extern int __cpu_logical_map[NR_CPUS];
#define NO_PROC_ID (-1)
#define topology_physical_package_id(cpu) (cpu_data[cpu].package)
#define topology_core_id(cpu) (cpu_data[cpu].core)
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
#define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu])
#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */
#define SMP_CALL_FUNCTION 0x2
/* Octeon - Tell another core to flush its icache */

View File

@ -11,7 +11,7 @@
#else
# define SECTION_SIZE_BITS 28
#endif
#define MAX_PHYSMEM_BITS 35
#define MAX_PHYSMEM_BITS 48
#endif /* CONFIG_SPARSEMEM */
#endif /* _MIPS_SPARSEMEM_H */

View File

@ -1,58 +0,0 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
*/
#ifndef _ASM_USER_H
#define _ASM_USER_H
#include <asm/page.h>
#include <asm/reg.h>
/*
* Core file format: The core file is written in such a way that gdb
* can understand it and provide useful information to the user (under
* linux we use the `trad-core' bfd, NOT the irix-core). The file
* contents are as follows:
*
* upage: 1 page consisting of a user struct that tells gdb
* what is present in the file. Directly after this is a
* copy of the task_struct, which is currently not used by gdb,
* but it may come in handy at some point. All of the registers
* are stored as part of the upage. The upage should always be
* only one page long.
* data: The data segment follows next. We use current->end_text to
* current->brk to pick up all of the user variables, plus any memory
* that may have been sbrk'ed. No attempt is made to determine if a
* page is demand-zero or if a page is totally unused, we just cover
* the entire range. All of the addresses are rounded in such a way
* that an integral number of pages is written.
* stack: We need the stack information in order to get a meaningful
* backtrace. We need to write the data from usp to
* current->start_stack, so we round each of these in order to be able
* to write an integer number of pages.
*/
struct user {
unsigned long regs[EF_SIZE / /* integer and fp regs */
sizeof(unsigned long) + 64];
size_t u_tsize; /* text size (pages) */
size_t u_dsize; /* data size (pages) */
size_t u_ssize; /* stack size (pages) */
unsigned long start_code; /* text starting address */
unsigned long start_data; /* data starting address */
unsigned long start_stack; /* stack starting address */
long int signal; /* signal causing core dump */
unsigned long u_ar0; /* help gdb find registers */
unsigned long magic; /* identifies a core file */
char u_comm[32]; /* user command name */
};
#define NBPG PAGE_SIZE
#define UPAGES 1
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_DATA_START_ADDR (u.start_data)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
#endif /* _ASM_USER_H */

View File

@ -22,24 +22,27 @@
#define DSP_CONTROL 77
#define ACX 78
#ifndef __KERNEL__
/*
* This struct defines the way the registers are stored on the stack during a
* system call/exception. As usual the registers k0/k1 aren't being saved.
* This struct defines the registers as used by PTRACE_{GET,SET}REGS. The
* format is the same for both 32- and 64-bit processes. Registers for 32-bit
* processes are sign extended.
*/
#ifdef __KERNEL__
struct user_pt_regs {
#else
struct pt_regs {
#endif
/* Saved main processor registers. */
unsigned long regs[32];
__u64 regs[32];
/* Saved special registers. */
unsigned long cp0_status;
unsigned long hi;
unsigned long lo;
unsigned long cp0_badvaddr;
unsigned long cp0_cause;
unsigned long cp0_epc;
__u64 lo;
__u64 hi;
__u64 cp0_epc;
__u64 cp0_badvaddr;
__u64 cp0_status;
__u64 cp0_cause;
} __attribute__ ((aligned (8)));
#endif /* __KERNEL__ */
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
#define PTRACE_GETREGS 12

View File

@ -0,0 +1,206 @@
/*
* Various register offset definitions for debuggers, core file
* examiners and whatnot.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1995, 1999 Ralf Baechle
* Copyright (C) 1995, 1999 Silicon Graphics
*/
#ifndef __UAPI_ASM_MIPS_REG_H
#define __UAPI_ASM_MIPS_REG_H
#define MIPS32_EF_R0 6
#define MIPS32_EF_R1 7
#define MIPS32_EF_R2 8
#define MIPS32_EF_R3 9
#define MIPS32_EF_R4 10
#define MIPS32_EF_R5 11
#define MIPS32_EF_R6 12
#define MIPS32_EF_R7 13
#define MIPS32_EF_R8 14
#define MIPS32_EF_R9 15
#define MIPS32_EF_R10 16
#define MIPS32_EF_R11 17
#define MIPS32_EF_R12 18
#define MIPS32_EF_R13 19
#define MIPS32_EF_R14 20
#define MIPS32_EF_R15 21
#define MIPS32_EF_R16 22
#define MIPS32_EF_R17 23
#define MIPS32_EF_R18 24
#define MIPS32_EF_R19 25
#define MIPS32_EF_R20 26
#define MIPS32_EF_R21 27
#define MIPS32_EF_R22 28
#define MIPS32_EF_R23 29
#define MIPS32_EF_R24 30
#define MIPS32_EF_R25 31
/*
* k0/k1 unsaved
*/
#define MIPS32_EF_R26 32
#define MIPS32_EF_R27 33
#define MIPS32_EF_R28 34
#define MIPS32_EF_R29 35
#define MIPS32_EF_R30 36
#define MIPS32_EF_R31 37
/*
* Saved special registers
*/
#define MIPS32_EF_LO 38
#define MIPS32_EF_HI 39
#define MIPS32_EF_CP0_EPC 40
#define MIPS32_EF_CP0_BADVADDR 41
#define MIPS32_EF_CP0_STATUS 42
#define MIPS32_EF_CP0_CAUSE 43
#define MIPS32_EF_UNUSED0 44
#define MIPS32_EF_SIZE 180
#define MIPS64_EF_R0 0
#define MIPS64_EF_R1 1
#define MIPS64_EF_R2 2
#define MIPS64_EF_R3 3
#define MIPS64_EF_R4 4
#define MIPS64_EF_R5 5
#define MIPS64_EF_R6 6
#define MIPS64_EF_R7 7
#define MIPS64_EF_R8 8
#define MIPS64_EF_R9 9
#define MIPS64_EF_R10 10
#define MIPS64_EF_R11 11
#define MIPS64_EF_R12 12
#define MIPS64_EF_R13 13
#define MIPS64_EF_R14 14
#define MIPS64_EF_R15 15
#define MIPS64_EF_R16 16
#define MIPS64_EF_R17 17
#define MIPS64_EF_R18 18
#define MIPS64_EF_R19 19
#define MIPS64_EF_R20 20
#define MIPS64_EF_R21 21
#define MIPS64_EF_R22 22
#define MIPS64_EF_R23 23
#define MIPS64_EF_R24 24
#define MIPS64_EF_R25 25
/*
* k0/k1 unsaved
*/
#define MIPS64_EF_R26 26
#define MIPS64_EF_R27 27
#define MIPS64_EF_R28 28
#define MIPS64_EF_R29 29
#define MIPS64_EF_R30 30
#define MIPS64_EF_R31 31
/*
* Saved special registers
*/
#define MIPS64_EF_LO 32
#define MIPS64_EF_HI 33
#define MIPS64_EF_CP0_EPC 34
#define MIPS64_EF_CP0_BADVADDR 35
#define MIPS64_EF_CP0_STATUS 36
#define MIPS64_EF_CP0_CAUSE 37
#define MIPS64_EF_SIZE 304 /* size in bytes */
#if _MIPS_SIM == _MIPS_SIM_ABI32
#define EF_R0 MIPS32_EF_R0
#define EF_R1 MIPS32_EF_R1
#define EF_R2 MIPS32_EF_R2
#define EF_R3 MIPS32_EF_R3
#define EF_R4 MIPS32_EF_R4
#define EF_R5 MIPS32_EF_R5
#define EF_R6 MIPS32_EF_R6
#define EF_R7 MIPS32_EF_R7
#define EF_R8 MIPS32_EF_R8
#define EF_R9 MIPS32_EF_R9
#define EF_R10 MIPS32_EF_R10
#define EF_R11 MIPS32_EF_R11
#define EF_R12 MIPS32_EF_R12
#define EF_R13 MIPS32_EF_R13
#define EF_R14 MIPS32_EF_R14
#define EF_R15 MIPS32_EF_R15
#define EF_R16 MIPS32_EF_R16
#define EF_R17 MIPS32_EF_R17
#define EF_R18 MIPS32_EF_R18
#define EF_R19 MIPS32_EF_R19
#define EF_R20 MIPS32_EF_R20
#define EF_R21 MIPS32_EF_R21
#define EF_R22 MIPS32_EF_R22
#define EF_R23 MIPS32_EF_R23
#define EF_R24 MIPS32_EF_R24
#define EF_R25 MIPS32_EF_R25
#define EF_R26 MIPS32_EF_R26
#define EF_R27 MIPS32_EF_R27
#define EF_R28 MIPS32_EF_R28
#define EF_R29 MIPS32_EF_R29
#define EF_R30 MIPS32_EF_R30
#define EF_R31 MIPS32_EF_R31
#define EF_LO MIPS32_EF_LO
#define EF_HI MIPS32_EF_HI
#define EF_CP0_EPC MIPS32_EF_CP0_EPC
#define EF_CP0_BADVADDR MIPS32_EF_CP0_BADVADDR
#define EF_CP0_STATUS MIPS32_EF_CP0_STATUS
#define EF_CP0_CAUSE MIPS32_EF_CP0_CAUSE
#define EF_UNUSED0 MIPS32_EF_UNUSED0
#define EF_SIZE MIPS32_EF_SIZE
#elif _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
#define EF_R0 MIPS64_EF_R0
#define EF_R1 MIPS64_EF_R1
#define EF_R2 MIPS64_EF_R2
#define EF_R3 MIPS64_EF_R3
#define EF_R4 MIPS64_EF_R4
#define EF_R5 MIPS64_EF_R5
#define EF_R6 MIPS64_EF_R6
#define EF_R7 MIPS64_EF_R7
#define EF_R8 MIPS64_EF_R8
#define EF_R9 MIPS64_EF_R9
#define EF_R10 MIPS64_EF_R10
#define EF_R11 MIPS64_EF_R11
#define EF_R12 MIPS64_EF_R12
#define EF_R13 MIPS64_EF_R13
#define EF_R14 MIPS64_EF_R14
#define EF_R15 MIPS64_EF_R15
#define EF_R16 MIPS64_EF_R16
#define EF_R17 MIPS64_EF_R17
#define EF_R18 MIPS64_EF_R18
#define EF_R19 MIPS64_EF_R19
#define EF_R20 MIPS64_EF_R20
#define EF_R21 MIPS64_EF_R21
#define EF_R22 MIPS64_EF_R22
#define EF_R23 MIPS64_EF_R23
#define EF_R24 MIPS64_EF_R24
#define EF_R25 MIPS64_EF_R25
#define EF_R26 MIPS64_EF_R26
#define EF_R27 MIPS64_EF_R27
#define EF_R28 MIPS64_EF_R28
#define EF_R29 MIPS64_EF_R29
#define EF_R30 MIPS64_EF_R30
#define EF_R31 MIPS64_EF_R31
#define EF_LO MIPS64_EF_LO
#define EF_HI MIPS64_EF_HI
#define EF_CP0_EPC MIPS64_EF_CP0_EPC
#define EF_CP0_BADVADDR MIPS64_EF_CP0_BADVADDR
#define EF_CP0_STATUS MIPS64_EF_CP0_STATUS
#define EF_CP0_CAUSE MIPS64_EF_CP0_CAUSE
#define EF_SIZE MIPS64_EF_SIZE
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
#endif /* __UAPI_ASM_MIPS_REG_H */

View File

@ -87,8 +87,7 @@ void jz4740_clock_debugfs_add_clk(struct clk *clk)
/* TODO: Locking */
void jz4740_clock_debugfs_update_parent(struct clk *clk)
{
if (clk->debugfs_parent_entry)
debugfs_remove(clk->debugfs_parent_entry);
debugfs_remove(clk->debugfs_parent_entry);
if (clk->parent) {
char parent_path[100];

View File

@ -59,7 +59,7 @@ struct platform_device jz4740_usb_ohci_device = {
/* USB Device Controller */
struct platform_device jz4740_udc_xceiv_device = {
.name = "usb_phy_gen_xceiv",
.name = "usb_phy_generic",
.id = 0,
};

View File

@ -234,6 +234,7 @@ void output_thread_fpu_defines(void)
thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]);
OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31);
OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr);
BLANK();
}

View File

@ -72,22 +72,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#include <asm/processor.h>
/*
* When this file is selected, we are definitely running a 64bit kernel.
* So using the right regs define in asm/reg.h
*/
#define WANT_COMPAT_REG_H
/* These MUST be defined before elf.h gets included */
extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs);
#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs);
#define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \
({ \
int __res = 1; \
elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \
__res; \
})
#include <linux/module.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@ -145,28 +129,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
value->tv_usec = rem / NSEC_PER_USEC;
}
void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
{
int i;
for (i = 0; i < EF_R0; i++)
grp[i] = 0;
grp[EF_R0] = 0;
for (i = 1; i <= 31; i++)
grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
grp[EF_R26] = 0;
grp[EF_R27] = 0;
grp[EF_LO] = (elf_greg_t) regs->lo;
grp[EF_HI] = (elf_greg_t) regs->hi;
grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
#ifdef EF_UNUSED0
grp[EF_UNUSED0] = 0;
#endif
}
MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");

View File

@ -54,6 +54,20 @@ static int __init dsp_disable(char *s)
__setup("nodsp", dsp_disable);
static int mips_htw_disabled;
static int __init htw_disable(char *s)
{
mips_htw_disabled = 1;
cpu_data[0].options &= ~MIPS_CPU_HTW;
write_c0_pwctl(read_c0_pwctl() &
~(1 << MIPS_PWCTL_PWEN_SHIFT));
return 1;
}
__setup("nohtw", htw_disable);
static inline void check_errata(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
@ -130,14 +144,13 @@ static inline int __cpu_has_fpu(void)
static inline unsigned long cpu_get_msa_id(void)
{
unsigned long status, conf5, msa_id;
unsigned long status, msa_id;
status = read_c0_status();
__enable_fpu(FPU_64BIT);
conf5 = read_c0_config5();
enable_msa();
msa_id = read_msa_ir();
write_c0_config5(conf5);
disable_msa();
write_c0_status(status);
return msa_id;
}
@ -321,6 +334,9 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
c->options |= MIPS_CPU_SEGMENTS;
if (config3 & MIPS_CONF3_MSA)
c->ases |= MIPS_ASE_MSA;
/* Only tested on 32-bit cores */
if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT))
c->options |= MIPS_CPU_HTW;
return config3 & MIPS_CONF_M;
}
@ -389,6 +405,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
if (config5 & MIPS_CONF5_EVA)
c->options |= MIPS_CPU_EVA;
if (config5 & MIPS_CONF5_MRP)
c->options |= MIPS_CPU_MAAR;
return config5 & MIPS_CONF_M;
}
@ -421,6 +439,15 @@ static void decode_configs(struct cpuinfo_mips *c)
mips_probe_watch_registers(c);
if (cpu_has_rixi) {
/* Enable the RIXI exceptions */
write_c0_pagegrain(read_c0_pagegrain() | PG_IEC);
back_to_back_c0_hazard();
/* Verify the IEC bit is set */
if (read_c0_pagegrain() & PG_IEC)
c->options |= MIPS_CPU_RIXIEX;
}
#ifndef CONFIG_MIPS_CPS
if (cpu_has_mips_r2) {
c->core = get_ebase_cpunum();
@ -740,6 +767,12 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
__cpu_name[cpu] = "ICT Loongson-3";
set_elf_platform(cpu, "loongson3a");
break;
case PRID_REV_LOONGSON3B_R1:
case PRID_REV_LOONGSON3B_R2:
c->cputype = CPU_LOONGSON3;
__cpu_name[cpu] = "ICT Loongson-3";
set_elf_platform(cpu, "loongson3b");
break;
}
set_isa(c, MIPS_CPU_ISA_III);
@ -1187,6 +1220,12 @@ void cpu_probe(void)
if (mips_dsp_disabled)
c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
if (mips_htw_disabled) {
c->options &= ~MIPS_CPU_HTW;
write_c0_pwctl(read_c0_pwctl() &
~(1 << MIPS_PWCTL_PWEN_SHIFT));
}
if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();

View File

@ -63,7 +63,7 @@ static inline int in_kernel_space(unsigned long ip)
((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK)))
static unsigned int insn_jal_ftrace_caller __read_mostly;
static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
static unsigned int insn_la_mcount[2] __read_mostly;
static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
static inline void ftrace_dyn_arch_init_insns(void)
@ -71,10 +71,10 @@ static inline void ftrace_dyn_arch_init_insns(void)
u32 *buf;
unsigned int v1;
/* lui v1, hi16_mcount */
/* la v1, _mcount */
v1 = 3;
buf = (u32 *)&insn_lui_v1_hi16_mcount;
UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
buf = (u32 *)&insn_la_mcount[0];
UASM_i_LA(&buf, v1, MCOUNT_ADDR);
/* jal (ftrace_caller + 8), jump over the first two instruction */
buf = (u32 *)&insn_jal_ftrace_caller;
@ -111,14 +111,47 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1,
unsigned int new_code2)
{
int faulted;
mm_segment_t old_fs;
safe_store_code(new_code1, ip, faulted);
if (unlikely(faulted))
return -EFAULT;
safe_store_code(new_code2, ip + 4, faulted);
ip += 4;
safe_store_code(new_code2, ip, faulted);
if (unlikely(faulted))
return -EFAULT;
ip -= 4;
old_fs = get_fs();
set_fs(get_ds());
flush_icache_range(ip, ip + 8);
set_fs(old_fs);
return 0;
}
static int ftrace_modify_code_2r(unsigned long ip, unsigned int new_code1,
unsigned int new_code2)
{
int faulted;
mm_segment_t old_fs;
ip += 4;
safe_store_code(new_code2, ip, faulted);
if (unlikely(faulted))
return -EFAULT;
ip -= 4;
safe_store_code(new_code1, ip, faulted);
if (unlikely(faulted))
return -EFAULT;
old_fs = get_fs();
set_fs(get_ds());
flush_icache_range(ip, ip + 8);
set_fs(old_fs);
return 0;
}
#endif
@ -130,13 +163,14 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1,
*
* move at, ra
* jal _mcount --> nop
* sub sp, sp, 8 --> nop (CONFIG_32BIT)
*
* 2. For modules:
*
* 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT
*
* lui v1, hi_16bit_of_mcount --> b 1f (0x10000005)
* addiu v1, v1, low_16bit_of_mcount
* addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT)
* move at, ra
* move $12, ra_address
* jalr v1
@ -145,7 +179,7 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1,
* 2.2 For the Other situations
*
* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
* addiu v1, v1, low_16bit_of_mcount
* addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT)
* move at, ra
* jalr v1
* nop | move $12, ra_address | sub sp, sp, 8
@ -184,10 +218,14 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
unsigned int new;
unsigned long ip = rec->ip;
new = in_kernel_space(ip) ? insn_jal_ftrace_caller :
insn_lui_v1_hi16_mcount;
new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
#ifdef CONFIG_64BIT
return ftrace_modify_code(ip, new);
#else
return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ?
INSN_NOP : insn_la_mcount[1]);
#endif
}
#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))

View File

@ -28,6 +28,18 @@ unsigned int gic_irq_flags[GIC_NUM_INTRS];
/* The index into this array is the vector # of the interrupt. */
struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
struct gic_pcpu_mask {
DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
};
struct gic_pending_regs {
DECLARE_BITMAP(pending, GIC_NUM_INTRS);
};
struct gic_intrmask_regs {
DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
};
static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
@ -177,7 +189,7 @@ unsigned int gic_compare_int(void)
return 0;
}
unsigned int gic_get_int(void)
void gic_get_int_mask(unsigned long *dst, const unsigned long *src)
{
unsigned int i;
unsigned long *pending, *intrmask, *pcpu_mask;
@ -202,8 +214,17 @@ unsigned int gic_get_int(void)
bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
bitmap_and(dst, src, pending, GIC_NUM_INTRS);
}
return find_first_bit(pending, GIC_NUM_INTRS);
unsigned int gic_get_int(void)
{
DECLARE_BITMAP(interrupts, GIC_NUM_INTRS);
bitmap_fill(interrupts, GIC_NUM_INTRS);
gic_get_int_mask(interrupts, interrupts);
return find_first_bit(interrupts, GIC_NUM_INTRS);
}
static void gic_mask_irq(struct irq_data *d)
@ -269,11 +290,13 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
/* Setup Intr to Pin mapping */
if (pin & GIC_MAP_TO_NMI_MSK) {
int i;
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
/* FIXME: hack to route NMI to all cpu's */
for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
for (i = 0; i < NR_CPUS; i += 32) {
GICWRITE(GIC_REG_ADDR(SHARED,
GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)),
0xffffffff);
}
} else {
@ -299,9 +322,10 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
/* Init Intr Masks */
GIC_CLR_INTR_MASK(intr);
/* Initialise per-cpu Interrupt software masks */
if (flags & GIC_FLAG_IPI)
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
GIC_SET_INTR_MASK(intr);
if (trigtype == GIC_TRIG_EDGE)
@ -340,8 +364,6 @@ static void __init gic_basic_init(int numintrs, int numvpes,
cpu = intrmap[i].cpunum;
if (cpu == GIC_UNUSED)
continue;
if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
continue;
gic_setup_intr(i,
intrmap[i].cpunum,
intrmap[i].pin + pin_offset,

View File

@ -80,6 +80,19 @@ _mcount:
#endif
PTR_SUBU a0, ra, 8 /* arg1: self address */
PTR_LA t1, _stext
sltu t2, a0, t1 /* t2 = (a0 < _stext) */
PTR_LA t1, _etext
sltu t3, t1, a0 /* t3 = (a0 > _etext) */
or t1, t2, t3
beqz t1, ftrace_call
nop
#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */
#else
PTR_SUBU a0, a0, 12
#endif
.globl ftrace_call
ftrace_call:
nop /* a placeholder for the call to a real tracing function */

View File

@ -1386,6 +1386,9 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
/* proAptiv */
#define IS_BOTH_COUNTERS_PROAPTIV_EVENT(b) \
((b) == 0 || (b) == 1)
/* P5600 */
#define IS_BOTH_COUNTERS_P5600_EVENT(b) \
((b) == 0 || (b) == 1)
/* 1004K */
#define IS_BOTH_COUNTERS_1004K_EVENT(b) \
@ -1420,20 +1423,23 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
/*
* User can use 0-255 raw events, where 0-127 for the events of even
* counters, and 128-255 for odd counters. Note that bit 7 is used to
* indicate the parity. So, for example, when user wants to take the
* Event Num of 15 for odd counters (by referring to the user manual),
* then 128 needs to be added to 15 as the input for the event config,
* i.e., 143 (0x8F) to be used.
* For most cores the user can use 0-255 raw events, where 0-127 for the events
* of even counters, and 128-255 for odd counters. Note that bit 7 is used to
* indicate the even/odd bank selector. So, for example, when user wants to take
* the Event Num of 15 for odd counters (by referring to the user manual), then
* 128 needs to be added to 15 as the input for the event config, i.e., 143 (0x8F)
* to be used.
*
* Some newer cores have even more events, in which case the user can use raw
* events 0-511, where 0-255 are for the events of even counters, and 256-511
* are for odd counters, so bit 8 is used to indicate the even/odd bank selector.
*/
static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
{
/* currently most cores have 7-bit event numbers */
unsigned int raw_id = config & 0xff;
unsigned int base_id = raw_id & 0x7f;
raw_event.event_id = base_id;
switch (current_cpu_type()) {
case CPU_24K:
if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
@ -1483,6 +1489,19 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
#ifdef CONFIG_MIPS_MT_SMP
raw_event.range = P;
#endif
break;
case CPU_P5600:
/* 8-bit event numbers */
raw_id = config & 0x1ff;
base_id = raw_id & 0xff;
if (IS_BOTH_COUNTERS_P5600_EVENT(base_id))
raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
else
raw_event.cntr_mask =
raw_id > 255 ? CNTR_ODD : CNTR_EVEN;
#ifdef CONFIG_MIPS_MT_SMP
raw_event.range = P;
#endif
break;
case CPU_1004K:
@ -1523,6 +1542,8 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
}
raw_event.event_id = base_id;
return &raw_event;
}
@ -1633,6 +1654,11 @@ init_hw_perf_events(void)
mipspmu.general_event_map = &mipsxxcore_event_map2;
mipspmu.cache_event_map = &mipsxxcore_cache_map2;
break;
case CPU_P5600:
mipspmu.name = "mips/P5600";
mipspmu.general_event_map = &mipsxxcore_event_map2;
mipspmu.cache_event_map = &mipsxxcore_cache_map2;
break;
case CPU_1004K:
mipspmu.name = "mips/1004K";
mipspmu.general_event_map = &mipsxxcore_event_map;

View File

@ -149,8 +149,12 @@ int cps_pm_enter_state(enum cps_pm_state state)
/* Setup the VPE to run mips_cps_pm_restore when started again */
if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) {
/* Power gating relies upon CPS SMP */
if (!mips_cps_smp_in_use())
return -EINVAL;
core_cfg = &mips_cps_core_bootcfg[core];
vpe_cfg = &core_cfg->vpe_config[current_cpu_data.vpe_id];
vpe_cfg = &core_cfg->vpe_config[cpu_vpe_id(&current_cpu_data)];
vpe_cfg->pc = (unsigned long)mips_cps_pm_restore;
vpe_cfg->gp = (unsigned long)current_thread_info();
vpe_cfg->sp = 0;
@ -376,6 +380,10 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
memset(relocs, 0, sizeof(relocs));
if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) {
/* Power gating relies upon CPS SMP */
if (!mips_cps_smp_in_use())
goto out_err;
/*
* Save CPU state. Note the non-standard calling convention
* with the return address placed in v0 to avoid clobbering

View File

@ -113,6 +113,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (cpu_has_vz) seq_printf(m, "%s", " vz");
if (cpu_has_msa) seq_printf(m, "%s", " msa");
if (cpu_has_eva) seq_printf(m, "%s", " eva");
if (cpu_has_htw) seq_printf(m, "%s", " htw");
seq_printf(m, "\n");
if (cpu_has_mmips) {
@ -123,6 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpu_data[n].srsets);
seq_printf(m, "kscratch registers\t: %d\n",
hweight8(cpu_data[n].kscratch_mask));
seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",

View File

@ -21,7 +21,6 @@
#include <linux/mman.h>
#include <linux/personality.h>
#include <linux/sys.h>
#include <linux/user.h>
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/kallsyms.h>
@ -36,6 +35,7 @@
#include <asm/pgtable.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
#include <asm/reg.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/elf.h>
@ -66,6 +66,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
clear_used_math();
clear_fpu_owner();
init_dsp();
clear_thread_flag(TIF_USEDMSA);
clear_thread_flag(TIF_MSA_CTX_LIVE);
disable_msa();
regs->cp0_epc = pc;
@ -141,6 +142,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
clear_tsk_thread_flag(p, TIF_USEDFPU);
clear_tsk_thread_flag(p, TIF_USEDMSA);
clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE);
#ifdef CONFIG_MIPS_MT_FPAFF
clear_tsk_thread_flag(p, TIF_FPUBOUND);
@ -152,61 +155,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return 0;
}
/* Fill in the fpu structure for a core dump.. */
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
{
int i;
for (i = 0; i < NUM_FPU_REGS; i++)
memcpy(&r[i], &current->thread.fpu.fpr[i], sizeof(*r));
memcpy(&r[NUM_FPU_REGS], &current->thread.fpu.fcr31,
sizeof(current->thread.fpu.fcr31));
return 1;
}
void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs)
{
int i;
for (i = 0; i < EF_R0; i++)
gp[i] = 0;
gp[EF_R0] = 0;
for (i = 1; i <= 31; i++)
gp[EF_R0 + i] = regs->regs[i];
gp[EF_R26] = 0;
gp[EF_R27] = 0;
gp[EF_LO] = regs->lo;
gp[EF_HI] = regs->hi;
gp[EF_CP0_EPC] = regs->cp0_epc;
gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
gp[EF_CP0_STATUS] = regs->cp0_status;
gp[EF_CP0_CAUSE] = regs->cp0_cause;
#ifdef EF_UNUSED0
gp[EF_UNUSED0] = 0;
#endif
}
int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
{
elf_dump_regs(*regs, task_pt_regs(tsk));
return 1;
}
int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr)
{
int i;
for (i = 0; i < NUM_FPU_REGS; i++)
memcpy(&fpr[i], &t->thread.fpu.fpr[i], sizeof(*fpr));
memcpy(&fpr[NUM_FPU_REGS], &t->thread.fpu.fcr31,
sizeof(t->thread.fpu.fcr31));
return 1;
}
#ifdef CONFIG_CC_STACKPROTECTOR
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;

View File

@ -24,7 +24,6 @@
#include <linux/ptrace.h>
#include <linux/regset.h>
#include <linux/smp.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/tracehook.h>
#include <linux/audit.h>
@ -63,7 +62,7 @@ void ptrace_disable(struct task_struct *child)
* for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
* Registers are sign extended to fill the available space.
*/
int ptrace_getregs(struct task_struct *child, __s64 __user *data)
int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data)
{
struct pt_regs *regs;
int i;
@ -74,13 +73,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)
regs = task_pt_regs(child);
for (i = 0; i < 32; i++)
__put_user((long)regs->regs[i], data + i);
__put_user((long)regs->lo, data + EF_LO - EF_R0);
__put_user((long)regs->hi, data + EF_HI - EF_R0);
__put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
__put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
__put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
__put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
__put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]);
__put_user((long)regs->lo, (__s64 __user *)&data->lo);
__put_user((long)regs->hi, (__s64 __user *)&data->hi);
__put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
__put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr);
__put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status);
__put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause);
return 0;
}
@ -90,7 +89,7 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)
* the 64-bit format. On a 32-bit kernel only the lower order half
* (according to endianness) will be used.
*/
int ptrace_setregs(struct task_struct *child, __s64 __user *data)
int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data)
{
struct pt_regs *regs;
int i;
@ -101,10 +100,10 @@ int ptrace_setregs(struct task_struct *child, __s64 __user *data)
regs = task_pt_regs(child);
for (i = 0; i < 32; i++)
__get_user(regs->regs[i], data + i);
__get_user(regs->lo, data + EF_LO - EF_R0);
__get_user(regs->hi, data + EF_HI - EF_R0);
__get_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
__get_user(regs->regs[i], (__s64 __user *)&data->regs[i]);
__get_user(regs->lo, (__s64 __user *)&data->lo);
__get_user(regs->hi, (__s64 __user *)&data->hi);
__get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
/* badvaddr, status, and cause may not be written. */
@ -129,7 +128,7 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
}
__put_user(child->thread.fpu.fcr31, data + 64);
__put_user(current_cpu_data.fpu_id, data + 65);
__put_user(boot_cpu_data.fpu_id, data + 65);
return 0;
}
@ -151,6 +150,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
}
__get_user(child->thread.fpu.fcr31, data + 64);
child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
/* FIR may not be written. */
@ -246,36 +246,160 @@ int ptrace_set_watch_regs(struct task_struct *child,
/* regset get/set implementations */
static int gpr_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
static int gpr32_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
struct pt_regs *regs = task_pt_regs(target);
u32 uregs[ELF_NGREG] = {};
unsigned i;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
regs, 0, sizeof(*regs));
for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) {
/* k0/k1 are copied as zero. */
if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27)
continue;
uregs[i] = regs->regs[i - MIPS32_EF_R0];
}
uregs[MIPS32_EF_LO] = regs->lo;
uregs[MIPS32_EF_HI] = regs->hi;
uregs[MIPS32_EF_CP0_EPC] = regs->cp0_epc;
uregs[MIPS32_EF_CP0_BADVADDR] = regs->cp0_badvaddr;
uregs[MIPS32_EF_CP0_STATUS] = regs->cp0_status;
uregs[MIPS32_EF_CP0_CAUSE] = regs->cp0_cause;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
sizeof(uregs));
}
static int gpr_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
static int gpr32_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
struct pt_regs newregs;
int ret;
struct pt_regs *regs = task_pt_regs(target);
u32 uregs[ELF_NGREG];
unsigned start, num_regs, i;
int err;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&newregs,
0, sizeof(newregs));
if (ret)
return ret;
start = pos / sizeof(u32);
num_regs = count / sizeof(u32);
*task_pt_regs(target) = newregs;
if (start + num_regs > ELF_NGREG)
return -EIO;
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
sizeof(uregs));
if (err)
return err;
for (i = start; i < num_regs; i++) {
/*
* Cast all values to signed here so that if this is a 64-bit
* kernel, the supplied 32-bit values will be sign extended.
*/
switch (i) {
case MIPS32_EF_R1 ... MIPS32_EF_R25:
/* k0/k1 are ignored. */
case MIPS32_EF_R28 ... MIPS32_EF_R31:
regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i];
break;
case MIPS32_EF_LO:
regs->lo = (s32)uregs[i];
break;
case MIPS32_EF_HI:
regs->hi = (s32)uregs[i];
break;
case MIPS32_EF_CP0_EPC:
regs->cp0_epc = (s32)uregs[i];
break;
}
}
return 0;
}
#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */
#ifdef CONFIG_64BIT
static int gpr64_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
struct pt_regs *regs = task_pt_regs(target);
u64 uregs[ELF_NGREG] = {};
unsigned i;
for (i = MIPS64_EF_R1; i <= MIPS64_EF_R31; i++) {
/* k0/k1 are copied as zero. */
if (i == MIPS64_EF_R26 || i == MIPS64_EF_R27)
continue;
uregs[i] = regs->regs[i - MIPS64_EF_R0];
}
uregs[MIPS64_EF_LO] = regs->lo;
uregs[MIPS64_EF_HI] = regs->hi;
uregs[MIPS64_EF_CP0_EPC] = regs->cp0_epc;
uregs[MIPS64_EF_CP0_BADVADDR] = regs->cp0_badvaddr;
uregs[MIPS64_EF_CP0_STATUS] = regs->cp0_status;
uregs[MIPS64_EF_CP0_CAUSE] = regs->cp0_cause;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
sizeof(uregs));
}
static int gpr64_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
struct pt_regs *regs = task_pt_regs(target);
u64 uregs[ELF_NGREG];
unsigned start, num_regs, i;
int err;
start = pos / sizeof(u64);
num_regs = count / sizeof(u64);
if (start + num_regs > ELF_NGREG)
return -EIO;
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
sizeof(uregs));
if (err)
return err;
for (i = start; i < num_regs; i++) {
switch (i) {
case MIPS64_EF_R1 ... MIPS64_EF_R25:
/* k0/k1 are ignored. */
case MIPS64_EF_R28 ... MIPS64_EF_R31:
regs->regs[i - MIPS64_EF_R0] = uregs[i];
break;
case MIPS64_EF_LO:
regs->lo = uregs[i];
break;
case MIPS64_EF_HI:
regs->hi = uregs[i];
break;
case MIPS64_EF_CP0_EPC:
regs->cp0_epc = uregs[i];
break;
}
}
return 0;
}
#endif /* CONFIG_64BIT */
static int fpr_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
@ -337,14 +461,16 @@ enum mips_regset {
REGSET_FPR,
};
#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
static const struct user_regset mips_regsets[] = {
[REGSET_GPR] = {
.core_note_type = NT_PRSTATUS,
.n = ELF_NGREG,
.size = sizeof(unsigned int),
.align = sizeof(unsigned int),
.get = gpr_get,
.set = gpr_set,
.get = gpr32_get,
.set = gpr32_set,
},
[REGSET_FPR] = {
.core_note_type = NT_PRFPREG,
@ -364,14 +490,18 @@ static const struct user_regset_view user_mips_view = {
.n = ARRAY_SIZE(mips_regsets),
};
#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */
#ifdef CONFIG_64BIT
static const struct user_regset mips64_regsets[] = {
[REGSET_GPR] = {
.core_note_type = NT_PRSTATUS,
.n = ELF_NGREG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
.get = gpr_get,
.set = gpr_set,
.get = gpr64_get,
.set = gpr64_set,
},
[REGSET_FPR] = {
.core_note_type = NT_PRFPREG,
@ -384,25 +514,26 @@ static const struct user_regset mips64_regsets[] = {
};
static const struct user_regset_view user_mips64_view = {
.name = "mips",
.name = "mips64",
.e_machine = ELF_ARCH,
.ei_osabi = ELF_OSABI,
.regsets = mips64_regsets,
.n = ARRAY_SIZE(mips_regsets),
.n = ARRAY_SIZE(mips64_regsets),
};
#endif /* CONFIG_64BIT */
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
#ifdef CONFIG_32BIT
return &user_mips_view;
#endif
#else
#ifdef CONFIG_MIPS32_O32
if (test_thread_flag(TIF_32BIT_REGS))
return &user_mips_view;
if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
return &user_mips_view;
#endif
return &user_mips64_view;
#endif
}
long arch_ptrace(struct task_struct *child, long request,
@ -480,7 +611,7 @@ long arch_ptrace(struct task_struct *child, long request,
break;
case FPC_EIR:
/* implementation / version register */
tmp = current_cpu_data.fpu_id;
tmp = boot_cpu_data.fpu_id;
break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@ -565,7 +696,7 @@ long arch_ptrace(struct task_struct *child, long request,
break;
#endif
case FPC_CSR:
child->thread.fpu.fcr31 = data;
child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;

View File

@ -22,7 +22,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/user.h>
#include <linux/security.h>
#include <asm/cpu.h>
@ -32,6 +31,7 @@
#include <asm/mipsmtregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/reg.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
@ -129,7 +129,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
case FPC_EIR:
/* implementation / version register */
tmp = current_cpu_data.fpu_id;
tmp = boot_cpu_data.fpu_id;
break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@ -256,11 +256,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
}
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (__s64 __user *) (__u64) data);
ret = ptrace_getregs(child,
(struct user_pt_regs __user *) (__u64) data);
break;
case PTRACE_SETREGS:
ret = ptrace_setregs(child, (__s64 __user *) (__u64) data);
ret = ptrace_setregs(child,
(struct user_pt_regs __user *) (__u64) data);
break;
case PTRACE_GETFPREGS:

View File

@ -64,8 +64,10 @@
/* Check whether we're saving scalar or vector context. */
bgtz a3, 1f
/* Save 128b MSA vector context. */
/* Save 128b MSA vector context + scalar FP control & status. */
cfc1 t1, fcr31
msa_save_all a0
sw t1, THREAD_FCR31(a0)
b 2f
1: /* Save 32b/64b scalar FP context. */
@ -142,6 +144,11 @@ LEAF(_restore_msa)
jr ra
END(_restore_msa)
LEAF(_init_msa_upper)
msa_init_all_upper
jr ra
END(_init_msa_upper)
#endif
/*

Some files were not shown because too many files have changed in this diff Show More