diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 14:52:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 14:52:21 -0700 |
commit | d1447464789918db1e1a3d0aaf50d3d0f6487a4f (patch) | |
tree | 490bd5c493cdba742dc90d3731962226838e5f33 /arch/mips | |
parent | 833e68340d108d88f4cb79b7d7223f6859d362ca (diff) | |
parent | 6ac5310e649df5fcd240d764503bf16a1317ea39 (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"MIPS updates:
- All the things that didn't make 3.10.
- Removes the Windriver PPMC platform. Nobody will miss it.
- Remove a workaround from kernel/irq/irqdomain.c which was there
exclusivly for MIPS. Patch by Grant Likely.
- More small improvments for the SEAD 3 platform
- Improvments on the BMIPS / SMP support for the BCM63xx series.
- Various cleanups of dead leftovers.
- Platform support for the Cavium Octeon-based EdgeRouter Lite.
Two large KVM patchsets didn't make it for this pull request because
their respective authors are vacationing"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (124 commits)
MIPS: Kconfig: Add missing MODULES dependency to VPE_LOADER
MIPS: BCM63xx: CLK: Add dummy clk_{set,round}_rate() functions
MIPS: SEAD3: Disable L2 cache on SEAD-3.
MIPS: BCM63xx: Enable second core SMP on BCM6328 if available
MIPS: BCM63xx: Add SMP support to prom.c
MIPS: define write{b,w,l,q}_relaxed
MIPS: Expose missing pci_io{map,unmap} declarations
MIPS: Malta: Update GCMP detection.
Revert "MIPS: make CAC_ADDR and UNCAC_ADDR account for PHYS_OFFSET"
MIPS: APSP: Remove <asm/kspd.h>
SSB: Kconfig: Amend SSB_EMBEDDED dependencies
MIPS: microMIPS: Fix improper definition of ISA exception bit.
MIPS: Don't try to decode microMIPS branch instructions where they cannot exist.
MIPS: Declare emulate_load_store_microMIPS as a static function.
MIPS: Fix typos and cleanup comment
MIPS: Cleanup indentation and whitespace
MIPS: BMIPS: support booting from physical CPU other than 0
MIPS: Only set cpu_has_mmips if SYS_SUPPORTS_MICROMIPS
MIPS: GIC: Fix gic_set_affinity infinite loop
MIPS: Don't save/restore OCTEON wide multiplier state on syscalls.
...
Diffstat (limited to 'arch/mips')
158 files changed, 2189 insertions, 2309 deletions
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 4b597d91a8d..d9d81c21925 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -30,7 +30,6 @@ platforms += sibyte platforms += sni platforms += txx9 platforms += vr41xx -platforms += wrppmc # include the platform specific files include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms)) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index beeff436b22..4758a8fd3e9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1,6 +1,7 @@ config MIPS bool default y + select HAVE_CONTEXT_TRACKING select HAVE_GENERIC_DMA_COHERENT select HAVE_IDE select HAVE_OPROFILE @@ -27,6 +28,7 @@ config MIPS select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP select HAVE_ARCH_JUMP_LABEL select ARCH_WANT_IPC_PARSE_VERSION select IRQ_FORCED_THREADING @@ -46,9 +48,6 @@ config MIPS menu "Machine selection" -config ZONE_DMA - bool - choice prompt "System type" default SGI_IP22 @@ -124,11 +123,14 @@ config BCM47XX config BCM63XX bool "Broadcom BCM63XX based boards" + select BOOT_RAW select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT select IRQ_CPU select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348 + select NR_CPUS_DEFAULT_2 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK @@ -341,7 +343,6 @@ config MIPS_SEAD3 select DMA_NONCOHERENT select IRQ_CPU select IRQ_GIC - select MIPS_CPU_SCACHE select MIPS_MSC select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 @@ -420,7 +421,6 @@ config POWERTV select CSRC_POWERTV select DMA_NONCOHERENT select HW_HAS_PCI - select SYS_HAS_EARLY_PRINTK select SYS_HAS_CPU_MIPS32_R2 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -713,46 +713,8 @@ config MIKROTIK_RB532 Support the Mikrotik(tm) RouterBoard 532 series, based on the IDT RC32434 SoC. -config WR_PPMC - bool "Wind River PPMC board" - select CEVT_R4K - select CSRC_R4K - select IRQ_CPU - select BOOT_ELF32 - select DMA_NONCOHERENT - select HW_HAS_PCI - select PCI_GT64XXX_PCI0 - select SWAP_IO_SPACE - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_CPU_MIPS32_R2 - select SYS_HAS_CPU_MIPS64_R1 - select SYS_HAS_CPU_NEVADA - select SYS_HAS_CPU_RM7000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - help - This enables support for the Wind River MIPS32 4KC PPMC evaluation - board, which is based on GT64120 bridge chip. - -config CAVIUM_OCTEON_SIMULATOR - bool "Cavium Networks Octeon Simulator" - select CEVT_R4K - select 64BIT_PHYS_ADDR - select DMA_COHERENT - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_HOTPLUG_CPU - select SYS_HAS_CPU_CAVIUM_OCTEON - select HOLES_IN_ZONE - help - The Octeon simulator is software performance model of the Cavium - Octeon Processor. It supports simulating Octeon processors on x86 - hardware. - -config CAVIUM_OCTEON_REFERENCE_BOARD - bool "Cavium Networks Octeon reference board" +config CAVIUM_OCTEON_SOC + bool "Cavium Networks Octeon SoC based boards" select CEVT_R4K select 64BIT_PHYS_ADDR select DMA_COHERENT @@ -806,6 +768,8 @@ config NLM_XLR_BOARD select SYS_HAS_EARLY_PRINTK select USB_ARCH_HAS_OHCI if USB_SUPPORT select USB_ARCH_HAS_EHCI if USB_SUPPORT + select SYS_SUPPORTS_ZBOOT + select SYS_SUPPORTS_ZBOOT_UART16550 help Support for systems based on Netlogic XLR and XLS processors. Say Y here if you have a XLR or XLS based board. @@ -832,6 +796,8 @@ config NLM_XLP_BOARD select SYNC_R4K select SYS_HAS_EARLY_PRINTK select USE_OF + select SYS_SUPPORTS_ZBOOT + select SYS_SUPPORTS_ZBOOT_UART16550 help This board is based on Netlogic XLP Processor. Say Y here if you have a XLP based board. @@ -1031,7 +997,6 @@ config CPU_BIG_ENDIAN config CPU_LITTLE_ENDIAN bool "Little endian" depends on SYS_SUPPORTS_LITTLE_ENDIAN - help endchoice @@ -1964,7 +1929,7 @@ config MIPS_MT_FPAFF config MIPS_VPE_LOADER bool "VPE loader support." - depends on SYS_SUPPORTS_MULTITHREADING + depends on SYS_SUPPORTS_MULTITHREADING && MODULES select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select MIPS_MT @@ -2382,6 +2347,19 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + + This feature requires gcc version 4.2 or above. + config USE_OF bool select OF @@ -2413,7 +2391,6 @@ config PCI bool "Support for PCI controller" depends on HW_HAS_PCI select PCI_DOMAINS - select GENERIC_PCI_IOMAP select NO_GENERIC_PCI_IOPORT_MAP help Find out whether you have a PCI motherboard. PCI is the name of a @@ -2479,6 +2456,9 @@ config I8253 select CLKEVT_I8253 select MIPS_EXTERNAL_TIMER +config ZONE_DMA + bool + config ZONE_DMA32 bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index dd58a04ef4b..37f9ef324f2 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -227,6 +227,10 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) LDFLAGS += -m $(ld-emul) +ifdef CONFIG_CC_STACKPROTECTOR + KBUILD_CFLAGS += -fstack-protector +endif + ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ diff --git a/arch/mips/ath79/mach-ap136.c b/arch/mips/ath79/mach-ap136.c index 479dd4b1d0d..07eac58c364 100644 --- a/arch/mips/ath79/mach-ap136.c +++ b/arch/mips/ath79/mach-ap136.c @@ -132,7 +132,7 @@ static void __init ap136_pci_init(u8 *eeprom) ath79_register_pci(); } #else -static inline void ap136_pci_init(void) {} +static inline void ap136_pci_init(u8 *eeprom) {} #endif /* CONFIG_PCI */ static void __init ap136_setup(void) diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig index 5639662fd50..b78306ce56c 100644 --- a/arch/mips/bcm63xx/Kconfig +++ b/arch/mips/bcm63xx/Kconfig @@ -1,6 +1,10 @@ menu "CPU support" depends on BCM63XX +config BCM63XX_CPU_3368 + bool "support 3368 CPU" + select HW_HAS_PCI + config BCM63XX_CPU_6328 bool "support 6328 CPU" select HW_HAS_PCI @@ -8,14 +12,9 @@ config BCM63XX_CPU_6328 config BCM63XX_CPU_6338 bool "support 6338 CPU" select HW_HAS_PCI - select USB_ARCH_HAS_OHCI - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO config BCM63XX_CPU_6345 bool "support 6345 CPU" - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO config BCM63XX_CPU_6348 bool "support 6348 CPU" diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 9c0ddafafb6..5b974eb125f 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -28,11 +28,47 @@ #include <bcm63xx_dev_usb_usbd.h> #include <board_bcm963xx.h> +#include <uapi/linux/bcm933xx_hcs.h> + #define PFX "board_bcm963xx: " +#define HCS_OFFSET_128K 0x20000 + static struct board_info board; /* + * known 3368 boards + */ +#ifdef CONFIG_BCM63XX_CPU_3368 +static struct board_info __initdata board_cvg834g = { + .name = "CVG834G_E15R3921", + .expected_cpu_id = 0x3368, + + .has_uart0 = 1, + .has_uart1 = 1, + + .has_enet0 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .leds = { + { + .name = "CVG834G:green:power", + .gpio = 37, + .default_trigger= "default-on", + }, + }, + + .ephy_reset_gpio = 36, + .ephy_reset_gpio_flags = GPIOF_INIT_HIGH, +}; +#endif + +/* * known 6328 boards */ #ifdef CONFIG_BCM63XX_CPU_6328 @@ -639,6 +675,9 @@ static struct board_info __initdata board_DWVS0 = { * all boards */ static const struct board_info __initconst *bcm963xx_boards[] = { +#ifdef CONFIG_BCM63XX_CPU_3368 + &board_cvg834g, +#endif #ifdef CONFIG_BCM63XX_CPU_6328 &board_96328avng, #endif @@ -722,8 +761,9 @@ void __init board_prom_init(void) unsigned int i; u8 *boot_addr, *cfe; char cfe_version[32]; - char *board_name; + char *board_name = NULL; u32 val; + struct bcm_hcs *hcs; /* read base address of boot chip select (0) * 6328/6362 do not have MPI but boot from a fixed address @@ -747,7 +787,12 @@ void __init board_prom_init(void) bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); - board_name = bcm63xx_nvram_get_name(); + if (BCMCPU_IS_3368()) { + hcs = (struct bcm_hcs *)boot_addr; + board_name = hcs->filename; + } else { + board_name = bcm63xx_nvram_get_name(); + } /* find board by name */ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) @@ -877,5 +922,9 @@ int __init board_register_devices(void) platform_device_register(&bcm63xx_gpio_leds); + if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags) + gpio_request_one(board.ephy_reset_gpio, + board.ephy_reset_gpio_flags, "ephy-reset"); + return 0; } diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index c726a97fc79..43da4ae04cc 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -84,7 +84,7 @@ static void enetx_set(struct clk *clk, int enable) else clk_disable_unlocked(&clk_enet_misc); - if (BCMCPU_IS_6358()) { + if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) { u32 mask; if (clk->id == 0) @@ -110,9 +110,8 @@ static struct clk clk_enet1 = { */ static void ephy_set(struct clk *clk, int enable) { - if (!BCMCPU_IS_6358()) - return; - bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable); + if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) + bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable); } @@ -155,9 +154,10 @@ static struct clk clk_enetsw = { */ static void pcm_set(struct clk *clk, int enable) { - if (!BCMCPU_IS_6358()) - return; - bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); + if (BCMCPU_IS_3368()) + bcm_hwclock_set(CKCTL_3368_PCM_EN, enable); + if (BCMCPU_IS_6358()) + bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); } static struct clk clk_pcm = { @@ -211,7 +211,7 @@ static void spi_set(struct clk *clk, int enable) mask = CKCTL_6338_SPI_EN; else if (BCMCPU_IS_6348()) mask = CKCTL_6348_SPI_EN; - else if (BCMCPU_IS_6358()) + else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) mask = CKCTL_6358_SPI_EN; else if (BCMCPU_IS_6362()) mask = CKCTL_6362_SPI_EN; @@ -318,6 +318,18 @@ unsigned long clk_get_rate(struct clk *clk) EXPORT_SYMBOL(clk_get_rate); +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} +EXPORT_SYMBOL_GPL(clk_round_rate); + struct clk *clk_get(struct device *dev, const char *id) { if (!strcmp(id, "enet0")) @@ -338,7 +350,7 @@ struct clk *clk_get(struct device *dev, const char *id) return &clk_xtm; if (!strcmp(id, "periph")) return &clk_periph; - if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) + if ((BCMCPU_IS_3368() || BCMCPU_IS_6358()) && !strcmp(id, "pcm")) return &clk_pcm; if ((BCMCPU_IS_6362() || BCMCPU_IS_6368()) && !strcmp(id, "ipsec")) return &clk_ipsec; diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 79fe32df5e9..7e17374a9ae 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c @@ -29,6 +29,14 @@ static u8 bcm63xx_cpu_rev; static unsigned int bcm63xx_cpu_freq; static unsigned int bcm63xx_memory_size; +static const unsigned long bcm3368_regs_base[] = { + __GEN_CPU_REGS_TABLE(3368) +}; + +static const int bcm3368_irqs[] = { + __GEN_CPU_IRQ_TABLE(3368) +}; + static const unsigned long bcm6328_regs_base[] = { __GEN_CPU_REGS_TABLE(6328) }; @@ -116,6 +124,9 @@ unsigned int bcm63xx_get_memory_size(void) static unsigned int detect_cpu_clock(void) { switch (bcm63xx_get_cpu_id()) { + case BCM3368_CPU_ID: + return 300000000; + case BCM6328_CPU_ID: { unsigned int tmp, mips_pll_fcvo; @@ -266,7 +277,7 @@ static unsigned int detect_memory_size(void) banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; } - if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { + if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) { val = bcm_memc_readl(MEMC_CFG_REG); rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; @@ -302,10 +313,17 @@ void __init bcm63xx_cpu_init(void) chipid_reg = BCM_6345_PERF_BASE; break; case CPU_BMIPS4350: - if ((read_c0_prid() & 0xf0) == 0x10) + switch ((read_c0_prid() & 0xff)) { + case 0x04: + chipid_reg = BCM_3368_PERF_BASE; + break; + case 0x10: chipid_reg = BCM_6345_PERF_BASE; - else + break; + default: chipid_reg = BCM_6368_PERF_BASE; + break; + } break; } @@ -322,6 +340,10 @@ void __init bcm63xx_cpu_init(void) bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; switch (bcm63xx_cpu_id) { + case BCM3368_CPU_ID: + bcm63xx_regs_base = bcm3368_regs_base; + bcm63xx_irqs = bcm3368_irqs; + break; case BCM6328_CPU_ID: bcm63xx_regs_base = bcm6328_regs_base; bcm63xx_irqs = bcm6328_irqs; diff --git a/arch/mips/bcm63xx/dev-flash.c b/arch/mips/bcm63xx/dev-flash.c index 588d1ec622e..172dd839717 100644 --- a/arch/mips/bcm63xx/dev-flash.c +++ b/arch/mips/bcm63xx/dev-flash.c @@ -71,6 +71,7 @@ static int __init bcm63xx_detect_flash_type(void) case BCM6348_CPU_ID: /* no way to auto detect so assume parallel */ return BCM63XX_FLASH_TYPE_PARALLEL; + case BCM3368_CPU_ID: case BCM6358_CPU_ID: val = bcm_gpio_readl(GPIO_STRAPBUS_REG); if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index 3065bb61820..d12daed749b 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c @@ -37,7 +37,8 @@ static __init void bcm63xx_spi_regs_init(void) { if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) bcm63xx_regs_spi = bcm6348_regs_spi; - if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) + if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || + BCMCPU_IS_6362() || BCMCPU_IS_6368()) bcm63xx_regs_spi = bcm6358_regs_spi; } #else @@ -87,7 +88,8 @@ int __init bcm63xx_spi_register(void) spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH; } - if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) { + if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() || + BCMCPU_IS_6368()) { spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c index d6e42c60832..3bc7f3bfc9a 100644 --- a/arch/mips/bcm63xx/dev-uart.c +++ b/arch/mips/bcm63xx/dev-uart.c @@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigned int id) if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) return -ENODEV; - if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())) + if (id == 1 && (!BCMCPU_IS_3368() && !BCMCPU_IS_6358() && + !BCMCPU_IS_6368())) return -ENODEV; if (id == 0) { diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index c0ab3887f42..1525f8a3841 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c @@ -27,6 +27,17 @@ 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 @@ -140,6 +151,13 @@ static void bcm63xx_init_irq(void) 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; @@ -294,6 +312,10 @@ asmlinkage void plat_irq_dispatch(void) if (cause & CAUSEF_IP7) do_IRQ(7); + if (cause & CAUSEF_IP0) + do_IRQ(0); + if (cause & CAUSEF_IP1) + do_IRQ(1); if (cause & CAUSEF_IP2) dispatch_internal(); if (!is_ext_irq_cascaded) { @@ -475,6 +497,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq); break; + case BCM3368_CPU_ID: case BCM6328_CPU_ID: case BCM6338_CPU_ID: case BCM6345_CPU_ID: diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index a4b8864f930..e652e578a67 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -42,6 +42,7 @@ void __init bcm63xx_nvram_init(void *addr) { unsigned int check_len; u32 crc, expected_crc; + u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; /* extract nvram data */ memcpy(&nvram, addr, sizeof(nvram)); @@ -62,6 +63,15 @@ void __init bcm63xx_nvram_init(void *addr) if (crc != expected_crc) pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", expected_crc, crc); + + /* Cable modems have a different NVRAM which is embedded in the eCos + * firmware and not easily extractible, give at least a MAC address + * pool. + */ + if (BCMCPU_IS_3368()) { + memcpy(nvram.mac_addr_base, hcs_mac_addr, ETH_ALEN); + nvram.mac_addr_count = 2; + } } u8 *bcm63xx_nvram_get_name(void) diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index fd698087fbf..8ac4e095e68 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c @@ -8,7 +8,11 @@ #include <linux/init.h> #include <linux/bootmem.h> +#include <linux/smp.h> #include <asm/bootinfo.h> +#include <asm/bmips.h> +#include <asm/smp-ops.h> +#include <asm/mipsregs.h> #include <bcm63xx_board.h> #include <bcm63xx_cpu.h> #include <bcm63xx_io.h> @@ -26,7 +30,9 @@ void __init prom_init(void) bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); /* disable all hardware blocks clock for now */ - if (BCMCPU_IS_6328()) + if (BCMCPU_IS_3368()) + mask = CKCTL_3368_ALL_SAFE_EN; + else if (BCMCPU_IS_6328()) mask = CKCTL_6328_ALL_SAFE_EN; else if (BCMCPU_IS_6338()) mask = CKCTL_6338_ALL_SAFE_EN; @@ -52,6 +58,47 @@ void __init prom_init(void) /* do low level board init */ board_prom_init(); + + if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) { + /* set up SMP */ + register_smp_ops(&bmips_smp_ops); + + /* + * BCM6328 might not have its second CPU enabled, while BCM6358 + * needs special handling for its shared TLB, so disable SMP + * for now. + */ + if (BCMCPU_IS_6328()) { + reg = bcm_readl(BCM_6328_OTP_BASE + + OTP_USER_BITS_6328_REG(3)); + + if (reg & OTP_6328_REG3_TP1_DISABLED) + bmips_smp_enabled = 0; + } else if (BCMCPU_IS_6358()) { + bmips_smp_enabled = 0; + } + + if (!bmips_smp_enabled) + return; + + /* + * The bootloader has set up the CPU1 reset vector at + * 0xa000_0200. + * This conflicts with the special interrupt vector (IV). + * The bootloader has also set up CPU1 to respond to the wrong + * IPI interrupt. + * Here we will start up CPU1 in the background and ask it to + * reconfigure itself then go back to sleep. + */ + memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20); + __sync(); + set_c0_cause(C_SW0); + cpumask_set_cpu(1, &bmips_booted_mask); + + /* + * FIXME: we really should have some sort of hazard barrier here + */ + } } void __init prom_free_prom_memory(void) diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c index 317931c6cf5..acbeb1fe7c5 100644 --- a/arch/mips/bcm63xx/reset.c +++ b/arch/mips/bcm63xx/reset.c @@ -30,6 +30,19 @@ [BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \ [BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT, +#define BCM3368_RESET_SPI SOFTRESET_3368_SPI_MASK +#define BCM3368_RESET_ENET SOFTRESET_3368_ENET_MASK +#define BCM3368_RESET_USBH 0 +#define BCM3368_RESET_USBD SOFTRESET_3368_USBS_MASK +#define BCM3368_RESET_DSL 0 +#define BCM3368_RESET_SAR 0 +#define BCM3368_RESET_EPHY SOFTRESET_3368_EPHY_MASK +#define BCM3368_RESET_ENETSW 0 +#define BCM3368_RESET_PCM SOFTRESET_3368_PCM_MASK +#define BCM3368_RESET_MPI SOFTRESET_3368_MPI_MASK +#define BCM3368_RESET_PCIE 0 +#define BCM3368_RESET_PCIE_EXT 0 + #define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK #define BCM6328_RESET_ENET 0 #define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK @@ -117,6 +130,10 @@ /* * core reset bits */ +static const u32 bcm3368_reset_bits[] = { + __GEN_RESET_BITS_TABLE(3368) +}; + static const u32 bcm6328_reset_bits[] = { __GEN_RESET_BITS_TABLE(6328) }; @@ -146,7 +163,10 @@ static int reset_reg; static int __init bcm63xx_reset_bits_init(void) { - if (BCMCPU_IS_6328()) { + if (BCMCPU_IS_3368()) { + reset_reg = PERF_SOFTRESET_6358_REG; + bcm63xx_reset_bits = bcm3368_reset_bits; + } else if (BCMCPU_IS_6328()) { reset_reg = PERF_SOFTRESET_6328_REG; bcm63xx_reset_bits = bcm6328_reset_bits; } else if (BCMCPU_IS_6338()) { @@ -170,6 +190,13 @@ static int __init bcm63xx_reset_bits_init(void) } #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) diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index 24a24445db6..6660c7ddf87 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void) /* mask and clear all external irq */ switch (bcm63xx_get_cpu_id()) { + case BCM3368_CPU_ID: + perf_regs[0] = PERF_EXTIRQ_CFG_REG_3368; + break; case BCM6328_CPU_ID: perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328; break; diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index bbaa1d4beb6..bb1dbf4abb9 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -18,6 +18,8 @@ BOOT_HEAP_SIZE := 0x400000 # Disable Function Tracer KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//") +KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) + KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index 1c7b739b6a1..c01d343ce6a 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c @@ -23,23 +23,39 @@ #define PORT(offset) (UART0_BASE + (4 * offset)) #endif +#ifdef CONFIG_CPU_XLR +#define UART0_BASE 0x1EF14000 +#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset)) +#define IOTYPE unsigned int +#endif + +#ifdef CONFIG_CPU_XLP +#define UART0_BASE 0x18030100 +#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset)) +#define IOTYPE unsigned int +#endif + +#ifndef IOTYPE +#define IOTYPE char +#endif + #ifndef PORT #error please define the serial port address for your own machine #endif static inline unsigned int serial_in(int offset) { - return *((char *)PORT(offset)); + return *((volatile IOTYPE *)PORT(offset)) & 0xFF; } static inline void serial_out(int offset, int value) { - *((char *)PORT(offset)) = value; + *((volatile IOTYPE *)PORT(offset)) = value & 0xFF; } void putc(char c) { - int timeout = 1024; + int timeout = 1000000; while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0)) ; diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index 75a6df7fd26..227705d9d5a 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig @@ -10,6 +10,10 @@ config CAVIUM_CN63XXP1 non-CN63XXP1 hardware, so it is recommended to select "n" unless it is known the workarounds are needed. +endif # CPU_CAVIUM_OCTEON + +if CAVIUM_OCTEON_SOC + config CAVIUM_OCTEON_2ND_KERNEL bool "Build the kernel to be used as a 2nd kernel on the same chip" default "n" @@ -19,17 +23,6 @@ config CAVIUM_OCTEON_2ND_KERNEL with this option to be run at the same time as one built without this option. -config CAVIUM_OCTEON_HW_FIX_UNALIGNED - bool "Enable hardware fixups of unaligned loads and stores" - default "y" - help - Configure the Octeon hardware to automatically fix unaligned loads - and stores. Normally unaligned accesses are fixed using a kernel - exception handler. This option enables the hardware automatic fixups, - which requires only an extra 3 cycles. Disable this option if you - are running code that relies on address exceptions on unaligned - accesses. - config CAVIUM_OCTEON_CVMSEG_SIZE int "Number of L1 cache lines reserved for CVMSEG memory" range 0 54 @@ -103,4 +96,4 @@ config OCTEON_ILM To compile this driver as a module, choose M here. The module will be called octeon-ilm -endif # CPU_CAVIUM_OCTEON +endif # CAVIUM_OCTEON_SOC diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index 3595affb977..4e952043c92 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile @@ -12,11 +12,12 @@ CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt -obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o -obj-y += dma-octeon.o flash_setup.o +obj-y := cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o +obj-y += dma-octeon.o obj-y += octeon-memcpy.o obj-y += executive/ +obj-$(CONFIG_MTD) += flash_setup.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o diff --git a/arch/mips/cavium-octeon/Platform b/arch/mips/cavium-octeon/Platform index 1e43ccf1a79..8a301cb12d6 100644 --- a/arch/mips/cavium-octeon/Platform +++ b/arch/mips/cavium-octeon/Platform @@ -1,11 +1,11 @@ # # Cavium Octeon # -platform-$(CONFIG_CPU_CAVIUM_OCTEON) += cavium-octeon/ -cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += \ +platform-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon/ +cflags-$(CONFIG_CAVIUM_OCTEON_SOC) += \ -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL -load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000 +load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff84100000 else -load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000 +load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff81100000 endif diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index 7c649778189..0a1283ce47f 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(int ipd_port) return ipd_port - 16 + 4; else return -1; + case CVMX_BOARD_TYPE_UBNT_E100: + if (ipd_port >= 0 && ipd_port <= 2) + return 7 - ipd_port; + else + return -1; } /* Some unknown board. Somebody forgot to update this function... */ @@ -706,6 +711,14 @@ int __cvmx_helper_board_hardware_enable(int interface) } } } + } else if (cvmx_sysinfo_get()->board_type == + CVMX_BOARD_TYPE_UBNT_E100) { + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0); + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10); + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0); + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10); + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0); + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10); } return 0; } diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index 389512e2abd..7b746e7bf7a 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -490,8 +490,15 @@ int __init octeon_prune_device_tree(void) if (alias_prop) { uart = fdt_path_offset(initial_boot_params, alias_prop); - if (uart_mask & (1 << i)) + if (uart_mask & (1 << i)) { + __be32 f; + + f = cpu_to_be32(octeon_get_io_clock_rate()); + fdt_setprop_inplace(initial_boot_params, + uart, "clock-frequency", + &f, sizeof(f)); continue; + } pr_debug("Deleting uart%d\n", i); fdt_nop_node(initial_boot_params, uart); fdt_nop_property(initial_boot_params, aliases, diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c deleted file mode 100644 index f393f65f392..00000000000 --- a/arch/mips/cavium-octeon/serial.c +++ /dev/null @@ -1,109 +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) 2004-2007 Cavium Networks - */ -#include <linux/console.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/serial.h> -#include <linux/serial_8250.h> -#include <linux/serial_reg.h> -#include <linux/tty.h> -#include <linux/irq.h> - -#include <asm/time.h> - -#include <asm/octeon/octeon.h> - -#define DEBUG_UART 1 - -unsigned int octeon_serial_in(struct uart_port *up, int offset) -{ - int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); - if (offset == UART_IIR && (rv & 0xf) == 7) { - /* Busy interrupt, read the USR (39) and try again. */ - cvmx_read_csr((uint64_t)(up->membase + (39 << 3))); - rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); - } - return rv; -} - -void octeon_serial_out(struct uart_port *up, int offset, int value) -{ - /* - * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits - * working. - */ - if (offset == UART_LCR) - value &= 0x9f; - cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value); -} - -static int octeon_serial_probe(struct platform_device *pdev) -{ - int irq, res; - struct resource *res_mem; - struct uart_8250_port up; - - /* All adaptors have an irq. */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - memset(&up, 0, sizeof(up)); - - up.port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; - up.port.type = PORT_OCTEON; - up.port.iotype = UPIO_MEM; - up.port.regshift = 3; - up.port.dev = &pdev->dev; - - if (octeon_is_simulation()) - /* Make simulator output fast*/ - up.port.uartclk = 115200 * 16; - else - up.port.uartclk = octeon_get_io_clock_rate(); - - up.port.serial_in = octeon_serial_in; - up.port.serial_out = octeon_serial_out; - up.port.irq = irq; - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "found no memory resource\n"); - return -ENXIO; - } - up.port.mapbase = res_mem->start; - up.port.membase = ioremap(res_mem->start, resource_size(res_mem)); - - res = serial8250_register_8250_port(&up); - - return res >= 0 ? 0 : res; -} - -static struct of_device_id octeon_serial_match[] = { - { - .compatible = "cavium,octeon-3860-uart", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, octeon_serial_match); - -static struct platform_driver octeon_serial_driver = { - .probe = octeon_serial_probe, - .driver = { - .owner = THIS_MODULE, - .name = "octeon_serial", - .of_match_table = octeon_serial_match, - }, -}; - -static int __init octeon_serial_init(void) -{ - return platform_driver_register(&octeon_serial_driver); -} -late_initcall(octeon_serial_init); diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 01b1b3f94fe..48b08eb9d9e 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -7,6 +7,7 @@ * Copyright (C) 2008, 2009 Wind River Systems * written by Ralf Baechle <ralf@linux-mips.org> */ +#include <linux/compiler.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/console.h> @@ -40,12 +41,6 @@ #include <asm/octeon/pci-octeon.h> #include <asm/octeon/cvmx-mio-defs.h> -#ifdef CONFIG_CAVIUM_DECODE_RSL -extern void cvmx_interrupt_rsl_decode(void); -extern int __cvmx_interrupt_ecc_report_single_bit_errors; -extern void cvmx_interrupt_rsl_enable(void); -#endif - extern struct plat_smp_ops octeon_smp_ops; #ifdef CONFIG_PCI @@ -463,18 +458,6 @@ static void octeon_halt(void) } /** - * Handle all the error condition interrupts that might occur. - * - */ -#ifdef CONFIG_CAVIUM_DECODE_RSL -static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id) -{ - cvmx_interrupt_rsl_decode(); - return IRQ_HANDLED; -} -#endif - -/** * Return a string representing the system type * * Returns @@ -712,7 +695,7 @@ void __init prom_init(void) if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) { pr_info("Skipping L2 locking due to reduced L2 cache size\n"); } else { - uint32_t ebase = read_c0_ebase() & 0x3ffff000; + uint32_t __maybe_unused ebase = read_c0_ebase() & 0x3ffff000; #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB /* TLB refill */ cvmx_l2c_lock_mem_region(ebase, 0x100); @@ -996,7 +979,7 @@ void __init plat_mem_setup(void) cvmx_bootmem_unlock(); /* Add the memory region for the kernel. */ kernel_start = (unsigned long) _text; - kernel_size = ALIGN(_end - _text, 0x100000); + kernel_size = _end - _text; /* Adjust for physical offset. */ kernel_start &= ~0xffffffff80000000ULL; @@ -1064,15 +1047,6 @@ void prom_free_prom_memory(void) panic("Core-14449 WAR not in place (%04x).\n" "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn); } -#ifdef CONFIG_CAVIUM_DECODE_RSL - cvmx_interrupt_rsl_enable(); - - /* Add an interrupt handler for general failures. */ - if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED, - "RML/RSL", octeon_rlm_interrupt)) { - panic("Unable to request_irq(OCTEON_IRQ_RML)"); - } -#endif } int octeon_prune_device_tree(void); diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index 014ba4bbba7..dace58268ce 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -1,13 +1,11 @@ -CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y +CONFIG_CAVIUM_OCTEON_SOC=y CONFIG_CAVIUM_CN63XXP1=y CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2 -CONFIG_SPARSEMEM_MANUAL=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_SMP=y CONFIG_NR_CPUS=32 CONFIG_HZ_100=y CONFIG_PREEMPT=y -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y # CONFIG_MTD_OF_PARTS is not set -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -114,6 +111,7 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_DW=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_OCTEON=y diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig deleted file mode 100644 index 44a451be359..00000000000 --- a/arch/mips/configs/wrppmc_defconfig +++ /dev/null @@ -1,97 +0,0 @@ -CONFIG_WR_PPMC=y -CONFIG_HZ_1000=y -CONFIG_EXPERIMENTAL=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EXPERT=y -CONFIG_KALLSYMS_EXTRA_PASS=y -# CONFIG_EPOLL is not set -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_PCI=y -CONFIG_HOTPLUG_PCI=y -CONFIG_BINFMT_MISC=y -CONFIG_PM=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_MIGRATE=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_IP_MROUTE=y -CONFIG_ARPD=y -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_TCP_MD5SIG=y -# CONFIG_IPV6 is not set -CONFIG_NETWORK_SECMARK=y -CONFIG_FW_LOADER=m -CONFIG_BLK_DEV_RAM=y -CONFIG_SGI_IOC4=m -CONFIG_NETDEVICES=y -CONFIG_PHYLIB=y -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -CONFIG_NET_ETHERNET=y -CONFIG_NET_PCI=y -CONFIG_E100=y -CONFIG_QLA3XXX=m -CONFIG_CHELSIO_T3=m -CONFIG_NETXEN_NIC=m -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -# CONFIG_HW_RANDOM is not set -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_DLM=m -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttyS0,115200n8" -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_LIBCRC32C=y diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile index 9eb2f9c036a..3d5d2c56de8 100644 --- a/arch/mips/dec/Makefile +++ b/arch/mips/dec/Makefile @@ -5,6 +5,5 @@ obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \ kn02-irq.o kn02xa-berr.o reset.o setup.o time.o -obj-$(CONFIG_PROM_CONSOLE) += promcon.o obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_CPU_HAS_WB) += wbflush.o diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c deleted file mode 100644 index c239c25b79f..00000000000 --- a/arch/mips/dec/promcon.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Wrap-around code for a console using the - * DECstation PROM io-routines. - * - * Copyright (c) 1998 Harald Koerfgen - */ - -#include <linux/tty.h> -#include <linux/ptrace.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/fs.h> - -#include <asm/dec/prom.h> - -static void prom_console_write(struct console *co, const char *s, - unsigned count) -{ - unsigned i; - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - if (*s == 10) - prom_printf("%c", 13); - prom_printf("%c", *s++); - } -} - -static int __init prom_console_setup(struct console *co, char *options) -{ - return 0; -} - -static struct console sercons = { - .name = "ttyS", - .write = prom_console_write, - .setup = prom_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ - -static int __init prom_console_init(void) -{ - register_console(&sercons); - - return 0; -} -console_initcall(prom_console_init); diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c index d06dc5a6b8d..cf84f01931c 100644 --- a/arch/mips/fw/cfe/cfe_api.c +++ b/arch/mips/fw/cfe/cfe_api.c @@ -406,12 +406,12 @@ int cfe_setenv(char *name, char *val) return xiocb.xiocb_status; } -int cfe_write(int handle, unsigned char *buffer, int length) +int cfe_write(int handle, const char *buffer, int length) { return cfe_writeblk(handle, 0, buffer, length); } -int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length) +int cfe_writeblk(int handle, s64 offset, const char *buffer, int length) { struct cfe_xiocb xiocb; diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h index 3532e2c5f09..c1516cc0285 100644 --- a/arch/mips/include/asm/cop2.h +++ b/arch/mips/include/asm/cop2.h @@ -11,6 +11,35 @@ #include <linux/notifier.h> +#if defined(CONFIG_CPU_CAVIUM_OCTEON) + +extern void octeon_cop2_save(struct octeon_cop2_state *); +extern void octeon_cop2_restore(struct octeon_cop2_state *); + +#define cop2_save(r) octeon_cop2_save(r) +#define cop2_restore(r) octeon_cop2_restore(r) + +#define cop2_present 1 +#define cop2_lazy_restore 1 + +#elif defined(CONFIG_CPU_XLP) + +extern void nlm_cop2_save(struct nlm_cop2_state *); +extern void nlm_cop2_restore(struct nlm_cop2_state *); +#define cop2_save(r) nlm_cop2_save(r) +#define cop2_restore(r) nlm_cop2_restore(r) + +#define cop2_present 1 +#define cop2_lazy_restore 0 + +#else + +#define cop2_present 0 +#define cop2_lazy_restore 0 +#define cop2_save(r) +#define cop2_restore(r) +#endif + enum cu2_ops { CU2_EXCEPTION, CU2_LWC2_OP, diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index e5ec8fcd8af..1dc086087a7 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -24,6 +24,16 @@ #ifndef cpu_has_tlb #define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB) #endif + +/* + * For the moment we don't consider R6000 and R8000 so we can assume that + * anything that doesn't support R4000-style exceptions and interrupts is + * R3000-like. Users should still treat these two macro definitions as + * opaque. + */ +#ifndef cpu_has_3kex +#define cpu_has_3kex (!cpu_has_4kex) +#endif #ifndef cpu_has_4kex #define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX) #endif @@ -87,19 +97,23 @@ #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) #endif #ifndef cpu_has_mdmx -#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX) +#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX) #endif #ifndef cpu_has_mips3d -#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D) +#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D) #endif #ifndef cpu_has_smartmips -#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS) +#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS) #endif #ifndef cpu_has_rixi #define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) #endif #ifndef cpu_has_mmips -#define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS) +# ifdef CONFIG_SYS_SUPPORTS_MICROMIPS +# define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS) +# else +# define cpu_has_mmips 0 +# endif #endif #ifndef cpu_has_vtag_icache #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) @@ -111,7 +125,7 @@ #define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC) #endif #ifndef cpu_has_pindexed_dcache -#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) +#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) #endif #ifndef cpu_has_local_ebase #define cpu_has_local_ebase 1 @@ -136,7 +150,6 @@ #endif #endif -# define cpu_has_mips_1 (cpu_data[0].isa_level & MIPS_CPU_ISA_I) #ifndef cpu_has_mips_2 # define cpu_has_mips_2 (cpu_data[0].isa_level & MIPS_CPU_ISA_II) #endif @@ -149,18 +162,18 @@ #ifndef cpu_has_mips_5 # define cpu_has_mips_5 (cpu_data[0].isa_level & MIPS_CPU_ISA_V) #endif -# ifndef cpu_has_mips32r1 +#ifndef cpu_has_mips32r1 # define cpu_has_mips32r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1) -# endif -# ifndef cpu_has_mips32r2 +#endif +#ifndef cpu_has_mips32r2 # define cpu_has_mips32r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2) -# endif -# ifndef cpu_has_mips64r1 +#endif +#ifndef cpu_has_mips64r1 # define cpu_has_mips64r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1) -# endif -# ifndef cpu_has_mips64r2 +#endif +#ifndef cpu_has_mips64r2 # define cpu_has_mips64r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2) -# endif +#endif /* * Shortcuts ... @@ -182,9 +195,9 @@ * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ. */ -# ifndef cpu_has_clo_clz -# define cpu_has_clo_clz cpu_has_mips_r -# endif +#ifndef cpu_has_clo_clz +#define cpu_has_clo_clz cpu_has_mips_r +#endif #ifndef cpu_has_dsp #define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP) @@ -210,7 +223,7 @@ # define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) # endif # ifndef cpu_has_64bit_zero_reg -# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) +# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) # endif # ifndef cpu_has_64bit_gp_regs # define cpu_has_64bit_gp_regs 0 diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index dd86ab20548..632bbe5a79e 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -282,18 +282,17 @@ enum cpu_type_enum { * ISA Level encodings * */ -#define MIPS_CPU_ISA_I 0x00000001 -#define MIPS_CPU_ISA_II 0x00000002 -#define MIPS_CPU_ISA_III 0x00000004 -#define MIPS_CPU_ISA_IV 0x00000008 -#define MIPS_CPU_ISA_V 0x00000010 -#define MIPS_CPU_ISA_M32R1 0x00000020 -#define MIPS_CPU_ISA_M32R2 0x00000040 -#define MIPS_CPU_ISA_M64R1 0x00000080 -#define MIPS_CPU_ISA_M64R2 0x00000100 - -#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ - MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2) +#define MIPS_CPU_ISA_II 0x00000001 +#define MIPS_CPU_ISA_III 0x00000002 +#define MIPS_CPU_ISA_IV 0x00000004 +#define MIPS_CPU_ISA_V 0x00000008 +#define MIPS_CPU_ISA_M32R1 0x00000010 +#define MIPS_CPU_ISA_M32R2 0x00000020 +#define MIPS_CPU_ISA_M64R1 0x00000040 +#define MIPS_CPU_ISA_M64R2 0x00000080 + +#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_II | MIPS_CPU_ISA_M32R1 | \ + MIPS_CPU_ISA_M32R2) #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \ MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) diff --git a/arch/mips/include/asm/fw/cfe/cfe_api.h b/arch/mips/include/asm/fw/cfe/cfe_api.h index 17347551a1b..a0ea69e91e2 100644 --- a/arch/mips/include/asm/fw/cfe/cfe_api.h +++ b/arch/mips/include/asm/fw/cfe/cfe_api.h @@ -115,8 +115,8 @@ int cfe_read(int handle, unsigned char *buffer, int length); int cfe_readblk(int handle, int64_t offset, unsigned char *buffer, int length); int cfe_setenv(char *name, char *val); -int cfe_write(int handle, unsigned char *buffer, int length); -int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer, +int cfe_write(int handle, const char *buffer, int length); +int cfe_writeblk(int handle, int64_t offset, const char *buffer, int length); #endif /* CFE_API_H */ diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 7153b32de18..b2e3e93dd7d 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -347,7 +347,7 @@ struct gic_shared_intr_map { #define GIC_CPU_INT2 2 /* . */ #define GIC_CPU_INT3 3 /* . */ #define GIC_CPU_INT4 4 /* . */ -#define GIC_CPU_INT5 5 /* Core Interrupt 5 */ +#define GIC_CPU_INT5 5 /* Core Interrupt 7 */ /* Local GIC interrupts. */ #define GIC_INT_TMR (GIC_CPU_INT5) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index b7e59853fd3..3321dd5a887 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -170,6 +170,11 @@ static inline void * isa_bus_to_virt(unsigned long address) extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); extern void __iounmap(const volatile void __iomem *addr); +#ifndef CONFIG_PCI +struct pci_dev; +static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} +#endif + static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, unsigned long flags) { @@ -449,6 +454,11 @@ __BUILDIO(q, u64) #define readl_relaxed readl #define readq_relaxed readq +#define writeb_relaxed writeb +#define writew_relaxed writew +#define writel_relaxed writel +#define writeq_relaxed writeq + #define readb_be(addr) \ __raw_readb((__force unsigned *)(addr)) #define readw_be(addr) \ diff --git a/arch/mips/include/asm/kspd.h b/arch/mips/include/asm/kspd.h deleted file mode 100644 index ec6832950ac..00000000000 --- a/arch/mips/include/asm/kspd.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - */ - -#ifndef _ASM_KSPD_H -#define _ASM_KSPD_H - -struct kspd_notifications { - void (*kspd_sp_exit)(int sp_id); - - struct list_head list; -}; - -static inline void kspd_notify(struct kspd_notifications *notify) -{ -} - -#endif diff --git a/arch/mips/include/asm/mach-ar7/spaces.h b/arch/mips/include/asm/mach-ar7/spaces.h index ac28f273449..660ab64c0fc 100644 --- a/arch/mips/include/asm/mach-ar7/spaces.h +++ b/arch/mips/include/asm/mach-ar7/spaces.h @@ -14,8 +14,11 @@ * This handles the memory map. * We handle pages at KSEG0 for kernels with 32 bit address space. */ -#define PAGE_OFFSET 0x94000000UL -#define PHYS_OFFSET 0x14000000UL +#define PAGE_OFFSET _AC(0x94000000, UL) +#define PHYS_OFFSET _AC(0x14000000, UL) + +#define UNCAC_BASE _AC(0xb4000000, UL) /* 0xa0000000 + PHYS_OFFSET */ +#define IO_BASE UNCAC_BASE #include <asm/mach-generic/spaces.h> diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index e6e65dc7d50..19f9134bfe2 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h @@ -9,6 +9,7 @@ * compile time if only one CPU support is enabled (idea stolen from * arm mach-types) */ +#define BCM3368_CPU_ID 0x3368 #define BCM6328_CPU_ID 0x6328 #define BCM6338_CPU_ID 0x6338 #define BCM6345_CPU_ID 0x6345 @@ -22,6 +23,19 @@ u16 __bcm63xx_get_cpu_id(void); u8 bcm63xx_get_cpu_rev(void); unsigned int bcm63xx_get_cpu_freq(void); +#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) +#endif + #ifdef CONFIG_BCM63XX_CPU_6328 # ifdef bcm63xx_get_cpu_id # undef bcm63xx_get_cpu_id @@ -194,6 +208,53 @@ enum bcm63xx_regs_set { #define RSET_RNG_SIZE 20 /* + * 3368 register sets base address + */ +#define BCM_3368_DSL_LMEM_BASE (0xdeadbeef) +#define BCM_3368_PERF_BASE (0xfff8c000) +#define BCM_3368_TIMER_BASE (0xfff8c040) +#define BCM_3368_WDT_BASE (0xfff8c080) +#define BCM_3368_UART0_BASE (0xfff8c100) +#define BCM_3368_UART1_BASE (0xfff8c120) +#define BCM_3368_GPIO_BASE (0xfff8c080) +#define BCM_3368_SPI_BASE (0xfff8c800) +#define BCM_3368_HSSPI_BASE (0xdeadbeef) +#define BCM_3368_UDC0_BASE (0xdeadbeef) +#define BCM_3368_USBDMA_BASE (0xdeadbeef) +#define BCM_3368_OHCI0_BASE (0xdeadbeef) +#define BCM_3368_OHCI_PRIV_BASE (0xdeadbeef) +#define BCM_3368_USBH_PRIV_BASE (0xdeadbeef) +#define BCM_3368_USBD_BASE (0xdeadbeef) +#define BCM_3368_MPI_BASE (0xfff80000) +#define BCM_3368_PCMCIA_BASE (0xfff80054) +#define BCM_3368_PCIE_BASE (0xdeadbeef) +#define BCM_3368_SDRAM_REGS_BASE (0xdeadbeef) +#define BCM_3368_DSL_BASE (0xdeadbeef) +#define BCM_3368_UBUS_BASE (0xdeadbeef) +#define BCM_3368_ENET0_BASE (0xfff98000) +#define BCM_3368_ENET1_BASE (0xfff98800) +#define BCM_3368_ENETDMA_BASE (0xfff99800) +#define BCM_3368_ENETDMAC_BASE (0xfff99900) +#define BCM_3368_ENETDMAS_BASE (0xfff99a00) +#define BCM_3368_ENETSW_BASE (0xdeadbeef) +#define BCM_3368_EHCI0_BASE (0xdeadbeef) +#define BCM_3368_SDRAM_BASE (0xdeadbeef) +#define BCM_3368_MEMC_BASE (0xfff84000) +#define BCM_3368_DDR_BASE (0xdeadbeef) +#define BCM_3368_M2M_BASE (0xdeadbeef) +#define BCM_3368_ATM_BASE (0xdeadbeef) +#define BCM_3368_XTM_BASE (0xdeadbeef) +#define BCM_3368_XTMDMA_BASE (0xdeadbeef) +#define BCM_3368_XTMDMAC_BASE (0xdeadbeef) +#define BCM_3368_XTMDMAS_BASE (0xdeadbeef) +#define BCM_3368_PCM_BASE (0xfff9c200) +#define BCM_3368_PCMDMA_BASE (0xdeadbeef) +#define BCM_3368_PCMDMAC_BASE (0xdeadbeef) +#define BCM_3368_PCMDMAS_BASE (0xdeadbeef) +#define BCM_3368_RNG_BASE (0xdeadbeef) +#define BCM_3368_MISC_BASE (0xdeadbeef) + +/* * 6328 register sets base address */ #define BCM_6328_DSL_LMEM_BASE (0xdeadbeef) @@ -238,6 +299,8 @@ enum bcm63xx_regs_set { #define BCM_6328_PCMDMAS_BASE (0xdeadbeef) #define BCM_6328_RNG_BASE (0xdeadbeef) #define BCM_6328_MISC_BASE (0xb0001800) +#define BCM_6328_OTP_BASE (0xb0000600) + /* * 6338 register sets base address */ @@ -623,6 +686,9 @@ 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 @@ -690,6 +756,52 @@ enum bcm63xx_irq { }; /* + * 3368 irqs + */ +#define BCM_3368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +#define BCM_3368_SPI_IRQ (IRQ_INTERNAL_BASE + 1) +#define BCM_3368_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_3368_UART1_IRQ (IRQ_INTERNAL_BASE + 3) +#define BCM_3368_DSL_IRQ 0 +#define BCM_3368_UDC0_IRQ 0 +#define BCM_3368_OHCI0_IRQ 0 +#define BCM_3368_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) +#define BCM_3368_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) +#define BCM_3368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) +#define BCM_3368_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15) +#define BCM_3368_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16) +#define BCM_3368_HSSPI_IRQ 0 +#define BCM_3368_EHCI0_IRQ 0 +#define BCM_3368_USBD_IRQ 0 +#define BCM_3368_USBD_RXDMA0_IRQ 0 +#define BCM_3368_USBD_TXDMA0_IRQ 0 +#define BCM_3368_USBD_RXDMA1_IRQ 0 +#define BCM_3368_USBD_TXDMA1_IRQ 0 +#define BCM_3368_USBD_RXDMA2_IRQ 0 +#define BCM_3368_USBD_TXDMA2_IRQ 0 +#define BCM_3368_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17) +#define BCM_3368_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 18) +#define BCM_3368_PCI_IRQ (IRQ_INTERNAL_BASE + 31) +#define BCM_3368_PCMCIA_IRQ 0 +#define BCM_3368_ATM_IRQ 0 +#define BCM_3368_ENETSW_RXDMA0_IRQ 0 +#define BCM_3368_ENETSW_RXDMA1_IRQ 0 +#define BCM_3368_ENETSW_RXDMA2_IRQ 0 +#define BCM_3368_ENETSW_RXDMA3_IRQ 0 +#define BCM_3368_ENETSW_TXDMA0_IRQ 0 +#define BCM_3368_ENETSW_TXDMA1_IRQ 0 +#define BCM_3368_ENETSW_TXDMA2_IRQ 0 +#define BCM_3368_ENETSW_TXDMA3_IRQ 0 +#define BCM_3368_XTM_IRQ 0 +#define BCM_3368_XTM_DMA0_IRQ 0 + +#define BCM_3368_EXT_IRQ0 (IRQ_INTERNAL_BASE + 25) +#define BCM_3368_EXT_IRQ1 (IRQ_INTERNAL_BASE + 26) +#define BCM_3368_EXT_IRQ2 (IRQ_INTERNAL_BASE + 27) +#define BCM_3368_EXT_IRQ3 (IRQ_INTERNAL_BASE + 28) + + +/* * 6328 irqs */ #define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 35baa1a60a6..565ff36a111 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h @@ -11,6 +11,7 @@ static inline unsigned long bcm63xx_gpio_count(void) switch (bcm63xx_get_cpu_id()) { case BCM6328_CPU_ID: return 32; + case BCM3368_CPU_ID: case BCM6358_CPU_ID: return 40; case BCM6338_CPU_ID: diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index eff7ca7d12b..9875db31d88 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -15,6 +15,39 @@ /* Clock Control register */ #define PERF_CKCTL_REG 0x4 +#define CKCTL_3368_MAC_EN (1 << 3) +#define CKCTL_3368_TC_EN (1 << 5) +#define CKCTL_3368_US_TOP_EN (1 << 6) +#define CKCTL_3368_DS_TOP_EN (1 << 7) +#define CKCTL_3368_APM_EN (1 << 8) +#define CKCTL_3368_SPI_EN (1 << 9) +#define CKCTL_3368_USBS_EN (1 << 10) +#define CKCTL_3368_BMU_EN (1 << 11) +#define CKCTL_3368_PCM_EN (1 << 12) +#define CKCTL_3368_NTP_EN (1 << 13) +#define CKCTL_3368_ACP_B_EN (1 << 14) +#define CKCTL_3368_ACP_A_EN (1 << 15) +#define CKCTL_3368_EMUSB_EN (1 << 17) +#define CKCTL_3368_ENET0_EN (1 << 18) +#define CKCTL_3368_ENET1_EN (1 << 19) +#define CKCTL_3368_USBU_EN (1 << 20) +#define CKCTL_3368_EPHY_EN (1 << 21) + +#define CKCTL_3368_ALL_SAFE_EN (CKCTL_3368_MAC_EN | \ + CKCTL_3368_TC_EN | \ + CKCTL_3368_US_TOP_EN | \ + CKCTL_3368_DS_TOP_EN | \ + CKCTL_3368_APM_EN | \ + CKCTL_3368_SPI_EN | \ + CKCTL_3368_USBS_EN | \ + CKCTL_3368_BMU_EN | \ + CKCTL_3368_PCM_EN | \ + CKCTL_3368_NTP_EN | \ + CKCTL_3368_ACP_B_EN | \ + CKCTL_3368_ACP_A_EN | \ + CKCTL_3368_EMUSB_EN | \ + CKCTL_3368_USBU_EN) + #define CKCTL_6328_PHYMIPS_EN (1 << 0) #define CKCTL_6328_ADSL_QPROC_EN (1 << 1) #define CKCTL_6328_ADSL_AFE_EN (1 << 2) @@ -181,6 +214,7 @@ #define SYS_PLL_SOFT_RESET 0x1 /* Interrupt Mask register */ +#define PERF_IRQMASK_3368_REG 0xc #define PERF_IRQMASK_6328_REG 0x20 #define PERF_IRQMASK_6338_REG 0xc #define PERF_IRQMASK_6345_REG 0xc @@ -190,6 +224,7 @@ #define PERF_IRQMASK_6368_REG 0x20 /* Interrupt Status register */ +#define PERF_IRQSTAT_3368_REG 0x10 #define PERF_IRQSTAT_6328_REG 0x28 #define PERF_IRQSTAT_6338_REG 0x10 #define PERF_IRQSTAT_6345_REG 0x10 @@ -199,6 +234,7 @@ #define PERF_IRQSTAT_6368_REG 0x28 /* External Interrupt Configuration register */ +#define PERF_EXTIRQ_CFG_REG_3368 0x14 #define PERF_EXTIRQ_CFG_REG_6328 0x18 #define PERF_EXTIRQ_CFG_REG_6338 0x14 #define PERF_EXTIRQ_CFG_REG_6345 0x14 @@ -236,6 +272,13 @@ #define PERF_SOFTRESET_6362_REG 0x10 #define PERF_SOFTRESET_6368_REG 0x10 +#define SOFTRESET_3368_SPI_MASK (1 << 0) +#define SOFTRESET_3368_ENET_MASK (1 << 2) +#define SOFTRESET_3368_MPI_MASK (1 << 3) +#define SOFTRESET_3368_EPHY_MASK (1 << 6) +#define SOFTRESET_3368_USBS_MASK (1 << 11) +#define SOFTRESET_3368_PCM_MASK (1 << 13) + #define SOFTRESET_6328_SPI_MASK (1 << 0) #define SOFTRESET_6328_EPHY_MASK (1 << 1) #define SOFTRESET_6328_SAR_MASK (1 << 2) @@ -1370,7 +1413,7 @@ #define SPI_6348_RX_DATA 0x80 #define SPI_6348_RX_DATA_SIZE 0x3f -/* BCM 6358/6262/6368 SPI core */ +/* BCM 3368/6358/6262/6368 SPI core */ #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ #define SPI_6358_MSG_CTL_WIDTH 16 #define SPI_6358_MSG_DATA 0x02 @@ -1511,4 +1554,11 @@ #define PCIE_DEVICE_OFFSET 0x8000 +/************************************************************************* + * _REG relative to RSET_OTP + *************************************************************************/ + +#define OTP_USER_BITS_6328_REG(i) (0x20 + (i) * 4) +#define OTP_6328_REG3_TP1_DISABLED BIT(9) + #endif /* BCM63XX_REGS_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index d9aee1a833f..b86a0efba66 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h @@ -47,6 +47,12 @@ struct board_info { /* GPIO LEDs */ struct gpio_led leds[5]; + + /* External PHY reset GPIO */ + unsigned int ephy_reset_gpio; + + /* External PHY reset GPIO flags from gpio.h */ + unsigned long ephy_reset_gpio_flags; }; #endif /* ! BOARD_BCM963XX_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index 94e3011ba7d..ff15e3b14e7 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h @@ -11,6 +11,10 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) static inline int is_bcm63xx_internal_registers(phys_t offset) { switch (bcm63xx_get_cpu_id()) { + case BCM3368_CPU_ID: + if (offset >= 0xfff80000) + return 1; + break; case BCM6338_CPU_ID: case BCM6345_CPU_ID: case BCM6348_CPU_ID: diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h index be8fb4240ce..47fb247f966 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h @@ -13,6 +13,8 @@ #ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H #define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H +#include <linux/bug.h> + struct device; extern void octeon_pci_dma_init(void); @@ -21,18 +23,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { BUG(); + return 0; } static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { BUG(); + return 0; } static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { BUG(); + return 0; } static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, @@ -44,6 +49,7 @@ static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, static inline int plat_dma_supported(struct device *dev, u64 mask) { BUG(); + return 0; } static inline void plat_extra_sync_for_device(struct device *dev) @@ -60,6 +66,7 @@ static inline int plat_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { BUG(); + return 0; } dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h index 1e7dbb19265..1668ee57acb 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h @@ -34,15 +34,10 @@ ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register -#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED # Disable unaligned load/store support but leave HW fixup enabled + # Needed for octeon specific memcpy or v0, v0, 0x5001 xor v0, v0, 0x1001 -#else - # Disable unaligned load/store and HW fixup support - or v0, v0, 0x5001 - xor v0, v0, 0x5001 -#endif # Read the processor ID register mfc0 v1, CP0_PRID_REG # Disable instruction prefetching (Octeon Pass1 errata) diff --git a/arch/mips/include/asm/mach-cavium-octeon/spaces.h b/arch/mips/include/asm/mach-cavium-octeon/spaces.h new file mode 100644 index 00000000000..daa91accf5a --- /dev/null +++ b/arch/mips/include/asm/mach-cavium-octeon/spaces.h @@ -0,0 +1,24 @@ +/* + * 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) 2012 Cavium, Inc. + */ +#ifndef _ASM_MACH_CAVIUM_OCTEON_SPACES_H +#define _ASM_MACH_CAVIUM_OCTEON_SPACES_H + +#include <linux/const.h> + +#ifdef CONFIG_64BIT +/* They are all the same and some OCTEON II cores cannot handle 0xa8.. */ +#define CAC_BASE _AC(0x8000000000000000, UL) +#define UNCAC_BASE _AC(0x8000000000000000, UL) +#define IO_BASE _AC(0x8000000000000000, UL) + + +#endif /* CONFIG_64BIT */ + +#include <asm/mach-generic/spaces.h> + +#endif /* _ASM_MACH_CAVIUM_OCTEON_SPACES_H */ diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index fe23034aaf7..74cb99257d5 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -66,4 +66,16 @@ static inline int plat_device_is_coherent(struct device *dev) #endif } +#ifdef CONFIG_SWIOTLB +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + return paddr; +} + +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) +{ + return daddr; +} +#endif + #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-generic/kernel-entry-init.h b/arch/mips/include/asm/mach-generic/kernel-entry-init.h index 7e66505fa57..13b0751b010 100644 --- a/arch/mips/include/asm/mach-generic/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-generic/kernel-entry-init.h @@ -12,8 +12,8 @@ /* Intentionally empty macro, used in head.S. Override in * arch/mips/mach-xxx/kernel-entry-init.h when necessary. */ -.macro kernel_entry_setup -.endm + .macro kernel_entry_setup + .endm /* * Do SMP slave processor setup necessary before we can savely execute C code. diff --git a/arch/mips/include/asm/mach-ip27/kernel-entry-init.h b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h index a323efb720d..b087cb83da3 100644 --- a/arch/mips/include/asm/mach-ip27/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h @@ -24,6 +24,53 @@ .endm /* + * TLB bits + */ +#define PAGE_GLOBAL (1 << 6) +#define PAGE_VALID (1 << 7) +#define PAGE_DIRTY (1 << 8) +#define CACHE_CACHABLE_COW (5 << 9) + + /* + * inputs are the text nasid in t1, data nasid in t2. + */ + .macro MAPPED_KERNEL_SETUP_TLB +#ifdef CONFIG_MAPPED_KERNEL + /* + * This needs to read the nasid - assume 0 for now. + * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, + * 0+DVG in tlblo_1. + */ + dli t0, 0xffffffffc0000000 + dmtc0 t0, CP0_ENTRYHI + li t0, 0x1c000 # Offset of text into node memory + dsll t1, NASID_SHFT # Shift text nasid into place + dsll t2, NASID_SHFT # Same for data nasid + or t1, t1, t0 # Physical load address of kernel text + or t2, t2, t0 # Physical load address of kernel data + dsrl t1, 12 # 4K pfn + dsrl t2, 12 # 4K pfn + dsll t1, 6 # Get pfn into place + dsll t2, 6 # Get pfn into place + li t0, ((PAGE_GLOBAL | PAGE_VALID | CACHE_CACHABLE_COW) >> 6) + or t0, t0, t1 + mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr + li t0, ((PAGE_GLOBAL | PAGE_VALID | PAGE_DIRTY | CACHE_CACHABLE_COW) >> 6) + or t0, t0, t2 + mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr + li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M + mtc0 t0, CP0_PAGEMASK + li t0, 0 # KMAP_INX + mtc0 t0, CP0_INDEX + li t0, 1 + mtc0 t0, CP0_WIRED + tlbwi +#else + mtc0 zero, CP0_WIRED +#endif + .endm + +/* * Intentionally empty macro, used in head.S. Override in * arch/mips/mach-xxx/kernel-entry-init.h when necessary. */ diff --git a/arch/mips/include/asm/mach-ip28/spaces.h b/arch/mips/include/asm/mach-ip28/spaces.h index 5edf05d9dad..5d6a76434d0 100644 --- a/arch/mips/include/asm/mach-ip28/spaces.h +++ b/arch/mips/include/asm/mach-ip28/spaces.h @@ -11,11 +11,14 @@ #ifndef _ASM_MACH_IP28_SPACES_H #define _ASM_MACH_IP28_SPACES_H -#define CAC_BASE 0xa800000000000000 +#define CAC_BASE _AC(0xa800000000000000, UL) -#define HIGHMEM_START (~0UL) +#define HIGHMEM_START (~0UL) -#define PHYS_OFFSET _AC(0x20000000, UL) +#define PHYS_OFFSET _AC(0x20000000, UL) + +#define UNCAC_BASE _AC(0xc0000000, UL) /* 0xa0000000 + PHYS_OFFSET */ +#define IO_BASE UNCAC_BASE #include <asm/mach-generic/spaces.h> diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h b/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h deleted file mode 100644 index ebdbab973e4..00000000000 --- a/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * include/asm-mips/pmc-sierra/msp71xx/gpio.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * @author Patrick Glass <patrickglass@gmail.com> - */ - -#ifndef __PMC_MSP71XX_GPIO_H -#define __PMC_MSP71XX_GPIO_H - -/* Max number of gpio's is 28 on chip plus 3 banks of I2C IO Expanders */ -#define ARCH_NR_GPIOS (28 + (3 * 8)) - -/* new generic GPIO API - see Documentation/gpio.txt */ -#include <asm-generic/gpio.h> - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep - -/* Setup calls for the gpio and gpio extended */ -extern void msp71xx_init_gpio(void); -extern void msp71xx_init_gpio_extended(void); -extern int msp71xx_set_output_drive(unsigned gpio, int value); - -/* Custom output drive functionss */ -static inline int gpio_set_output_drive(unsigned gpio, int value) -{ - return msp71xx_set_output_drive(gpio, value); -} - -/* IRQ's are not supported for gpio lines */ -static inline int gpio_to_irq(unsigned gpio) -{ - return -EINVAL; -} - -static inline int irq_to_gpio(unsigned irq) -{ - return -EINVAL; -} - -#endif /* __PMC_MSP71XX_GPIO_H */ diff --git a/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h b/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h deleted file mode 100644 index 00fa3684ac9..00000000000 --- a/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global - * search and replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef __ASM_MIPS_GT64120_H -#define __ASM_MIPS_GT64120_H - -/* - * This is the CPU physical memory map of PPMC Board: - * - * 0x00000000-0x03FFFFFF - 64MB SDRAM (SCS[0]#) - * 0x1C000000-0x1C000000 - LED (CS0) - * 0x1C800000-0x1C800007 - UART 16550 port (CS1) - * 0x1F000000-0x1F000000 - MailBox (CS3) - * 0x1FC00000-0x20000000 - 4MB Flash (BOOT CS) - */ - -#define WRPPMC_SDRAM_SCS0_BASE 0x00000000 -#define WRPPMC_SDRAM_SCS0_SIZE 0x04000000 - -#define WRPPMC_UART16550_BASE 0x1C800000 -#define WRPPMC_UART16550_CLOCK 3686400 /* 3.68MHZ */ - -#define WRPPMC_LED_BASE 0x1C000000 -#define WRPPMC_MBOX_BASE 0x1F000000 - -#define WRPPMC_BOOTROM_BASE 0x1FC00000 -#define WRPPMC_BOOTROM_SIZE 0x00400000 /* 4M Flash */ - -#define WRPPMC_MIPS_TIMER_IRQ 7 /* MIPS compare/count timer interrupt */ -#define WRPPMC_UART16550_IRQ 6 -#define WRPPMC_PCI_INTA_IRQ 3 - -/* - * PCI Bus I/O and Memory resources allocation - * - * NOTE: We only have PCI_0 hose interface - */ -#define GT_PCI_MEM_BASE 0x13000000UL -#define GT_PCI_MEM_SIZE 0x02000000UL -#define GT_PCI_IO_BASE 0x11000000UL -#define GT_PCI_IO_SIZE 0x02000000UL - -/* - * PCI interrupts will come in on either the INTA or INTD interrupt lines, - * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our - * boards, they all either come in on IntD or they all come in on IntA, they - * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the - * "requested" interrupt numbers and go through the list whenever we get an - * IntA/D. - * - * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and - * INTD is 11. - */ -#define GT_TIMER 4 -#define GT_INTA 2 -#define GT_INTD 5 - -#ifndef __ASSEMBLY__ - -/* - * GT64120 internal register space base address - */ -extern unsigned long gt64120_base; - -#define GT64120_BASE (gt64120_base) - -/* define WRPPMC_EARLY_DEBUG to enable early output something to UART */ -#undef WRPPMC_EARLY_DEBUG - -#ifdef WRPPMC_EARLY_DEBUG -extern void wrppmc_led_on(int mask); -extern void wrppmc_led_off(int mask); -extern void wrppmc_early_printk(const char *fmt, ...); -#else -#define wrppmc_early_printk(fmt, ...) do {} while (0) -#endif /* WRPPMC_EARLY_DEBUG */ - -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_MIPS_GT64120_H */ diff --git a/arch/mips/include/asm/mach-wrppmc/war.h b/arch/mips/include/asm/mach-wrppmc/war.h deleted file mode 100644 index e86084c0bd6..00000000000 --- a/arch/mips/include/asm/mach-wrppmc/war.h +++ /dev/null @@ -1,24 +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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_WRPPMC_WAR_H -#define __ASM_MIPS_MACH_WRPPMC_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_WRPPMC_WAR_H */ diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index bd9746fbe4a..48616816bcb 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h @@ -24,12 +24,6 @@ #define ASCII_DISPLAY_POS_BASE 0x1f000418 /* - * Reset register. - */ -#define SOFTRES_REG 0x1f000500 -#define GORESET 0x42 - -/* * Revision register. */ #define MIPS_REVISION_REG 0x1fc00010 diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 87e6207b05e..fed1c3e9b48 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -596,7 +596,7 @@ #define MIPS_CONF3_RXI (_ULCAST_(1) << 12) #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) #define MIPS_CONF3_ISA (_ULCAST_(3) << 14) -#define MIPS_CONF3_ISA_OE (_ULCAST_(3) << 16) +#define MIPS_CONF3_ISA_OE (_ULCAST_(1) << 16) #define MIPS_CONF3_VZ (_ULCAST_(1) << 23) #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 516e6e9a559..3b29079b542 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -28,11 +28,7 @@ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ do { \ - void (*tlbmiss_handler_setup_pgd)(unsigned long); \ - extern u32 tlbmiss_handler_setup_pgd_array[16]; \ - \ - tlbmiss_handler_setup_pgd = \ - (__typeof__(tlbmiss_handler_setup_pgd)) tlbmiss_handler_setup_pgd_array; \ + extern void tlbmiss_handler_setup_pgd(unsigned long); \ tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ } while (0) diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h index aef560a51a7..bb68c3398c8 100644 --- a/arch/mips/include/asm/netlogic/common.h +++ b/arch/mips/include/asm/netlogic/common.h @@ -39,11 +39,17 @@ * Common SMP definitions */ #define RESET_VEC_PHYS 0x1fc00000 +#define RESET_VEC_SIZE 8192 /* 8KB reset code and data */ #define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10)) + +/* Offsets of parameters in the RESET_DATA_PHYS area */ #define BOOT_THREAD_MODE 0 #define BOOT_NMI_LOCK 4 #define BOOT_NMI_HANDLER 8 +/* CPU ready flags for each CPU */ +#define BOOT_CPU_READY 2048 + #ifndef __ASSEMBLY__ #include <linux/cpumask.h> #include <linux/spinlock.h> @@ -59,23 +65,32 @@ int nlm_wakeup_secondary_cpus(void); void nlm_rmiboot_preboot(void); void nlm_percpu_init(int hwcpuid); +static inline void * +nlm_get_boot_data(int offset) +{ + return (void *)(CKSEG1ADDR(RESET_DATA_PHYS) + offset); +} + static inline void nlm_set_nmi_handler(void *handler) { - char *reset_data; + void *nmih = nlm_get_boot_data(BOOT_NMI_HANDLER); - reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); - *(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler; + *(int64_t *)nmih = (long)handler; } /* * Misc. */ +void nlm_init_boot_cpu(void); unsigned int nlm_get_cpu_frequency(void); void nlm_node_init(int node); extern struct plat_smp_ops nlm_smp_ops; extern char nlm_reset_entry[], nlm_reset_entry_end[]; +/* SWIOTLB */ +extern struct dma_map_ops nlm_swiotlb_dma_ops; + extern unsigned int nlm_threads_per_core; extern cpumask_t nlm_cpumask; diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h index a981f4681a1..4b5108dfaa1 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h @@ -315,7 +315,7 @@ nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi) { uint64_t ipi; - ipi = (nmi << 31) | (irq << 20); + ipi = ((uint64_t)nmi << 31) | (irq << 20); ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */ nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); } diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h index 7e47209327a..f4ea0f7f396 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h @@ -59,6 +59,7 @@ void xlp_wakeup_secondary_cpus(void); void xlp_mmu_init(void); void nlm_hal_init(void); +void *xlp_dt_init(void *fdtp); #endif /* !__ASSEMBLY__ */ #endif /* _ASM_NLM_XLP_H */ diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h index 2a78929cef7..5604db3d183 100644 --- a/arch/mips/include/asm/netlogic/xlr/fmn.h +++ b/arch/mips/include/asm/netlogic/xlr/fmn.h @@ -175,6 +175,10 @@ #define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v) #define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v) +#define nlm_read_c2_status0() __read_32bit_c2_register($2, 0) +#define nlm_write_c2_status0(v) __write_32bit_c2_register($2, 0, v) +#define nlm_read_c2_status1() __read_32bit_c2_register($2, 1) +#define nlm_write_c2_status1(v) __write_32bit_c2_register($2, 1, v) #define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0) #define nlm_read_c2_config() __read_32bit_c2_register($3, 0) #define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v) @@ -237,7 +241,7 @@ static inline void nlm_msgwait(unsigned int mask) /* * Disable interrupts and enable COP2 access */ -static inline uint32_t nlm_cop2_enable(void) +static inline uint32_t nlm_cop2_enable_irqsave(void) { uint32_t sr = read_c0_status(); @@ -245,7 +249,7 @@ static inline uint32_t nlm_cop2_enable(void) return sr; } -static inline void nlm_cop2_restore(uint32_t sr) +static inline void nlm_cop2_disable_irqrestore(uint32_t sr) { write_c0_status(sr); } @@ -296,7 +300,7 @@ static inline int nlm_fmn_send(unsigned int size, unsigned int code, */ for (i = 0; i < 8; i++) { nlm_msgsnd(dest); - status = nlm_read_c2_status(0); + status = nlm_read_c2_status0(); if ((status & 0x2) == 1) pr_info("Send pending fail!\n"); if ((status & 0x4) == 0) @@ -316,7 +320,7 @@ static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid, /* wait for load pending to clear */ do { - status = nlm_read_c2_status(1); + status = nlm_read_c2_status0(); } while ((status & 0x08) != 0); /* receive error bits */ diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index 284fa8d773b..7b7818d1e4d 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -227,6 +227,7 @@ enum cvmx_board_types_enum { * use any numbers in this range. */ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, + CVMX_BOARD_TYPE_UBNT_E100 = 20002, CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, /* The remaining range is reserved for future use. */ @@ -325,6 +326,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_PRIVATE_MAX) } return "Unsupported Board"; diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index f59552fae91..f6be4741f7e 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -205,10 +205,8 @@ extern int __virt_addr_valid(const volatile void *kaddr); #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \ - PHYS_OFFSET) -#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \ - PHYS_OFFSET) +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) +#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index b8e24fd4cbc..fa8e0aa250c 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -52,7 +52,6 @@ struct pci_controller { /* * Used by boards to register their PCI busses before the actual scanning. */ -extern struct pci_controller * alloc_pci_controller(void); extern void register_pci_controller(struct pci_controller *hose); /* diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 1470b7b68b0..3605b844ad8 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -137,7 +137,7 @@ union mips_watch_reg_state { struct mips3264_watch_reg_state mips3264; }; -#ifdef CONFIG_CPU_CAVIUM_OCTEON +#if defined(CONFIG_CPU_CAVIUM_OCTEON) struct octeon_cop2_state { /* DMFC2 rt, 0x0201 */ @@ -182,13 +182,26 @@ struct octeon_cop2_state { /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ unsigned long cop2_gfm_result[2]; }; -#define INIT_OCTEON_COP2 {0,} +#define COP2_INIT \ + .cp2 = {0,}, struct octeon_cvmseg_state { unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE] [cpu_dcache_line_size() / sizeof(unsigned long)]; }; +#elif defined(CONFIG_CPU_XLP) +struct nlm_cop2_state { + u64 rx[4]; + u64 tx[4]; + u32 tx_msg_status; + u32 rx_msg_status; +}; + +#define COP2_INIT \ + .cp2 = {{0}, {0}, 0, 0}, +#else +#define COP2_INIT #endif typedef struct { @@ -231,8 +244,11 @@ struct thread_struct { unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; #ifdef CONFIG_CPU_CAVIUM_OCTEON - struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); - struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); + struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); + struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); +#endif +#ifdef CONFIG_CPU_XLP + struct nlm_cop2_state cp2; #endif struct mips_abi *abi; }; @@ -245,13 +261,6 @@ struct thread_struct { #define FPAFF_INIT #endif /* CONFIG_MIPS_MT_FPAFF */ -#ifdef CONFIG_CPU_CAVIUM_OCTEON -#define OCTEON_INIT \ - .cp2 = INIT_OCTEON_COP2, -#else -#define OCTEON_INIT -#endif /* CONFIG_CPU_CAVIUM_OCTEON */ - #define INIT_THREAD { \ /* \ * Saved main processor registers \ @@ -300,9 +309,9 @@ struct thread_struct { .cp0_baduaddr = 0, \ .error_code = 0, \ /* \ - * Cavium Octeon specifics (null if not Octeon) \ + * Platform specific cop2 registers(null if no COP2) \ */ \ - OCTEON_INIT \ + COP2_INIT \ } struct task_struct; diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index a89d1b10d02..23fc95e6567 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -70,6 +70,14 @@ #ifndef CONFIG_CPU_HAS_SMARTMIPS LONG_S v1, PT_LO(sp) #endif +#ifdef CONFIG_CPU_CAVIUM_OCTEON + /* + * The Octeon multiplier state is affected by general + * multiply instructions. It must be saved before and + * kernel code might corrupt it + */ + jal octeon_mult_save +#endif .endm .macro SAVE_STATIC @@ -218,17 +226,8 @@ ori $28, sp, _THREAD_MASK xori $28, _THREAD_MASK #ifdef CONFIG_CPU_CAVIUM_OCTEON - .set mips64 - pref 0, 0($28) /* Prefetch the current pointer */ - pref 0, PT_R31(sp) /* Prefetch the $31(ra) */ - /* The Octeon multiplier state is affected by general multiply - instructions. It must be saved before and kernel code might - corrupt it */ - jal octeon_mult_save - LONG_L v1, 0($28) /* Load the current pointer */ - /* Restore $31(ra) that was changed by the jal */ - LONG_L ra, PT_R31(sp) - pref 0, 0(v1) /* Prefetch the current thread */ + .set mips64 + pref 0, 0($28) /* Prefetch the current pointer */ #endif .set pop .endm @@ -248,6 +247,10 @@ .endm .macro RESTORE_TEMP +#ifdef CONFIG_CPU_CAVIUM_OCTEON + /* Restore the Octeon multiplier state */ + jal octeon_mult_restore +#endif #ifdef CONFIG_CPU_HAS_SMARTMIPS LONG_L $24, PT_ACX(sp) mtlhx $24 @@ -360,10 +363,6 @@ DVPE 5 # dvpe a1 jal mips_ihb #endif /* CONFIG_MIPS_MT_SMTC */ -#ifdef CONFIG_CPU_CAVIUM_OCTEON - /* Restore the Octeon multiplier state */ - jal octeon_mult_restore -#endif mfc0 a0, CP0_STATUS ori a0, STATMASK xori a0, STATMASK diff --git a/arch/mips/include/asm/stackprotector.h b/arch/mips/include/asm/stackprotector.h new file mode 100644 index 00000000000..eb9b1035e92 --- /dev/null +++ b/arch/mips/include/asm/stackprotector.h @@ -0,0 +1,40 @@ +/* + * GCC stack protector support. + * + * (This is directly adopted from the ARM implementation) + * + * Stack protector works by putting predefined pattern at the start of + * the stack frame and verifying that it hasn't been overwritten when + * returning from the function. The pattern is called stack canary + * and gcc expects it to be defined by a global variable called + * "__stack_chk_guard" on MIPS. This unfortunately means that on SMP + * we cannot have a different canary value per task. + */ + +#ifndef _ASM_STACKPROTECTOR_H +#define _ASM_STACKPROTECTOR_H 1 + +#include <linux/random.h> +#include <linux/version.h> + +extern unsigned long __stack_chk_guard; + +/* + * Initialize the stackprotector canary value. + * + * NOTE: this must only be called from functions that never return, + * and it must always be inlined. + */ +static __always_inline void boot_init_stack_canary(void) +{ + unsigned long canary; + + /* Try to get a semi random initial value. */ + get_random_bytes(&canary, sizeof(canary)); + canary ^= LINUX_VERSION_CODE; + + current->stack_canary = canary; + __stack_chk_guard = current->stack_canary; +} + +#endif /* _ASM_STACKPROTECTOR_H */ diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index fd16bcb6c31..eb0af15ac65 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h @@ -15,6 +15,7 @@ #include <asm/cpu-features.h> #include <asm/watch.h> #include <asm/dsp.h> +#include <asm/cop2.h> struct task_struct; @@ -66,10 +67,18 @@ do { \ #define switch_to(prev, next, last) \ do { \ - u32 __usedfpu; \ + u32 __usedfpu, __c0_stat; \ __mips_mt_fpaff_switch_to(prev); \ if (cpu_has_dsp) \ __save_dsp(prev); \ + if (cop2_present && (KSTK_STATUS(prev) & ST0_CU2)) { \ + if (cop2_lazy_restore) \ + KSTK_STATUS(prev) &= ~ST0_CU2; \ + __c0_stat = read_c0_status(); \ + write_c0_status(__c0_stat | ST0_CU2); \ + cop2_save(&prev->thread.cp2); \ + write_c0_status(__c0_stat & ~ST0_CU2); \ + } \ __clear_software_ll_bit(); \ __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \ (last) = resume(prev, next, task_thread_info(next), __usedfpu); \ @@ -77,6 +86,14 @@ do { \ #define finish_arch_switch(prev) \ do { \ + u32 __c0_stat; \ + if (cop2_present && !cop2_lazy_restore && \ + (KSTK_STATUS(current) & ST0_CU2)) { \ + __c0_stat = read_c0_status(); \ + write_c0_status(__c0_stat | ST0_CU2); \ + cop2_restore(¤t->thread.cp2); \ + write_c0_status(__c0_stat & ~ST0_CU2); \ + } \ if (cpu_has_dsp) \ __restore_dsp(current); \ if (cpu_has_userlocal) \ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 895320e2566..61215a34acc 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ +#define TIF_NOHZ 19 /* in adaptive nohz mode */ #define TIF_FIXADE 20 /* Fix address errors in software */ #define TIF_LOGADE 21 /* Log address errors to syslog */ #define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */ @@ -124,6 +125,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_USEDFPU (1<<TIF_USEDFPU) +#define _TIF_NOHZ (1<<TIF_NOHZ) #define _TIF_FIXADE (1<<TIF_FIXADE) #define _TIF_LOGADE (1<<TIF_LOGADE) #define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS) @@ -131,14 +133,19 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) +#define _TIF_WORK_SYSCALL_ENTRY (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \ + _TIF_SYSCALL_AUDIT) + /* work to do in syscall_trace_leave() */ -#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) +#define _TIF_WORK_SYSCALL_EXIT (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \ + _TIF_SYSCALL_AUDIT) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME) /* work to do on any return to u-space */ -#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT) +#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \ + _TIF_WORK_SYSCALL_EXIT) #endif /* __KERNEL__ */ diff --git a/arch/mips/include/asm/xtalk/xtalk.h b/arch/mips/include/asm/xtalk/xtalk.h index 680e7efebba..26d2ed1fa91 100644 --- a/arch/mips/include/asm/xtalk/xtalk.h +++ b/arch/mips/include/asm/xtalk/xtalk.h @@ -47,6 +47,15 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t; #define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT)) #define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS)) +#ifdef CONFIG_PCI +extern int bridge_probe(nasid_t nasid, int widget, int masterwid); +#else +static inline int bridge_probe(nasid_t nasid, int widget, int masterwid) +{ + return 0; +} +#endif + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_XTALK_XTALK_H */ diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h index 0bda78f70e1..6ca432f0086 100644 --- a/arch/mips/include/uapi/asm/fcntl.h +++ b/arch/mips/include/uapi/asm/fcntl.h @@ -5,9 +5,10 @@ * * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle */ -#ifndef _ASM_FCNTL_H -#define _ASM_FCNTL_H +#ifndef _UAPI_ASM_FCNTL_H +#define _UAPI_ASM_FCNTL_H +#include <asm/sgidefs.h> #define O_APPEND 0x0008 #define O_DSYNC 0x0010 /* used to be O_SYNC, see below */ @@ -55,14 +56,15 @@ * contain all the same fields as struct flock. */ -#ifdef CONFIG_32BIT +#if _MIPS_SIM != _MIPS_SIM_ABI64 + #include <linux/types.h> struct flock { short l_type; short l_whence; - off_t l_start; - off_t l_len; + __kernel_off_t l_start; + __kernel_off_t l_len; long l_sysid; __kernel_pid_t l_pid; long pad[4]; @@ -70,8 +72,8 @@ struct flock { #define HAVE_ARCH_STRUCT_FLOCK -#endif /* CONFIG_32BIT */ +#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #include <asm-generic/fcntl.h> -#endif /* _ASM_FCNTL_H */ +#endif /* _UAPI_ASM_FCNTL_H */ diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 0f4aec2ad1e..e5a676e3d3c 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h @@ -409,10 +409,11 @@ enum mm_32f_73_minor_op { enum mm_16c_minor_op { mm_lwm16_op = 0x04, mm_swm16_op = 0x05, - mm_jr16_op = 0x18, - mm_jrc_op = 0x1a, - mm_jalr16_op = 0x1c, - mm_jalrs16_op = 0x1e, + mm_jr16_op = 0x0c, + mm_jrc_op = 0x0d, + mm_jalr16_op = 0x0e, + mm_jalrs16_op = 0x0f, + mm_jraddiusp_op = 0x18, }; /* diff --git a/arch/mips/include/uapi/asm/msgbuf.h b/arch/mips/include/uapi/asm/msgbuf.h index 0d6c7f14de3..df849e87d9a 100644 --- a/arch/mips/include/uapi/asm/msgbuf.h +++ b/arch/mips/include/uapi/asm/msgbuf.h @@ -14,25 +14,25 @@ struct msqid64_ds { struct ipc64_perm msg_perm; -#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEB__) unsigned long __unused1; #endif __kernel_time_t msg_stime; /* last msgsnd time */ -#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEL__) unsigned long __unused1; #endif -#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEB__) unsigned long __unused2; #endif __kernel_time_t msg_rtime; /* last msgrcv time */ -#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEL__) unsigned long __unused2; #endif -#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEB__) unsigned long __unused3; #endif __kernel_time_t msg_ctime; /* last change time */ -#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) +#if !defined(__mips64) && defined(__MIPSEL__) unsigned long __unused3; #endif unsigned long msg_cbytes; /* current number of bytes on queue */ diff --git a/arch/mips/include/uapi/asm/resource.h b/arch/mips/include/uapi/asm/resource.h index 87cb3085269..b26439d4ab0 100644 --- a/arch/mips/include/uapi/asm/resource.h +++ b/arch/mips/include/uapi/asm/resource.h @@ -26,7 +26,7 @@ * but we keep the old value on MIPS32, * for compatibility: */ -#ifdef CONFIG_32BIT +#ifndef __mips64 # define RLIM_INFINITY 0x7fffffffUL #endif diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 6a8714193fb..b7a23064841 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h @@ -25,10 +25,10 @@ struct siginfo; /* * Careful to keep union _sifields from shifting ... */ -#ifdef CONFIG_32BIT +#if __SIZEOF_LONG__ == 4 #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) #endif -#ifdef CONFIG_64BIT +#if __SIZEOF_LONG__ == 8 #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #endif diff --git a/arch/mips/include/uapi/asm/swab.h b/arch/mips/include/uapi/asm/swab.h index 97c2f81b4b4..ac9a8f9cd1f 100644 --- a/arch/mips/include/uapi/asm/swab.h +++ b/arch/mips/include/uapi/asm/swab.h @@ -13,7 +13,7 @@ #define __SWAB_64_THRU_32__ -#ifdef CONFIG_CPU_MIPSR2 +#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2) static inline __attribute_const__ __u16 __arch_swab16(__u16 x) { @@ -39,10 +39,10 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) #define __arch_swab32 __arch_swab32 /* - * Having already checked for CONFIG_CPU_MIPSR2, enable the - * optimized version for 64-bit kernel on r2 CPUs. + * Having already checked for MIPS R2, enable the optimized version for + * 64-bit kernel on r2 CPUs. */ -#ifdef CONFIG_64BIT +#ifdef __mips64 static inline __attribute_const__ __u64 __arch_swab64(__u64 x) { __asm__( @@ -54,6 +54,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x) return x; } #define __arch_swab64 __arch_swab64 -#endif /* CONFIG_64BIT */ -#endif /* CONFIG_CPU_MIPSR2 */ +#endif /* __mips64 */ +#endif /* MIPS R2 or newer */ #endif /* _ASM_SWAB_H */ diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 0845091ba48..0c2e853c3db 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -82,6 +82,9 @@ void output_task_defines(void) OFFSET(TASK_FLAGS, task_struct, flags); OFFSET(TASK_MM, task_struct, mm); OFFSET(TASK_PID, task_struct, pid); +#if defined(CONFIG_CC_STACKPROTECTOR) + OFFSET(TASK_STACK_CANARY, task_struct, stack_canary); +#endif DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct)); BLANK(); } diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 46c2ad0703a..4d78bf445a9 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -467,5 +467,4 @@ unaligned: printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); force_sig(SIGBUS, current); return -EFAULT; - } diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index de3c25ffd9f..0c61df281ce 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -6,6 +6,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include <linux/context_tracking.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/ptrace.h> @@ -171,8 +172,12 @@ static volatile int daddi_ov __cpuinitdata; asmlinkage void __init do_daddi_ov(struct pt_regs *regs) { + enum ctx_state prev_state; + + prev_state = exception_enter(); daddi_ov = 1; regs->cp0_epc += 4; + exception_exit(prev_state); } static inline void check_daddi(void) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index c6568bf4b1b..c7b1b3c5a76 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -146,8 +146,7 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa) case MIPS_CPU_ISA_IV: c->isa_level |= MIPS_CPU_ISA_IV; case MIPS_CPU_ISA_III: - c->isa_level |= MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | - MIPS_CPU_ISA_III; + c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III; break; case MIPS_CPU_ISA_M32R2: @@ -156,8 +155,6 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa) c->isa_level |= MIPS_CPU_ISA_M32R1; case MIPS_CPU_ISA_II: c->isa_level |= MIPS_CPU_ISA_II; - case MIPS_CPU_ISA_I: - c->isa_level |= MIPS_CPU_ISA_I; break; } } @@ -272,9 +269,6 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) c->options |= MIPS_CPU_ULRI; if (config3 & MIPS_CONF3_ISA) c->options |= MIPS_CPU_MICROMIPS; -#ifdef CONFIG_CPU_MICROMIPS - write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE); -#endif if (config3 & MIPS_CONF3_VZ) c->ases |= MIPS_ASE_VZ; @@ -332,7 +326,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) case PRID_IMP_R2000: c->cputype = CPU_R2000; __cpu_name[cpu] = "R2000"; - set_isa(c, MIPS_CPU_ISA_I); c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | MIPS_CPU_NOFPUEX; if (__cpu_has_fpu()) @@ -352,7 +345,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_R3000; __cpu_name[cpu] = "R3000"; } - set_isa(c, MIPS_CPU_ISA_I); c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | MIPS_CPU_NOFPUEX; if (__cpu_has_fpu()) @@ -455,7 +447,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) break; #endif case PRID_IMP_TX39: - set_isa(c, MIPS_CPU_ISA_I); c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE; if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { @@ -959,6 +950,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) set_isa(c, MIPS_CPU_ISA_M64R1); c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1; } + c->kscratch_mask = 0xf; } #ifdef CONFIG_64BIT diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index c61cdaed2b1..09991232442 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -28,45 +28,6 @@ #include <kernel-entry-init.h> /* - * inputs are the text nasid in t1, data nasid in t2. - */ - .macro MAPPED_KERNEL_SETUP_TLB -#ifdef CONFIG_MAPPED_KERNEL - /* - * This needs to read the nasid - assume 0 for now. - * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, - * 0+DVG in tlblo_1. - */ - dli t0, 0xffffffffc0000000 - dmtc0 t0, CP0_ENTRYHI - li t0, 0x1c000 # Offset of text into node memory - dsll t1, NASID_SHFT # Shift text nasid into place - dsll t2, NASID_SHFT # Same for data nasid - or t1, t1, t0 # Physical load address of kernel text - or t2, t2, t0 # Physical load address of kernel data - dsrl t1, 12 # 4K pfn - dsrl t2, 12 # 4K pfn - dsll t1, 6 # Get pfn into place - dsll t2, 6 # Get pfn into place - li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6) - or t0, t0, t1 - mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr - li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6) - or t0, t0, t2 - mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr - li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M - mtc0 t0, CP0_PAGEMASK - li t0, 0 # KMAP_INX - mtc0 t0, CP0_INDEX - li t0, 1 - mtc0 t0, CP0_WIRED - tlbwi -#else - mtc0 zero, CP0_WIRED -#endif - .endm - - /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using * 64-bit addresses. A full initialization of the CPU's status diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index c01b307317a..5b5ddb231f2 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -219,16 +219,15 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, /* Assumption : cpumask refers to a single CPU */ spin_lock_irqsave(&gic_lock, flags); - for (;;) { - /* Re-route this IRQ */ - GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); - /* Update the pcpu_masks */ - for (i = 0; i < NR_CPUS; i++) - clear_bit(irq, pcpu_masks[i].pcpu_mask); - set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); + /* Re-route this IRQ */ + GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); + + /* Update the pcpu_masks */ + for (i = 0; i < NR_CPUS; i++) + clear_bit(irq, pcpu_masks[i].pcpu_mask); + set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); - } cpumask_copy(d->affinity, cpumask); spin_unlock_irqrestore(&gic_lock, flags); diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 33d067148e6..a03e93c4a94 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -168,15 +168,11 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra) #endif /* arg3: Get frame pointer of current stack */ -#ifdef CONFIG_FRAME_POINTER - move a2, fp -#else /* ! CONFIG_FRAME_POINTER */ #ifdef CONFIG_64BIT PTR_LA a2, PT_SIZE(sp) #else PTR_LA a2, (PT_SIZE+8)(sp) #endif -#endif jal prepare_ftrace_return nop diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index 0e23343eb0a..4204d76af85 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -40,33 +40,6 @@ cpu_save_nonscratch a0 LONG_S ra, THREAD_REG31(a0) - /* check if we need to save COP2 registers */ - PTR_L t2, TASK_THREAD_INFO(a0) - LONG_L t0, ST_OFF(t2) - bbit0 t0, 30, 1f - - /* Disable COP2 in the stored process state */ - li t1, ST0_CU2 - xor t0, t1 - LONG_S t0, ST_OFF(t2) - - /* Enable COP2 so we can save it */ - mfc0 t0, CP0_STATUS - or t0, t1 - mtc0 t0, CP0_STATUS - - /* Save COP2 */ - daddu a0, THREAD_CP2 - jal octeon_cop2_save - dsubu a0, THREAD_CP2 - - /* Disable COP2 now that we are done */ - mfc0 t0, CP0_STATUS - li t1, ST0_CU2 - xor t0, t1 - mtc0 t0, CP0_STATUS - -1: #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 /* Check if we need to store CVMSEG state */ mfc0 t0, $11,7 /* CvmMemCtl */ @@ -98,6 +71,13 @@ mtc0 t0, $11,7 /* CvmMemCtl */ #endif 3: + +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index acb34373679..8c58d8a84bf 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -66,9 +66,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "]\n"); } if (cpu_has_mips_r) { - seq_printf(m, "isa\t\t\t:"); - if (cpu_has_mips_1) - seq_printf(m, "%s", " mips1"); + seq_printf(m, "isa\t\t\t: mips1"); if (cpu_has_mips_2) seq_printf(m, "%s", " mips2"); if (cpu_has_mips_3) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index c6a041d9d05..ddc76103e78 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -201,9 +201,12 @@ int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) return 1; } -/* - * - */ +#ifdef CONFIG_CC_STACKPROTECTOR +#include <linux/stackprotector.h> +unsigned long __stack_chk_guard __read_mostly; +EXPORT_SYMBOL(__stack_chk_guard); +#endif + struct mips_frame_info { void *func; unsigned long func_size; diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 5712bb53224..7e954042f25 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -30,7 +30,7 @@ __init void mips_set_machine_name(const char *name) if (name == NULL) return; - strncpy(mips_machine_name, name, sizeof(mips_machine_name)); + strlcpy(mips_machine_name, name, sizeof(mips_machine_name)); pr_info("MIPS: machine is %s\n", mips_get_machine_name()); } diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 9c6299c733a..8ae1ebef8b7 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -15,6 +15,7 @@ * binaries. */ #include <linux/compiler.h> +#include <linux/context_tracking.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -534,6 +535,8 @@ static inline int audit_arch(void) */ asmlinkage void syscall_trace_enter(struct pt_regs *regs) { + user_exit(); + /* do the secure computing check first */ secure_computing_strict(regs->regs[2]); @@ -570,6 +573,13 @@ out: */ asmlinkage void syscall_trace_leave(struct pt_regs *regs) { + /* + * We may come here right after calling schedule_user() + * or do_notify_resume(), in which case we can be in RCU + * user mode. + */ + user_exit(); + audit_syscall_exit(regs); if (!(current->ptrace & PT_PTRACED)) @@ -592,4 +602,6 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) send_sig(current->exit_code, current, 1); current->exit_code = 0; } + + user_enter(); } diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 5266c6ee2b3..38af83f84c4 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -65,6 +65,13 @@ LEAF(resume) fpu_save_single a0, t0 # clobbers t0 1: + +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 5e51219990a..921238a6bd2 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -68,6 +68,12 @@ # clobbers t1 1: +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 6fa198db899..d763f11e35e 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -437,7 +437,6 @@ static ssize_t file_write(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { int minor = iminor(file_inode(file)); - struct rtlx_channel *rt = &rtlx->channel[minor]; /* any space left... */ if (!rtlx_write_poll(minor)) { diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index e9127ec612e..e774bb1088b 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp) stack_done: lw t0, TI_FLAGS($28) # syscall tracing enabled? - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_WORK_SYSCALL_ENTRY and t0, t1 bnez t0, syscall_trace_entry # -> yes diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 97a5909a61c..be6627ead61 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp) sd a3, PT_R26(sp) # save a3 for syscall restarting - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, syscall_trace_entry diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index edcb6594e7b..cab150789c8 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -47,7 +47,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) sd a3, PT_R26(sp) # save a3 for syscall restarting - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, n32_syscall_trace_entry diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 74f485d3c0e..37605dc8eef 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp) PTR 4b, bad_stack .previous - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, trace_a_syscall diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index fd3ef2c2afb..2f285abc76d 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include <linux/cache.h> +#include <linux/context_tracking.h> #include <linux/irqflags.h> #include <linux/sched.h> #include <linux/mm.h> @@ -573,6 +574,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, { local_irq_enable(); + user_exit(); + /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); @@ -581,6 +584,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } + + user_enter(); } #ifdef CONFIG_SMP diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 8e393b8443f..aea6c088583 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id); static void __init bmips_smp_setup(void) { - int i; + int i, cpu = 1, boot_cpu = 0; #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) /* arbitration priority */ @@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void) /* NBK and weak order flags */ set_c0_brcm_config_0(0x30000); + /* Find out if we are running on TP0 or TP1 */ + boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); + /* * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output + * + * If booting from TP1, leave the existing CMT interrupt routing + * such that TP0 responds to SW1 and TP1 responds to SW0. */ - change_c0_brcm_cmt_intr(0xf8018000, - (0x02 << 27) | (0x03 << 15)); + if (boot_cpu == 0) + change_c0_brcm_cmt_intr(0xf8018000, + (0x02 << 27) | (0x03 << 15)); + else + change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27)); /* single core, 2 threads (2 pipelines) */ max_cpus = 2; @@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void) if (!board_ebase_setup) board_ebase_setup = &bmips_ebase_setup; + __cpu_number_map[boot_cpu] = 0; + __cpu_logical_map[0] = boot_cpu; + for (i = 0; i < max_cpus; i++) { - __cpu_number_map[i] = 1; - __cpu_logical_map[i] = 1; + if (i != boot_cpu) { + __cpu_number_map[i] = cpu; + __cpu_logical_map[cpu] = i; + cpu++; + } set_cpu_possible(i, 1); set_cpu_present(i, 1); } @@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) bmips_send_ipi_single(cpu, 0); else { #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) - set_c0_brcm_cmt_ctrl(0x01); + /* Reset slave TP1 if booting from TP0 */ + if (cpu_logical_map(cpu) == 0) + set_c0_brcm_cmt_ctrl(0x01); #elif defined(CONFIG_CPU_BMIPS5000) if (cpu & 0x01) write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index a75ae40184a..0903d70b2cf 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -13,6 +13,7 @@ */ #include <linux/bug.h> #include <linux/compiler.h> +#include <linux/context_tracking.h> #include <linux/kexec.h> #include <linux/init.h> #include <linux/kernel.h> @@ -264,7 +265,7 @@ static void __show_regs(const struct pt_regs *regs) printk("Status: %08x ", (uint32_t) regs->cp0_status); - if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) { + if (cpu_has_3kex) { if (regs->cp0_status & ST0_KUO) printk("KUo "); if (regs->cp0_status & ST0_IEO) @@ -277,7 +278,7 @@ static void __show_regs(const struct pt_regs *regs) printk("KUc "); if (regs->cp0_status & ST0_IEC) printk("IEc "); - } else { + } else if (cpu_has_4kex) { if (regs->cp0_status & ST0_KX) printk("KX "); if (regs->cp0_status & ST0_SX) @@ -423,7 +424,9 @@ asmlinkage void do_be(struct pt_regs *regs) const struct exception_table_entry *fixup = NULL; int data = regs->cp0_cause & 4; int action = MIPS_BE_FATAL; + enum ctx_state prev_state; + prev_state = exception_enter(); /* XXX For now. Fixme, this searches the wrong table ... */ if (data && !user_mode(regs)) fixup = search_dbe_tables(exception_epc(regs)); @@ -436,11 +439,11 @@ asmlinkage void do_be(struct pt_regs *regs) switch (action) { case MIPS_BE_DISCARD: - return; + goto out; case MIPS_BE_FIXUP: if (fixup) { regs->cp0_epc = fixup->nextinsn; - return; + goto out; } break; default: @@ -455,10 +458,13 @@ asmlinkage void do_be(struct pt_regs *regs) field, regs->cp0_epc, field, regs->regs[31]); if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS) == NOTIFY_STOP) - return; + goto out; die_if_kernel("Oops", regs); force_sig(SIGBUS, current); + +out: + exception_exit(prev_state); } /* @@ -673,8 +679,10 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode) asmlinkage void do_ov(struct pt_regs *regs) { + enum ctx_state prev_state; siginfo_t info; + prev_state = exception_enter(); die_if_kernel("Integer overflow", regs); info.si_code = FPE_INTOVF; @@ -682,6 +690,7 @@ asmlinkage void do_ov(struct pt_regs *regs) info.si_errno = 0; info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); + exception_exit(prev_state); } int process_fpemu_return(int sig, void __user *fault_addr) @@ -713,11 +722,13 @@ int process_fpemu_return(int sig, void __user *fault_addr) */ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) { + enum ctx_state prev_state; siginfo_t info = {0}; + prev_state = exception_enter(); if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP) - return; + goto out; die_if_kernel("FP exception in kernel code", regs); if (fcr31 & FPU_CSR_UNI_X) { @@ -753,7 +764,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) /* If something went wrong, signal */ process_fpemu_return(sig, fault_addr); - return; + goto out; } else if (fcr31 & FPU_CSR_INV_X) info.si_code = FPE_FLTINV; else if (fcr31 & FPU_CSR_DIV_X) @@ -770,6 +781,9 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) info.si_errno = 0; info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); + +out: + exception_exit(prev_state); } static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, @@ -835,9 +849,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; + enum ctx_state prev_state; unsigned long epc; u16 instr[2]; + prev_state = exception_enter(); if (get_isa16_mode(regs->cp0_epc)) { /* Calculate EPC. */ epc = exception_epc(regs); @@ -852,7 +868,7 @@ asmlinkage void do_bp(struct pt_regs *regs) goto out_sigsegv; bcode = (instr[0] >> 6) & 0x3f; do_trap_or_bp(regs, bcode, "Break"); - return; + goto out; } } else { if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) @@ -876,12 +892,12 @@ asmlinkage void do_bp(struct pt_regs *regs) switch (bcode) { case BRK_KPROBE_BP: if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) - return; + goto out; else break; case BRK_KPROBE_SSTEPBP: if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) - return; + goto out; else break; default: @@ -889,18 +905,24 @@ asmlinkage void do_bp(struct pt_regs *regs) } do_trap_or_bp(regs, bcode, "Break"); + +out: + exception_exit(prev_state); return; out_sigsegv: force_sig(SIGSEGV, current); + goto out; } asmlinkage void do_tr(struct pt_regs *regs) { u32 opcode, tcode = 0; + enum ctx_state prev_state; u16 instr[2]; unsigned long epc = msk_isa16_mode(exception_epc(regs)); + prev_state = exception_enter(); if (get_isa16_mode(regs->cp0_epc)) { if (__get_user(instr[0], (u16 __user *)(epc + 0)) || __get_user(instr[1], (u16 __user *)(epc + 2))) @@ -918,10 +940,14 @@ asmlinkage void do_tr(struct pt_regs *regs) } do_trap_or_bp(regs, tcode, "Trap"); + +out: + exception_exit(prev_state); return; out_sigsegv: force_sig(SIGSEGV, current); + goto out; } asmlinkage void do_ri(struct pt_regs *regs) @@ -929,17 +955,19 @@ asmlinkage void do_ri(struct pt_regs *regs) unsigned int __user *epc = (unsigned int __user *)exception_epc(regs); unsigned long old_epc = regs->cp0_epc; unsigned long old31 = regs->regs[31]; + enum ctx_state prev_state; unsigned int opcode = 0; int status = -1; + prev_state = exception_enter(); if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL) == NOTIFY_STOP) - return; + goto out; die_if_kernel("Reserved instruction in kernel code", regs); if (unlikely(compute_return_epc(regs) < 0)) - return; + goto out; if (get_isa16_mode(regs->cp0_epc)) { unsigned short mmop[2] = { 0 }; @@ -974,6 +1002,9 @@ asmlinkage void do_ri(struct pt_regs *regs) regs->regs[31] = old31; force_sig(status, current); } + +out: + exception_exit(prev_state); } /* @@ -1025,21 +1056,16 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, { struct pt_regs *regs = data; - switch (action) { - default: - die_if_kernel("Unhandled kernel unaligned access or invalid " + die_if_kernel("COP2: Unhandled kernel unaligned access or invalid " "instruction", regs); - /* Fall through */ - - case CU2_EXCEPTION: - force_sig(SIGILL, current); - } + force_sig(SIGILL, current); return NOTIFY_OK; } asmlinkage void do_cpu(struct pt_regs *regs) { + enum ctx_state prev_state; unsigned int __user *epc; unsigned long old_epc, old31; unsigned int opcode; @@ -1047,10 +1073,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) int status; unsigned long __maybe_unused flags; - die_if_kernel("do_cpu invoked from kernel context!", regs); - + prev_state = exception_enter(); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; + if (cpid != 2) + die_if_kernel("do_cpu invoked from kernel context!", regs); + switch (cpid) { case 0: epc = (unsigned int __user *)exception_epc(regs); @@ -1060,7 +1088,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) status = -1; if (unlikely(compute_return_epc(regs) < 0)) - return; + goto out; if (get_isa16_mode(regs->cp0_epc)) { unsigned short mmop[2] = { 0 }; @@ -1093,7 +1121,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) force_sig(status, current); } - return; + goto out; case 3: /* @@ -1131,19 +1159,26 @@ asmlinkage void do_cpu(struct pt_regs *regs) mt_ase_fp_affinity(); } - return; + goto out; case 2: raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); - return; + goto out; } force_sig(SIGILL, current); + +out: + exception_exit(prev_state); } asmlinkage void do_mdmx(struct pt_regs *regs) { + enum ctx_state prev_state; + + prev_state = exception_enter(); force_sig(SIGILL, current); + exception_exit(prev_state); } /* @@ -1151,8 +1186,10 @@ asmlinkage void do_mdmx(struct pt_regs *regs) */ asmlinkage void do_watch(struct pt_regs *regs) { + enum ctx_state prev_state; u32 cause; + prev_state = exception_enter(); /* * Clear WP (bit 22) bit of cause register so we don't loop * forever. @@ -1174,13 +1211,16 @@ asmlinkage void do_watch(struct pt_regs *regs) mips_clear_watch_registers(); local_irq_enable(); } + exception_exit(prev_state); } asmlinkage void do_mcheck(struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); int multi_match = regs->cp0_status & ST0_TS; + enum ctx_state prev_state; + prev_state = exception_enter(); show_regs(regs); if (multi_match) { @@ -1202,6 +1242,7 @@ asmlinkage void do_mcheck(struct pt_regs *regs) panic("Caught Machine Check exception - %scaused by multiple " "matching entries in the TLB.", (multi_match) ? "" : "not "); + exception_exit(prev_state); } asmlinkage void do_mt(struct pt_regs *regs) @@ -1627,7 +1668,6 @@ void *set_vi_handler(int n, vi_handler_t addr) } extern void tlb_init(void); -extern void flush_tlb_handlers(void); /* * Timer interrupt @@ -1837,6 +1877,15 @@ void __init trap_init(void) ebase += (read_c0_ebase() & 0x3ffff000); } + if (cpu_has_mmips) { + unsigned int config3 = read_c0_config3(); + + if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) + write_c0_config3(config3 | MIPS_CONF3_ISA_OE); + else + write_c0_config3(config3 & ~MIPS_CONF3_ISA_OE); + } + if (board_ebase_setup) board_ebase_setup(); per_cpu_trap_init(true); @@ -1956,7 +2005,6 @@ void __init trap_init(void) set_handler(0x080, &except_vec3_generic, 0x80); local_flush_icache_range(ebase, ebase + 0x400); - flush_tlb_handlers(); sort_extable(__start___dbe_table, __stop___dbe_table); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 203d8857070..c369a5d3552 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -72,6 +72,7 @@ * A store crossing a page boundary might be executed only partially. * Undo the partial store in this case. */ +#include <linux/context_tracking.h> #include <linux/mm.h> #include <linux/signal.h> #include <linux/smp.h> @@ -684,7 +685,8 @@ const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; /* Recode table from 16-bit STORE register notation to 32-bit GPR. */ const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; -void emulate_load_store_microMIPS(struct pt_regs *regs, void __user * addr) +static void emulate_load_store_microMIPS(struct pt_regs *regs, + void __user *addr) { unsigned long value; unsigned int res; @@ -1548,11 +1550,14 @@ sigill: ("Unhandled kernel unaligned access or invalid instruction", regs); force_sig(SIGILL, current); } + asmlinkage void do_ade(struct pt_regs *regs) { + enum ctx_state prev_state; unsigned int __user *pc; mm_segment_t seg; + prev_state = exception_enter(); perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->cp0_badvaddr); /* @@ -1628,6 +1633,7 @@ sigbus: /* * XXX On return from the signal handler we should advance the epc */ + exception_exit(prev_state); } #ifdef CONFIG_DEBUG_FS diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c index 7726f6157d9..cbdc4de85bb 100644 --- a/arch/mips/kernel/watch.c +++ b/arch/mips/kernel/watch.c @@ -111,6 +111,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) * disable the register. */ write_c0_watchlo0(7); + back_to_back_c0_hazard(); t = read_c0_watchlo0(); write_c0_watchlo0(0); c->watch_reg_masks[0] = t & 7; @@ -121,12 +122,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) c->watch_reg_use_cnt = 1; t = read_c0_watchhi0(); write_c0_watchhi0(t | 0xff8); + back_to_back_c0_hazard(); t = read_c0_watchhi0(); c->watch_reg_masks[0] |= (t & 0xff8); if ((t & 0x80000000) == 0) return; write_c0_watchlo1(7); + back_to_back_c0_hazard(); t = read_c0_watchlo1(); write_c0_watchlo1(0); c->watch_reg_masks[1] = t & 7; @@ -135,12 +138,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) c->watch_reg_use_cnt = 2; t = read_c0_watchhi1(); write_c0_watchhi1(t | 0xff8); + back_to_back_c0_hazard(); t = read_c0_watchhi1(); c->watch_reg_masks[1] |= (t & 0xff8); if ((t & 0x80000000) == 0) return; write_c0_watchlo2(7); + back_to_back_c0_hazard(); t = read_c0_watchlo2(); write_c0_watchlo2(0); c->watch_reg_masks[2] = t & 7; @@ -149,12 +154,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) c->watch_reg_use_cnt = 3; t = read_c0_watchhi2(); write_c0_watchhi2(t | 0xff8); + back_to_back_c0_hazard(); t = read_c0_watchhi2(); c->watch_reg_masks[2] |= (t & 0xff8); if ((t & 0x80000000) == 0) return; write_c0_watchlo3(7); + back_to_back_c0_hazard(); t = read_c0_watchlo3(); write_c0_watchlo3(0); c->watch_reg_masks[3] = t & 7; @@ -163,6 +170,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) c->watch_reg_use_cnt = 4; t = read_c0_watchhi3(); write_c0_watchhi3(t | 0xff8); + back_to_back_c0_hazard(); t = read_c0_watchhi3(); c->watch_reg_masks[3] |= (t & 0xff8); if ((t & 0x80000000) == 0) diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 9f9e875967a..49c46037028 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -112,7 +112,7 @@ int __init plat_of_setup(void) if (!of_have_populated_dt()) panic("device tree not present"); - strncpy(of_ids[0].compatible, soc_info.compatible, + strlcpy(of_ids[0].compatible, soc_info.compatible, sizeof(of_ids[0].compatible)); strncpy(of_ids[1].compatible, "simple-bus", sizeof(of_ids[1].compatible)); diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index f27694fb2ad..3b7f65cc421 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c @@ -39,7 +39,7 @@ /* And the same for proc */ -int proc_dolasatstring(ctl_table *table, int write, +int proc_dolasatstring(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { int r; @@ -54,7 +54,7 @@ int proc_dolasatstring(ctl_table *table, int write, } /* proc function to write EEPROM after changing int entry */ -int proc_dolasatint(ctl_table *table, int write, +int proc_dolasatint(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { int r; @@ -72,7 +72,7 @@ int proc_dolasatint(ctl_table *table, int write, static int rtctmp; /* proc function to read/write RealTime Clock */ -int proc_dolasatrtc(ctl_table *table, int write, +int proc_dolasatrtc(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { struct timespec ts; @@ -97,7 +97,7 @@ int proc_dolasatrtc(ctl_table *table, int write, #endif #ifdef CONFIG_INET -int proc_lasat_ip(ctl_table *table, int write, +int proc_lasat_ip(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { unsigned int ip; @@ -157,7 +157,7 @@ int proc_lasat_ip(ctl_table *table, int write, } #endif -int proc_lasat_prid(ctl_table *table, int write, +int proc_lasat_prid(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { int r; @@ -176,7 +176,7 @@ int proc_lasat_prid(ctl_table *table, int write, extern int lasat_boot_to_service; -static ctl_table lasat_table[] = { +static struct ctl_table lasat_table[] = { { .procname = "cpu-hz", .data = &lasat_board_info.li_cpu_hz, @@ -262,7 +262,7 @@ static ctl_table lasat_table[] = { {} }; -static ctl_table lasat_root_table[] = { +static struct ctl_table lasat_root_table[] = { { .procname = "lasat", .mode = 0555, diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c index a6eb2e853d9..924be39e773 100644 --- a/arch/mips/loongson/common/cs5536/cs5536_isa.c +++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c @@ -13,6 +13,7 @@ * option) any later version. */ +#include <linux/pci.h> #include <cs5536/cs5536.h> #include <cs5536/cs5536_pci.h> @@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg) return conf_data; } + +/* + * The mfgpt timer interrupt is running early, so we must keep the south bridge + * mmio always enabled. Otherwise we may race with the PCI configuration which + * may temporarily disable it. When that happens and the timer interrupt fires, + * we are not able to clear it and the system will hang. + */ +static void cs5536_isa_mmio_always_on(struct pci_dev *dev) +{ + dev->mmio_always_on = 1; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on); diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index f0377190081..e773659ccf9 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -471,6 +471,9 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, unsigned int fcr31; unsigned int bit; + if (!cpu_has_mmips) + return 0; + switch (insn.mm_i_format.opcode) { case mm_pool32a_op: if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) == diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index e87aae1f2e8..7f4f93ab22b 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -4,7 +4,7 @@ obj-y += cache.o dma-default.o extable.o fault.o \ gup.o init.o mmap.o page.o page-funcs.o \ - tlbex.o tlbex-fault.o uasm-mips.o + tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c index 576add33bf5..ee5c1ff861a 100644 --- a/arch/mips/mm/cerr-sb1.c +++ b/arch/mips/mm/cerr-sb1.c @@ -182,11 +182,7 @@ asmlinkage void sb1_cache_error(void) #ifdef CONFIG_SIBYTE_BW_TRACE /* Freeze the trace buffer now */ -#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) - csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG)); -#else csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG)); -#endif printk("Trace buffer frozen\n"); #endif diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index caf92ecb37d..aaccf1c1069 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -246,6 +246,9 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, if (!plat_device_is_coherent(dev)) __dma_sync(sg_page(sg), sg->offset, sg->length, direction); +#ifdef CONFIG_NEED_SG_DMA_LENGTH + sg->dma_length = sg->length; +#endif sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) + sg->offset; } diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 0fead53d1c2..85df1cd8d44 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -5,6 +5,7 @@ * * Copyright (C) 1995 - 2000 by Ralf Baechle */ +#include <linux/context_tracking.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> @@ -32,8 +33,8 @@ * and the problem, and then passes it off to one of the appropriate * routines. */ -asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long write, - unsigned long address) +static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, + unsigned long address) { struct vm_area_struct * vma = NULL; struct task_struct *tsk = current; @@ -312,3 +313,13 @@ vmalloc_fault: } #endif } + +asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, + unsigned long write, unsigned long address) +{ + enum ctx_state prev_state; + + prev_state = exception_enter(); + __do_page_fault(regs, write, address); + exception_exit(prev_state); +} diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index 4eb8dcfaf1c..2c0bd580b9d 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -232,7 +232,7 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off) uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0); } - } + } } extern u32 __clear_page_start; diff --git a/arch/mips/mm/tlb-funcs.S b/arch/mips/mm/tlb-funcs.S new file mode 100644 index 00000000000..30a494db99c --- /dev/null +++ b/arch/mips/mm/tlb-funcs.S @@ -0,0 +1,37 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Micro-assembler generated tlb handler functions. + * + * Copyright (C) 2013 Broadcom Corporation. + * + * Based on mm/page-funcs.c + * Copyright (C) 2012 MIPS Technologies, Inc. + * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org> + */ +#include <asm/asm.h> +#include <asm/regdef.h> + +#define FASTPATH_SIZE 128 + +LEAF(tlbmiss_handler_setup_pgd) + .space 16 * 4 +END(tlbmiss_handler_setup_pgd) +EXPORT(tlbmiss_handler_setup_pgd_end) + +LEAF(handle_tlbm) + .space FASTPATH_SIZE * 4 +END(handle_tlbm) +EXPORT(handle_tlbm_end) + +LEAF(handle_tlbs) + .space FASTPATH_SIZE * 4 +END(handle_tlbs) +EXPORT(handle_tlbs_end) + +LEAF(handle_tlbl) + .space FASTPATH_SIZE * 4 +END(handle_tlbl) +EXPORT(handle_tlbl_end) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index afeef93f81a..9ab0f907a52 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -305,6 +305,17 @@ static int check_for_high_segbits __cpuinitdata; static unsigned int kscratch_used_mask __cpuinitdata; +static inline int __maybe_unused c0_kscratch(void) +{ + switch (current_cpu_type()) { + case CPU_XLP: + case CPU_XLR: + return 22; + default: + return 31; + } +} + static int __cpuinit allocate_kscratch(void) { int r; @@ -334,9 +345,9 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p) int smp_processor_id_sel; int smp_processor_id_shift; - if (scratch_reg > 0) { + if (scratch_reg >= 0) { /* Save in CPU local C0_KScratch? */ - UASM_i_MTC0(p, 1, 31, scratch_reg); + UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg); r.r1 = K0; r.r2 = K1; r.r3 = 1; @@ -384,8 +395,8 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p) static void __cpuinit build_restore_work_registers(u32 **p) { - if (scratch_reg > 0) { - UASM_i_MFC0(p, 1, 31, scratch_reg); + if (scratch_reg >= 0) { + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); return; } /* K0 already points to save area, restore $1 and $2 */ @@ -673,8 +684,8 @@ static __cpuinit void build_restore_pagemask(u32 **p, uasm_i_mtc0(p, 0, C0_PAGEMASK); uasm_il_b(p, r, lid); } - if (scratch_reg > 0) - UASM_i_MFC0(p, 1, 31, scratch_reg); + if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); else UASM_i_LW(p, 1, scratchpad_offset(0), 0); } else { @@ -817,7 +828,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, #ifdef CONFIG_MIPS_PGD_C0_CONTEXT if (pgd_reg != -1) { /* pgd is in pgd_reg */ - UASM_i_MFC0(p, ptr, 31, pgd_reg); + UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); } else { /* * &pgd << 11 stored in CONTEXT [23..63]. @@ -929,8 +940,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, uasm_i_jr(p, ptr); if (mode == refill_scratch) { - if (scratch_reg > 0) - UASM_i_MFC0(p, 1, 31, scratch_reg); + if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); else UASM_i_LW(p, 1, scratchpad_offset(0), 0); } else { @@ -961,7 +972,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) uasm_i_srl(p, ptr, ptr, 19); #else /* - * smp_processor_id() << 3 is stored in CONTEXT. + * smp_processor_id() << 2 is stored in CONTEXT. */ uasm_i_mfc0(p, ptr, C0_CONTEXT); UASM_i_LA_mostly(p, tmp, pgdc); @@ -1096,7 +1107,7 @@ struct mips_huge_tlb_info { static struct mips_huge_tlb_info __cpuinit build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int tmp, - unsigned int ptr, int c0_scratch) + unsigned int ptr, int c0_scratch_reg) { struct mips_huge_tlb_info rv; unsigned int even, odd; @@ -1110,12 +1121,12 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, UASM_i_MFC0(p, tmp, C0_BADVADDR); if (pgd_reg != -1) - UASM_i_MFC0(p, ptr, 31, pgd_reg); + UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); else UASM_i_MFC0(p, ptr, C0_CONTEXT); - if (c0_scratch >= 0) - UASM_i_MTC0(p, scratch, 31, c0_scratch); + if (c0_scratch_reg >= 0) + UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg); else UASM_i_SW(p, scratch, scratchpad_offset(0), 0); @@ -1130,14 +1141,14 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, } } else { if (pgd_reg != -1) - UASM_i_MFC0(p, ptr, 31, pgd_reg); + UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); else UASM_i_MFC0(p, ptr, C0_CONTEXT); UASM_i_MFC0(p, tmp, C0_BADVADDR); - if (c0_scratch >= 0) - UASM_i_MTC0(p, scratch, 31, c0_scratch); + if (c0_scratch_reg >= 0) + UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg); else UASM_i_SW(p, scratch, scratchpad_offset(0), 0); @@ -1242,8 +1253,8 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, } UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */ - if (c0_scratch >= 0) { - UASM_i_MFC0(p, scratch, 31, c0_scratch); + if (c0_scratch_reg >= 0) { + UASM_i_MFC0(p, scratch, c0_kscratch(), c0_scratch_reg); build_tlb_write_entry(p, l, r, tlb_random); uasm_l_leave(l, *p); rv.restore_scratch = 1; @@ -1286,7 +1297,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) memset(relocs, 0, sizeof(relocs)); memset(final_handler, 0, sizeof(final_handler)); - if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) { + if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) { htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1, scratch_reg); vmalloc_mode = refill_scratch; @@ -1444,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); } -/* - * 128 instructions for the fastpath handler is generous and should - * never be exceeded. - */ -#define FASTPATH_SIZE 128 +extern u32 handle_tlbl[], handle_tlbl_end[]; +extern u32 handle_tlbs[], handle_tlbs_end[]; +extern u32 handle_tlbm[], handle_tlbm_end[]; -u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned; -u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned; -u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned; #ifdef CONFIG_MIPS_PGD_C0_CONTEXT -u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned; +extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[]; static void __cpuinit build_r4000_setup_pgd(void) { const int a0 = 4; const int a1 = 5; u32 *p = tlbmiss_handler_setup_pgd_array; + const int tlbmiss_handler_setup_pgd_size = + tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; - memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array)); + memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size * + sizeof(tlbmiss_handler_setup_pgd[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -1490,17 +1499,17 @@ static void __cpuinit build_r4000_setup_pgd(void) } else { /* PGD in c0_KScratch */ uasm_i_jr(&p, 31); - UASM_i_MTC0(&p, a0, 31, pgd_reg); + UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); } - if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array)) - panic("tlbmiss_handler_setup_pgd_array space exceeded"); + if (p >= tlbmiss_handler_setup_pgd_end) + panic("tlbmiss_handler_setup_pgd space exceeded"); + uasm_resolve_relocs(relocs, labels); - pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n", - (unsigned int)(p - tlbmiss_handler_setup_pgd_array)); + pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n", + (unsigned int)(p - tlbmiss_handler_setup_pgd)); - dump_handler("tlbmiss_handler", - tlbmiss_handler_setup_pgd_array, - ARRAY_SIZE(tlbmiss_handler_setup_pgd_array)); + dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd, + tlbmiss_handler_setup_pgd_size); } #endif @@ -1745,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, static void __cpuinit build_r3000_tlb_load_handler(void) { u32 *p = handle_tlbl; + const int handle_tlbl_size = handle_tlbl_end - handle_tlbl; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; - memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -1762,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbl) > FASTPATH_SIZE) + if (p >= handle_tlbl_end) panic("TLB load handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbl)); - dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); + dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size); } static void __cpuinit build_r3000_tlb_store_handler(void) { u32 *p = handle_tlbs; + const int handle_tlbs_size = handle_tlbs_end - handle_tlbs; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; - memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -1792,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbs) > FASTPATH_SIZE) + if (p >= handle_tlbs) panic("TLB store handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbs)); - dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); + dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size); } static void __cpuinit build_r3000_tlb_modify_handler(void) { u32 *p = handle_tlbm; + const int handle_tlbm_size = handle_tlbm_end - handle_tlbm; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; - memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -1822,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbm) > FASTPATH_SIZE) + if (p >= handle_tlbm_end) panic("TLB modify handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbm)); - dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); + dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size); } #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ @@ -1893,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, static void __cpuinit build_r4000_tlb_load_handler(void) { u32 *p = handle_tlbl; + const int handle_tlbl_size = handle_tlbl_end - handle_tlbl; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; struct work_registers wr; - memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -1935,6 +1948,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void) uasm_i_nop(&p); uasm_i_tlbr(&p); + + switch (current_cpu_type()) { + default: + if (cpu_has_mips_r2) { + uasm_i_ehb(&p); + + case CPU_CAVIUM_OCTEON: + case CPU_CAVIUM_OCTEON_PLUS: + case CPU_CAVIUM_OCTEON2: + break; + } + } + /* Examine entrylo 0 or 1 based on ptr. */ if (use_bbit_insns()) { uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); @@ -1989,6 +2015,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void) uasm_i_nop(&p); uasm_i_tlbr(&p); + + switch (current_cpu_type()) { + default: + if (cpu_has_mips_r2) { + uasm_i_ehb(&p); + + case CPU_CAVIUM_OCTEON: + case CPU_CAVIUM_OCTEON_PLUS: + case CPU_CAVIUM_OCTEON2: + break; + } + } + /* Examine entrylo 0 or 1 based on ptr. */ if (use_bbit_insns()) { uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); @@ -2036,24 +2075,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbl) > FASTPATH_SIZE) + if (p >= handle_tlbl_end) panic("TLB load handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbl)); - dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); + dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size); } static void __cpuinit build_r4000_tlb_store_handler(void) { u32 *p = handle_tlbs; + const int handle_tlbs_size = handle_tlbs_end - handle_tlbs; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; struct work_registers wr; - memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -2090,24 +2130,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbs) > FASTPATH_SIZE) + if (p >= handle_tlbs_end) panic("TLB store handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbs)); - dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); + dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size); } static void __cpuinit build_r4000_tlb_modify_handler(void) { u32 *p = handle_tlbm; + const int handle_tlbm_size = handle_tlbm_end - handle_tlbm; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; struct work_registers wr; - memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); @@ -2145,14 +2186,28 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); - if ((p - handle_tlbm) > FASTPATH_SIZE) + if (p >= handle_tlbm_end) panic("TLB modify handler fastpath space exceeded"); uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbm)); - dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); + dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size); +} + +static void __cpuinit flush_tlb_handlers(void) +{ + local_flush_icache_range((unsigned long)handle_tlbl, + (unsigned long)handle_tlbl_end); + local_flush_icache_range((unsigned long)handle_tlbs, + (unsigned long)handle_tlbs_end); + local_flush_icache_range((unsigned long)handle_tlbm, + (unsigned long)handle_tlbm_end); +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT + local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd, + (unsigned long)tlbmiss_handler_setup_pgd_end); +#endif } void __cpuinit build_tlb_refill_handler(void) @@ -2187,6 +2242,7 @@ void __cpuinit build_tlb_refill_handler(void) build_r3000_tlb_load_handler(); build_r3000_tlb_store_handler(); build_r3000_tlb_modify_handler(); + flush_tlb_handlers(); run_once++; } #else @@ -2214,23 +2270,10 @@ void __cpuinit build_tlb_refill_handler(void) build_r4000_tlb_modify_handler(); if (!cpu_has_local_ebase) build_r4000_tlb_refill_handler(); + flush_tlb_handlers(); run_once++; } if (cpu_has_local_ebase) build_r4000_tlb_refill_handler(); } } - -void __cpuinit flush_tlb_handlers(void) -{ - local_flush_icache_range((unsigned long)handle_tlbl, - (unsigned long)handle_tlbl + sizeof(handle_tlbl)); - local_flush_icache_range((unsigned long)handle_tlbs, - (unsigned long)handle_tlbs + sizeof(handle_tlbs)); - local_flush_icache_range((unsigned long)handle_tlbm, - (unsigned long)handle_tlbm + sizeof(handle_tlbm)); -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT - local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array, - (unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm)); -#endif -} diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile index 0388fc8b561..72fdedbf76d 100644 --- a/arch/mips/mti-malta/Makefile +++ b/arch/mips/mti-malta/Makefile @@ -10,7 +10,6 @@ obj-y := malta-amon.o malta-display.o malta-init.o \ malta-reset.o malta-setup.o malta-time.o obj-$(CONFIG_EARLY_PRINTK) += malta-console.o -obj-$(CONFIG_PCI) += malta-pci.o # FIXME FIXME FIXME obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 0a1339ac3ec..c69da373469 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -422,8 +422,10 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { */ int __init gcmp_probe(unsigned long addr, unsigned long size) { - if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) { + if ((mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) && + (mips_revision_sconid != MIPS_REVISION_SCON_GT64120)) { gcmp_present = 0; + pr_debug("GCMP NOT present\n"); return gcmp_present; } diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c index 32942053624..d627d4b2b47 100644 --- a/arch/mips/mti-malta/malta-reset.c +++ b/arch/mips/mti-malta/malta-reset.c @@ -1,33 +1,18 @@ /* + * 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. + * * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Reset the MIPS boards. - * */ -#include <linux/init.h> +#include <linux/io.h> #include <linux/pm.h> -#include <asm/io.h> #include <asm/reboot.h> -#include <asm/mips-boards/generic.h> + +#define SOFTRES_REG 0x1f000500 +#define GORESET 0x42 static void mips_machine_restart(char *command) { @@ -45,7 +30,6 @@ static void mips_machine_halt(void) __raw_writel(GORESET, softres_reg); } - static int __init mips_reboot_setup(void) { _machine_restart = mips_machine_restart; @@ -54,5 +38,4 @@ static int __init mips_reboot_setup(void) return 0; } - arch_initcall(mips_reboot_setup); diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c index 20475c5e7b9..e6fb24414a7 100644 --- a/arch/mips/mti-sead3/sead3-reset.c +++ b/arch/mips/mti-sead3/sead3-reset.c @@ -9,7 +9,9 @@ #include <linux/pm.h> #include <asm/reboot.h> -#include <asm/mips-boards/generic.h> + +#define SOFTRES_REG 0x1f000050 +#define GORESET 0x4d static void mips_machine_restart(char *command) { @@ -35,5 +37,4 @@ static int __init mips_reboot_setup(void) return 0; } - arch_initcall(mips_reboot_setup); diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig index e0873a31eba..2447bf97d35 100644 --- a/arch/mips/netlogic/Kconfig +++ b/arch/mips/netlogic/Kconfig @@ -51,4 +51,15 @@ endif config NLM_COMMON bool +config IOMMU_HELPER + bool + +config NEED_SG_DMA_LENGTH + bool + +config SWIOTLB + def_bool y + select NEED_SG_DMA_LENGTH + select IOMMU_HELPER + endif diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile index 291372a086f..362739d62b1 100644 --- a/arch/mips/netlogic/common/Makefile +++ b/arch/mips/netlogic/common/Makefile @@ -1,3 +1,5 @@ obj-y += irq.o time.o +obj-y += nlm-dma.o +obj-y += reset.o obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_EARLY_PRINTK) += earlycons.o diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c index 9f84c60bf53..73facb2b33b 100644 --- a/arch/mips/netlogic/common/irq.c +++ b/arch/mips/netlogic/common/irq.c @@ -253,13 +253,12 @@ asmlinkage void plat_irq_dispatch(void) node = nlm_nodeid(); eirr = read_c0_eirr_and_eimr(); - - i = __ilog2_u64(eirr); - if (i == -1) + if (eirr == 0) return; + i = __ffs64(eirr); /* per-CPU IRQs don't need translation */ - if (eirr & PERCPU_IRQ_MASK) { + if (i < PIC_IRQ_BASE) { do_IRQ(i); return; } diff --git a/arch/mips/netlogic/common/nlm-dma.c b/arch/mips/netlogic/common/nlm-dma.c new file mode 100644 index 00000000000..f3d4ae87abc --- /dev/null +++ b/arch/mips/netlogic/common/nlm-dma.c @@ -0,0 +1,107 @@ +/* +* Copyright (C) 2003-2013 Broadcom Corporation +* All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ +#include <linux/dma-mapping.h> +#include <linux/scatterlist.h> +#include <linux/bootmem.h> +#include <linux/export.h> +#include <linux/swiotlb.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> + +#include <asm/bootinfo.h> + +static char *nlm_swiotlb; + +static void *nlm_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) +{ + void *ret; + + if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) + return ret; + + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); + +#ifdef CONFIG_ZONE_DMA32 + if (dev->coherent_dma_mask <= DMA_BIT_MASK(32)) + gfp |= __GFP_DMA32; +#endif + + /* Don't invoke OOM killer */ + gfp |= __GFP_NORETRY; + + return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); +} + +static void nlm_dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) +{ + int order = get_order(size); + + if (dma_release_from_coherent(dev, order, vaddr)) + return; + + swiotlb_free_coherent(dev, size, vaddr, dma_handle); +} + +struct dma_map_ops nlm_swiotlb_dma_ops = { + .alloc = nlm_dma_alloc_coherent, + .free = nlm_dma_free_coherent, + .map_page = swiotlb_map_page, + .unmap_page = swiotlb_unmap_page, + .map_sg = swiotlb_map_sg_attrs, + .unmap_sg = swiotlb_unmap_sg_attrs, + .sync_single_for_cpu = swiotlb_sync_single_for_cpu, + .sync_single_for_device = swiotlb_sync_single_for_device, + .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = swiotlb_sync_sg_for_device, + .mapping_error = swiotlb_dma_mapping_error, + .dma_supported = swiotlb_dma_supported +}; + +void __init plat_swiotlb_setup(void) +{ + size_t swiotlbsize; + unsigned long swiotlb_nslabs; + + swiotlbsize = 1 << 20; /* 1 MB for now */ + swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT; + swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE); + swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT; + + nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize); + swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1); +} diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S new file mode 100644 index 00000000000..adb18288a6c --- /dev/null +++ b/arch/mips/netlogic/common/reset.S @@ -0,0 +1,230 @@ +/* + * Copyright 2003-2013 Broadcom Corporation. + * All Rights Reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ + +#include <linux/init.h> + +#include <asm/asm.h> +#include <asm/asm-offsets.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> +#include <asm/asmmacro.h> +#include <asm/addrspace.h> + +#include <asm/netlogic/common.h> + +#include <asm/netlogic/xlp-hal/iomap.h> +#include <asm/netlogic/xlp-hal/xlp.h> +#include <asm/netlogic/xlp-hal/sys.h> +#include <asm/netlogic/xlp-hal/cpucontrol.h> + +#define CP0_EBASE $15 +#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \ + XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \ + SYS_CPU_NONCOHERENT_MODE * 4 + +/* Enable XLP features and workarounds in the LSU */ +.macro xlp_config_lsu + li t0, LSU_DEFEATURE + mfcr t1, t0 + + lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */ + or t1, t1, t2 + mtcr t1, t0 + + li t0, ICU_DEFEATURE + mfcr t1, t0 + ori t1, 0x1000 /* Enable Icache partitioning */ + mtcr t1, t0 + + li t0, SCHED_DEFEATURE + lui t1, 0x0100 /* Disable BRU accepting ALU ops */ + mtcr t1, t0 +.endm + +/* + * Low level flush for L1D cache on XLP, the normal cache ops does + * not do the complete and correct cache flush. + */ +.macro xlp_flush_l1_dcache + li t0, LSU_DEBUG_DATA0 + li t1, LSU_DEBUG_ADDR + li t2, 0 /* index */ + li t3, 0x1000 /* loop count */ +1: + sll v0, t2, 5 + mtcr zero, t0 + ori v1, v0, 0x3 /* way0 | write_enable | write_active */ + mtcr v1, t1 +2: + mfcr v1, t1 + andi v1, 0x1 /* wait for write_active == 0 */ + bnez v1, 2b + nop + mtcr zero, t0 + ori v1, v0, 0x7 /* way1 | write_enable | write_active */ + mtcr v1, t1 +3: + mfcr v1, t1 + andi v1, 0x1 /* wait for write_active == 0 */ + bnez v1, 3b + nop + addi t2, 1 + bne t3, t2, 1b + nop +.endm + +/* + * nlm_reset_entry will be copied to the reset entry point for + * XLR and XLP. The XLP cores start here when they are woken up. This + * is also the NMI entry point. + * + * We use scratch reg 6/7 to save k0/k1 and check for NMI first. + * + * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS + * location, this will have the thread mask (used when core is woken up) + * and the current NMI handler in case we reached here for an NMI. + * + * When a core or thread is newly woken up, it marks itself ready and + * loops in a 'wait'. When the CPU really needs waking up, we send an NMI + * IPI to it, with the NMI handler set to prom_boot_secondary_cpus + */ + .set noreorder + .set noat + .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ + +FEXPORT(nlm_reset_entry) + dmtc0 k0, $22, 6 + dmtc0 k1, $22, 7 + mfc0 k0, CP0_STATUS + li k1, 0x80000 + and k1, k0, k1 + beqz k1, 1f /* go to real reset entry */ + nop + li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */ + ld k0, BOOT_NMI_HANDLER(k1) + jr k0 + nop + +1: /* Entry point on core wakeup */ + mfc0 t0, CP0_EBASE, 1 + mfc0 t1, CP0_EBASE, 1 + srl t1, 5 + andi t1, 0x3 /* t1 <- node */ + li t2, 0x40000 + mul t3, t2, t1 /* t3 = node * 0x40000 */ + srl t0, t0, 2 + and t0, t0, 0x7 /* t0 <- core */ + li t1, 0x1 + sll t0, t1, t0 + nor t0, t0, zero /* t0 <- ~(1 << core) */ + li t2, SYS_CPU_COHERENT_BASE(0) + add t2, t2, t3 /* t2 <- SYS offset for node */ + lw t1, 0(t2) + and t1, t1, t0 + sw t1, 0(t2) + + /* read back to ensure complete */ + lw t1, 0(t2) + sync + + /* Configure LSU on Non-0 Cores. */ + xlp_config_lsu + /* FALL THROUGH */ + +/* + * Wake up sibling threads from the initial thread in + * a core. + */ +EXPORT(nlm_boot_siblings) + /* core L1D flush before enable threads */ + xlp_flush_l1_dcache + /* Enable hw threads by writing to MAP_THREADMODE of the core */ + li t0, CKSEG1ADDR(RESET_DATA_PHYS) + lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ + li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE) + mfcr t2, t0 + or t2, t2, t1 + mtcr t2, t0 + + /* + * The new hardware thread starts at the next instruction + * For all the cases other than core 0 thread 0, we will + * jump to the secondary wait function. + */ + mfc0 v0, CP0_EBASE, 1 + andi v0, 0x3ff /* v0 <- node/core */ + + beqz v0, 4f /* boot cpu (cpuid == 0)? */ + nop + + /* setup status reg */ + move t1, zero +#ifdef CONFIG_64BIT + ori t1, ST0_KX +#endif + mtc0 t1, CP0_STATUS + + /* mark CPU ready, careful here, previous mtcr trashed registers */ + li t3, CKSEG1ADDR(RESET_DATA_PHYS) + ADDIU t1, t3, BOOT_CPU_READY + sll v1, v0, 2 + PTR_ADDU t1, v1 + li t2, 1 + sw t2, 0(t1) + /* Wait until NMI hits */ +3: wait + b 3b + nop + + /* + * For the boot CPU, we have to restore registers and + * return + */ +4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ + li t1, 0xfadebeef + dmtc0 t1, $4, 2 /* restore SP from UserLocal */ + PTR_SUBU sp, t0, PT_SIZE + RESTORE_ALL + jr ra + nop +EXPORT(nlm_reset_entry_end) + +LEAF(nlm_init_boot_cpu) +#ifdef CONFIG_CPU_XLP + xlp_config_lsu +#endif + jr ra + nop +END(nlm_init_boot_cpu) diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index ffba52489be..885d293b61d 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -145,7 +145,6 @@ void nlm_cpus_done(void) * Boot all other cpus in the system, initialize them, and bring them into * the boot function */ -int nlm_cpu_ready[NR_CPUS]; unsigned long nlm_next_gp; unsigned long nlm_next_sp; static cpumask_t phys_cpu_present_mask; @@ -168,6 +167,7 @@ void __init nlm_smp_setup(void) { unsigned int boot_cpu; int num_cpus, i, ncore; + volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY); char buf[64]; boot_cpu = hard_smp_processor_id(); @@ -181,10 +181,10 @@ void __init nlm_smp_setup(void) num_cpus = 1; for (i = 0; i < NR_CPUS; i++) { /* - * nlm_cpu_ready array is not set for the boot_cpu, + * cpu_ready array is not set for the boot_cpu, * it is only set for ASPs (see smpboot.S) */ - if (nlm_cpu_ready[i]) { + if (cpu_ready[i]) { cpumask_set_cpu(i, &phys_cpu_present_mask); __cpu_number_map[i] = num_cpus; __cpu_logical_map[num_cpus] = i; @@ -254,21 +254,15 @@ unsupp: int __cpuinit nlm_wakeup_secondary_cpus(void) { - unsigned long reset_vec; - char *reset_data; + u32 *reset_data; int threadmode; - /* Update reset entry point with CPU init code */ - reset_vec = CKSEG1ADDR(RESET_VEC_PHYS); - memcpy((void *)reset_vec, (void *)nlm_reset_entry, - (nlm_reset_entry_end - nlm_reset_entry)); - /* verify the mask and setup core config variables */ threadmode = nlm_parse_cpumask(&nlm_cpumask); /* Setup CPU init parameters */ - reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); - *(int *)(reset_data + BOOT_THREAD_MODE) = threadmode; + reset_data = nlm_get_boot_data(BOOT_THREAD_MODE); + *reset_data = threadmode; #ifdef CONFIG_CPU_XLP xlp_wakeup_secondary_cpus(); diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index 02651748858..528c46c5a17 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S @@ -50,197 +50,12 @@ #include <asm/netlogic/xlp-hal/cpucontrol.h> #define CP0_EBASE $15 -#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \ - XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \ - SYS_CPU_NONCOHERENT_MODE * 4 - -#define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */ - -/* Enable XLP features and workarounds in the LSU */ -.macro xlp_config_lsu - li t0, LSU_DEFEATURE - mfcr t1, t0 - - lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */ - or t1, t1, t2 -#ifdef XLP_AX_WORKAROUND - li t2, ~0xe /* S1RCM */ - and t1, t1, t2 -#endif - mtcr t1, t0 - - li t0, ICU_DEFEATURE - mfcr t1, t0 - ori t1, 0x1000 /* Enable Icache partitioning */ - mtcr t1, t0 - - -#ifdef XLP_AX_WORKAROUND - li t0, SCHED_DEFEATURE - lui t1, 0x0100 /* Disable BRU accepting ALU ops */ - mtcr t1, t0 -#endif -.endm - -/* - * This is the code that will be copied to the reset entry point for - * XLR and XLP. The XLP cores start here when they are woken up. This - * is also the NMI entry point. - */ -.macro xlp_flush_l1_dcache - li t0, LSU_DEBUG_DATA0 - li t1, LSU_DEBUG_ADDR - li t2, 0 /* index */ - li t3, 0x1000 /* loop count */ -1: - sll v0, t2, 5 - mtcr zero, t0 - ori v1, v0, 0x3 /* way0 | write_enable | write_active */ - mtcr v1, t1 -2: - mfcr v1, t1 - andi v1, 0x1 /* wait for write_active == 0 */ - bnez v1, 2b - nop - mtcr zero, t0 - ori v1, v0, 0x7 /* way1 | write_enable | write_active */ - mtcr v1, t1 -3: - mfcr v1, t1 - andi v1, 0x1 /* wait for write_active == 0 */ - bnez v1, 3b - nop - addi t2, 1 - bne t3, t2, 1b - nop -.endm - -/* - * The cores can come start when they are woken up. This is also the NMI - * entry, so check that first. - * - * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS - * location, this will have the thread mask (used when core is woken up) - * and the current NMI handler in case we reached here for an NMI. - * - * When a core or thread is newly woken up, it loops in a 'wait'. When - * the CPU really needs waking up, we send an NMI to it, with the NMI - * handler set to prom_boot_secondary_cpus - */ .set noreorder .set noat - .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ - -FEXPORT(nlm_reset_entry) - dmtc0 k0, $22, 6 - dmtc0 k1, $22, 7 - mfc0 k0, CP0_STATUS - li k1, 0x80000 - and k1, k0, k1 - beqz k1, 1f /* go to real reset entry */ - nop - li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */ - ld k0, BOOT_NMI_HANDLER(k1) - jr k0 - nop - -1: /* Entry point on core wakeup */ - mfc0 t0, CP0_EBASE, 1 - mfc0 t1, CP0_EBASE, 1 - srl t1, 5 - andi t1, 0x3 /* t1 <- node */ - li t2, 0x40000 - mul t3, t2, t1 /* t3 = node * 0x40000 */ - srl t0, t0, 2 - and t0, t0, 0x7 /* t0 <- core */ - li t1, 0x1 - sll t0, t1, t0 - nor t0, t0, zero /* t0 <- ~(1 << core) */ - li t2, SYS_CPU_COHERENT_BASE(0) - add t2, t2, t3 /* t2 <- SYS offset for node */ - lw t1, 0(t2) - and t1, t1, t0 - sw t1, 0(t2) - - /* read back to ensure complete */ - lw t1, 0(t2) - sync - - /* Configure LSU on Non-0 Cores. */ - xlp_config_lsu - /* FALL THROUGH */ - -/* - * Wake up sibling threads from the initial thread in - * a core. - */ -EXPORT(nlm_boot_siblings) - /* core L1D flush before enable threads */ - xlp_flush_l1_dcache - /* Enable hw threads by writing to MAP_THREADMODE of the core */ - li t0, CKSEG1ADDR(RESET_DATA_PHYS) - lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ - li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE) - mfcr t2, t0 - or t2, t2, t1 - mtcr t2, t0 - - /* - * The new hardware thread starts at the next instruction - * For all the cases other than core 0 thread 0, we will - * jump to the secondary wait function. - */ - mfc0 v0, CP0_EBASE, 1 - andi v0, 0x3ff /* v0 <- node/core */ - - /* Init MMU in the first thread after changing THREAD_MODE - * register (Ax Errata?) - */ - andi v1, v0, 0x3 /* v1 <- thread id */ - bnez v1, 2f - nop - - li t0, MMU_SETUP - li t1, 0 - mtcr t1, t0 - _ehb - -2: beqz v0, 4f /* boot cpu (cpuid == 0)? */ - nop - - /* setup status reg */ - move t1, zero -#ifdef CONFIG_64BIT - ori t1, ST0_KX -#endif - mtc0 t1, CP0_STATUS - /* mark CPU ready */ - PTR_LA t1, nlm_cpu_ready - sll v1, v0, 2 - PTR_ADDU t1, v1 - li t2, 1 - sw t2, 0(t1) - /* Wait until NMI hits */ -3: wait - j 3b - nop - - /* - * For the boot CPU, we have to restore registers and - * return - */ -4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ - li t1, 0xfadebeef - dmtc0 t1, $4, 2 /* restore SP from UserLocal */ - PTR_SUBU sp, t0, PT_SIZE - RESTORE_ALL - jr ra - nop -EXPORT(nlm_reset_entry_end) + .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ - xlp_config_lsu dmtc0 sp, $4, 2 /* SP saved in UserLocal */ SAVE_ALL sync @@ -294,8 +109,9 @@ NESTED(nlm_rmiboot_preboot, 16, sp) andi t2, t0, 0x3 /* thread num */ sll t0, 2 /* offset in cpu array */ - PTR_LA t1, nlm_cpu_ready /* mark CPU ready */ - PTR_ADDU t1, t0 + li t3, CKSEG1ADDR(RESET_DATA_PHYS) + ADDIU t1, t3, BOOT_CPU_READY + ADDU t1, t0 li t3, 1 sw t3, 0(t1) @@ -321,7 +137,7 @@ NESTED(nlm_rmiboot_preboot, 16, sp) mtcr t1, t0 /* update core control */ 1: wait - j 1b + b 1b nop END(nlm_rmiboot_preboot) __FINIT diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile index a84d6ed3746..85ac4a892ce 100644 --- a/arch/mips/netlogic/xlp/Makefile +++ b/arch/mips/netlogic/xlp/Makefile @@ -1,3 +1,3 @@ -obj-y += setup.o nlm_hal.o +obj-y += setup.o nlm_hal.o cop2-ex.o dt.o obj-$(CONFIG_SMP) += wakeup.o obj-$(CONFIG_USB) += usb-init.o diff --git a/arch/mips/netlogic/xlp/cop2-ex.c b/arch/mips/netlogic/xlp/cop2-ex.c new file mode 100644 index 00000000000..52bc5de4200 --- /dev/null +++ b/arch/mips/netlogic/xlp/cop2-ex.c @@ -0,0 +1,118 @@ +/* + * 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) 2013 Broadcom Corporation. + * + * based on arch/mips/cavium-octeon/cpu.c + * Copyright (C) 2009 Wind River Systems, + * written by Ralf Baechle <ralf@linux-mips.org> + */ +#include <linux/init.h> +#include <linux/irqflags.h> +#include <linux/notifier.h> +#include <linux/prefetch.h> +#include <linux/sched.h> + +#include <asm/cop2.h> +#include <asm/current.h> +#include <asm/mipsregs.h> +#include <asm/page.h> + +#include <asm/netlogic/mips-extns.h> + +/* + * 64 bit ops are done in inline assembly to support 32 bit + * compilation + */ +void nlm_cop2_save(struct nlm_cop2_state *r) +{ + asm volatile( + ".set push\n" + ".set noat\n" + "dmfc2 $1, $0, 0\n" + "sd $1, 0(%1)\n" + "dmfc2 $1, $0, 1\n" + "sd $1, 8(%1)\n" + "dmfc2 $1, $0, 2\n" + "sd $1, 16(%1)\n" + "dmfc2 $1, $0, 3\n" + "sd $1, 24(%1)\n" + "dmfc2 $1, $1, 0\n" + "sd $1, 0(%2)\n" + "dmfc2 $1, $1, 1\n" + "sd $1, 8(%2)\n" + "dmfc2 $1, $1, 2\n" + "sd $1, 16(%2)\n" + "dmfc2 $1, $1, 3\n" + "sd $1, 24(%2)\n" + ".set pop\n" + : "=m"(*r) + : "r"(r->tx), "r"(r->rx)); + + r->tx_msg_status = __read_32bit_c2_register($2, 0); + r->rx_msg_status = __read_32bit_c2_register($3, 0) & 0x0fffffff; +} + +void nlm_cop2_restore(struct nlm_cop2_state *r) +{ + u32 rstat; + + asm volatile( + ".set push\n" + ".set noat\n" + "ld $1, 0(%1)\n" + "dmtc2 $1, $0, 0\n" + "ld $1, 8(%1)\n" + "dmtc2 $1, $0, 1\n" + "ld $1, 16(%1)\n" + "dmtc2 $1, $0, 2\n" + "ld $1, 24(%1)\n" + "dmtc2 $1, $0, 3\n" + "ld $1, 0(%2)\n" + "dmtc2 $1, $1, 0\n" + "ld $1, 8(%2)\n" + "dmtc2 $1, $1, 1\n" + "ld $1, 16(%2)\n" + "dmtc2 $1, $1, 2\n" + "ld $1, 24(%2)\n" + "dmtc2 $1, $1, 3\n" + ".set pop\n" + : : "m"(*r), "r"(r->tx), "r"(r->rx)); + + __write_32bit_c2_register($2, 0, r->tx_msg_status); + rstat = __read_32bit_c2_register($3, 0) & 0xf0000000u; + __write_32bit_c2_register($3, 0, r->rx_msg_status | rstat); +} + +static int nlm_cu2_call(struct notifier_block *nfb, unsigned long action, + void *data) +{ + unsigned long flags; + unsigned int status; + + switch (action) { + case CU2_EXCEPTION: + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) + break; + local_irq_save(flags); + KSTK_STATUS(current) |= ST0_CU2; + status = read_c0_status(); + write_c0_status(status | ST0_CU2); + nlm_cop2_restore(&(current->thread.cp2)); + write_c0_status(status & ~ST0_CU2); + local_irq_restore(flags); + pr_info("COP2 access enabled for pid %d (%s)\n", + current->pid, current->comm); + return NOTIFY_BAD; /* Don't call default notifier */ + } + + return NOTIFY_OK; /* Let default notifier send signals */ +} + +static int __init nlm_cu2_setup(void) +{ + return cu2_notifier(nlm_cu2_call, 0); +} +early_initcall(nlm_cu2_setup); diff --git a/arch/mips/netlogic/xlp/dt.c b/arch/mips/netlogic/xlp/dt.c new file mode 100644 index 00000000000..a15cdbb8d0b --- /dev/null +++ b/arch/mips/netlogic/xlp/dt.c @@ -0,0 +1,99 @@ +/* + * Copyright 2003-2013 Broadcom Corporation. + * All Rights Reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ + +#include <linux/kernel.h> +#include <linux/bootmem.h> + +#include <linux/of_fdt.h> +#include <linux/of_platform.h> +#include <linux/of_device.h> + +extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[]; + +void __init *xlp_dt_init(void *fdtp) +{ + if (!fdtp) { + switch (current_cpu_data.processor_id & 0xff00) { +#ifdef CONFIG_DT_XLP_SVP + case PRID_IMP_NETLOGIC_XLP3XX: + fdtp = __dtb_xlp_svp_begin; + break; +#endif +#ifdef CONFIG_DT_XLP_EVP + case PRID_IMP_NETLOGIC_XLP8XX: + fdtp = __dtb_xlp_evp_begin; + break; +#endif + default: + /* Pick a built-in if any, and hope for the best */ + fdtp = __dtb_start; + break; + } + } + initial_boot_params = fdtp; + return fdtp; +} + +void __init device_tree_init(void) +{ + unsigned long base, size; + + if (!initial_boot_params) + return; + + base = virt_to_phys((void *)initial_boot_params); + size = be32_to_cpu(initial_boot_params->totalsize); + + /* Before we do anything, lets reserve the dt blob */ + reserve_bootmem(base, size, BOOTMEM_DEFAULT); + + unflatten_device_tree(); + + /* free the space reserved for the dt blob */ + free_bootmem(base, size); +} + +static struct of_device_id __initdata xlp_ids[] = { + { .compatible = "simple-bus", }, + {}, +}; + +int __init xlp8xx_ds_publish_devices(void) +{ + if (!of_have_populated_dt()) + return 0; + return of_platform_bus_probe(NULL, xlp_ids, NULL); +} + +device_initcall(xlp8xx_ds_publish_devices); diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index eaa99d28cb8..7b638f7be49 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -33,19 +33,13 @@ */ #include <linux/kernel.h> -#include <linux/serial_8250.h> -#include <linux/pm.h> -#include <linux/bootmem.h> +#include <linux/of_fdt.h> #include <asm/idle.h> #include <asm/reboot.h> #include <asm/time.h> #include <asm/bootinfo.h> -#include <linux/of_fdt.h> -#include <linux/of_platform.h> -#include <linux/of_device.h> - #include <asm/netlogic/haldefs.h> #include <asm/netlogic/common.h> @@ -57,7 +51,6 @@ uint64_t nlm_io_base; struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; cpumask_t nlm_cpumask = CPU_MASK_CPU0; unsigned int nlm_threads_per_core; -extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[]; static void nlm_linux_exit(void) { @@ -68,41 +61,28 @@ static void nlm_linux_exit(void) cpu_wait(); } -void __init plat_mem_setup(void) +static void nlm_fixup_mem(void) { - void *fdtp; + const int pref_backup = 512; + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + boot_mem_map.map[i].size -= pref_backup; + } +} +void __init plat_mem_setup(void) +{ panic_timeout = 5; _machine_restart = (void (*)(char *))nlm_linux_exit; _machine_halt = nlm_linux_exit; pm_power_off = nlm_linux_exit; - /* - * If no FDT pointer is passed in, use the built-in FDT. - * device_tree_init() does not handle CKSEG0 pointers in - * 64-bit, so convert pointer. - */ - fdtp = (void *)(long)fw_arg0; - if (!fdtp) { - switch (current_cpu_data.processor_id & 0xff00) { -#ifdef CONFIG_DT_XLP_SVP - case PRID_IMP_NETLOGIC_XLP3XX: - fdtp = __dtb_xlp_svp_begin; - break; -#endif -#ifdef CONFIG_DT_XLP_EVP - case PRID_IMP_NETLOGIC_XLP8XX: - fdtp = __dtb_xlp_evp_begin; - break; -#endif - default: - /* Pick a built-in if any, and hope for the best */ - fdtp = __dtb_start; - break; - } - } - fdtp = phys_to_virt(__pa(fdtp)); - early_init_devtree(fdtp); + /* memory and bootargs from DT */ + early_init_devtree(initial_boot_params); + nlm_fixup_mem(); } const char *get_system_type(void) @@ -131,9 +111,19 @@ void nlm_percpu_init(int hwcpuid) void __init prom_init(void) { + void *reset_vec; + nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); + nlm_init_boot_cpu(); xlp_mmu_init(); nlm_node_init(0); + xlp_dt_init((void *)(long)fw_arg0); + + /* Update reset entry point with CPU init code */ + reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS); + memset(reset_vec, 0, RESET_VEC_SIZE); + memcpy(reset_vec, (void *)nlm_reset_entry, + (nlm_reset_entry_end - nlm_reset_entry)); #ifdef CONFIG_SMP cpumask_setall(&nlm_cpumask); @@ -145,36 +135,3 @@ void __init prom_init(void) register_smp_ops(&nlm_smp_ops); #endif } - -void __init device_tree_init(void) -{ - unsigned long base, size; - - if (!initial_boot_params) - return; - - base = virt_to_phys((void *)initial_boot_params); - size = be32_to_cpu(initial_boot_params->totalsize); - - /* Before we do anything, lets reserve the dt blob */ - reserve_bootmem(base, size, BOOTMEM_DEFAULT); - - unflatten_device_tree(); - - /* free the space reserved for the dt blob */ - free_bootmem(base, size); -} - -static struct of_device_id __initdata xlp_ids[] = { - { .compatible = "simple-bus", }, - {}, -}; - -int __init xlp8xx_ds_publish_devices(void) -{ - if (!of_have_populated_dt()) - return 0; - return of_platform_bus_probe(NULL, xlp_ids, NULL); -} - -device_initcall(xlp8xx_ds_publish_devices); diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index abb3e08cc05..0cce37cbffe 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c @@ -77,12 +77,28 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core) return count != 0; } +static int wait_for_cpus(int cpu, int bootcpu) +{ + volatile uint32_t *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY); + int i, count, notready; + + count = 0x20000000; + do { + notready = nlm_threads_per_core; + for (i = 0; i < nlm_threads_per_core; i++) + if (cpu_ready[cpu + i] || cpu == bootcpu) + --notready; + } while (notready != 0 && --count > 0); + + return count != 0; +} + static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) { struct nlm_soc_info *nodep; uint64_t syspcibase; uint32_t syscoremask; - int core, n, cpu, count, val; + int core, n, cpu; for (n = 0; n < NLM_NR_NODES; n++) { syspcibase = nlm_get_sys_pcibase(n); @@ -122,11 +138,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) /* core is up */ nodep->coremask |= 1u << core; - /* spin until the first hw thread sets its ready */ - count = 0x20000000; - do { - val = *(volatile int *)&nlm_cpu_ready[cpu]; - } while (val == 0 && --count > 0); + /* spin until the hw threads sets their ready */ + wait_for_cpus(cpu, 0); } } } @@ -138,6 +151,7 @@ void xlp_wakeup_secondary_cpus() * first wakeup core 0 threads */ xlp_boot_core0_siblings(); + wait_for_cpus(0, 0); /* now get other cores out of reset */ xlp_enable_secondary_cores(&nlm_cpumask); diff --git a/arch/mips/netlogic/xlr/fmn.c b/arch/mips/netlogic/xlr/fmn.c index 4d74f03de50..d428e8471ee 100644 --- a/arch/mips/netlogic/xlr/fmn.c +++ b/arch/mips/netlogic/xlr/fmn.c @@ -74,13 +74,13 @@ static irqreturn_t fmn_message_handler(int irq, void *data) struct nlm_fmn_msg msg; uint32_t mflags, bkt_status; - mflags = nlm_cop2_enable(); + mflags = nlm_cop2_enable_irqsave(); /* Disable message ring interrupt */ nlm_fmn_setup_intr(irq, 0); while (1) { /* 8 bkts per core, [24:31] each bit represents one bucket * Bit is Zero if bucket is not empty */ - bkt_status = (nlm_read_c2_status() >> 24) & 0xff; + bkt_status = (nlm_read_c2_status0() >> 24) & 0xff; if (bkt_status == 0xff) break; for (bucket = 0; bucket < 8; bucket++) { @@ -97,16 +97,16 @@ static irqreturn_t fmn_message_handler(int irq, void *data) pr_warn("No msgring handler for stnid %d\n", src_stnid); else { - nlm_cop2_restore(mflags); + nlm_cop2_disable_irqrestore(mflags); hndlr->action(bucket, src_stnid, size, code, &msg, hndlr->arg); - mflags = nlm_cop2_enable(); + mflags = nlm_cop2_enable_irqsave(); } } }; /* Enable message ring intr, to any thread in core */ nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1); - nlm_cop2_restore(mflags); + nlm_cop2_disable_irqrestore(mflags); return IRQ_HANDLED; } @@ -128,7 +128,7 @@ void xlr_percpu_fmn_init(void) bucket_sizes = xlr_board_fmn_config.bucket_size; cpu_fmn_info = &xlr_board_fmn_config.cpu[id]; - flags = nlm_cop2_enable(); + flags = nlm_cop2_enable_irqsave(); /* Setup bucket sizes for the core. */ nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]); @@ -166,7 +166,7 @@ void xlr_percpu_fmn_init(void) /* enable FMN interrupts on this CPU */ nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); - nlm_cop2_restore(flags); + nlm_cop2_disable_irqrestore(flags); } @@ -198,7 +198,7 @@ void nlm_setup_fmn_irq(void) /* setup irq only once */ setup_irq(IRQ_FMN, &fmn_irqaction); - flags = nlm_cop2_enable(); + flags = nlm_cop2_enable_irqsave(); nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); - nlm_cop2_restore(flags); + nlm_cop2_disable_irqrestore(flags); } diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index 89c8c106663..214d123b79f 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c @@ -196,6 +196,7 @@ void __init prom_init(void) { int *argv, *envp; /* passed as 32 bit ptrs */ struct psb_info *prom_infop; + void *reset_vec; #ifdef CONFIG_SMP int i; #endif @@ -208,6 +209,12 @@ void __init prom_init(void) nlm_prom_info = *prom_infop; nlm_init_node(); + /* Update reset entry point with CPU init code */ + reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS); + memset(reset_vec, 0, RESET_VEC_SIZE); + memcpy(reset_vec, (void *)nlm_reset_entry, + (nlm_reset_entry_end - nlm_reset_entry)); + nlm_early_serial_setup(); build_arcs_cmdline(argv); prom_add_memory(); diff --git a/arch/mips/netlogic/xlr/wakeup.c b/arch/mips/netlogic/xlr/wakeup.c index 3ebf7411d67..c06e4c9f047 100644 --- a/arch/mips/netlogic/xlr/wakeup.c +++ b/arch/mips/netlogic/xlr/wakeup.c @@ -53,6 +53,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void) { struct nlm_soc_info *nodep; unsigned int i, j, boot_cpu; + volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY); /* * In case of RMI boot, hit with NMI to get the cores @@ -71,7 +72,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void) nodep->coremask = 1; for (i = 1; i < NLM_CORES_PER_NODE; i++) { for (j = 1000000; j > 0; j--) { - if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE]) + if (cpu_ready[i * NLM_THREADS_PER_CORE]) break; udelay(10); } diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 2cb1d315d22..c382042911d 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o -obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o +obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o @@ -52,12 +52,11 @@ obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o -obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o +obj-$(CONFIG_CAVIUM_OCTEON_SOC) += pci-octeon.o pcie-octeon.o obj-$(CONFIG_CPU_XLR) += pci-xlr.o obj-$(CONFIG_CPU_XLP) += pci-xlp.o ifdef CONFIG_PCI_MSI -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o +obj-$(CONFIG_CAVIUM_OCTEON_SOC) += msi-octeon.o endif diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c deleted file mode 100644 index 29737edd121..00000000000 --- a/arch/mips/pci/fixup-wrppmc.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * fixup-wrppmc.c: PPMC board specific PCI fixup - * - * 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) 2006, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com) - */ -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/gt64120.h> - -/* PCI interrupt pins */ -#define PCI_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 - -#define PCI_SLOT_MAXNR 32 /* Each PCI bus has 32 physical slots */ - -static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = { - /* 0 INTA INTB INTC INTD */ - [0] = {0, 0, 0, 0, 0}, /* Slot 0: GT64120 PCI bridge */ - [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0}, -}; - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - return pci_irq_tab[slot][pin]; -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c index 2eb954239bc..151d9b5870b 100644 --- a/arch/mips/pci/pci-bcm63xx.c +++ b/arch/mips/pci/pci-bcm63xx.c @@ -266,7 +266,7 @@ static int __init bcm63xx_register_pci(void) /* setup PCI to local bus access, used by PCI device to target * local RAM while bus mastering */ bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3); - if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) + if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) val = MPI_SP0_REMAP_ENABLE_MASK; else val = 0; @@ -338,6 +338,7 @@ static int __init bcm63xx_pci_init(void) case BCM6328_CPU_ID: case BCM6362_CPU_ID: return bcm63xx_register_pcie(); + case BCM3368_CPU_ID: case BCM6348_CPU_ID: case BCM6358_CPU_ID: case BCM6368_CPU_ID: diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 6eb65e44d9e..7b2ac81e1f5 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -217,6 +217,7 @@ static void pci_fixup_ioc3(struct pci_dev *d) pci_disable_swapping(d); } +#ifdef CONFIG_NUMA int pcibus_to_node(struct pci_bus *bus) { struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); @@ -224,6 +225,7 @@ int pcibus_to_node(struct pci_bus *bus) return bc->nasid; } EXPORT_SYMBOL(pcibus_to_node); +#endif /* CONFIG_NUMA */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, pci_fixup_ioc3); diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/pci/pci-malta.c index 37134ddfeaa..37134ddfeaa 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/pci/pci-malta.c diff --git a/arch/mips/pmcs-msp71xx/Makefile b/arch/mips/pmcs-msp71xx/Makefile index cefba7733b7..9201c8b3858 100644 --- a/arch/mips/pmcs-msp71xx/Makefile +++ b/arch/mips/pmcs-msp71xx/Makefile @@ -3,7 +3,6 @@ # obj-y += msp_prom.o msp_setup.o msp_irq.o \ msp_time.o msp_serial.o msp_elb.o -obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o diff --git a/arch/mips/pmcs-msp71xx/gpio.c b/arch/mips/pmcs-msp71xx/gpio.c deleted file mode 100644 index aaccbe52438..00000000000 --- a/arch/mips/pmcs-msp71xx/gpio.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Generic PMC MSP71xx GPIO handling. These base gpio are controlled by two - * types of registers. The data register sets the output level when in output - * mode and when in input mode will contain the value at the input. The config - * register sets the various modes for each gpio. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * @author Patrick Glass <patrickglass@gmail.com> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/spinlock.h> -#include <linux/io.h> - -#define MSP71XX_CFG_OFFSET(gpio) (4 * (gpio)) -#define CONF_MASK 0x0F -#define MSP71XX_GPIO_INPUT 0x01 -#define MSP71XX_GPIO_OUTPUT 0x08 - -#define MSP71XX_GPIO_BASE 0x0B8400000L - -#define to_msp71xx_gpio_chip(c) container_of(c, struct msp71xx_gpio_chip, chip) - -static spinlock_t gpio_lock; - -/* - * struct msp71xx_gpio_chip - container for gpio chip and registers - * @chip: chip structure for the specified gpio bank - * @data_reg: register for reading and writing the gpio pin value - * @config_reg: register to set the mode for the gpio pin bank - * @out_drive_reg: register to set the output drive mode for the gpio pin bank - */ -struct msp71xx_gpio_chip { - struct gpio_chip chip; - void __iomem *data_reg; - void __iomem *config_reg; - void __iomem *out_drive_reg; -}; - -/* - * msp71xx_gpio_get() - return the chip's gpio value - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose value will be returned - * - * It will return 0 if gpio value is low and other if high. - */ -static int msp71xx_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip); - - return __raw_readl(msp_chip->data_reg) & (1 << offset); -} - -/* - * msp71xx_gpio_set() - set the output value for the gpio - * @chip: chip structure who controls the specified gpio - * @offset: gpio whose value will be assigned - * @value: logic level to assign to the gpio initially - * - * This will set the gpio bit specified to the desired value. It will set the - * gpio pin low if value is 0 otherwise it will be high. - */ -static void msp71xx_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip); - unsigned long flags; - u32 data; - - spin_lock_irqsave(&gpio_lock, flags); - - data = __raw_readl(msp_chip->data_reg); - if (value) - data |= (1 << offset); - else - data &= ~(1 << offset); - __raw_writel(data, msp_chip->data_reg); - - spin_unlock_irqrestore(&gpio_lock, flags); -} - -/* - * msp71xx_set_gpio_mode() - declare the mode for a gpio - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose value will be assigned - * @mode: desired configuration for the gpio (see datasheet) - * - * It will set the gpio pin config to the @mode value passed in. - */ -static int msp71xx_set_gpio_mode(struct gpio_chip *chip, - unsigned offset, int mode) -{ - struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip); - const unsigned bit_offset = MSP71XX_CFG_OFFSET(offset); - unsigned long flags; - u32 cfg; - - spin_lock_irqsave(&gpio_lock, flags); - - cfg = __raw_readl(msp_chip->config_reg); - cfg &= ~(CONF_MASK << bit_offset); - cfg |= (mode << bit_offset); - __raw_writel(cfg, msp_chip->config_reg); - - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -} - -/* - * msp71xx_direction_output() - declare the direction mode for a gpio - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose value will be assigned - * @value: logic level to assign to the gpio initially - * - * This call will set the mode for the @gpio to output. It will set the - * gpio pin low if value is 0 otherwise it will be high. - */ -static int msp71xx_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - msp71xx_gpio_set(chip, offset, value); - - return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_OUTPUT); -} - -/* - * msp71xx_direction_input() - declare the direction mode for a gpio - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose to which the value will be assigned - * - * This call will set the mode for the @gpio to input. - */ -static int msp71xx_direction_input(struct gpio_chip *chip, unsigned offset) -{ - return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_INPUT); -} - -/* - * msp71xx_set_output_drive() - declare the output drive for the gpio line - * @gpio: gpio pin whose output drive you wish to modify - * @value: zero for active drain 1 for open drain drive - * - * This call will set the output drive mode for the @gpio to output. - */ -int msp71xx_set_output_drive(unsigned gpio, int value) -{ - unsigned long flags; - u32 data; - - if (gpio > 15 || gpio < 0) - return -EINVAL; - - spin_lock_irqsave(&gpio_lock, flags); - - data = __raw_readl((void __iomem *)(MSP71XX_GPIO_BASE + 0x190)); - if (value) - data |= (1 << gpio); - else - data &= ~(1 << gpio); - __raw_writel(data, (void __iomem *)(MSP71XX_GPIO_BASE + 0x190)); - - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -} -EXPORT_SYMBOL(msp71xx_set_output_drive); - -#define MSP71XX_GPIO_BANK(name, dr, cr, base_gpio, num_gpio) \ -{ \ - .chip = { \ - .label = name, \ - .direction_input = msp71xx_direction_input, \ - .direction_output = msp71xx_direction_output, \ - .get = msp71xx_gpio_get, \ - .set = msp71xx_gpio_set, \ - .base = base_gpio, \ - .ngpio = num_gpio \ - }, \ - .data_reg = (void __iomem *)(MSP71XX_GPIO_BASE + dr), \ - .config_reg = (void __iomem *)(MSP71XX_GPIO_BASE + cr), \ - .out_drive_reg = (void __iomem *)(MSP71XX_GPIO_BASE + 0x190), \ -} - -/* - * struct msp71xx_gpio_banks[] - container array of gpio banks - * @chip: chip structure for the specified gpio bank - * @data_reg: register for reading and writing the gpio pin value - * @config_reg: register to set the mode for the gpio pin bank - * - * This array structure defines the gpio banks for the PMC MIPS Processor. - * We specify the bank name, the data register, the config register, base - * starting gpio number, and the number of gpios exposed by the bank. - */ -static struct msp71xx_gpio_chip msp71xx_gpio_banks[] = { - - MSP71XX_GPIO_BANK("GPIO_1_0", 0x170, 0x180, 0, 2), - MSP71XX_GPIO_BANK("GPIO_5_2", 0x174, 0x184, 2, 4), - MSP71XX_GPIO_BANK("GPIO_9_6", 0x178, 0x188, 6, 4), - MSP71XX_GPIO_BANK("GPIO_15_10", 0x17C, 0x18C, 10, 6), -}; - -void __init msp71xx_init_gpio(void) -{ - int i; - - spin_lock_init(&gpio_lock); - - for (i = 0; i < ARRAY_SIZE(msp71xx_gpio_banks); i++) - gpiochip_add(&msp71xx_gpio_banks[i].chip); -} diff --git a/arch/mips/pmcs-msp71xx/gpio_extended.c b/arch/mips/pmcs-msp71xx/gpio_extended.c deleted file mode 100644 index 2a99f360fae..00000000000 --- a/arch/mips/pmcs-msp71xx/gpio_extended.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Generic PMC MSP71xx EXTENDED (EXD) GPIO handling. The extended gpio is - * a set of hardware registers that have no need for explicit locking as - * it is handled by unique method of writing individual set/clr bits. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * @author Patrick Glass <patrickglass@gmail.com> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/io.h> - -#define MSP71XX_DATA_OFFSET(gpio) (2 * (gpio)) -#define MSP71XX_READ_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 1) -#define MSP71XX_CFG_OUT_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 16) -#define MSP71XX_CFG_IN_OFFSET(gpio) (MSP71XX_CFG_OUT_OFFSET(gpio) + 1) - -#define MSP71XX_EXD_GPIO_BASE 0x0BC000000L - -#define to_msp71xx_exd_gpio_chip(c) \ - container_of(c, struct msp71xx_exd_gpio_chip, chip) - -/* - * struct msp71xx_exd_gpio_chip - container for gpio chip and registers - * @chip: chip structure for the specified gpio bank - * @reg: register for control and data of gpio pin - */ -struct msp71xx_exd_gpio_chip { - struct gpio_chip chip; - void __iomem *reg; -}; - -/* - * msp71xx_exd_gpio_get() - return the chip's gpio value - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose value will be returned - * - * It will return 0 if gpio value is low and other if high. - */ -static int msp71xx_exd_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct msp71xx_exd_gpio_chip *msp71xx_chip = - to_msp71xx_exd_gpio_chip(chip); - const unsigned bit = MSP71XX_READ_OFFSET(offset); - - return __raw_readl(msp71xx_chip->reg) & (1 << bit); -} - -/* - * msp71xx_exd_gpio_set() - set the output value for the gpio - * @chip: chip structure who controls the specified gpio - * @offset: gpio whose value will be assigned - * @value: logic level to assign to the gpio initially - * - * This will set the gpio bit specified to the desired value. It will set the - * gpio pin low if value is 0 otherwise it will be high. - */ -static void msp71xx_exd_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct msp71xx_exd_gpio_chip *msp71xx_chip = - to_msp71xx_exd_gpio_chip(chip); - const unsigned bit = MSP71XX_DATA_OFFSET(offset); - - __raw_writel(1 << (bit + (value ? 1 : 0)), msp71xx_chip->reg); -} - -/* - * msp71xx_exd_direction_output() - declare the direction mode for a gpio - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose value will be assigned - * @value: logic level to assign to the gpio initially - * - * This call will set the mode for the @gpio to output. It will set the - * gpio pin low if value is 0 otherwise it will be high. - */ -static int msp71xx_exd_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct msp71xx_exd_gpio_chip *msp71xx_chip = - to_msp71xx_exd_gpio_chip(chip); - - msp71xx_exd_gpio_set(chip, offset, value); - __raw_writel(1 << MSP71XX_CFG_OUT_OFFSET(offset), msp71xx_chip->reg); - return 0; -} - -/* - * msp71xx_exd_direction_input() - declare the direction mode for a gpio - * @chip: chip structure which controls the specified gpio - * @offset: gpio whose to which the value will be assigned - * - * This call will set the mode for the @gpio to input. - */ -static int msp71xx_exd_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct msp71xx_exd_gpio_chip *msp71xx_chip = - to_msp71xx_exd_gpio_chip(chip); - - __raw_writel(1 << MSP71XX_CFG_IN_OFFSET(offset), msp71xx_chip->reg); - return 0; -} - -#define MSP71XX_EXD_GPIO_BANK(name, exd_reg, base_gpio, num_gpio) \ -{ \ - .chip = { \ - .label = name, \ - .direction_input = msp71xx_exd_direction_input, \ - .direction_output = msp71xx_exd_direction_output, \ - .get = msp71xx_exd_gpio_get, \ - .set = msp71xx_exd_gpio_set, \ - .base = base_gpio, \ - .ngpio = num_gpio, \ - }, \ - .reg = (void __iomem *)(MSP71XX_EXD_GPIO_BASE + exd_reg), \ -} - -/* - * struct msp71xx_exd_gpio_banks[] - container array of gpio banks - * @chip: chip structure for the specified gpio bank - * @reg: register for reading and writing the gpio pin value - * - * This array structure defines the extended gpio banks for the - * PMC MIPS Processor. We specify the bank name, the data/config - * register,the base starting gpio number, and the number of - * gpios exposed by the bank of gpios. - */ -static struct msp71xx_exd_gpio_chip msp71xx_exd_gpio_banks[] = { - - MSP71XX_EXD_GPIO_BANK("GPIO_23_16", 0x188, 16, 8), - MSP71XX_EXD_GPIO_BANK("GPIO_27_24", 0x18C, 24, 4), -}; - -void __init msp71xx_init_gpio_extended(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(msp71xx_exd_gpio_banks); i++) - gpiochip_add(&msp71xx_exd_gpio_banks[i].chip); -} diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c index d38b095fd0d..9f64c238780 100644 --- a/arch/mips/powertv/asic/asic_devices.c +++ b/arch/mips/powertv/asic/asic_devices.c @@ -529,17 +529,8 @@ EXPORT_SYMBOL(asic_resource_get); */ void platform_release_memory(void *ptr, int size) { - unsigned long addr; - unsigned long end; - - addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK; - end = ((unsigned long)ptr + size) & PAGE_MASK; - - for (; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(__va(addr))); - init_page_count(virt_to_page(__va(addr))); - free_page((unsigned long)__va(addr)); - } + free_reserved_area((unsigned long)ptr, (unsigned long)(ptr + size), + -1, NULL); } EXPORT_SYMBOL(platform_release_memory); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 6b5f3406f41..f25ea5b4505 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -104,7 +104,7 @@ static int __init plat_of_setup(void) if (!of_have_populated_dt()) panic("device tree not present"); - strncpy(of_ids[0].compatible, soc_info.compatible, len); + strlcpy(of_ids[0].compatible, soc_info.compatible, len); strncpy(of_ids[1].compatible, "palmbus", len); if (of_platform_populate(NULL, of_ids, NULL, NULL)) diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile index 1f29e761d69..da8f6816d34 100644 --- a/arch/mips/sgi-ip27/Makefile +++ b/arch/mips/sgi-ip27/Makefile @@ -7,4 +7,5 @@ obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \ ip27-xtalk.o obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o +obj-$(CONFIG_PCI) += ip27-irq-pci.o obj-$(CONFIG_SMP) += ip27-smp.o diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c new file mode 100644 index 00000000000..ec22ec5600f --- /dev/null +++ b/arch/mips/sgi-ip27/ip27-irq-pci.c @@ -0,0 +1,266 @@ +/* + * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. + * + * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 1999 - 2001 Kanoj Sarcar + */ + +#undef DEBUG + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/smp.h> +#include <linux/random.h> +#include <linux/kernel.h> +#include <linux/kernel_stat.h> +#include <linux/delay.h> +#include <linux/bitops.h> + +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/mipsregs.h> + +#include <asm/processor.h> +#include <asm/pci/bridge.h> +#include <asm/sn/addrs.h> +#include <asm/sn/agent.h> +#include <asm/sn/arch.h> +#include <asm/sn/hub.h> +#include <asm/sn/intr.h> + +/* + * Linux has a controller-independent x86 interrupt architecture. + * every controller has a 'controller-template', that is used + * by the main code to do the right thing. Each driver-visible + * interrupt source is transparently wired to the appropriate + * controller. Thus drivers need not be aware of the + * interrupt-controller. + * + * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, + * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. + * (IO-APICs assumed to be messaging to Pentium local-APICs) + * + * the code is designed to be easily extended with new/different + * interrupt controllers, without having to do assembly magic. + */ + +extern struct bridge_controller *irq_to_bridge[]; +extern int irq_to_slot[]; + +/* + * use these macros to get the encoded nasid and widget id + * from the irq value + */ +#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)] +#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] + +static inline int alloc_level(int cpu, int irq) +{ + struct hub_data *hub = hub_data(cpu_to_node(cpu)); + struct slice_data *si = cpu_data[cpu].data; + int level; + + level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE); + if (level >= LEVELS_PER_SLICE) + panic("Cpu %d flooded with devices", cpu); + + __set_bit(level, hub->irq_alloc_mask); + si->level_to_irq[level] = irq; + + return level; +} + +static inline int find_level(cpuid_t *cpunum, int irq) +{ + int cpu, i; + + for_each_online_cpu(cpu) { + struct slice_data *si = cpu_data[cpu].data; + + for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++) + if (si->level_to_irq[i] == irq) { + *cpunum = cpu; + + return i; + } + } + + panic("Could not identify cpu/level for irq %d", irq); +} + +static int intr_connect_level(int cpu, int bit) +{ + nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); + struct slice_data *si = cpu_data[cpu].data; + + set_bit(bit, si->irq_enable_mask); + + if (!cputoslice(cpu)) { + REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); + REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); + } else { + REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); + REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); + } + + return 0; +} + +static int intr_disconnect_level(int cpu, int bit) +{ + nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); + struct slice_data *si = cpu_data[cpu].data; + + clear_bit(bit, si->irq_enable_mask); + + if (!cputoslice(cpu)) { + REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); + REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); + } else { + REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); + REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); + } + + return 0; +} + +/* Startup one of the (PCI ...) IRQs routes over a bridge. */ +static unsigned int startup_bridge_irq(struct irq_data *d) +{ + struct bridge_controller *bc; + bridgereg_t device; + bridge_t *bridge; + int pin, swlevel; + cpuid_t cpu; + + pin = SLOT_FROM_PCI_IRQ(d->irq); + bc = IRQ_TO_BRIDGE(d->irq); + bridge = bc->base; + + pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); + /* + * "map" irq to a swlevel greater than 6 since the first 6 bits + * of INT_PEND0 are taken + */ + swlevel = find_level(&cpu, d->irq); + bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); + bridge->b_int_enable |= (1 << pin); + bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ + + /* + * Enable sending of an interrupt clear packt to the hub on a high to + * low transition of the interrupt pin. + * + * IRIX sets additional bits in the address which are documented as + * reserved in the bridge docs. + */ + bridge->b_int_mode |= (1UL << pin); + + /* + * We assume the bridge to have a 1:1 mapping between devices + * (slots) and intr pins. + */ + device = bridge->b_int_device; + device &= ~(7 << (pin*3)); + device |= (pin << (pin*3)); + bridge->b_int_device = device; + + bridge->b_wid_tflush; + + intr_connect_level(cpu, swlevel); + + return 0; /* Never anything pending. */ +} + +/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ +static void shutdown_bridge_irq(struct irq_data *d) +{ + struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); + bridge_t *bridge = bc->base; + int pin, swlevel; + cpuid_t cpu; + + pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); + pin = SLOT_FROM_PCI_IRQ(d->irq); + + /* + * map irq to a swlevel greater than 6 since the first 6 bits + * of INT_PEND0 are taken + */ + swlevel = find_level(&cpu, d->irq); + intr_disconnect_level(cpu, swlevel); + + bridge->b_int_enable &= ~(1 << pin); + bridge->b_wid_tflush; +} + +static inline void enable_bridge_irq(struct irq_data *d) +{ + cpuid_t cpu; + int swlevel; + + swlevel = find_level(&cpu, d->irq); /* Criminal offence */ + intr_connect_level(cpu, swlevel); +} + +static inline void disable_bridge_irq(struct irq_data *d) +{ + cpuid_t cpu; + int swlevel; + + swlevel = find_level(&cpu, d->irq); /* Criminal offence */ + intr_disconnect_level(cpu, swlevel); +} + +static struct irq_chip bridge_irq_type = { + .name = "bridge", + .irq_startup = startup_bridge_irq, + .irq_shutdown = shutdown_bridge_irq, + .irq_mask = disable_bridge_irq, + .irq_unmask = enable_bridge_irq, +}; + +void register_bridge_irq(unsigned int irq) +{ + irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); +} + +int request_bridge_irq(struct bridge_controller *bc) +{ + int irq = allocate_irqno(); + int swlevel, cpu; + nasid_t nasid; + + if (irq < 0) + return irq; + + /* + * "map" irq to a swlevel greater than 6 since the first 6 bits + * of INT_PEND0 are taken + */ + cpu = bc->irq_cpu; + swlevel = alloc_level(cpu, irq); + if (unlikely(swlevel < 0)) { + free_irqno(irq); + + return -EAGAIN; + } + + /* Make sure it's not already pending when we connect it. */ + nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); + REMOTE_HUB_CLR_INTR(nasid, swlevel); + + intr_connect_level(cpu, swlevel); + + register_bridge_irq(irq); + + return irq; +} diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 2315cfeb268..3fbaef97a1b 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -29,7 +29,6 @@ #include <asm/mipsregs.h> #include <asm/processor.h> -#include <asm/pci/bridge.h> #include <asm/sn/addrs.h> #include <asm/sn/agent.h> #include <asm/sn/arch.h> @@ -54,50 +53,6 @@ extern asmlinkage void ip27_irq(void); -extern struct bridge_controller *irq_to_bridge[]; -extern int irq_to_slot[]; - -/* - * use these macros to get the encoded nasid and widget id - * from the irq value - */ -#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)] -#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] - -static inline int alloc_level(int cpu, int irq) -{ - struct hub_data *hub = hub_data(cpu_to_node(cpu)); - struct slice_data *si = cpu_data[cpu].data; - int level; - - level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE); - if (level >= LEVELS_PER_SLICE) - panic("Cpu %d flooded with devices", cpu); - - __set_bit(level, hub->irq_alloc_mask); - si->level_to_irq[level] = irq; - - return level; -} - -static inline int find_level(cpuid_t *cpunum, int irq) -{ - int cpu, i; - - for_each_online_cpu(cpu) { - struct slice_data *si = cpu_data[cpu].data; - - for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++) - if (si->level_to_irq[i] == irq) { - *cpunum = cpu; - - return i; - } - } - - panic("Could not identify cpu/level for irq %d", irq); -} - /* * Find first bit set */ @@ -204,175 +159,6 @@ static void ip27_hub_error(void) panic("CPU %d got a hub error interrupt", smp_processor_id()); } -static int intr_connect_level(int cpu, int bit) -{ - nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); - struct slice_data *si = cpu_data[cpu].data; - - set_bit(bit, si->irq_enable_mask); - - if (!cputoslice(cpu)) { - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); - } else { - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); - } - - return 0; -} - -static int intr_disconnect_level(int cpu, int bit) -{ - nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); - struct slice_data *si = cpu_data[cpu].data; - - clear_bit(bit, si->irq_enable_mask); - - if (!cputoslice(cpu)) { - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); - } else { - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); - } - - return 0; -} - -/* Startup one of the (PCI ...) IRQs routes over a bridge. */ -static unsigned int startup_bridge_irq(struct irq_data *d) -{ - struct bridge_controller *bc; - bridgereg_t device; - bridge_t *bridge; - int pin, swlevel; - cpuid_t cpu; - - pin = SLOT_FROM_PCI_IRQ(d->irq); - bc = IRQ_TO_BRIDGE(d->irq); - bridge = bc->base; - - pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); - /* - * "map" irq to a swlevel greater than 6 since the first 6 bits - * of INT_PEND0 are taken - */ - swlevel = find_level(&cpu, d->irq); - bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); - bridge->b_int_enable |= (1 << pin); - bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ - - /* - * Enable sending of an interrupt clear packt to the hub on a high to - * low transition of the interrupt pin. - * - * IRIX sets additional bits in the address which are documented as - * reserved in the bridge docs. - */ - bridge->b_int_mode |= (1UL << pin); - - /* - * We assume the bridge to have a 1:1 mapping between devices - * (slots) and intr pins. - */ - device = bridge->b_int_device; - device &= ~(7 << (pin*3)); - device |= (pin << (pin*3)); - bridge->b_int_device = device; - - bridge->b_wid_tflush; - - intr_connect_level(cpu, swlevel); - - return 0; /* Never anything pending. */ -} - -/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ -static void shutdown_bridge_irq(struct irq_data *d) -{ - struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); - bridge_t *bridge = bc->base; - int pin, swlevel; - cpuid_t cpu; - - pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); - pin = SLOT_FROM_PCI_IRQ(d->irq); - - /* - * map irq to a swlevel greater than 6 since the first 6 bits - * of INT_PEND0 are taken - */ - swlevel = find_level(&cpu, d->irq); - intr_disconnect_level(cpu, swlevel); - - bridge->b_int_enable &= ~(1 << pin); - bridge->b_wid_tflush; -} - -static inline void enable_bridge_irq(struct irq_data *d) -{ - cpuid_t cpu; - int swlevel; - - swlevel = find_level(&cpu, d->irq); /* Criminal offence */ - intr_connect_level(cpu, swlevel); -} - -static inline void disable_bridge_irq(struct irq_data *d) -{ - cpuid_t cpu; - int swlevel; - - swlevel = find_level(&cpu, d->irq); /* Criminal offence */ - intr_disconnect_level(cpu, swlevel); -} - -static struct irq_chip bridge_irq_type = { - .name = "bridge", - .irq_startup = startup_bridge_irq, - .irq_shutdown = shutdown_bridge_irq, - .irq_mask = disable_bridge_irq, - .irq_unmask = enable_bridge_irq, -}; - -void register_bridge_irq(unsigned int irq) -{ - irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); -} - -int request_bridge_irq(struct bridge_controller *bc) -{ - int irq = allocate_irqno(); - int swlevel, cpu; - nasid_t nasid; - - if (irq < 0) - return irq; - - /* - * "map" irq to a swlevel greater than 6 since the first 6 bits - * of INT_PEND0 are taken - */ - cpu = bc->irq_cpu; - swlevel = alloc_level(cpu, irq); - if (unlikely(swlevel < 0)) { - free_irqno(irq); - - return -EAGAIN; - } - - /* Make sure it's not already pending when we connect it. */ - nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); - REMOTE_HUB_CLR_INTR(nasid, swlevel); - - intr_connect_level(cpu, swlevel); - - register_bridge_irq(irq); - - return irq; -} - asmlinkage void plat_irq_dispatch(void) { unsigned long pending = read_c0_cause() & read_c0_status(); diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 01cc1a749c7..5fbd3605d24 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -147,7 +147,8 @@ config SIBYTE_CFE_CONSOLE config SIBYTE_BUS_WATCHER bool "Support for Bus Watcher statistics" - depends on SIBYTE_SB1xxx_SOC + depends on SIBYTE_SB1xxx_SOC && \ + (SIBYTE_BCM112X || SIBYTE_SB1250) help Handle and keep statistics on the bus error interrupts (COR_ECC, BAD_ECC, IO_BUS). diff --git a/arch/mips/sibyte/Platform b/arch/mips/sibyte/Platform index d03a07516f8..af117330ce1 100644 --- a/arch/mips/sibyte/Platform +++ b/arch/mips/sibyte/Platform @@ -13,7 +13,6 @@ cflags-$(CONFIG_SIBYTE_BCM112X) += \ -I$(srctree)/arch/mips/include/asm/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL -platform-$(CONFIG_SIBYTE_SB1250) += sibyte/ cflags-$(CONFIG_SIBYTE_SB1250) += \ -I$(srctree)/arch/mips/include/asm/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL @@ -31,7 +30,8 @@ cflags-$(CONFIG_SIBYTE_BCM1x80) += \ # Sibyte BCM91120C (CRhine) board # Sibyte BCM91125C (CRhone) board # Sibyte BCM91125E (Rhone) board -# Sibyte SWARM board +# Sibyte BCM91250A (SWARM) board +# Sibyte BCM91250C2 (LittleSur) board # Sibyte BCM91x80 (BigSur) board # load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000 @@ -41,3 +41,4 @@ load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000 +load-$(CONFIG_SIBYTE_LITTLESUR) := 0xffffffff80100000 diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile index 36aa700cc40..b3d6bf23a66 100644 --- a/arch/mips/sibyte/common/Makefile +++ b/arch/mips/sibyte/common/Makefile @@ -1,3 +1,4 @@ obj-y := cfe.o +obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/common/bus_watcher.c index 8871e3345bf..5581844c919 100644 --- a/arch/mips/sibyte/sb1250/bus_watcher.c +++ b/arch/mips/sibyte/common/bus_watcher.c @@ -37,6 +37,9 @@ #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_int.h> #include <asm/sibyte/sb1250_scd.h> +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) +#include <asm/sibyte/bcm1480_regs.h> +#endif struct bw_stats_struct { @@ -81,9 +84,15 @@ void check_bus_watcher(void) #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Destructive read, clears register and interrupt */ status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS)); -#else +#elif defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250) /* Use non-destructive register */ status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG)); +#elif defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) + /* Use non-destructive register */ + /* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */ + status = csr_in32(IOADDR(A_BCM1480_BUS_ERR_STATUS_DEBUG)); +#else +#error bus watcher being built for unknown Sibyte SOC! #endif if (!(status & 0x7fffffff)) { printk("Using last values reaped by bus watcher driver\n"); @@ -175,9 +184,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data) #ifdef CONFIG_SIBYTE_BW_TRACE int i; #endif -#ifndef CONFIG_PROC_FS - char bw_buf[1024]; -#endif #ifdef CONFIG_SIBYTE_BW_TRACE csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG)); diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c index 2188b39a125..059e28c8fd9 100644 --- a/arch/mips/sibyte/common/sb_tbprof.c +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -27,6 +27,7 @@ #include <linux/types.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/sched.h> #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/errno.h> diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile index d3d969de407..cdc4c56c3e2 100644 --- a/arch/mips/sibyte/sb1250/Makefile +++ b/arch/mips/sibyte/sb1250/Makefile @@ -1,4 +1,3 @@ obj-y := setup.o irq.o time.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index cec4b8ca143..12336c2a649 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -185,6 +185,7 @@ static void __init sni_pcimt_resource_init(void) extern struct pci_ops sni_pcimt_ops; +#ifdef CONFIG_PCI static struct pci_controller sni_controller = { .pci_ops = &sni_pcimt_ops, .mem_resource = &sni_mem_resource, @@ -193,6 +194,7 @@ static struct pci_controller sni_controller = { .io_offset = 0x00000000UL, .io_map_base = SNI_PORT_BASE }; +#endif static void enable_pcimt_irq(struct irq_data *d) { diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index 7cddd03d1fe..05bb51676e8 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -128,13 +128,6 @@ static struct resource pcit_io_resources[] = { } }; -static struct resource sni_mem_resource = { - .start = 0x18000000UL, - .end = 0x1fbfffffUL, - .name = "PCIT PCI MEM", - .flags = IORESOURCE_MEM -}; - static void __init sni_pcit_resource_init(void) { int i; @@ -147,6 +140,14 @@ static void __init sni_pcit_resource_init(void) extern struct pci_ops sni_pcit_ops; +#ifdef CONFIG_PCI +static struct resource sni_mem_resource = { + .start = 0x18000000UL, + .end = 0x1fbfffffUL, + .name = "PCIT PCI MEM", + .flags = IORESOURCE_MEM +}; + static struct pci_controller sni_pcit_controller = { .pci_ops = &sni_pcit_ops, .mem_resource = &sni_mem_resource, @@ -155,6 +156,7 @@ static struct pci_controller sni_pcit_controller = { .io_offset = 0x00000000UL, .io_map_base = SNI_PORT_BASE }; +#endif /* CONFIG_PCI */ static void enable_pcit_irq(struct irq_data *d) { diff --git a/arch/mips/wrppmc/Makefile b/arch/mips/wrppmc/Makefile deleted file mode 100644 index 307cc6920ce..00000000000 --- a/arch/mips/wrppmc/Makefile +++ /dev/null @@ -1,12 +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 2006 Wind River System, Inc. -# Author: Rongkai.Zhan <rongkai.zhan@windriver.com> -# -# Makefile for the Wind River MIPS 4Kc PPMC Eval Board -# - -obj-y += irq.o pci.o reset.o serial.o setup.o time.o diff --git a/arch/mips/wrppmc/Platform b/arch/mips/wrppmc/Platform deleted file mode 100644 index dc78b25b95f..00000000000 --- a/arch/mips/wrppmc/Platform +++ /dev/null @@ -1,7 +0,0 @@ -# -# Wind River PPMC Board (4KC + GT64120) -# -platform-$(CONFIG_WR_PPMC) += wrppmc/ -cflags-$(CONFIG_WR_PPMC) += \ - -I$(srctree)/arch/mips/include/asm/mach-wrppmc -load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 diff --git a/arch/mips/wrppmc/irq.c b/arch/mips/wrppmc/irq.c deleted file mode 100644 index f237bf4d5c3..00000000000 --- a/arch/mips/wrppmc/irq.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * irq.c: GT64120 Interrupt Controller - * - * Copyright (C) 2006, Wind River System Inc. - * Author: Rongkai.Zhan, <rongkai.zhan@windriver.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. - */ -#include <linux/hardirq.h> -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/gt64120.h> -#include <asm/irq_cpu.h> -#include <asm/mipsregs.h> - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) - do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */ - else if (pending & STATUSF_IP6) - do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */ - else if (pending & STATUSF_IP3) - do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */ - else - spurious_interrupt(); -} - -/** - * Initialize GT64120 Interrupt Controller - */ -void gt64120_init_pic(void) -{ - /* clear CPU Interrupt Cause Registers */ - GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21)); - GT_WRITE(GT_HINTRCAUSE_OFS, 0x00); - - /* Disable all interrupts from GT64120 bridge chip */ - GT_WRITE(GT_INTRMASK_OFS, 0x00); - GT_WRITE(GT_HINTRMASK_OFS, 0x00); - GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00); - GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00); -} - -void __init arch_init_irq(void) -{ - /* IRQ 0 - 7 are for MIPS common irq_cpu controller */ - mips_cpu_irq_init(); - - gt64120_init_pic(); -} diff --git a/arch/mips/wrppmc/pci.c b/arch/mips/wrppmc/pci.c deleted file mode 100644 index 8b8a0e1a40c..00000000000 --- a/arch/mips/wrppmc/pci.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * pci.c: GT64120 PCI support. - * - * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/gt64120.h> - -extern struct pci_ops gt64xxx_pci0_ops; - -static struct resource pci0_io_resource = { - .name = "pci_0 io", - .start = GT_PCI_IO_BASE, - .end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource pci0_mem_resource = { - .name = "pci_0 memory", - .start = GT_PCI_MEM_BASE, - .end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct pci_controller hose_0 = { - .pci_ops = >64xxx_pci0_ops, - .io_resource = &pci0_io_resource, - .mem_resource = &pci0_mem_resource, -}; - -static int __init gt64120_pci_init(void) -{ - (void) GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ - (void) GT_READ(GT_PCI0_BARE_OFS); - - /* reset the whole PCI I/O space range */ - ioport_resource.start = GT_PCI_IO_BASE; - ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; - - register_pci_controller(&hose_0); - return 0; -} - -arch_initcall(gt64120_pci_init); diff --git a/arch/mips/wrppmc/reset.c b/arch/mips/wrppmc/reset.c deleted file mode 100644 index 80beb188ed4..00000000000 --- a/arch/mips/wrppmc/reset.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1997 Ralf Baechle - */ -#include <linux/irqflags.h> -#include <linux/kernel.h> - -#include <asm/cacheflush.h> -#include <asm/idle.h> -#include <asm/mipsregs.h> -#include <asm/processor.h> - -void wrppmc_machine_restart(char *command) -{ - /* - * Ouch, we're still alive ... This time we take the silver bullet ... - * ... and find that we leave the hardware in a state in which the - * kernel in the flush locks up somewhen during of after the PCI - * detection stuff. - */ - local_irq_disable(); - set_c0_status(ST0_BEV | ST0_ERL); - change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_c0_wired(0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -void wrppmc_machine_halt(void) -{ - local_irq_disable(); - - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) { - if (cpu_wait) - cpu_wait(); - } -} diff --git a/arch/mips/wrppmc/serial.c b/arch/mips/wrppmc/serial.c deleted file mode 100644 index 83f0f7d0518..00000000000 --- a/arch/mips/wrppmc/serial.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Registration of WRPPMC UART platform device. - * - * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/platform_device.h> -#include <linux/serial_8250.h> - -#include <asm/gt64120.h> - -static struct resource wrppmc_uart_resource[] __initdata = { - { - .start = WRPPMC_UART16550_BASE, - .end = WRPPMC_UART16550_BASE + 7, - .flags = IORESOURCE_MEM, - }, - { - .start = WRPPMC_UART16550_IRQ, - .end = WRPPMC_UART16550_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct plat_serial8250_port wrppmc_serial8250_port[] = { - { - .irq = WRPPMC_UART16550_IRQ, - .uartclk = WRPPMC_UART16550_CLOCK, - .iotype = UPIO_MEM, - .flags = UPF_IOREMAP | UPF_SKIP_TEST, - .mapbase = WRPPMC_UART16550_BASE, - }, - {}, -}; - -static __init int wrppmc_uart_add(void) -{ - struct platform_device *pdev; - int retval; - - pdev = platform_device_alloc("serial8250", -1); - if (!pdev) - return -ENOMEM; - - pdev->id = PLAT8250_DEV_PLATFORM; - pdev->dev.platform_data = wrppmc_serial8250_port; - - retval = platform_device_add_resources(pdev, wrppmc_uart_resource, - ARRAY_SIZE(wrppmc_uart_resource)); - if (retval) - goto err_free_device; - - retval = platform_device_add(pdev); - if (retval) - goto err_free_device; - - return 0; - -err_free_device: - platform_device_put(pdev); - - return retval; -} -device_initcall(wrppmc_uart_add); diff --git a/arch/mips/wrppmc/setup.c b/arch/mips/wrppmc/setup.c deleted file mode 100644 index ca65c84031a..00000000000 --- a/arch/mips/wrppmc/setup.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * setup.c: Setup pointers to hardware dependent routines. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com> - */ -#include <linux/init.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/pm.h> - -#include <asm/io.h> -#include <asm/bootinfo.h> -#include <asm/reboot.h> -#include <asm/time.h> -#include <asm/gt64120.h> - -unsigned long gt64120_base = KSEG1ADDR(0x14000000); - -#ifdef WRPPMC_EARLY_DEBUG - -static volatile unsigned char * wrppmc_led = \ - (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE); - -/* - * PPMC LED control register: - * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON) - * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON) - * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON) - */ -void wrppmc_led_on(int mask) -{ - unsigned char value = *wrppmc_led; - - value &= (0xF8 | mask); - *wrppmc_led = value; -} - -/* If mask = 0, turn off all LEDs */ -void wrppmc_led_off(int mask) -{ - unsigned char value = *wrppmc_led; - - value |= (0x7 & mask); - *wrppmc_led = value; -} - -/* - * We assume that bootloader has initialized UART16550 correctly - */ -void __init wrppmc_early_putc(char ch) -{ - static volatile unsigned char *wrppmc_uart = \ - (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE); - unsigned char value; - - /* Wait until Transmit-Holding-Register is empty */ - while (1) { - value = *(wrppmc_uart + 5); - if (value & 0x20) - break; - } - - *wrppmc_uart = ch; -} - -void __init wrppmc_early_printk(const char *fmt, ...) -{ - static char pbuf[256] = {'\0', }; - char *ch = pbuf; - va_list args; - unsigned int i; - - memset(pbuf, 0, 256); - va_start(args, fmt); - i = vsprintf(pbuf, fmt, args); - va_end(args); - - /* Print the string */ - while (*ch != '\0') { - wrppmc_early_putc(*ch); - /* if print '\n', also print '\r' */ - if (*ch++ == '\n') - wrppmc_early_putc('\r'); - } -} -#endif /* WRPPMC_EARLY_DEBUG */ - -void __init prom_free_prom_memory(void) -{ -} - -void __init plat_mem_setup(void) -{ - extern void wrppmc_machine_restart(char *command); - extern void wrppmc_machine_halt(void); - - _machine_restart = wrppmc_machine_restart; - _machine_halt = wrppmc_machine_halt; - pm_power_off = wrppmc_machine_halt; - - /* This makes the operations of 'in/out[bwl]' to the - * physical address ( < KSEG0) can work via KSEG1 - */ - set_io_port_base(KSEG1); -} - -const char *get_system_type(void) -{ - return "Wind River PPMC (GT64120)"; -} - -/* - * Initializes basic routines and structures pointers, memory size (as - * given by the bios and saves the command line. - */ -void __init prom_init(void) -{ - add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); - add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); - - wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n", - WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE)); -} diff --git a/arch/mips/wrppmc/time.c b/arch/mips/wrppmc/time.c deleted file mode 100644 index 668dbd5f12c..00000000000 --- a/arch/mips/wrppmc/time.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * time.c: MIPS CPU Count/Compare timer hookup - * - * Author: Mark.Zhan, <rongkai.zhan@windriver.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2006, Wind River System Inc. - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> - -#include <asm/gt64120.h> -#include <asm/time.h> - -#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */ - -/* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect - * - * NOTE: We disable all GT64120 timers, and use MIPS processor internal - * timer as the source of kernel clock tick. - */ -void __init plat_time_init(void) -{ - /* Disable GT64120 timers */ - GT_WRITE(GT_TC_CONTROL_OFS, 0x00); - GT_WRITE(GT_TC0_OFS, 0x00); - GT_WRITE(GT_TC1_OFS, 0x00); - GT_WRITE(GT_TC2_OFS, 0x00); - GT_WRITE(GT_TC3_OFS, 0x00); - - /* Use MIPS compare/count internal timer */ - mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ; -} |