diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2020-05-13 12:14:05 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-05-13 12:14:05 -0400 |
commit | 4aef2ec9022b217f74d0f4c9b84081f07cc223d9 (patch) | |
tree | edf9bb9ca1f8ab6345c156a7e87aaed28939f66c /arch | |
parent | 7c67f54661fcc8d141fb11abbab1739f32e13b03 (diff) | |
parent | 37486135d3a7b03acc7755b63627a130437f066a (diff) | |
download | linux-4aef2ec9022b217f74d0f4c9b84081f07cc223d9.tar.bz2 |
Merge branch 'kvm-amd-fixes' into HEAD
Diffstat (limited to 'arch')
1238 files changed, 35145 insertions, 15777 deletions
diff --git a/arch/.gitignore b/arch/.gitignore index 741468920320..4191da401dbb 100644 --- a/arch/.gitignore +++ b/arch/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only i386 x86_64 diff --git a/arch/Kconfig b/arch/Kconfig index 516f2b05bd66..786a85d4ad40 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -248,11 +248,18 @@ config ARCH_HAS_SET_DIRECT_MAP bool # -# Select if arch has an uncached kernel segment and provides the -# uncached_kernel_address / cached_kernel_address symbols to use it +# Select if the architecture provides the arch_dma_set_uncached symbol to +# either provide an uncached segement alias for a DMA allocation, or +# to remap the page tables in place. # -config ARCH_HAS_UNCACHED_SEGMENT - select ARCH_HAS_DMA_PREP_COHERENT +config ARCH_HAS_DMA_SET_UNCACHED + bool + +# +# Select if the architectures provides the arch_dma_clear_uncached symbol +# to undo an in-place page table remap for uncached access. +# +config ARCH_HAS_DMA_CLEAR_UNCACHED bool # Select if arch init_task must go in the __init_task_data section diff --git a/arch/alpha/configs/defconfig b/arch/alpha/configs/defconfig index f4ec420d7f2d..6293675db164 100644 --- a/arch/alpha/configs/defconfig +++ b/arch/alpha/configs/defconfig @@ -36,7 +36,6 @@ CONFIG_BLK_DEV_CY82C693=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_AIC7XXX=m CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set @@ -53,7 +52,8 @@ CONFIG_NET_PCI=y CONFIG_YELLOWFIN=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_CMOS=y CONFIG_EXT2_FS=y CONFIG_REISERFS_FS=m CONFIG_ISO9660_FS=y diff --git a/arch/alpha/include/asm/mmzone.h b/arch/alpha/include/asm/mmzone.h index 7ee144f484f1..9b521c857436 100644 --- a/arch/alpha/include/asm/mmzone.h +++ b/arch/alpha/include/asm/mmzone.h @@ -8,8 +8,6 @@ #include <asm/smp.h> -struct bootmem_data_t; /* stupid forward decl. */ - /* * Following are macros that are specific to this numa platform. */ diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h index f3fb2848470a..e241bd88880f 100644 --- a/arch/alpha/include/asm/page.h +++ b/arch/alpha/include/asm/page.h @@ -90,9 +90,6 @@ typedef struct page *pgtable_t; #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #endif /* CONFIG_DISCONTIGMEM */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h index 299791ce14b6..0267aa8a4f86 100644 --- a/arch/alpha/include/asm/pgtable.h +++ b/arch/alpha/include/asm/pgtable.h @@ -268,7 +268,6 @@ extern inline void pud_clear(pud_t * pudp) { pud_val(*pudp) = 0; } extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); } extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline int pte_special(pte_t pte) { return 0; } extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } @@ -276,7 +275,6 @@ extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); ret extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } -extern inline pte_t pte_mkspecial(pte_t pte) { return pte; } #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) diff --git a/arch/alpha/kernel/.gitignore b/arch/alpha/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/alpha/kernel/.gitignore +++ b/arch/alpha/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index cd9a112d67ff..32850e45834b 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -187,10 +187,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) extern void pcibios_claim_one_bus(struct pci_bus *); -static struct resource irongate_io = { - .name = "Irongate PCI IO", - .flags = IORESOURCE_IO, -}; static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, @@ -208,17 +204,19 @@ nautilus_init_pci(void) struct pci_controller *hose = hose_head; struct pci_host_bridge *bridge; struct pci_bus *bus; - struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; - int ret; bridge = pci_alloc_host_bridge(0); if (!bridge) return; + /* Use default IO. */ pci_add_resource(&bridge->windows, &ioport_resource); - pci_add_resource(&bridge->windows, &iomem_resource); + /* Irongate PCI memory aperture, calculate requred size before + setting it up. */ + pci_add_resource(&bridge->windows, &irongate_mem); + pci_add_resource(&bridge->windows, &busn_resource); bridge->dev.parent = NULL; bridge->sysdata = hose; @@ -226,59 +224,49 @@ nautilus_init_pci(void) bridge->ops = alpha_mv.pci_ops; bridge->swizzle_irq = alpha_mv.pci_swizzle; bridge->map_irq = alpha_mv.pci_map_irq; + bridge->size_windows = 1; /* Scan our single hose. */ - ret = pci_scan_root_bus_bridge(bridge); - if (ret) { + if (pci_scan_root_bus_bridge(bridge)) { pci_free_host_bridge(bridge); return; } - bus = hose->bus = bridge->bus; pcibios_claim_one_bus(bus); - irongate = pci_get_domain_bus_and_slot(pci_domain_nr(bus), 0, 0); - bus->self = irongate; - bus->resource[0] = &irongate_io; - bus->resource[1] = &irongate_mem; - pci_bus_size_bridges(bus); - /* IO port range. */ - bus->resource[0]->start = 0; - bus->resource[0]->end = 0xffff; - - /* Set up PCI memory range - limit is hardwired to 0xffffffff, - base must be at aligned to 16Mb. */ - bus_align = bus->resource[1]->start; - bus_size = bus->resource[1]->end + 1 - bus_align; + /* Now we've got the size and alignment of PCI memory resources + stored in irongate_mem. Set up the PCI memory range: limit is + hardwired to 0xffffffff, base must be aligned to 16Mb. */ + bus_align = irongate_mem.start; + bus_size = irongate_mem.end + 1 - bus_align; if (bus_align < 0x1000000UL) bus_align = 0x1000000UL; pci_mem = (0x100000000UL - bus_size) & -bus_align; + irongate_mem.start = pci_mem; + irongate_mem.end = 0xffffffffUL; - bus->resource[1]->start = pci_mem; - bus->resource[1]->end = 0xffffffffUL; - if (request_resource(&iomem_resource, bus->resource[1]) < 0) + /* Register our newly calculated PCI memory window in the resource + tree. */ + if (request_resource(&iomem_resource, &irongate_mem) < 0) printk(KERN_ERR "Failed to request MEM on hose 0\n"); + printk(KERN_INFO "Irongate pci_mem %pR\n", &irongate_mem); + if (pci_mem < memtop) memtop = pci_mem; if (memtop > alpha_mv.min_mem_address) { free_reserved_area(__va(alpha_mv.min_mem_address), __va(memtop), -1, NULL); - printk("nautilus_init_pci: %ldk freed\n", + printk(KERN_INFO "nautilus_init_pci: %ldk freed\n", (memtop - alpha_mv.min_mem_address) >> 10); } - if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */ IRONGATE0->pci_mem = pci_mem; pci_bus_assign_resources(bus); - - /* pci_common_swizzle() relies on bus->self being NULL - for the root bus, so just clear it. */ - bus->self = NULL; pci_bus_add_devices(bus); } diff --git a/arch/alpha/kernel/syscalls/syscallhdr.sh b/arch/alpha/kernel/syscalls/syscallhdr.sh index e5b99bd2e5e7..1780e861492a 100644 --- a/arch/alpha/kernel/syscalls/syscallhdr.sh +++ b/arch/alpha/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 7124ab82dfa3..ff306246d0f8 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -401,13 +401,61 @@ config ARC_HAS_DIV_REM default y config ARC_HAS_ACCL_REGS - bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)" + bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6 and/or DSP)" default y help Depending on the configuration, CPU can contain accumulator reg-pair (also referred to as r58:r59). These can also be used by gcc as GPR so kernel needs to save/restore per process +config ARC_DSP_HANDLED + def_bool n + +config ARC_DSP_SAVE_RESTORE_REGS + def_bool n + +choice + prompt "DSP support" + default ARC_DSP_NONE + help + Depending on the configuration, CPU can contain DSP registers + (ACC0_GLO, ACC0_GHI, DSP_BFLY0, DSP_CTRL, DSP_FFT_CTRL). + Bellow is options describing how to handle these registers in + interrupt entry / exit and in context switch. + +config ARC_DSP_NONE + bool "No DSP extension presence in HW" + help + No DSP extension presence in HW + +config ARC_DSP_KERNEL + bool "DSP extension in HW, no support for userspace" + select ARC_HAS_ACCL_REGS + select ARC_DSP_HANDLED + help + DSP extension presence in HW, no support for DSP-enabled userspace + applications. We don't save / restore DSP registers and only do + some minimal preparations so userspace won't be able to break kernel + +config ARC_DSP_USERSPACE + bool "Support DSP for userspace apps" + select ARC_HAS_ACCL_REGS + select ARC_DSP_HANDLED + select ARC_DSP_SAVE_RESTORE_REGS + help + DSP extension presence in HW, support save / restore DSP registers to + run DSP-enabled userspace applications + +config ARC_DSP_AGU_USERSPACE + bool "Support DSP with AGU for userspace apps" + select ARC_HAS_ACCL_REGS + select ARC_DSP_HANDLED + select ARC_DSP_SAVE_RESTORE_REGS + help + DSP and AGU extensions presence in HW, support save / restore DSP + and AGU registers to run DSP-enabled userspace applications +endchoice + config ARC_IRQ_NO_AUTOSAVE bool "Disable hardware autosave regfile on interrupts" default n diff --git a/arch/arc/boot/.gitignore b/arch/arc/boot/.gitignore index c4c5fd529c25..675db1494028 100644 --- a/arch/arc/boot/.gitignore +++ b/arch/arc/boot/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only uImage diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index 1d109b06e7d8..99d3e7175bf7 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -305,7 +305,6 @@ pgu@17000 { compatible = "snps,arcpgu"; reg = <0x17000 0x400>; - encoder-slave = <&adv7511>; clocks = <&pguclk>; clock-names = "pxlclk"; memory-region = <&frame_buffer>; diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index f7e432448e4b..2162023195c5 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -118,6 +118,32 @@ #define ARC_AUX_DPFP_2H 0x304 #define ARC_AUX_DPFP_STAT 0x305 +/* + * DSP-related registers + * Registers names must correspond to dsp_callee_regs structure fields names + * for automatic offset calculation in DSP_AUX_SAVE_RESTORE macros. + */ +#define ARC_AUX_DSP_BUILD 0x7A +#define ARC_AUX_ACC0_LO 0x580 +#define ARC_AUX_ACC0_GLO 0x581 +#define ARC_AUX_ACC0_HI 0x582 +#define ARC_AUX_ACC0_GHI 0x583 +#define ARC_AUX_DSP_BFLY0 0x598 +#define ARC_AUX_DSP_CTRL 0x59F +#define ARC_AUX_DSP_FFT_CTRL 0x59E + +#define ARC_AUX_AGU_BUILD 0xCC +#define ARC_AUX_AGU_AP0 0x5C0 +#define ARC_AUX_AGU_AP1 0x5C1 +#define ARC_AUX_AGU_AP2 0x5C2 +#define ARC_AUX_AGU_AP3 0x5C3 +#define ARC_AUX_AGU_OS0 0x5D0 +#define ARC_AUX_AGU_OS1 0x5D1 +#define ARC_AUX_AGU_MOD0 0x5E0 +#define ARC_AUX_AGU_MOD1 0x5E1 +#define ARC_AUX_AGU_MOD2 0x5E2 +#define ARC_AUX_AGU_MOD3 0x5E3 + #ifndef __ASSEMBLY__ #include <soc/arc/aux.h> diff --git a/arch/arc/include/asm/asserts.h b/arch/arc/include/asm/asserts.h new file mode 100644 index 000000000000..108f33be6aa5 --- /dev/null +++ b/arch/arc/include/asm/asserts.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com) + * + * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> + */ +#ifndef __ASM_ARC_ASSERTS_H +#define __ASM_ARC_ASSERTS_H + +/* Helpers to sanitize config options. */ + +void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena); +void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena); + +/* + * Check required config option: + * - panic in case of OPT enabled but corresponding HW absent. + * - warn in case of OPT disabled but corresponding HW exists. +*/ +#define CHK_OPT_STRICT(opt_name, hw_exists) \ +({ \ + chk_opt_strict(#opt_name, hw_exists, IS_ENABLED(opt_name)); \ +}) + +/* + * Check optional config option: + * - panic in case of OPT enabled but corresponding HW absent. +*/ +#define CHK_OPT_WEAK(opt_name, hw_exists) \ +({ \ + chk_opt_weak(#opt_name, hw_exists, IS_ENABLED(opt_name)); \ +}) + +#endif /* __ASM_ARC_ASSERTS_H */ diff --git a/arch/arc/include/asm/dsp-impl.h b/arch/arc/include/asm/dsp-impl.h new file mode 100644 index 000000000000..e1aa212ca6eb --- /dev/null +++ b/arch/arc/include/asm/dsp-impl.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com) + * + * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> + */ +#ifndef __ASM_ARC_DSP_IMPL_H +#define __ASM_ARC_DSP_IMPL_H + +#include <asm/dsp.h> + +#define DSP_CTRL_DISABLED_ALL 0 + +#ifdef __ASSEMBLY__ + +/* clobbers r5 register */ +.macro DSP_EARLY_INIT + lr r5, [ARC_AUX_DSP_BUILD] + bmsk r5, r5, 7 + breq r5, 0, 1f + mov r5, DSP_CTRL_DISABLED_ALL + sr r5, [ARC_AUX_DSP_CTRL] +1: +.endm + +/* clobbers r10, r11 registers pair */ +.macro DSP_SAVE_REGFILE_IRQ +#if defined(CONFIG_ARC_DSP_KERNEL) + /* + * Drop any changes to DSP_CTRL made by userspace so userspace won't be + * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value + */ + mov r10, DSP_CTRL_DISABLED_ALL + sr r10, [ARC_AUX_DSP_CTRL] + +#elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS) + /* + * Save DSP_CTRL register and reset it to value suitable for kernel + * (DSP_CTRL_DISABLED_ALL) + */ + mov r10, DSP_CTRL_DISABLED_ALL + aex r10, [ARC_AUX_DSP_CTRL] + st r10, [sp, PT_DSP_CTRL] + +#endif +.endm + +/* clobbers r10, r11 registers pair */ +.macro DSP_RESTORE_REGFILE_IRQ +#if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS) + ld r10, [sp, PT_DSP_CTRL] + sr r10, [ARC_AUX_DSP_CTRL] + +#endif +.endm + +#else /* __ASEMBLY__ */ + +#include <linux/sched.h> +#include <asm/asserts.h> +#include <asm/switch_to.h> + +#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS + +/* + * As we save new and restore old AUX register value in the same place we + * can optimize a bit and use AEX instruction (swap contents of an auxiliary + * register with a core register) instead of LR + SR pair. + */ +#define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \ +do { \ + long unsigned int _scratch; \ + \ + __asm__ __volatile__( \ + "ld %0, [%2, %4] \n" \ + "aex %0, [%3] \n" \ + "st %0, [%1, %4] \n" \ + : \ + "=&r" (_scratch) /* must be early clobber */ \ + : \ + "r" (_saveto), \ + "r" (_readfrom), \ + "Ir" (_aux), \ + "Ir" (_offt) \ + : \ + "memory" \ + ); \ +} while (0) + +#define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \ + AUX_SAVE_RESTORE(_saveto, _readfrom, \ + offsetof(struct dsp_callee_regs, _aux), \ + ARC_AUX_##_aux) + +static inline void dsp_save_restore(struct task_struct *prev, + struct task_struct *next) +{ + long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO; + long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO; + + DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI); + + DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL); + +#ifdef CONFIG_ARC_DSP_AGU_USERSPACE + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3); + + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1); + + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2); + DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3); +#endif /* CONFIG_ARC_DSP_AGU_USERSPACE */ +} + +#else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */ +#define dsp_save_restore(p, n) +#endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */ + +static inline bool dsp_exist(void) +{ + struct bcr_generic bcr; + + READ_BCR(ARC_AUX_DSP_BUILD, bcr); + return !!bcr.ver; +} + +static inline bool agu_exist(void) +{ + struct bcr_generic bcr; + + READ_BCR(ARC_AUX_AGU_BUILD, bcr); + return !!bcr.ver; +} + +static inline void dsp_config_check(void) +{ + CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist()); + CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist()); +} + +#endif /* __ASEMBLY__ */ +#endif /* __ASM_ARC_DSP_IMPL_H */ diff --git a/arch/arc/include/asm/dsp.h b/arch/arc/include/asm/dsp.h new file mode 100644 index 000000000000..202c78e56704 --- /dev/null +++ b/arch/arc/include/asm/dsp.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com) + * + * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> + */ +#ifndef __ASM_ARC_DSP_H +#define __ASM_ARC_DSP_H + +#ifndef __ASSEMBLY__ + +/* + * DSP-related saved registers - need to be saved only when you are + * scheduled out. + * structure fields name must correspond to aux register defenitions for + * automatic offset calculation in DSP_AUX_SAVE_RESTORE macros + */ +struct dsp_callee_regs { + unsigned long ACC0_GLO, ACC0_GHI, DSP_BFLY0, DSP_FFT_CTRL; +#ifdef CONFIG_ARC_DSP_AGU_USERSPACE + unsigned long AGU_AP0, AGU_AP1, AGU_AP2, AGU_AP3; + unsigned long AGU_OS0, AGU_OS1; + unsigned long AGU_MOD0, AGU_MOD1, AGU_MOD2, AGU_MOD3; +#endif +}; + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_ARC_DSP_H */ diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index 0b8b63d0bec1..ae0aa5323be1 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -4,6 +4,7 @@ #define __ASM_ARC_ENTRY_ARCV2_H #include <asm/asm-offsets.h> +#include <asm/dsp-impl.h> #include <asm/irqflags-arcv2.h> #include <asm/thread_info.h> /* For THREAD_SIZE */ @@ -165,6 +166,8 @@ ST2 r58, r59, PT_r58 #endif + /* clobbers r10, r11 registers pair */ + DSP_SAVE_REGFILE_IRQ .endm /*------------------------------------------------------------------------*/ @@ -189,6 +192,9 @@ ld r25, [sp, PT_user_r25] #endif + /* clobbers r10, r11 registers pair */ + DSP_RESTORE_REGFILE_IRQ + #ifdef CONFIG_ARC_HAS_ACCL_REGS LD2 r58, r59, PT_r58 #endif diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 0a32e8cfd074..b0dfed0f12be 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -102,7 +102,7 @@ typedef pte_t * pgtable_t; #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) /* Default Permissions for stack/heaps pages (Non Executable) */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC #define WANT_PAGE_VIRTUAL 1 diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index ec532d1e0725..0fcea5bad343 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -14,6 +14,7 @@ #ifndef __ASSEMBLY__ #include <asm/ptrace.h> +#include <asm/dsp.h> #include <asm/fpu.h> #ifdef CONFIG_ARC_PLAT_EZNPS @@ -31,6 +32,9 @@ struct thread_struct { unsigned long ksp; /* kernel mode stack pointer */ unsigned long callee_reg; /* pointer to callee regs */ unsigned long fault_address; /* dbls as brkpt holder as well */ +#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS + struct dsp_callee_regs dsp; +#endif #ifdef CONFIG_ARC_FPU_SAVE_RESTORE struct arc_fpu fpu; #endif diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index ba9854ef39e8..2fdb87addadc 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -91,6 +91,9 @@ struct pt_regs { #ifdef CONFIG_ARC_HAS_ACCL_REGS unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */ #endif +#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS + unsigned long DSP_CTRL; +#endif /*------- Below list auto saved by h/w -----------*/ unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; diff --git a/arch/arc/include/asm/switch_to.h b/arch/arc/include/asm/switch_to.h index aadf65b2b56c..4a3d67989d19 100644 --- a/arch/arc/include/asm/switch_to.h +++ b/arch/arc/include/asm/switch_to.h @@ -9,6 +9,7 @@ #ifndef __ASSEMBLY__ #include <linux/sched.h> +#include <asm/dsp-impl.h> #include <asm/fpu.h> #ifdef CONFIG_ARC_PLAT_EZNPS @@ -24,6 +25,7 @@ struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n); #define switch_to(prev, next, last) \ do { \ ARC_EZNPS_DP_PREV(prev, next); \ + dsp_save_restore(prev, next); \ fpu_save_restore(prev, next); \ last = __switch_to(prev, next);\ mb(); \ diff --git a/arch/arc/kernel/.gitignore b/arch/arc/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/arc/kernel/.gitignore +++ b/arch/arc/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index c783bcd35eb8..0e884036ab74 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c @@ -12,6 +12,7 @@ #include <asm/hardirq.h> #include <asm/page.h> + int main(void) { DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); @@ -75,6 +76,9 @@ int main(void) OFFSET(PT_r58, pt_regs, r58); OFFSET(PT_r59, pt_regs, r59); #endif +#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS + OFFSET(PT_DSP_CTRL, pt_regs, DSP_CTRL); +#endif return 0; } diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 6f41265f6250..6eb23f1545ee 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -14,6 +14,7 @@ #include <asm/entry.h> #include <asm/arcregs.h> #include <asm/cache.h> +#include <asm/dsp-impl.h> #include <asm/irqflags.h> .macro CPU_EARLY_SETUP @@ -59,6 +60,9 @@ #endif kflag r5 #endif + ; Config DSP_CTRL properly, so kernel may use integer multiply, + ; multiply-accumulate, and divide operations + DSP_EARLY_INIT .endm .section .init.text, "ax",@progbits diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index aa41af6ef4ac..b2b1cb645d9e 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -19,6 +19,7 @@ #include <uapi/linux/mount.h> #include <asm/sections.h> #include <asm/arcregs.h> +#include <asm/asserts.h> #include <asm/tlb.h> #include <asm/setup.h> #include <asm/page.h> @@ -26,6 +27,7 @@ #include <asm/unwind.h> #include <asm/mach_desc.h> #include <asm/smp.h> +#include <asm/dsp-impl.h> #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) @@ -389,11 +391,24 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) return buf; } +void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena) +{ + if (hw_exists && !opt_ena) + pr_warn(" ! Enable %s for working apps\n", opt_name); + else if (!hw_exists && opt_ena) + panic("Disable %s, hardware NOT present\n", opt_name); +} + +void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena) +{ + if (!hw_exists && opt_ena) + panic("Disable %s, hardware NOT present\n", opt_name); +} + static void arc_chk_core_config(void) { struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - int saved = 0, present = 0; - char *opt_nm = NULL; + int present = 0; if (!cpu->extn.timer0) panic("Timer0 is not present!\n"); @@ -425,23 +440,16 @@ static void arc_chk_core_config(void) */ if (is_isa_arcompact()) { - opt_nm = "CONFIG_ARC_FPU_SAVE_RESTORE"; - saved = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); - /* only DPDP checked since SP has no arch visible regs */ present = cpu->extn.fpu_dp; + CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); } else { - opt_nm = "CONFIG_ARC_HAS_ACCL_REGS"; - saved = IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS); - /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */ present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp; - } + CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present); - if (present && !saved) - pr_warn("Enable %s for working apps\n", opt_nm); - else if (!present && saved) - panic("Disable %s, hardware NOT present\n", opt_nm); + dsp_config_check(); + } } /* diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index b70d7debf5ca..f46e18a77645 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1201,23 +1201,49 @@ choice config STM32F4_DEBUG_UART bool "Use STM32F4 UART for low-level debug" - depends on ARCH_STM32 + depends on MACH_STM32F429 || MACH_STM32F469 select DEBUG_STM32_UART help Say Y here if you want kernel low-level debugging support on STM32F4 based platforms, which default UART is wired on - USART1. + USART1, but another UART instance can be selected by modifying + CONFIG_DEBUG_UART_PHYS. If unsure, say N. config STM32F7_DEBUG_UART bool "Use STM32F7 UART for low-level debug" - depends on ARCH_STM32 + depends on MACH_STM32F746 || MACH_STM32F769 select DEBUG_STM32_UART help Say Y here if you want kernel low-level debugging support on STM32F7 based platforms, which default UART is wired on - USART1. + USART1, but another UART instance can be selected by modifying + CONFIG_DEBUG_UART_PHYS. + + If unsure, say N. + + config STM32H7_DEBUG_UART + bool "Use STM32H7 UART for low-level debug" + depends on MACH_STM32H743 + select DEBUG_STM32_UART + help + Say Y here if you want kernel low-level debugging support + on STM32H7 based platforms, which default UART is wired on + USART1, but another UART instance can be selected by modifying + CONFIG_DEBUG_UART_PHYS. + + If unsure, say N. + + config STM32MP1_DEBUG_UART + bool "Use STM32MP1 UART for low-level debug" + depends on MACH_STM32MP157 + select DEBUG_STM32_UART + help + Say Y here if you want kernel low-level debugging support + on STM32MP1 based platforms, wich default UART is wired on + UART4, but another UART instance can be selected by modifying + CONFIG_DEBUG_UART_PHYS and CONFIG_DEBUG_UART_VIRT. If unsure, say N. @@ -1619,6 +1645,9 @@ config DEBUG_UART_PHYS default 0x3e000000 if DEBUG_BCM_KONA_UART default 0x3f201000 if DEBUG_BCM2836 default 0x4000e400 if DEBUG_LL_UART_EFM32 + default 0x40010000 if STM32MP1_DEBUG_UART + default 0x40011000 if STM32F4_DEBUG_UART || STM32F7_DEBUG_UART || \ + STM32H7_DEBUG_UART default 0x40028000 if DEBUG_AT91_SAMV7_USART1 default 0x40081000 if DEBUG_LPC18XX_UART0 default 0x40090000 if DEBUG_LPC32XX @@ -1713,7 +1742,7 @@ config DEBUG_UART_PHYS DEBUG_S3C64XX_UART || \ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ - DEBUG_AT91_UART + DEBUG_AT91_UART || DEBUG_STM32_UART config DEBUG_UART_VIRT hex "Virtual base address of debug UART" @@ -1779,6 +1808,7 @@ config DEBUG_UART_VIRT default 0xfcfe8600 if DEBUG_BCM63XX_UART default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX default 0xfd883000 if DEBUG_ALPINE_UART0 + default 0xfe010000 if STM32MP1_DEBUG_UART default 0xfe017000 if DEBUG_MMP_UART2 default 0xfe018000 if DEBUG_MMP_UART3 default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART @@ -1823,7 +1853,7 @@ config DEBUG_UART_VIRT DEBUG_S3C64XX_UART || \ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ - DEBUG_AT91_UART + DEBUG_AT91_UART || DEBUG_STM32_UART config DEBUG_UART_8250_SHIFT int "Register offset shift for the 8250 debug UART" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e1d13d779e08..7d5cd0f85461 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -152,6 +152,7 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000 ifeq ($(CONFIG_ARCH_SA1100),y) textofs-$(CONFIG_SA1111) := 0x00208000 endif +textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000 textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 textofs-$(CONFIG_ARCH_MESON) := 0x00208000 diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore index ce1c5ff746e7..8c759326baf4 100644 --- a/arch/arm/boot/.gitignore +++ b/arch/arm/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only Image zImage xipImage diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index 86b2f5d28240..db05c6ef3e31 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only ashldi3.S bswapsdi2.S font.c diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 04f77214f050..e8e1c866e413 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -151,6 +151,25 @@ .L_\@: .endm + /* + * The kernel build system appends the size of the + * decompressed kernel at the end of the compressed data + * in little-endian form. + */ + .macro get_inflated_image_size, res:req, tmp1:req, tmp2:req + adr \res, .Linflated_image_size_offset + ldr \tmp1, [\res] + add \tmp1, \tmp1, \res @ address of inflated image size + + ldrb \res, [\tmp1] @ get_unaligned_le32 + ldrb \tmp2, [\tmp1, #1] + orr \res, \res, \tmp2, lsl #8 + ldrb \tmp2, [\tmp1, #2] + ldrb \tmp1, [\tmp1, #3] + orr \res, \res, \tmp2, lsl #16 + orr \res, \res, \tmp1, lsl #24 + .endm + .section ".start", "ax" /* * sort out different calling conventions @@ -268,15 +287,15 @@ not_angel: */ mov r0, pc cmp r0, r4 - ldrcc r0, LC0+32 + ldrcc r0, LC0+28 addcc r0, r0, pc cmpcc r4, r0 orrcc r4, r4, #1 @ remember we skipped cache_on blcs cache_on restart: adr r0, LC0 - ldmia r0, {r1, r2, r3, r6, r10, r11, r12} - ldr sp, [r0, #28] + ldmia r0, {r1, r2, r3, r6, r11, r12} + ldr sp, [r0, #24] /* * We might be running at a different address. We need @@ -284,20 +303,8 @@ restart: adr r0, LC0 */ sub r0, r0, r1 @ calculate the delta offset add r6, r6, r0 @ _edata - add r10, r10, r0 @ inflated kernel size location - /* - * The kernel build system appends the size of the - * decompressed kernel at the end of the compressed data - * in little-endian form. - */ - ldrb r9, [r10, #0] - ldrb lr, [r10, #1] - orr r9, r9, lr, lsl #8 - ldrb lr, [r10, #2] - ldrb r10, [r10, #3] - orr r9, r9, lr, lsl #16 - orr r9, r9, r10, lsl #24 + get_inflated_image_size r9, r10, lr #ifndef CONFIG_ZBOOT_ROM /* malloc space is above the relocated stack (64k max) */ @@ -521,11 +528,8 @@ dtb_check_done: /* Preserve offset to relocated code. */ sub r6, r9, r6 -#ifndef CONFIG_ZBOOT_ROM - /* cache_clean_flush may use the stack, so relocate it */ - add sp, sp, r6 -#endif - + mov r0, r9 @ start of relocated zImage + add r1, sp, r6 @ end of relocated zImage bl cache_clean_flush badr r0, restart @@ -622,6 +626,11 @@ not_relocated: mov r0, #0 add r2, sp, #0x10000 @ 64k max mov r3, r7 bl decompress_kernel + + get_inflated_image_size r1, r2, r3 + + mov r0, r4 @ start of inflated image + add r1, r1, r0 @ end of inflated image bl cache_clean_flush bl cache_off @@ -652,13 +661,15 @@ LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 .word _edata @ r6 - .word input_data_end - 4 @ r10 (inflated size location) .word _got_start @ r11 .word _got_end @ ip .word .L_user_stack_end @ sp .word _end - restart + 16384 + 1024*1024 .size LC0, . - LC0 +.Linflated_image_size_offset: + .long (input_data_end - 4) - . + #ifdef CONFIG_ARCH_RPC .globl params params: ldr r0, =0x10000100 @ params_phys for RPC @@ -668,6 +679,24 @@ params: ldr r0, =0x10000100 @ params_phys for RPC #endif /* + * dcache_line_size - get the minimum D-cache line size from the CTR register + * on ARMv7. + */ + .macro dcache_line_size, reg, tmp +#ifdef CONFIG_CPU_V7M + movw \tmp, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_CTR + movt \tmp, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_CTR + ldr \tmp, [\tmp] +#else + mrc p15, 0, \tmp, c0, c0, 1 @ read ctr +#endif + lsr \tmp, \tmp, #16 + and \tmp, \tmp, #0xf @ cache line size encoding + mov \reg, #4 @ bytes per word + mov \reg, \reg, lsl \tmp @ actual cache line size + .endm + +/* * Turn on the cache. We need to setup some page tables so that we * can have both the I and D caches on. * @@ -1159,8 +1188,6 @@ __armv7_mmu_cache_off: bic r0, r0, #0x000c #endif mcr p15, 0, r0, c1, c0 @ turn MMU and cache off - mov r12, lr - bl __armv7_mmu_cache_flush mov r0, #0 #ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB @@ -1168,11 +1195,14 @@ __armv7_mmu_cache_off: mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB - mov pc, r12 + mov pc, lr /* * Clean and flush the cache to maintain consistency. * + * On entry, + * r0 = start address + * r1 = end address (exclusive) * On exit, * r1, r2, r3, r9, r10, r11, r12 corrupted * This routine must preserve: @@ -1181,6 +1211,7 @@ __armv7_mmu_cache_off: .align 5 cache_clean_flush: mov r3, #16 + mov r11, r1 b call_cache_fn __armv4_mpu_cache_flush: @@ -1231,51 +1262,16 @@ __armv7_mmu_cache_flush: mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D b iflush hierarchical: - mcr p15, 0, r10, c7, c10, 5 @ DMB - stmfd sp!, {r0-r7, r9-r11} - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished @ if loc is 0, then no need to clean - mov r10, #0 @ start clean at cache level 0 -loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache level - mov r1, r0, lsr r2 @ extract cache type bits from clidr - and r1, r1, #7 @ mask of the bits for current cache only - cmp r1, #2 @ see what cache we have at this level - blt skip @ skip if no cache, or just i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the way size - clz r5, r4 @ find bit position of way size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the index size -loop2: - mov r9, r4 @ create working copy of max way size -loop3: - ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 - ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 - THUMB( lsl r6, r9, r5 ) - THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 - THUMB( lsl r6, r7, r2 ) - THUMB( orr r11, r11, r6 ) @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge loop3 - subs r7, r7, #1 @ decrement the index - bge loop2 -skip: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt loop1 -finished: - ldmfd sp!, {r0-r7, r9-r11} - mov r10, #0 @ switch back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + dcache_line_size r1, r2 @ r1 := dcache min line size + sub r2, r1, #1 @ r2 := line size mask + bic r0, r0, r2 @ round down start to line size + sub r11, r11, #1 @ end address is exclusive + bic r11, r11, r2 @ round down end to line size +0: cmp r0, r11 @ finished? + bgt iflush + mcr p15, 0, r0, c7, c14, 1 @ Dcache clean/invalidate by VA + add r0, r0, r1 + b 0b iflush: mcr p15, 0, r10, c7, c10, 4 @ DSB mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB @@ -1454,7 +1450,8 @@ ENTRY(efi_enter_kernel) @ running beyond the PoU, and so calling cache_off below from @ inside the PE/COFF loader allocated region is unsafe unless @ we explicitly clean it to the PoC. - adr r0, call_cache_fn @ region of code we will + ARM( adrl r0, call_cache_fn ) + THUMB( adr r0, call_cache_fn ) @ region of code we will adr r1, 0f @ run with MMU off bl cache_clean_flush bl cache_off diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index fc7ed03d8b93..b247f399de71 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -36,7 +36,6 @@ SECTIONS *(.start) *(.text) *(.text.*) - *(.fixup) *(.gnu.warning) *(.glue_7t) *(.glue_7) diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index d6546d2676b9..e8dd99201397 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -446,6 +446,10 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-nitrogen6x.dtb \ imx6dl-phytec-mira-rdk-nand.dtb \ imx6dl-phytec-pbab01.dtb \ + imx6dl-pico-dwarf.dtb \ + imx6dl-pico-hobbit.dtb \ + imx6dl-pico-nymph.dtb \ + imx6dl-pico-pi.dtb \ imx6dl-rex-basic.dtb \ imx6dl-riotboard.dtb \ imx6dl-sabreauto.dtb \ @@ -529,6 +533,10 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-phytec-mira-rdk-emmc.dtb \ imx6q-phytec-mira-rdk-nand.dtb \ imx6q-phytec-pbab01.dtb \ + imx6q-pico-dwarf.dtb \ + imx6q-pico-hobbit.dtb \ + imx6q-pico-nymph.dtb \ + imx6q-pico-pi.dtb \ imx6q-pistachio.dtb \ imx6q-rex-pro.dtb \ imx6q-sabreauto.dtb \ @@ -594,6 +602,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ul-kontron-n6310-s-43.dtb \ imx6ul-liteboard.dtb \ imx6ul-opos6uldev.dtb \ + imx6ul-pico-dwarf.dtb \ imx6ul-pico-hobbit.dtb \ imx6ul-pico-pi.dtb \ imx6ul-phytec-segin-ff-rdk-nand.dtb \ @@ -610,12 +619,16 @@ dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ulz-14x14-evk.dtb dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-cl-som-imx7.dtb \ + imx7d-colibri-aster.dtb \ + imx7d-colibri-emmc-aster.dtb \ imx7d-colibri-emmc-eval-v3.dtb \ imx7d-colibri-eval-v3.dtb \ imx7d-mba7.dtb \ imx7d-meerkat96.dtb \ imx7d-nitrogen7.dtb \ + imx7d-pico-dwarf.dtb \ imx7d-pico-hobbit.dtb \ + imx7d-pico-nymph.dtb \ imx7d-pico-pi.dtb \ imx7d-sbc-imx7.dtb \ imx7d-sdb.dtb \ @@ -623,6 +636,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-sdb-sht11.dtb \ imx7d-zii-rmu2.dtb \ imx7d-zii-rpu2.dtb \ + imx7s-colibri-aster.dtb \ imx7s-colibri-eval-v3.dtb \ imx7s-mba7.dtb \ imx7s-warp.dtb @@ -1016,6 +1030,7 @@ dtb-$(CONFIG_ARCH_STM32) += \ stm32h743i-disco.dtb \ stm32mp157a-avenger96.dtb \ stm32mp157a-dk1.dtb \ + stm32mp157c-dhcom-pdk2.dtb \ stm32mp157c-dk2.dtb \ stm32mp157c-ed1.dtb \ stm32mp157c-ev1.dtb @@ -1056,6 +1071,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \ sun5i-a13-licheepi-one.dtb \ sun5i-a13-olinuxino.dtb \ sun5i-a13-olinuxino-micro.dtb \ + sun5i-a13-pocketbook-touch-lux-3.dtb \ sun5i-a13-q8-tablet.dtb \ sun5i-a13-utoo-p66.dtb \ sun5i-gr8-chip-pro.dtb \ @@ -1086,6 +1102,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-i12-tvbox.dtb \ sun7i-a20-icnova-swac.dtb \ sun7i-a20-lamobo-r1.dtb \ + sun7i-a20-linutronix-testbox-v2.dtb \ sun7i-a20-m3.dtb \ sun7i-a20-mk808c.dtb \ sun7i-a20-olimex-som-evb.dtb \ @@ -1202,7 +1219,8 @@ dtb-$(CONFIG_ARCH_U8500) += \ ste-hrefv60plus-stuib.dtb \ ste-hrefv60plus-tvk.dtb \ ste-href520-tvk.dtb \ - ste-ux500-samsung-golden.dtb + ste-ux500-samsung-golden.dtb \ + ste-ux500-samsung-skomer.dtb dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ld4-ref.dtb \ uniphier-ld6b-ref.dtb \ diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi index 4e2986f0c604..5ed7f3c58c0f 100644 --- a/arch/arm/boot/dts/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/am33xx-l4.dtsi @@ -759,12 +759,27 @@ ranges = <0x0 0x200000 0x80000>; }; - target-module@300000 { /* 0x4a300000, ap 9 04.0 */ - compatible = "ti,sysc"; - status = "disabled"; + pruss_tm: target-module@300000 { /* 0x4a300000, ap 9 04.0 */ + compatible = "ti,sysc-pruss", "ti,sysc"; + reg = <0x326000 0x4>, + <0x326004 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <(SYSC_PRUSS_STANDBY_INIT | + SYSC_PRUSS_SUB_MWAIT)>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + clocks = <&pruss_ocp_clkctrl AM3_PRUSS_OCP_PRUSS_CLKCTRL 0>; + clock-names = "fck"; + resets = <&prm_per 1>; + reset-names = "rstctrl"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x300000 0x80000>; + status = "disabled"; }; }; }; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 41dcfb37155a..a35f5052d76f 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -47,6 +47,7 @@ #size-cells = <0>; cpu@0 { compatible = "arm,cortex-a8"; + enable-method = "ti,am3352"; device_type = "cpu"; reg = <0>; @@ -56,6 +57,17 @@ clock-names = "cpu"; clock-latency = <300000>; /* From omap-cpufreq driver */ + cpu-idle-states = <&mpu_gate>; + }; + + idle-states { + mpu_gate: mpu_gate { + compatible = "arm,idle-state"; + entry-latency-us = <40>; + exit-latency-us = <90>; + min-residency-us = <300>; + ti,idle-wkup-m3; + }; }; }; @@ -193,45 +205,100 @@ reg = <0x48200000 0x1000>; }; - edma: edma@49000000 { - compatible = "ti,edma3-tpcc"; - ti,hwmods = "tpcc"; - reg = <0x49000000 0x10000>; - reg-names = "edma3_cc"; - interrupts = <12 13 14>; - interrupt-names = "edma3_ccint", "edma3_mperr", - "edma3_ccerrint"; - dma-requests = <64>; - #dma-cells = <2>; - - ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, - <&edma_tptc2 0>; - - ti,edma-memcpy-channels = <20 21>; + target-module@49000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49000000 0x4>; + reg-names = "rev"; + clocks = <&l3_clkctrl AM3_L3_TPCC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49000000 0x10000>; + + edma: dma@0 { + compatible = "ti,edma3-tpcc"; + reg = <0 0x10000>; + reg-names = "edma3_cc"; + interrupts = <12 13 14>; + interrupt-names = "edma3_ccint", "edma3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, + <&edma_tptc2 0>; + + ti,edma-memcpy-channels = <20 21>; + }; }; - edma_tptc0: tptc@49800000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc0"; - reg = <0x49800000 0x100000>; - interrupts = <112>; - interrupt-names = "edma3_tcerrint"; + target-module@49800000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49800000 0x4>, + <0x49800010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM3_L3_TPTC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49800000 0x100000>; + + edma_tptc0: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <112>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc1: tptc@49900000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc1"; - reg = <0x49900000 0x100000>; - interrupts = <113>; - interrupt-names = "edma3_tcerrint"; + target-module@49900000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49900000 0x4>, + <0x49900010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM3_L3_TPTC1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49900000 0x100000>; + + edma_tptc1: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <113>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc2: tptc@49a00000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc2"; - reg = <0x49a00000 0x100000>; - interrupts = <114>; - interrupt-names = "edma3_tcerrint"; + target-module@49a00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49a00000 0x4>, + <0x49a00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM3_L3_TPTC2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49a00000 0x100000>; + + edma_tptc2: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <114>; + interrupt-names = "edma3_tcerrint"; + }; }; target-module@47810000 { diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index faa14dc0faff..dba87bfaf33e 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -45,6 +45,7 @@ #size-cells = <0>; cpu: cpu@0 { compatible = "arm,cortex-a9"; + enable-method = "ti,am4372"; device_type = "cpu"; reg = <0>; @@ -54,6 +55,17 @@ operating-points-v2 = <&cpu0_opp_table>; clock-latency = <300000>; /* From omap-cpufreq driver */ + cpu-idle-states = <&mpu_gate>; + }; + + idle-states { + mpu_gate: mpu_gate { + compatible = "arm,idle-state"; + entry-latency-us = <40>; + exit-latency-us = <100>; + min-residency-us = <300>; + local-timer-stop; + }; }; }; @@ -185,47 +197,102 @@ &pm_sram_data>; }; - edma: edma@49000000 { - compatible = "ti,edma3-tpcc"; - ti,hwmods = "tpcc"; - reg = <0x49000000 0x10000>; - reg-names = "edma3_cc"; - interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_ccint", "edma3_mperr", - "edma3_ccerrint"; - dma-requests = <64>; - #dma-cells = <2>; - - ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, - <&edma_tptc2 0>; - - ti,edma-memcpy-channels = <58 59>; + target-module@49000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49000000 0x4>; + reg-names = "rev"; + clocks = <&l3_clkctrl AM4_L3_TPCC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49000000 0x10000>; + + edma: dma@0 { + compatible = "ti,edma3-tpcc"; + reg = <0 0x10000>; + reg-names = "edma3_cc"; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_ccint", "edma3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, + <&edma_tptc2 0>; + + ti,edma-memcpy-channels = <58 59>; + }; }; - edma_tptc0: tptc@49800000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc0"; - reg = <0x49800000 0x100000>; - interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_tcerrint"; + target-module@49800000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49800000 0x4>, + <0x49800010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM4_L3_TPTC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49800000 0x100000>; + + edma_tptc0: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc1: tptc@49900000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc1"; - reg = <0x49900000 0x100000>; - interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_tcerrint"; + target-module@49900000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49900000 0x4>, + <0x49900010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM4_L3_TPTC1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49900000 0x100000>; + + edma_tptc1: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc2: tptc@49a00000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc2"; - reg = <0x49a00000 0x100000>; - interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_tcerrint"; + target-module@49a00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49a00000 0x4>, + <0x49a00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&l3_clkctrl AM4_L3_TPTC2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49a00000 0x100000>; + + edma_tptc2: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_tcerrint"; + }; }; target-module@47810000 { @@ -344,6 +411,28 @@ }; }; + pruss_tm: target-module@54400000 { + compatible = "ti,sysc-pruss", "ti,sysc"; + reg = <0x54426000 0x4>, + <0x54426004 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <(SYSC_PRUSS_STANDBY_INIT | + SYSC_PRUSS_SUB_MWAIT)>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + clocks = <&pruss_ocp_clkctrl AM4_PRUSS_OCP_PRUSS_CLKCTRL 0>; + clock-names = "fck"; + resets = <&prm_per 1>; + reset-names = "rstctrl"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x54400000 0x80000>; + }; + gpmc: gpmc@50000000 { compatible = "ti,am3352-gpmc"; ti,hwmods = "gpmc"; @@ -394,38 +483,6 @@ }; }; - dss: dss@4832a000 { - compatible = "ti,omap3-dss"; - reg = <0x4832a000 0x200>; - status = "disabled"; - ti,hwmods = "dss_core"; - clocks = <&disp_clk>; - clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - dispc: dispc@4832a400 { - compatible = "ti,omap3-dispc"; - reg = <0x4832a400 0x400>; - interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dss_dispc"; - clocks = <&disp_clk>; - clock-names = "fck"; - - max-memory-bandwidth = <230000000>; - }; - - rfbi: rfbi@4832a800 { - compatible = "ti,omap3-rfbi"; - reg = <0x4832a800 0x100>; - ti,hwmods = "dss_rfbi"; - clocks = <&disp_clk>; - clock-names = "fck"; - status = "disabled"; - }; - }; - ocmcram: sram@40300000 { compatible = "mmio-sram"; reg = <0x40300000 0x40000>; /* 256k */ diff --git a/arch/arm/boot/dts/am437x-l4.dtsi b/arch/arm/boot/dts/am437x-l4.dtsi index e18e17d31272..49c6a872052e 100644 --- a/arch/arm/boot/dts/am437x-l4.dtsi +++ b/arch/arm/boot/dts/am437x-l4.dtsi @@ -2117,7 +2117,6 @@ target-module@2a000 { /* 0x4832a000, ap 88 3c.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; - ti,hwmods = "dss_core"; reg = <0x2a000 0x4>, <0x2a010 0x4>, <0x2a014 0x4>; @@ -2135,6 +2134,82 @@ <0x00000800 0x0002a800 0x00000400>, <0x00000c00 0x0002ac00 0x00000400>, <0x00001000 0x0002b000 0x00001000>; + + dss: dss@0 { + compatible = "ti,omap3-dss"; + reg = <0 0x200>; + status = "disabled"; + clocks = <&disp_clk>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00000000 0x00000000 0x00000400>, + <0x00000400 0x00000400 0x00000400>, + <0x00000800 0x00000800 0x00000400>, + <0x00000c00 0x00000c00 0x00000400>, + <0x00001000 0x00001000 0x00001000>; + + target-module@400 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x400 0x4>, + <0x410 0x4>, + <0x414 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl AM4_DSS_DSS_CORE_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x400 0x400>; + + dispc: dispc@0 { + compatible = "ti,omap3-dispc"; + reg = <0 0x400>; + interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&disp_clk>; + clock-names = "fck"; + + max-memory-bandwidth = <230000000>; + }; + }; + + target-module@800 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x800 0x4>, + <0x810 0x4>, + <0x814 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl AM4_DSS_DSS_CORE_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x800 0x400>; + + rfbi: rfbi@0 { + compatible = "ti,omap3-rfbi"; + reg = <0 0x100>; + clocks = <&dss_clkctrl AM4_DSS_DSS_CORE_CLKCTRL 0>; + clock-names = "fck"; + status = "disabled"; + }; + }; + }; }; target-module@3d000 { /* 0x4833d000, ap 102 6e.0 */ diff --git a/arch/arm/boot/dts/am57-pruss.dtsi b/arch/arm/boot/dts/am57-pruss.dtsi new file mode 100644 index 000000000000..b1c583dee10b --- /dev/null +++ b/arch/arm/boot/dts/am57-pruss.dtsi @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ + * + * Common PRUSS data for TI AM57xx platforms + */ + +&ocp { + pruss1_tm: target-module@4b226000 { + compatible = "ti,sysc-pruss", "ti,sysc"; + reg = <0x4b226000 0x4>, + <0x4b226004 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <(SYSC_PRUSS_STANDBY_INIT | + SYSC_PRUSS_SUB_MWAIT)>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + /* Domains (P, C): coreaon_pwrdm, l4per2_clkdm */ + clocks = <&l4per2_clkctrl DRA7_L4PER2_PRUSS1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00000000 0x4b200000 0x80000>; + }; + + pruss2_tm: target-module@4b2a6000 { + compatible = "ti,sysc-pruss", "ti,sysc"; + reg = <0x4b2a6000 0x4>, + <0x4b2a6004 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <(SYSC_PRUSS_STANDBY_INIT | + SYSC_PRUSS_SUB_MWAIT)>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + /* Domains (P, C): coreaon_pwrdm, l4per2_clkdm */ + clocks = <&l4per2_clkctrl DRA7_L4PER2_PRUSS2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00000000 0x4b280000 0x80000>; + }; +}; diff --git a/arch/arm/boot/dts/am5718.dtsi b/arch/arm/boot/dts/am5718.dtsi index d51007c3e8c4..a80c2e3eee2e 100644 --- a/arch/arm/boot/dts/am5718.dtsi +++ b/arch/arm/boot/dts/am5718.dtsi @@ -4,6 +4,7 @@ */ #include "dra72x.dtsi" +#include "am57-pruss.dtsi" / { compatible = "ti,am5718", "ti,dra7"; diff --git a/arch/arm/boot/dts/am5728.dtsi b/arch/arm/boot/dts/am5728.dtsi index 82e5427ef6a9..9a3810f5adcc 100644 --- a/arch/arm/boot/dts/am5728.dtsi +++ b/arch/arm/boot/dts/am5728.dtsi @@ -4,6 +4,7 @@ */ #include "dra74x.dtsi" +#include "am57-pruss.dtsi" / { compatible = "ti,am5728", "ti,dra7"; diff --git a/arch/arm/boot/dts/am5748.dtsi b/arch/arm/boot/dts/am5748.dtsi index 5e129759d04a..2b65317b1513 100644 --- a/arch/arm/boot/dts/am5748.dtsi +++ b/arch/arm/boot/dts/am5748.dtsi @@ -4,6 +4,7 @@ */ #include "dra76x.dtsi" +#include "am57-pruss.dtsi" / { compatible = "ti,am5748", "ti,dra762", "ti,dra7"; diff --git a/arch/arm/boot/dts/arm-realview-pbx.dtsi b/arch/arm/boot/dts/arm-realview-pbx.dtsi index 09f3f544f3a7..f61bd59ae5ba 100644 --- a/arch/arm/boot/dts/arm-realview-pbx.dtsi +++ b/arch/arm/boot/dts/arm-realview-pbx.dtsi @@ -210,7 +210,7 @@ }; }; - soc: soc@0 { + soc: soc { compatible = "arm,realview-pbx-soc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi b/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi index df0f0cc575c1..bea920b192b6 100644 --- a/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi +++ b/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi @@ -17,7 +17,7 @@ }; panel: panel { - compatible = "winstar,wf70gtiagdng0", "innolux,at070tn92", "simple-panel"; + compatible = "winstar,wf70gtiagdng0", "innolux,at070tn92"; backlight = <&backlight>; power-supply = <&vcc_lcd_reg>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index 9f30132d7d7b..b484745bf2d4 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -645,3 +645,8 @@ &usb2 { status = "okay"; }; + +&watchdog { + status = "okay"; +}; + diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts index 0b9fa2942dff..6b8461278950 100644 --- a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts @@ -186,6 +186,11 @@ pinmux = <PIN_PA10__GPIO>; bias-disable; }; + + pinctrl_usba_vbus: usba_vbus { + pinmux = <PIN_PA16__GPIO>; + bias-disable; + }; }; &pwm0 { @@ -248,6 +253,13 @@ status = "okay"; }; +&usb0 { + atmel,vbus-gpio = <&pioA PIN_PA16 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; +}; + &usb1 { num-ports = <3>; atmel,vbus-gpio = <0 diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts index ba7f3e646c26..1c24ac8019ba 100644 --- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts @@ -180,8 +180,11 @@ i2c0: i2c@f8028000 { dmas = <0>, <0>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + sda-gpios = <&pioA PIN_PD21 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PD22 GPIO_ACTIVE_HIGH>; status = "okay"; }; @@ -198,8 +201,11 @@ #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_flx0_default>; + pinctrl-1 = <&pinctrl_flx0_gpio>; + sda-gpios = <&pioA PIN_PB28 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PB29 GPIO_ACTIVE_HIGH>; atmel,fifo-size = <16>; status = "okay"; }; @@ -226,8 +232,11 @@ i2c1: i2c@fc028000 { dmas = <0>, <0>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&pioA PIN_PC6 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PC7 GPIO_ACTIVE_HIGH>; status = "okay"; at24@50 { @@ -244,18 +253,36 @@ bias-disable; }; + pinctrl_flx0_gpio: flx0_gpio { + pinmux = <PIN_PB28__GPIO>, + <PIN_PB29__GPIO>; + bias-disable; + }; + pinctrl_i2c0_default: i2c0_default { pinmux = <PIN_PD21__TWD0>, <PIN_PD22__TWCK0>; bias-disable; }; + pinctrl_i2c0_gpio: i2c0_gpio { + pinmux = <PIN_PD21__GPIO>, + <PIN_PD22__GPIO>; + bias-disable; + }; + pinctrl_i2c1_default: i2c1_default { pinmux = <PIN_PC6__TWD1>, <PIN_PC7__TWCK1>; bias-disable; }; + pinctrl_i2c1_gpio: i2c1_gpio { + pinmux = <PIN_PC6__GPIO>, + <PIN_PC7__GPIO>; + bias-disable; + }; + pinctrl_key_gpio_default: key_gpio_default { pinmux = <PIN_PA10__GPIO>; bias-pull-up; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 9d0a7fbea725..055ee53e4773 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -129,8 +129,11 @@ i2c0: i2c@f8028000 { dmas = <0>, <0>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + sda-gpios = <&pioA PIN_PD21 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PD22 GPIO_ACTIVE_HIGH>; i2c-sda-hold-time-ns = <350>; status = "okay"; @@ -331,8 +334,11 @@ #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 23>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_flx4_default>; + pinctrl-1 = <&pinctrl_flx4_gpio>; + sda-gpios = <&pioA PIN_PD12 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>; atmel,fifo-size = <16>; i2c-analog-filter; i2c-digital-filter; @@ -343,11 +349,14 @@ i2c1: i2c@fc028000 { dmas = <0>, <0>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1_default>; i2c-analog-filter; i2c-digital-filter; i2c-digital-filter-width-ns = <35>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&pioA PIN_PD4 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA PIN_PD5 GPIO_ACTIVE_HIGH>; status = "okay"; at24@54 { @@ -441,18 +450,36 @@ bias-disable; }; + pinctrl_flx4_gpio: flx4_gpio { + pinmux = <PIN_PD12__GPIO>, + <PIN_PD13__GPIO>; + bias-disable; + }; + pinctrl_i2c0_default: i2c0_default { pinmux = <PIN_PD21__TWD0>, <PIN_PD22__TWCK0>; bias-disable; }; + pinctrl_i2c0_gpio: i2c0_gpio { + pinmux = <PIN_PD21__GPIO>, + <PIN_PD22__GPIO>; + bias-disable; + }; + pinctrl_i2c1_default: i2c1_default { pinmux = <PIN_PD4__TWD1>, <PIN_PD5__TWCK1>; bias-disable; }; + pinctrl_i2c1_gpio: i2c1_gpio { + pinmux = <PIN_PD4__GPIO>, + <PIN_PD5__GPIO>; + bias-disable; + }; + pinctrl_i2s0_default: i2s0_default { pinmux = <PIN_PC1__I2SC0_CK>, <PIN_PC2__I2SC0_MCK>, diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts index af4969485c88..4d7cee569ff2 100644 --- a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts +++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts @@ -136,7 +136,7 @@ panel: panel { /* Actually Ampire 800480R2 */ - compatible = "foxlink,fl500wvr00-a0t", "simple-panel"; + compatible = "foxlink,fl500wvr00-a0t"; backlight = <&backlight>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index ea5cef0b0974..d36e162a8817 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -238,7 +238,7 @@ }; panel: panel { - compatible = "qiaodian,qd43003c0-40", "simple-panel"; + compatible = "qiaodian,qd43003c0-40"; backlight = <&backlight>; power-supply = <&panel_reg>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91sam9x5dm.dtsi b/arch/arm/boot/dts/at91sam9x5dm.dtsi index 7f00c1f57b90..a9278038af3b 100644 --- a/arch/arm/boot/dts/at91sam9x5dm.dtsi +++ b/arch/arm/boot/dts/at91sam9x5dm.dtsi @@ -27,7 +27,7 @@ }; panel: panel { - compatible = "foxlink,fl500wvr00-a0t", "simple-panel"; + compatible = "foxlink,fl500wvr00-a0t"; backlight = <&backlight>; power-supply = <&panel_reg>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts index efea891b1a76..e26ea9006378 100644 --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts @@ -20,6 +20,7 @@ }; aliases { + emmc2bus = &emmc2bus; ethernet0 = &genet; pcie0 = &pcie0; }; @@ -74,6 +75,79 @@ }; }; +&gpio { + /* + * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and + * the official GPU firmware DT blob. + * + * Legend: + * "FOO" = GPIO line named "FOO" on the schematic + * "FOO_N" = GPIO line named "FOO" on schematic, active low + */ + gpio-line-names = "ID_SDA", + "ID_SCL", + "SDA1", + "SCL1", + "GPIO_GCLK", + "GPIO5", + "GPIO6", + "SPI_CE1_N", + "SPI_CE0_N", + "SPI_MISO", + "SPI_MOSI", + "SPI_SCLK", + "GPIO12", + "GPIO13", + /* Serial port */ + "TXD1", + "RXD1", + "GPIO16", + "GPIO17", + "GPIO18", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO22", + "GPIO23", + "GPIO24", + "GPIO25", + "GPIO26", + "GPIO27", + "RGMII_MDIO", + "RGMIO_MDC", + /* Used by BT module */ + "CTS0", + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", + /* Shared with SPI flash */ + "PWM0_MISO", + "PWM1_MOSI", + "STATUS_LED_G_CLK", + "SPIFLASH_CE_N", + "SDA0", + "SCL0", + "RGMII_RXCLK", + "RGMII_RXCTL", + "RGMII_RXD0", + "RGMII_RXD1", + "RGMII_RXD2", + "RGMII_RXD3", + "RGMII_TXCLK", + "RGMII_TXCTL", + "RGMII_TXD0", + "RGMII_TXD1", + "RGMII_TXD2", + "RGMII_TXD3"; +}; + &pwm1 { pinctrl-names = "default"; pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi index d1e684d0acfd..a91cf68e3c4c 100644 --- a/arch/arm/boot/dts/bcm2711.dtsi +++ b/arch/arm/boot/dts/bcm2711.dtsi @@ -241,17 +241,32 @@ status = "disabled"; }; + hvs@7e400000 { + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + /* + * emmc2 has different DMA constraints based on SoC revisions. It was + * moved into its own bus, so as for RPi4's firmware to update them. + * The firmware will find whether the emmc2bus alias is defined, and if + * so, it'll edit the dma-ranges property below accordingly. + */ + emmc2bus: emmc2bus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; + dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; + emmc2: emmc2@7e340000 { compatible = "brcm,bcm2711-emmc2"; - reg = <0x7e340000 0x100>; + reg = <0x0 0x7e340000 0x100>; interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clocks BCM2711_CLOCK_EMMC2>; status = "disabled"; }; - - hvs@7e400000 { - interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; - }; }; arm-pmu { diff --git a/arch/arm/boot/dts/dm814x-clocks.dtsi b/arch/arm/boot/dts/dm814x-clocks.dtsi index e5e4d0affefa..f7939f43413b 100644 --- a/arch/arm/boot/dts/dm814x-clocks.dtsi +++ b/arch/arm/boot/dts/dm814x-clocks.dtsi @@ -362,4 +362,18 @@ #clock-cells = <2>; }; }; + + alwon_ethernet_cm: alwon_ethernet_cm@15d4 { + compatible = "ti,omap4-cm"; + reg = <0x15d4 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x15d4 0x4>; + + alwon_ethernet_clkctrl: clk@0 { + compatible = "ti,clkctrl"; + reg = <0 0x4>; + #clock-cells = <2>; + }; + }; }; diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi index 95de9f214c14..44ed5a798164 100644 --- a/arch/arm/boot/dts/dm814x.dtsi +++ b/arch/arm/boot/dts/dm814x.dtsi @@ -4,6 +4,8 @@ * kind, whether express or implied. */ +#include <dt-bindings/bus/ti-sysc.h> +#include <dt-bindings/clock/dm814.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/dm814x.h> @@ -519,53 +521,123 @@ reg = <0x47810000 0x1000>; }; - edma: edma@49000000 { - compatible = "ti,edma3-tpcc"; - ti,hwmods = "tpcc"; - reg = <0x49000000 0x10000>; - reg-names = "edma3_cc"; - interrupts = <12 13 14>; - interrupt-names = "edma3_ccint", "edma3_mperr", - "edma3_ccerrint"; - dma-requests = <64>; - #dma-cells = <2>; - - ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, - <&edma_tptc2 3>, <&edma_tptc3 0>; - - ti,edma-memcpy-channels = <20 21>; + target-module@49000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49000000 0x4>; + reg-names = "rev"; + clocks = <&alwon_clkctrl DM814_TPCC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49000000 0x10000>; + + edma: dma@0 { + compatible = "ti,edma3-tpcc"; + reg = <0 0x10000>; + reg-names = "edma3_cc"; + interrupts = <12 13 14>; + interrupt-names = "edma3_ccint", "edma3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, + <&edma_tptc2 3>, <&edma_tptc3 0>; + + ti,edma-memcpy-channels = <20 21>; + }; }; - edma_tptc0: tptc@49800000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc0"; - reg = <0x49800000 0x100000>; - interrupts = <112>; - interrupt-names = "edma3_tcerrint"; + target-module@49800000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49800000 0x4>, + <0x49800010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM814_TPTC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49800000 0x100000>; + + edma_tptc0: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <112>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc1: tptc@49900000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc1"; - reg = <0x49900000 0x100000>; - interrupts = <113>; - interrupt-names = "edma3_tcerrint"; + target-module@49900000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49900000 0x4>, + <0x49900010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM814_TPTC1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49900000 0x100000>; + + edma_tptc1: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <113>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc2: tptc@49a00000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc2"; - reg = <0x49a00000 0x100000>; - interrupts = <114>; - interrupt-names = "edma3_tcerrint"; + target-module@49a00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49a00000 0x4>, + <0x49a00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM814_TPTC2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49a00000 0x100000>; + + edma_tptc2: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <114>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc3: tptc@49b00000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc3"; - reg = <0x49b00000 0x100000>; - interrupts = <115>; - interrupt-names = "edma3_tcerrint"; + target-module@49b00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49b00000 0x4>, + <0x49b00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM814_TPTC3_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49b00000 0x100000>; + + edma_tptc3: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <115>; + interrupt-names = "edma3_tcerrint"; + }; }; /* See TRM "Table 1-318. L4HS Instance Summary" */ @@ -574,57 +646,73 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0 0x4a000000 0x1b4040>; - }; - /* REVISIT: Move to live under l4hs once driver is fixed */ - mac: ethernet@4a100000 { - compatible = "ti,cpsw"; - ti,hwmods = "cpgmac0"; - clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>; - clock-names = "fck", "cpts"; - cpdma_channels = <8>; - ale_entries = <1024>; - bd_ram_size = <0x2000>; - mac_control = <0x20>; - slaves = <2>; - active_slave = <0>; - cpts_clock_mult = <0x80000000>; - cpts_clock_shift = <29>; - reg = <0x4a100000 0x800 - 0x4a100900 0x100>; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - /* - * c0_rx_thresh_pend - * c0_rx_pend - * c0_tx_pend - * c0_misc_pend - */ - interrupts = <40 41 42 43>; - ranges; - syscon = <&scm_conf>; - - davinci_mdio: mdio@4a100800 { - compatible = "ti,davinci_mdio"; + target-module@100000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + reg = <0x100900 0x4>, + <0x100908 0x4>, + <0x100904 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-mask = <0>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>; + ti,syss-mask = <1>; + clocks = <&alwon_ethernet_clkctrl DM814_ETHERNET_CPGMAC0_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "davinci_mdio"; - bus_freq = <1000000>; - reg = <0x4a100800 0x100>; - }; - - cpsw_emac0: slave@4a100200 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 1>; + #size-cells = <1>; + ranges = <0 0x100000 0x8000>; + + mac: ethernet@0 { + compatible = "ti,cpsw"; + clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>; + clock-names = "fck", "cpts"; + cpdma_channels = <8>; + ale_entries = <1024>; + bd_ram_size = <0x2000>; + mac_control = <0x20>; + slaves = <2>; + active_slave = <0>; + cpts_clock_mult = <0x80000000>; + cpts_clock_shift = <29>; + reg = <0 0x800>, + <0x900 0x100>; + #address-cells = <1>; + #size-cells = <1>; + /* + * c0_rx_thresh_pend + * c0_rx_pend + * c0_tx_pend + * c0_misc_pend + */ + interrupts = <40 41 42 43>; + ranges = <0 0 0x8000>; + syscon = <&scm_conf>; + + davinci_mdio: mdio@800 { + compatible = "ti,cpsw-mdio", "ti,davinci_mdio"; + clocks = <&alwon_ethernet_clkctrl DM814_ETHERNET_CPGMAC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <0>; + bus_freq = <1000000>; + reg = <0x800 0x100>; + }; - }; + cpsw_emac0: slave@200 { + /* Filled in by U-Boot */ + mac-address = [ 00 00 00 00 00 00 ]; + phys = <&phy_gmii_sel 1>; + }; - cpsw_emac1: slave@4a100300 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 2>; + cpsw_emac1: slave@300 { + /* Filled in by U-Boot */ + mac-address = [ 00 00 00 00 00 00 ]; + phys = <&phy_gmii_sel 2>; + }; + }; }; }; diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index 1edc2b48b254..2a4934b60ded 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi @@ -4,6 +4,8 @@ * kind, whether express or implied. */ +#include <dt-bindings/bus/ti-sysc.h> +#include <dt-bindings/clock/dm816.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/omap.h> @@ -138,13 +140,123 @@ }; }; - edma: edma@49000000 { - compatible = "ti,edma3"; - ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2", "tptc3"; - reg = <0x49000000 0x10000>, - <0x44e10f90 0x40>; - interrupts = <12 13 14>; - #dma-cells = <1>; + target-module@49000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49000000 0x4>; + reg-names = "rev"; + clocks = <&alwon_clkctrl DM816_TPCC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49000000 0x10000>; + + edma: dma@0 { + compatible = "ti,edma3-tpcc"; + reg = <0 0x10000>; + reg-names = "edma3_cc"; + interrupts = <12 13 14>; + interrupt-names = "edma3_ccint", "edma3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, + <&edma_tptc2 3>, <&edma_tptc3 0>; + + ti,edma-memcpy-channels = <20 21>; + }; + }; + + target-module@49800000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49800000 0x4>, + <0x49800010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM816_TPTC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49800000 0x100000>; + + edma_tptc0: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <112>; + interrupt-names = "edma3_tcerrint"; + }; + }; + + target-module@49900000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49900000 0x4>, + <0x49900010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM816_TPTC1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49900000 0x100000>; + + edma_tptc1: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <113>; + interrupt-names = "edma3_tcerrint"; + }; + }; + + target-module@49a00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49a00000 0x4>, + <0x49a00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM816_TPTC2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49a00000 0x100000>; + + edma_tptc2: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <114>; + interrupt-names = "edma3_tcerrint"; + }; + }; + + target-module@49b00000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x49b00000 0x4>, + <0x49b00010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; + ti,sysc-midle = <SYSC_IDLE_FORCE>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_SMART>; + clocks = <&alwon_clkctrl DM816_TPTC3_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x49b00000 0x100000>; + + edma_tptc3: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <115>; + interrupt-names = "edma3_tcerrint"; + }; }; elm: elm@48080000 { @@ -185,7 +297,7 @@ #address-cells = <2>; #size-cells = <1>; interrupts = <100>; - dmas = <&edma 52>; + dmas = <&edma 52 0>; dma-names = "rxtx"; gpmc,num-cs = <6>; gpmc,num-waitpins = <2>; @@ -202,7 +314,7 @@ #address-cells = <1>; #size-cells = <0>; interrupts = <70>; - dmas = <&edma 58 &edma 59>; + dmas = <&edma 58 0 &edma 59 0>; dma-names = "tx", "rx"; }; @@ -213,7 +325,7 @@ #address-cells = <1>; #size-cells = <0>; interrupts = <71>; - dmas = <&edma 60 &edma 61>; + dmas = <&edma 60 0 &edma 61 0>; dma-names = "tx", "rx"; }; @@ -311,10 +423,10 @@ interrupts = <65>; ti,spi-num-cs = <4>; ti,hwmods = "mcspi1"; - dmas = <&edma 16 &edma 17 - &edma 18 &edma 19 - &edma 20 &edma 21 - &edma 22 &edma 23>; + dmas = <&edma 16 0 &edma 17 0 + &edma 18 0 &edma 19 0 + &edma 20 0 &edma 21 0 + &edma 22 0 &edma 23 0>; dma-names = "tx0", "rx0", "tx1", "rx1", "tx2", "rx2", "tx3", "rx3"; }; @@ -324,7 +436,7 @@ reg = <0x48060000 0x11000>; ti,hwmods = "mmc1"; interrupts = <64>; - dmas = <&edma 24 &edma 25>; + dmas = <&edma 24 0 &edma 25 0>; dma-names = "tx", "rx"; }; @@ -392,7 +504,7 @@ reg = <0x48020000 0x2000>; clock-frequency = <48000000>; interrupts = <72>; - dmas = <&edma 26 &edma 27>; + dmas = <&edma 26 0 &edma 27 0>; dma-names = "tx", "rx"; }; @@ -402,7 +514,7 @@ reg = <0x48022000 0x2000>; clock-frequency = <48000000>; interrupts = <73>; - dmas = <&edma 28 &edma 29>; + dmas = <&edma 28 0 &edma 29 0>; dma-names = "tx", "rx"; }; @@ -412,7 +524,7 @@ reg = <0x48024000 0x2000>; clock-frequency = <48000000>; interrupts = <74>; - dmas = <&edma 30 &edma 31>; + dmas = <&edma 30 0 &edma 31 0>; dma-names = "tx", "rx"; }; diff --git a/arch/arm/boot/dts/dra62x.dtsi b/arch/arm/boot/dts/dra62x.dtsi index d3cbb4ea35a8..cc4878aaa8ea 100644 --- a/arch/arm/boot/dts/dra62x.dtsi +++ b/arch/arm/boot/dts/dra62x.dtsi @@ -12,12 +12,12 @@ /* Compared to dm814x, dra62x has different offsets for Ethernet */ &mac { - reg = <0x4a100000 0x800 - 0x4a101200 0x100>; + reg = <0 0x800>, + <0x1200 0x100>; }; &davinci_mdio { - reg = <0x4a101000 0x100>; + reg = <0x1000 0x100>; }; #include "dra62x-clocks.dtsi" diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 5f5ee16f07a3..4740989ed9c4 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -143,7 +143,7 @@ * the moment, just use a fake OCP bus entry to represent the whole bus * hierarchy. */ - ocp { + ocp: ocp { compatible = "ti,dra7-l3-noc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -334,43 +334,73 @@ #pinctrl-cells = <2>; }; - edma: edma@43300000 { - compatible = "ti,edma3-tpcc"; - ti,hwmods = "tpcc"; - reg = <0x43300000 0x100000>; - reg-names = "edma3_cc"; - interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_ccint", "edma3_mperr", - "edma3_ccerrint"; - dma-requests = <64>; - #dma-cells = <2>; + target-module@43300000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x43300000 0x4>; + reg-names = "rev"; + clocks = <&l3main1_clkctrl DRA7_L3MAIN1_TPCC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x43300000 0x100000>; + + edma: dma@0 { + compatible = "ti,edma3-tpcc"; + reg = <0 0x100000>; + reg-names = "edma3_cc"; + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_ccint", "edma3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 0>; + + /* + * memcpy is disabled, can be enabled with: + * ti,edma-memcpy-channels = <20 21>; + * for example. Note that these channels need to be + * masked in the xbar as well. + */ + }; + }; - ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 0>; + target-module@43400000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x43400000 0x4>; + reg-names = "rev"; + clocks = <&l3main1_clkctrl DRA7_L3MAIN1_TPTC0_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x43400000 0x100000>; - /* - * memcpy is disabled, can be enabled with: - * ti,edma-memcpy-channels = <20 21>; - * for example. Note that these channels need to be - * masked in the xbar as well. - */ + edma_tptc0: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_tcerrint"; + }; }; - edma_tptc0: tptc@43400000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc0"; - reg = <0x43400000 0x100000>; - interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_tcerrint"; - }; + target-module@43500000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x43500000 0x4>; + reg-names = "rev"; + clocks = <&l3main1_clkctrl DRA7_L3MAIN1_TPTC1_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x43500000 0x100000>; - edma_tptc1: tptc@43500000 { - compatible = "ti,edma3-tptc"; - ti,hwmods = "tptc1"; - reg = <0x43500000 0x100000>; - interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "edma3_tcerrint"; + edma_tptc1: dma@0 { + compatible = "ti,edma3-tptc"; + reg = <0 0x100000>; + interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma3_tcerrint"; + }; }; dmm@4e000000 { @@ -708,44 +738,99 @@ ti,irqs-safe-map = <0>; }; - dss: dss@58000000 { - compatible = "ti,dra7-dss"; - /* 'reg' defined in dra72x.dtsi and dra74x.dtsi */ - /* 'clocks' defined in dra72x.dtsi and dra74x.dtsi */ - status = "disabled"; - ti,hwmods = "dss_core"; - /* CTRL_CORE_DSS_PLL_CONTROL */ - syscon-pll-ctrl = <&scm_conf 0x538>; + target-module@58000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x58000000 4>, + <0x58000014 4>; + reg-names = "rev", "syss"; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 0>, + <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 10>, + <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "hdmi_clk", "sys_clk", "tv_clk"; #address-cells = <1>; #size-cells = <1>; - ranges; - - dispc@58001000 { - compatible = "ti,dra7-dispc"; - reg = <0x58001000 0x1000>; - interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dss_dispc"; - clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; - /* CTRL_CORE_SMA_SW_1 */ - syscon-pol = <&scm_conf 0x534>; - }; + ranges = <0 0x58000000 0x800000>; - hdmi: encoder@58060000 { - compatible = "ti,dra7-hdmi"; - reg = <0x58040000 0x200>, - <0x58040200 0x80>, - <0x58040300 0x80>, - <0x58060000 0x19000>; - reg-names = "wp", "pll", "phy", "core"; - interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + dss: dss@0 { + compatible = "ti,dra7-dss"; + /* 'reg' defined in dra72x.dtsi and dra74x.dtsi */ + /* 'clocks' defined in dra72x.dtsi and dra74x.dtsi */ status = "disabled"; - ti,hwmods = "dss_hdmi"; - clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>, - <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - dmas = <&sdma_xbar 76>; - dma-names = "audio_tx"; + /* CTRL_CORE_DSS_PLL_CONTROL */ + syscon-pll-ctrl = <&scm_conf 0x538>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x800000>; + + target-module@1000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x1000 0x4>, + <0x1010 0x4>, + <0x1014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1000 0x1000>; + + dispc@0 { + compatible = "ti,dra7-dispc"; + reg = <0 0x1000>; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + /* CTRL_CORE_SMA_SW_1 */ + syscon-pol = <&scm_conf 0x534>; + }; + }; + + target-module@40000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x40000 0x4>, + <0x40010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>, + <SYSC_IDLE_SMART_WKUP>; + ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET)>; + clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>; + clock-names = "fck", "dss_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40000 0x40000>; + + hdmi: encoder@0 { + compatible = "ti,dra7-hdmi"; + reg = <0 0x200>, + <0x200 0x80>, + <0x300 0x80>, + <0x20000 0x19000>; + reg-names = "wp", "pll", "phy", "core"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + dmas = <&sdma_xbar 76>; + dma-names = "audio_tx"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi index 82b57a35abc0..da334489b18f 100644 --- a/arch/arm/boot/dts/dra72x.dtsi +++ b/arch/arm/boot/dts/dra72x.dtsi @@ -60,9 +60,9 @@ }; &dss { - reg = <0x58000000 0x80>, - <0x58004054 0x4>, - <0x58004300 0x20>; + reg = <0 0x80>, + <0x4054 0x4>, + <0x4300 0x20>; reg-names = "dss", "pll1_clkctrl", "pll1"; clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>, diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index c5abc436ca1f..7b1c61298253 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -132,11 +132,11 @@ }; &dss { - reg = <0x58000000 0x80>, - <0x58004054 0x4>, - <0x58004300 0x20>, - <0x58009054 0x4>, - <0x58009300 0x20>; + reg = <0 0x80>, + <0x4054 0x4>, + <0x4300 0x20>, + <0x9054 0x4>, + <0x9300 0x20>; reg-names = "dss", "pll1_clkctrl", "pll1", "pll2_clkctrl", "pll2"; diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts index 5651ae6dc969..f6eb71553b95 100644 --- a/arch/arm/boot/dts/ecx-2000.dts +++ b/arch/arm/boot/dts/ecx-2000.dts @@ -13,7 +13,6 @@ compatible = "calxeda,ecx-2000"; #address-cells = <2>; #size-cells = <2>; - clock-ranges; cpus { #address-cells = <1>; @@ -83,8 +82,7 @@ intc: interrupt-controller@fff11000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; - #size-cells = <0>; - #address-cells = <1>; + #address-cells = <0>; interrupt-controller; interrupts = <1 9 0xf04>; reg = <0xfff11000 0x1000>, @@ -95,7 +93,7 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 76 4 0 75 4 0 74 4 0 73 4>; + interrupts = <0 76 4>, <0 75 4>, <0 74 4>, <0 73 4>; }; }; }; diff --git a/arch/arm/boot/dts/ecx-common.dtsi b/arch/arm/boot/dts/ecx-common.dtsi index 66ee1d34f72b..57a028a69373 100644 --- a/arch/arm/boot/dts/ecx-common.dtsi +++ b/arch/arm/boot/dts/ecx-common.dtsi @@ -27,10 +27,11 @@ reg = <0xffe08000 0x10000>; interrupts = <0 83 4>; dma-coherent; - calxeda,port-phys = <&combophy5 0 &combophy0 0 - &combophy0 1 &combophy0 2 - &combophy0 3>; - calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>; + calxeda,port-phys = < &combophy5 0>, <&combophy0 0>, + <&combophy0 1>, <&combophy0 2>, + <&combophy0 3>; + calxeda,sgpio-gpio =<&gpioh 5 1>, <&gpioh 6 1>, + <&gpioh 7 1>; calxeda,led-order = <4 0 1 2 3>; }; @@ -114,8 +115,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0xfff36000 0x1000>; interrupts = <0 20 4>; - clocks = <&pclk>; - clock-names = "apb_pclk"; + clocks = <&pclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; }; smic@fff3a000 { @@ -202,14 +203,14 @@ ethernet@fff50000 { compatible = "calxeda,hb-xgmac"; reg = <0xfff50000 0x1000>; - interrupts = <0 77 4 0 78 4 0 79 4>; + interrupts = <0 77 4>, <0 78 4>, <0 79 4>; dma-coherent; }; ethernet@fff51000 { compatible = "calxeda,hb-xgmac"; reg = <0xfff51000 0x1000>; - interrupts = <0 80 4 0 81 4 0 82 4>; + interrupts = <0 80 4>, <0 81 4>, <0 82 4>; dma-coherent; }; diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi index dee35e3a5c4b..b27a82072365 100644 --- a/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -23,7 +23,7 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x1ff00000>; + reg = <0x40000000 0x1f800000>; }; firmware@205f000 { diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index a1bdf7830a87..9dda6bdb9253 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -115,7 +115,7 @@ gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>; gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>; num-chipselects = <1>; - cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>; lcd@0 { compatible = "samsung,ld9040"; @@ -124,8 +124,6 @@ vci-supply = <&ldo17_reg>; reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>; spi-max-frequency = <1200000>; - spi-cpol; - spi-cpha; power-on-delay = <10>; reset-delay = <10>; panel-width-mm = <90>; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 9c39e82e4ecb..73d6a71da88d 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -165,6 +165,15 @@ cpu0-supply = <&buck2_reg>; }; +&cpu0_opp_table { + opp-1000000000 { + opp-suspend; + }; + opp-800000000 { + /delete-property/opp-suspend; + }; +}; + &pinctrl_1 { gpio_power_key: power_key { samsung,pins = "gpx1-3"; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index f8ebc620f42d..6904091d4837 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -93,22 +93,23 @@ compatible = "regulator-fixed"; reg = <0>; regulator-name = "MAIN_DC"; + regulator-always-on; }; mmc_reg: regulator@1 { compatible = "regulator-fixed"; reg = <1>; - regulator-name = "VDD_33ON_2.8V"; + regulator-name = "VDD_MMC"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; - gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>; - enable-active-high; + regulator-always-on; }; reg_hdmi_en: regulator@2 { compatible = "regulator-fixed"; reg = <2>; regulator-name = "hdmi-en"; + regulator-always-on; }; vcc_1v2_reg: regulator@3 { @@ -117,6 +118,7 @@ regulator-name = "VCC_1V2"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; + regulator-always-on; }; vcc_1v8_reg: regulator@4 { @@ -125,6 +127,7 @@ regulator-name = "VCC_1V8"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-always-on; }; vcc_3v3_reg: regulator@5 { @@ -133,6 +136,7 @@ regulator-name = "VCC_3V3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + regulator-always-on; }; }; diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index ee28d30f5476..e9a09dd0a49b 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -584,6 +584,7 @@ regulator-name = "PVDD_G3DS_1V0"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1100000>; + regulator-always-on; regulator-state-mem { regulator-on-in-suspend; @@ -697,6 +698,7 @@ regulator-name = "PVDD_G3D_1V0"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1400000>; + regulator-always-on; regulator-state-mem { regulator-off-in-suspend; diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi index 1b8605cf2407..4b641b9b8179 100644 --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi @@ -31,6 +31,7 @@ operating-points-v2 = <&cluster_a7_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <539>; + dynamic-power-coefficient = <90>; }; cpu1: cpu@101 { @@ -43,6 +44,7 @@ operating-points-v2 = <&cluster_a7_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <539>; + dynamic-power-coefficient = <90>; }; cpu2: cpu@102 { @@ -55,6 +57,7 @@ operating-points-v2 = <&cluster_a7_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <539>; + dynamic-power-coefficient = <90>; }; cpu3: cpu@103 { @@ -67,6 +70,7 @@ operating-points-v2 = <&cluster_a7_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <539>; + dynamic-power-coefficient = <90>; }; cpu4: cpu@0 { @@ -79,6 +83,7 @@ operating-points-v2 = <&cluster_a15_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <310>; }; cpu5: cpu@1 { @@ -91,6 +96,7 @@ operating-points-v2 = <&cluster_a15_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <310>; }; cpu6: cpu@2 { @@ -103,6 +109,7 @@ operating-points-v2 = <&cluster_a15_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <310>; }; cpu7: cpu@3 { @@ -115,6 +122,7 @@ operating-points-v2 = <&cluster_a15_opp_table>; #cooling-cells = <2>; /* min followed by max */ capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <310>; }; }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi index 5cf1aed20490..ab27ff8bc3dc 100644 --- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi @@ -901,6 +901,7 @@ regulator-min-microvolt = <800000>; regulator-max-microvolt = <1400000>; regulator-boot-on; + regulator-always-on; regulator-state-mem { regulator-off-in-suspend; diff --git a/arch/arm/boot/dts/exynos5422-odroidhc1.dts b/arch/arm/boot/dts/exynos5422-odroidhc1.dts index f163206265bb..812659260278 100644 --- a/arch/arm/boot/dts/exynos5422-odroidhc1.dts +++ b/arch/arm/boot/dts/exynos5422-odroidhc1.dts @@ -215,6 +215,36 @@ }; }; }; + gpu_thermal: gpu-thermal { + thermal-sensors = <&tmu_gpu 0>; + trips { + gpu_alert0: gpu-alert-0 { + temperature = <70000>; + hysteresis = <10000>; + type = "active"; + }; + gpu_alert1: gpu-alert-1 { + temperature = <85000>; + hysteresis = <10000>; + type = "active"; + }; + gpu_crit0: gpu-crit-0 { + temperature = <120000>; + hysteresis = <0>; + type = "critical"; + }; + }; + cooling-maps { + map0 { + trip = <&gpu_alert0>; + cooling-device = <&gpu 0 2>; + }; + map1 { + trip = <&gpu_alert1>; + cooling-device = <&gpu 3 6>; + }; + }; + }; }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 1865a708b49f..5da2d81e3be2 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -357,6 +357,65 @@ }; }; }; + gpu_thermal: gpu-thermal { + thermal-sensors = <&tmu_gpu 0>; + polling-delay-passive = <250>; + polling-delay = <0>; + trips { + gpu_alert0: gpu-alert-0 { + temperature = <50000>; + hysteresis = <5000>; + type = "active"; + }; + gpu_alert1: gpu-alert-1 { + temperature = <60000>; + hysteresis = <5000>; + type = "active"; + }; + gpu_alert2: gpu-alert-2 { + temperature = <70000>; + hysteresis = <5000>; + type = "active"; + }; + gpu_crit0: gpu-crit-0 { + temperature = <120000>; + hysteresis = <0>; + type = "critical"; + }; + gpu_alert3: gpu-alert-3 { + temperature = <70000>; + hysteresis = <10000>; + type = "passive"; + }; + gpu_alert4: gpu-alert-4 { + temperature = <85000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + map0 { + trip = <&gpu_alert0>; + cooling-device = <&fan0 0 1>; + }; + map1 { + trip = <&gpu_alert1>; + cooling-device = <&fan0 1 2>; + }; + map2 { + trip = <&gpu_alert2>; + cooling-device = <&fan0 2 3>; + }; + map3 { + trip = <&gpu_alert3>; + cooling-device = <&gpu 0 2>; + }; + map4 { + trip = <&gpu_alert4>; + cooling-device = <&gpu 3 6>; + }; + }; + }; }; }; diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts index e2030ba16512..cc39289e99dd 100644 --- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts +++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts @@ -119,13 +119,11 @@ /* * This is a Sunon Maglev GM0502PFV2-8 cooling fan @10000 RPM. - * Since the platform has no temperature sensor, this is controlled - * from userspace by using the hard disks S.M.A.R.T. temperature * sensor. It is turned on when the temperature exceeds 46 degrees * and turned off when the temperatures goes below 41 degrees * (celsius). */ - gpio-fan { + fan0: gpio-fan { compatible = "gpio-fan"; /* Collides with IDE */ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; @@ -133,6 +131,40 @@ #cooling-cells = <2>; }; + thermal-zones { + chassis-thermal { + /* Poll every 20 seconds */ + polling-delay = <20000>; + /* Poll every 2nd second when cooling */ + polling-delay-passive = <2000>; + /* Use the thermal sensor in the hard drive */ + thermal-sensors = <&drive0>; + + /* Tripping points from the fan.script in the rootfs */ + trips { + alert: chassis-alert { + /* At 43 degrees turn on the fan */ + temperature = <43000>; + hysteresis = <3000>; + type = "active"; + }; + crit: chassis-crit { + /* Just shut down at 60 degrees */ + temperature = <60000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&alert>; + cooling-device = <&fan0 1 1>; + }; + }; + }; + }; + /* * The touchpad input is connected to a GPIO bit-banged * I2C bus. @@ -443,8 +475,18 @@ }; }; - ata@63000000 { + ide@63000000 { status = "okay"; + + /* + * This drive may have a temperature sensor with a + * thermal zone we can use for thermal control of the + * chassis temperature using the fan. + */ + drive0: ide-port@0 { + reg = <0>; + #thermal-sensor-cells = <0>; + }; }; display-controller@6a000000 { diff --git a/arch/arm/boot/dts/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini-dlink-dns-313.dts index 360642a02a48..c6f3d90e3e90 100644 --- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts +++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts @@ -297,7 +297,7 @@ }; }; - ata@63000000 { + ide@63000000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts index 521714f38eed..43c45f7e1e0a 100644 --- a/arch/arm/boot/dts/gemini-nas4220b.dts +++ b/arch/arm/boot/dts/gemini-nas4220b.dts @@ -170,11 +170,11 @@ }; }; - ata@63000000 { + ide@63000000 { status = "okay"; }; - ata@63400000 { + ide@63400000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini-sl93512r.dts index a98af0351906..a0916d3c1059 100644 --- a/arch/arm/boot/dts/gemini-sl93512r.dts +++ b/arch/arm/boot/dts/gemini-sl93512r.dts @@ -293,11 +293,11 @@ }; }; - ata@63000000 { + ide@63000000 { status = "okay"; }; - ata@63400000 { + ide@63400000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts index 239dfacaae4d..0c6e6d35bfaa 100644 --- a/arch/arm/boot/dts/gemini-sq201.dts +++ b/arch/arm/boot/dts/gemini-sq201.dts @@ -289,7 +289,7 @@ }; }; - ata@63000000 { + ide@63000000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi index 8cf67b11751f..065ed10a79fa 100644 --- a/arch/arm/boot/dts/gemini.dtsi +++ b/arch/arm/boot/dts/gemini.dtsi @@ -356,7 +356,7 @@ }; }; - ata@63000000 { + ide@63000000 { compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63000000 0x1000>; interrupts = <4 IRQ_TYPE_EDGE_RISING>; @@ -365,9 +365,11 @@ clock-names = "PCLK"; sata = <&sata>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; - ata@63400000 { + ide@63400000 { compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63400000 0x1000>; interrupts = <5 IRQ_TYPE_EDGE_RISING>; @@ -376,6 +378,8 @@ clock-names = "PCLK"; sata = <&sata>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; dma-controller@67000000 { diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index f4e4dca6f7e7..b6b0225a769e 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -13,7 +13,6 @@ compatible = "calxeda,highbank"; #address-cells = <1>; #size-cells = <1>; - clock-ranges; cpus { #address-cells = <1>; @@ -96,7 +95,7 @@ }; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x00000000 0xff900000>; @@ -128,14 +127,12 @@ intc: interrupt-controller@fff11000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #size-cells = <0>; - #address-cells = <1>; interrupt-controller; reg = <0xfff11000 0x1000>, <0xfff10100 0x100>; }; - L2: l2-cache { + L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xfff12000 0x1000>; interrupts = <0 70 4>; @@ -145,14 +142,14 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 76 4 0 75 4 0 74 4 0 73 4>; + interrupts = <0 76 4>, <0 75 4>, <0 74 4>, <0 73 4>; }; sregs@fff3c200 { compatible = "calxeda,hb-sregs-l2-ecc"; reg = <0xfff3c200 0x100>; - interrupts = <0 71 4 0 72 4>; + interrupts = <0 71 4>, <0 72 4>; }; }; diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts index 4c9aafe00b5d..0729e72f2283 100644 --- a/arch/arm/boot/dts/imx23-olinuxino.dts +++ b/arch/arm/boot/dts/imx23-olinuxino.dts @@ -23,7 +23,7 @@ ssp0: spi@80010000 { compatible = "fsl,imx23-mmc"; pinctrl-names = "default"; - pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>; + pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_sck_cfg>; bus-width = <4>; broken-cd; status = "okay"; diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index 8257630f7a49..c5edff381213 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi @@ -267,6 +267,14 @@ fsl,pull-up = <MXS_PULL_DISABLE>; }; + mmc0_sck_cfg: mmc0-sck-cfg@0 { + reg = <0>; + fsl,pinmux-ids = < + MX23_PAD_SSP1_SCK__SSP1_SCK + >; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + mmc1_4bit_pins_a: mmc1-4bit@0 { reg = <0>; fsl,pinmux-ids = < @@ -422,7 +430,7 @@ clocks = <&clks 16>; }; - dcp@80028000 { + dcp: crypto@80028000 { compatible = "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; interrupts = <53 54>; diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h index f4516ccf2c1a..111bfdcbe552 100644 --- a/arch/arm/boot/dts/imx25-pinfunc.h +++ b/arch/arm/boot/dts/imx25-pinfunc.h @@ -82,6 +82,7 @@ #define MX25_PAD_EB0__EB0 0x040 0x258 0x000 0x00 0x000 #define MX25_PAD_EB0__AUD4_TXD 0x040 0x258 0x464 0x04 0x000 #define MX25_PAD_EB0__GPIO_2_12 0x040 0x258 0x000 0x05 0x000 +#define MX25_PAD_EB0__CSPI3_SS0 0x040 0x258 0x4bc 0x06 0x000 #define MX25_PAD_EB1__EB1 0x044 0x25c 0x000 0x00 0x000 #define MX25_PAD_EB1__AUD4_RXD 0x044 0x25c 0x460 0x04 0x000 @@ -102,11 +103,13 @@ #define MX25_PAD_CS4__NF_CE1 0x054 0x264 0x000 0x01 0x000 #define MX25_PAD_CS4__UART5_CTS 0x054 0x264 0x000 0x03 0x000 #define MX25_PAD_CS4__GPIO_3_20 0x054 0x264 0x000 0x05 0x000 +#define MX25_PAD_CS4__CSPI3_MOSI 0x054 0x264 0x4b8 0x06 0x000 #define MX25_PAD_CS5__CS5 0x058 0x268 0x000 0x00 0x000 #define MX25_PAD_CS5__NF_CE2 0x058 0x268 0x000 0x01 0x000 #define MX25_PAD_CS5__UART5_RTS 0x058 0x268 0x574 0x03 0x000 #define MX25_PAD_CS5__GPIO_3_21 0x058 0x268 0x000 0x05 0x000 +#define MX25_PAD_CS5__CSPI3_MISO 0x058 0x268 0x4b4 0x06 0x000 #define MX25_PAD_NF_CE0__NF_CE0 0x05c 0x26c 0x000 0x00 0x000 #define MX25_PAD_NF_CE0__GPIO_3_22 0x05c 0x26c 0x000 0x05 0x000 @@ -114,6 +117,7 @@ #define MX25_PAD_ECB__ECB 0x060 0x270 0x000 0x00 0x000 #define MX25_PAD_ECB__UART5_TXD 0x060 0x270 0x000 0x03 0x000 #define MX25_PAD_ECB__GPIO_3_23 0x060 0x270 0x000 0x05 0x000 +#define MX25_PAD_ECB__CSPI3_SCLK 0x060 0x270 0x4ac 0x06 0x000 #define MX25_PAD_LBA__LBA 0x064 0x274 0x000 0x00 0x000 #define MX25_PAD_LBA__UART5_RXD 0x064 0x274 0x578 0x03 0x000 @@ -251,10 +255,12 @@ #define MX25_PAD_LD12__LD12 0x0f8 0x2f0 0x000 0x00 0x000 #define MX25_PAD_LD12__CSPI2_MOSI 0x0f8 0x2f0 0x4a0 0x02 0x000 +#define MX25_PAD_LD12__KPP_ROW6 0x0f8 0x2f0 0x544 0x04 0x000 #define MX25_PAD_LD12__FEC_RDATA3 0x0f8 0x2f0 0x510 0x05 0x001 #define MX25_PAD_LD13__LD13 0x0fc 0x2f4 0x000 0x00 0x000 #define MX25_PAD_LD13__CSPI2_MISO 0x0fc 0x2f4 0x49c 0x02 0x000 +#define MX25_PAD_LD13__KPP_ROW7 0x0fc 0x2f4 0x548 0x04 0x000 #define MX25_PAD_LD13__FEC_TDATA2 0x0fc 0x2f4 0x000 0x05 0x000 #define MX25_PAD_LD14__LD14 0x100 0x2f8 0x000 0x00 0x000 @@ -512,9 +518,11 @@ #define MX25_PAD_FEC_TX_EN__FEC_TX_EN 0x1d8 0x3d0 0x000 0x00 0x000 #define MX25_PAD_FEC_TX_EN__GPIO_3_9 0x1d8 0x3d0 0x000 0x05 0x000 +#define MX25_PAD_FEC_TX_EN__KPP_ROW4 0x1d8 0x3d0 0x53c 0x06 0x000 #define MX25_PAD_FEC_RDATA0__FEC_RDATA0 0x1dc 0x3d4 0x000 0x00 0x000 #define MX25_PAD_FEC_RDATA0__GPIO_3_10 0x1dc 0x3d4 0x000 0x05 0x000 +#define MX25_PAD_FEC_RDATA0__KPP_ROW5 0x1dc 0x3d4 0x540 0x06 0x000 #define MX25_PAD_FEC_RDATA1__FEC_RDATA1 0x1e0 0x3d8 0x000 0x00 0x000 /* diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 40b95a290bd6..1123e683025c 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -75,7 +75,7 @@ interrupt-parent = <&asic>; ranges; - aips@43f00000 { /* AIPS1 */ + bus@43f00000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -332,7 +332,7 @@ }; }; - aips@53f00000 { /* AIPS2 */ + bus@53f00000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index f3464cf52e49..002cd223f22d 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -525,7 +525,7 @@ reg = <0x10024600 0x200>; }; - sahara2: sahara@10025000 { + sahara2: crypto@10025000 { compatible = "fsl,imx27-sahara"; reg = <0x10025000 0x1000>; interrupts = <59>; diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts index 3a184d13887b..c5acc19c982d 100644 --- a/arch/arm/boot/dts/imx28-apx4devkit.dts +++ b/arch/arm/boot/dts/imx28-apx4devkit.dts @@ -183,10 +183,20 @@ pinctrl-0 = <&auart2_2pins_a>; status = "okay"; }; + + usbphy1: usbphy@8007e000 { + pinctrl-names = "default"; + pinctrl-0 = <&usb1_pins_a>; + status = "okay"; + }; }; }; ahb@80080000 { + usb1: usb@80090000 { + status = "okay"; + }; + mac0: ethernet@800f0000 { phy-mode = "rmii"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index e14d8ef0158b..a1cbbeb39a4f 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -998,7 +998,7 @@ clocks = <&clks 26>; }; - dcp: dcp@80028000 { + dcp: crypto@80028000 { compatible = "fsl,imx28-dcp", "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; interrupts = <52 53 54>; diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi index 6b62f0745b82..18270ec648fe 100644 --- a/arch/arm/boot/dts/imx31.dtsi +++ b/arch/arm/boot/dts/imx31.dtsi @@ -63,7 +63,7 @@ ranges = <0 0x1fffc000 0x4000>; }; - aips@43f00000 { /* AIPS1 */ + bus@43f00000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -225,7 +225,7 @@ }; }; - aips@53f00000 { /* AIPS2 */ + bus@53f00000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi index 9cbdc1a15cda..2ebf2c1fa682 100644 --- a/arch/arm/boot/dts/imx35.dtsi +++ b/arch/arm/boot/dts/imx35.dtsi @@ -66,7 +66,7 @@ cache-level = <2>; }; - aips1: aips@43f00000 { + aips1: bus@43f00000 { compatible = "fsl,aips", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -199,7 +199,7 @@ }; }; - aips2: aips@53f00000 { + aips2: bus@53f00000 { compatible = "fsl,aips", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi index 0bfe7c91d0eb..d325658901c5 100644 --- a/arch/arm/boot/dts/imx50.dtsi +++ b/arch/arm/boot/dts/imx50.dtsi @@ -101,7 +101,7 @@ interrupt-parent = <&tzic>; ranges; - aips@50000000 { /* AIPS1 */ + bus@50000000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -389,7 +389,7 @@ }; }; - aips@60000000 { /* AIPS2 */ + bus@60000000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts index 3596060f52e7..e559ab0c3645 100644 --- a/arch/arm/boot/dts/imx51-zii-rdu1.dts +++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts @@ -217,8 +217,8 @@ simple-audio-card,widgets = "Headphone", "Headphone Jack"; simple-audio-card,routing = - "Headphone Jack", "HPLEFT", - "Headphone Jack", "HPRIGHT"; + "Headphone Jack", "TPA6130A2 HPLEFT", + "Headphone Jack", "TPA6130A2 HPRIGHT"; simple-audio-card,aux-devs = <&hpa1>; sound_cpu: simple-audio-card,cpu { @@ -470,6 +470,7 @@ compatible = "ti,tpa6130a2"; reg = <0x60>; Vdd-supply = <®_3p3v>; + sound-name-prefix = "TPA6130A2"; }; ds1341: rtc@68 { diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index dea86b98e9c3..92fbb90bec57 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -104,6 +104,11 @@ #phy-cells = <0>; }; + capture-subsystem { + compatible = "fsl,imx-capture-subsystem"; + ports = <&ipu_csi0>, <&ipu_csi1>; + }; + display-subsystem { compatible = "fsl,imx-display-subsystem"; ports = <&ipu_di0>, <&ipu_di1>; @@ -143,6 +148,14 @@ clock-names = "bus", "di0", "di1"; resets = <&src 2>; + ipu_csi0: port@0 { + reg = <0>; + }; + + ipu_csi1: port@1 { + reg = <1>; + }; + ipu_di0: port@2 { reg = <2>; @@ -158,7 +171,7 @@ }; }; - aips@70000000 { /* AIPS1 */ + bus@70000000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -440,7 +453,7 @@ }; }; - aips@80000000 { /* AIPS2 */ + bus@80000000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index ed341cfd9d09..8536f59f59e6 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -222,7 +222,7 @@ clock-names = "core_clk", "mem_iface_clk"; }; - aips@50000000 { /* AIPS1 */ + bus@50000000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -654,7 +654,7 @@ }; }; - aips@60000000 { /* AIPS2 */ + bus@60000000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts index 84fcc203a2e4..65359aece950 100644 --- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx6dl-pico-dwarf.dts b/arch/arm/boot/dts/imx6dl-pico-dwarf.dts new file mode 100644 index 000000000000..659a8e8714ea --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-pico-dwarf.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 DualLite/Solo Board and Dwarf baseboard"; + compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; +}; diff --git a/arch/arm/boot/dts/imx6dl-pico-hobbit.dts b/arch/arm/boot/dts/imx6dl-pico-hobbit.dts new file mode 100644 index 000000000000..d7403c5c4337 --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-pico-hobbit.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-pico-hobbit.dtsi" + +/ { + model = "TechNexion PICO-IMX6 DualLite/Solo Board and Hobbit baseboard"; + compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; +}; diff --git a/arch/arm/boot/dts/imx6dl-pico-nymph.dts b/arch/arm/boot/dts/imx6dl-pico-nymph.dts new file mode 100644 index 000000000000..b282dbf953aa --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-pico-nymph.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 DualLite/Solo Board and Nymph baseboard"; + compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; +}; diff --git a/arch/arm/boot/dts/imx6dl-pico-pi.dts b/arch/arm/boot/dts/imx6dl-pico-pi.dts new file mode 100644 index 000000000000..b7b1c07f96f3 --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-pico-pi.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 DualLite/Solo Board and PI baseboard"; + compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; +}; diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts index 829654e1835a..065d3ab0f50a 100644 --- a/arch/arm/boot/dts/imx6dl-riotboard.dts +++ b/arch/arm/boot/dts/imx6dl-riotboard.dts @@ -89,11 +89,25 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + phy-handle = <&rgmii_phy>; interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>, <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; fsl,err006687-workaround-present; status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* Atheros AR8035 PHY */ + rgmii_phy: ethernet-phy@4 { + reg = <4>; + interrupts-extended = <&gpio1 28 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <1000>; + }; + }; }; &gpio1 { diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi index 80ed5f16a76e..2b9423d55c37 100644 --- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi @@ -562,6 +562,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbh1>; vbus-supply = <®_usb_h1_vbus>; + over-current-active-low; status = "disabled"; }; @@ -569,6 +570,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg>; vbus-supply = <®_usb_otg_vbus>; + over-current-active-low; srp-disable; hnp-disable; adp-disable; diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 008312ee0c31..77b65a402e19 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -44,6 +44,8 @@ arm-supply = <®_arm>; pu-supply = <®_pu>; soc-supply = <®_soc>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; }; cpu@1 { @@ -85,8 +87,8 @@ clocks = <&clks IMX6QDL_CLK_OCRAM>; }; - aips1: aips-bus@2000000 { - iomuxc: iomuxc@20e0000 { + aips1: bus@2000000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6dl-iomuxc"; }; @@ -101,7 +103,7 @@ }; }; - aips2: aips-bus@2100000 { + aips2: bus@2100000 { i2c4: i2c@21f8000 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts index 4665e15b196d..fab83abb6466 100644 --- a/arch/arm/boot/dts/imx6q-apalis-eval.dts +++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2017 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts index a3fa04a97d81..1614b1ae501d 100644 --- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts +++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2017 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts index 5ba49d0f4880..fa9f98dd15ac 100644 --- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts +++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2017 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx6q-marsboard.dts b/arch/arm/boot/dts/imx6q-marsboard.dts index 84b30bd6908f..05ee28388229 100644 --- a/arch/arm/boot/dts/imx6q-marsboard.dts +++ b/arch/arm/boot/dts/imx6q-marsboard.dts @@ -111,8 +111,22 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + phy-handle = <&rgmii_phy>; status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* Atheros AR8035 PHY */ + rgmii_phy: ethernet-phy@4 { + reg = <4>; + interrupts-extended = <&gpio1 28 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <1000>; + }; + }; }; &hdmi { diff --git a/arch/arm/boot/dts/imx6q-novena.dts b/arch/arm/boot/dts/imx6q-novena.dts index 61347a545d6c..69f170ff31c5 100644 --- a/arch/arm/boot/dts/imx6q-novena.dts +++ b/arch/arm/boot/dts/imx6q-novena.dts @@ -107,7 +107,7 @@ }; panel: panel { - compatible = "innolux,n133hse-ea1", "simple-panel"; + compatible = "innolux,n133hse-ea1"; backlight = <&backlight>; }; diff --git a/arch/arm/boot/dts/imx6q-pico-dwarf.dts b/arch/arm/boot/dts/imx6q-pico-dwarf.dts new file mode 100644 index 000000000000..618d2743e1e9 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-pico-dwarf.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 Quad Board and Dwarf baseboard"; + compatible = "technexion,imx6q-pico", "fsl,imx6q"; +}; diff --git a/arch/arm/boot/dts/imx6q-pico-hobbit.dts b/arch/arm/boot/dts/imx6q-pico-hobbit.dts new file mode 100644 index 000000000000..7a666507b456 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-pico-hobbit.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-pico-hobbit.dtsi" + +/ { + model = "TechNexion PICO-IMX6 Quad Board and Hobbit baseboard"; + compatible = "technexion,imx6q-pico", "fsl,imx6q"; +}; diff --git a/arch/arm/boot/dts/imx6q-pico-nymph.dts b/arch/arm/boot/dts/imx6q-pico-nymph.dts new file mode 100644 index 000000000000..fe5a7becc9e5 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-pico-nymph.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 Quad Board and Nymph baseboard"; + compatible = "technexion,imx6q-pico", "fsl,imx6q"; +}; diff --git a/arch/arm/boot/dts/imx6q-pico-pi.dts b/arch/arm/boot/dts/imx6q-pico-pi.dts new file mode 100644 index 000000000000..9413f0a68f54 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-pico-pi.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-pico-pi.dtsi" + +/ { + model = "TechNexion PICO-IMX6 Quad Board and PI baseboard"; + compatible = "technexion,imx6q-pico", "fsl,imx6q"; +}; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 9d3be1cc6b64..78a4d64929f3 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -49,6 +49,8 @@ arm-supply = <®_arm>; pu-supply = <®_pu>; soc-supply = <®_soc>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; }; cpu1: cpu@1 { @@ -164,7 +166,7 @@ clocks = <&clks IMX6QDL_CLK_OCRAM>; }; - aips-bus@2000000 { /* AIPS1 */ + bus@2000000 { /* AIPS1 */ spba-bus@2000000 { ecspi5: spi@2018000 { #address-cells = <1>; @@ -181,7 +183,7 @@ }; }; - iomuxc: iomuxc@20e0000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6q-iomuxc"; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi index 347a5edc6927..e34be8fabd93 100644 --- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2017 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ #include <dt-bindings/gpio/gpio.h> diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi index d03dff23863d..6e3c6b4925a7 100644 --- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi @@ -1,44 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2020 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ #include <dt-bindings/gpio/gpio.h> diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 1a9a9d98f284..60563ff0b7ce 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -313,6 +313,11 @@ interrupts = <12 2>; wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; }; + + accel@1e { + compatible = "nxp,fxos8700"; + reg = <0x1e>; + }; }; &ldb { diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index 54b2beadd7a2..8942bec65c5c 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -304,6 +304,11 @@ interrupts = <11 2>; wakeup-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; + + accel@1e { + compatible = "nxp,fxos8700"; + reg = <0x1e>; + }; }; &ldb { diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 1b6c1331c220..c40583dbd96d 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -361,6 +361,11 @@ interrupts = <12 2>; wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; }; + + accel@1e { + compatible = "nxp,fxos8700"; + reg = <0x1e>; + }; }; &ldb { diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi index a1066897be18..ee85031c3916 100644 --- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi @@ -173,6 +173,25 @@ pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; + magn@1c { + compatible = "st,lsm9ds1-magn"; + reg = <0x1c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mag>; + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_EDGE_RISING>; + }; + + imu@6a { + compatible = "st,lsm9ds1-imu"; + reg = <0x6a>; + st,drdy-int-pin = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_imu>; + interrupt-parent = <&gpio7>; + interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; + }; + ltc3676: pmic@3c { compatible = "lltc,ltc3676"; reg = <0x3c>; @@ -426,6 +445,12 @@ >; }; + pinctrl_imu: imugrp { + fsl,pins = < + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0 + >; + }; + pinctrl_ipu1_csi0: ipu1csi0grp { fsl,pins = < MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 @@ -449,6 +474,12 @@ >; }; + pinctrl_mag: maggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 + >; + }; + pinctrl_pcie: pciegrp { fsl,pins = < MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi index be1af7482f89..30fe47ff64a4 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi @@ -220,6 +220,14 @@ status = "okay"; }; +/* cc1352 */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + status = "okay"; +}; + /* Sterling-LWB Bluetooth */ &uart4 { pinctrl-names = "default"; @@ -411,6 +419,23 @@ >; }; + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x4001b0b1 /* DIO20 */ + MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x4001b0b1 /* DIO14 */ + MX6QDL_PAD_DISP0_DAT12__GPIO5_IO06 0x4001b0b1 /* DIO15 */ + MX6QDL_PAD_DISP0_DAT14__GPIO5_IO08 0x1b0b1 /* TMS */ + MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x1b0b1 /* TCK */ + MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10 0x1b0b1 /* TDO */ + MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x1b0b1 /* TDI */ + MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x4001b0b1 /* RST# */ + >; + }; + pinctrl_uart4: uart4grp { fsl,pins = < MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi index 77d871340eb7..41ebe4599e43 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi @@ -88,7 +88,7 @@ reg = <0x50>; }; - pmic@58 { + pmic: pmic@58 { compatible = "dlg,da9062"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pmic>; @@ -96,6 +96,8 @@ interrupt-parent = <&gpio1>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; + gpio-controller; + #gpio-cells = <2>; da9062_rtc: rtc { compatible = "dlg,da9062-rtc"; @@ -107,6 +109,7 @@ watchdog { compatible = "dlg,da9062-watchdog"; + dlg,use-sw-pm; }; regulators { diff --git a/arch/arm/boot/dts/imx6qdl-pico-dwarf.dtsi b/arch/arm/boot/dts/imx6qdl-pico-dwarf.dtsi new file mode 100644 index 000000000000..3a968782e854 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-pico-dwarf.dtsi @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +// +// Copyright 2017 NXP + +#include "imx6qdl-pico.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led { + label = "gpio-led"; + gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>; + }; + }; + +}; + +&i2c1 { + mpl3115@60 { + compatible = "fsl,mpl3115"; + reg = <0x60>; + }; +}; + +&i2c2 { + io-expander@25 { + compatible = "nxp,pca9554"; + reg = <0x25>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + }; + +}; + +&iomuxc { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-pico-hobbit.dtsi b/arch/arm/boot/dts/imx6qdl-pico-hobbit.dtsi new file mode 100644 index 000000000000..144c4727fbc7 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-pico-hobbit.dtsi @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +// +// Copyright 2017 NXP + +#include "imx6qdl-pico.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led { + label = "gpio-led"; + gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>; + }; + }; + +}; + +&i2c2 { + status = "okay"; + + adc081c: adc@50 { + compatible = "ti,adc081c"; + reg = <0x50>; + vref-supply = <®_3p3v>; + }; +}; + +&iomuxc { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-pico-nymph.dtsi b/arch/arm/boot/dts/imx6qdl-pico-nymph.dtsi new file mode 100644 index 000000000000..3d56a4216448 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-pico-nymph.dtsi @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT + +#include "imx6qdl-pico.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led { + label = "gpio-led"; + gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>; + }; + }; + +}; + +&i2c1 { + adc@52 { + compatible = "ti,adc081c"; + reg = <0x52>; + vref-supply = <®_2p5v>; + }; +}; + +&i2c2 { + io-expander@25 { + compatible = "nxp,pca9554"; + reg = <0x25>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + }; +}; + +&i2c3 { + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +&pcie { + status = "okay"; +}; + +&iomuxc { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-pico-pi.dtsi b/arch/arm/boot/dts/imx6qdl-pico-pi.dtsi new file mode 100644 index 000000000000..b823dce62e63 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-pico-pi.dtsi @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +// +// Copyright 2017 NXP + +#include "imx6qdl-pico.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led { + label = "gpio-led"; + gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>; + }; + }; + +}; + +&hdmi { + status = "disabled"; +}; + +&iomuxc { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-pico.dtsi b/arch/arm/boot/dts/imx6qdl-pico.dtsi new file mode 100644 index 000000000000..39dfd90c2c6b --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-pico.dtsi @@ -0,0 +1,617 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +// +// Copyright 2018 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> + +#include <dt-bindings/gpio/gpio.h> + +/ { + chosen { + stdout-path = &uart1; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_1p5v: regulator-1p5v { + compatible = "regulator-fixed"; + regulator-name = "1P5V"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + reg_2p8v: regulator-2p8v { + compatible = "regulator-fixed"; + regulator-name = "2P8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg_vbus>; + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_LOW>; + }; + + codec_osc: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx6-pico-sgtl5000"; + ssi-controller = <&ssi1>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <3>; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 50000 0>; + brightness-levels = <0 36 72 108 144 180 216 255>; + default-brightness-level = <6>; + status = "okay"; + }; + + reg_lcd_3v3: regulator-lcd-3v3 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_lcd>; + regulator-name = "lcd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + lcd_display: disp0 { + compatible = "fsl,imx-parallel-display"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1>; + status = "okay"; + + port@0 { + reg = <0>; + + lcd_display_in: endpoint { + remote-endpoint = <&ipu1_di0_disp0>; + }; + }; + + port@1 { + reg = <1>; + + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; + }; + + panel { + compatible = "vxt,vl050-8048nt-c01"; + backlight = <&backlight>; + power-supply = <®_lcd_3v3>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + status = "okay"; +}; + +&can2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + status = "okay"; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + cs-gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + phy-reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c2>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + sgtl5000: audio-codec@a { + #sound-dai-cells = <0>; + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&codec_osc>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_1p8v>; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + touchscreen@38 { + compatible = "edt,edt-ft5x06"; + reg = <0x38>; + interrupt-parent = <&gpio5>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio5 27 GPIO_ACTIVE_LOW>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + wakeup-source; + }; + + camera@3c { + compatible = "ovti,ov5645"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ov5645>; + reg = <0x3c>; + clocks = <&clks IMX6QDL_CLK_CKO2>; + clock-names = "xclk"; + clock-frequency = <24000000>; + vdddo-supply = <®_1p8v>; + vdda-supply = <®_2p8v>; + vddd-supply = <®_1p5v>; + enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + + port { + ov5645_to_mipi_csi2: endpoint { + remote-endpoint = <&mipi_csi2_in>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + }; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&ipu1_di0_disp0 { + remote-endpoint = <&lcd_display_in>; +}; + +&mipi_csi { + status = "okay"; + + port@0 { + reg = <0>; + + mipi_csi2_in: endpoint { + remote-endpoint = <&ov5645_to_mipi_csi2>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_reset>; + reset-gpio = <&gpio5 21 GPIO_ACTIVE_LOW>; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "okay"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "okay"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { /* Bluetooth module */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + uart-has-rtscts; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + status = "okay"; +}; + +&usbh1 { + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + dr_mode = "otg"; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + bus-width = <8>; + cd-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usdhc2 { /* Wifi/BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <4>; + no-1-8-v; + keep-power-in-suspend; + non-removable; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <8>; + no-1-8-v; + non-removable; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x4001b0b5 /* PICO_P24 */ + MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x4001b0b5 /* PICO_P26 */ + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x4001b0b5 /* PICO_P28 */ + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x4001b0b5 /* PICO_P30 */ + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x4001b0b5 /* PICO_P32 */ + MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x4001b0b5 /* PICO_P34 */ + MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x4001b0b5 /* PICO_P42 */ + MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x4001b0b5 /* PICO_P44 */ + MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x4001b0b5 /* PICO_P48 */ + >; + }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0 + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0 + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x000f0b0 + >; + }; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x1b0b1 + MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x1b0b1 + MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x1b0b1 + MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x000f0b0 + MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x000f0b0 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1f0b1 + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b0 + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_ipu1: ipu1grp { + fsl,pins = < + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10 + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10 + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10 + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10 + MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x10 + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10 + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10 + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10 + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10 + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10 + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10 + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10 + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10 + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10 + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10 + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10 + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10 + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10 + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10 + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10 + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10 + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10 + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10 + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10 + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10 + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10 + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10 + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10 + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10 + >; + }; + + pinctrl_ov5645: ov5645grp { + fsl,pins = < + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x0b0b0 + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0b0b0 + MX6QDL_PAD_GPIO_3__CCM_CLKO2 0x000b0 + >; + }; + + pinctrl_pcie_reset: pciegrp { + fsl,pins = < + MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x130b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + >; + }; + + pinctrl_reg_lcd: reglcdgrp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x1b0b0 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT5__UART2_RTS_B 0x1b0b1 + MX6QDL_PAD_SD4_DAT6__UART2_CTS_B 0x1b0b1 + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usbotg_vbus: usbotgvbusgrp { + fsl,pins = < + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x17071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0xb0b1 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi b/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi index 44a97ba93a95..352ac585ca6b 100644 --- a/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi @@ -153,6 +153,7 @@ bus-width = <4>; keep-power-in-suspend; mmc-pwrseq = <&pwrseq_ti_wifi>; + cap-power-off-card; non-removable; vmmc-supply = <&vcc_3v3>; /* vqmmc-supply = <&nvcc_sd1>; - MMC layer doesn't like it! */ diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi index 0075637f9b0b..20350e803377 100644 --- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -216,6 +216,13 @@ }; }; +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, + <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>; +}; + &cpu0 { fsl,soc-operating-points = < /* ARM kHz SOC-PU uV */ diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index e6b4b8525f98..98da446aa0f2 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -294,7 +294,7 @@ status = "disabled"; }; - aips-bus@2000000 { /* AIPS1 */ + bus@2000000 { /* AIPS1 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -574,7 +574,7 @@ status = "disabled"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt"; reg = <0x02098000 0x4000>; interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; @@ -661,7 +661,7 @@ #interrupt-cells = <2>; }; - kpp: kpp@20b8000 { + kpp: keypad@20b8000 { compatible = "fsl,imx6q-kpp", "fsl,imx21-kpp"; reg = <0x020b8000 0x4000>; interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; @@ -669,14 +669,14 @@ status = "disabled"; }; - wdog1: wdog@20bc000 { + wdog1: watchdog@20bc000 { compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt"; reg = <0x020bc000 0x4000>; interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_IPG>; }; - wdog2: wdog@20c0000 { + wdog2: watchdog@20c0000 { compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt"; reg = <0x020c0000 0x4000>; interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; @@ -684,7 +684,7 @@ status = "disabled"; }; - clks: ccm@20c4000 { + clks: clock-controller@20c4000 { compatible = "fsl,imx6q-ccm"; reg = <0x020c4000 0x4000>; interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>, @@ -908,7 +908,7 @@ }; }; - iomuxc: iomuxc@20e0000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc"; reg = <0x20e0000 0x4000>; }; @@ -935,14 +935,14 @@ }; }; - aips-bus@2100000 { /* AIPS2 */ + bus@2100000 { /* AIPS2 */ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; reg = <0x02100000 0x100000>; ranges; - crypto: caam@2100000 { + crypto: crypto@2100000 { compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; @@ -954,13 +954,13 @@ <&clks IMX6QDL_CLK_EIM_SLOW>; clock-names = "mem", "aclk", "ipg", "emi_slow"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; @@ -1039,13 +1039,13 @@ compatible = "fsl,imx6q-fec"; reg = <0x02188000 0x4000>; interrupt-names = "int0", "pps"; - interrupts-extended = - <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>, - <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, + <0 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET_REF>; clock-names = "ipg", "ahb", "ptp"; + gpr = <&gpr>; status = "disabled"; }; @@ -1161,10 +1161,16 @@ status = "disabled"; }; - ocotp: ocotp@21bc000 { + ocotp: ocotp-ctrl@21bc000 { compatible = "fsl,imx6q-ocotp", "syscon"; reg = <0x021bc000 0x4000>; clocks = <&clks IMX6QDL_CLK_IIM>; + #address-cells = <1>; + #size-cells = <1>; + + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; }; tzasc@21d0000 { /* TZASC1 */ diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi index 5f51f8e5c1fa..b310f13a53f2 100644 --- a/arch/arm/boot/dts/imx6qp.dtsi +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -18,7 +18,7 @@ clocks = <&clks IMX6QDL_CLK_OCRAM>; }; - aips-bus@2100000 { + bus@2100000 { pre1: pre@21c8000 { compatible = "fsl,imx6qp-pre"; reg = <0x021c8000 0x1000>; @@ -77,7 +77,6 @@ }; &fec { - /delete-property/interrupts-extended; interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, <0 119 IRQ_TYPE_LEVEL_HIGH>; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 59c54e6ad09a..8230b45057a1 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -74,6 +74,8 @@ arm-supply = <®_arm>; pu-supply = <®_pu>; soc-supply = <®_soc>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; }; }; @@ -143,7 +145,7 @@ arm,data-latency = <4 2 3>; }; - aips1: aips-bus@2000000 { + aips1: bus@2000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -380,7 +382,7 @@ clock-names = "ipg", "per"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6sl-gpt"; reg = <0x02098000 0x4000>; interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; @@ -491,7 +493,7 @@ <&iomuxc 21 161 1>; }; - kpp: kpp@20b8000 { + kpp: keypad@20b8000 { compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp"; reg = <0x020b8000 0x4000>; interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; @@ -499,14 +501,14 @@ status = "disabled"; }; - wdog1: wdog@20bc000 { + wdog1: watchdog@20bc000 { compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt"; reg = <0x020bc000 0x4000>; interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6SL_CLK_IPG>; }; - wdog2: wdog@20c0000 { + wdog2: watchdog@20c0000 { compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt"; reg = <0x020c0000 0x4000>; interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; @@ -514,7 +516,7 @@ status = "disabled"; }; - clks: ccm@20c4000 { + clks: clock-controller@20c4000 { compatible = "fsl,imx6sl-ccm"; reg = <0x020c4000 0x4000>; interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>, @@ -728,7 +730,7 @@ reg = <0x020e0000 0x38>; }; - iomuxc: iomuxc@20e0000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6sl-iomuxc"; reg = <0x020e0000 0x4000>; }; @@ -777,7 +779,7 @@ power-domains = <&pd_disp>; }; - dcp: dcp@20fc000 { + dcp: crypto@20fc000 { compatible = "fsl,imx6sl-dcp", "fsl,imx28-dcp"; reg = <0x020fc000 0x4000>; interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>, @@ -786,7 +788,7 @@ }; }; - aips2: aips-bus@2100000 { + aips2: bus@2100000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -949,10 +951,16 @@ status = "disabled"; }; - ocotp: ocotp@21bc000 { + ocotp: ocotp-ctrl@21bc000 { compatible = "fsl,imx6sl-ocotp", "syscon"; reg = <0x021bc000 0x4000>; clocks = <&clks IMX6SL_CLK_OCOTP>; + #address-cells = <1>; + #size-cells = <1>; + + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; }; audmux: audmux@21d8000 { diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi index a1bc5bb31756..edd3abb9a9f1 100644 --- a/arch/arm/boot/dts/imx6sll.dtsi +++ b/arch/arm/boot/dts/imx6sll.dtsi @@ -72,6 +72,8 @@ <&clks IMX6SLL_CLK_PLL1_SYS>; clock-names = "arm", "pll2_pfd2_396m", "step", "pll1_sw", "pll1_sys"; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; }; }; @@ -144,7 +146,7 @@ arm,data-latency = <4 2 3>; }; - aips1: aips-bus@2000000 { + aips1: bus@2000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -652,7 +654,7 @@ status = "disabled"; }; - dcp: dcp@20fc000 { + dcp: crypto@20fc000 { compatible = "fsl,imx28-dcp"; reg = <0x020fc000 0x4000>; interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, @@ -663,7 +665,7 @@ }; }; - aips2: aips-bus@2100000 { + aips2: bus@2100000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -791,6 +793,10 @@ reg = <0x021bc000 0x4000>; clocks = <&clks IMX6SLL_CLK_OCOTP>; + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; + tempmon_calib: calib@38 { reg = <0x38 4>; }; diff --git a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts index 832b5c5d7441..d84ea6999377 100644 --- a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts +++ b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts @@ -484,31 +484,31 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x1b0b1 >; }; pinctrl_uart2: uart2grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO06__UART2_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO07__UART2_DCE_RX 0x1b0b1 >; }; pinctrl_uart3: uart3grp { fsl,pins = < - MX6SX_PAD_QSPI1B_SS0_B__UART3_TX 0x1b0b1 - MX6SX_PAD_QSPI1B_SCLK__UART3_RX 0x1b0b1 + MX6SX_PAD_QSPI1B_SS0_B__UART3_DCE_TX 0x1b0b1 + MX6SX_PAD_QSPI1B_SCLK__UART3_DCE_RX 0x1b0b1 >; }; pinctrl_uart5: uart5grp { fsl,pins = < - MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1 - MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1 - MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x1b0b1 - MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x1b0b1 + MX6SX_PAD_KEY_COL3__UART5_DCE_TX 0x1b0b1 + MX6SX_PAD_KEY_ROW3__UART5_DCE_RX 0x1b0b1 + MX6SX_PAD_SD3_DATA6__UART3_DCE_RTS 0x1b0b1 + MX6SX_PAD_SD3_DATA7__UART3_DCE_CTS 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6sx-pinfunc.h b/arch/arm/boot/dts/imx6sx-pinfunc.h index aa194a2fdd53..0b02c7e60c17 100644 --- a/arch/arm/boot/dts/imx6sx-pinfunc.h +++ b/arch/arm/boot/dts/imx6sx-pinfunc.h @@ -42,8 +42,8 @@ #define MX6SX_PAD_GPIO1_IO03__GPIO1_IO_3 0x0020 0x0368 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO03__CCM_PLL3_BYP 0x0020 0x0368 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO03__PHY_TCK 0x0020 0x0368 0x0000 0x7 0x0 -#define MX6SX_PAD_GPIO1_IO04__UART1_RX 0x0024 0x036C 0x0830 0x0 0x0 -#define MX6SX_PAD_GPIO1_IO04__UART1_TX 0x0024 0x036C 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x0024 0x036C 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO04__UART1_DTE_RX 0x0024 0x036C 0x0830 0x0 0x0 #define MX6SX_PAD_GPIO1_IO04__USDHC2_RESET_B 0x0024 0x036C 0x0000 0x1 0x0 #define MX6SX_PAD_GPIO1_IO04__ENET1_MDC 0x0024 0x036C 0x0000 0x2 0x0 #define MX6SX_PAD_GPIO1_IO04__OSC32K_32K_OUT 0x0024 0x036C 0x0000 0x3 0x0 @@ -51,8 +51,8 @@ #define MX6SX_PAD_GPIO1_IO04__GPIO1_IO_4 0x0024 0x036C 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO04__CCM_PLL2_BYP 0x0024 0x036C 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO04__PHY_TMS 0x0024 0x036C 0x0000 0x7 0x0 -#define MX6SX_PAD_GPIO1_IO05__UART1_RX 0x0028 0x0370 0x0830 0x0 0x1 -#define MX6SX_PAD_GPIO1_IO05__UART1_TX 0x0028 0x0370 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x0028 0x0370 0x0830 0x0 0x1 +#define MX6SX_PAD_GPIO1_IO05__UART1_DTE_TX 0x0028 0x0370 0x0000 0x0 0x0 #define MX6SX_PAD_GPIO1_IO05__USDHC2_VSELECT 0x0028 0x0370 0x0000 0x1 0x0 #define MX6SX_PAD_GPIO1_IO05__ENET1_MDIO 0x0028 0x0370 0x0764 0x2 0x0 #define MX6SX_PAD_GPIO1_IO05__ASRC_ASRC_EXT_CLK 0x0028 0x0370 0x0000 0x3 0x0 @@ -60,21 +60,23 @@ #define MX6SX_PAD_GPIO1_IO05__GPIO1_IO_5 0x0028 0x0370 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO05__SRC_TESTER_ACK 0x0028 0x0370 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO05__PHY_TDO 0x0028 0x0370 0x0000 0x7 0x0 -#define MX6SX_PAD_GPIO1_IO06__UART2_RX 0x002C 0x0374 0x0838 0x0 0x0 -#define MX6SX_PAD_GPIO1_IO06__UART2_TX 0x002C 0x0374 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO06__UART2_DCE_TX 0x002C 0x0374 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO06__UART2_DTE_RX 0x002C 0x0374 0x0838 0x0 0x0 #define MX6SX_PAD_GPIO1_IO06__USDHC2_CD_B 0x002C 0x0374 0x086C 0x1 0x1 #define MX6SX_PAD_GPIO1_IO06__ENET2_MDC 0x002C 0x0374 0x0000 0x2 0x0 #define MX6SX_PAD_GPIO1_IO06__CSI1_MCLK 0x002C 0x0374 0x0000 0x3 0x0 -#define MX6SX_PAD_GPIO1_IO06__UART1_RTS_B 0x002C 0x0374 0x082C 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO06__UART1_DCE_RTS 0x002C 0x0374 0x082C 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO06__UART1_DTE_CTS 0x002C 0x0374 0x0000 0x4 0x0 #define MX6SX_PAD_GPIO1_IO06__GPIO1_IO_6 0x002C 0x0374 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO06__SRC_ANY_PU_RESET 0x002C 0x0374 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO06__OCOTP_CTRL_WRAPPER_FUSE_LATCHED 0x002C 0x0374 0x0000 0x7 0x0 -#define MX6SX_PAD_GPIO1_IO07__UART2_RX 0x0030 0x0378 0x0838 0x0 0x1 -#define MX6SX_PAD_GPIO1_IO07__UART2_TX 0x0030 0x0378 0x0000 0x0 0x0 +#define MX6SX_PAD_GPIO1_IO07__UART2_DCE_RX 0x0030 0x0378 0x0838 0x0 0x1 +#define MX6SX_PAD_GPIO1_IO07__UART2_DTE_TX 0x0030 0x0378 0x0000 0x0 0x0 #define MX6SX_PAD_GPIO1_IO07__USDHC2_WP 0x0030 0x0378 0x0870 0x1 0x1 #define MX6SX_PAD_GPIO1_IO07__ENET2_MDIO 0x0030 0x0378 0x0770 0x2 0x0 #define MX6SX_PAD_GPIO1_IO07__AUDMUX_MCLK 0x0030 0x0378 0x0000 0x3 0x0 -#define MX6SX_PAD_GPIO1_IO07__UART1_CTS_B 0x0030 0x0378 0x0000 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO07__UART1_DCE_CTS 0x0030 0x0378 0x0000 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO07__UART1_DTE_RTS 0x0030 0x0378 0x082C 0x4 0x1 #define MX6SX_PAD_GPIO1_IO07__GPIO1_IO_7 0x0030 0x0378 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO07__SRC_EARLY_RESET 0x0030 0x0378 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO07__DCIC2_OUT 0x0030 0x0378 0x0000 0x7 0x0 @@ -83,7 +85,8 @@ #define MX6SX_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x0034 0x037C 0x0000 0x1 0x0 #define MX6SX_PAD_GPIO1_IO08__SDMA_EXT_EVENT_0 0x0034 0x037C 0x081C 0x2 0x0 #define MX6SX_PAD_GPIO1_IO08__CCM_PMIC_RDY 0x0034 0x037C 0x069C 0x3 0x1 -#define MX6SX_PAD_GPIO1_IO08__UART2_RTS_B 0x0034 0x037C 0x0834 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO08__UART2_DCE_RTS 0x0034 0x037C 0x0834 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO08__UART2_DTE_CTS 0x0034 0x037C 0x0000 0x4 0x0 #define MX6SX_PAD_GPIO1_IO08__GPIO1_IO_8 0x0034 0x037C 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO08__SRC_SYSTEM_RESET 0x0034 0x037C 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO08__DCIC1_OUT 0x0034 0x037C 0x0000 0x7 0x0 @@ -92,7 +95,8 @@ #define MX6SX_PAD_GPIO1_IO09__WDOG2_WDOG_B 0x0038 0x0380 0x0000 0x1 0x0 #define MX6SX_PAD_GPIO1_IO09__SDMA_EXT_EVENT_1 0x0038 0x0380 0x0820 0x2 0x0 #define MX6SX_PAD_GPIO1_IO09__CCM_OUT0 0x0038 0x0380 0x0000 0x3 0x0 -#define MX6SX_PAD_GPIO1_IO09__UART2_CTS_B 0x0038 0x0380 0x0000 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO09__UART2_DCE_CTS 0x0038 0x0380 0x0000 0x4 0x0 +#define MX6SX_PAD_GPIO1_IO09__UART2_DTE_RTS 0x0038 0x0380 0x0834 0x4 0x1 #define MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x0038 0x0380 0x0000 0x5 0x0 #define MX6SX_PAD_GPIO1_IO09__SRC_INT_BOOT 0x0038 0x0380 0x0000 0x6 0x0 #define MX6SX_PAD_GPIO1_IO09__OBSERVE_MUX_OUT_4 0x0038 0x0380 0x0000 0x7 0x0 @@ -177,8 +181,8 @@ #define MX6SX_PAD_CSI_DATA04__ESAI_TX1 0x005C 0x03A4 0x0794 0x1 0x1 #define MX6SX_PAD_CSI_DATA04__SPDIF_OUT 0x005C 0x03A4 0x0000 0x2 0x0 #define MX6SX_PAD_CSI_DATA04__KPP_COL_6 0x005C 0x03A4 0x07CC 0x3 0x0 -#define MX6SX_PAD_CSI_DATA04__UART6_RX 0x005C 0x03A4 0x0858 0x4 0x0 -#define MX6SX_PAD_CSI_DATA04__UART6_TX 0x005C 0x03A4 0x0000 0x4 0x0 +#define MX6SX_PAD_CSI_DATA04__UART6_DCE_RX 0x005C 0x03A4 0x0858 0x4 0x0 +#define MX6SX_PAD_CSI_DATA04__UART6_DTE_TX 0x005C 0x03A4 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x005C 0x03A4 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_DATA04__WEIM_DATA_19 0x005C 0x03A4 0x0000 0x6 0x0 #define MX6SX_PAD_CSI_DATA04__PWM5_OUT 0x005C 0x03A4 0x0000 0x7 0x0 @@ -188,8 +192,8 @@ #define MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1 0x0060 0x03A8 0x07A0 0x1 0x1 #define MX6SX_PAD_CSI_DATA05__SPDIF_IN 0x0060 0x03A8 0x0824 0x2 0x1 #define MX6SX_PAD_CSI_DATA05__KPP_ROW_6 0x0060 0x03A8 0x07D8 0x3 0x0 -#define MX6SX_PAD_CSI_DATA05__UART6_RX 0x0060 0x03A8 0x0858 0x4 0x1 -#define MX6SX_PAD_CSI_DATA05__UART6_TX 0x0060 0x03A8 0x0000 0x4 0x0 +#define MX6SX_PAD_CSI_DATA05__UART6_DCE_TX 0x0060 0x03A8 0x0000 0x4 0x0 +#define MX6SX_PAD_CSI_DATA05__UART6_DTE_RX 0x0060 0x03A8 0x0858 0x4 0x1 #define MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x0060 0x03A8 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_DATA05__WEIM_DATA_18 0x0060 0x03A8 0x0000 0x6 0x0 #define MX6SX_PAD_CSI_DATA05__PWM6_OUT 0x0060 0x03A8 0x0000 0x7 0x0 @@ -199,7 +203,8 @@ #define MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3 0x0064 0x03AC 0x0798 0x1 0x1 #define MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x0064 0x03AC 0x07C0 0x2 0x2 #define MX6SX_PAD_CSI_DATA06__KPP_COL_7 0x0064 0x03AC 0x07D0 0x3 0x0 -#define MX6SX_PAD_CSI_DATA06__UART6_RTS_B 0x0064 0x03AC 0x0854 0x4 0x0 +#define MX6SX_PAD_CSI_DATA06__UART6_DCE_RTS 0x0064 0x03AC 0x0854 0x4 0x0 +#define MX6SX_PAD_CSI_DATA06__UART6_DTE_CTS 0x0064 0x03AC 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_DATA06__GPIO1_IO_20 0x0064 0x03AC 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_DATA06__WEIM_DATA_17 0x0064 0x03AC 0x0000 0x6 0x0 #define MX6SX_PAD_CSI_DATA06__DCIC2_OUT 0x0064 0x03AC 0x0000 0x7 0x0 @@ -209,7 +214,8 @@ #define MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2 0x0068 0x03B0 0x079C 0x1 0x1 #define MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x0068 0x03B0 0x07C4 0x2 0x2 #define MX6SX_PAD_CSI_DATA07__KPP_ROW_7 0x0068 0x03B0 0x07DC 0x3 0x0 -#define MX6SX_PAD_CSI_DATA07__UART6_CTS_B 0x0068 0x03B0 0x0000 0x4 0x0 +#define MX6SX_PAD_CSI_DATA07__UART6_DCE_CTS 0x0068 0x03B0 0x0000 0x4 0x0 +#define MX6SX_PAD_CSI_DATA07__UART6_DTE_RTS 0x0068 0x03B0 0x0854 0x4 0x1 #define MX6SX_PAD_CSI_DATA07__GPIO1_IO_21 0x0068 0x03B0 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_DATA07__WEIM_DATA_16 0x0068 0x03B0 0x0000 0x6 0x0 #define MX6SX_PAD_CSI_DATA07__DCIC1_OUT 0x0068 0x03B0 0x0000 0x7 0x0 @@ -218,7 +224,8 @@ #define MX6SX_PAD_CSI_HSYNC__CSI1_HSYNC 0x006C 0x03B4 0x0700 0x0 0x0 #define MX6SX_PAD_CSI_HSYNC__ESAI_TX0 0x006C 0x03B4 0x0790 0x1 0x1 #define MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x006C 0x03B4 0x0678 0x2 0x1 -#define MX6SX_PAD_CSI_HSYNC__UART4_RTS_B 0x006C 0x03B4 0x0844 0x3 0x2 +#define MX6SX_PAD_CSI_HSYNC__UART4_DCE_RTS 0x006C 0x03B4 0x0844 0x3 0x2 +#define MX6SX_PAD_CSI_HSYNC__UART4_DTE_CTS 0x006C 0x03B4 0x0000 0x3 0x0 #define MX6SX_PAD_CSI_HSYNC__MQS_LEFT 0x006C 0x03B4 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_HSYNC__GPIO1_IO_22 0x006C 0x03B4 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_HSYNC__WEIM_DATA_25 0x006C 0x03B4 0x0000 0x6 0x0 @@ -228,8 +235,8 @@ #define MX6SX_PAD_CSI_MCLK__CSI1_MCLK 0x0070 0x03B8 0x0000 0x0 0x0 #define MX6SX_PAD_CSI_MCLK__ESAI_TX_HF_CLK 0x0070 0x03B8 0x0784 0x1 0x1 #define MX6SX_PAD_CSI_MCLK__OSC32K_32K_OUT 0x0070 0x03B8 0x0000 0x2 0x0 -#define MX6SX_PAD_CSI_MCLK__UART4_RX 0x0070 0x03B8 0x0848 0x3 0x2 -#define MX6SX_PAD_CSI_MCLK__UART4_TX 0x0070 0x03B8 0x0000 0x3 0x0 +#define MX6SX_PAD_CSI_MCLK__UART4_DCE_RX 0x0070 0x03B8 0x0848 0x3 0x2 +#define MX6SX_PAD_CSI_MCLK__UART4_DTE_TX 0x0070 0x03B8 0x0000 0x3 0x0 #define MX6SX_PAD_CSI_MCLK__ANATOP_32K_OUT 0x0070 0x03B8 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_MCLK__GPIO1_IO_23 0x0070 0x03B8 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_MCLK__WEIM_DATA_26 0x0070 0x03B8 0x0000 0x6 0x0 @@ -239,8 +246,8 @@ #define MX6SX_PAD_CSI_PIXCLK__CSI1_PIXCLK 0x0074 0x03BC 0x0704 0x0 0x0 #define MX6SX_PAD_CSI_PIXCLK__ESAI_RX_HF_CLK 0x0074 0x03BC 0x0780 0x1 0x1 #define MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x0074 0x03BC 0x0000 0x2 0x0 -#define MX6SX_PAD_CSI_PIXCLK__UART4_RX 0x0074 0x03BC 0x0848 0x3 0x3 -#define MX6SX_PAD_CSI_PIXCLK__UART4_TX 0x0074 0x03BC 0x0000 0x3 0x0 +#define MX6SX_PAD_CSI_PIXCLK__UART4_DCE_TX 0x0074 0x03BC 0x0000 0x3 0x0 +#define MX6SX_PAD_CSI_PIXCLK__UART4_DTE_RX 0x0074 0x03BC 0x0848 0x3 0x3 #define MX6SX_PAD_CSI_PIXCLK__ANATOP_24M_OUT 0x0074 0x03BC 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_PIXCLK__GPIO1_IO_24 0x0074 0x03BC 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_PIXCLK__WEIM_DATA_27 0x0074 0x03BC 0x0000 0x6 0x0 @@ -250,7 +257,8 @@ #define MX6SX_PAD_CSI_VSYNC__CSI1_VSYNC 0x0078 0x03C0 0x0708 0x0 0x0 #define MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0 0x0078 0x03C0 0x07A4 0x1 0x1 #define MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x0078 0x03C0 0x0674 0x2 0x1 -#define MX6SX_PAD_CSI_VSYNC__UART4_CTS_B 0x0078 0x03C0 0x0000 0x3 0x0 +#define MX6SX_PAD_CSI_VSYNC__UART4_DCE_CTS 0x0078 0x03C0 0x0000 0x3 0x0 +#define MX6SX_PAD_CSI_VSYNC__UART4_DTE_RTS 0x0078 0x03C0 0x0844 0x3 0x3 #define MX6SX_PAD_CSI_VSYNC__MQS_RIGHT 0x0078 0x03C0 0x0000 0x4 0x0 #define MX6SX_PAD_CSI_VSYNC__GPIO1_IO_25 0x0078 0x03C0 0x0000 0x5 0x0 #define MX6SX_PAD_CSI_VSYNC__WEIM_DATA_24 0x0078 0x03C0 0x0000 0x6 0x0 @@ -330,8 +338,8 @@ #define MX6SX_PAD_ENET2_COL__ENET2_COL 0x0094 0x03DC 0x0000 0x0 0x0 #define MX6SX_PAD_ENET2_COL__ENET1_MDC 0x0094 0x03DC 0x0000 0x1 0x0 #define MX6SX_PAD_ENET2_COL__AUDMUX_AUD4_RXC 0x0094 0x03DC 0x064C 0x2 0x1 -#define MX6SX_PAD_ENET2_COL__UART1_RX 0x0094 0x03DC 0x0830 0x3 0x2 -#define MX6SX_PAD_ENET2_COL__UART1_TX 0x0094 0x03DC 0x0000 0x3 0x0 +#define MX6SX_PAD_ENET2_COL__UART1_DCE_RX 0x0094 0x03DC 0x0830 0x3 0x2 +#define MX6SX_PAD_ENET2_COL__UART1_DTE_TX 0x0094 0x03DC 0x0000 0x3 0x0 #define MX6SX_PAD_ENET2_COL__SPDIF_IN 0x0094 0x03DC 0x0824 0x4 0x3 #define MX6SX_PAD_ENET2_COL__GPIO2_IO_6 0x0094 0x03DC 0x0000 0x5 0x0 #define MX6SX_PAD_ENET2_COL__ANATOP_OTG1_ID 0x0094 0x03DC 0x0624 0x6 0x1 @@ -341,8 +349,8 @@ #define MX6SX_PAD_ENET2_CRS__ENET2_CRS 0x0098 0x03E0 0x0000 0x0 0x0 #define MX6SX_PAD_ENET2_CRS__ENET1_MDIO 0x0098 0x03E0 0x0764 0x1 0x2 #define MX6SX_PAD_ENET2_CRS__AUDMUX_AUD4_RXFS 0x0098 0x03E0 0x0650 0x2 0x1 -#define MX6SX_PAD_ENET2_CRS__UART1_RX 0x0098 0x03E0 0x0830 0x3 0x3 -#define MX6SX_PAD_ENET2_CRS__UART1_TX 0x0098 0x03E0 0x0000 0x3 0x0 +#define MX6SX_PAD_ENET2_CRS__UART1_DCE_TX 0x0098 0x03E0 0x0000 0x3 0x0 +#define MX6SX_PAD_ENET2_CRS__UART1_DTE_RX 0x0098 0x03E0 0x0830 0x3 0x3 #define MX6SX_PAD_ENET2_CRS__MLB_SIG 0x0098 0x03E0 0x07F0 0x4 0x1 #define MX6SX_PAD_ENET2_CRS__GPIO2_IO_7 0x0098 0x03E0 0x0000 0x5 0x0 #define MX6SX_PAD_ENET2_CRS__ANATOP_OTG2_ID 0x0098 0x03E0 0x0628 0x6 0x1 @@ -352,7 +360,8 @@ #define MX6SX_PAD_ENET2_RX_CLK__ENET2_RX_CLK 0x009C 0x03E4 0x0774 0x0 0x0 #define MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x009C 0x03E4 0x0000 0x1 0x0 #define MX6SX_PAD_ENET2_RX_CLK__I2C3_SCL 0x009C 0x03E4 0x07B8 0x2 0x1 -#define MX6SX_PAD_ENET2_RX_CLK__UART1_RTS_B 0x009C 0x03E4 0x082C 0x3 0x2 +#define MX6SX_PAD_ENET2_RX_CLK__UART1_DCE_RTS 0x009C 0x03E4 0x082C 0x3 0x2 +#define MX6SX_PAD_ENET2_RX_CLK__UART1_DTE_CTS 0x009C 0x03E4 0x0000 0x3 0x0 #define MX6SX_PAD_ENET2_RX_CLK__MLB_DATA 0x009C 0x03E4 0x07EC 0x4 0x1 #define MX6SX_PAD_ENET2_RX_CLK__GPIO2_IO_8 0x009C 0x03E4 0x0000 0x5 0x0 #define MX6SX_PAD_ENET2_RX_CLK__USB_OTG2_OC 0x009C 0x03E4 0x085C 0x6 0x1 @@ -362,7 +371,8 @@ #define MX6SX_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x00A0 0x03E8 0x0000 0x0 0x0 #define MX6SX_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x00A0 0x03E8 0x076C 0x1 0x1 #define MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA 0x00A0 0x03E8 0x07BC 0x2 0x1 -#define MX6SX_PAD_ENET2_TX_CLK__UART1_CTS_B 0x00A0 0x03E8 0x0000 0x3 0x0 +#define MX6SX_PAD_ENET2_TX_CLK__UART1_DCE_CTS 0x00A0 0x03E8 0x0000 0x3 0x0 +#define MX6SX_PAD_ENET2_TX_CLK__UART1_DTE_RTS 0x00A0 0x03E8 0x082C 0x3 0x3 #define MX6SX_PAD_ENET2_TX_CLK__MLB_CLK 0x00A0 0x03E8 0x07E8 0x4 0x1 #define MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9 0x00A0 0x03E8 0x0000 0x5 0x0 #define MX6SX_PAD_ENET2_TX_CLK__USB_OTG2_PWR 0x00A0 0x03E8 0x0000 0x6 0x0 @@ -371,7 +381,8 @@ #define MX6SX_PAD_ENET2_TX_CLK__PCIE_CTRL_DEBUG_24 0x00A0 0x03E8 0x0000 0x9 0x0 #define MX6SX_PAD_KEY_COL0__KPP_COL_0 0x00A4 0x03EC 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_COL0__USDHC3_CD_B 0x00A4 0x03EC 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_COL0__UART6_RTS_B 0x00A4 0x03EC 0x0854 0x2 0x2 +#define MX6SX_PAD_KEY_COL0__UART6_DCE_RTS 0x00A4 0x03EC 0x0854 0x2 0x2 +#define MX6SX_PAD_KEY_COL0__UART6_DTE_CTS 0x00A4 0x03EC 0x0000 0x2 0x0 #define MX6SX_PAD_KEY_COL0__ECSPI1_SCLK 0x00A4 0x03EC 0x0710 0x3 0x0 #define MX6SX_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x00A4 0x03EC 0x066C 0x4 0x0 #define MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x00A4 0x03EC 0x0000 0x5 0x0 @@ -380,8 +391,8 @@ #define MX6SX_PAD_KEY_COL0__VADC_DATA_0 0x00A4 0x03EC 0x0000 0x8 0x0 #define MX6SX_PAD_KEY_COL1__KPP_COL_1 0x00A8 0x03F0 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_COL1__USDHC3_RESET_B 0x00A8 0x03F0 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_COL1__UART6_RX 0x00A8 0x03F0 0x0858 0x2 0x2 -#define MX6SX_PAD_KEY_COL1__UART6_TX 0x00A8 0x03F0 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_COL1__UART6_DCE_TX 0x00A8 0x03F0 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_COL1__UART6_DTE_RX 0x00A8 0x03F0 0x0858 0x2 0x2 #define MX6SX_PAD_KEY_COL1__ECSPI1_MISO 0x00A8 0x03F0 0x0714 0x3 0x0 #define MX6SX_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x00A8 0x03F0 0x0670 0x4 0x0 #define MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x00A8 0x03F0 0x0000 0x5 0x0 @@ -389,7 +400,8 @@ #define MX6SX_PAD_KEY_COL1__SAI2_TX_SYNC 0x00A8 0x03F0 0x0818 0x7 0x0 #define MX6SX_PAD_KEY_COL2__KPP_COL_2 0x00AC 0x03F4 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_COL2__USDHC4_CD_B 0x00AC 0x03F4 0x0874 0x1 0x1 -#define MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x00AC 0x03F4 0x084C 0x2 0x2 +#define MX6SX_PAD_KEY_COL2__UART5_DCE_RTS 0x00AC 0x03F4 0x084C 0x2 0x2 +#define MX6SX_PAD_KEY_COL2__UART5_DTE_CTS 0x00AC 0x03F4 0x0000 0x2 0x0 #define MX6SX_PAD_KEY_COL2__CAN1_TX 0x00AC 0x03F4 0x0000 0x3 0x0 #define MX6SX_PAD_KEY_COL2__CANFD_TX1 0x00AC 0x03F4 0x0000 0x4 0x0 #define MX6SX_PAD_KEY_COL2__GPIO2_IO_12 0x00AC 0x03F4 0x0000 0x5 0x0 @@ -397,8 +409,8 @@ #define MX6SX_PAD_KEY_COL2__ECSPI1_RDY 0x00AC 0x03F4 0x0000 0x7 0x0 #define MX6SX_PAD_KEY_COL3__KPP_COL_3 0x00B0 0x03F8 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_COL3__USDHC4_LCTL 0x00B0 0x03F8 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_COL3__UART5_RX 0x00B0 0x03F8 0x0850 0x2 0x2 -#define MX6SX_PAD_KEY_COL3__UART5_TX 0x00B0 0x03F8 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_COL3__UART5_DCE_TX 0x00B0 0x03F8 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_COL3__UART5_DTE_RX 0x00B0 0x03F8 0x0850 0x2 0x2 #define MX6SX_PAD_KEY_COL3__CAN2_TX 0x00B0 0x03F8 0x0000 0x3 0x0 #define MX6SX_PAD_KEY_COL3__CANFD_TX2 0x00B0 0x03F8 0x0000 0x4 0x0 #define MX6SX_PAD_KEY_COL3__GPIO2_IO_13 0x00B0 0x03F8 0x0000 0x5 0x0 @@ -414,7 +426,8 @@ #define MX6SX_PAD_KEY_COL4__SAI2_RX_BCLK 0x00B4 0x03FC 0x0808 0x7 0x0 #define MX6SX_PAD_KEY_ROW0__KPP_ROW_0 0x00B8 0x0400 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_ROW0__USDHC3_WP 0x00B8 0x0400 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_ROW0__UART6_CTS_B 0x00B8 0x0400 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW0__UART6_DCE_CTS 0x00B8 0x0400 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW0__UART6_DTE_RTS 0x00B8 0x0400 0x0854 0x2 0x3 #define MX6SX_PAD_KEY_ROW0__ECSPI1_MOSI 0x00B8 0x0400 0x0718 0x3 0x0 #define MX6SX_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x00B8 0x0400 0x0660 0x4 0x0 #define MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x00B8 0x0400 0x0000 0x5 0x0 @@ -423,8 +436,8 @@ #define MX6SX_PAD_KEY_ROW0__GPU_IDLE 0x00B8 0x0400 0x0000 0x8 0x0 #define MX6SX_PAD_KEY_ROW1__KPP_ROW_1 0x00BC 0x0404 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_ROW1__USDHC4_VSELECT 0x00BC 0x0404 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_ROW1__UART6_RX 0x00BC 0x0404 0x0858 0x2 0x3 -#define MX6SX_PAD_KEY_ROW1__UART6_TX 0x00BC 0x0404 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW1__UART6_DCE_RX 0x00BC 0x0404 0x0858 0x2 0x3 +#define MX6SX_PAD_KEY_ROW1__UART6_DTE_TX 0x00BC 0x0404 0x0000 0x2 0x0 #define MX6SX_PAD_KEY_ROW1__ECSPI1_SS0 0x00BC 0x0404 0x071C 0x3 0x0 #define MX6SX_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x00BC 0x0404 0x065C 0x4 0x0 #define MX6SX_PAD_KEY_ROW1__GPIO2_IO_16 0x00BC 0x0404 0x0000 0x5 0x0 @@ -433,7 +446,8 @@ #define MX6SX_PAD_KEY_ROW1__M4_NMI 0x00BC 0x0404 0x0000 0x8 0x0 #define MX6SX_PAD_KEY_ROW2__KPP_ROW_2 0x00C0 0x0408 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_ROW2__USDHC4_WP 0x00C0 0x0408 0x0878 0x1 0x1 -#define MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x00C0 0x0408 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW2__UART5_DCE_CTS 0x00C0 0x0408 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW2__UART5_DTE_RTS 0x00C0 0x0408 0x084C 0x2 0x3 #define MX6SX_PAD_KEY_ROW2__CAN1_RX 0x00C0 0x0408 0x068C 0x3 0x1 #define MX6SX_PAD_KEY_ROW2__CANFD_RX1 0x00C0 0x0408 0x0694 0x4 0x1 #define MX6SX_PAD_KEY_ROW2__GPIO2_IO_17 0x00C0 0x0408 0x0000 0x5 0x0 @@ -441,8 +455,8 @@ #define MX6SX_PAD_KEY_ROW2__ECSPI1_SS3 0x00C0 0x0408 0x0000 0x7 0x0 #define MX6SX_PAD_KEY_ROW3__KPP_ROW_3 0x00C4 0x040C 0x0000 0x0 0x0 #define MX6SX_PAD_KEY_ROW3__USDHC3_LCTL 0x00C4 0x040C 0x0000 0x1 0x0 -#define MX6SX_PAD_KEY_ROW3__UART5_RX 0x00C4 0x040C 0x0850 0x2 0x3 -#define MX6SX_PAD_KEY_ROW3__UART5_TX 0x00C4 0x040C 0x0000 0x2 0x0 +#define MX6SX_PAD_KEY_ROW3__UART5_DCE_RX 0x00C4 0x040C 0x0850 0x2 0x3 +#define MX6SX_PAD_KEY_ROW3__UART5_DTE_TX 0x00C4 0x040C 0x0000 0x2 0x0 #define MX6SX_PAD_KEY_ROW3__CAN2_RX 0x00C4 0x040C 0x0690 0x3 0x1 #define MX6SX_PAD_KEY_ROW3__CANFD_RX2 0x00C4 0x040C 0x0698 0x4 0x1 #define MX6SX_PAD_KEY_ROW3__GPIO2_IO_18 0x00C4 0x040C 0x0000 0x5 0x0 @@ -815,7 +829,8 @@ #define MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04 0x0160 0x04A8 0x0000 0x0 0x0 #define MX6SX_PAD_NAND_DATA04__USDHC2_DATA4 0x0160 0x04A8 0x0000 0x1 0x0 #define MX6SX_PAD_NAND_DATA04__QSPI2_B_SS1_B 0x0160 0x04A8 0x0000 0x2 0x0 -#define MX6SX_PAD_NAND_DATA04__UART3_RTS_B 0x0160 0x04A8 0x083C 0x3 0x0 +#define MX6SX_PAD_NAND_DATA04__UART3_DCE_RTS 0x0160 0x04A8 0x083C 0x3 0x0 +#define MX6SX_PAD_NAND_DATA04__UART3_DTE_CTS 0x0160 0x04A8 0x0000 0x3 0x0 #define MX6SX_PAD_NAND_DATA04__AUDMUX_AUD4_RXFS 0x0160 0x04A8 0x0650 0x4 0x0 #define MX6SX_PAD_NAND_DATA04__GPIO4_IO_8 0x0160 0x04A8 0x0000 0x5 0x0 #define MX6SX_PAD_NAND_DATA04__WEIM_AD_4 0x0160 0x04A8 0x0000 0x6 0x0 @@ -825,7 +840,8 @@ #define MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05 0x0164 0x04AC 0x0000 0x0 0x0 #define MX6SX_PAD_NAND_DATA05__USDHC2_DATA5 0x0164 0x04AC 0x0000 0x1 0x0 #define MX6SX_PAD_NAND_DATA05__QSPI2_B_DQS 0x0164 0x04AC 0x0000 0x2 0x0 -#define MX6SX_PAD_NAND_DATA05__UART3_CTS_B 0x0164 0x04AC 0x0000 0x3 0x0 +#define MX6SX_PAD_NAND_DATA05__UART3_DCE_CTS 0x0164 0x04AC 0x0000 0x3 0x0 +#define MX6SX_PAD_NAND_DATA05__UART3_DTE_RTS 0x0164 0x04AC 0x083C 0x3 0x1 #define MX6SX_PAD_NAND_DATA05__AUDMUX_AUD4_RXC 0x0164 0x04AC 0x064C 0x4 0x0 #define MX6SX_PAD_NAND_DATA05__GPIO4_IO_9 0x0164 0x04AC 0x0000 0x5 0x0 #define MX6SX_PAD_NAND_DATA05__WEIM_AD_5 0x0164 0x04AC 0x0000 0x6 0x0 @@ -835,8 +851,8 @@ #define MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06 0x0168 0x04B0 0x0000 0x0 0x0 #define MX6SX_PAD_NAND_DATA06__USDHC2_DATA6 0x0168 0x04B0 0x0000 0x1 0x0 #define MX6SX_PAD_NAND_DATA06__QSPI2_A_SS1_B 0x0168 0x04B0 0x0000 0x2 0x0 -#define MX6SX_PAD_NAND_DATA06__UART3_RX 0x0168 0x04B0 0x0840 0x3 0x0 -#define MX6SX_PAD_NAND_DATA06__UART3_TX 0x0168 0x04B0 0x0000 0x3 0x0 +#define MX6SX_PAD_NAND_DATA06__UART3_DCE_RX 0x0168 0x04B0 0x0840 0x3 0x0 +#define MX6SX_PAD_NAND_DATA06__UART3_DTE_TX 0x0168 0x04B0 0x0000 0x3 0x0 #define MX6SX_PAD_NAND_DATA06__PWM3_OUT 0x0168 0x04B0 0x0000 0x4 0x0 #define MX6SX_PAD_NAND_DATA06__GPIO4_IO_10 0x0168 0x04B0 0x0000 0x5 0x0 #define MX6SX_PAD_NAND_DATA06__WEIM_AD_6 0x0168 0x04B0 0x0000 0x6 0x0 @@ -846,8 +862,8 @@ #define MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07 0x016C 0x04B4 0x0000 0x0 0x0 #define MX6SX_PAD_NAND_DATA07__USDHC2_DATA7 0x016C 0x04B4 0x0000 0x1 0x0 #define MX6SX_PAD_NAND_DATA07__QSPI2_A_DQS 0x016C 0x04B4 0x0000 0x2 0x0 -#define MX6SX_PAD_NAND_DATA07__UART3_RX 0x016C 0x04B4 0x0840 0x3 0x1 -#define MX6SX_PAD_NAND_DATA07__UART3_TX 0x016C 0x04B4 0x0000 0x3 0x0 +#define MX6SX_PAD_NAND_DATA07__UART3_DCE_TX 0x016C 0x04B4 0x0000 0x3 0x0 +#define MX6SX_PAD_NAND_DATA07__UART3_DTE_RX 0x016C 0x04B4 0x0840 0x3 0x1 #define MX6SX_PAD_NAND_DATA07__PWM4_OUT 0x016C 0x04B4 0x0000 0x4 0x0 #define MX6SX_PAD_NAND_DATA07__GPIO4_IO_11 0x016C 0x04B4 0x0000 0x5 0x0 #define MX6SX_PAD_NAND_DATA07__WEIM_AD_7 0x016C 0x04B4 0x0000 0x6 0x0 @@ -967,7 +983,8 @@ #define MX6SX_PAD_QSPI1A_SS1_B__SIM_M_HADDR_12 0x019C 0x04E4 0x0000 0x7 0x0 #define MX6SX_PAD_QSPI1A_SS1_B__SDMA_DEBUG_PC_3 0x019C 0x04E4 0x0000 0x9 0x0 #define MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 0x01A0 0x04E8 0x0000 0x0 0x0 -#define MX6SX_PAD_QSPI1B_DATA0__UART3_CTS_B 0x01A0 0x04E8 0x0000 0x1 0x0 +#define MX6SX_PAD_QSPI1B_DATA0__UART3_DCE_CTS 0x01A0 0x04E8 0x0000 0x1 0x0 +#define MX6SX_PAD_QSPI1B_DATA0__UART3_DTE_RTS 0x01A0 0x04E8 0x083C 0x1 0x4 #define MX6SX_PAD_QSPI1B_DATA0__ECSPI3_MOSI 0x01A0 0x04E8 0x0738 0x2 0x1 #define MX6SX_PAD_QSPI1B_DATA0__ESAI_RX_FS 0x01A0 0x04E8 0x0778 0x3 0x2 #define MX6SX_PAD_QSPI1B_DATA0__CSI1_DATA_22 0x01A0 0x04E8 0x06F4 0x4 0x1 @@ -975,7 +992,8 @@ #define MX6SX_PAD_QSPI1B_DATA0__WEIM_DATA_14 0x01A0 0x04E8 0x0000 0x6 0x0 #define MX6SX_PAD_QSPI1B_DATA0__SIM_M_HADDR_9 0x01A0 0x04E8 0x0000 0x7 0x0 #define MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 0x01A4 0x04EC 0x0000 0x0 0x0 -#define MX6SX_PAD_QSPI1B_DATA1__UART3_RTS_B 0x01A4 0x04EC 0x083C 0x1 0x5 +#define MX6SX_PAD_QSPI1B_DATA1__UART3_DCE_RTS 0x01A4 0x04EC 0x083C 0x1 0x5 +#define MX6SX_PAD_QSPI1B_DATA1__UART3_DTE_CTS 0x01A4 0x04EC 0x0000 0x1 0x0 #define MX6SX_PAD_QSPI1B_DATA1__ECSPI3_MISO 0x01A4 0x04EC 0x0734 0x2 0x1 #define MX6SX_PAD_QSPI1B_DATA1__ESAI_RX_CLK 0x01A4 0x04EC 0x0788 0x3 0x2 #define MX6SX_PAD_QSPI1B_DATA1__CSI1_DATA_21 0x01A4 0x04EC 0x06F0 0x4 0x1 @@ -1007,8 +1025,8 @@ #define MX6SX_PAD_QSPI1B_DQS__WEIM_DATA_15 0x01B0 0x04F8 0x0000 0x6 0x0 #define MX6SX_PAD_QSPI1B_DQS__SIM_M_HADDR_15 0x01B0 0x04F8 0x0000 0x7 0x0 #define MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK 0x01B4 0x04FC 0x0000 0x0 0x0 -#define MX6SX_PAD_QSPI1B_SCLK__UART3_RX 0x01B4 0x04FC 0x0840 0x1 0x4 -#define MX6SX_PAD_QSPI1B_SCLK__UART3_TX 0x01B4 0x04FC 0x0000 0x0 0x0 +#define MX6SX_PAD_QSPI1B_SCLK__UART3_DCE_RX 0x01B4 0x04FC 0x0840 0x1 0x4 +#define MX6SX_PAD_QSPI1B_SCLK__UART3_DTE_TX 0x01B4 0x04FC 0x0000 0x0 0x0 #define MX6SX_PAD_QSPI1B_SCLK__ECSPI3_SCLK 0x01B4 0x04FC 0x0730 0x2 0x1 #define MX6SX_PAD_QSPI1B_SCLK__ESAI_RX_HF_CLK 0x01B4 0x04FC 0x0780 0x3 0x2 #define MX6SX_PAD_QSPI1B_SCLK__CSI1_DATA_16 0x01B4 0x04FC 0x06DC 0x4 0x1 @@ -1016,8 +1034,8 @@ #define MX6SX_PAD_QSPI1B_SCLK__WEIM_DATA_8 0x01B4 0x04FC 0x0000 0x6 0x0 #define MX6SX_PAD_QSPI1B_SCLK__SIM_M_HADDR_11 0x01B4 0x04FC 0x0000 0x7 0x0 #define MX6SX_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B 0x01B8 0x0500 0x0000 0x0 0x0 -#define MX6SX_PAD_QSPI1B_SS0_B__UART3_RX 0x01B8 0x0500 0x0840 0x1 0x5 -#define MX6SX_PAD_QSPI1B_SS0_B__UART3_TX 0x01B8 0x0500 0x0000 0x1 0x0 +#define MX6SX_PAD_QSPI1B_SS0_B__UART3_DCE_TX 0x01B8 0x0500 0x0000 0x1 0x0 +#define MX6SX_PAD_QSPI1B_SS0_B__UART3_DTE_RX 0x01B8 0x0500 0x0840 0x1 0x5 #define MX6SX_PAD_QSPI1B_SS0_B__ECSPI3_SS0 0x01B8 0x0500 0x073C 0x2 0x1 #define MX6SX_PAD_QSPI1B_SS0_B__ESAI_TX_HF_CLK 0x01B8 0x0500 0x0784 0x3 0x3 #define MX6SX_PAD_QSPI1B_SS0_B__CSI1_DATA_17 0x01B8 0x0500 0x06E0 0x4 0x1 @@ -1224,8 +1242,8 @@ #define MX6SX_PAD_SD1_DATA0__AUDMUX_AUD5_RXD 0x0228 0x0570 0x065C 0x1 0x1 #define MX6SX_PAD_SD1_DATA0__CAAM_WRAPPER_RNG_OSC_OBS 0x0228 0x0570 0x0000 0x2 0x0 #define MX6SX_PAD_SD1_DATA0__GPT_CAPTURE1 0x0228 0x0570 0x0000 0x3 0x0 -#define MX6SX_PAD_SD1_DATA0__UART2_RX 0x0228 0x0570 0x0838 0x4 0x2 -#define MX6SX_PAD_SD1_DATA0__UART2_TX 0x0228 0x0570 0x0000 0x4 0x0 +#define MX6SX_PAD_SD1_DATA0__UART2_DCE_RX 0x0228 0x0570 0x0838 0x4 0x2 +#define MX6SX_PAD_SD1_DATA0__UART2_DTE_TX 0x0228 0x0570 0x0000 0x4 0x0 #define MX6SX_PAD_SD1_DATA0__GPIO6_IO_2 0x0228 0x0570 0x0000 0x5 0x0 #define MX6SX_PAD_SD1_DATA0__ENET1_1588_EVENT1_IN 0x0228 0x0570 0x0000 0x6 0x0 #define MX6SX_PAD_SD1_DATA0__CCM_OUT2 0x0228 0x0570 0x0000 0x7 0x0 @@ -1235,8 +1253,8 @@ #define MX6SX_PAD_SD1_DATA1__AUDMUX_AUD5_TXC 0x022C 0x0574 0x066C 0x1 0x1 #define MX6SX_PAD_SD1_DATA1__PWM4_OUT 0x022C 0x0574 0x0000 0x2 0x0 #define MX6SX_PAD_SD1_DATA1__GPT_CAPTURE2 0x022C 0x0574 0x0000 0x3 0x0 -#define MX6SX_PAD_SD1_DATA1__UART2_RX 0x022C 0x0574 0x0838 0x4 0x3 -#define MX6SX_PAD_SD1_DATA1__UART2_TX 0x022C 0x0574 0x0000 0x4 0x0 +#define MX6SX_PAD_SD1_DATA1__UART2_DCE_TX 0x022C 0x0574 0x0000 0x4 0x0 +#define MX6SX_PAD_SD1_DATA1__UART2_DTE_RX 0x022C 0x0574 0x0838 0x4 0x3 #define MX6SX_PAD_SD1_DATA1__GPIO6_IO_3 0x022C 0x0574 0x0000 0x5 0x0 #define MX6SX_PAD_SD1_DATA1__ENET1_1588_EVENT1_OUT 0x022C 0x0574 0x0000 0x6 0x0 #define MX6SX_PAD_SD1_DATA1__CCM_CLKO2 0x022C 0x0574 0x0000 0x7 0x0 @@ -1246,7 +1264,8 @@ #define MX6SX_PAD_SD1_DATA2__AUDMUX_AUD5_TXFS 0x0230 0x0578 0x0670 0x1 0x1 #define MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x0230 0x0578 0x0000 0x2 0x0 #define MX6SX_PAD_SD1_DATA2__GPT_COMPARE2 0x0230 0x0578 0x0000 0x3 0x0 -#define MX6SX_PAD_SD1_DATA2__UART2_CTS_B 0x0230 0x0578 0x0000 0x4 0x0 +#define MX6SX_PAD_SD1_DATA2__UART2_DCE_CTS 0x0230 0x0578 0x0000 0x4 0x0 +#define MX6SX_PAD_SD1_DATA2__UART2_DTE_RTS 0x0230 0x0578 0x0834 0x4 0x2 #define MX6SX_PAD_SD1_DATA2__GPIO6_IO_4 0x0230 0x0578 0x0000 0x5 0x0 #define MX6SX_PAD_SD1_DATA2__ECSPI4_RDY 0x0230 0x0578 0x0000 0x6 0x0 #define MX6SX_PAD_SD1_DATA2__CCM_OUT0 0x0230 0x0578 0x0000 0x7 0x0 @@ -1255,7 +1274,8 @@ #define MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_TXD 0x0234 0x057C 0x0660 0x1 0x1 #define MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD 0x0234 0x057C 0x065C 0x2 0x2 #define MX6SX_PAD_SD1_DATA3__GPT_COMPARE3 0x0234 0x057C 0x0000 0x3 0x0 -#define MX6SX_PAD_SD1_DATA3__UART2_RTS_B 0x0234 0x057C 0x0834 0x4 0x3 +#define MX6SX_PAD_SD1_DATA3__UART2_DCE_RTS 0x0234 0x057C 0x0834 0x4 0x3 +#define MX6SX_PAD_SD1_DATA3__UART2_DTE_CTS 0x0234 0x057C 0x0000 0x4 0x0 #define MX6SX_PAD_SD1_DATA3__GPIO6_IO_5 0x0234 0x057C 0x0000 0x5 0x0 #define MX6SX_PAD_SD1_DATA3__ECSPI4_SS1 0x0234 0x057C 0x0000 0x6 0x0 #define MX6SX_PAD_SD1_DATA3__CCM_PMIC_RDY 0x0234 0x057C 0x069C 0x7 0x2 @@ -1287,8 +1307,8 @@ #define MX6SX_PAD_SD2_DATA0__I2C4_SDA 0x0240 0x0588 0x07C4 0x4 0x3 #define MX6SX_PAD_SD2_DATA0__GPIO6_IO_8 0x0240 0x0588 0x0000 0x5 0x0 #define MX6SX_PAD_SD2_DATA0__ECSPI4_SS3 0x0240 0x0588 0x0000 0x6 0x0 -#define MX6SX_PAD_SD2_DATA0__UART4_RX 0x0240 0x0588 0x0848 0x7 0x4 -#define MX6SX_PAD_SD2_DATA0__UART4_TX 0x0240 0x0588 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA0__UART4_DCE_RX 0x0240 0x0588 0x0848 0x7 0x4 +#define MX6SX_PAD_SD2_DATA0__UART4_DTE_TX 0x0240 0x0588 0x0000 0x7 0x0 #define MX6SX_PAD_SD2_DATA0__VADC_CLAMP_CURRENT_0 0x0240 0x0588 0x0000 0x8 0x0 #define MX6SX_PAD_SD2_DATA0__MMDC_DEBUG_50 0x0240 0x0588 0x0000 0x9 0x0 #define MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x0244 0x058C 0x0000 0x0 0x0 @@ -1298,8 +1318,8 @@ #define MX6SX_PAD_SD2_DATA1__I2C4_SCL 0x0244 0x058C 0x07C0 0x4 0x3 #define MX6SX_PAD_SD2_DATA1__GPIO6_IO_9 0x0244 0x058C 0x0000 0x5 0x0 #define MX6SX_PAD_SD2_DATA1__ECSPI4_SS2 0x0244 0x058C 0x0000 0x6 0x0 -#define MX6SX_PAD_SD2_DATA1__UART4_RX 0x0244 0x058C 0x0848 0x7 0x5 -#define MX6SX_PAD_SD2_DATA1__UART4_TX 0x0244 0x058C 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA1__UART4_DCE_TX 0x0244 0x058C 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA1__UART4_DTE_RX 0x0244 0x058C 0x0848 0x7 0x5 #define MX6SX_PAD_SD2_DATA1__VADC_CLAMP_CURRENT_1 0x0244 0x058C 0x0000 0x8 0x0 #define MX6SX_PAD_SD2_DATA1__MMDC_DEBUG_49 0x0244 0x058C 0x0000 0x9 0x0 #define MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x0248 0x0590 0x0000 0x0 0x0 @@ -1309,8 +1329,8 @@ #define MX6SX_PAD_SD2_DATA2__SDMA_EXT_EVENT_0 0x0248 0x0590 0x081C 0x4 0x2 #define MX6SX_PAD_SD2_DATA2__GPIO6_IO_10 0x0248 0x0590 0x0000 0x5 0x0 #define MX6SX_PAD_SD2_DATA2__SPDIF_OUT 0x0248 0x0590 0x0000 0x6 0x0 -#define MX6SX_PAD_SD2_DATA2__UART6_RX 0x0248 0x0590 0x0858 0x7 0x4 -#define MX6SX_PAD_SD2_DATA2__UART6_TX 0x0248 0x0590 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA2__UART6_DCE_RX 0x0248 0x0590 0x0858 0x7 0x4 +#define MX6SX_PAD_SD2_DATA2__UART6_DTE_TX 0x0248 0x0590 0x0000 0x7 0x0 #define MX6SX_PAD_SD2_DATA2__VADC_CLAMP_CURRENT_2 0x0248 0x0590 0x0000 0x8 0x0 #define MX6SX_PAD_SD2_DATA2__MMDC_DEBUG_32 0x0248 0x0590 0x0000 0x9 0x0 #define MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x024C 0x0594 0x0000 0x0 0x0 @@ -1320,12 +1340,13 @@ #define MX6SX_PAD_SD2_DATA3__MLB_DATA 0x024C 0x0594 0x07EC 0x4 0x2 #define MX6SX_PAD_SD2_DATA3__GPIO6_IO_11 0x024C 0x0594 0x0000 0x5 0x0 #define MX6SX_PAD_SD2_DATA3__SPDIF_IN 0x024C 0x0594 0x0824 0x6 0x4 -#define MX6SX_PAD_SD2_DATA3__UART6_RX 0x024C 0x0594 0x0858 0x7 0x5 -#define MX6SX_PAD_SD2_DATA3__UART6_TX 0x024C 0x0594 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA3__UART6_DCE_TX 0x024C 0x0594 0x0000 0x7 0x0 +#define MX6SX_PAD_SD2_DATA3__UART6_DTE_RX 0x024C 0x0594 0x0858 0x7 0x5 #define MX6SX_PAD_SD2_DATA3__VADC_CLAMP_CURRENT_3 0x024C 0x0594 0x0000 0x8 0x0 #define MX6SX_PAD_SD2_DATA3__MMDC_DEBUG_31 0x024C 0x0594 0x0000 0x9 0x0 #define MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x0250 0x0598 0x0000 0x0 0x0 -#define MX6SX_PAD_SD3_CLK__UART4_CTS_B 0x0250 0x0598 0x0000 0x1 0x0 +#define MX6SX_PAD_SD3_CLK__UART4_DCE_CTS 0x0250 0x0598 0x0000 0x1 0x0 +#define MX6SX_PAD_SD3_CLK__UART4_DTE_RTS 0x0250 0x0598 0x0844 0x1 0x0 #define MX6SX_PAD_SD3_CLK__ECSPI4_SCLK 0x0250 0x0598 0x0740 0x2 0x0 #define MX6SX_PAD_SD3_CLK__AUDMUX_AUD6_RXFS 0x0250 0x0598 0x0680 0x3 0x0 #define MX6SX_PAD_SD3_CLK__LCDIF2_VSYNC 0x0250 0x0598 0x0000 0x4 0x0 @@ -1334,8 +1355,8 @@ #define MX6SX_PAD_SD3_CLK__TPSMP_HDATA_29 0x0250 0x0598 0x0000 0x7 0x0 #define MX6SX_PAD_SD3_CLK__SDMA_DEBUG_EVENT_CHANNEL_5 0x0250 0x0598 0x0000 0x9 0x0 #define MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x0254 0x059C 0x0000 0x0 0x0 -#define MX6SX_PAD_SD3_CMD__UART4_RX 0x0254 0x059C 0x0848 0x1 0x0 -#define MX6SX_PAD_SD3_CMD__UART4_TX 0x0254 0x059C 0x0000 0x1 0x0 +#define MX6SX_PAD_SD3_CMD__UART4_DCE_TX 0x0254 0x059C 0x0000 0x1 0x0 +#define MX6SX_PAD_SD3_CMD__UART4_DTE_RX 0x0254 0x059C 0x0848 0x1 0x0 #define MX6SX_PAD_SD3_CMD__ECSPI4_MOSI 0x0254 0x059C 0x0748 0x2 0x0 #define MX6SX_PAD_SD3_CMD__AUDMUX_AUD6_RXC 0x0254 0x059C 0x067C 0x3 0x0 #define MX6SX_PAD_SD3_CMD__LCDIF2_HSYNC 0x0254 0x059C 0x07E4 0x4 0x1 @@ -1364,7 +1385,8 @@ #define MX6SX_PAD_SD3_DATA1__GPU_DEBUG_1 0x025C 0x05A4 0x0000 0x8 0x0 #define MX6SX_PAD_SD3_DATA1__SDMA_DEBUG_EVT_CHN_LINES_1 0x025C 0x05A4 0x0000 0x9 0x0 #define MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x0260 0x05A8 0x0000 0x0 0x0 -#define MX6SX_PAD_SD3_DATA2__UART4_RTS_B 0x0260 0x05A8 0x0844 0x1 0x1 +#define MX6SX_PAD_SD3_DATA2__UART4_DCE_RTS 0x0260 0x05A8 0x0844 0x1 0x1 +#define MX6SX_PAD_SD3_DATA2__UART4_DTE_CTS 0x0260 0x05A8 0x0000 0x1 0x0 #define MX6SX_PAD_SD3_DATA2__ECSPI4_SS0 0x0260 0x05A8 0x074C 0x2 0x0 #define MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS 0x0260 0x05A8 0x0688 0x3 0x0 #define MX6SX_PAD_SD3_DATA2__LCDIF2_CLK 0x0260 0x05A8 0x0000 0x4 0x0 @@ -1374,8 +1396,8 @@ #define MX6SX_PAD_SD3_DATA2__GPU_DEBUG_2 0x0260 0x05A8 0x0000 0x8 0x0 #define MX6SX_PAD_SD3_DATA2__SDMA_DEBUG_EVENT_CHANNEL_2 0x0260 0x05A8 0x0000 0x9 0x0 #define MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x0264 0x05AC 0x0000 0x0 0x0 -#define MX6SX_PAD_SD3_DATA3__UART4_RX 0x0264 0x05AC 0x0848 0x1 0x1 -#define MX6SX_PAD_SD3_DATA3__UART4_TX 0x0264 0x05AC 0x0000 0x1 0x0 +#define MX6SX_PAD_SD3_DATA3__UART4_DCE_RX 0x0264 0x05AC 0x0848 0x1 0x1 +#define MX6SX_PAD_SD3_DATA3__UART4_DTE_TX 0x0264 0x05AC 0x0000 0x1 0x0 #define MX6SX_PAD_SD3_DATA3__ECSPI4_MISO 0x0264 0x05AC 0x0744 0x2 0x0 #define MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD 0x0264 0x05AC 0x0678 0x3 0x0 #define MX6SX_PAD_SD3_DATA3__LCDIF2_ENABLE 0x0264 0x05AC 0x0000 0x4 0x0 @@ -1387,8 +1409,8 @@ #define MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x0268 0x05B0 0x0000 0x0 0x0 #define MX6SX_PAD_SD3_DATA4__CAN2_RX 0x0268 0x05B0 0x0690 0x1 0x0 #define MX6SX_PAD_SD3_DATA4__CANFD_RX2 0x0268 0x05B0 0x0698 0x2 0x0 -#define MX6SX_PAD_SD3_DATA4__UART3_RX 0x0268 0x05B0 0x0840 0x3 0x2 -#define MX6SX_PAD_SD3_DATA4__UART3_TX 0x0268 0x05B0 0x0000 0x3 0x0 +#define MX6SX_PAD_SD3_DATA4__UART3_DCE_RX 0x0268 0x05B0 0x0840 0x3 0x2 +#define MX6SX_PAD_SD3_DATA4__UART3_DTE_TX 0x0268 0x05B0 0x0000 0x3 0x0 #define MX6SX_PAD_SD3_DATA4__LCDIF2_DATA_3 0x0268 0x05B0 0x0000 0x4 0x0 #define MX6SX_PAD_SD3_DATA4__GPIO7_IO_6 0x0268 0x05B0 0x0000 0x5 0x0 #define MX6SX_PAD_SD3_DATA4__ENET2_1588_EVENT0_IN 0x0268 0x05B0 0x0000 0x6 0x0 @@ -1398,8 +1420,8 @@ #define MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x026C 0x05B4 0x0000 0x0 0x0 #define MX6SX_PAD_SD3_DATA5__CAN1_TX 0x026C 0x05B4 0x0000 0x1 0x0 #define MX6SX_PAD_SD3_DATA5__CANFD_TX1 0x026C 0x05B4 0x0000 0x2 0x0 -#define MX6SX_PAD_SD3_DATA5__UART3_RX 0x026C 0x05B4 0x0840 0x3 0x3 -#define MX6SX_PAD_SD3_DATA5__UART3_TX 0x026C 0x05B4 0x0000 0x3 0x0 +#define MX6SX_PAD_SD3_DATA5__UART3_DCE_TX 0x026C 0x05B4 0x0000 0x3 0x0 +#define MX6SX_PAD_SD3_DATA5__UART3_DTE_RX 0x026C 0x05B4 0x0840 0x3 0x3 #define MX6SX_PAD_SD3_DATA5__LCDIF2_DATA_2 0x026C 0x05B4 0x0000 0x4 0x0 #define MX6SX_PAD_SD3_DATA5__GPIO7_IO_7 0x026C 0x05B4 0x0000 0x5 0x0 #define MX6SX_PAD_SD3_DATA5__ENET2_1588_EVENT0_OUT 0x026C 0x05B4 0x0000 0x6 0x0 @@ -1409,7 +1431,8 @@ #define MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x0270 0x05B8 0x0000 0x0 0x0 #define MX6SX_PAD_SD3_DATA6__CAN2_TX 0x0270 0x05B8 0x0000 0x1 0x0 #define MX6SX_PAD_SD3_DATA6__CANFD_TX2 0x0270 0x05B8 0x0000 0x2 0x0 -#define MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x0270 0x05B8 0x083C 0x3 0x2 +#define MX6SX_PAD_SD3_DATA6__UART3_DCE_RTS 0x0270 0x05B8 0x083C 0x3 0x2 +#define MX6SX_PAD_SD3_DATA6__UART3_DTE_CTS 0x0270 0x05B8 0x0000 0x3 0x0 #define MX6SX_PAD_SD3_DATA6__LCDIF2_DATA_4 0x0270 0x05B8 0x0000 0x4 0x0 #define MX6SX_PAD_SD3_DATA6__GPIO7_IO_8 0x0270 0x05B8 0x0000 0x5 0x0 #define MX6SX_PAD_SD3_DATA6__ENET1_1588_EVENT0_OUT 0x0270 0x05B8 0x0000 0x6 0x0 @@ -1419,7 +1442,8 @@ #define MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x0274 0x05BC 0x0000 0x0 0x0 #define MX6SX_PAD_SD3_DATA7__CAN1_RX 0x0274 0x05BC 0x068C 0x1 0x0 #define MX6SX_PAD_SD3_DATA7__CANFD_RX1 0x0274 0x05BC 0x0694 0x2 0x0 -#define MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x0274 0x05BC 0x0000 0x3 0x0 +#define MX6SX_PAD_SD3_DATA7__UART3_DCE_CTS 0x0274 0x05BC 0x0000 0x3 0x0 +#define MX6SX_PAD_SD3_DATA7__UART3_DTE_RTS 0x0274 0x05BC 0x083C 0x3 0x3 #define MX6SX_PAD_SD3_DATA7__LCDIF2_DATA_5 0x0274 0x05BC 0x0000 0x4 0x0 #define MX6SX_PAD_SD3_DATA7__GPIO7_IO_9 0x0274 0x05BC 0x0000 0x5 0x0 #define MX6SX_PAD_SD3_DATA7__ENET1_1588_EVENT0_IN 0x0274 0x05BC 0x0000 0x6 0x0 @@ -1488,8 +1512,8 @@ #define MX6SX_PAD_SD4_DATA3__SDMA_DEBUG_MATCHED_DMBUS 0x028C 0x05D4 0x0000 0x9 0x0 #define MX6SX_PAD_SD4_DATA4__USDHC4_DATA4 0x0290 0x05D8 0x0000 0x0 0x0 #define MX6SX_PAD_SD4_DATA4__RAWNAND_DATA09 0x0290 0x05D8 0x0000 0x1 0x0 -#define MX6SX_PAD_SD4_DATA4__UART5_RX 0x0290 0x05D8 0x0850 0x2 0x0 -#define MX6SX_PAD_SD4_DATA4__UART5_TX 0x0290 0x05D8 0x0000 0x2 0x0 +#define MX6SX_PAD_SD4_DATA4__UART5_DCE_RX 0x0290 0x05D8 0x0850 0x2 0x0 +#define MX6SX_PAD_SD4_DATA4__UART5_DTE_TX 0x0290 0x05D8 0x0000 0x2 0x0 #define MX6SX_PAD_SD4_DATA4__ECSPI3_SCLK 0x0290 0x05D8 0x0730 0x3 0x0 #define MX6SX_PAD_SD4_DATA4__LCDIF2_DATA_8 0x0290 0x05D8 0x0000 0x4 0x0 #define MX6SX_PAD_SD4_DATA4__GPIO6_IO_18 0x0290 0x05D8 0x0000 0x5 0x0 @@ -1499,8 +1523,8 @@ #define MX6SX_PAD_SD4_DATA4__SDMA_DEBUG_RTBUFFER_WRITE 0x0290 0x05D8 0x0000 0x9 0x0 #define MX6SX_PAD_SD4_DATA5__USDHC4_DATA5 0x0294 0x05DC 0x0000 0x0 0x0 #define MX6SX_PAD_SD4_DATA5__RAWNAND_CE2_B 0x0294 0x05DC 0x0000 0x1 0x0 -#define MX6SX_PAD_SD4_DATA5__UART5_RX 0x0294 0x05DC 0x0850 0x2 0x1 -#define MX6SX_PAD_SD4_DATA5__UART5_TX 0x0294 0x05DC 0x0000 0x2 0x0 +#define MX6SX_PAD_SD4_DATA5__UART5_DCE_TX 0x0294 0x05DC 0x0000 0x2 0x0 +#define MX6SX_PAD_SD4_DATA5__UART5_DTE_RX 0x0294 0x05DC 0x0850 0x2 0x1 #define MX6SX_PAD_SD4_DATA5__ECSPI3_MOSI 0x0294 0x05DC 0x0738 0x3 0x0 #define MX6SX_PAD_SD4_DATA5__LCDIF2_DATA_7 0x0294 0x05DC 0x0000 0x4 0x0 #define MX6SX_PAD_SD4_DATA5__GPIO6_IO_19 0x0294 0x05DC 0x0000 0x5 0x0 @@ -1510,7 +1534,8 @@ #define MX6SX_PAD_SD4_DATA5__SDMA_DEBUG_EVENT_CHANNEL_0 0x0294 0x05DC 0x0000 0x9 0x0 #define MX6SX_PAD_SD4_DATA6__USDHC4_DATA6 0x0298 0x05E0 0x0000 0x0 0x0 #define MX6SX_PAD_SD4_DATA6__RAWNAND_CE3_B 0x0298 0x05E0 0x0000 0x1 0x0 -#define MX6SX_PAD_SD4_DATA6__UART5_RTS_B 0x0298 0x05E0 0x084C 0x2 0x0 +#define MX6SX_PAD_SD4_DATA6__UART5_DCE_RTS 0x0298 0x05E0 0x084C 0x2 0x0 +#define MX6SX_PAD_SD4_DATA6__UART5_DTE_CTS 0x0298 0x05E0 0x0000 0x2 0x0 #define MX6SX_PAD_SD4_DATA6__ECSPI3_MISO 0x0298 0x05E0 0x0734 0x3 0x0 #define MX6SX_PAD_SD4_DATA6__LCDIF2_DATA_6 0x0298 0x05E0 0x0000 0x4 0x0 #define MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x0298 0x05E0 0x0000 0x5 0x0 @@ -1520,7 +1545,8 @@ #define MX6SX_PAD_SD4_DATA6__SDMA_DEBUG_EVENT_CHANNEL_1 0x0298 0x05E0 0x0000 0x9 0x0 #define MX6SX_PAD_SD4_DATA7__USDHC4_DATA7 0x029C 0x05E4 0x0000 0x0 0x0 #define MX6SX_PAD_SD4_DATA7__RAWNAND_DATA08 0x029C 0x05E4 0x0000 0x1 0x0 -#define MX6SX_PAD_SD4_DATA7__UART5_CTS_B 0x029C 0x05E4 0x0000 0x2 0x0 +#define MX6SX_PAD_SD4_DATA7__UART5_DCE_CTS 0x029C 0x05E4 0x0000 0x2 0x0 +#define MX6SX_PAD_SD4_DATA7__UART5_DTE_RTS 0x029C 0x05E4 0x084C 0x2 0x1 #define MX6SX_PAD_SD4_DATA7__ECSPI3_SS0 0x029C 0x05E4 0x073C 0x3 0x0 #define MX6SX_PAD_SD4_DATA7__LCDIF2_DATA_15 0x029C 0x05E4 0x0000 0x4 0x0 #define MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x029C 0x05E4 0x0000 0x5 0x0 @@ -1551,4 +1577,92 @@ #define MX6SX_PAD_USB_H_STROBE__WDOG3_WDOG_RST_B_DEB 0x02A8 0x05F0 0x0000 0x4 0x0 #define MX6SX_PAD_USB_H_STROBE__GPIO7_IO_11 0x02A8 0x05F0 0x0000 0x5 0x0 +/* these are not supposed to be used any more and remove them after some time */ +#define MX6SX_PAD_GPIO1_IO04__UART1_RX MX6SX_PAD_GPIO1_IO04__UART1_DTE_RX +#define MX6SX_PAD_GPIO1_IO04__UART1_TX MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX +#define MX6SX_PAD_GPIO1_IO05__UART1_RX MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX +#define MX6SX_PAD_GPIO1_IO05__UART1_TX MX6SX_PAD_GPIO1_IO05__UART1_DTE_TX +#define MX6SX_PAD_GPIO1_IO06__UART2_RX MX6SX_PAD_GPIO1_IO06__UART2_DTE_RX +#define MX6SX_PAD_GPIO1_IO06__UART2_TX MX6SX_PAD_GPIO1_IO06__UART2_DCE_TX +#define MX6SX_PAD_GPIO1_IO06__UART1_RTS_B MX6SX_PAD_GPIO1_IO06__UART1_DCE_RTS +#define MX6SX_PAD_GPIO1_IO07__UART2_RX MX6SX_PAD_GPIO1_IO07__UART2_DCE_RX +#define MX6SX_PAD_GPIO1_IO07__UART2_TX MX6SX_PAD_GPIO1_IO07__UART2_DTE_TX +#define MX6SX_PAD_GPIO1_IO07__UART1_CTS_B MX6SX_PAD_GPIO1_IO07__UART1_DCE_CTS +#define MX6SX_PAD_GPIO1_IO08__UART2_RTS_B MX6SX_PAD_GPIO1_IO08__UART2_DCE_RTS +#define MX6SX_PAD_GPIO1_IO09__UART2_CTS_B MX6SX_PAD_GPIO1_IO09__UART2_DCE_CTS +#define MX6SX_PAD_CSI_DATA04__UART6_RX MX6SX_PAD_CSI_DATA04__UART6_DCE_RX +#define MX6SX_PAD_CSI_DATA04__UART6_TX MX6SX_PAD_CSI_DATA04__UART6_DTE_TX +#define MX6SX_PAD_CSI_DATA05__UART6_RX MX6SX_PAD_CSI_DATA05__UART6_DTE_RX +#define MX6SX_PAD_CSI_DATA05__UART6_TX MX6SX_PAD_CSI_DATA05__UART6_DCE_TX +#define MX6SX_PAD_CSI_DATA06__UART6_RTS_B MX6SX_PAD_CSI_DATA06__UART6_DCE_RTS +#define MX6SX_PAD_CSI_DATA07__UART6_CTS_B MX6SX_PAD_CSI_DATA07__UART6_DCE_CTS +#define MX6SX_PAD_CSI_HSYNC__UART4_RTS_B MX6SX_PAD_CSI_HSYNC__UART4_DCE_RTS +#define MX6SX_PAD_CSI_MCLK__UART4_RX MX6SX_PAD_CSI_MCLK__UART4_DCE_RX +#define MX6SX_PAD_CSI_MCLK__UART4_TX MX6SX_PAD_CSI_MCLK__UART4_DTE_TX +#define MX6SX_PAD_CSI_PIXCLK__UART4_RX MX6SX_PAD_CSI_PIXCLK__UART4_DTE_RX +#define MX6SX_PAD_CSI_PIXCLK__UART4_TX MX6SX_PAD_CSI_PIXCLK__UART4_DCE_TX +#define MX6SX_PAD_CSI_VSYNC__UART4_CTS_B MX6SX_PAD_CSI_VSYNC__UART4_DCE_CTS +#define MX6SX_PAD_ENET2_COL__UART1_RX MX6SX_PAD_ENET2_COL__UART1_DCE_RX +#define MX6SX_PAD_ENET2_COL__UART1_TX MX6SX_PAD_ENET2_COL__UART1_DTE_TX +#define MX6SX_PAD_ENET2_CRS__UART1_RX MX6SX_PAD_ENET2_CRS__UART1_DTE_RX +#define MX6SX_PAD_ENET2_CRS__UART1_TX MX6SX_PAD_ENET2_CRS__UART1_DCE_TX +#define MX6SX_PAD_ENET2_RX_CLK__UART1_RTS_B MX6SX_PAD_ENET2_RX_CLK__UART1_DCE_RTS +#define MX6SX_PAD_ENET2_TX_CLK__UART1_CTS_B MX6SX_PAD_ENET2_TX_CLK__UART1_DCE_CTS +#define MX6SX_PAD_KEY_COL0__UART6_RTS_B MX6SX_PAD_KEY_COL0__UART6_DCE_RTS +#define MX6SX_PAD_KEY_COL1__UART6_RX MX6SX_PAD_KEY_COL1__UART6_DTE_RX +#define MX6SX_PAD_KEY_COL1__UART6_TX MX6SX_PAD_KEY_COL1__UART6_DCE_TX +#define MX6SX_PAD_KEY_COL2__UART5_RTS_B MX6SX_PAD_KEY_COL2__UART5_DCE_RTS +#define MX6SX_PAD_KEY_COL3__UART5_RX MX6SX_PAD_KEY_COL3__UART5_DTE_RX +#define MX6SX_PAD_KEY_COL3__UART5_TX MX6SX_PAD_KEY_COL3__UART5_DCE_TX +#define MX6SX_PAD_KEY_ROW0__UART6_CTS_B MX6SX_PAD_KEY_ROW0__UART6_DCE_CTS +#define MX6SX_PAD_KEY_ROW1__UART6_RX MX6SX_PAD_KEY_ROW1__UART6_DCE_RX +#define MX6SX_PAD_KEY_ROW1__UART6_TX MX6SX_PAD_KEY_ROW1__UART6_DTE_TX +#define MX6SX_PAD_KEY_ROW2__UART5_CTS_B MX6SX_PAD_KEY_ROW2__UART5_DCE_CTS +#define MX6SX_PAD_KEY_ROW3__UART5_RX MX6SX_PAD_KEY_ROW3__UART5_DCE_RX +#define MX6SX_PAD_KEY_ROW3__UART5_TX MX6SX_PAD_KEY_ROW3__UART5_DTE_TX +#define MX6SX_PAD_NAND_DATA04__UART3_RTS_B MX6SX_PAD_NAND_DATA04__UART3_DCE_RTS +#define MX6SX_PAD_NAND_DATA05__UART3_CTS_B MX6SX_PAD_NAND_DATA05__UART3_DCE_CTS +#define MX6SX_PAD_NAND_DATA06__UART3_RX MX6SX_PAD_NAND_DATA06__UART3_DCE_RX +#define MX6SX_PAD_NAND_DATA06__UART3_TX MX6SX_PAD_NAND_DATA06__UART3_DTE_TX +#define MX6SX_PAD_NAND_DATA07__UART3_RX MX6SX_PAD_NAND_DATA07__UART3_DTE_RX +#define MX6SX_PAD_NAND_DATA07__UART3_TX MX6SX_PAD_NAND_DATA07__UART3_DCE_TX +#define MX6SX_PAD_QSPI1B_DATA0__UART3_CTS_B MX6SX_PAD_QSPI1B_DATA0__UART3_DCE_CTS +#define MX6SX_PAD_QSPI1B_DATA1__UART3_RTS_B MX6SX_PAD_QSPI1B_DATA1__UART3_DCE_RTS +#define MX6SX_PAD_QSPI1B_SCLK__UART3_RX MX6SX_PAD_QSPI1B_SCLK__UART3_DCE_RX +#define MX6SX_PAD_QSPI1B_SCLK__UART3_TX MX6SX_PAD_QSPI1B_SCLK__UART3_DTE_TX +#define MX6SX_PAD_QSPI1B_SS0_B__UART3_RX MX6SX_PAD_QSPI1B_SS0_B__UART3_DTE_RX +#define MX6SX_PAD_QSPI1B_SS0_B__UART3_TX MX6SX_PAD_QSPI1B_SS0_B__UART3_DCE_TX +#define MX6SX_PAD_SD1_DATA0__UART2_RX MX6SX_PAD_SD1_DATA0__UART2_DCE_RX +#define MX6SX_PAD_SD1_DATA0__UART2_TX MX6SX_PAD_SD1_DATA0__UART2_DTE_TX +#define MX6SX_PAD_SD1_DATA1__UART2_RX MX6SX_PAD_SD1_DATA1__UART2_DTE_RX +#define MX6SX_PAD_SD1_DATA1__UART2_TX MX6SX_PAD_SD1_DATA1__UART2_DCE_TX +#define MX6SX_PAD_SD1_DATA2__UART2_CTS_B MX6SX_PAD_SD1_DATA2__UART2_DCE_CTS +#define MX6SX_PAD_SD1_DATA3__UART2_RTS_B MX6SX_PAD_SD1_DATA3__UART2_DCE_RTS +#define MX6SX_PAD_SD2_DATA0__UART4_RX MX6SX_PAD_SD2_DATA0__UART4_DCE_RX +#define MX6SX_PAD_SD2_DATA0__UART4_TX MX6SX_PAD_SD2_DATA0__UART4_DTE_TX +#define MX6SX_PAD_SD2_DATA1__UART4_RX MX6SX_PAD_SD2_DATA1__UART4_DTE_RX +#define MX6SX_PAD_SD2_DATA1__UART4_TX MX6SX_PAD_SD2_DATA1__UART4_DCE_TX +#define MX6SX_PAD_SD2_DATA2__UART6_RX MX6SX_PAD_SD2_DATA2__UART6_DCE_RX +#define MX6SX_PAD_SD2_DATA2__UART6_TX MX6SX_PAD_SD2_DATA2__UART6_DTE_TX +#define MX6SX_PAD_SD2_DATA3__UART6_RX MX6SX_PAD_SD2_DATA3__UART6_DTE_RX +#define MX6SX_PAD_SD2_DATA3__UART6_TX MX6SX_PAD_SD2_DATA3__UART6_DCE_TX +#define MX6SX_PAD_SD3_CLK__UART4_CTS_B MX6SX_PAD_SD3_CLK__UART4_DCE_CTS +#define MX6SX_PAD_SD3_CMD__UART4_RX MX6SX_PAD_SD3_CMD__UART4_DTE_RX +#define MX6SX_PAD_SD3_CMD__UART4_TX MX6SX_PAD_SD3_CMD__UART4_DCE_TX +#define MX6SX_PAD_SD3_DATA2__UART4_RTS_B MX6SX_PAD_SD3_DATA2__UART4_DCE_RTS +#define MX6SX_PAD_SD3_DATA3__UART4_RX MX6SX_PAD_SD3_DATA3__UART4_DCE_RX +#define MX6SX_PAD_SD3_DATA3__UART4_TX MX6SX_PAD_SD3_DATA3__UART4_DTE_TX +#define MX6SX_PAD_SD3_DATA4__UART3_RX MX6SX_PAD_SD3_DATA4__UART3_DCE_RX +#define MX6SX_PAD_SD3_DATA4__UART3_TX MX6SX_PAD_SD3_DATA4__UART3_DTE_TX +#define MX6SX_PAD_SD3_DATA5__UART3_RX MX6SX_PAD_SD3_DATA5__UART3_DTE_RX +#define MX6SX_PAD_SD3_DATA5__UART3_TX MX6SX_PAD_SD3_DATA5__UART3_DCE_TX +#define MX6SX_PAD_SD3_DATA6__UART3_RTS_B MX6SX_PAD_SD3_DATA6__UART3_DCE_RTS +#define MX6SX_PAD_SD3_DATA7__UART3_CTS_B MX6SX_PAD_SD3_DATA7__UART3_DCE_CTS +#define MX6SX_PAD_SD4_DATA4__UART5_RX MX6SX_PAD_SD4_DATA4__UART5_DCE_RX +#define MX6SX_PAD_SD4_DATA4__UART5_TX MX6SX_PAD_SD4_DATA4__UART5_DTE_TX +#define MX6SX_PAD_SD4_DATA5__UART5_RX MX6SX_PAD_SD4_DATA5__UART5_DTE_RX +#define MX6SX_PAD_SD4_DATA5__UART5_TX MX6SX_PAD_SD4_DATA5__UART5_DCE_TX +#define MX6SX_PAD_SD4_DATA6__UART5_RTS_B MX6SX_PAD_SD4_DATA6__UART5_DCE_RTS +#define MX6SX_PAD_SD4_DATA7__UART5_CTS_B MX6SX_PAD_SD4_DATA7__UART5_DCE_CTS + #endif /* __DTS_IMX6SX_PINFUNC_H */ diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts index 315044ccd65f..825924448ab4 100644 --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts @@ -229,8 +229,8 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi index f6972deb5e39..3e5fb72f21fc 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dtsi +++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi @@ -564,17 +564,17 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x1b0b1 >; }; pinctrl_uart5: uart5grp { fsl,pins = < - MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1 - MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1 - MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1 - MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1 + MX6SX_PAD_KEY_ROW3__UART5_DCE_RX 0x1b0b1 + MX6SX_PAD_KEY_COL3__UART5_DCE_TX 0x1b0b1 + MX6SX_PAD_KEY_ROW2__UART5_DCE_CTS 0x1b0b1 + MX6SX_PAD_KEY_COL2__UART5_DCE_RTS 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts index 28563f21024e..6b728b03f1f2 100644 --- a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts +++ b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts @@ -352,6 +352,12 @@ >; }; + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6SX_PAD_NAND_DATA02__GPIO4_IO_6 0x10b0 + >; + }; + pinctrl_pwm1: pwm1grp-1 { fsl,pins = < /* blue LED */ @@ -384,15 +390,15 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x1b0b1 >; }; pinctrl_uart2: uart2grp { fsl,pins = < - MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1 - MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1 + MX6SX_PAD_GPIO1_IO06__UART2_DCE_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO07__UART2_DCE_RX 0x1b0b1 >; }; @@ -490,6 +496,14 @@ }; }; +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; + reset-gpio-active-high; + status = "okay"; +}; + &pwm1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm1>; diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi index 25d4aa985a69..ee645655090d 100644 --- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi +++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi @@ -235,28 +235,28 @@ pinctrl_uart1: uart1grp { fsl,pins = - <MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1>, - <MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1>; + <MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1>, + <MX6SX_PAD_GPIO1_IO05__UART1_DCE_RX 0x1b0b1>; }; pinctrl_uart2: uart2grp { fsl,pins = - <MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1>, - <MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1>; + <MX6SX_PAD_GPIO1_IO06__UART2_DCE_TX 0x1b0b1>, + <MX6SX_PAD_GPIO1_IO07__UART2_DCE_RX 0x1b0b1>; }; pinctrl_uart3: uart3grp { fsl,pins = - <MX6SX_PAD_SD3_DATA4__UART3_RX 0x13059>, - <MX6SX_PAD_SD3_DATA5__UART3_TX 0x13059>, - <MX6SX_PAD_SD3_DATA6__UART3_RTS_B 0x13059>, - <MX6SX_PAD_SD3_DATA7__UART3_CTS_B 0x13059>; + <MX6SX_PAD_SD3_DATA4__UART3_DCE_RX 0x13059>, + <MX6SX_PAD_SD3_DATA5__UART3_DCE_TX 0x13059>, + <MX6SX_PAD_SD3_DATA6__UART3_DCE_RTS 0x13059>, + <MX6SX_PAD_SD3_DATA7__UART3_DCE_CTS 0x13059>; }; pinctrl_uart5: uart5grp { fsl,pins = - <MX6SX_PAD_SD4_DATA4__UART5_RX 0x1b0b1>, - <MX6SX_PAD_SD4_DATA5__UART5_TX 0x1b0b1>; + <MX6SX_PAD_SD4_DATA4__UART5_DCE_RX 0x1b0b1>, + <MX6SX_PAD_SD4_DATA5__UART5_DCE_TX 0x1b0b1>; }; pinctrl_uart6: uart6grp { @@ -265,10 +265,10 @@ <MX6SX_PAD_CSI_DATA01__UART6_DSR_B 0x1b0b1>, <MX6SX_PAD_CSI_DATA02__UART6_DTR_B 0x1b0b1>, <MX6SX_PAD_CSI_DATA03__UART6_DCD_B 0x1b0b1>, - <MX6SX_PAD_CSI_DATA04__UART6_RX 0x1b0b1>, - <MX6SX_PAD_CSI_DATA05__UART6_TX 0x1b0b1>, - <MX6SX_PAD_CSI_DATA06__UART6_RTS_B 0x1b0b1>, - <MX6SX_PAD_CSI_DATA07__UART6_CTS_B 0x1b0b1>; + <MX6SX_PAD_CSI_DATA04__UART6_DCE_RX 0x1b0b1>, + <MX6SX_PAD_CSI_DATA05__UART6_DCE_TX 0x1b0b1>, + <MX6SX_PAD_CSI_DATA06__UART6_DCE_RTS 0x1b0b1>, + <MX6SX_PAD_CSI_DATA07__UART6_DCE_CTS 0x1b0b1>; }; pinctrl_otg1_reg: otg1grp { diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 59bad60a47dc..d6f831731460 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -87,6 +87,8 @@ "pll1_sw", "pll1_sys"; arm-supply = <®_arm>; soc-supply = <®_soc>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; }; }; @@ -235,7 +237,7 @@ status = "disabled"; }; - aips1: aips-bus@2000000 { + aips1: bus@2000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -466,7 +468,7 @@ status = "disabled"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6sx-gpt", "fsl,imx6dl-gpt"; reg = <0x02098000 0x4000>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; @@ -559,7 +561,7 @@ gpio-ranges = <&iomuxc 0 148 10>, <&iomuxc 10 169 2>; }; - kpp: kpp@20b8000 { + kpp: keypad@20b8000 { compatible = "fsl,imx6sx-kpp", "fsl,imx21-kpp"; reg = <0x020b8000 0x4000>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; @@ -567,14 +569,14 @@ status = "disabled"; }; - wdog1: wdog@20bc000 { + wdog1: watchdog@20bc000 { compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt"; reg = <0x020bc000 0x4000>; interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6SX_CLK_IPG>; }; - wdog2: wdog@20c0000 { + wdog2: watchdog@20c0000 { compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt"; reg = <0x020c0000 0x4000>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; @@ -582,7 +584,7 @@ status = "disabled"; }; - clks: ccm@20c4000 { + clks: clock-controller@20c4000 { compatible = "fsl,imx6sx-ccm"; reg = <0x020c4000 0x4000>; interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, @@ -806,7 +808,7 @@ }; }; - iomuxc: iomuxc@20e0000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6sx-iomuxc"; reg = <0x020e0000 0x4000>; }; @@ -830,14 +832,14 @@ }; }; - aips2: aips-bus@2100000 { + aips2: bus@2100000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; reg = <0x02100000 0x100000>; ranges; - crypto: caam@2100000 { + crypto: crypto@2100000 { compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; @@ -850,13 +852,13 @@ <&clks IMX6SX_CLK_EIM_SLOW>; clock-names = "mem", "aclk", "ipg", "emi_slow"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; @@ -1051,13 +1053,17 @@ status = "disabled"; }; - ocotp: ocotp@21bc000 { + ocotp: ocotp-ctrl@21bc000 { #address-cells = <1>; #size-cells = <1>; compatible = "fsl,imx6sx-ocotp", "syscon"; reg = <0x021bc000 0x4000>; clocks = <&clks IMX6SX_CLK_OCOTP>; + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; + tempmon_calib: calib@38 { reg = <0x38 4>; }; @@ -1188,7 +1194,7 @@ }; }; - aips3: aips-bus@2200000 { + aips3: bus@2200000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -1289,7 +1295,7 @@ status = "disabled"; }; - wdog3: wdog@2288000 { + wdog3: watchdog@2288000 { compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt"; reg = <0x02288000 0x4000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts index 3749fdda3611..5d3805b07032 100644 --- a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts +++ b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts @@ -25,7 +25,7 @@ }; panel { - compatible = "auo,g101evn010", "simple-panel"; + compatible = "auo,g101evn010"; power-supply = <&ldo4_ext>; backlight = <&lcd_backlight>; diff --git a/arch/arm/boot/dts/imx6ul-pico-dwarf.dts b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts new file mode 100644 index 000000000000..162dc259edc8 --- /dev/null +++ b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// +// Copyright 2015 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> +/dts-v1/; + +#include "imx6ul-pico.dtsi" +/ { + model = "TechNexion PICO-IMX6UL and DWARF baseboard"; + compatible = "technexion,imx6ul-pico-dwarf", "fsl,imx6ul"; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx6ul-sgtl5000"; + audio-cpu = <&sai1>; + audio-codec = <&sgtl5000>; + audio-routing = + "LINE_IN", "Line In Jack", + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + }; + + sys_mclk: clock-sys-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; +}; + +&i2c2 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + sgtl5000: audio-codec@a { + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&sys_mclk>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + + pressure-sensor@60 { + compatible = "fsl,mpl3115"; + reg = <0x60>; + }; +}; diff --git a/arch/arm/boot/dts/imx6ul-pico.dtsi b/arch/arm/boot/dts/imx6ul-pico.dtsi index de9f83189ba8..df1da98ab10f 100644 --- a/arch/arm/boot/dts/imx6ul-pico.dtsi +++ b/arch/arm/boot/dts/imx6ul-pico.dtsi @@ -20,7 +20,7 @@ stdout-path = &uart6; }; - backlight { + backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm3 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; @@ -72,6 +72,17 @@ regulator-max-microvolt = <3300000>; startup-delay-us = <200000>; }; + + panel { + compatible = "vxt,vl050-8048nt-c01"; + backlight = <&backlight>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; }; &can1 { @@ -154,31 +165,11 @@ &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; - display = <&display0>; status = "okay"; - display0: display0 { - bits-per-pixel = <32>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <33200000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <210>; - hback-porch = <46>; - hsync-len = <1>; - vback-porch = <22>; - vfront-porch = <23>; - vsync-len = <1>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; + port { + display_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index d9fdca12819b..2ccf67c4ac1a 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -204,7 +204,7 @@ status = "disabled"; }; - aips1: aips-bus@2000000 { + aips1: bus@2000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -430,7 +430,7 @@ status = "disabled"; }; - gpt1: gpt@2098000 { + gpt1: timer@2098000 { compatible = "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"; reg = <0x02098000 0x4000>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; @@ -523,7 +523,7 @@ status = "disabled"; }; - kpp: kpp@20b8000 { + kpp: keypad@20b8000 { compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp"; reg = <0x020b8000 0x4000>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; @@ -531,14 +531,14 @@ status = "disabled"; }; - wdog1: wdog@20bc000 { + wdog1: watchdog@20bc000 { compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt"; reg = <0x020bc000 0x4000>; interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_WDOG1>; }; - wdog2: wdog@20c0000 { + wdog2: watchdog@20c0000 { compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt"; reg = <0x020c0000 0x4000>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; @@ -546,7 +546,7 @@ status = "disabled"; }; - clks: ccm@20c4000 { + clks: clock-controller@20c4000 { compatible = "fsl,imx6ul-ccm"; reg = <0x020c4000 0x4000>; interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, @@ -693,7 +693,7 @@ interrupt-parent = <&intc>; }; - iomuxc: iomuxc@20e0000 { + iomuxc: pinctrl@20e0000 { compatible = "fsl,imx6ul-iomuxc"; reg = <0x020e0000 0x4000>; }; @@ -704,7 +704,7 @@ reg = <0x020e4000 0x4000>; }; - gpt2: gpt@20e8000 { + gpt2: timer@20e8000 { compatible = "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"; reg = <0x020e8000 0x4000>; interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; @@ -771,14 +771,14 @@ }; }; - aips2: aips-bus@2100000 { + aips2: bus@2100000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; reg = <0x02100000 0x100000>; ranges; - crypto: caam@2140000 { + crypto: crypto@2140000 { compatible = "fsl,imx6ul-caam", "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; @@ -789,19 +789,19 @@ <&clks IMX6UL_CLK_CAAM_MEM>; clock-names = "ipg", "aclk", "mem"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr2: jr2@3000 { + sec_jr2: jr@3000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; @@ -1007,7 +1007,7 @@ status = "disabled"; }; - wdog3: wdog@21e4000 { + wdog3: watchdog@21e4000 { compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt"; reg = <0x021e4000 0x4000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi index b7e67d121322..fcde7f77ae42 100644 --- a/arch/arm/boot/dts/imx6ull.dtsi +++ b/arch/arm/boot/dts/imx6ull.dtsi @@ -51,7 +51,7 @@ / { soc { - aips3: aips-bus@2200000 { + aips3: bus@2200000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi new file mode 100644 index 000000000000..9fa701bec2ec --- /dev/null +++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017-2020 Toradex AG + * + */ + + +#include <dt-bindings/input/input.h> +#include <dt-bindings/pwm/pwm.h> + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiokeys>; + + power { + label = "Wake-Up"; + gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + linux,code = <KEY_WAKEUP>; + debounce-interval = <10>; + wakeup-source; + }; + }; + + panel: panel { + compatible = "edt,et057090dhu"; + backlight = <&bl>; + power-supply = <®_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&lcdif_out>; + }; + }; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 7 GPIO_ACTIVE_LOW>; + vin-supply = <®_5v0>; + }; +}; + +&adc1 { + status = "okay"; +}; + +/* + * ADC2 is not available on the Aster board and + * conflicts with AD7879 resistive touchscreen. + */ +&adc2 { + status = "disabled"; +}; + +&bl { + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <®_3v3>; + status = "okay"; +}; + +&fec1 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; + + /* Microchip/Atmel maxtouch controller */ + touchscreen@4a { + compatible = "atmel,maxtouch"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiotouch>; + reg = <0x4a>; + interrupt-parent = <&gpio2>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 */ + reset-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */ + }; + + /* M41T0M6 real time clock on carrier board */ + rtc: m41t0m6@68 { + compatible = "st,m41t0"; + reg = <0x68>; + }; +}; + +&iomuxc { + pinctrl_gpiotouch: touchgpios { + fsl,pins = < + MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x14 + >; + }; +}; + +&lcdif { + status = "okay"; + + port { + lcdif_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usbotg1 { + status = "okay"; +}; + +&usdhc1 { + keep-power-in-suspend; + no-1-8-v; + wakeup-source; + vmmc-supply = <®_3v3>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index 6aa123cbdadb..97601375f264 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -1,46 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ / { + aliases { + rtc0 = &rtc; + rtc1 = &snvs_rtc; + }; + chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index 04717cf69db0..e18e89dec879 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ / { @@ -130,6 +93,184 @@ status = "disabled"; }; +&gpio1 { + gpio-line-names = "SODIMM_43", + "SODIMM_45", + "SODIMM_135", + "SODIMM_22", + "", + "", + "SODIMM_37", + "SODIMM_29", + "SODIMM_59", + "SODIMM_28", + "SODIMM_30", + "SODIMM_67", + "", + "", + "SODIMM_188", + "SODIMM_178"; +}; + +&gpio2 { + gpio-line-names = "SODIMM_111", + "SODIMM_113", + "SODIMM_115", + "SODIMM_117", + "SODIMM_119", + "SODIMM_121", + "SODIMM_123", + "SODIMM_125", + "SODIMM_91", + "SODIMM_89", + "SODIMM_105", + "SODIMM_152", + "SODIMM_150", + "SODIMM_95", + "SODIMM_126", + "SODIMM_107", + "SODIMM_114", + "SODIMM_116", + "SODIMM_118", + "SODIMM_120", + "SODIMM_122", + "SODIMM_124", + "SODIMM_127", + "SODIMM_130", + "SODIMM_132", + "SODIMM_134", + "SODIMM_133", + "SODIMM_104", + "SODIMM_106", + "SODIMM_110", + "SODIMM_112", + "SODIMM_128"; +}; + +&gpio3 { + gpio-line-names = "SODIMM_56", + "SODIMM_44", + "SODIMM_68", + "SODIMM_82", + "SODIMM_93", + "SODIMM_76", + "SODIMM_70", + "SODIMM_60", + "SODIMM_58", + "SODIMM_78", + "SODIMM_72", + "SODIMM_80", + "SODIMM_46", + "SODIMM_62", + "SODIMM_48", + "SODIMM_74", + "SODIMM_50", + "SODIMM_52", + "SODIMM_54", + "SODIMM_66", + "SODIMM_64", + "SODIMM_57", + "SODIMM_61", + "SODIMM_136", + "SODIMM_138", + "SODIMM_140", + "SODIMM_142", + "SODIMM_144", + "SODIMM_146"; +}; + +&gpio4 { + gpio-line-names = "SODIMM_35", + "SODIMM_33", + "SODIMM_38", + "SODIMM_36", + "SODIMM_21", + "SODIMM_19", + "SODIMM_131", + "SODIMM_129", + "SODIMM_90", + "SODIMM_92", + "SODIMM_88", + "SODIMM_86", + "SODIMM_81", + "SODIMM_94", + "SODIMM_96", + "SODIMM_75", + "SODIMM_101", + "SODIMM_103", + "SODIMM_79", + "SODIMM_97", + "SODIMM_67", + "SODIMM_59", + "SODIMM_85", + "SODIMM_65"; +}; + +&gpio5 { + gpio-line-names = "SODIMM_69", + "SODIMM_71", + "SODIMM_73", + "SODIMM_47", + "SODIMM_190", + "SODIMM_192", + "SODIMM_49", + "SODIMM_51", + "SODIMM_53", + "", + "", + "SODIMM_98", + "SODIMM_184", + "SODIMM_186", + "SODIMM_23", + "SODIMM_31", + "SODIMM_100", + "SODIMM_102"; +}; + +&gpio6 { + gpio-line-names = "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "SODIMM_169", + "", + "", + "", + "SODIMM_77", + "SODIMM_24", + "", + "SODIMM_25", + "SODIMM_27", + "SODIMM_32", + "SODIMM_34"; +}; + +&gpio7 { + gpio-line-names = "", + "", + "SODIMM_63", + "SODIMM_55", + "", + "", + "", + "", + "SODIMM_196", + "SODIMM_194", + "", + "SODIMM_99", + "", + "", + "SODIMM_137"; +}; + &gpmi { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpmi_nand>; @@ -345,7 +486,7 @@ &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4 - &pinctrl_gpio7>; + &pinctrl_gpio7 &pinctrl_usbc_det>; pinctrl_gpio1: gpio1-grp { fsl,pins = < @@ -356,7 +497,6 @@ MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 /* SODIMM 95 */ MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x14 /* SODIMM 99 */ MX7D_PAD_EPDC_DATA10__GPIO2_IO10 0x74 /* SODIMM 105 */ - MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 /* SODIMM 107 */ MX7D_PAD_EPDC_DATA00__GPIO2_IO0 0x14 /* SODIMM 111 */ MX7D_PAD_EPDC_DATA01__GPIO2_IO1 0x14 /* SODIMM 113 */ MX7D_PAD_EPDC_DATA02__GPIO2_IO2 0x14 /* SODIMM 115 */ @@ -373,7 +513,6 @@ MX7D_PAD_SD2_DATA2__GPIO5_IO16 0x14 /* SODIMM 100 */ MX7D_PAD_SD2_DATA3__GPIO5_IO17 0x14 /* SODIMM 102 */ MX7D_PAD_EPDC_GDSP__GPIO2_IO27 0x14 /* SODIMM 104 */ - MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x74 /* SODIMM 106 */ MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x14 /* SODIMM 110 */ MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x14 /* SODIMM 112 */ MX7D_PAD_EPDC_SDCLK__GPIO2_IO16 0x14 /* SODIMM 114 */ @@ -450,7 +589,6 @@ pinctrl_enet1: enet1grp { fsl,pins = < - MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14 MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x73 MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x73 MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x73 @@ -648,6 +786,12 @@ >; }; + pinctrl_usbc_det: gpio-usbc-det { + fsl,pins = < + MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14 + >; + }; + pinctrl_usbh_reg: gpio-usbh-vbus { fsl,pins = < MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 /* SODIMM 129 USBH PEN */ diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts index 7646284e13a7..89267cd59037 100644 --- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts +++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts @@ -85,12 +85,12 @@ pmic: pmic@8 { compatible = "fsl,pfuze3000"; - reg = <0x08>; + reg = <0x8>; regulators { sw1a_reg: sw1a { regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1475000>; + regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; regulator-ramp-delay = <6250>; diff --git a/arch/arm/boot/dts/imx7d-colibri-aster.dts b/arch/arm/boot/dts/imx7d-colibri-aster.dts new file mode 100644 index 000000000000..f3f0537d5a37 --- /dev/null +++ b/arch/arm/boot/dts/imx7d-colibri-aster.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017-2020 Toradex AG + * + */ + +/dts-v1/; +#include "imx7d-colibri.dtsi" +#include "imx7-colibri-aster.dtsi" + +/ { + model = "Toradex Colibri iMX7D on Aster Carrier Board"; + compatible = "toradex,colibri-imx7d-aster", "toradex,colibri-imx7d", + "fsl,imx7d"; +}; + +&usbotg2 { + vbus-supply = <®_usbh_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts b/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts new file mode 100644 index 000000000000..20480276cb0e --- /dev/null +++ b/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017-2020 Toradex AG + * + */ + +/dts-v1/; +#include "imx7d-colibri-emmc.dtsi" +#include "imx7-colibri-aster.dtsi" + +/ { + model = "Toradex Colibri iMX7D 1GB (eMMC) on Aster Carrier Board"; + compatible = "toradex,colibri-imx7d-emmc-aster", + "toradex,colibri-imx7d-emmc", "fsl,imx7d"; +}; + +&usbotg2 { + vbus-supply = <®_usbh_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi index 898f4b8d7421..af39e5370fa1 100644 --- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi +++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi @@ -13,6 +13,32 @@ }; }; +&gpio6 { + gpio-line-names = "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "SODIMM_169", + "SODIMM_157", + "", + "SODIMM_163", + "SODIMM_77", + "SODIMM_24", + "", + "SODIMM_25", + "SODIMM_27", + "SODIMM_32", + "SODIMM_34"; +}; + &usbotg2 { dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts index 136e11ab4893..87b132bcd272 100644 --- a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx7d-colibri.dtsi b/arch/arm/boot/dts/imx7d-colibri.dtsi index e2e327f437e3..c59d72e50920 100644 --- a/arch/arm/boot/dts/imx7d-colibri.dtsi +++ b/arch/arm/boot/dts/imx7d-colibri.dtsi @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ #include "imx7d.dtsi" diff --git a/arch/arm/boot/dts/imx7d-pico-dwarf.dts b/arch/arm/boot/dts/imx7d-pico-dwarf.dts new file mode 100644 index 000000000000..5162fe227d1e --- /dev/null +++ b/arch/arm/boot/dts/imx7d-pico-dwarf.dts @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// +// Copyright 2015 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> +/dts-v1/; + +#include "imx7d-pico.dtsi" +/ { + model = "TechNexion PICO-IMX7D and DWARF baseboard"; + compatible = "technexion,imx7d-pico-dwarf", "fsl,imx7d"; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx7d-sgtl5000"; + audio-cpu = <&sai1>; + audio-codec = <&sgtl5000>; + audio-routing = + "LINE_IN", "Line In Jack", + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + }; + + sys_mclk: clock-sys-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; +}; + +&i2c1 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + sgtl5000: audio-codec@a { + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&sys_mclk>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + + pressure-sensor@60 { + compatible = "fsl,mpl3115"; + reg = <0x60>; + }; +}; + +&i2c4 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pca9554: io-expander@25 { + compatible = "nxp,pca9554"; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + reg = <0x25>; + }; + + touchscreen@38 { + compatible = "edt,edt-ft5x06"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_touchscreen>; + interrupt-parent = <&gpio2>; + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&pca9554 4 GPIO_ACTIVE_LOW>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; +}; + +&iomuxc { + pinctrl_touchscreen: touchscreengrp { + fsl,pins = < + MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx7d-pico-nymph.dts b/arch/arm/boot/dts/imx7d-pico-nymph.dts new file mode 100644 index 000000000000..104a85254adb --- /dev/null +++ b/arch/arm/boot/dts/imx7d-pico-nymph.dts @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// +// Copyright 2015 Technexion Ltd. +// +// Author: Wig Cheng <wig.cheng@technexion.com> +// Richard Hu <richard.hu@technexion.com> +// Tapani Utriainen <tapani@technexion.com> +/dts-v1/; + +#include "imx7d-pico.dtsi" +/ { + model = "TechNexion PICO-IMX7 and NYMPH baseboard"; + compatible = "technexion,imx7d-pico-nymph", "fsl,imx7d"; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led { + label = "gpio-led"; + gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx7d-sgtl5000"; + audio-cpu = <&sai1>; + audio-codec = <&sgtl5000>; + audio-routing = + "LINE_IN", "Line In Jack", + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + }; + + sys_mclk: clock-sys-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; +}; + +&i2c1 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + sgtl5000: audio-codec@a { + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&sys_mclk>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + + adc@52 { + compatible = "ti,adc081c"; + reg = <0x52>; + vref-supply = <®_2p5v>; + }; +}; + +&i2c2 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +&iomuxc { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx7s-colibri-aster.dts b/arch/arm/boot/dts/imx7s-colibri-aster.dts new file mode 100644 index 000000000000..fca4e0a95c1b --- /dev/null +++ b/arch/arm/boot/dts/imx7s-colibri-aster.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017-2020 Toradex AG + * + */ + +/dts-v1/; +#include "imx7s-colibri.dtsi" +#include "imx7-colibri-aster.dtsi" + +/ { + model = "Toradex Colibri iMX7S on Aster Carrier Board"; + compatible = "toradex,colibri-imx7s-aster", "toradex,colibri-imx7s", + "fsl,imx7s"; +}; diff --git a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts index bd2a49c1ade6..aa70d3f2e2e2 100644 --- a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ /dts-v1/; diff --git a/arch/arm/boot/dts/imx7s-colibri.dtsi b/arch/arm/boot/dts/imx7s-colibri.dtsi index 6d16e32aed89..94de220a5965 100644 --- a/arch/arm/boot/dts/imx7s-colibri.dtsi +++ b/arch/arm/boot/dts/imx7s-colibri.dtsi @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2016 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2016-2020 Toradex */ #include "imx7s.dtsi" diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 568d7a984aa6..76e3ffbbbfbf 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -315,7 +315,7 @@ <0x31006000 0x2000>; }; - aips1: aips-bus@30000000 { + aips1: bus@30000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -406,14 +406,14 @@ gpio-ranges = <&iomuxc 0 139 16>; }; - wdog1: wdog@30280000 { + wdog1: watchdog@30280000 { compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt"; reg = <0x30280000 0x10000>; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX7D_WDOG1_ROOT_CLK>; }; - wdog2: wdog@30290000 { + wdog2: watchdog@30290000 { compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt"; reg = <0x30290000 0x10000>; interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; @@ -421,7 +421,7 @@ status = "disabled"; }; - wdog3: wdog@302a0000 { + wdog3: watchdog@302a0000 { compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt"; reg = <0x302a0000 0x10000>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; @@ -429,7 +429,7 @@ status = "disabled"; }; - wdog4: wdog@302b0000 { + wdog4: watchdog@302b0000 { compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt"; reg = <0x302b0000 0x10000>; interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; @@ -443,7 +443,7 @@ fsl,input-sel = <&iomuxc>; }; - gpt1: gpt@302d0000 { + gpt1: timer@302d0000 { compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302d0000 0x10000>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; @@ -452,7 +452,7 @@ clock-names = "ipg", "per"; }; - gpt2: gpt@302e0000 { + gpt2: timer@302e0000 { compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302e0000 0x10000>; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; @@ -462,7 +462,7 @@ status = "disabled"; }; - gpt3: gpt@302f0000 { + gpt3: timer@302f0000 { compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302f0000 0x10000>; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; @@ -472,7 +472,7 @@ status = "disabled"; }; - gpt4: gpt@30300000 { + gpt4: timer@30300000 { compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x30300000 0x10000>; interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; @@ -482,7 +482,7 @@ status = "disabled"; }; - kpp: kpp@30320000 { + kpp: keypad@30320000 { compatible = "fsl,imx7d-kpp", "fsl,imx21-kpp"; reg = <0x30320000 0x10000>; interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; @@ -490,7 +490,7 @@ status = "disabled"; }; - iomuxc: iomuxc@30330000 { + iomuxc: pinctrl@30330000 { compatible = "fsl,imx7d-iomuxc"; reg = <0x30330000 0x10000>; }; @@ -606,13 +606,15 @@ compatible = "fsl,sec-v4.0-pwrkey"; regmap = <&snvs>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_SNVS_CLK>; + clock-names = "snvs-pwrkey"; linux,keycode = <KEY_POWER>; wakeup-source; status = "disabled"; }; }; - clks: ccm@30380000 { + clks: clock-controller@30380000 { compatible = "fsl,imx7d-ccm"; reg = <0x30380000 0x10000>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -663,7 +665,7 @@ }; }; - aips2: aips-bus@30400000 { + aips2: bus@30400000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -803,7 +805,7 @@ }; }; - aips3: aips-bus@30800000 { + aips3: bus@30800000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -932,7 +934,7 @@ }; }; - crypto: caam@30900000 { + crypto: crypto@30900000 { compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; @@ -943,19 +945,19 @@ <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>; clock-names = "ipg", "aclk"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr2: jr1@3000 { + sec_jr2: jr@3000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/imx7ulp-evk.dts b/arch/arm/boot/dts/imx7ulp-evk.dts index a863a2b337d6..eff51e113db4 100644 --- a/arch/arm/boot/dts/imx7ulp-evk.dts +++ b/arch/arm/boot/dts/imx7ulp-evk.dts @@ -72,7 +72,7 @@ srp-disable; hnp-disable; adp-disable; - over-current-active-low; + disable-over-current; status = "okay"; }; @@ -110,7 +110,6 @@ pinctrl_usbotg1_id: otg1idgrp { fsl,pins = < IMX7ULP_PAD_PTC13__USB0_ID 0x10003 - IMX7ULP_PAD_PTC16__USB1_OC2 0x10003 >; }; diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi index ab91c98f2124..f7c4878534c8 100644 --- a/arch/arm/boot/dts/imx7ulp.dtsi +++ b/arch/arm/boot/dts/imx7ulp.dtsi @@ -132,13 +132,13 @@ <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>; clock-names = "aclk", "ipg"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index 94d2ff9836d0..198d66181c50 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -9,7 +9,6 @@ / { model = "ARM Integrator/AP"; compatible = "arm,integrator-ap"; - dma-ranges = <0x80000000 0x0 0x80000000>; cpus { #address-cells = <1>; diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index 51e1305c6471..2093b38d6e6d 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -148,7 +148,7 @@ reg = <0 0x10005000 0 0x1000>; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt2701-scpsys", "syscon"; #power-domain-cells = <1>; reg = <0 0x10006000 0 0x1000>; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi index a79f0b6c3429..f76b4a3c34b9 100644 --- a/arch/arm/boot/dts/mt7623.dtsi +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -268,7 +268,7 @@ reg = <0 0x10005000 0 0x1000>; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt7623-scpsys", "mediatek,mt2701-scpsys", "syscon"; diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi index 867b88103b9d..5cbb3d244c75 100644 --- a/arch/arm/boot/dts/mt7629.dtsi +++ b/arch/arm/boot/dts/mt7629.dtsi @@ -90,7 +90,7 @@ #clock-cells = <1>; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt7629-scpsys", "mediatek,mt7622-scpsys"; #power-domain-cells = <1>; @@ -241,6 +241,20 @@ status = "disabled"; }; + pwm: pwm@11006000 { + compatible = "mediatek,mt7629-pwm"; + reg = <0x11006000 0x1000>; + #pwm-cells = <2>; + clocks = <&topckgen CLK_TOP_PWM_SEL>, + <&pericfg CLK_PERI_PWM_PD>, + <&pericfg CLK_PERI_PWM1_PD>; + clock-names = "top", "main", "pwm1"; + assigned-clocks = <&topckgen CLK_TOP_PWM_SEL>; + assigned-clock-parents = + <&topckgen CLK_TOP_UNIVPLL2_D4>; + status = "disabled"; + }; + i2c: i2c@11007000 { compatible = "mediatek,mt7629-i2c", "mediatek,mt2712-i2c"; diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi index 459fd7027591..ef59e4e97d7c 100644 --- a/arch/arm/boot/dts/omap4-l4.dtsi +++ b/arch/arm/boot/dts/omap4-l4.dtsi @@ -1529,6 +1529,7 @@ }; }; + /* Unused DSS L4 access, see L3 instead */ target-module@40000 { /* 0x48040000, ap 13 0a.0 */ compatible = "ti,sysc"; status = "disabled"; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 9a87440d0b9d..763bdea8c829 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -108,7 +108,6 @@ dsp { compatible = "ti,omap3-c64"; - ti,hwmods = "dsp"; }; iva { @@ -415,87 +414,213 @@ */ }; - dss: dss@58000000 { - compatible = "ti,omap4-dss"; - reg = <0x58000000 0x80>; - status = "disabled"; - ti,hwmods = "dss_core"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; + /* + * DSS is only using l3 mapping without l4 as noted in the TRM + * "10.1.3 DSS Register Manual" for omap4460. + */ + target-module@58000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x58000000 4>, + <0x58000014 4>; + reg-names = "rev", "syss"; + ti,syss-mask = <1>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 0>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "hdmi_clk", "sys_clk", "tv_clk"; #address-cells = <1>; #size-cells = <1>; - ranges; - - dispc@58001000 { - compatible = "ti,omap4-dispc"; - reg = <0x58001000 0x1000>; - interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dss_dispc"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; - }; - - rfbi: encoder@58002000 { - compatible = "ti,omap4-rfbi"; - reg = <0x58002000 0x1000>; - status = "disabled"; - ti,hwmods = "dss_rfbi"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, <&l3_div_ck>; - clock-names = "fck", "ick"; - }; + ranges = <0 0x58000000 0x1000000>; - venc: encoder@58003000 { - compatible = "ti,omap4-venc"; - reg = <0x58003000 0x1000>; + dss: dss@0 { + compatible = "ti,omap4-dss"; + reg = <0 0x80>; status = "disabled"; - ti,hwmods = "dss_venc"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 11>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>; clock-names = "fck"; - }; - - dsi1: encoder@58004000 { - compatible = "ti,omap4-dsi"; - reg = <0x58004000 0x200>, - <0x58004200 0x40>, - <0x58004300 0x20>; - reg-names = "proto", "phy", "pll"; - interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_dsi1"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, - <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - }; - - dsi2: encoder@58005000 { - compatible = "ti,omap4-dsi"; - reg = <0x58005000 0x200>, - <0x58005200 0x40>, - <0x58005300 0x20>; - reg-names = "proto", "phy", "pll"; - interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_dsi2"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, - <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - }; - - hdmi: encoder@58006000 { - compatible = "ti,omap4-hdmi"; - reg = <0x58006000 0x200>, - <0x58006200 0x100>, - <0x58006300 0x100>, - <0x58006400 0x1000>; - reg-names = "wp", "pll", "phy", "core"; - interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_hdmi"; - clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, - <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - dmas = <&sdma 76>; - dma-names = "audio_tx"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x1000000>; + + target-module@1000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x1000 0x4>, + <0x1010 0x4>, + <0x1014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1000 0x1000>; + + dispc@0 { + compatible = "ti,omap4-dispc"; + reg = <0 0x1000>; + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + }; + }; + + target-module@2000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x2000 0x4>, + <0x2010 0x4>, + <0x2014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x2000 0x1000>; + + rfbi: encoder@0 { + reg = <0 0x1000>; + status = "disabled"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, <&l3_div_ck>; + clock-names = "fck", "ick"; + }; + }; + + target-module@3000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x3000 0x4>; + reg-names = "rev"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "sys_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x3000 0x1000>; + + venc: encoder@0 { + compatible = "ti,omap4-venc"; + reg = <0 0x1000>; + status = "disabled"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 11>; + clock-names = "fck"; + }; + }; + + target-module@4000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x4000 0x4>, + <0x4010 0x4>, + <0x4014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x4000 0x1000>; + + dsi1: encoder@0 { + compatible = "ti,omap4-dsi"; + reg = <0 0x200>, + <0x200 0x40>, + <0x300 0x20>; + reg-names = "proto", "phy", "pll"; + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + }; + }; + + target-module@5000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x5000 0x4>, + <0x5010 0x4>, + <0x5014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x5000 0x1000>; + + dsi2: encoder@0 { + compatible = "ti,omap4-dsi"; + reg = <0 0x200>, + <0x200 0x40>, + <0x300 0x20>; + reg-names = "proto", "phy", "pll"; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + }; + }; + + target-module@6000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x6000 0x4>, + <0x6010 0x4>; + reg-names = "rev", "sysc"; + /* + * Has SYSC_IDLE_SMART and SYSC_IDLE_SMART_WKUP + * but HDMI audio will fail with them. + */ + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>; + ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET)>; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>; + clock-names = "fck", "dss_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x6000 0x2000>; + + hdmi: encoder@0 { + compatible = "ti,omap4-hdmi"; + reg = <0 0x200>, + <0x200 0x100>, + <0x300 0x100>, + <0x400 0x1000>; + reg-names = "wp", "pll", "phy", "core"; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + dmas = <&sdma 76>; + dma-names = "audio_tx"; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/omap5-l4-abe.dtsi b/arch/arm/boot/dts/omap5-l4-abe.dtsi index 4ec7909df78b..bafd6adf9f45 100644 --- a/arch/arm/boot/dts/omap5-l4-abe.dtsi +++ b/arch/arm/boot/dts/omap5-l4-abe.dtsi @@ -426,8 +426,20 @@ }; target-module@f1000 { /* 0x401f1000, ap 32 20.0 */ - compatible = "ti,sysc"; - status = "disabled"; + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0xf1000 0x4>, + <0xf1010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>, + <SYSC_IDLE_SMART_WKUP>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + /* Domains (V, P, C): iva, abe_pwrdm, abe_clkdm */ + clocks = <&abe_clkctrl OMAP5_AESS_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xf1000 0x1000>, diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index a7562d3deb1a..2ac7f021c284 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -293,78 +293,185 @@ */ }; - dss: dss@58000000 { - compatible = "ti,omap5-dss"; - reg = <0x58000000 0x80>; - status = "disabled"; - ti,hwmods = "dss_core"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; + target-module@58000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x58000000 4>, + <0x58000014 4>; + reg-names = "rev", "syss"; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 0>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "hdmi_clk", "sys_clk", "tv_clk"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0 0x58000000 0x1000000>; - dispc@58001000 { - compatible = "ti,omap5-dispc"; - reg = <0x58001000 0x1000>; - interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dss_dispc"; + dss: dss@0 { + compatible = "ti,omap5-dss"; + reg = <0 0x80>; + status = "disabled"; clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; clock-names = "fck"; - }; - - rfbi: encoder@58002000 { - compatible = "ti,omap5-rfbi"; - reg = <0x58002000 0x100>; - status = "disabled"; - ti,hwmods = "dss_rfbi"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, <&l3_iclk_div>; - clock-names = "fck", "ick"; - }; - - dsi1: encoder@58004000 { - compatible = "ti,omap5-dsi"; - reg = <0x58004000 0x200>, - <0x58004200 0x40>, - <0x58004300 0x40>; - reg-names = "proto", "phy", "pll"; - interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_dsi1"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, - <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - }; - - dsi2: encoder@58005000 { - compatible = "ti,omap5-dsi"; - reg = <0x58009000 0x200>, - <0x58009200 0x40>, - <0x58009300 0x40>; - reg-names = "proto", "phy", "pll"; - interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_dsi2"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, - <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - }; - - hdmi: encoder@58060000 { - compatible = "ti,omap5-hdmi"; - reg = <0x58040000 0x200>, - <0x58040200 0x80>, - <0x58040300 0x80>, - <0x58060000 0x19000>; - reg-names = "wp", "pll", "phy", "core"; - interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ti,hwmods = "dss_hdmi"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, - <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; - dmas = <&sdma 76>; - dma-names = "audio_tx"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x1000000>; + + target-module@1000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x1000 0x4>, + <0x1010 0x4>, + <0x1014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1000 0x1000>; + + dispc@0 { + compatible = "ti,omap5-dispc"; + reg = <0 0x1000>; + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + }; + }; + + target-module@2000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x2000 0x4>, + <0x2010 0x4>, + <0x2014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x2000 0x1000>; + + rfbi: encoder@0 { + compatible = "ti,omap5-rfbi"; + reg = <0 0x100>; + status = "disabled"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, <&l3_iclk_div>; + clock-names = "fck", "ick"; + }; + }; + + target-module@5000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x5000 0x4>, + <0x5010 0x4>, + <0x5014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x5000 0x1000>; + + dsi1: encoder@0 { + compatible = "ti,omap5-dsi"; + reg = <0 0x200>, + <0x200 0x40>, + <0x300 0x40>; + reg-names = "proto", "phy", "pll"; + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + }; + }; + + target-module@9000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x9000 0x4>, + <0x9010 0x4>, + <0x9014 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | + SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,syss-mask = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x9000 0x1000>; + + dsi2: encoder@0 { + compatible = "ti,omap5-dsi"; + reg = <0 0x200>, + <0x200 0x40>, + <0x300 0x40>; + reg-names = "proto", "phy", "pll"; + interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck"; + }; + }; + + target-module@40000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x40000 0x4>, + <0x40010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>, + <SYSC_IDLE_SMART_WKUP>; + ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET)>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; + clock-names = "fck", "dss_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40000 0x40000>; + + hdmi: encoder@0 { + compatible = "ti,omap5-hdmi"; + reg = <0 0x200>, + <0x200 0x80>, + <0x300 0x80>, + <0x20000 0x19000>; + reg-names = "wp", "pll", "phy", "core"; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; + dmas = <&sdma 76>; + dma-names = "audio_tx"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 8b79b4112ee1..2687c4e890ba 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -350,6 +350,7 @@ reg = <0x800000 0x4000>; gpio-controller; + gpio-ranges = <&tlmm_pinmux 0 0 90>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index fa1852eed37b..bf6a03506b45 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -403,6 +403,7 @@ compatible = "qcom,apq8084-pinctrl"; reg = <0xfd510000 0x4000>; gpio-controller; + gpio-ranges = <&tlmm 0 0 147>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi index 71bb25a8afc0..bfa9ce4c6e69 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -201,6 +201,7 @@ compatible = "qcom,ipq4019-pinctrl"; reg = <0x01000000 0x300000>; gpio-controller; + gpio-ranges = <&tlmm 0 0 100>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index 16c0da97932c..4021f661cd11 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -119,6 +119,7 @@ reg = <0x800000 0x4000>; gpio-controller; + gpio-ranges = <&qcom_pinmux 0 0 69>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi index 356e9535f7a6..347b4f7d7889 100644 --- a/arch/arm/boot/dts/qcom-mdm9615.dtsi +++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi @@ -128,6 +128,7 @@ msmgpio: pinctrl@800000 { compatible = "qcom,mdm9615-pinctrl"; gpio-controller; + gpio-ranges = <&msmgpio 0 0 88>; #gpio-cells = <2>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi index ec5cbc468bd3..480fc08cbe8e 100644 --- a/arch/arm/boot/dts/qcom-msm8660.dtsi +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi @@ -115,6 +115,7 @@ reg = <0x800000 0x4000>; gpio-controller; + gpio-ranges = <&tlmm 0 0 173>; #gpio-cells = <2>; interrupts = <0 16 0x4>; interrupt-controller; diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi index f2aeaccdc1ad..172ea3c70eac 100644 --- a/arch/arm/boot/dts/qcom-msm8960.dtsi +++ b/arch/arm/boot/dts/qcom-msm8960.dtsi @@ -107,6 +107,7 @@ msmgpio: pinctrl@800000 { compatible = "qcom,msm8960-pinctrl"; gpio-controller; + gpio-ranges = <&msmgpio 0 0 152>; #gpio-cells = <2>; interrupts = <0 16 0x4>; interrupt-controller; diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts index 3487daf98e81..32b474bfeec3 100644 --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -12,6 +12,7 @@ aliases { serial0 = &blsp1_uart1; + serial1 = &blsp2_uart10; }; chosen { @@ -355,6 +356,57 @@ bias-disable; }; }; + + bt_pin: bt { + hostwake { + pins = "gpio42"; + function = "gpio"; + }; + + devwake { + pins = "gpio62"; + function = "gpio"; + }; + + shutdown { + pins = "gpio41"; + function = "gpio"; + }; + }; + + blsp2_uart10_pin_a: blsp2-uart10-pin-active { + tx { + pins = "gpio53"; + function = "blsp_uart10"; + + drive-strength = <2>; + bias-disable; + }; + + rx { + pins = "gpio54"; + function = "blsp_uart10"; + + drive-strength = <2>; + bias-pull-up; + }; + + cts { + pins = "gpio55"; + function = "blsp_uart10"; + + drive-strength = <2>; + bias-pull-up; + }; + + rts { + pins = "gpio56"; + function = "blsp_uart10"; + + drive-strength = <2>; + bias-disable; + }; + }; }; sdhci@f9824900 { @@ -418,6 +470,25 @@ }; }; + serial@f9960000 { + status = "ok"; + + pinctrl-names = "default"; + pinctrl-0 = <&blsp2_uart10_pin_a>; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <3000000>; + + pinctrl-names = "default"; + pinctrl-0 = <&bt_pin>; + + host-wakeup-gpios = <&msmgpio 42 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&msmgpio 62 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&msmgpio 41 GPIO_ACTIVE_HIGH>; + }; + }; + i2c@f9967000 { status = "ok"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts index 450b8321e0a6..611bae9fe66b 100644 --- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts +++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts @@ -260,6 +260,31 @@ }; &soc { + usb@f9a55000 { + status = "ok"; + + phys = <&usb_hs1_phy>; + phy-select = <&tcsr 0xb000 0>; + extcon = <&smbb>, <&usb_id>; + vbus-supply = <&chg_otg>; + + hnp-disable; + srp-disable; + adp-disable; + + ulpi { + phy@a { + status = "ok"; + + v1p8-supply = <&pm8941_l6>; + v3p3-supply = <&pm8941_l24>; + + extcon = <&smbb>; + qcom,init-seq = /bits/ 8 <0x1 0x64>; + }; + }; + }; + sdhci@f9824900 { status = "ok"; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 4b161b809dd5..2ea2308d91b3 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -715,6 +715,15 @@ status = "disabled"; }; + blsp2_uart10: serial@f9960000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0xf9960000 0x1000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP2_UART4_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + sdhci@f9824900 { compatible = "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4"; reg = <0xf9824900 0x11c>, <0xf9824000 0x800>; @@ -925,6 +934,7 @@ compatible = "qcom,msm8974-pinctrl"; reg = <0xfd510000 0x4000>; gpio-controller; + gpio-ranges = <&msmgpio 0 0 146>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/r7s72100-gr-peach.dts b/arch/arm/boot/dts/r7s72100-gr-peach.dts index fe1a4aa4d7cb..2562cc9b5356 100644 --- a/arch/arm/boot/dts/r7s72100-gr-peach.dts +++ b/arch/arm/boot/dts/r7s72100-gr-peach.dts @@ -41,6 +41,9 @@ bank-width = <4>; device-width = <1>; + clocks = <&mstp9_clks R7S72100_CLK_SPIBSC0>; + power-domains = <&cpg_clocks>; + #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 75b2796ebfca..0a567d8ebc66 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -467,11 +467,12 @@ #clock-cells = <1>; compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0xfcfe0438 4>; - clocks = <&p0_clk>, <&p0_clk>, <&p0_clk>, <&p0_clk>; + clocks = <&p0_clk>, <&p0_clk>, <&p0_clk>, <&p0_clk>, <&b_clk>, <&b_clk>; clock-indices = < R7S72100_CLK_I2C0 R7S72100_CLK_I2C1 R7S72100_CLK_I2C2 R7S72100_CLK_I2C3 + R7S72100_CLK_SPIBSC0 R7S72100_CLK_SPIBSC1 >; - clock-output-names = "i2c0", "i2c1", "i2c2", "i2c3"; + clock-output-names = "i2c0", "i2c1", "i2c2", "i2c3", "spibsc0", "spibsc1"; }; mstp10_clks: mstp10_clks@fcfe043c { diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index a5351ddbf506..b088e8e351d5 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -157,11 +157,8 @@ &cpu0 { cpu0-supply = <&vdd_dvfs>; - operating-points = < - /* kHz uV */ - 1950000 1115000 - 1462500 995000 - >; + operating-points = <1950000 1115000>, /* kHz uV */ + <1462500 995000>; voltage-tolerance = <1>; /* 1% */ }; diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 1cd19a569bd0..e8b340bb99bc 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -1669,9 +1669,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7744.dtsi b/arch/arm/boot/dts/r8a7744.dtsi index 1c82dd0abd76..def840b8b2d3 100644 --- a/arch/arm/boot/dts/r8a7744.dtsi +++ b/arch/arm/boot/dts/r8a7744.dtsi @@ -1655,9 +1655,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dts b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dts index 2aeebfc9e4f1..92aa26ba423c 100644 --- a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dts +++ b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dts @@ -108,6 +108,12 @@ }; }; +&lcd_panel { + status = "disabled"; + + /delete-node/ port; +}; + &pfc { can1_pins: can1 { groups = "can1_data_b"; diff --git a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts index 58d369ad8279..b15b1b088a32 100644 --- a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts +++ b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts @@ -30,6 +30,7 @@ /dts-v1/; #include "r8a7745-iwg22m.dtsi" +#include <dt-bindings/pwm/pwm.h> / { model = "iWave Systems RainboW-G22D-SODIMM board based on RZ/G1E"; @@ -78,6 +79,49 @@ gpios-states = <1>; states = <3300000 1>, <1800000 0>; }; + + vccq_panel: regulator-vccq-panel { + compatible = "regulator-fixed"; + regulator-name = "Panel VccQ"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 13 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + backlight_lcd: backlight { + compatible = "pwm-backlight"; + pwms = <&tpu 3 5000000 PWM_POLARITY_INVERTED>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <7>; + }; + + lcd_panel: lcd { + compatible = "edt,etm043080dh6gp"; + power-supply = <&vccq_panel>; + backlight = <&backlight_lcd>; + + port { + lcd_in: endpoint { + remote-endpoint = <&du_out_rgb0>; + }; + }; + }; +}; + +&du { + pinctrl-0 = <&du0_pins>; + pinctrl-names = "default"; + + status = "okay"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&lcd_in>; + }; + }; + }; }; &avb { @@ -127,6 +171,39 @@ status = "okay"; clock-frequency = <400000>; + stmpe811@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + interrupt-parent = <&gpio4>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + + /* 3.25 MHz ADC clock speed */ + st,adc-freq = <1>; + /* ADC converstion time: 80 clocks */ + st,sample-time = <4>; + /* 12-bit ADC */ + st,mod-12b = <1>; + /* internal ADC reference */ + st,ref-sel = <0>; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + /* 8 sample average control */ + st,ave-ctrl = <3>; + /* 7 length fractional part in z */ + st,fraction-z = <7>; + /* + * 50 mA typical 80 mA max touchscreen drivers + * current limit value + */ + st,i-drive = <1>; + /* 1 ms panel driver settling time */ + st,settling = <3>; + /* 5 ms touch detect interrupt delay */ + st,touch-det-delay = <5>; + }; + }; + sgtl5000: codec@a { compatible = "fsl,sgtl5000"; #sound-dai-cells = <0>; @@ -149,11 +226,21 @@ function = "avb"; }; + backlight_pins: backlight { + groups = "tpu_to3_c"; + function = "tpu"; + }; + can0_pins: can0 { groups = "can0_data"; function = "can0"; }; + du0_pins: du0 { + groups = "du0_rgb666", "du0_sync", "du0_disp", "du0_clk0_out"; + function = "du0"; + }; + hscif1_pins: hscif1 { groups = "hscif1_data", "hscif1_ctrl"; function = "hscif1"; @@ -229,6 +316,12 @@ shared-pin; }; +&tpu { + pinctrl-0 = <&backlight_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + &usbphy { status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 3f88a7e34af2..7ab58d8bb740 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -1506,11 +1506,12 @@ du: display@feb00000 { compatible = "renesas,du-r8a7745"; reg = <0 0xfeb00000 0 0x40000>; - reg-names = "du"; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a77470.dtsi b/arch/arm/boot/dts/r8a77470.dtsi index 6efcef1670e1..f55153192276 100644 --- a/arch/arm/boot/dts/r8a77470.dtsi +++ b/arch/arm/boot/dts/r8a77470.dtsi @@ -942,9 +942,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 097fd9317c6e..69745def44d4 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -674,6 +674,7 @@ interrupt-parent = <&irqc0>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio5 31 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7790-stout.dts b/arch/arm/boot/dts/r8a7790-stout.dts index a315ba749aa4..4138efb2766d 100644 --- a/arch/arm/boot/dts/r8a7790-stout.dts +++ b/arch/arm/boot/dts/r8a7790-stout.dts @@ -203,6 +203,7 @@ interrupt-parent = <&irqc0>; interrupts = <1 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 334ba19769b9..e5ef9fd4284a 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -1719,6 +1719,8 @@ clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>; clock-names = "du.0", "du.1", "du.2"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 2b096d5e06fb..687167b70cb6 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -633,6 +633,7 @@ interrupt-parent = <&irqc0>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index f9ece7ab2010..a8e0335148a5 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -307,6 +307,7 @@ interrupt-parent = <&irqc0>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 59a55e87fcc6..6e5bd86731cd 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1681,9 +1681,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi index 39af16caa2ae..4627eefa502b 100644 --- a/arch/arm/boot/dts/r8a7792.dtsi +++ b/arch/arm/boot/dts/r8a7792.dtsi @@ -852,9 +852,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 22ca7cd1e7d2..cfe06a74ce89 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -591,6 +591,7 @@ interrupt-parent = <&irqc0>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index eef035c4d983..dadbda16161b 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -1341,9 +1341,10 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts index f79fce74cd9c..935935c1dbac 100644 --- a/arch/arm/boot/dts/r8a7794-alt.dts +++ b/arch/arm/boot/dts/r8a7794-alt.dts @@ -343,6 +343,7 @@ interrupt-parent = <&irqc0>; interrupts = <8 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts index 2c16ad854300..9aaa96ea9943 100644 --- a/arch/arm/boot/dts/r8a7794-silk.dts +++ b/arch/arm/boot/dts/r8a7794-silk.dts @@ -394,6 +394,7 @@ interrupt-parent = <&irqc0>; interrupts = <8 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; + reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 05ef79c6ed7f..2c9e7a1ebfec 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -1356,6 +1356,8 @@ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; + resets = <&cpg 724>; + reset-names = "du.0"; status = "disabled"; ports { diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index fb3cf005cc90..2ff9f152d29b 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -319,7 +319,7 @@ bus-width = <4>; cap-sd-highspeed; cap-sdio-irq; - default-sample-phase = <90>; + rockchip,default-sample-phase = <90>; keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index cf36e25195b4..781ac7583522 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -54,7 +54,7 @@ }; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -101,7 +101,7 @@ #clock-cells = <0>; }; - bus_intmem@10080000 { + bus_intmem: sram@10080000 { compatible = "mmio-sram"; reg = <0x10080000 0x2000>; #address-cells = <1>; @@ -263,7 +263,7 @@ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; - default-sample-phase = <158>; + rockchip,default-sample-phase = <158>; disable-wp; dmas = <&pdma 12>; dma-names = "rx-tx"; @@ -281,8 +281,6 @@ compatible = "rockchip,rk3036-i2s", "rockchip,rk3066-i2s"; reg = <0x10220000 0x4000>; interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S>, <&cru HCLK_I2S>; dmas = <&pdma 0>, <&pdma 1>; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 3d1b02f45ffd..b599394d149d 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -156,14 +156,12 @@ compatible = "rockchip,rk3066-i2s"; reg = <0x10118000 0x2000>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>; + clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac1_s 4>, <&dmac1_s 5>; dma-names = "tx", "rx"; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; rockchip,playback-channels = <8>; rockchip,capture-channels = <2>; #sound-dai-cells = <0>; @@ -174,14 +172,12 @@ compatible = "rockchip,rk3066-i2s"; reg = <0x1011a000 0x2000>; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&i2s1_bus>; + clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>; + clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac1_s 6>, <&dmac1_s 7>; dma-names = "tx", "rx"; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S1>, <&cru SCLK_I2S1>; rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; #sound-dai-cells = <0>; @@ -192,14 +188,12 @@ compatible = "rockchip,rk3066-i2s"; reg = <0x1011c000 0x2000>; interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&i2s2_bus>; + clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>; + clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac1_s 9>, <&dmac1_s 10>; dma-names = "tx", "rx"; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S2>, <&cru SCLK_I2S2>; rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; #sound-dai-cells = <0>; diff --git a/arch/arm/boot/dts/rk3188-bqedison2qc.dts b/arch/arm/boot/dts/rk3188-bqedison2qc.dts index ad1afd403052..66a0ff196eb1 100644 --- a/arch/arm/boot/dts/rk3188-bqedison2qc.dts +++ b/arch/arm/boot/dts/rk3188-bqedison2qc.dts @@ -58,20 +58,25 @@ lvds-encoder { compatible = "ti,sn75lvds83", "lvds-encoder"; - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - lvds_in_vop0: endpoint { - remote-endpoint = <&vop0_out_lvds>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lvds_in_vop0: endpoint { + remote-endpoint = <&vop0_out_lvds>; + }; }; - }; - port@1 { - reg = <1>; - lvds_out_panel: endpoint { - remote-endpoint = <&panel_in_lvds>; + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; }; }; }; @@ -465,7 +470,7 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; - vmmcq-supply = <&vccio_wl>; + vqmmc-supply = <&vccio_wl>; #address-cells = <1>; #size-cells = <0>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 10ede65d90f3..2298a8d840ba 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -166,14 +166,12 @@ compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s"; reg = <0x1011a000 0x2000>; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>; + clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac1_s 6>, <&dmac1_s 7>; dma-names = "tx", "rx"; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; #sound-dai-cells = <0>; @@ -184,8 +182,8 @@ compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif"; reg = <0x1011e000 0x2000>; #sound-dai-cells = <0>; - clock-names = "hclk", "mclk"; - clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>; + clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF>; + clock-names = "mclk", "hclk"; dmas = <&dmac1_s 8>; dma-names = "tx"; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index 4e90efdc9630..06172ebbf0ce 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -95,7 +95,7 @@ }; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -152,8 +152,6 @@ compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100b0000 0x4000>; interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>; dmas = <&pdma 14>, <&pdma 15>; @@ -167,8 +165,6 @@ compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100c0000 0x4000>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; dmas = <&pdma 11>, <&pdma 12>; @@ -193,8 +189,6 @@ compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100e0000 0x4000>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2_2CH>; dmas = <&pdma 0>, <&pdma 1>; @@ -698,7 +692,7 @@ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; bus-width = <8>; - default-sample-phase = <158>; + rockchip,default-sample-phase = <158>; fifo-depth = <0x100>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; @@ -718,7 +712,6 @@ g-np-tx-fifo-size = <16>; g-rx-fifo-size = <280>; g-tx-fifo-size = <256 128 128 64 32 16>; - g-use-dma; phys = <&u2phy0_otg>; phy-names = "usb2-phy"; status = "disabled"; @@ -729,7 +722,6 @@ reg = <0x30080000 0x20000>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy0>; - clock-names = "usbhost", "utmi"; phys = <&u2phy0_host>; phy-names = "usb"; status = "disabled"; @@ -740,7 +732,6 @@ reg = <0x300a0000 0x20000>; interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy0>; - clock-names = "usbhost", "utmi"; phys = <&u2phy0_host>; phy-names = "usb"; status = "disabled"; @@ -751,7 +742,6 @@ reg = <0x300c0000 0x20000>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST1>, <&u2phy1>; - clock-names = "usbhost", "utmi"; phys = <&u2phy1_otg>; phy-names = "usb"; status = "disabled"; @@ -762,7 +752,6 @@ reg = <0x300e0000 0x20000>; interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST1>, <&u2phy1>; - clock-names = "usbhost", "utmi"; phys = <&u2phy1_otg>; phy-names = "usb"; status = "disabled"; @@ -775,7 +764,6 @@ clocks = <&cru HCLK_HOST2>, <&u2phy1>; phys = <&u2phy1_host>; phy-names = "usb"; - clock-names = "usbhost", "utmi"; status = "disabled"; }; @@ -784,7 +772,6 @@ reg = <0x30120000 0x20000>; interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST2>, <&u2phy1>; - clock-names = "usbhost", "utmi"; phys = <&u2phy1_host>; phy-names = "usb"; status = "disabled"; diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts index 80080767c365..be695b8c1f67 100644 --- a/arch/arm/boot/dts/rk3288-evb-act8846.dts +++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts @@ -4,6 +4,7 @@ #include "rk3288-evb.dtsi" / { + model = "Rockchip RK3288 EVB ACT8846"; compatible = "rockchip,rk3288-evb-act8846", "rockchip,rk3288"; vcc_lcd: vcc-lcd { diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts index 16788209625b..42384ea4ca21 100644 --- a/arch/arm/boot/dts/rk3288-evb-rk808.dts +++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts @@ -4,6 +4,7 @@ #include "rk3288-evb.dtsi" / { + model = "Rockchip RK3288 EVB RK808"; compatible = "rockchip,rk3288-evb-rk808", "rockchip,rk3288"; }; diff --git a/arch/arm/boot/dts/rk3288-firefly-reload.dts b/arch/arm/boot/dts/rk3288-firefly-reload.dts index 1574383fd2dc..8c38bda21a7c 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload.dts +++ b/arch/arm/boot/dts/rk3288-firefly-reload.dts @@ -234,6 +234,7 @@ }; &saradc { + vref-supply = <&vcc_18>; status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index a6ffc381abaa..a258c7ae5329 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -9,6 +9,7 @@ #include "rk3288.dtsi" / { + model = "Netxeon R89"; compatible = "netxeon,r89", "rockchip,rk3288"; memory@0 { diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi index 312582c1bd37..acfaa12ec239 100644 --- a/arch/arm/boot/dts/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rk3288-tinker.dtsi @@ -276,6 +276,7 @@ }; vccio_sd: LDO_REG5 { + regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; diff --git a/arch/arm/boot/dts/rk3288-vyasa.dts b/arch/arm/boot/dts/rk3288-vyasa.dts index ba06e9f97ddc..385dd59393e1 100644 --- a/arch/arm/boot/dts/rk3288-vyasa.dts +++ b/arch/arm/boot/dts/rk3288-vyasa.dts @@ -78,6 +78,18 @@ vin-supply = <&vcc_io>; }; + vcc50_hdmi: vcc50-hdmi { + compatible = "regulator-fixed"; + regulator-name = "vcc50_hdmi"; + enable-active-high; + gpio = <&gpio7 RK_PB4 GPIO_ACTIVE_HIGH>; /* HDMI_EN */ + pinctrl-names = "default"; + pinctrl-0 = <&vcc50_hdmi_en>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vsus_5v>; + }; + vusb1_5v: vusb1-5v { compatible = "regulator-fixed"; regulator-name = "vusb1_5v"; @@ -150,7 +162,7 @@ }; &hdmi { - ddc-i2c-bus = <&i2c2>; + ddc-i2c-bus = <&i2c5>; status = "okay"; }; @@ -286,15 +298,15 @@ }; }; - vcc10_lcd: LDO_REG6 { - regulator-name = "vcc10_lcd"; + vdd10_lcd: LDO_REG6 { + regulator-name = "vdd10_lcd"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; regulator-always-on; regulator-boot-on; regulator-state-mem { regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; + regulator-suspend-microvolt = <1000000>; }; }; @@ -347,7 +359,7 @@ }; }; -&i2c2 { +&i2c5 { status = "okay"; }; @@ -446,6 +458,12 @@ }; }; + hdmi { + vcc50_hdmi_en: vcc50-hdmi-en { + rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int: pmic-int { rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 9beb662166aa..0cd88774db95 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -155,7 +155,7 @@ }; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -420,6 +420,8 @@ reg-io-width = <4>; clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac_peri 1>, <&dmac_peri 2>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>; status = "disabled"; @@ -433,6 +435,8 @@ reg-io-width = <4>; clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac_peri 3>, <&dmac_peri 4>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "disabled"; @@ -459,6 +463,8 @@ reg-io-width = <4>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac_peri 7>, <&dmac_peri 8>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&uart3_xfer>; status = "disabled"; @@ -472,6 +478,8 @@ reg-io-width = <4>; clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac_peri 9>, <&dmac_peri 10>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer>; status = "disabled"; @@ -601,7 +609,6 @@ reg = <0x0 0xff500000 0x0 0x100>; interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_USBHOST0>; - clock-names = "usbhost"; phys = <&usbphy1>; phy-names = "usb"; status = "disabled"; @@ -644,7 +651,6 @@ reg = <0x0 0xff5c0000 0x0 0x100>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HSIC>; - clock-names = "usbhost"; status = "disabled"; }; @@ -718,7 +724,7 @@ status = "disabled"; }; - bus_intmem@ff700000 { + bus_intmem: sram@ff700000 { compatible = "mmio-sram"; reg = <0x0 0xff700000 0x0 0x18000>; #address-cells = <1>; @@ -730,7 +736,7 @@ }; }; - sram@ff720000 { + pmu_sram: sram@ff720000 { compatible = "rockchip,rk3288-pmu-sram", "mmio-sram"; reg = <0x0 0xff720000 0x0 0x1000>; }; @@ -946,8 +952,8 @@ compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif"; reg = <0x0 0xff8b0000 0x0 0x10000>; #sound-dai-cells = <0>; - clock-names = "hclk", "mclk"; - clocks = <&cru HCLK_SPDIF8CH>, <&cru SCLK_SPDIF8CH>; + clocks = <&cru SCLK_SPDIF8CH>, <&cru HCLK_SPDIF8CH>; + clock-names = "mclk", "hclk"; dmas = <&dmac_bus_s 3>; dma-names = "tx"; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; @@ -962,12 +968,10 @@ reg = <0x0 0xff890000 0x0 0x10000>; #sound-dai-cells = <0>; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>; + clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac_bus_s 0>, <&dmac_bus_s 1>; dma-names = "tx", "rx"; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; rockchip,playback-channels = <8>; diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 241f43e29c77..f9fcb7e9657b 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -32,7 +32,7 @@ spi1 = &spi1; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -91,7 +91,7 @@ status = "disabled"; }; - L2: l2-cache-controller@10138000 { + L2: cache-controller@10138000 { compatible = "arm,pl310-cache"; reg = <0x10138000 0x1000>; cache-unified; diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi index 1fd06e7cb983..f9cfe2c80791 100644 --- a/arch/arm/boot/dts/rv1108.dtsi +++ b/arch/arm/boot/dts/rv1108.dtsi @@ -85,7 +85,7 @@ #clock-cells = <0>; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -102,7 +102,7 @@ }; }; - bus_intmem@10080000 { + bus_intmem: sram@10080000 { compatible = "mmio-sram"; reg = <0x10080000 0x2000>; #address-cells = <1>; @@ -120,7 +120,6 @@ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; clock-names = "baudclk", "apb_pclk"; dmas = <&pdma 6>, <&pdma 7>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart2m0_xfer>; status = "disabled"; @@ -136,7 +135,6 @@ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; clock-names = "baudclk", "apb_pclk"; dmas = <&pdma 4>, <&pdma 5>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "disabled"; @@ -152,7 +150,6 @@ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; dmas = <&pdma 2>, <&pdma 3>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; status = "disabled"; @@ -208,7 +205,6 @@ clock-names = "spiclk", "apb_pclk"; dmas = <&pdma 8>, <&pdma 9>; dma-names = "tx", "rx"; - #dma-cells = <2>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -370,7 +366,6 @@ reg = <0x1038c000 0x100>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; #io-channel-cells = <1>; - clock-frequency = <1000000>; clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; clock-names = "saradc", "apb_pclk"; status = "disabled"; @@ -499,7 +494,6 @@ reg = <0x30140000 0x20000>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy>; - clock-names = "usbhost", "utmi"; phys = <&u2phy_host>; phy-names = "usb"; status = "disabled"; @@ -510,7 +504,6 @@ reg = <0x30160000 0x20000>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy>; - clock-names = "usbhost", "utmi"; phys = <&u2phy_host>; phy-names = "usb"; status = "disabled"; @@ -527,7 +520,6 @@ g-np-tx-fifo-size = <16>; g-rx-fifo-size = <280>; g-tx-fifo-size = <256 128 128 64 32 16>; - g-use-dma; phys = <&u2phy_otg>; phy-names = "usb2-phy"; status = "disabled"; diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi index 326b39328b58..6763423d64b8 100644 --- a/arch/arm/boot/dts/sam9x60.dtsi +++ b/arch/arm/boot/dts/sam9x60.dtsi @@ -686,6 +686,14 @@ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; clocks = <&clk32k 0>; }; + + watchdog: watchdog@ffffff80 { + compatible = "microchip,sam9x60-wdt"; + reg = <0xffffff80 0x24>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k 0>; + status = "disabled"; + }; }; }; }; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 2012b7407c60..ab550d69db91 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -695,7 +695,7 @@ }; rtc: rtc@f80480b0 { - compatible = "atmel,at91rm9200-rtc"; + compatible = "atmel,sama5d2-rtc"; reg = <0xf80480b0 0x30>; interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>; clocks = <&clk32k>; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 203d40be70a5..f11b018e9173 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -159,8 +159,11 @@ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(7)>, <&dma0 2 AT91_DMA_CFG_PER_ID(8)>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c0>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA 31 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&twi0_clk>; @@ -174,8 +177,11 @@ dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(9)>, <&dma0 2 AT91_DMA_CFG_PER_ID(10)>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&pioC 26 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioC 27 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&twi1_clk>; @@ -357,8 +363,11 @@ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(11)>, <&dma1 2 AT91_DMA_CFG_PER_ID(12)>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + sda-gpios = <&pioA 18 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA 19 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&twi2_clk>; @@ -639,6 +648,12 @@ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA30 periph A TWD0 pin, conflicts with URXD1, ISI_VSYNC */ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA31 periph A TWCK0 pin, conflicts with UTXD1, ISI_HSYNC */ }; + + pinctrl_i2c0_gpio: i2c0-gpio { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOA 31 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; i2c1 { @@ -647,6 +662,12 @@ <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC26 periph B TWD1 pin, conflicts with SPI1_NPCS1, ISI_D11 */ AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10 */ }; + + pinctrl_i2c1_gpio: i2c1-gpio { + atmel,pins = + <AT91_PIOC 26 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOC 27 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; i2c2 { @@ -655,6 +676,12 @@ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* TWD2 pin, conflicts with LCDDAT18, ISI_D2 */ AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* TWCK2 pin, conflicts with LCDDAT19, ISI_D3 */ }; + + pinctrl_i2c2_gpio: i2c2-gpio { + atmel,pins = + <AT91_PIOA 18 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOA 19 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; isi { diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 6ab27a7b388d..c9c0316b5b0e 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -458,8 +458,11 @@ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(3))>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c0>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA 31 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 32>; @@ -477,8 +480,11 @@ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(5))>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioE 30 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 33>; @@ -519,8 +525,11 @@ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(7))>; dma-names = "tx", "rx"; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + sda-gpios = <&pioB 29 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioB 30 GPIO_ACTIVE_HIGH>; #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 34>; @@ -884,7 +893,7 @@ }; rtc@fc0686b0 { - compatible = "atmel,at91rm9200-rtc"; + compatible = "atmel,sama5d4-rtc"; reg = <0xfc0686b0 0x30>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; clocks = <&clk32k>; @@ -1122,6 +1131,12 @@ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>; }; + + pinctrl_i2c0_gpio: i2c0-gpio { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOA 31 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; i2c1 { @@ -1130,6 +1145,12 @@ <AT91_PIOE 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* TWD1, conflicts with UART0 RX and DIBP */ AT91_PIOE 30 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* TWCK1, conflicts with UART0 TX and DIBN */ }; + + pinctrl_i2c1_gpio: i2c1-gpio { + atmel,pins = + <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOE 30 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; i2c2 { @@ -1138,6 +1159,12 @@ <AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* TWD2, conflicts with RD0 and PWML1 */ AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* TWCK2, conflicts with RF0 */ }; + + pinctrl_i2c2_gpio: i2c2-gpio { + atmel,pins = + <AT91_PIOB 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOB 30 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; isi { diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts index 1916f31a30ff..5a8d92a061df 100644 --- a/arch/arm/boot/dts/sh73a0-kzm9g.dts +++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts @@ -25,12 +25,9 @@ cpus { cpu@0 { cpu0-supply = <&vdd_dvfs>; - operating-points = < - /* kHz uV */ - 1196000 1315000 - 598000 1175000 - 398667 1065000 - >; + operating-points = <1196000 1315000>, /* kHz uV */ + < 598000 1175000>, + < 398667 1065000>; voltage-tolerance = <1>; /* 1% */ }; }; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index 2a86e72d9791..3b8571b8b412 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -431,8 +431,8 @@ snps,perfect-filter-entries = <128>; tx-fifo-depth = <4096>; rx-fifo-depth = <16384>; - clocks = <&l4_mp_clk>; - clock-names = "stmmaceth"; + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; snps,axi-config = <&socfpga_axi_setup>; @@ -451,8 +451,8 @@ snps,perfect-filter-entries = <128>; tx-fifo-depth = <4096>; rx-fifo-depth = <16384>; - clocks = <&l4_mp_clk>; - clock-names = "stmmaceth"; + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; snps,axi-config = <&socfpga_axi_setup>; @@ -471,8 +471,8 @@ snps,perfect-filter-entries = <128>; tx-fifo-depth = <4096>; rx-fifo-depth = <16384>; - clocks = <&l4_mp_clk>; - clock-names = "stmmaceth"; + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; snps,axi-config = <&socfpga_axi_setup>; diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts b/arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts index 9bd9e04c7361..9aa897b79544 100644 --- a/arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts +++ b/arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts @@ -16,11 +16,11 @@ partition@0 { label = "Boot and fpga data"; - reg = <0x0 0x1C00000>; + reg = <0x0 0x02000000>; }; partition@1c00000 { label = "Root Filesystem - JFFS2"; - reg = <0x1C00000 0x6400000>; + reg = <0x02000000 0x06000000>; }; }; }; diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi index 14d4d8617d75..3cd6ee6d50e0 100644 --- a/arch/arm/boot/dts/ste-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-ab8500.dtsi @@ -314,13 +314,13 @@ mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>; - dsi@a0351000 { + dsi-controller@a0351000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi@a0352000 { + dsi-controller@a0352000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi@a0353000 { + dsi-controller@a0353000 { vana-supply = <&ab8500_ldo_ana_reg>; }; }; diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi index c72aa250bf6f..67bc69e67b33 100644 --- a/arch/arm/boot/dts/ste-ab8505.dtsi +++ b/arch/arm/boot/dts/ste-ab8505.dtsi @@ -261,13 +261,13 @@ mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>; - dsi@a0351000 { + dsi-controller@a0351000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi@a0352000 { + dsi-controller@a0352000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi@a0353000 { + dsi-controller@a0353000 { vana-supply = <&ab8500_ldo_ana_reg>; }; }; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 6671f74c9f03..3e10da3f8fd3 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -1097,7 +1097,7 @@ ranges; status = "disabled"; - dsi0: dsi@a0351000 { + dsi0: dsi-controller@a0351000 { compatible = "ste,mcde-dsi"; reg = <0xa0351000 0x1000>; clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; @@ -1105,7 +1105,7 @@ #address-cells = <1>; #size-cells = <0>; }; - dsi1: dsi@a0352000 { + dsi1: dsi-controller@a0352000 { compatible = "ste,mcde-dsi"; reg = <0xa0352000 0x1000>; clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; @@ -1113,7 +1113,7 @@ #address-cells = <1>; #size-cells = <0>; }; - dsi2: dsi@a0353000 { + dsi2: dsi-controller@a0353000 { compatible = "ste,mcde-dsi"; reg = <0xa0353000 0x1000>; /* This DSI port only has the Low Power / Energy Save clock */ diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi index e32d0c36feb8..b8fd8f18ba16 100644 --- a/arch/arm/boot/dts/ste-href-stuib.dtsi +++ b/arch/arm/boot/dts/ste-href-stuib.dtsi @@ -199,7 +199,7 @@ mcde@a0350000 { status = "okay"; - dsi@a0351000 { + dsi-controller@a0351000 { panel { compatible = "samsung,s6d16d0"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi index e024520f4d47..de82b9db956f 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi @@ -66,7 +66,7 @@ mcde@a0350000 { status = "okay"; - dsi@a0351000 { + dsi-controller@a0351000 { panel { compatible = "samsung,s6d16d0"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi index cb3677f0a1cb..9f285c7cf914 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi @@ -45,7 +45,7 @@ mcde@a0350000 { status = "okay"; - dsi@a0351000 { + dsi-controller@a0351000 { panel { compatible = "sony,acx424akp"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts new file mode 100644 index 000000000000..292ed5286652 --- /dev/null +++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Devicetree for the Samsung XCover 2 GT-S7710 also known as Skomer. + */ + +/dts-v1/; +#include "ste-db8500.dtsi" +#include "ste-ab8505.dtsi" +#include "ste-dbx5x0-pinctrl.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + model = "Samsung XCover 2 (GT-S7710)"; + compatible = "samsung,skomer", "st-ericsson,u8500"; + + chosen { + stdout-path = &serial2; + }; + + /* TI TXS0206 level translator for 2.9 V */ + sd_level_translator: regulator-gpio { + compatible = "regulator-fixed"; + + /* GPIO87 EN */ + gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>; + enable-active-high; + + regulator-name = "sd-level-translator"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-type = "voltage"; + + startup-delay-us = <200>; + + pinctrl-names = "default"; + pinctrl-0 = <&sd_level_translator_default>; + }; + + /* External LDO MIC5366-3.3YMT for eMMC */ + ldo_3v3_reg: regulator-gpio-ldo-3v3 { + compatible = "regulator-fixed"; + regulator-name = "en-3v3-fixed-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio6 31 GPIO_ACTIVE_HIGH>; + startup-delay-us = <5000>; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_ldo_en_default_mode>; + }; + + wlan_en: regulator-gpio-wlan-en { + compatible = "regulator-fixed"; + regulator-name = "wl-reg-on"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + startup-delay-us = <200000>; + /* GPIO215 WLAN_EN */ + gpio = <&gpio6 23 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&wlan_en_default_mode>; + }; + + vibrator { + compatible = "gpio-vibrator"; + enable-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_default>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys_default_mode>; + + button-home { + linux,code = <KEY_HOME>; + label = "HOME"; + /* GPIO91 */ + gpios = <&gpio2 27 GPIO_ACTIVE_LOW>; + }; + button-volup { + linux,code = <KEY_VOLUMEUP>; + label = "VOL+"; + /* GPIO67 */ + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; + }; + button-voldown { + linux,code = <KEY_VOLUMEDOWN>; + label = "VOL-"; + /* GPIO92 */ + gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + }; + button-menu { + linux,code = <KEY_MENU>; + label = "MENU"; + /* GPIO204 */ + gpios = <&gpio6 12 GPIO_ACTIVE_LOW>; + }; + button-back { + linux,code = <KEY_BACK>; + label = "BACK"; + /* GPIO205 */ + gpios = <&gpio6 13 GPIO_ACTIVE_LOW>; + }; + }; + + /* + * FIXME: this is not quite GPIO backlight. This is a + * KTD253 one-wire GPIO-controlled backlight. It can + * work as a GPIO backlight. + */ + gpio_bl: backlight { + compatible = "gpio-backlight"; + /* GPIO 69 */ + gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_backlight_default_mode>; + }; + + i2c-gpio-0 { + compatible = "i2c-gpio"; + sda-gpios = <&gpio4 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio4 15 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c_gpio_0_default>; + #address-cells = <1>; + #size-cells = <0>; + /* TODO: this should be used by the NCP6914 Camera power management unit */ + }; + + i2c-gpio-1 { + compatible = "i2c-gpio"; + sda-gpios = <&gpio4 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio4 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c_gpio_1_default>; + #address-cells = <1>; + #size-cells = <0>; + /* TODO: this should be used by the ALPS HSCDTD008A compass sensor */ + }; + + soc { + // External Micro SD slot + sdi0_per1@80126000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <4>; + cap-sd-highspeed; + cap-mmc-highspeed; + /* All direction control is used */ + st,sig-dir-cmd; + st,sig-dir-dat0; + st,sig-dir-dat2; + st,sig-dir-dat31; + st,sig-pin-fbclk; + full-pwr-cycle; + vmmc-supply = <&ab8500_ldo_aux3_reg>; + vqmmc-supply = <&sd_level_translator>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&mc0_a_1_default>; + pinctrl-1 = <&mc0_a_1_sleep>; + status = "okay"; + }; + + // WLAN SDIO channel + sdi1_per2@80118000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <50000000>; + bus-width = <4>; + non-removable; + cap-sd-highspeed; + vmmc-supply = <&wlan_en>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&mc1_a_2_default>; + pinctrl-1 = <&mc1_a_2_sleep>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + /* GPIO216 WL_HOST_WAKE */ + interrupt-parent = <&gpio6>; + interrupts = <24 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "host-wake"; + pinctrl-names = "default"; + pinctrl-0 = <&wlan_default_mode>; + }; + }; + + // eMMC + sdi2_per3@80005000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <8>; + non-removable; + cap-mmc-highspeed; + mmc-ddr-1_8v; + vmmc-supply = <&ldo_3v3_reg>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&mc2_a_1_default>; + pinctrl-1 = <&mc2_a_1_sleep>; + + status = "okay"; + }; + + /* GBF (Bluetooth) UART */ + uart@80120000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&u0_a_1_default>; + pinctrl-1 = <&u0_a_1_sleep>; + status = "okay"; + + /* FIXME: not quite working yet, probably needs regulators */ + bluetooth { + compatible = "brcm,bcm4330-bt"; + shutdown-gpios = <&gpio6 30 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&bluetooth_default_mode>; + }; + }; + + /* GPF UART */ + uart@80121000 { + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&u1rxtx_a_1_default &u1ctsrts_a_1_default>; + pinctrl-1 = <&u1rxtx_a_1_sleep &u1ctsrts_a_1_sleep>; + }; + + /* Debugging console UART connected to AB8505 USB */ + uart@80007000 { + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&u2rxtx_c_1_default>; + pinctrl-1 = <&u2rxtx_c_1_sleep>; + }; + + prcmu@80157000 { + ab8505 { + ab8500_usb { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&usb_a_1_default>; + pinctrl-1 = <&usb_a_1_sleep>; + }; + + ab8505-regulators { + ab8500_ldo_aux1 { + /* Used for VDD for sensors */ + regulator-name = "AUX1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + }; + + ab8500_ldo_aux2 { + /* Supplies the Cypress TMA140 touchscreen only with 3.3V */ + regulator-name = "AUX2"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ab8500_ldo_aux3 { + /* Used for voltage for external MMC/SD card */ + regulator-name = "AUX3"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <3300000>; + }; + + ab8500_ldo_aux4 { + regulator-name = "AUX4"; + /* Hammer to 3.0V for the display */ + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ab8500_ldo_aux5 { + regulator-name = "AUX5"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <2790000>; + regulator-always-on; + }; + + ab8500_ldo_aux6 { + regulator-name = "AUX6"; + /* Hammer to 1.8V for the display */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ab8500_ldo_aux8 { + /* Mostly VIO for sensors */ + regulator-name = "AUX8"; + }; + }; + }; + }; + + /* I2C0 */ + i2c@80004000 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c0_a_1_default>; + pinctrl-1 = <&i2c0_a_1_sleep>; + + proximity@44 { + compatible = "sharp,gp2ap002s00f"; + clock-frequency = <400000>; + reg = <0x44>; + + interrupt-parent = <&gpio4>; + interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + vio-supply = <&ab8500_ldo_aux8_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&gp2ap002_skomer_default>; + sharp,proximity-far-hysteresis = /bits/ 8 <0x2f>; + sharp,proximity-close-hysteresis = /bits/ 8 <0x0f>; + }; + }; + + + /* I2C2 */ + i2c@80128000 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c2_b_2_default>; + pinctrl-1 = <&i2c2_b_2_sleep>; + + accel@18 { + compatible = "bosch,bma254"; + clock-frequency = <400000>; + reg = <0x18>; + + /* GPIO224 used as "smart alert" interrupt */ + interrupt-parent = <&gpio7>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + + mount-matrix = "0", "1", "0", + "-1", "0", "0", + "0", "0", "1"; + vdd-supply = <&ab8500_ldo_aux1_reg>; + vddio-supply = <&ab8500_ldo_aux8_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&bma254_skomer_default>; + }; + }; + + /* I2C3 */ + i2c@80110000 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c3_c_2_default>; + pinctrl-1 = <&i2c3_c_2_sleep>; + + /* TODO: this should be used by the Cypress TMA140 touchscreen */ + }; + + mcde@a0350000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dsi_default_mode>; + + dsi-controller@a0351000 { + panel { + /* NT35510-based Hydis HVA40WV1 */ + compatible = "hydis,hva40wv1", "novatek,nt35510"; + reg = <0>; + /* v_lcd_3v0 2.3-4.8V */ + vdd-supply = <&ab8500_ldo_aux4_reg>; + /* v_lcd_1v8 1.65-3.3V */ + vddi-supply = <&ab8500_ldo_aux6_reg>; + /* GPIO 139 */ + reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&display_default_mode>; + backlight = <&gpio_bl>; + }; + }; + }; + }; +}; + +&pinctrl { + /* + * This extends the MC0 default config to include DAT32DIR + * which is used by this machine. If we don't do this the + * SD card does not work. + */ + sdi0 { + mc0_a_1_default { + default_mux { + function = "mc0"; + /* This machine uses the DAT31 pin */ + groups = "mc0_a_1", "mc0dat31dir_a_1"; + }; + default_cfg5 { + pins = "GPIO21_AB3"; /* DAT31DIR */ + ste,config = <&out_hi>; + }; + }; + }; + + mcde { + dsi_default_mode: dsi_default { + default_mux1 { + /* Mux in VSI0 used for DSI TE */ + function = "lcd"; + groups = "lcdvsi0_a_1"; /* VSI0 for LCD */ + }; + default_cfg1 { + pins = "GPIO68_E1"; /* VSI0 */ + ste,config = <&in_nopull>; + }; + }; + }; + + /* Two GPIO lines used by the display */ + display { + display_default_mode: display_default { + skomer_cfg1 { + /* + * OLED DETECT or check_pba, this appears to be high + * on "PBA" which I guess is "prototype board A". + */ + pins = "GPIO93_B7"; + ste,config = <&gpio_in_nopull>; + }; + skomer_cfg2 { + pins = "GPIO139_C9"; + /* + * MIPI_DSI0_RESET_N resets the display, leave high + * (de-asserted) so we only assert reset explicitly + * from the display driver. + */ + ste,config = <&gpio_out_hi>; + }; + }; + }; + backlight { + gpio_backlight_default_mode: backlight_default { + skomer_cfg1 { + pins = "GPIO69_E2"; /* LCD_BL_CTRL */ + ste,config = <&gpio_out_lo>; + }; + }; + }; + /* GPIO that enables the 2.9V SD card level translator */ + sd-level-translator { + sd_level_translator_default: sd_level_translator_default { + /* level shifter on GPIO87 */ + skomer_cfg1 { + pins = "GPIO87_B3"; + ste,config = <&gpio_out_hi>; + }; + }; + }; + /* GPIO that enables the LDO regulator for the eMMC */ + emmc-ldo { + emmc_ldo_en_default_mode: emmc_ldo_default { + /* LDO enable on GPIO223 */ + skomer_cfg1 { + pins = "GPIO223_AH9"; + ste,config = <&gpio_out_hi>; + }; + }; + }; + /* GPIO keys */ + gpio-keys { + gpio_keys_default_mode: gpio_keys_default { + skomer_cfg1 { + pins = "GPIO67_G2", /* VOL UP */ + "GPIO91_B6", /* HOME */ + "GPIO92_D6", /* VOL DOWN */ + "GPIO204_AF23", /* MENU */ + "GPIO205_AG23"; /* BACK */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + /* Interrupt line for BMA254 */ + bma254 { + bma254_skomer_default: bma254_skomer { + skomer_cfg1 { + pins = "GPIO224_AG9"; + ste,config = <&gpio_in_pd>; + }; + }; + }; + /* Interrupt line for light/proximity sensor GP2AP002 */ + gp2ap002 { + gp2ap002_skomer_default: gp2ap002_skomer { + skomer_cfg1 { + pins = "GPIO146_D13"; + ste,config = <&gpio_in_nopull>; + }; + }; + }; + /* GPIO-based I2C bus for NCP6914 */ + i2c-gpio-0 { + i2c_gpio_0_default: i2c_gpio_0 { + skomer_cfg1 { + pins = "GPIO143_D12", "GPIO144_B13"; + ste,config = <&gpio_in_nopull>; + }; + }; + }; + /* GPIO-based I2C bus for ALPS HSCD compass */ + i2c-gpio-1 { + i2c_gpio_1_default: i2c_gpio_1 { + skomer_cfg1 { + pins = "GPIO151_B17", "GPIO152_D16"; + ste,config = <&gpio_in_nopull>; + }; + }; + }; + wlan { + wlan_default_mode: wlan_default { + skomer_cfg1 { + pins = "GPIO216_AG12"; + ste,config = <&gpio_in_pd>; + }; + }; + wlan_en_default_mode: wlan_en_default { + skomer_cfg2 { + pins = "GPIO215_AH13"; + ste,config = <&gpio_out_lo>; + }; + }; + }; + bluetooth { + bluetooth_default_mode: bluetooth_default { + skomer_cfg1 { + pins = "GPIO199_AH23", "GPIO222_AJ9"; + ste,config = <&gpio_out_lo>; + }; + skomer_cfg2 { + pins = "GPIO97_D9"; + ste,config = <&gpio_in_nopull>; + }; + }; + }; + vibrator { + vibrator_default: vibrator_default { + skomer_cfg1 { + pins = "GPIO195_AG28"; /* MOT_EN */ + ste,config = <&gpio_out_lo>; + }; + }; + }; +}; + +&ab8505_gpio { + /* Hog a few default settings */ + pinctrl-names = "default"; + pinctrl-0 = <&gpio_default>; + + gpio { + gpio_default: gpio_default { + skomer_mux { + /* Change unused pins to GPIO mode */ + function = "gpio"; + groups = "gpio3_a_1", /* default: SysClkReq4 */ + "gpio14_a_1"; /* default: PWMOut1 */ + }; + skomer_cfg1 { + pins = "GPIO11_B17", "GPIO13_D17", "GPIO50_L4"; + bias-disable; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts index fcc804e3c158..4ea3f98dd275 100644 --- a/arch/arm/boot/dts/stm32746g-eval.dts +++ b/arch/arm/boot/dts/stm32746g-eval.dts @@ -165,7 +165,7 @@ interrupts = <8 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&gpioi>; - stmfx_pinctrl: stmfx-pin-controller { + stmfx_pinctrl: pinctrl { compatible = "st,stmfx-0300-pinctrl"; gpio-controller; #gpio-cells = <2>; diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi index 0237d4ddaa92..73c07f0dfad2 100644 --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi @@ -162,6 +162,40 @@ }; }; + ethernet0_rmii_pins_a: rmii-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */ + <STM32_PINMUX('G', 14, AF11)>, /* ETH1_RMII_TXD1 */ + <STM32_PINMUX('B', 11, AF11)>, /* ETH1_RMII_TX_EN */ + <STM32_PINMUX('A', 1, AF0)>, /* ETH1_RMII_REF_CLK */ + <STM32_PINMUX('A', 2, AF11)>, /* ETH1_MDIO */ + <STM32_PINMUX('C', 1, AF11)>; /* ETH1_MDC */ + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + pins2 { + pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RMII_RXD0 */ + <STM32_PINMUX('C', 5, AF11)>, /* ETH1_RMII_RXD1 */ + <STM32_PINMUX('A', 7, AF11)>; /* ETH1_RMII_CRS_DV */ + bias-disable; + }; + }; + + ethernet0_rmii_pins_sleep_a: rmii-sleep-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_RMII_TXD0 */ + <STM32_PINMUX('G', 14, ANALOG)>, /* ETH1_RMII_TXD1 */ + <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_RMII_TX_EN */ + <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */ + <STM32_PINMUX('C', 1, ANALOG)>, /* ETH1_MDC */ + <STM32_PINMUX('C', 4, ANALOG)>, /* ETH1_RMII_RXD0 */ + <STM32_PINMUX('C', 5, ANALOG)>, /* ETH1_RMII_RXD1 */ + <STM32_PINMUX('A', 1, ANALOG)>, /* ETH1_RMII_REF_CLK */ + <STM32_PINMUX('A', 7, ANALOG)>; /* ETH1_RMII_CRS_DV */ + }; + }; + fmc_pins_a: fmc-0 { pins1 { pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */ @@ -685,6 +719,26 @@ }; }; + + sai2a_pins_b: sai2a-2 { + pins1 { + pinmux = <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */ + <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */ + <STM32_PINMUX('D', 13, AF10)>; /* SAI2_SCK_A */ + slew-rate = <0>; + drive-push-pull; + bias-disable; + }; + }; + + sai2a_sleep_pins_b: sai2a-sleep-3 { + pins { + pinmux = <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */ + <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */ + <STM32_PINMUX('D', 13, ANALOG)>; /* SAI2_SCK_A */ + }; + }; + sai2b_pins_a: sai2b-0 { pins1 { pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */ @@ -1000,6 +1054,19 @@ }; }; + usart3_pins_a: usart3-0 { + pins1 { + pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */ + bias-disable; + }; + }; + uart4_pins_a: uart4-0 { pins1 { pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */ @@ -1040,6 +1107,32 @@ bias-disable; }; }; + + uart8_pins_a: uart8-0 { + pins1 { + pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 0, AF8)>; /* UART8_RX */ + bias-disable; + }; + }; + + usbotg_hs_pins_a: usbotg-hs-0 { + pins { + pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */ + }; + }; + + usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 { + pins { + pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* OTG_FS_DM */ + <STM32_PINMUX('A', 12, ANALOG)>; /* OTG_FS_DP */ + }; + }; }; &pinctrl_z { diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index fb41d0778b00..3ea05ba48215 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -17,6 +17,7 @@ cpu0: cpu@0 { compatible = "arm,cortex-a7"; + clock-frequency = <650000000>; device_type = "cpu"; reg = <0>; }; @@ -483,6 +484,7 @@ resets = <&rcc I2C1_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; @@ -496,6 +498,7 @@ resets = <&rcc I2C2_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; @@ -509,6 +512,7 @@ resets = <&rcc I2C3_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; @@ -522,6 +526,7 @@ resets = <&rcc I2C5_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; @@ -959,6 +964,7 @@ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc DMA1>; + resets = <&rcc DMA1_R>; #dma-cells = <4>; st,mem2mem; dma-requests = <8>; @@ -976,6 +982,7 @@ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc DMA2>; + resets = <&rcc DMA2_R>; #dma-cells = <4>; st,mem2mem; dma-requests = <8>; @@ -989,6 +996,7 @@ dma-masters = <&dma1 &dma2>; dma-channels = <16>; clocks = <&rcc DMAMUX>; + resets = <&rcc DMAMUX_R>; }; adc: adc@48003000 { @@ -1044,7 +1052,7 @@ }; usbotg_hs: usb-otg@49000000 { - compatible = "snps,dwc2"; + compatible = "st,stm32mp15-hsotg", "snps,dwc2"; reg = <0x49000000 0x10000>; clocks = <&rcc USBO_K>; clock-names = "otg"; @@ -1055,6 +1063,7 @@ g-np-tx-fifo-size = <32>; g-tx-fifo-size = <128 128 64 64 64 64 32 32>; dr_mode = "otg"; + usb33d-supply = <&usb33>; status = "disabled"; }; @@ -1280,6 +1289,7 @@ reg = <0x58000000 0x1000>; interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc MDMA>; + resets = <&rcc MDMA_R>; #dma-cells = <5>; dma-channels = <32>; dma-requests = <48>; @@ -1369,10 +1379,12 @@ clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", + "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, + <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; @@ -1473,6 +1485,7 @@ resets = <&rcc I2C4_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; @@ -1508,6 +1521,7 @@ resets = <&rcc I2C6_R>; #address-cells = <1>; #size-cells = <0>; + wakeup-source; status = "disabled"; }; diff --git a/arch/arm/boot/dts/stm32mp153.dtsi b/arch/arm/boot/dts/stm32mp153.dtsi index 2d759fc6015c..6d9ab08667fc 100644 --- a/arch/arm/boot/dts/stm32mp153.dtsi +++ b/arch/arm/boot/dts/stm32mp153.dtsi @@ -10,6 +10,7 @@ cpus { cpu1: cpu@1 { compatible = "arm,cortex-a7"; + clock-frequency = <650000000>; device_type = "cpu"; reg = <1>; }; diff --git a/arch/arm/boot/dts/stm32mp157a-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-avenger96.dts index cbfa4075907e..425175f7d83c 100644 --- a/arch/arm/boot/dts/stm32mp157a-avenger96.dts +++ b/arch/arm/boot/dts/stm32mp157a-avenger96.dts @@ -135,10 +135,6 @@ #interrupt-cells = <2>; status = "okay"; - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; - st,usb-control-register = <0x30>; - regulators { compatible = "st,stpmic1-regulators"; @@ -173,7 +169,6 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; - st,mask_reset; regulator-initial-mode = <0>; regulator-over-current-protection; }; @@ -213,8 +208,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = <IT_CURLIM_LDO4 0>; interrupt-parent = <&pmic>; }; @@ -240,7 +233,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -300,7 +292,8 @@ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; pinctrl-1 = <&sdmmc1_b4_od_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; - broken-cd; + cd-gpios = <&gpioi 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; st,sig-dir; st,neg-edge; st,use-ckin; diff --git a/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts b/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts new file mode 100644 index 000000000000..af99e132e1b1 --- /dev/null +++ b/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019 Marek Vasut <marex@denx.de> + */ + +#include "stm32mp157c-dhcom-som.dtsi" +#include <dt-bindings/pwm/pwm.h> + +/ { + model = "STMicroelectronics STM32MP157C DHCOM Premium Developer Kit (2)"; + compatible = "dh,stm32mp157c-dhcom-pdk2", "st,stm32mp157"; + + aliases { + serial0 = &uart4; + serial1 = &usart3; + serial2 = &uart8; + ethernet0 = ðernet0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clk_ext_audio_codec: clock-codec { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + + display_bl: display-bl { + compatible = "pwm-backlight"; + pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>; + brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>; + default-brightness-level = <8>; + enable-gpios = <&gpioi 0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + ethernet_vio: vioregulator { + compatible = "regulator-fixed"; + regulator-name = "vio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpiog 3 GPIO_ACTIVE_LOW>; + regulator-always-on; + regulator-boot-on; + }; + + panel { + compatible = "edt,etm0700g0edh6"; + backlight = <&display_bl>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; + + sound { + compatible = "audio-graph-card"; + routing = + "MIC_IN", "Capture", + "Capture", "Mic Bias", + "Playback", "HP_OUT"; + dais = <&sai2a_port &sai2b_port>; + status = "okay"; + }; +}; + +&cec { + pinctrl-names = "default"; + pinctrl-0 = <&cec_pins_a>; + status = "okay"; +}; + +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_rmii_pins_a>; + pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; + pinctrl-names = "default", "sleep"; + phy-mode = "rmii"; + max-speed = <100>; + phy-handle = <&phy0>; + st,eth-ref-clk-sel; + phy-reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy0: ethernet-phy@1 { + reg = <1>; + }; + }; +}; + +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /* spare dmas for other usage */ + /delete-property/dmas; + /delete-property/dma-names; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + #sound-dai-cells = <0>; + clocks = <&clk_ext_audio_codec>; + VDDA-supply = <&v3v3>; + VDDIO-supply = <&vdd>; + + sgtl5000_port: port { + #address-cells = <1>; + #size-cells = <0>; + + sgtl5000_tx_endpoint: endpoint@0 { + reg = <0>; + remote-endpoint = <&sai2a_endpoint>; + frame-master; + bitclock-master; + }; + + sgtl5000_rx_endpoint: endpoint@1 { + reg = <1>; + remote-endpoint = <&sai2b_endpoint>; + frame-master; + bitclock-master; + }; + }; + + }; + + polytouch@38 { + compatible = "edt,edt-ft5x06"; + reg = <0x38>; + interrupt-parent = <&gpiog>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */ + linux,wakeup; + }; +}; + +<dc { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <<dc_pins_b>; + pinctrl-1 = <<dc_pins_sleep_b>; + status = "okay"; + + port { + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; +}; + +&m_can1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&m_can1_pins_a>; + pinctrl-1 = <&m_can1_sleep_pins_a>; + status = "okay"; +}; + +&sai2 { + clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; + clock-names = "pclk", "x8k", "x11k"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sai2a_pins_b &sai2b_pins_b>; + pinctrl-1 = <&sai2a_sleep_pins_b &sai2b_sleep_pins_b>; + status = "okay"; + + sai2a: audio-controller@4400b004 { + #clock-cells = <0>; + dma-names = "tx"; + clocks = <&rcc SAI2_K>; + clock-names = "sai_ck"; + status = "okay"; + + sai2a_port: port { + sai2a_endpoint: endpoint { + remote-endpoint = <&sgtl5000_tx_endpoint>; + format = "i2s"; + mclk-fs = <512>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <16>; + }; + }; + }; + + sai2b: audio-controller@4400b024 { + dma-names = "rx"; + st,sync = <&sai2a 2>; + clocks = <&rcc SAI2_K>, <&sai2a>; + clock-names = "sai_ck", "MCLK"; + status = "okay"; + + sai2b_port: port { + sai2b_endpoint: endpoint { + remote-endpoint = <&sgtl5000_rx_endpoint>; + format = "i2s"; + mclk-fs = <512>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <16>; + }; + }; + }; +}; + +&timers2 { + /* spare dmas for other usage (un-delete to enable pwm capture) */ + /delete-property/dmas; + /delete-property/dma-names; + status = "okay"; + pwm2: pwm { + pinctrl-0 = <&pwm2_pins_a>; + pinctrl-names = "default"; + status = "okay"; + }; + timer@1 { + status = "okay"; + }; +}; + +&usart3 { + pinctrl-names = "default"; + pinctrl-0 = <&usart3_pins_a>; + status = "okay"; +}; + +&uart8 { + pinctrl-names = "default"; + pinctrl-0 = <&uart8_pins_a>; + status = "okay"; +}; + +&usbh_ehci { + phys = <&usbphyc_port0>; + status = "okay"; +}; + +&usbotg_hs { + dr_mode = "peripheral"; + phys = <&usbphyc_port1 0>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usbphyc { + status = "okay"; +}; + +&usbphyc_port0 { + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; +}; + +&usbphyc_port1 { + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; +}; diff --git a/arch/arm/boot/dts/stm32mp157c-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp157c-dhcom-som.dtsi new file mode 100644 index 000000000000..f81dc3134135 --- /dev/null +++ b/arch/arm/boot/dts/stm32mp157c-dhcom-som.dtsi @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) 2019 Marek Vasut <marex@denx.de> + */ +/dts-v1/; + +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxaa-pinctrl.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/mfd/st,stpmic1.h> + +/ { + memory@c0000000 { + device_type = "memory"; + reg = <0xC0000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mcuram2: mcuram2@10000000 { + compatible = "shared-dma-pool"; + reg = <0x10000000 0x40000>; + no-map; + }; + + vdev0vring0: vdev0vring0@10040000 { + compatible = "shared-dma-pool"; + reg = <0x10040000 0x1000>; + no-map; + }; + + vdev0vring1: vdev0vring1@10041000 { + compatible = "shared-dma-pool"; + reg = <0x10041000 0x1000>; + no-map; + }; + + vdev0buffer: vdev0buffer@10042000 { + compatible = "shared-dma-pool"; + reg = <0x10042000 0x4000>; + no-map; + }; + + mcuram: mcuram@30000000 { + compatible = "shared-dma-pool"; + reg = <0x30000000 0x40000>; + no-map; + }; + + retram: retram@38000000 { + compatible = "shared-dma-pool"; + reg = <0x38000000 0x10000>; + no-map; + }; + }; +}; + +&adc { + vdd-supply = <&vdd>; + vdda-supply = <&vdda>; + vref-supply = <&vdda>; + status = "okay"; + + adc1: adc@0 { + st,min-sample-time-nsecs = <5000>; + st,adc-channels = <0>; + status = "okay"; + }; + + adc2: adc@100 { + st,adc-channels = <1>; + st,min-sample-time-nsecs = <5000>; + status = "okay"; + }; +}; + +&dac { + pinctrl-names = "default"; + pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; + vref-supply = <&vdda>; + status = "okay"; + + dac1: dac@1 { + status = "okay"; + }; + dac2: dac@2 { + status = "okay"; + }; +}; + +&dts { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /* spare dmas for other usage */ + /delete-property/dmas; + /delete-property/dma-names; + + rtc@32 { + compatible = "microcrystal,rv8803"; + reg = <0x32>; + }; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; + reg = <0x33>; + interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + status = "okay"; + + regulators { + compatible = "st,stpmic1-regulators"; + ldo1-supply = <&v3v3>; + ldo2-supply = <&v3v3>; + ldo3-supply = <&vdd_ddr>; + ldo5-supply = <&v3v3>; + ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; + + vddcore: buck1 { + regulator-name = "vddcore"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd_ddr: buck2 { + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd: buck3 { + regulator-name = "vdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + v3v3: buck4 { + regulator-name = "v3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; + }; + + vdda: ldo1 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + interrupts = <IT_CURLIM_LDO1 0>; + }; + + v2v8: ldo2 { + regulator-name = "v2v8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + interrupts = <IT_CURLIM_LDO2 0>; + }; + + vtt_ddr: ldo3 { + regulator-name = "vtt_ddr"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + interrupts = <IT_CURLIM_LDO4 0>; + }; + + vdd_sd: ldo5 { + regulator-name = "vdd_sd"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + interrupts = <IT_CURLIM_LDO5 0>; + regulator-boot-on; + }; + + v1v8: ldo6 { + regulator-name = "v1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + interrupts = <IT_CURLIM_LDO6 0>; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; + }; + + bst_out: boost { + regulator-name = "bst_out"; + interrupts = <IT_OCP_BOOST 0>; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + interrupts = <IT_OCP_OTG 0>; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + interrupts = <IT_OCP_SWOUT 0>; + regulator-active-discharge; + }; + }; + + onkey { + compatible = "st,stpmic1-onkey"; + interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>; + interrupt-names = "onkey-falling", "onkey-rising"; + power-off-time-sec = <10>; + status = "okay"; + }; + + watchdog { + compatible = "st,stpmic1-wdt"; + status = "disabled"; + }; + }; + + touchscreen@49 { + compatible = "ti,tsc2004"; + reg = <0x49>; + vio-supply = <&v3v3>; + interrupts-extended = <&gpioh 3 IRQ_TYPE_EDGE_FALLING>; + }; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&ipcc { + status = "okay"; +}; + +&iwdg2 { + timeout-sec = <32>; + status = "okay"; +}; + +&m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, + <&vdev0vring1>, <&vdev0buffer>; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; + mbox-names = "vq0", "vq1", "shutdown"; + interrupt-parent = <&exti>; + interrupts = <68 1>; + status = "okay"; +}; + +&pwr_regulators { + vdd-supply = <&vdd>; + vdd_3v3_usbfs-supply = <&vdd_usb>; +}; + +&qspi { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; + reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + flash0: mx66l51235l@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc1 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; + pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; + broken-cd; + st,sig-dir; + st,neg-edge; + st,use-ckin; + bus-width = <4>; + vmmc-supply = <&vdd_sd>; + status = "okay"; +}; + +&sdmmc2 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + vmmc-supply = <&v3v3>; + vqmmc-supply = <&v3v3>; + mmc-ddr-3_3v; + status = "okay"; +}; + +&sdmmc3 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc3_b4_pins_a>; + pinctrl-1 = <&sdmmc3_b4_od_pins_a>; + pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; + broken-cd; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&v3v3>; + vqmmc-supply = <&v3v3>; + mmc-ddr-3_3v; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts index 1fc43251d697..9d2592db630c 100644 --- a/arch/arm/boot/dts/stm32mp157c-ed1.dts +++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts @@ -130,10 +130,12 @@ }; &i2c4 { - pinctrl-names = "default"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c4_pins_a>; + pinctrl-1 = <&i2c4_pins_sleep_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; + clock-frequency = <400000>; status = "okay"; /* spare dmas for other usage */ /delete-property/dmas; @@ -218,8 +220,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = <IT_CURLIM_LDO4 0>; }; @@ -241,7 +241,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -313,7 +312,8 @@ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; - broken-cd; + cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; st,sig-dir; st,neg-edge; st,use-ckin; @@ -334,7 +334,7 @@ st,neg-edge; bus-width = <8>; vmmc-supply = <&v3v3>; - vqmmc-supply = <&v3v3>; + vqmmc-supply = <&vdd>; mmc-ddr-3_3v; status = "okay"; }; @@ -355,6 +355,10 @@ status = "okay"; }; +&usbotg_hs { + vbus-supply = <&vbus_otg>; +}; + &usbphyc_port0 { phy-supply = <&vdd_usb>; vdda1v1-supply = <®11>; diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts index 228e35e16884..8a4c7ff31a92 100644 --- a/arch/arm/boot/dts/stm32mp157c-ev1.dts +++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts @@ -174,8 +174,9 @@ }; &i2c2 { - pinctrl-names = "default"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c2_pins_a>; + pinctrl-1 = <&i2c2_pins_sleep_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; status = "okay"; @@ -210,7 +211,7 @@ interrupt-parent = <&gpioi>; vdd-supply = <&v3v3>; - stmfx_pinctrl: stmfx-pin-controller { + stmfx_pinctrl: pinctrl { compatible = "st,stmfx-0300-pinctrl"; gpio-controller; #gpio-cells = <2>; @@ -218,7 +219,7 @@ #interrupt-cells = <2>; gpio-ranges = <&stmfx_pinctrl 0 0 24>; - joystick_pins: joystick { + joystick_pins: joystick-pins { pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; bias-pull-down; }; @@ -227,8 +228,9 @@ }; &i2c5 { - pinctrl-names = "default"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c5_pins_a>; + pinctrl-1 = <&i2c5_pins_sleep_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; status = "okay"; @@ -353,7 +355,8 @@ }; &usbotg_hs { - dr_mode = "peripheral"; + pinctrl-0 = <&usbotg_hs_pins_a>; + pinctrl-names = "default"; phys = <&usbphyc_port1 0>; phy-names = "usb2-phy"; status = "okay"; diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index f6672e87aef3..d946e0a02f5c 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -216,10 +216,12 @@ }; &i2c4 { - pinctrl-names = "default"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c4_pins_a>; + pinctrl-1 = <&i2c4_pins_sleep_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; + clock-frequency = <400000>; status = "okay"; /* spare dmas for other usage */ /delete-property/dmas; @@ -304,8 +306,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = <IT_CURLIM_LDO4 0>; }; @@ -328,7 +328,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -479,7 +478,8 @@ pinctrl-0 = <&sdmmc1_b4_pins_a>; pinctrl-1 = <&sdmmc1_b4_od_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; - broken-cd; + cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; st,neg-edge; bus-width = <4>; vmmc-supply = <&v3v3>; diff --git a/arch/arm/boot/dts/sun5i-a13-pocketbook-touch-lux-3.dts b/arch/arm/boot/dts/sun5i-a13-pocketbook-touch-lux-3.dts new file mode 100644 index 000000000000..e9ef97c9c893 --- /dev/null +++ b/arch/arm/boot/dts/sun5i-a13-pocketbook-touch-lux-3.dts @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright 2019 Ondrej Jirman <megous@megous.com> + */ + +/dts-v1/; +#include "sun5i-a13.dtsi" +#include "sunxi-common-regulators.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pwm/pwm.h> + +/ { + model = "PocketBook Touch Lux 3"; + compatible = "pocketbook,touch-lux-3", "allwinner,sun5i-a13"; + + aliases { + serial0 = &uart1; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; + enable-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ + brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; + default-brightness-level = <8>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + power { + gpios = <&pio 4 8 GPIO_ACTIVE_LOW>; /* PE8 */ + default-state = "on"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + label = "GPIO Keys"; + + key-right { + label = "Right"; + linux,code = <KEY_RIGHT>; + gpios = <&pio 6 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PG9 */ + }; + + key-left { + label = "Left"; + linux,code = <KEY_LEFT>; + gpios = <&pio 6 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PG10 */ + }; + }; + + reg_1v8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd-1v8-nor-ctp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&pio 2 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_1v8_nor: regulator-nor { + compatible = "regulator-fixed"; + regulator-name = "vdd-nor"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&pio 2 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <®_1v8>; + regulator-always-on; + }; + + reg_1v8_ctp: regulator-ctp { + compatible = "regulator-fixed"; + regulator-name = "vdd-ctp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&pio 2 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <®_1v8>; + }; + + reg_3v3_mmc0: regulator-mmc0 { + compatible = "regulator-fixed"; + regulator-name = "vdd-mmc0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pio 4 4 GPIO_ACTIVE_LOW>; /* PE4 */ + vin-supply = <®_vcc3v3>; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + interrupts = <0>; + }; +}; + +#include "axp209.dtsi" + +&i2c1 { + status = "okay"; + + pcf8563: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +}; + +&i2c2 { + status = "okay"; + + /* Touchpanel is connected here. */ +}; + +&lradc { + vref-supply = <®_ldo2>; + status = "okay"; + + button-200 { + label = "Home"; + linux,code = <KEY_HOME>; + channel = <0>; + voltage = <200000>; + }; + + button-400 { + label = "Menu"; + linux,code = <KEY_MENU>; + channel = <0>; + voltage = <400000>; + }; +}; + +&mmc0 { + vmmc-supply = <®_3v3_mmc0>; + bus-width = <4>; + cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */ + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_4bit_pc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&otg_sram { + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + status = "okay"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd-int-pll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_ldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; + /* We need this otherwise the LDO3 would overload */ + regulator-soft-start; + regulator-ramp-delay = <1600>; +}; + +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pe_pins>, <&spi2_cs0_pe_pin>; + status = "okay"; + + epd_flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "macronix,mx25u4033", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <4000000>; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pg_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&battery_power_supply { + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_ldo3>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi index 0b526e6e5a95..e6b036734a64 100644 --- a/arch/arm/boot/dts/sun5i.dtsi +++ b/arch/arm/boot/dts/sun5i.dtsi @@ -186,6 +186,8 @@ compatible = "allwinner,sun5i-a13-mbus"; reg = <0x01c01000 0x1000>; clocks = <&ccu CLK_MBUS>; + #address-cells = <1>; + #size-cells = <1>; dma-ranges = <0x00000000 0x40000000 0x20000000>; #interconnect-cells = <1>; }; @@ -771,9 +773,6 @@ interconnect-names = "dma-mem"; status = "disabled"; - assigned-clocks = <&ccu CLK_DE_BE>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 7762fbd9a133..f3425a66fc0a 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -1139,9 +1139,6 @@ "ram"; resets = <&ccu RST_AHB1_BE1>; - assigned-clocks = <&ccu CLK_BE1>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; @@ -1185,9 +1182,6 @@ "ram"; resets = <&ccu RST_AHB1_DRC1>; - assigned-clocks = <&ccu CLK_IEP_DRC1>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; @@ -1231,9 +1225,6 @@ "ram"; resets = <&ccu RST_AHB1_BE0>; - assigned-clocks = <&ccu CLK_BE0>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; @@ -1274,9 +1265,6 @@ "ram"; resets = <&ccu RST_AHB1_DRC0>; - assigned-clocks = <&ccu CLK_IEP_DRC0>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun7i-a20-linutronix-testbox-v2.dts b/arch/arm/boot/dts/sun7i-a20-linutronix-testbox-v2.dts new file mode 100644 index 000000000000..da5a2eea4ce3 --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-linutronix-testbox-v2.dts @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2020 Linutronix GmbH + * Author: Benedikt Spranger <b.spranger@linutronix.de> + */ + +/dts-v1/; +#include "sun7i-a20-lamobo-r1.dts" + +/ { + model = "Lamobo R1"; + compatible = "linutronix,testbox-v2", "lamobo,lamobo-r1", "allwinner,sun7i-a20"; + + leds { + led-opto1 { + label = "lamobo_r1:opto:powerswitch"; + gpios = <&pio 7 3 GPIO_ACTIVE_HIGH>; + }; + + led-opto2 { + label = "lamobo_r1:opto:relay"; + gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + status = "okay"; + + eeprom: eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + status = "okay"; + }; + + atecc508a@60 { + compatible = "atmel,atecc508a"; + reg = <0x60>; + }; +}; + +&can0 { + pinctrl-names = "default"; + pinctrl-0 = <&can_ph_pins>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 92b5be97085d..ffe1d10a1a84 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/dma/sun4i-a10.h> #include <dt-bindings/clock/sun7i-a20-ccu.h> #include <dt-bindings/reset/sun4i-a10-ccu.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> / { interrupt-parent = <&gic>; @@ -404,11 +405,12 @@ }; tcon0: lcd-controller@1c0c000 { - compatible = "allwinner,sun7i-a20-tcon"; + compatible = "allwinner,sun7i-a20-tcon0", + "allwinner,sun7i-a20-tcon"; reg = <0x01c0c000 0x1000>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - resets = <&ccu RST_TCON0>; - reset-names = "lcd"; + resets = <&ccu RST_TCON0>, <&ccu RST_LVDS>; + reset-names = "lcd", "lvds"; clocks = <&ccu CLK_AHB_LCD0>, <&ccu CLK_TCON0_CH0>, <&ccu CLK_TCON0_CH1>; @@ -454,7 +456,8 @@ }; tcon1: lcd-controller@1c0d000 { - compatible = "allwinner,sun7i-a20-tcon"; + compatible = "allwinner,sun7i-a20-tcon1", + "allwinner,sun7i-a20-tcon"; reg = <0x01c0d000 0x1000>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; resets = <&ccu RST_TCON1>; @@ -932,6 +935,20 @@ }; /omit-if-no-ref/ + lcd_lvds0_pins: lcd-lvds0-pins { + pins = "PD0", "PD1", "PD2", "PD3", "PD4", + "PD5", "PD6", "PD7", "PD8", "PD9"; + function = "lvds0"; + }; + + /omit-if-no-ref/ + lcd_lvds1_pins: lcd-lvds1-pins { + pins = "PD10", "PD11", "PD12", "PD13", "PD14", + "PD15", "PD16", "PD17", "PD18", "PD19"; + function = "lvds1"; + }; + + /omit-if-no-ref/ mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index 48487f6d4ab9..c1362d0f0ff8 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -684,9 +684,6 @@ clock-names = "ahb", "mod", "ram"; resets = <&ccu RST_BUS_DRC>; - assigned-clocks = <&ccu CLK_DRC>; - assigned-clock-rates = <300000000>; - ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index a2c37adacf77..cfd3858afb3e 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -372,8 +372,6 @@ "ram", "sat"; resets = <&ccu RST_BUS_DE_BE>, <&ccu RST_BUS_SAT>; reset-names = "be", "sat"; - assigned-clocks = <&ccu CLK_DE_BE>; - assigned-clock-rates = <300000000>; }; &ccu { diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts index e8b3669e0e5d..bfc9bb277a49 100644 --- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts +++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts @@ -493,7 +493,6 @@ }; &usb_otg { - dr_mode = "otg"; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index e7b9bef1be6b..655404d6d3a3 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -72,7 +72,7 @@ #cooling-cells = <2>; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C0CPUX>; @@ -83,7 +83,7 @@ #cooling-cells = <2>; }; - cpu@2 { + cpu2: cpu@2 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C0CPUX>; @@ -94,7 +94,7 @@ #cooling-cells = <2>; }; - cpu@3 { + cpu3: cpu@3 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C0CPUX>; @@ -116,7 +116,7 @@ #cooling-cells = <2>; }; - cpu@101 { + cpu101: cpu@101 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C1CPUX>; @@ -127,7 +127,7 @@ #cooling-cells = <2>; }; - cpu@102 { + cpu102: cpu@102 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C1CPUX>; @@ -138,7 +138,7 @@ #cooling-cells = <2>; }; - cpu@103 { + cpu103: cpu@103 { compatible = "arm,cortex-a7"; device_type = "cpu"; clocks = <&ccu CLK_C1CPUX>; @@ -314,7 +314,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-a83t-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_PLL_DE>; clock-names = "bus", @@ -324,6 +324,17 @@ #reset-cells = <1>; }; + rotate: rotate@1020000 { + compatible = "allwinner,sun8i-a83t-de2-rotate"; + reg = <0x1020000 0x10000>; + interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&display_clocks CLK_BUS_ROT>, + <&display_clocks CLK_ROT>; + clock-names = "bus", + "mod"; + resets = <&display_clocks RST_ROT>; + }; + mixer0: mixer@1100000 { compatible = "allwinner,sun8i-a83t-de2-mixer-0"; reg = <0x01100000 0x100000>; @@ -1188,12 +1199,60 @@ polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 0>; + + trips { + cpu0_hot: cpu-hot { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu0_very_hot: cpu-very-hot { + temperature = <100000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + cpu-hot-limit { + trip = <&cpu0_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; cpu1_thermal: cpu1-thermal { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 1>; + + trips { + cpu1_hot: cpu-hot { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu1_very_hot: cpu-very-hot { + temperature = <100000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + cpu-hot-limit { + trip = <&cpu1_hot>; + cooling-device = <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpu_thermal: gpu-thermal { diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi index 20217e2ca4d3..e83aa6866e7e 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi @@ -41,6 +41,7 @@ */ #include "sunxi-h3-h5.dtsi" +#include <dt-bindings/thermal/thermal.h> / { cpu0_opp_table: opp_table0 { @@ -227,6 +228,30 @@ polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 0>; + + trips { + cpu_hot_trip: cpu-hot { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_very_hot_trip: cpu-very-hot { + temperature = <100000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + cpu-hot-limit { + trip = <&cpu_hot_trip>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi index a9d5d6ddbd71..b782041e0e04 100644 --- a/arch/arm/boot/dts/sun8i-r40.dtsi +++ b/arch/arm/boot/dts/sun8i-r40.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/clock/sun8i-tcon-top.h> #include <dt-bindings/reset/sun8i-r40-ccu.h> #include <dt-bindings/reset/sun8i-de2.h> +#include <dt-bindings/thermal/thermal.h> / { #address-cells = <1>; @@ -110,6 +111,22 @@ status = "disabled"; }; + thermal-zones { + cpu_thermal: cpu0-thermal { + /* milliseconds */ + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&ths 0>; + }; + + gpu_thermal: gpu-thermal { + /* milliseconds */ + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&ths 1>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; @@ -119,7 +136,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-r40-de2-clk", "allwinner,sun8i-h3-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -562,6 +579,17 @@ clocks = <&osc24M>; }; + ths: thermal-sensor@1c24c00 { + compatible = "allwinner,sun8i-r40-ths"; + reg = <0x01c24c00 0x100>; + clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; + clock-names = "bus", "mod"; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ccu RST_BUS_THS>; + /* TODO: add nvmem-cells for calibration */ + #thermal-sensor-cells = <1>; + }; + uart0: serial@1c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; @@ -738,6 +766,8 @@ compatible = "allwinner,sun8i-r40-mbus"; reg = <0x01c62000 0x1000>; clocks = <&ccu 155>; + #address-cells = <1>; + #size-cells = <1>; dma-ranges = <0x00000000 0x40000000 0x80000000>; #interconnect-cells = <1>; }; diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi index 81ea50838cd5..e5312869c0d2 100644 --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -105,7 +105,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-v3s-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 5e9c3060aa08..01a5df9aa71b 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -114,7 +114,7 @@ display_clocks: clock@1000000 { /* compatible is in per SoC .dtsi file */ - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -560,6 +560,8 @@ compatible = "allwinner,sun8i-h3-mbus"; reg = <0x01c62000 0x1000>; clocks = <&ccu CLK_MBUS>; + #address-cells = <1>; + #size-cells = <1>; dma-ranges = <0x00000000 0x40000000 0xc0000000>; #interconnect-cells = <1>; }; @@ -892,6 +894,21 @@ pins = "PL0", "PL1"; function = "s_i2c"; }; + + r_pwm_pin: r-pwm-pin { + pins = "PL10"; + function = "s_pwm"; + }; + }; + + r_pwm: pwm@1f03800 { + compatible = "allwinner,sun8i-h3-pwm"; + reg = <0x01f03800 0x8>; + pinctrl-names = "default"; + pinctrl-0 = <&r_pwm_pin>; + clocks = <&osc24M>; + #pwm-cells = <3>; + status = "disabled"; }; }; }; diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 97a5c3504bbe..d3e032e7d21a 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -1296,7 +1296,13 @@ clocks = <&tegra_car TEGRA114_CLK_PLL_A>, <&tegra_car TEGRA114_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA114_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA114_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA114_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA114_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 0d7a6327e404..450a1f1b12a0 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -4,6 +4,7 @@ #include <dt-bindings/memory/tegra114-mc.h> #include <dt-bindings/pinctrl/pinctrl-tegra.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra114"; @@ -514,11 +515,12 @@ status = "disabled"; }; - pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra114-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; }; fuse@7000f800 { diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi index 0462ed2dd8b8..de499f736bda 100644 --- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi @@ -2009,8 +2009,14 @@ nvidia,audio-codec = <&sgtl5000>; clocks = <&tegra_car TEGRA124_CLK_PLL_A>, <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA124_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA124_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; }; thermal-zones { diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi b/arch/arm/boot/dts/tegra124-apalis.dtsi index d1e8593ef0d9..d70a86da4ee4 100644 --- a/arch/arm/boot/dts/tegra124-apalis.dtsi +++ b/arch/arm/boot/dts/tegra124-apalis.dtsi @@ -2001,8 +2001,14 @@ nvidia,audio-codec = <&sgtl5000>; clocks = <&tegra_car TEGRA124_CLK_PLL_A>, <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA124_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA124_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; }; thermal-zones { diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index d5fd642f8b77..1b567e2d5ce0 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -1782,12 +1782,6 @@ }; ports { - /* Micro A/B */ - usb2-0 { - status = "okay"; - mode = "otg"; - }; - /* Mini PCIe */ usb2-1 { status = "okay"; @@ -2058,8 +2052,14 @@ clocks = <&tegra_car TEGRA124_CLK_PLL_A>, <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA124_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA124_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; }; thermal-zones { diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi index 3b10f475037f..9b1af50cd4b8 100644 --- a/arch/arm/boot/dts/tegra124-nyan.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan.dtsi @@ -788,9 +788,15 @@ clocks = <&tegra_car TEGRA124_CLK_PLL_A>, <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA124_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + assigned-clocks = <&tegra_car TEGRA124_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(I, 7) GPIO_ACTIVE_HIGH>; nvidia,mic-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts index 7309393bfced..8c2ee6e7d6f1 100644 --- a/arch/arm/boot/dts/tegra124-venice2.dts +++ b/arch/arm/boot/dts/tegra124-venice2.dts @@ -1266,8 +1266,14 @@ clocks = <&tegra_car TEGRA124_CLK_PLL_A>, <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA124_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA124_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 7f330b1f150f..94cac13d3e50 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -6,6 +6,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/reset/tegra124-car.h> #include <dt-bindings/thermal/tegra124-soctherm.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra124"; @@ -595,11 +596,12 @@ clocks = <&tegra_car TEGRA124_CLK_RTC>; }; - pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra124-pmc"; reg = <0x0 0x7000e400 0x0 0x400>; clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; }; fuse@7000f800 { diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 9c58e7fcf5c0..c3b8ad53b967 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -4,6 +4,7 @@ #include <dt-bindings/memory/tegra20-mc.h> #include <dt-bindings/pinctrl/pinctrl-tegra.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra20"; @@ -608,11 +609,12 @@ status = "disabled"; }; - pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; }; mc: memory-controller@7000f000 { diff --git a/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi b/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi index 8b7a827d604d..387b17458e22 100644 --- a/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi +++ b/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi @@ -1189,7 +1189,13 @@ nvidia,audio-codec = <&sgtl5000>; clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA30_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi index c18f6f61d764..6648506f3aa4 100644 --- a/arch/arm/boot/dts/tegra30-apalis.dtsi +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi @@ -1171,7 +1171,13 @@ nvidia,audio-codec = <&sgtl5000>; clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA30_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts index a3b0f3555cd2..45ef6002b225 100644 --- a/arch/arm/boot/dts/tegra30-beaver.dts +++ b/arch/arm/boot/dts/tegra30-beaver.dts @@ -2111,7 +2111,13 @@ clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA30_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index 7ce61edd52f5..4b4f49a49394 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -619,8 +619,14 @@ clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA30_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; }; gpio-keys { diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi index 1f9198bb24ff..adba554381c7 100644 --- a/arch/arm/boot/dts/tegra30-colibri.dtsi +++ b/arch/arm/boot/dts/tegra30-colibri.dtsi @@ -1030,8 +1030,14 @@ nvidia,audio-codec = <&sgtl5000>; clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, - <&tegra_car TEGRA30_CLK_EXTERN1>; + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; clock-names = "pll_a", "pll_a_out0", "mclk"; + + assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>, + <&tegra_pmc TEGRA_PMC_CLK_OUT_1>; + + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; }; }; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 55ae050042ce..d2d05f1da274 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -4,6 +4,7 @@ #include <dt-bindings/memory/tegra30-mc.h> #include <dt-bindings/pinctrl/pinctrl-tegra.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra30"; @@ -714,11 +715,12 @@ status = "disabled"; }; - pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra30-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; }; mc: memory-controller@7000f000 { diff --git a/arch/arm/boot/dts/uniphier-ld4.dtsi b/arch/arm/boot/dts/uniphier-ld4.dtsi index 64ec46c72a4c..06e7400d2940 100644 --- a/arch/arm/boot/dts/uniphier-ld4.dtsi +++ b/arch/arm/boot/dts/uniphier-ld4.dtsi @@ -51,7 +51,7 @@ ranges; interrupt-parent = <&intc>; - l2: l2-cache@500c0000 { + l2: cache-controller@500c0000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>; @@ -245,7 +245,7 @@ #dma-cells = <1>; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a400000 0x200>; @@ -265,7 +265,7 @@ sd-uhs-sdr50; }; - emmc: sdhc@5a500000 { + emmc: mmc@5a500000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a500000 0x200>; @@ -375,7 +375,7 @@ interrupt-controller; }; - aidet: aidet@61830000 { + aidet: interrupt-controller@61830000 { compatible = "socionext,uniphier-ld4-aidet"; reg = <0x61830000 0x200>; interrupt-controller; @@ -398,7 +398,7 @@ }; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5a"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm/boot/dts/uniphier-pro4.dtsi b/arch/arm/boot/dts/uniphier-pro4.dtsi index 2ec04d7972ef..1c866f0306fc 100644 --- a/arch/arm/boot/dts/uniphier-pro4.dtsi +++ b/arch/arm/boot/dts/uniphier-pro4.dtsi @@ -59,7 +59,7 @@ ranges; interrupt-parent = <&intc>; - l2: l2-cache@500c0000 { + l2: cache-controller@500c0000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>; @@ -279,7 +279,7 @@ #dma-cells = <1>; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a400000 0x200>; @@ -299,7 +299,7 @@ sd-uhs-sdr50; }; - emmc: sdhc@5a500000 { + emmc: mmc@5a500000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a500000 0x200>; @@ -317,7 +317,7 @@ non-removable; }; - sd1: sdhc@5a600000 { + sd1: mmc@5a600000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a600000 0x200>; @@ -426,7 +426,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-pro4-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -588,7 +588,7 @@ }; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5a"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi index ea3961f920a0..8f1ae0957f5f 100644 --- a/arch/arm/boot/dts/uniphier-pro5.dtsi +++ b/arch/arm/boot/dts/uniphier-pro5.dtsi @@ -131,7 +131,7 @@ ranges; interrupt-parent = <&intc>; - l2: l2-cache@500c0000 { + l2: cache-controller@500c0000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c0000 0x2000>, <0x503c0100 0x8>, <0x506c0000 0x400>; @@ -144,7 +144,7 @@ next-level-cache = <&l3>; }; - l3: l3-cache@500c8000 { + l3: cache-controller@500c8000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c8000 0x2000>, <0x503c8100 0x8>, <0x506c8000 0x400>; @@ -174,8 +174,8 @@ interrupts = <0 216 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 11>; /* common with spi0 */ + resets = <&peri_rst 12>; }; serial0: serial@54006800 { @@ -408,7 +408,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-pro5-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -453,7 +453,155 @@ }; }; - nand: nand@68000000 { + usb0: usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "host"; + interrupts = <0 134 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb0_rst 15>; + phys = <&usb0_hsphy0>, <&usb0_ssphy0>; + dr_mode = "host"; + }; + + usb-glue@65b00000 { + compatible = "socionext,uniphier-pro5-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65b00000 0x400>; + + usb0_rst: reset@0 { + compatible = "socionext,uniphier-pro5-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + }; + + usb0_vbus0: regulator@100 { + compatible = "socionext,uniphier-pro5-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + }; + + usb0_hsphy0: hs-phy@280 { + compatible = "socionext,uniphier-pro5-usb3-hsphy"; + reg = <0x280 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + vbus-supply = <&usb0_vbus0>; + }; + + usb0_ssphy0: ss-phy@380 { + compatible = "socionext,uniphier-pro5-usb3-ssphy"; + reg = <0x380 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + vbus-supply = <&usb0_vbus0>; + }; + }; + + usb1: usb@65c00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65c00000 0xcd00>; + interrupt-names = "host"; + interrupts = <0 137 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb2>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb1_rst 15>; + phys = <&usb1_hsphy0>, <&usb1_hsphy1>, <&usb1_ssphy0>; + dr_mode = "host"; + }; + + usb-glue@65d00000 { + compatible = "socionext,uniphier-pro5-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65d00000 0x400>; + + usb1_rst: reset@0 { + compatible = "socionext,uniphier-pro5-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + }; + + usb1_vbus0: regulator@100 { + compatible = "socionext,uniphier-pro5-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + }; + + usb1_vbus1: regulator@110 { + compatible = "socionext,uniphier-pro5-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + }; + + usb1_hsphy0: hs-phy@280 { + compatible = "socionext,uniphier-pro5-usb3-hsphy"; + reg = <0x280 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + vbus-supply = <&usb1_vbus0>; + }; + + usb1_hsphy1: hs-phy@290 { + compatible = "socionext,uniphier-pro5-usb3-hsphy"; + reg = <0x290 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + vbus-supply = <&usb1_vbus1>; + }; + + usb1_ssphy0: ss-phy@380 { + compatible = "socionext,uniphier-pro5-usb3-ssphy"; + reg = <0x380 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + vbus-supply = <&usb1_vbus0>; + }; + }; + + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5b"; status = "disabled"; reg-names = "nand_data", "denali_reg"; @@ -469,7 +617,7 @@ resets = <&sys_rst 2>, <&sys_rst 2>; }; - emmc: sdhc@68400000 { + emmc: mmc@68400000 { compatible = "socionext,uniphier-sd-v3.1"; status = "disabled"; reg = <0x68400000 0x800>; @@ -485,7 +633,7 @@ non-removable; }; - sd: sdhc@68800000 { + sd: mmc@68800000 { compatible = "socionext,uniphier-sd-v3.1"; status = "disabled"; reg = <0x68800000 0x800>; diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi index 13b0d4a7741f..2f2a24994c69 100644 --- a/arch/arm/boot/dts/uniphier-pxs2.dtsi +++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi @@ -157,7 +157,7 @@ ranges; interrupt-parent = <&intc>; - l2: l2-cache@500c0000 { + l2: cache-controller@500c0000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c0000 0x2000>, <0x503c0100 0x8>, <0x506c0000 0x400>; @@ -187,8 +187,8 @@ interrupts = <0 216 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 12>; + resets = <&peri_rst 12>; }; serial0: serial@54006800 { @@ -446,7 +446,7 @@ }; }; - emmc: sdhc@5a000000 { + emmc: mmc@5a000000 { compatible = "socionext,uniphier-sd-v3.1.1"; status = "disabled"; reg = <0x5a000000 0x800>; @@ -462,7 +462,7 @@ non-removable; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v3.1.1"; status = "disabled"; reg = <0x5a400000 0x800>; @@ -508,7 +508,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-pxs2-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -761,7 +761,7 @@ }; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5b"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi index 04e60c295319..a11897669c26 100644 --- a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi +++ b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi @@ -7,7 +7,7 @@ &i2c0 { eeprom@50 { - compatible = "microchip,24lc128"; + compatible = "microchip,24lc128", "atmel,24c128"; reg = <0x50>; pagesize = <64>; }; diff --git a/arch/arm/boot/dts/uniphier-sld8.dtsi b/arch/arm/boot/dts/uniphier-sld8.dtsi index 4fc6676f5486..09992163e1f4 100644 --- a/arch/arm/boot/dts/uniphier-sld8.dtsi +++ b/arch/arm/boot/dts/uniphier-sld8.dtsi @@ -51,7 +51,7 @@ ranges; interrupt-parent = <&intc>; - l2: l2-cache@500c0000 { + l2: cache-controller@500c0000 { compatible = "socionext,uniphier-system-cache"; reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>; @@ -249,7 +249,7 @@ #dma-cells = <1>; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a400000 0x200>; @@ -269,7 +269,7 @@ sd-uhs-sdr50; }; - emmc: sdhc@5a500000 { + emmc: mmc@5a500000 { compatible = "socionext,uniphier-sd-v2.91"; status = "disabled"; reg = <0x5a500000 0x200>; @@ -379,7 +379,7 @@ interrupt-controller; }; - aidet: aidet@61830000 { + aidet: interrupt-controller@61830000 { compatible = "socionext,uniphier-sld8-aidet"; reg = <0x61830000 0x200>; interrupt-controller; @@ -402,7 +402,7 @@ }; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5a"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm/boot/dts/versatile-ab-ib2.dts b/arch/arm/boot/dts/versatile-ab-ib2.dts index 5890cb974f78..c577ff4bb4be 100644 --- a/arch/arm/boot/dts/versatile-ab-ib2.dts +++ b/arch/arm/boot/dts/versatile-ab-ib2.dts @@ -10,7 +10,7 @@ model = "ARM Versatile AB + IB2 board"; /* Special IB2 control register */ - ib2_syscon@27000000 { + syscon@27000000 { compatible = "arm,versatile-ib2-syscon", "syscon", "simple-mfd"; reg = <0x27000000 0x4>; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi index dfae90adbb7c..5c183483ec3b 100644 --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -19,7 +19,7 @@ */ / { - smb@8000000 { + bus@8000000 { motherboard { model = "V2M-P1"; arm,hbi = <0x190>; diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi index 2e29d7790497..5e48b641068a 100644 --- a/arch/arm/boot/dts/vexpress-v2m.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -19,7 +19,7 @@ */ / { - smb@4000000 { + bus@4000000 { motherboard { model = "V2M-P1"; arm,hbi = <0x190>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 0dc4277d5f8b..f82fa34c90be 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -236,7 +236,7 @@ }; }; - smb@8000000 { + bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 1de0a658adf1..3ac95a179452 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -608,7 +608,7 @@ }; }; - smb: smb@8000000 { + smb: bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts index d5b47d526f9e..7aa64ae25779 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -206,7 +206,7 @@ }; }; - smb: smb@8000000 { + smb: bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts index d796efaadbe3..623246f37448 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -295,7 +295,7 @@ }; }; - smb: smb@4000000 { + smb: bus@4000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index e2da122a63f4..c12a1b8bc086 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -1,42 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2014-2020 Toradex */ / { diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index fba37b8756f7..cc1e069c44e6 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -1,42 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG + * Copyright 2014-2020 Toradex * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ / { diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts index 076998968fb5..088964f8dc4b 100644 --- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts @@ -1,42 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2014-2020 Toradex */ /dts-v1/; diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi index 92255f8893ce..8af7ed56e653 100644 --- a/arch/arm/boot/dts/vf500-colibri.dtsi +++ b/arch/arm/boot/dts/vf500-colibri.dtsi @@ -1,42 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2014-2020 Toradex */ #include "vf500.dtsi" diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi index b0ec475017ad..0c0dd442300a 100644 --- a/arch/arm/boot/dts/vf500.dtsi +++ b/arch/arm/boot/dts/vf500.dtsi @@ -23,7 +23,7 @@ }; soc { - aips-bus@40000000 { + bus@40000000 { intc: interrupt-controller@40003000 { compatible = "arm,cortex-a9-gic"; @@ -43,7 +43,7 @@ }; }; - aips-bus@40080000 { + bus@40080000 { pmu@40089000 { compatible = "arm,cortex-a5-pmu"; interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts index ef9b4d6209f6..fb661e8a2dc6 100644 --- a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts @@ -1,42 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2014-2020 Toradex */ /dts-v1/; diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi index 05c9a39509b8..607cec2df861 100644 --- a/arch/arm/boot/dts/vf610-colibri.dtsi +++ b/arch/arm/boot/dts/vf610-colibri.dtsi @@ -1,42 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014 Toradex AG - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * Copyright 2014-2020 Toradex */ #include "vf610.dtsi" diff --git a/arch/arm/boot/dts/vf610-zii-cfu1.dts b/arch/arm/boot/dts/vf610-zii-cfu1.dts index 28732249cfc0..ce1920c052fc 100644 --- a/arch/arm/boot/dts/vf610-zii-cfu1.dts +++ b/arch/arm/boot/dts/vf610-zii-cfu1.dts @@ -71,6 +71,14 @@ los-gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>; tx-disable-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; }; + + supply-voltage-monitor { + compatible = "iio-hwmon"; + io-channels = <&adc0 8>, /* 28VDC_IN */ + <&adc0 9>, /* +3.3V */ + <&adc1 8>, /* VCC_1V5 */ + <&adc1 9>; /* VCC_1V2 */ + }; }; &adc0 { diff --git a/arch/arm/boot/dts/vf610-zii-dev.dtsi b/arch/arm/boot/dts/vf610-zii-dev.dtsi index a1b4ccee2a10..95d0060fb56c 100644 --- a/arch/arm/boot/dts/vf610-zii-dev.dtsi +++ b/arch/arm/boot/dts/vf610-zii-dev.dtsi @@ -84,6 +84,14 @@ regulator-boot-on; gpio = <&gpio0 6 0>; }; + + supply-voltage-monitor { + compatible = "iio-hwmon"; + io-channels = <&adc0 8>, /* VCC_1V5 */ + <&adc0 9>, /* VCC_1V8 */ + <&adc1 8>, /* VCC_1V0 */ + <&adc1 9>; /* VCC_1V2 */ + }; }; &adc0 { diff --git a/arch/arm/boot/dts/vf610-zii-spb4.dts b/arch/arm/boot/dts/vf610-zii-spb4.dts index 77e1484211e4..55b4201e27f6 100644 --- a/arch/arm/boot/dts/vf610-zii-spb4.dts +++ b/arch/arm/boot/dts/vf610-zii-spb4.dts @@ -42,6 +42,14 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; + + supply-voltage-monitor { + compatible = "iio-hwmon"; + io-channels = <&adc0 8>, /* 28V_SW */ + <&adc0 9>, /* +3.3V */ + <&adc1 8>, /* VCC_1V5 */ + <&adc1 9>; /* VCC_1V2 */ + }; }; &adc0 { diff --git a/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts b/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts index 847c5858fea1..a6c22a79779e 100644 --- a/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts +++ b/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts @@ -46,6 +46,14 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; + + supply-voltage-monitor { + compatible = "iio-hwmon"; + io-channels = <&adc0 8>, /* 12V_MAIN */ + <&adc0 9>, /* +3.3V */ + <&adc1 8>, /* VCC_1V5 */ + <&adc1 9>; /* VCC_1V2 */ + }; }; &adc0 { diff --git a/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts b/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts index 453fce80f858..3d05c894bdc0 100644 --- a/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts +++ b/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts @@ -46,6 +46,14 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; + + supply-voltage-monitor { + compatible = "iio-hwmon"; + io-channels = <&adc0 8>, /* 12V_MAIN */ + <&adc0 9>, /* +3.3V */ + <&adc1 8>, /* VCC_1V5 */ + <&adc1 9>; /* VCC_1V2 */ + }; }; &adc0 { diff --git a/arch/arm/boot/dts/vf610m4-colibri.dts b/arch/arm/boot/dts/vf610m4-colibri.dts index d4bc0e3f2f11..2c2db47af441 100644 --- a/arch/arm/boot/dts/vf610m4-colibri.dts +++ b/arch/arm/boot/dts/vf610m4-colibri.dts @@ -1,45 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT /* * Device tree for Colibri VF61 Cortex-M4 support * * Copyright (C) 2015 Stefan Agner - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index 028e0ec30e0c..2d547e7b21ad 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -59,7 +59,7 @@ interrupt-parent = <&mscm_ir>; ranges; - aips0: aips-bus@40000000 { + aips0: bus@40000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -471,7 +471,7 @@ }; }; - aips1: aips-bus@40080000 { + aips1: bus@40080000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index f66bb98a5cce..4a0ba2ae1a25 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -118,6 +118,7 @@ CONFIG_POWER_SUPPLY=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_SAMA5D4_WATCHDOG=y CONFIG_MFD_ATMEL_FLEXCOM=y CONFIG_MFD_ATMEL_HLCDC=y CONFIG_REGULATOR=y diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 0afcae9f7cf8..8e7a3ed2a4df 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -72,6 +72,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y +CONFIG_BCMGENET=y CONFIG_USB_LAN78XX=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y @@ -96,9 +97,13 @@ CONFIG_SPI_BCM2835AUX=y CONFIG_GPIO_SYSFS=y CONFIG_SENSORS_RASPBERRYPI_HWMON=m CONFIG_THERMAL=y +CONFIG_BCM2711_THERMAL=y CONFIG_BCM2835_THERMAL=y CONFIG_WATCHDOG=y CONFIG_BCM2835_WDT=y +CONFIG_MFD_SYSCON=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_DRM=y diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index c8e0c14092e8..3c3a00fc71f6 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -8,6 +8,7 @@ CONFIG_PERF_EVENTS=y CONFIG_ARCH_EXYNOS=y CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND=y CONFIG_SMP=y +CONFIG_SCHED_MC=y CONFIG_BIG_LITTLE=y CONFIG_NR_CPUS=8 CONFIG_HIGHMEM=y @@ -17,6 +18,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" +CONFIG_ENERGY_MODEL=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y @@ -92,7 +94,7 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y @@ -111,11 +113,13 @@ CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y +CONFIG_BRCMFMAC=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_SAMSUNG=y +CONFIG_KEYBOARD_TM2_TOUCHKEY=y CONFIG_KEYBOARD_CROS_EC=y # CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_CYAPA=y @@ -204,6 +208,9 @@ CONFIG_V4L_TEST_DRIVERS=y CONFIG_VIDEO_VIVID=m CONFIG_CEC_PLATFORM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_CEC=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_S5C73M3=m CONFIG_DRM=y CONFIG_DRM_EXYNOS=y CONFIG_DRM_EXYNOS_FIMD=y @@ -276,6 +283,7 @@ CONFIG_MMC_DW_EXYNOS=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_FLASH=y +CONFIG_LEDS_AAT1290=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_MAX77693=y @@ -320,6 +328,7 @@ CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y CONFIG_ROMFS_FS=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 8f216a599735..5a20d12d62bd 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -179,6 +179,9 @@ CONFIG_MOUSE_PS2=m CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=y +CONFIG_TOUCHSCREEN_AD7879=y +CONFIG_TOUCHSCREEN_AD7879_I2C=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y CONFIG_TOUCHSCREEN_DA9052=y CONFIG_TOUCHSCREEN_EGALAX=y CONFIG_TOUCHSCREEN_GOODIX=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 0b020863abdb..f8e45351c3f9 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -113,6 +113,7 @@ CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y CONFIG_ARM_ZYNQ_CPUIDLE=y CONFIG_ARM_EXYNOS_CPUIDLE=y +CONFIG_ARM_TEGRA_CPUIDLE=y CONFIG_KERNEL_MODE_NEON=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_TRUSTED_FOUNDATIONS=y @@ -640,6 +641,7 @@ CONFIG_CEC_PLATFORM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_CEC=m CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_ML86V7667=m +CONFIG_IMX_IPUV3_CORE=m CONFIG_DRM=y # CONFIG_DRM_I2C_CH7006 is not set # CONFIG_DRM_I2C_SIL164 is not set @@ -655,6 +657,11 @@ CONFIG_ROCKCHIP_ANALOGIX_DP=y CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_DRM_IMX=m +CONFIG_DRM_IMX_PARALLEL_DISPLAY=m +CONFIG_DRM_IMX_TVE=m +CONFIG_DRM_IMX_LDB=m +CONFIG_DRM_IMX_HDMI=m CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DU=m CONFIG_DRM_RCAR_LVDS=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 54f1a21de7e0..3cc3ca5fa027 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -56,6 +56,8 @@ CONFIG_CPUFREQ_DT=m # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set CONFIG_ARM_TI_CPUFREQ=y CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_DT_IDLE_STATES=y CONFIG_KERNEL_MODE_NEON=y CONFIG_PM_DEBUG=y CONFIG_ARM_CRYPTO=y @@ -78,6 +80,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_BINFMT_MISC=y CONFIG_CMA=y +CONFIG_ZSMALLOC=m +CONFIG_PGTABLE_MAPPING=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -130,6 +134,7 @@ CONFIG_PCI_EPF_TEST=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_OMAP_OCP2SCP=y +CONFIG_SIMPLE_PM_BUS=y CONFIG_CONNECTOR=m CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y @@ -139,7 +144,6 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_M25P80=m CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_VERIFY_WRITE=y CONFIG_MTD_ONENAND_OMAP2=y @@ -149,6 +153,8 @@ CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_NAND_OMAP_BCH=y CONFIG_MTD_SPI_NOR=m CONFIG_MTD_UBI=y +CONFIG_ZRAM=m +CONFIG_ZRAM_WRITEBACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 @@ -186,10 +192,10 @@ CONFIG_TI_CPSW_SWITCHDEV=y CONFIG_TI_CPTS=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_AT803X_PHY=y CONFIG_DP83848_PHY=y CONFIG_DP83867_PHY=y CONFIG_MICREL_PHY=y +CONFIG_AT803X_PHY=y CONFIG_SMSC_PHY=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -278,6 +284,7 @@ CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TWL4030=y CONFIG_W1=m CONFIG_HDQ_MASTER_OMAP=m +CONFIG_W1_SLAVE_DS250X=m CONFIG_POWER_AVS=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y @@ -353,16 +360,16 @@ CONFIG_OMAP2_DSS_DSI=y CONFIG_DRM_OMAP_PANEL_DSI_CM=m CONFIG_DRM_TILCDC=m CONFIG_DRM_PANEL_SIMPLE=m -CONFIG_DRM_DISPLAY_CONNECTOR=m -CONFIG_DRM_SIMPLE_BRIDGE=m -CONFIG_DRM_TI_TFP410=m -CONFIG_DRM_TI_TPD12S015=m CONFIG_DRM_PANEL_LG_LB035Q02=m CONFIG_DRM_PANEL_NEC_NL8048HL11=m CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m CONFIG_DRM_PANEL_SONY_ACX565AKM=m CONFIG_DRM_PANEL_TPO_TD028TTEC1=m CONFIG_DRM_PANEL_TPO_TD043MTEA1=m +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_TI_TFP410=m +CONFIG_DRM_TI_TPD12S015=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y @@ -482,6 +489,8 @@ CONFIG_RTC_DRV_PALMAS=m CONFIG_RTC_DRV_OMAP=m CONFIG_RTC_DRV_CPCAP=m CONFIG_DMADEVICES=y +CONFIG_CLK_TWL6040=m +CONFIG_COMMON_CLK_PALMAS=m CONFIG_OMAP_IOMMU=y CONFIG_REMOTEPROC=y CONFIG_OMAP_REMOTEPROC=m @@ -498,7 +507,9 @@ CONFIG_IIO_SW_DEVICE=m CONFIG_IIO_SW_TRIGGER=m CONFIG_IIO_ST_ACCEL_3AXIS=m CONFIG_CPCAP_ADC=m +CONFIG_INA2XX_ADC=m CONFIG_TI_AM335X_ADC=m +CONFIG_SENSORS_ISL29028=m CONFIG_BMP280=m CONFIG_PWM=y CONFIG_PWM_OMAP_DMTIMER=m @@ -514,6 +525,7 @@ CONFIG_TI_PIPE3=y CONFIG_TWL4030_USB=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_FANOTIFY=y CONFIG_QUOTA=y CONFIG_QFMT_V2=y @@ -552,10 +564,10 @@ CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y +# CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_SPLIT=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y CONFIG_SCHEDSTATS=y -# CONFIG_DEBUG_BUGVERBOSE is not set diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index cdc75ef7d529..c882167e1496 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -50,6 +50,11 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set +CONFIG_QRTR=m +CONFIG_QRTR_SMD=m +CONFIG_BT=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCM=y CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_RFKILL=y @@ -111,6 +116,7 @@ CONFIG_SERIO_LIBPS2=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index 3b82b64950d9..c090643b1ecb 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig @@ -32,7 +32,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 73ed73a8785a..153009130dab 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -202,7 +202,6 @@ CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_CONSTANTS=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index a27592d3b1fa..aa94369bdd0f 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -25,6 +25,7 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y CONFIG_CPU_IDLE=y +CONFIG_ARM_TEGRA_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_TRUSTED_FOUNDATIONS=y diff --git a/arch/arm/crypto/.gitignore b/arch/arm/crypto/.gitignore index a3c7ad52a469..8d7f4bcaec2c 100644 --- a/arch/arm/crypto/.gitignore +++ b/arch/arm/crypto/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only aesbs-core.S sha256-core.S sha512-core.S diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index 772f48ef84b7..86405cc81385 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -33,7 +33,5 @@ int arm_iommu_attach_device(struct device *dev, struct dma_iommu_mapping *mapping); void arm_iommu_detach_device(struct device *dev); -int arm_dma_supported(struct device *dev, u64 mask); - #endif /* __KERNEL__ */ #endif diff --git a/arch/arm/include/asm/nwflash.h b/arch/arm/include/asm/nwflash.h index 0ec6f07c2d8a..66b7e68c9b58 100644 --- a/arch/arm/include/asm/nwflash.h +++ b/arch/arm/include/asm/nwflash.h @@ -2,7 +2,6 @@ #ifndef _FLASH_H #define _FLASH_H -#define FLASH_MINOR 160 /* MAJOR is 10 - miscdevice */ #define CMD_WRITE_DISABLE 0 #define CMD_WRITE_ENABLE 0x28 #define CMD_WRITE_BASE64K_ENABLE 0x47 diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index c2b75cba26df..11b058a72a5b 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -161,9 +161,7 @@ extern int pfn_valid(unsigned long); #endif /* !__ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #include <asm-generic/getorder.h> diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 0d3ea35c97fe..9e084a464a97 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h @@ -211,8 +211,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) #define pmd_addr_end(addr,end) (end) #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) -#define pte_special(pte) (0) -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } /* * We don't have huge page support for short descriptors, for the moment diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 0483cf413315..befc8fcec98f 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -243,19 +243,8 @@ static inline void __sync_icache_dcache(pte_t pteval) extern void __sync_icache_dcache(pte_t pteval); #endif -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval) -{ - unsigned long ext = 0; - - if (addr < TASK_SIZE && pte_valid_user(pteval)) { - if (!pte_special(pteval)) - __sync_icache_dcache(pteval); - ext |= PTE_EXT_NG; - } - - set_pte_ext(ptep, pteval, ext); -} +void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval); static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot) { diff --git a/arch/arm/include/debug/stm32.S b/arch/arm/include/debug/stm32.S index 1abb32f685fd..f3c4a37210ed 100644 --- a/arch/arm/include/debug/stm32.S +++ b/arch/arm/include/debug/stm32.S @@ -4,14 +4,13 @@ * Author: Gerald Baeza <gerald.baeza@st.com> for STMicroelectronics. */ -#define STM32_UART_BASE 0x40011000 /* USART1 */ - #ifdef CONFIG_STM32F4_DEBUG_UART #define STM32_USART_SR_OFF 0x00 #define STM32_USART_TDR_OFF 0x04 #endif -#ifdef CONFIG_STM32F7_DEBUG_UART +#if defined(CONFIG_STM32F7_DEBUG_UART) || defined(CONFIG_STM32H7_DEBUG_UART) || \ + defined(CONFIG_STM32MP1_DEBUG_UART) #define STM32_USART_SR_OFF 0x1C #define STM32_USART_TDR_OFF 0x28 #endif @@ -20,8 +19,8 @@ #define STM32_USART_TXE (1 << 7) /* Tx data reg empty */ .macro addruart, rp, rv, tmp - ldr \rp, =STM32_UART_BASE @ physical base - ldr \rv, =STM32_UART_BASE @ virt base /* NoMMU */ + ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical base + ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virt base .endm .macro senduart,rd,rx diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/arm/kernel/.gitignore +++ b/arch/arm/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 7eaa2ae7aff5..72a08786e16e 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -25,26 +25,26 @@ ENTRY(relocate_new_kernel) ldr r3, [r0],#4 /* Is it a destination page. Put destination address to r4 */ - tst r3,#1,0 + tst r3,#1 beq 1f bic r4,r3,#1 b 0b 1: /* Is it an indirection page */ - tst r3,#2,0 + tst r3,#2 beq 1f bic r0,r3,#2 b 0b 1: /* are we done ? */ - tst r3,#4,0 + tst r3,#4 beq 1f b 2f 1: /* is it source ? */ - tst r3,#8,0 + tst r3,#8 beq 0b bic r3,r3,#8 mov r6,#1024 diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 4574e6aea0a5..11a964fd66f4 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -444,7 +444,7 @@ int unwind_frame(struct stackframe *frame) ctrl.vrs[PC] = ctrl.vrs[LR]; /* check for infinite loop */ - if (frame->pc == ctrl.vrs[PC]) + if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP]) return -URC_FAILURE; frame->fp = ctrl.vrs[FP]; diff --git a/arch/arm/mach-at91/.gitignore b/arch/arm/mach-at91/.gitignore index 2ecd6f51c8a9..f6d47389675e 100644 --- a/arch/arm/mach-at91/.gitignore +++ b/arch/arm/mach-at91/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only pm_data-offsets.h diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 7979420bd48b..ccd7e80ce943 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK config COMMON_CLK_AT91 bool - select COMMON_CLK select MFD_SYSCON config HAVE_AT91_SMD diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 374b9d155558..074bde64064e 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -736,13 +736,36 @@ backup_default: struct pmc_info { unsigned long uhp_udp_mask; + unsigned long mckr; + unsigned long version; }; static const struct pmc_info pmc_infos[] __initconst = { - { .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP }, - { .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP }, - { .uhp_udp_mask = AT91SAM926x_PMC_UHP }, - { .uhp_udp_mask = 0 }, + { + .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP, + .mckr = 0x30, + .version = AT91_PMC_V1, + }, + + { + .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP, + .mckr = 0x30, + .version = AT91_PMC_V1, + }, + { + .uhp_udp_mask = AT91SAM926x_PMC_UHP, + .mckr = 0x30, + .version = AT91_PMC_V1, + }, + { .uhp_udp_mask = 0, + .mckr = 0x30, + .version = AT91_PMC_V1, + }, + { + .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP, + .mckr = 0x28, + .version = AT91_PMC_V2, + }, }; static const struct of_device_id atmel_pmc_ids[] __initconst = { @@ -757,7 +780,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = { { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] }, - { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] }, + { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] }, { /* sentinel */ }, }; @@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void)) pmc = of_id->data; soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask; + soc_pm.data.pmc_mckr_offset = pmc->mckr; + soc_pm.data.pmc_version = pmc->version; if (pm_idle) arm_pm_idle = pm_idle; diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 9fa4f483f2b5..218e8d1a30fb 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -33,6 +33,8 @@ struct at91_pm_data { void __iomem *sfrbu; unsigned int standby_mode; unsigned int suspend_mode; + unsigned int pmc_mckr_offset; + unsigned int pmc_version; }; #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index f2d893c03cd9..82089ff258c0 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -12,6 +12,10 @@ int main(void) DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); + DEFINE(PM_DATA_PMC_MCKR_OFFSET, offsetof(struct at91_pm_data, + pmc_mckr_offset)); + DEFINE(PM_DATA_PMC_VERSION, offsetof(struct at91_pm_data, + pmc_version)); return 0; } diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index ed57c879d4e1..be9764e8d3fa 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -18,6 +18,7 @@ pmc .req r0 tmp1 .req r4 tmp2 .req r5 +tmp3 .req r6 /* * Wait until master clock is ready (after switching master clock source) @@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram) str tmp1, .memtype ldr tmp1, [r0, #PM_DATA_MODE] str tmp1, .pm_mode + ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] + str tmp1, .mckr_offset + ldr tmp1, [r0, #PM_DATA_PMC_VERSION] + str tmp1, .pmc_version /* Both ldrne below are here to preload their address in the TLB */ ldr tmp1, [r0, #PM_DATA_SHDWC] str tmp1, .shdwc cmp tmp1, #0 ldrne tmp2, [tmp1, #0] ldr tmp1, [r0, #PM_DATA_SFRBU] - str tmp1, .sfr + str tmp1, .sfrbu cmp tmp1, #0 ldrne tmp2, [tmp1, #0x10] @@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram) ENTRY(at91_backup_mode) /* Switch the master clock source to slow clock. */ ldr pmc, .pmc_base - ldr tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp2, .mckr_offset + ldr tmp1, [pmc, tmp2] bic tmp1, tmp1, #AT91_PMC_CSS - str tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, [pmc, tmp2] wait_mckrdy /*BUMEN*/ - ldr r0, .sfr + ldr r0, .sfrbu mov tmp1, #0x1 str tmp1, [r0, #0x10] @@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode) */ .macro at91_pm_ulp1_mode ldr pmc, .pmc_base + ldr tmp2, .mckr_offset /* Save RC oscillator state and check if it is enabled. */ ldr tmp1, [pmc, #AT91_PMC_SR] @@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode) str tmp1, [pmc, #AT91_CKGR_MOR] /* Switch the master clock source to main clock */ - ldr tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp1, [pmc, tmp2] bic tmp1, tmp1, #AT91_PMC_CSS orr tmp1, tmp1, #AT91_PMC_CSS_MAIN - str tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, [pmc, tmp2] wait_mckrdy @@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode) orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] + /* Quirk for SAM9X60's PMC */ + nop + nop + wait_mckrdy /* Enable the crystal oscillator */ @@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode) wait_moscrdy /* Switch the master clock source to slow clock */ - ldr tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp1, [pmc, tmp2] bic tmp1, tmp1, #AT91_PMC_CSS - str tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, [pmc, tmp2] wait_mckrdy @@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode) wait_moscsels /* Switch the master clock source to main clock */ - ldr tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp1, [pmc, tmp2] bic tmp1, tmp1, #AT91_PMC_CSS orr tmp1, tmp1, #AT91_PMC_CSS_MAIN - str tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, [pmc, tmp2] wait_mckrdy @@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode) 3: .endm +.macro at91_plla_disable + /* Save PLLA setting and disable it */ + ldr tmp1, .pmc_version + cmp tmp1, #AT91_PMC_V1 + beq 1f + +#ifdef CONFIG_SOC_SAM9X60 + /* Save PLLA settings. */ + ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID + str tmp2, [pmc, #AT91_PMC_PLL_UPDT] + + /* save div. */ + mov tmp1, #0 + ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] + bic tmp2, tmp2, #0xffffff00 + orr tmp1, tmp1, tmp2 + + /* save mul. */ + ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] + bic tmp2, tmp2, #0xffffff + orr tmp1, tmp1, tmp2 + str tmp1, .saved_pllar + + /* step 2. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + /* step 3. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK + orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL + str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + + /* step 4. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + /* step 5. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL + str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + + /* step 7. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + b 2f +#endif + +1: /* Save PLLA setting and disable it */ + ldr tmp1, [pmc, #AT91_CKGR_PLLAR] + str tmp1, .saved_pllar + + /* Disable PLLA. */ + mov tmp1, #AT91_PMC_PLLCOUNT + orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ + str tmp1, [pmc, #AT91_CKGR_PLLAR] +2: +.endm + +.macro at91_plla_enable + ldr tmp2, .saved_pllar + ldr tmp3, .pmc_version + cmp tmp3, #AT91_PMC_V1 + beq 4f + +#ifdef CONFIG_SOC_SAM9X60 + /* step 1. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + /* step 2. */ + ldr tmp1, =#AT91_PMC_PLL_ACR_DEFAULT_PLLA + str tmp1, [pmc, #AT91_PMC_PLL_ACR] + + /* step 3. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] + mov tmp3, tmp2 + bic tmp3, tmp3, #0xffffff + orr tmp1, tmp1, tmp3 + str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] + + /* step 8. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + /* step 9. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK + orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL + orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK + bic tmp1, tmp1, #0xff + mov tmp3, tmp2 + bic tmp3, tmp3, #0xffffff00 + orr tmp1, tmp1, tmp3 + str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] + + /* step 10. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID + str tmp1, [pmc, #AT91_PMC_PLL_UPDT] + + /* step 11. */ +3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] + tst tmp1, #0x1 + beq 3b + b 2f +#endif + + /* Restore PLLA setting */ +4: str tmp2, [pmc, #AT91_CKGR_PLLAR] + + /* Enable PLLA. */ + tst tmp2, #(AT91_PMC_MUL & 0xff0000) + bne 1f + tst tmp2, #(AT91_PMC_MUL & ~0xff0000) + beq 2f + +1: ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKA + beq 1b +2: +.endm + ENTRY(at91_ulp_mode) ldr pmc, .pmc_base + ldr tmp2, .mckr_offset /* Save Master clock setting */ - ldr tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp1, [pmc, tmp2] str tmp1, .saved_mckr /* * Set the Master clock source to slow clock */ bic tmp1, tmp1, #AT91_PMC_CSS - str tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, [pmc, tmp2] wait_mckrdy + at91_plla_disable + ldr r0, .pm_mode cmp r0, #AT91_PM_ULP1 beq ulp1_mode @@ -352,11 +502,14 @@ ulp1_mode: ulp_exit: ldr pmc, .pmc_base + at91_plla_enable + /* * Restore master clock setting */ - ldr tmp1, .saved_mckr - str tmp1, [pmc, #AT91_PMC_MCKR] + ldr tmp1, .mckr_offset + ldr tmp2, .saved_mckr + str tmp2, [pmc, tmp1] wait_mckrdy @@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh) .word 0 .shdwc: .word 0 -.sfr: +.sfrbu: .word 0 .memtype: .word 0 .pm_mode: .word 0 +.mckr_offset: + .word 0 +.pmc_version: + .word 0 .saved_mckr: .word 0 +.saved_pllar: + .word 0 .saved_sam9_lpr: .word 0 .saved_sam9_lpr1: diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index fcfe2a0e8058..6aa938b949db 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -20,7 +20,6 @@ config ARCH_BCM_IPROC select GPIOLIB select ARM_AMBA select PINCTRL - select PCI_DOMAINS_GENERIC if PCI help This enables support for systems based on Broadcom IPROC architected SoCs. The IPROC complex contains one or more ARM CPUs along with common @@ -54,7 +53,6 @@ config ARCH_BCM_NSP select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_ERRATA_764369 if SMP - select HAVE_SMP select THERMAL select THERMAL_OF help @@ -73,7 +71,6 @@ config ARCH_BCM_5301X select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_ERRATA_764369 if SMP - select HAVE_SMP help Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. @@ -109,7 +106,6 @@ config ARCH_BCM_281XX bool "Broadcom BCM281XX SoC family" depends on ARCH_MULTI_V7 select ARCH_BCM_MOBILE - select HAVE_SMP help Enable support for the BCM281XX family, which includes BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155 @@ -119,7 +115,6 @@ config ARCH_BCM_21664 bool "Broadcom BCM21664 SoC family" depends on ARCH_MULTI_V7 select ARCH_BCM_MOBILE - select HAVE_SMP help Enable support for the BCM21664 family, which includes BCM21663 and BCM21664 variants. @@ -128,7 +123,6 @@ config ARCH_BCM_23550 bool "Broadcom BCM23550 SoC" depends on ARCH_MULTI_V7 select ARCH_BCM_MOBILE - select HAVE_SMP help Enable support for the BCM23550. @@ -165,7 +159,6 @@ config ARCH_BCM2835 select ZONE_DMA if ARCH_MULTI_V7 select ARM_TIMER_SP804 select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 - select TIMER_OF select BCM2835_TIMER select PINCTRL select PINCTRL_BCM2835 @@ -201,7 +194,6 @@ config ARCH_BCM_63XX select HAVE_ARM_ARCH_TIMER select HAVE_ARM_TWD if SMP select HAVE_ARM_SCU if SMP - select HAVE_SMP help This enables support for systems based on Broadcom DSL SoCs. It currently supports the 'BCM63XX' ARM-based family, which includes diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c index 1d61a7701c11..e4f4b20b83a2 100644 --- a/arch/arm/mach-cns3xxx/core.c +++ b/arch/arm/mach-cns3xxx/core.c @@ -189,12 +189,6 @@ static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction cns3xxx_timer_irq = { - .name = "timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = cns3xxx_timer_interrupt, -}; - /* * Set up the clock source and clock events devices */ @@ -245,7 +239,9 @@ static void __init __cns3xxx_timer_init(unsigned int timer_irq) writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); /* Make irqs happen for the system timer */ - setup_irq(timer_irq, &cns3xxx_timer_irq); + if (request_irq(timer_irq, cns3xxx_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "timer", NULL)) + pr_err("Failed to request irq %d (timer)\n", timer_irq); cns3xxx_clockevents_init(timer_irq); } diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 01b830afcea9..dbe970e37895 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -48,7 +48,7 @@ /***************************************************************************** * I/O Address Mapping ****************************************************************************/ -static struct map_desc dove_io_desc[] __initdata = { +static struct map_desc __maybe_unused dove_io_desc[] __initdata = { { .virtual = (unsigned long) DOVE_SB_REGS_VIRT_BASE, .pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE), diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index da2ff4f61d6b..575b2e2b6759 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -201,17 +201,13 @@ ebsa110_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction ebsa110_timer_irq = { - .name = "EBSA110 Timer Tick", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = ebsa110_timer_interrupt, -}; - /* * Set up timer interrupt. */ void __init ebsa110_timer_init(void) { + int irq = IRQ_EBSA110_TIMER0; + arch_gettimeoffset = ebsa110_gettimeoffset; /* @@ -221,7 +217,9 @@ void __init ebsa110_timer_init(void) __raw_writeb(COUNT & 0xff, PIT_T1); __raw_writeb(COUNT >> 8, PIT_T1); - setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq); + if (request_irq(irq, ebsa110_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, + "EBSA110 Timer Tick", NULL)) + pr_err("Failed to request irq %d (EBSA110 Timer Tick)\n", irq); } static struct plat_serial8250_port serial_platform_data[] = { diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index de998830f534..dd4b164d1831 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -117,15 +117,11 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction ep93xx_timer_irq = { - .name = "ep93xx timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = ep93xx_timer_interrupt, - .dev_id = &ep93xx_clockevent, -}; - void __init ep93xx_timer_init(void) { + int irq = IRQ_EP93XX_TIMER3; + unsigned long flags = IRQF_TIMER | IRQF_IRQPOLL; + /* Enable and register clocksource and sched_clock on timer 4 */ writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, EP93XX_TIMER4_VALUE_HIGH); @@ -136,7 +132,9 @@ void __init ep93xx_timer_init(void) EP93XX_TIMER4_RATE); /* Set up clockevent on timer 3 */ - setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq); + if (request_irq(irq, ep93xx_timer_interrupt, flags, "ep93xx timer", + &ep93xx_clockevent)) + pr_err("Failed to request irq %d (ep93xx timer)\n", irq); clockevents_config_and_register(&ep93xx_clockevent, EP93XX_TIMER123_RATE, 1, diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index f76212d2dbf1..2908c9ef3c9b 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -101,13 +101,6 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction footbridge_timer_irq = { - .name = "dc21285_timer1", - .handler = timer1_interrupt, - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .dev_id = &ckevt_dc21285, -}; - /* * Set up timer interrupt. */ @@ -118,7 +111,9 @@ void __init footbridge_timer_init(void) clocksource_register_hz(&cksrc_dc21285, rate); - setup_irq(ce->irq, &footbridge_timer_irq); + if (request_irq(ce->irq, timer1_interrupt, IRQF_TIMER | IRQF_IRQPOLL, + "dc21285_timer1", &ckevt_dc21285)) + pr_err("Failed to request irq %d (dc21285_timer1)", ce->irq); ce->cpumask = cpumask_of(smp_processor_id()); clockevents_config_and_register(ce, rate, 0x4, 0xffffff); diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c index 88a553932c33..842ddb4121ef 100644 --- a/arch/arm/mach-footbridge/isa-irq.c +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -96,11 +96,6 @@ static void isa_irq_handler(struct irq_desc *desc) generic_handle_irq(isa_irq); } -static struct irqaction irq_cascade = { - .handler = no_action, - .name = "cascade", -}; - static struct resource pic1_resource = { .name = "pic1", .start = 0x20, @@ -160,7 +155,10 @@ void __init isa_init_irq(unsigned int host_irq) request_resource(&ioport_resource, &pic1_resource); request_resource(&ioport_resource, &pic2_resource); - setup_irq(IRQ_ISA_CASCADE, &irq_cascade); + + irq = IRQ_ISA_CASCADE; + if (request_irq(irq, no_action, 0, "cascade", NULL)) + pr_err("Failed to request irq %u (cascade)\n", irq); irq_set_chained_handler(host_irq, isa_irq_handler); diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index 82f45591fb2c..723e3eae995d 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -25,17 +25,12 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction pit_timer_irq = { - .name = "pit", - .handler = pit_timer_interrupt, - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .dev_id = &i8253_clockevent, -}; - void __init isa_timer_init(void) { clocksource_i8253_init(); - setup_irq(i8253_clockevent.irq, &pit_timer_irq); + if (request_irq(i8253_clockevent.irq, pit_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "pit", &i8253_clockevent)) + pr_err("Failed to request irq %d(pit)\n", i8253_clockevent.irq); clockevent_i8253_init(false); } diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 95584ee02b55..e7d7b90e2cf8 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -471,8 +471,6 @@ config SOC_IMX53 config SOC_IMX6 bool select ARM_CPU_SUSPEND if (PM || CPU_IDLE) - select ARM_ERRATA_754322 - select ARM_ERRATA_775420 select ARM_GIC select HAVE_IMX_ANATOP select HAVE_IMX_GPC @@ -484,6 +482,8 @@ config SOC_IMX6 config SOC_IMX6Q bool "i.MX6 Quad/DualLite support" select ARM_ERRATA_764369 if SMP + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD select PINCTRL_IMX6Q @@ -494,6 +494,8 @@ config SOC_IMX6Q config SOC_IMX6SL bool "i.MX6 SoloLite support" + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 select PINCTRL_IMX6SL select SOC_IMX6 @@ -502,6 +504,8 @@ config SOC_IMX6SL config SOC_IMX6SLL bool "i.MX6 SoloLiteLite support" + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 select PINCTRL_IMX6SLL select SOC_IMX6 @@ -510,6 +514,8 @@ config SOC_IMX6SLL config SOC_IMX6SX bool "i.MX6 SoloX support" + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 select PINCTRL_IMX6SX select SOC_IMX6 diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 8fb68c0ec34c..d841bed8664d 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -89,12 +89,11 @@ void imx_anatop_post_resume(void) if (cpu_is_imx6sl()) imx_anatop_disconnect_high_snvs(false); - } void __init imx_init_revision_from_anatop(void) { - struct device_node *np; + struct device_node *np, *src_np; void __iomem *anatop_base; unsigned int revision; u32 digprog; @@ -135,9 +134,10 @@ void __init imx_init_revision_from_anatop(void) void __iomem *src_base; u32 sbmr2; - np = of_find_compatible_node(NULL, NULL, + src_np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-src"); src_base = of_iomap(np, 0); + of_node_put(src_np); WARN_ON(!src_base); sbmr2 = readl_relaxed(src_base + SRC_SBMR2); iounmap(src_base); @@ -149,6 +149,7 @@ void __init imx_init_revision_from_anatop(void) } } } + of_node_put(np); mxc_set_cpu_type(digprog >> 16 & 0xff); imx_set_soc_revision(revision); diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index b5b557fe2c49..ebc4339b8be4 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -10,7 +10,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include <linux/irqchip/arm-gic.h> + #include "common.h" #include "hardware.h" @@ -111,7 +111,6 @@ void imx_gpc_mask_all(void) gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); writel_relaxed(~0, reg_imr1 + i * 4); } - } void imx_gpc_restore_all(void) @@ -282,4 +281,5 @@ void __init imx_gpc_check_dt(void) /* map GPC, so that at least CPUidle and WARs keep working */ gpc_base = of_iomap(np, 0); } + of_node_put(np); } diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index edd26e0ffeec..284bce1112d2 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -5,29 +5,16 @@ */ #include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/cpu.h> -#include <linux/delay.h> -#include <linux/export.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/irq.h> #include <linux/irqchip.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> -#include <linux/pm_opp.h> #include <linux/pci.h> #include <linux/phy.h> -#include <linux/reboot.h> #include <linux/regmap.h> #include <linux/micrel_phy.h> #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <asm/system_misc.h> #include "common.h" #include "cpuidle.h" diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index e00818abe54d..e27a6889cc56 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -4,7 +4,6 @@ */ #include <linux/irqchip.h> -#include <linux/of.h> #include <linux/of_platform.h> #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c index 311f5e4ff723..3b0e16ccd59d 100644 --- a/arch/arm/mach-imx/mach-imx6ul.c +++ b/arch/arm/mach-imx/mach-imx6ul.c @@ -25,7 +25,6 @@ static void __init imx6ul_enet_clk_init(void) IMX6UL_GPR1_ENET_CLK_OUTPUT); else pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n"); - } static int ksz8081_phy_fixup(struct phy_device *dev) diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 2aa26928221d..cf4e9335831c 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -109,6 +109,7 @@ static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg"); dcfg_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!dcfg_base); paddr = __pa_symbol(secondary_startup); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 1c0ecad3620e..dd34dff13762 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -655,6 +655,8 @@ void __init imx6_pm_ccm_init(const char *ccm_compat) if (of_property_read_bool(np, "fsl,pmic-stby-poweroff")) imx6_pm_stby_poweroff_probe(); + + of_node_put(np); } void __init imx6q_pm_init(void) diff --git a/arch/arm/mach-imx/pm-imx7ulp.c b/arch/arm/mach-imx/pm-imx7ulp.c index 7b2f7387e662..2e756d8191fa 100644 --- a/arch/arm/mach-imx/pm-imx7ulp.c +++ b/arch/arm/mach-imx/pm-imx7ulp.c @@ -62,6 +62,7 @@ void __init imx7ulp_pm_init(void) np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1"); smc1_base = of_iomap(np, 0); + of_node_put(np); WARN_ON(!smc1_base); imx7ulp_set_lpm(ULP_PM_RUN); diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 0beea6d0217f..f52f371292ac 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -43,9 +43,6 @@ static int imx_src_reset_module(struct reset_controller_dev *rcdev, int bit; u32 val; - if (!src_base) - return -ENODEV; - if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits)) return -EINVAL; diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 1ecbea5331d6..6f875ded8419 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -410,13 +410,10 @@ static int __ref impd1_probe(struct lm_device *dev) * 5 = Key lower right */ /* We need the two MMCI GPIO entries */ - lookup->table[0].chip_label = chipname; - lookup->table[0].chip_hwnum = 3; - lookup->table[0].con_id = "wp"; - lookup->table[1].chip_label = chipname; - lookup->table[1].chip_hwnum = 4; - lookup->table[1].con_id = "cd"; - lookup->table[1].flags = GPIO_ACTIVE_LOW; + lookup->table[0] = (struct gpiod_lookup) + GPIO_LOOKUP(chipname, 3, "wp", 0); + lookup->table[1] = (struct gpiod_lookup) + GPIO_LOOKUP(chipname, 4, "cd", GPIO_ACTIVE_LOW); gpiod_add_lookup_table(lookup); } diff --git a/arch/arm/mach-iop32x/time.c b/arch/arm/mach-iop32x/time.c index 18a4df5c1baa..ae533b66fefd 100644 --- a/arch/arm/mach-iop32x/time.c +++ b/arch/arm/mach-iop32x/time.c @@ -137,13 +137,6 @@ iop_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction iop_timer_irq = { - .name = "IOP Timer Tick", - .handler = iop_timer_interrupt, - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .dev_id = &iop_clockevent, -}; - static unsigned long iop_tick_rate; unsigned long get_iop_tick_rate(void) { @@ -154,6 +147,7 @@ EXPORT_SYMBOL(get_iop_tick_rate); void __init iop_init_time(unsigned long tick_rate) { u32 timer_ctl; + int irq = IRQ_IOP32X_TIMER0; sched_clock_register(iop_read_sched_clock, 32, tick_rate); @@ -168,7 +162,9 @@ void __init iop_init_time(unsigned long tick_rate) */ write_tmr0(timer_ctl & ~IOP_TMR_EN); write_tisr(1); - setup_irq(IRQ_IOP32X_TIMER0, &iop_timer_irq); + if (request_irq(irq, iop_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, + "IOP Timer Tick", &iop_clockevent)) + pr_err("Failed to request irq() %d (IOP Timer Tick)\n", irq); iop_clockevent.cpumask = cpumask_of(0); clockevents_config_and_register(&iop_clockevent, tick_rate, 0xf, 0xfffffffe); diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index c65cfc1ad99b..049a65f47b42 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -175,13 +175,6 @@ static void __init timer_config(void) __raw_writel(0x2, mmp_timer_base + TMR_CER); } -static struct irqaction timer_irq = { - .name = "timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = timer_interrupt, - .dev_id = &ckevt, -}; - void __init mmp_timer_init(int irq, unsigned long rate) { timer_config(); @@ -190,7 +183,9 @@ void __init mmp_timer_init(int irq, unsigned long rate) ckevt.cpumask = cpumask_of(0); - setup_irq(irq, &timer_irq); + if (request_irq(irq, timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, + "timer", &ckevt)) + pr_err("Failed to request irq %d (timer)\n", irq); clocksource_register_hz(&cksrc, rate); clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA); diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index a2aa7a12b374..8d32894ecd2e 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -17,6 +17,8 @@ #include <linux/input.h> #include <linux/interrupt.h> #include <linux/leds.h> +#include <linux/mtd/nand-gpio.h> +#include <linux/mtd/partitions.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/regulator/fixed.h> @@ -294,9 +296,42 @@ struct modem_private_data { static struct modem_private_data modem_priv; +/* + * Define partitions for flash device + */ + +static struct mtd_partition partition_info[] = { + { .name = "Kernel", + .offset = 0, + .size = 3 * SZ_1M + SZ_512K }, + { .name = "u-boot", + .offset = 3 * SZ_1M + SZ_512K, + .size = SZ_256K }, + { .name = "u-boot params", + .offset = 3 * SZ_1M + SZ_512K + SZ_256K, + .size = SZ_256K }, + { .name = "Amstrad LDR", + .offset = 4 * SZ_1M, + .size = SZ_256K }, + { .name = "File system", + .offset = 4 * SZ_1M + 1 * SZ_256K, + .size = 27 * SZ_1M }, + { .name = "PBL reserved", + .offset = 32 * SZ_1M - 3 * SZ_256K, + .size = 3 * SZ_256K }, +}; + +static struct gpio_nand_platdata nand_platdata = { + .parts = partition_info, + .num_parts = ARRAY_SIZE(partition_info), +}; + static struct platform_device ams_delta_nand_device = { .name = "ams-delta-nand", .id = -1, + .dev = { + .platform_data = &nand_platdata, + }, }; #define OMAP_GPIO_LABEL "gpio-0-15" @@ -306,10 +341,14 @@ static struct gpiod_lookup_table ams_delta_nand_gpio_table = { .table = { GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_NAND_RB, "rdy", 0), - GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", 0), - GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", 0), - GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", 0), - GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 0), + GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", + GPIO_ACTIVE_LOW), + GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", + GPIO_ACTIVE_LOW), + GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", + GPIO_ACTIVE_LOW), + GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", + GPIO_ACTIVE_LOW), GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0), GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0), GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 0, "data", 0, 0), diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index d068958d6f8a..2c1e2b32b9b3 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -596,11 +596,6 @@ static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) return IRQ_HANDLED; } -static struct irqaction omap_wakeup_irq = { - .name = "peripheral wakeup", - .handler = omap_wakeup_interrupt -}; - static const struct platform_suspend_ops omap_pm_ops = { @@ -613,6 +608,7 @@ static const struct platform_suspend_ops omap_pm_ops = { static int __init omap_pm_init(void) { int error = 0; + int irq; if (!cpu_class_is_omap1()) return -ENODEV; @@ -656,9 +652,12 @@ static int __init omap_pm_init(void) arm_pm_idle = omap1_pm_idle; if (cpu_is_omap7xx()) - setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq); + irq = INT_7XX_WAKE_UP_REQ; else if (cpu_is_omap16xx()) - setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); + irq = INT_1610_WAKE_UP_REQ; + if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", + NULL)) + pr_err("Failed to request irq %d (peripheral wakeup)\n", irq); /* Program new power ramp-up time * (0 for most boards since we don't lower voltage when in deep sleep) diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 524977a31a49..de590a85a42b 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -155,15 +155,11 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction omap_mpu_timer1_irq = { - .name = "mpu_timer1", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap_mpu_timer1_interrupt, -}; - static __init void omap_init_mpu_timer(unsigned long rate) { - setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); + if (request_irq(INT_TIMER1, omap_mpu_timer1_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "mpu_timer1", NULL)) + pr_err("Failed to request irq %d (mpu_timer1)\n", INT_TIMER1); omap_mpu_timer_start(0, (rate / HZ) - 1, 1); clockevent_mpu_timer1.cpumask = cpumask_of(0); diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 0ae6c52a7d70..780fdf03c3ce 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -148,15 +148,11 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction omap_32k_timer_irq = { - .name = "32KHz timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap_32k_timer_interrupt, -}; - static __init void omap_init_32k_timer(void) { - setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); + if (request_irq(INT_OS_TIMER, omap_32k_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "32KHz timer", NULL)) + pr_err("Failed to request irq %d(32KHz timer)\n", INT_OS_TIMER); clockevent_32k_timer.cpumask = cpumask_of(0); clockevents_config_and_register(&clockevent_32k_timer, diff --git a/arch/arm/mach-omap2/.gitignore b/arch/arm/mach-omap2/.gitignore index 79a8d6ea7152..dc7be7556736 100644 --- a/arch/arm/mach-omap2/.gitignore +++ b/arch/arm/mach-omap2/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only pm-asm-offsets.h diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 532a3e4b98c6..090a8aafb25e 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -109,6 +109,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, int index) { struct omap3_idle_statedata *cx = &omap3_idle_data[index]; + int error; if (omap_irq_pending() || need_resched()) goto return_sleep_time; @@ -125,8 +126,11 @@ static int omap3_enter_idle(struct cpuidle_device *dev, * Call idle CPU PM enter notifier chain so that * VFP context is saved. */ - if (cx->mpu_state == PWRDM_POWER_OFF) - cpu_pm_enter(); + if (cx->mpu_state == PWRDM_POWER_OFF) { + error = cpu_pm_enter(); + if (error) + goto out_clkdm_set; + } /* Execute ARM wfi */ omap_sram_idle(); @@ -139,6 +143,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) cpu_pm_exit(); +out_clkdm_set: /* Re-allow idle for C1 */ if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index fe75d4fa6073..6f5f89711f25 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -122,6 +122,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, { struct idle_statedata *cx = state_ptr + index; u32 mpuss_can_lose_context = 0; + int error; /* * CPU0 has to wait and stay ON until CPU1 is OFF state. @@ -159,7 +160,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, * Call idle CPU PM enter notifier chain so that * VFP and per CPU interrupt context is saved. */ - cpu_pm_enter(); + error = cpu_pm_enter(); + if (error) + goto cpu_pm_out; if (dev->cpu == 0) { pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); @@ -169,13 +172,17 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, * Call idle CPU cluster PM enter notifier chain * to save GIC and wakeupgen context. */ - if (mpuss_can_lose_context) - cpu_cluster_pm_enter(); + if (mpuss_can_lose_context) { + error = cpu_cluster_pm_enter(); + if (error) + goto cpu_cluster_pm_out; + } } omap4_enter_lowpower(dev->cpu, cx->cpu_state); cpu_done[dev->cpu] = true; +cpu_cluster_pm_out: /* Wakeup CPU1 only if it is not offlined */ if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { @@ -198,18 +205,19 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, } /* - * Call idle CPU PM exit notifier chain to restore - * VFP and per CPU IRQ context. - */ - cpu_pm_exit(); - - /* * Call idle CPU cluster PM exit notifier chain * to restore GIC and wakeupgen context. */ if (dev->cpu == 0 && mpuss_can_lose_context) cpu_cluster_pm_exit(); + /* + * Call idle CPU PM exit notifier chain to restore + * VFP and per CPU IRQ context. + */ + cpu_pm_exit(); + +cpu_pm_out: tick_broadcast_exit(); fail: diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c index d00e3c72e37d..f70d561f37f7 100644 --- a/arch/arm/mach-omap2/omap-secure.c +++ b/arch/arm/mach-omap2/omap-secure.c @@ -5,7 +5,7 @@ * Copyright (C) 2011 Texas Instruments, Inc. * Santosh Shilimkar <santosh.shilimkar@ti.com> * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> - * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * Copyright (C) 2013 Pali Rohár <pali@kernel.org> */ #include <linux/arm-smccc.h> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index ba8c486c0454..4aaa95706d39 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -5,7 +5,7 @@ * Copyright (C) 2011 Texas Instruments, Inc. * Santosh Shilimkar <santosh.shilimkar@ti.com> * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> - * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * Copyright (C) 2013 Pali Rohár <pali@kernel.org> */ #ifndef OMAP_ARCH_OMAP_SECURE_H #define OMAP_ARCH_OMAP_SECURE_H diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S index d4832845a4e8..7376f528034d 100644 --- a/arch/arm/mach-omap2/omap-smc.S +++ b/arch/arm/mach-omap2/omap-smc.S @@ -6,7 +6,7 @@ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com> * * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> - * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * Copyright (C) 2013 Pali Rohár <pali@kernel.org> */ #include <linux/linkage.h> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 17d337ed18be..82706af307de 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3148,15 +3148,14 @@ static int omap_hwmod_check_sysc(struct device *dev, /** * omap_hwmod_init_regbits - init sysconfig specific register bits * @dev: struct device + * @oh: module * @data: module data * @sysc_fields: new sysc configuration */ -static int omap_hwmod_init_regbits(struct device *dev, +static int omap_hwmod_init_regbits(struct device *dev, struct omap_hwmod *oh, const struct ti_sysc_module_data *data, struct sysc_regbits **sysc_fields) { - *sysc_fields = NULL; - switch (data->cap->type) { case TI_SYSC_OMAP2: case TI_SYSC_OMAP2_TIMER: @@ -3191,6 +3190,12 @@ static int omap_hwmod_init_regbits(struct device *dev, *sysc_fields = &omap_hwmod_sysc_type_usb_host_fs; break; default: + *sysc_fields = NULL; + if (!oh->class->sysc->sysc_fields) + return 0; + + dev_err(dev, "sysc_fields not found\n"); + return -EINVAL; } @@ -3356,9 +3361,9 @@ static int omap_hwmod_check_module(struct device *dev, if (!oh->class->sysc) return -ENODEV; - if (sysc_fields != oh->class->sysc->sysc_fields) - dev_warn(dev, "sysc_fields %p != %p\n", sysc_fields, - oh->class->sysc->sysc_fields); + if (oh->class->sysc->sysc_fields && + sysc_fields != oh->class->sysc->sysc_fields) + dev_warn(dev, "sysc_fields mismatch\n"); if (rev_offs != oh->class->sysc->rev_offs) dev_warn(dev, "rev_offs %08x != %08x\n", rev_offs, @@ -3574,7 +3579,7 @@ int omap_hwmod_init_module(struct device *dev, cookie->data = oh; - error = omap_hwmod_init_regbits(dev, data, &sysc_fields); + error = omap_hwmod_init_regbits(dev, oh, data, &sysc_fields); if (error) return error; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h index 5ef76fe3f33d..fa2ff41f84b9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -24,16 +24,11 @@ extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup; extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr; extern struct omap_hwmod_ocp_if am33xx_mpu__prcm; extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main; -extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main; extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main; extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx; extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc; extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc; extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2; -extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc; -extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0; -extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1; -extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2; extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc; extern struct omap_hwmod am33xx_l3_main_hwmod; @@ -42,7 +37,6 @@ extern struct omap_hwmod am33xx_l3_instr_hwmod; extern struct omap_hwmod am33xx_l4_ls_hwmod; extern struct omap_hwmod am33xx_l4_wkup_hwmod; extern struct omap_hwmod am33xx_mpu_hwmod; -extern struct omap_hwmod am33xx_pruss_hwmod; extern struct omap_hwmod am33xx_gfx_hwmod; extern struct omap_hwmod am33xx_prcm_hwmod; extern struct omap_hwmod am33xx_ocmcram_hwmod; @@ -52,10 +46,6 @@ extern struct omap_hwmod am33xx_gpmc_hwmod; extern struct omap_hwmod am33xx_rtc_hwmod; extern struct omap_hwmod am33xx_timer1_hwmod; extern struct omap_hwmod am33xx_timer2_hwmod; -extern struct omap_hwmod am33xx_tpcc_hwmod; -extern struct omap_hwmod am33xx_tptc0_hwmod; -extern struct omap_hwmod am33xx_tptc1_hwmod; -extern struct omap_hwmod am33xx_tptc2_hwmod; extern struct omap_hwmod_class am33xx_emif_hwmod_class; extern struct omap_hwmod_class am33xx_l4_hwmod_class; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c index ac7d5bb1a02f..0ebbfbb4fb1c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c @@ -74,14 +74,6 @@ struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* pru-icss -> l3 main */ -struct omap_hwmod_ocp_if am33xx_pruss__l3_main = { - .master = &am33xx_pruss_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* gfx -> l3 main */ struct omap_hwmod_ocp_if am33xx_gfx__l3_main = { .master = &am33xx_gfx_hwmod, @@ -122,38 +114,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = { .user = OCP_USER_MPU, }; -/* l3 main -> tpcc */ -struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tpcc_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc0 */ -struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc0_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc1 */ -struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc1_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc2 */ -struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc2_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU, -}; - /* l3 main -> ocmc */ struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { .master = &am33xx_l3_main_hwmod, diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index 78ec1bc8e3a1..dca5a3a7b97c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -133,34 +133,6 @@ struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { .name = "wkup_m3", }; -/* - * 'pru-icss' class - * Programmable Real-Time Unit and Industrial Communication Subsystem - */ -static struct omap_hwmod_class am33xx_pruss_hwmod_class = { - .name = "pruss", -}; - -static struct omap_hwmod_rst_info am33xx_pruss_resets[] = { - { .name = "pruss", .rst_shift = 1 }, -}; - -/* pru-icss */ -/* Pseudo hwmod for reset control purpose only */ -struct omap_hwmod am33xx_pruss_hwmod = { - .name = "pruss", - .class = &am33xx_pruss_hwmod_class, - .clkdm_name = "pruss_ocp_clkdm", - .main_clk = "pruss_ocp_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_pruss_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_pruss_resets), -}; - /* gfx */ /* Pseudo hwmod for reset control purpose only */ static struct omap_hwmod_class am33xx_gfx_hwmod_class = { @@ -393,80 +365,6 @@ struct omap_hwmod am33xx_timer2_hwmod = { }, }; -/* tpcc */ -static struct omap_hwmod_class am33xx_tpcc_hwmod_class = { - .name = "tpcc", -}; - -struct omap_hwmod am33xx_tpcc_hwmod = { - .name = "tpcc", - .class = &am33xx_tpcc_hwmod_class, - .clkdm_name = "l3_clkdm", - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x10, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSC_HAS_MIDLEMODE), - .idlemodes = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -/* 'tptc' class */ -static struct omap_hwmod_class am33xx_tptc_hwmod_class = { - .name = "tptc", - .sysc = &am33xx_tptc_sysc, -}; - -/* tptc0 */ -struct omap_hwmod am33xx_tptc0_hwmod = { - .name = "tptc0", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* tptc1 */ -struct omap_hwmod am33xx_tptc1_hwmod = { - .name = "tptc1", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* tptc2 */ -struct omap_hwmod am33xx_tptc2_hwmod = { - .name = "tptc2", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - static void omap_hwmod_am33xx_clkctrl(void) { CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET); @@ -481,12 +379,7 @@ static void omap_hwmod_am33xx_clkctrl(void) CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET); CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET); - CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET); CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET); CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); @@ -494,7 +387,6 @@ static void omap_hwmod_am33xx_clkctrl(void) static void omap_hwmod_am33xx_rst(void) { - RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET); RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET); RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET); } @@ -518,12 +410,7 @@ static void omap_hwmod_am43xx_clkctrl(void) CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET); - CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET); CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET); - CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET); CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET); CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); @@ -531,9 +418,7 @@ static void omap_hwmod_am43xx_clkctrl(void) static void omap_hwmod_am43xx_rst(void) { - RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET); RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); - RSTST(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTST_OFFSET); RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); } diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index f1ea8c604595..c64b735c8acc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -233,14 +233,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l4 hs -> pru-icss */ -static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = { - .master = &am33xx_l4_hs_hwmod, - .slave = &am33xx_pruss_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main -> debugss */ static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = { .master = &am33xx_l3_main_hwmod, @@ -292,7 +284,6 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__l3_instr, &am33xx_l3_main__gfx, &am33xx_l3_s__l3_main, - &am33xx_pruss__l3_main, &am33xx_wkup_m3__l4_wkup, &am33xx_gfx__l3_main, &am33xx_l3_main__debugss, @@ -302,13 +293,8 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_wkup__smartreflex1, &am33xx_l4_wkup__timer1, &am33xx_l4_wkup__rtc, - &am33xx_l4_hs__pruss, &am33xx_l4_ls__timer2, - &am33xx_l3_main__tpcc, &am33xx_l3_s__gpmc, - &am33xx_l3_main__tptc0, - &am33xx_l3_main__tptc1, - &am33xx_l3_main__tptc2, &am33xx_l3_main__ocmc, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index d0867dbd788e..d2203f44af88 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -156,75 +156,6 @@ static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = { }, }; -/* dss */ - -static struct omap_hwmod am43xx_dss_core_hwmod = { - .name = "dss_core", - .class = &omap2_dss_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "disp_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* dispc */ - -static struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = { - .manager_count = 1, - .has_framedonetv_irq = 0 -}; - -static struct omap_hwmod_class_sysconfig am43xx_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | - SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_MIDLEMODE), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am43xx_dispc_hwmod_class = { - .name = "dispc", - .sysc = &am43xx_dispc_sysc, -}; - -static struct omap_hwmod am43xx_dss_dispc_hwmod = { - .name = "dss_dispc", - .class = &am43xx_dispc_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "disp_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, - }, - }, - .dev_attr = &am43xx_dss_dispc_dev_attr, - .parent_hwmod = &am43xx_dss_core_hwmod, -}; - -/* rfbi */ - -static struct omap_hwmod am43xx_dss_rfbi_hwmod = { - .name = "dss_rfbi", - .class = &omap2_rfbi_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "disp_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, - }, - }, - .parent_hwmod = &am43xx_dss_core_hwmod, -}; - - /* Interfaces */ static struct omap_hwmod_ocp_if am43xx_l3_main__emif = { .master = &am33xx_l3_main_hwmod, @@ -254,13 +185,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_pruss_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = { .master = &am33xx_l4_wkup_hwmod, .slave = &am33xx_smartreflex0_hwmod, @@ -310,37 +234,8 @@ static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -static struct omap_hwmod_ocp_if am43xx_dss__l3_main = { - .master = &am43xx_dss_core_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_ls__dss = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am43xx_dss_core_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_dispc = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am43xx_dss_dispc_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_rfbi = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am43xx_dss_rfbi_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_wkup__synctimer, - &am43xx_l3_main__pruss, &am33xx_mpu__l3_main, &am33xx_mpu__prcm, &am33xx_l3_s__l4_ls, @@ -351,7 +246,6 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__gfx, &am33xx_l3_s__l3_main, &am43xx_l3_main__emif, - &am33xx_pruss__l3_main, &am43xx_wkup_m3__l4_wkup, &am33xx_gfx__l3_main, &am43xx_l4_wkup__wkup_m3, @@ -360,18 +254,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am43xx_l4_wkup__smartreflex1, &am43xx_l4_wkup__timer1, &am33xx_l4_ls__timer2, - &am33xx_l3_main__tpcc, &am33xx_l3_s__gpmc, - &am33xx_l3_main__tptc0, - &am33xx_l3_main__tptc1, - &am33xx_l3_main__tptc2, &am33xx_l3_main__ocmc, &am43xx_l3_s__usbotgss0, &am43xx_l3_s__usbotgss1, - &am43xx_dss__l3_main, - &am43xx_l4_ls__dss, - &am43xx_l4_ls__dss_dispc, - &am43xx_l4_ls__dss_rfbi, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index b7c51ea8c9a6..33f6596c03f7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -356,306 +356,6 @@ static struct omap_hwmod omap44xx_debugss_hwmod = { }; /* - * 'dsp' class - * dsp sub-system - */ - -static struct omap_hwmod_class omap44xx_dsp_hwmod_class = { - .name = "dsp", -}; - -/* dsp */ -static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = { - { .name = "dsp", .rst_shift = 0 }, -}; - -static struct omap_hwmod omap44xx_dsp_hwmod = { - .name = "dsp", - .class = &omap44xx_dsp_hwmod_class, - .clkdm_name = "tesla_clkdm", - .rst_lines = omap44xx_dsp_resets, - .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), - .main_clk = "dpll_iva_m4x2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET, - .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, - .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - -/* - * 'dss' class - * display sub-system - */ - -static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { - .rev_offs = 0x0000, - .syss_offs = 0x0014, - .sysc_flags = SYSS_HAS_RESET_STATUS, -}; - -static struct omap_hwmod_class omap44xx_dss_hwmod_class = { - .name = "dss", - .sysc = &omap44xx_dss_sysc, - .reset = omap_dss_reset, -}; - -/* dss */ -static struct omap_hwmod_opt_clk dss_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, - { .role = "tv_clk", .clk = "dss_tv_clk" }, - { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, -}; - -static struct omap_hwmod omap44xx_dss_hwmod = { - .name = "dss_core", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .class = &omap44xx_dss_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = dss_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -}; - -/* - * 'dispc' class - * display controller - */ - -static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | - SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap44xx_dispc_hwmod_class = { - .name = "dispc", - .sysc = &omap44xx_dispc_sysc, -}; - -/* dss_dispc */ -static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = { - .manager_count = 3, - .has_framedonetv_irq = 1 -}; - -static struct omap_hwmod omap44xx_dss_dispc_hwmod = { - .name = "dss_dispc", - .class = &omap44xx_dispc_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .dev_attr = &omap44xx_dss_dispc_dev_attr, - .parent_hwmod = &omap44xx_dss_hwmod, -}; - -/* - * 'dsi' class - * display serial interface controller - */ - -static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap44xx_dsi_hwmod_class = { - .name = "dsi", - .sysc = &omap44xx_dsi_sysc, -}; - -/* dss_dsi1 */ -static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { - .name = "dss_dsi1", - .class = &omap44xx_dsi_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .opt_clks = dss_dsi1_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), - .parent_hwmod = &omap44xx_dss_hwmod, -}; - -/* dss_dsi2 */ -static struct omap_hwmod_opt_clk dss_dsi2_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { - .name = "dss_dsi2", - .class = &omap44xx_dsi_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .opt_clks = dss_dsi2_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), - .parent_hwmod = &omap44xx_dss_hwmod, -}; - -/* - * 'hdmi' class - * hdmi controller - */ - -static struct omap_hwmod_class_sysconfig omap44xx_hdmi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = { - .name = "hdmi", - .sysc = &omap44xx_hdmi_sysc, -}; - -/* dss_hdmi */ -static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, - { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, -}; - -static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { - .name = "dss_hdmi", - .class = &omap44xx_hdmi_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - /* - * HDMI audio requires to use no-idle mode. Hence, - * set idle mode by software. - */ - .flags = HWMOD_SWSUP_SIDLE | HWMOD_OPT_CLKS_NEEDED, - .main_clk = "dss_48mhz_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .opt_clks = dss_hdmi_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), - .parent_hwmod = &omap44xx_dss_hwmod, -}; - -/* - * 'rfbi' class - * remote frame buffer interface - */ - -static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = { - .name = "rfbi", - .sysc = &omap44xx_rfbi_sysc, -}; - -/* dss_rfbi */ -static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { - { .role = "ick", .clk = "l3_div_ck" }, -}; - -static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { - .name = "dss_rfbi", - .class = &omap44xx_rfbi_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .opt_clks = dss_rfbi_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), - .parent_hwmod = &omap44xx_dss_hwmod, -}; - -/* - * 'venc' class - * video encoder - */ - -static struct omap_hwmod_class omap44xx_venc_hwmod_class = { - .name = "venc", -}; - -/* dss_venc */ -static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = { - { .role = "tv_clk", .clk = "dss_tv_clk" }, -}; - -static struct omap_hwmod omap44xx_dss_venc_hwmod = { - .name = "dss_venc", - .class = &omap44xx_venc_hwmod_class, - .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_tv_clk", - .flags = HWMOD_OPT_CLKS_NEEDED, - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, - }, - }, - .parent_hwmod = &omap44xx_dss_hwmod, - .opt_clks = dss_venc_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), -}; - - - -/* * 'emif' class * external memory interface no1 */ @@ -737,39 +437,6 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { }, }; - -/* - * 'ipu' class - * imaging processor unit - */ - -static struct omap_hwmod_class omap44xx_ipu_hwmod_class = { - .name = "ipu", -}; - -/* ipu */ -static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = { - { .name = "cpu0", .rst_shift = 0 }, - { .name = "cpu1", .rst_shift = 1 }, -}; - -static struct omap_hwmod omap44xx_ipu_hwmod = { - .name = "ipu", - .class = &omap44xx_ipu_hwmod_class, - .clkdm_name = "ducati_clkdm", - .rst_lines = omap44xx_ipu_resets, - .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), - .main_clk = "ducati_clk_mux_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET, - .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, - .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - /* * 'iss' class * external images sensor pixel data processor @@ -1236,22 +903,6 @@ static struct omap_hwmod_ocp_if omap44xx_ocp_wp_noc__l3_instr = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* dsp -> l3_main_1 */ -static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = { - .master = &omap44xx_dsp_hwmod, - .slave = &omap44xx_l3_main_1_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* dss -> l3_main_1 */ -static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = { - .master = &omap44xx_dss_hwmod, - .slave = &omap44xx_l3_main_1_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_2 -> l3_main_1 */ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = { .master = &omap44xx_l3_main_2_hwmod, @@ -1284,14 +935,6 @@ static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* ipu -> l3_main_2 */ -static struct omap_hwmod_ocp_if omap44xx_ipu__l3_main_2 = { - .master = &omap44xx_ipu_hwmod, - .slave = &omap44xx_l3_main_2_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* iss -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = { .master = &omap44xx_iss_hwmod, @@ -1364,14 +1007,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* dsp -> l4_abe */ -static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = { - .master = &omap44xx_dsp_hwmod, - .slave = &omap44xx_l4_abe_hwmod, - .clk = "ocp_abe_iclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_1 -> l4_abe */ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = { .master = &omap44xx_l3_main_1_hwmod, @@ -1476,142 +1111,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* dsp -> iva */ -static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { - .master = &omap44xx_dsp_hwmod, - .slave = &omap44xx_iva_hwmod, - .clk = "dpll_iva_m5x2_ck", - .user = OCP_USER_DSP, -}; - -/* dsp -> sl2if */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = { - .master = &omap44xx_dsp_hwmod, - .slave = &omap44xx_sl2if_hwmod, - .clk = "dpll_iva_m5x2_ck", - .user = OCP_USER_DSP, -}; - -/* l4_cfg -> dsp */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_dsp_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_dispc */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_dispc_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_dispc */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_dispc_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_dsi1 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_dsi1_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_dsi1 */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_dsi1_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_dsi2 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_dsi2_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_dsi2 */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_dsi2_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_hdmi */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_hdmi_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_hdmi */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_hdmi_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_rfbi */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_rfbi_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_rfbi */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_rfbi_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - -/* l3_main_2 -> dss_venc */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_dss_venc_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_SDMA, -}; - -/* l4_per -> dss_venc */ -static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { - .master = &omap44xx_l4_per_hwmod, - .slave = &omap44xx_dss_venc_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU, -}; - /* l3_main_2 -> gpmc */ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = { .master = &omap44xx_l3_main_2_hwmod, @@ -1620,14 +1119,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_2 -> ipu */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_ipu_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_2 -> iss */ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { .master = &omap44xx_l3_main_2_hwmod, @@ -1762,13 +1253,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_iva__l3_instr, &omap44xx_l3_main_3__l3_instr, &omap44xx_ocp_wp_noc__l3_instr, - &omap44xx_dsp__l3_main_1, - &omap44xx_dss__l3_main_1, &omap44xx_l3_main_2__l3_main_1, &omap44xx_l4_cfg__l3_main_1, &omap44xx_mpu__l3_main_1, &omap44xx_debugss__l3_main_2, - &omap44xx_ipu__l3_main_2, &omap44xx_iss__l3_main_2, &omap44xx_iva__l3_main_2, &omap44xx_l3_main_1__l3_main_2, @@ -1778,7 +1266,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_1__l3_main_3, &omap44xx_l3_main_2__l3_main_3, &omap44xx_l4_cfg__l3_main_3, - &omap44xx_dsp__l4_abe, &omap44xx_l3_main_1__l4_abe, &omap44xx_mpu__l4_abe, &omap44xx_l3_main_1__l4_cfg, @@ -1792,25 +1279,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_wkup__ctrl_module_wkup, &omap44xx_l4_wkup__ctrl_module_pad_wkup, &omap44xx_l3_instr__debugss, - &omap44xx_dsp__iva, - /* &omap44xx_dsp__sl2if, */ - &omap44xx_l4_cfg__dsp, - &omap44xx_l3_main_2__dss, - &omap44xx_l4_per__dss, - &omap44xx_l3_main_2__dss_dispc, - &omap44xx_l4_per__dss_dispc, - &omap44xx_l3_main_2__dss_dsi1, - &omap44xx_l4_per__dss_dsi1, - &omap44xx_l3_main_2__dss_dsi2, - &omap44xx_l4_per__dss_dsi2, - &omap44xx_l3_main_2__dss_hdmi, - &omap44xx_l4_per__dss_hdmi, - &omap44xx_l3_main_2__dss_rfbi, - &omap44xx_l4_per__dss_rfbi, - &omap44xx_l3_main_2__dss_venc, - &omap44xx_l4_per__dss_venc, &omap44xx_l3_main_2__gpmc, - &omap44xx_l3_main_2__ipu, &omap44xx_l3_main_2__iss, /* &omap44xx_iva__sl2if, */ &omap44xx_l3_main_2__iva, diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index ad398f6bc011..08f34f4732fd 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -227,240 +227,6 @@ static struct omap_hwmod omap54xx_counter_32k_hwmod = { }; /* - * 'dss' class - * display sub-system - */ -static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { - .rev_offs = 0x0000, - .syss_offs = 0x0014, - .sysc_flags = SYSS_HAS_RESET_STATUS, -}; - -static struct omap_hwmod_class omap54xx_dss_hwmod_class = { - .name = "dss", - .sysc = &omap54xx_dss_sysc, - .reset = omap_dss_reset, -}; - -/* dss */ -static struct omap_hwmod_opt_clk dss_opt_clks[] = { - { .role = "32khz_clk", .clk = "dss_32khz_clk" }, - { .role = "sys_clk", .clk = "dss_sys_clk" }, - { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, -}; - -static struct omap_hwmod omap54xx_dss_hwmod = { - .name = "dss_core", - .class = &omap54xx_dss_hwmod_class, - .clkdm_name = "dss_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = dss_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -}; - -/* - * 'dispc' class - * display controller - */ - -static struct omap_hwmod_class_sysconfig omap54xx_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | - SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap54xx_dispc_hwmod_class = { - .name = "dispc", - .sysc = &omap54xx_dispc_sysc, -}; - -/* dss_dispc */ -static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -/* dss_dispc dev_attr */ -static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { - .has_framedonetv_irq = 1, - .manager_count = 4, -}; - -static struct omap_hwmod omap54xx_dss_dispc_hwmod = { - .name = "dss_dispc", - .class = &omap54xx_dispc_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_dispc_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), - .dev_attr = &dss_dispc_dev_attr, - .parent_hwmod = &omap54xx_dss_hwmod, -}; - -/* - * 'dsi1' class - * display serial interface controller - */ - -static struct omap_hwmod_class_sysconfig omap54xx_dsi1_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap54xx_dsi1_hwmod_class = { - .name = "dsi1", - .sysc = &omap54xx_dsi1_sysc, -}; - -/* dss_dsi1_a */ -static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { - .name = "dss_dsi1", - .class = &omap54xx_dsi1_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_dsi1_a_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), - .parent_hwmod = &omap54xx_dss_hwmod, -}; - -/* dss_dsi1_c */ -static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { - .name = "dss_dsi2", - .class = &omap54xx_dsi1_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_dsi1_c_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), - .parent_hwmod = &omap54xx_dss_hwmod, -}; - -/* - * 'hdmi' class - * hdmi controller - */ - -static struct omap_hwmod_class_sysconfig omap54xx_hdmi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class omap54xx_hdmi_hwmod_class = { - .name = "hdmi", - .sysc = &omap54xx_hdmi_sysc, -}; - -static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, -}; - -static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { - .name = "dss_hdmi", - .class = &omap54xx_hdmi_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_48mhz_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_hdmi_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), - .parent_hwmod = &omap54xx_dss_hwmod, -}; - -/* - * 'rfbi' class - * remote frame buffer interface - */ - -static struct omap_hwmod_class_sysconfig omap54xx_rfbi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap54xx_rfbi_hwmod_class = { - .name = "rfbi", - .sysc = &omap54xx_rfbi_sysc, -}; - -/* dss_rfbi */ -static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { - { .role = "ick", .clk = "l3_iclk_div" }, -}; - -static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { - .name = "dss_rfbi", - .class = &omap54xx_rfbi_hwmod_class, - .clkdm_name = "dss_clkdm", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_rfbi_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), - .parent_hwmod = &omap54xx_dss_hwmod, -}; - -/* * 'emif' class * external memory interface no1 (wrapper) */ @@ -908,54 +674,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_2 -> dss */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss_dispc */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_dispc_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss_dsi1_a */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_dsi1_a_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss_dsi1_c */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_dsi1_c_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss_hdmi */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_hdmi_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> dss_rfbi */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = { - .master = &omap54xx_l3_main_2_hwmod, - .slave = &omap54xx_dss_rfbi_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* mpu -> emif1 */ static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { .master = &omap54xx_mpu_hwmod, @@ -1030,12 +748,6 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l3_main_1__l4_wkup, &omap54xx_mpu__mpu_private, &omap54xx_l4_wkup__counter_32k, - &omap54xx_l3_main_2__dss, - &omap54xx_l3_main_2__dss_dispc, - &omap54xx_l3_main_2__dss_dsi1_a, - &omap54xx_l3_main_2__dss_dsi1_c, - &omap54xx_l3_main_2__dss_hdmi, - &omap54xx_l3_main_2__dss_rfbi, &omap54xx_mpu__emif1, &omap54xx_mpu__emif2, &omap54xx_l4_cfg__mpu, diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index acef3733db4c..e95668bdbc3f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -277,203 +277,6 @@ static struct omap_hwmod dra7xx_ctrl_module_wkup_hwmod = { }; /* - * 'tpcc' class - * - */ -static struct omap_hwmod_class dra7xx_tpcc_hwmod_class = { - .name = "tpcc", -}; - -static struct omap_hwmod dra7xx_tpcc_hwmod = { - .name = "tpcc", - .class = &dra7xx_tpcc_hwmod_class, - .clkdm_name = "l3main1_clkdm", - .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET, - }, - }, -}; - -/* - * 'tptc' class - * - */ -static struct omap_hwmod_class dra7xx_tptc_hwmod_class = { - .name = "tptc", -}; - -/* tptc0 */ -static struct omap_hwmod dra7xx_tptc0_hwmod = { - .name = "tptc0", - .class = &dra7xx_tptc_hwmod_class, - .clkdm_name = "l3main1_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, - .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - -/* tptc1 */ -static struct omap_hwmod dra7xx_tptc1_hwmod = { - .name = "tptc1", - .class = &dra7xx_tptc_hwmod_class, - .clkdm_name = "l3main1_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, - .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - -/* - * 'dss' class - * - */ - -static struct omap_hwmod_class_sysconfig dra7xx_dss_sysc = { - .rev_offs = 0x0000, - .syss_offs = 0x0014, - .sysc_flags = SYSS_HAS_RESET_STATUS, -}; - -static struct omap_hwmod_class dra7xx_dss_hwmod_class = { - .name = "dss", - .sysc = &dra7xx_dss_sysc, - .reset = omap_dss_reset, -}; - -/* dss */ -static struct omap_hwmod_opt_clk dss_opt_clks[] = { - { .role = "dss_clk", .clk = "dss_dss_clk" }, - { .role = "hdmi_phy_clk", .clk = "dss_48mhz_clk" }, - { .role = "32khz_clk", .clk = "dss_32khz_clk" }, - { .role = "video2_clk", .clk = "dss_video2_clk" }, - { .role = "video1_clk", .clk = "dss_video1_clk" }, - { .role = "hdmi_clk", .clk = "dss_hdmi_clk" }, - { .role = "hdcp_clk", .clk = "dss_deshdcp_clk" }, -}; - -static struct omap_hwmod dra7xx_dss_hwmod = { - .name = "dss_core", - .class = &dra7xx_dss_hwmod_class, - .clkdm_name = "dss_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_DSS_DSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = dss_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -}; - -/* - * 'dispc' class - * display controller - */ - -static struct omap_hwmod_class_sysconfig dra7xx_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | - SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class dra7xx_dispc_hwmod_class = { - .name = "dispc", - .sysc = &dra7xx_dispc_sysc, -}; - -/* dss_dispc */ -/* dss_dispc dev_attr */ -static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { - .has_framedonetv_irq = 1, - .manager_count = 4, -}; - -static struct omap_hwmod dra7xx_dss_dispc_hwmod = { - .name = "dss_dispc", - .class = &dra7xx_dispc_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_dss_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .dev_attr = &dss_dispc_dev_attr, - .parent_hwmod = &dra7xx_dss_hwmod, -}; - -/* - * 'hdmi' class - * hdmi controller - */ - -static struct omap_hwmod_class_sysconfig dra7xx_hdmi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class dra7xx_hdmi_hwmod_class = { - .name = "hdmi", - .sysc = &dra7xx_hdmi_sysc, -}; - -/* dss_hdmi */ - -static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_hdmi_clk" }, -}; - -static struct omap_hwmod dra7xx_dss_hdmi_hwmod = { - .name = "dss_hdmi", - .class = &dra7xx_hdmi_hwmod_class, - .clkdm_name = "dss_clkdm", - .main_clk = "dss_48mhz_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, - .opt_clks = dss_hdmi_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), - .parent_hwmod = &dra7xx_dss_hwmod, -}; - - - - - -/* * 'gpmc' class * */ @@ -1077,54 +880,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_1 -> tpcc */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tpcc = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_tpcc_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU, -}; - -/* l3_main_1 -> tptc0 */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc0 = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_tptc0_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU, -}; - -/* l3_main_1 -> tptc1 */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc1 = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_tptc1_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU, -}; - -/* l3_main_1 -> dss */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dss = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_dss_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_1 -> dispc */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dispc = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_dss_dispc_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_1 -> dispc */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_dss_hdmi_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_1 -> gpmc */ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = { .master = &dra7xx_l3_main_1_hwmod, @@ -1309,12 +1064,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l3_main_1__bb2d, &dra7xx_l4_wkup__counter_32k, &dra7xx_l4_wkup__ctrl_module_wkup, - &dra7xx_l3_main_1__tpcc, - &dra7xx_l3_main_1__tptc0, - &dra7xx_l3_main_1__tptc1, - &dra7xx_l3_main_1__dss, - &dra7xx_l3_main_1__dispc, - &dra7xx_l3_main_1__hdmi, &dra7xx_l3_main_1__gpmc, &dra7xx_l4_cfg__mpu, &dra7xx_l3_main_1__pciess1, diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index 83230d9ce5ed..6a9f1ad9d413 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -129,13 +129,6 @@ static struct omap_hwmod dm81xx_alwon_l3_med_hwmod = { .flags = HWMOD_NO_IDLEST, }; -static struct omap_hwmod dm81xx_alwon_l3_fast_hwmod = { - .name = "l3_fast", - .clkdm_name = "alwon_l3_fast_clkdm", - .class = &l3_hwmod_class, - .flags = HWMOD_NO_IDLEST, -}; - /* * L4 standard peripherals, see TRM table 1-12 for devices using this. * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock. @@ -867,62 +860,6 @@ static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = { .user = OCP_USER_MPU, }; -/* CPSW on dm814x */ -static struct omap_hwmod_class_sysconfig dm814x_cpgmac_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x8, - .syss_offs = 0x4, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | - SYSS_HAS_RESET_STATUS, - .idlemodes = SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | - MSTANDBY_NO, - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class dm814x_cpgmac0_hwmod_class = { - .name = "cpgmac0", - .sysc = &dm814x_cpgmac_sysc, -}; - -static struct omap_hwmod dm814x_cpgmac0_hwmod = { - .name = "cpgmac0", - .class = &dm814x_cpgmac0_hwmod_class, - .clkdm_name = "alwon_ethernet_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, - .main_clk = "cpsw_125mhz_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_class dm814x_mdio_hwmod_class = { - .name = "davinci_mdio", -}; - -static struct omap_hwmod dm814x_mdio_hwmod = { - .name = "davinci_mdio", - .class = &dm814x_mdio_hwmod_class, - .clkdm_name = "alwon_ethernet_clkdm", - .main_clk = "cpsw_125mhz_gclk", -}; - -static struct omap_hwmod_ocp_if dm814x_l4_hs__cpgmac0 = { - .master = &dm81xx_l4_hs_hwmod, - .slave = &dm814x_cpgmac0_hwmod, - .clk = "cpsw_125mhz_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if dm814x_cpgmac0__mdio = { - .master = &dm814x_cpgmac0_hwmod, - .slave = &dm814x_mdio_hwmod, - .user = OCP_USER_MPU, - .flags = HWMOD_NO_IDLEST, -}; - /* EMAC Ethernet */ static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = { .rev_offs = 0x0, @@ -1321,154 +1258,6 @@ static struct omap_hwmod_ocp_if dm81xx_l4_ls__spinbox = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_class dm81xx_tpcc_hwmod_class = { - .name = "tpcc", -}; - -static struct omap_hwmod dm81xx_tpcc_hwmod = { - .name = "tpcc", - .class = &dm81xx_tpcc_hwmod_class, - .clkdm_name = "alwon_l3s_clkdm", - .main_clk = "sysclk4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_TPCC_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tpcc = { - .master = &dm81xx_alwon_l3_fast_hwmod, - .slave = &dm81xx_tpcc_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_class dm81xx_tptc0_hwmod_class = { - .name = "tptc0", -}; - -static struct omap_hwmod dm81xx_tptc0_hwmod = { - .name = "tptc0", - .class = &dm81xx_tptc0_hwmod_class, - .clkdm_name = "alwon_l3s_clkdm", - .main_clk = "sysclk4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_TPTC0_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc0 = { - .master = &dm81xx_alwon_l3_fast_hwmod, - .slave = &dm81xx_tptc0_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if dm81xx_tptc0__alwon_l3_fast = { - .master = &dm81xx_tptc0_hwmod, - .slave = &dm81xx_alwon_l3_fast_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_class dm81xx_tptc1_hwmod_class = { - .name = "tptc1", -}; - -static struct omap_hwmod dm81xx_tptc1_hwmod = { - .name = "tptc1", - .class = &dm81xx_tptc1_hwmod_class, - .clkdm_name = "alwon_l3s_clkdm", - .main_clk = "sysclk4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_TPTC1_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc1 = { - .master = &dm81xx_alwon_l3_fast_hwmod, - .slave = &dm81xx_tptc1_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if dm81xx_tptc1__alwon_l3_fast = { - .master = &dm81xx_tptc1_hwmod, - .slave = &dm81xx_alwon_l3_fast_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_class dm81xx_tptc2_hwmod_class = { - .name = "tptc2", -}; - -static struct omap_hwmod dm81xx_tptc2_hwmod = { - .name = "tptc2", - .class = &dm81xx_tptc2_hwmod_class, - .clkdm_name = "alwon_l3s_clkdm", - .main_clk = "sysclk4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_TPTC2_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc2 = { - .master = &dm81xx_alwon_l3_fast_hwmod, - .slave = &dm81xx_tptc2_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if dm81xx_tptc2__alwon_l3_fast = { - .master = &dm81xx_tptc2_hwmod, - .slave = &dm81xx_alwon_l3_fast_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_class dm81xx_tptc3_hwmod_class = { - .name = "tptc3", -}; - -static struct omap_hwmod dm81xx_tptc3_hwmod = { - .name = "tptc3", - .class = &dm81xx_tptc3_hwmod_class, - .clkdm_name = "alwon_l3s_clkdm", - .main_clk = "sysclk4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DM81XX_CM_ALWON_TPTC3_CLKCTRL, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc3 = { - .master = &dm81xx_alwon_l3_fast_hwmod, - .slave = &dm81xx_tptc3_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = { - .master = &dm81xx_tptc3_hwmod, - .slave = &dm81xx_alwon_l3_fast_hwmod, - .clk = "sysclk4_ck", - .user = OCP_USER_MPU, -}; - /* * REVISIT: Test and enable the following once clocks work: * dm81xx_l4_ls__mailbox @@ -1499,19 +1288,8 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = { &dm814x_l4_ls__mmc1, &dm814x_l4_ls__mmc2, &ti81xx_l4_ls__rtc, - &dm81xx_alwon_l3_fast__tpcc, - &dm81xx_alwon_l3_fast__tptc0, - &dm81xx_alwon_l3_fast__tptc1, - &dm81xx_alwon_l3_fast__tptc2, - &dm81xx_alwon_l3_fast__tptc3, - &dm81xx_tptc0__alwon_l3_fast, - &dm81xx_tptc1__alwon_l3_fast, - &dm81xx_tptc2__alwon_l3_fast, - &dm81xx_tptc3__alwon_l3_fast, &dm814x_l4_ls__timer1, &dm814x_l4_ls__timer2, - &dm814x_l4_hs__cpgmac0, - &dm814x_cpgmac0__mdio, &dm81xx_alwon_l3_slow__gpmc, &dm814x_default_l3_slow__usbss, &dm814x_alwon_l3_med__mmc3, @@ -1554,15 +1332,6 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm81xx_emac0__mdio, &dm816x_l4_hs__emac1, &dm81xx_l4_hs__sata, - &dm81xx_alwon_l3_fast__tpcc, - &dm81xx_alwon_l3_fast__tptc0, - &dm81xx_alwon_l3_fast__tptc1, - &dm81xx_alwon_l3_fast__tptc2, - &dm81xx_alwon_l3_fast__tptc3, - &dm81xx_tptc0__alwon_l3_fast, - &dm81xx_tptc1__alwon_l3_fast, - &dm81xx_tptc2__alwon_l3_fast, - &dm81xx_tptc3__alwon_l3_fast, &dm81xx_alwon_l3_slow__gpmc, &dm816x_default_l3_slow__usbss, NULL, diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index dbb7c2acef31..2a4fe3e68b82 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -397,10 +397,16 @@ static int ti_sysc_shutdown_module(struct device *dev, return omap_hwmod_shutdown(cookie->data); } +static bool ti_sysc_soc_type_gp(void) +{ + return omap_type() == OMAP2_DEVICE_TYPE_GP; +} + static struct of_dev_auxdata omap_auxdata_lookup[]; static struct ti_sysc_platform_data ti_sysc_pdata = { .auxdata = omap_auxdata_lookup, + .soc_type_gp = ti_sysc_soc_type_gp, .init_clockdomain = ti_sysc_clkdm_init, .clkdm_deny_idle = ti_sysc_clkdm_deny_idle, .clkdm_allow_idle = ti_sysc_clkdm_allow_idle, diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c index 7461b0346549..5455fc98c60e 100644 --- a/arch/arm/mach-omap2/pm33xx-core.c +++ b/arch/arm/mach-omap2/pm33xx-core.c @@ -6,11 +6,14 @@ * Dave Gerlach */ +#include <linux/cpuidle.h> +#include <linux/platform_data/pm33xx.h> +#include <asm/cpuidle.h> #include <asm/smp_scu.h> #include <asm/suspend.h> #include <linux/errno.h> -#include <linux/platform_data/pm33xx.h> #include <linux/clk.h> +#include <linux/cpu.h> #include <linux/platform_data/gpio-omap.h> #include <linux/pinctrl/pinmux.h> #include <linux/wkup_m3_ipc.h> @@ -35,6 +38,14 @@ static struct clockdomain *gfx_l4ls_clkdm; static void __iomem *scu_base; static struct omap_hwmod *rtc_oh; +static int (*idle_fn)(u32 wfi_flags); + +struct amx3_idle_state { + int wfi_flags; +}; + +static struct amx3_idle_state *idle_states; + static int am43xx_map_scu(void) { scu_base = ioremap(scu_a9_get_base(), SZ_256); @@ -68,7 +79,7 @@ static int am43xx_check_off_mode_enable(void) return 0; } -static int amx3_common_init(void) +static int amx3_common_init(int (*idle)(u32 wfi_flags)) { gfx_pwrdm = pwrdm_lookup("gfx_pwrdm"); per_pwrdm = pwrdm_lookup("per_pwrdm"); @@ -88,10 +99,12 @@ static int amx3_common_init(void) else omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF); + idle_fn = idle; + return 0; } -static int am33xx_suspend_init(void) +static int am33xx_suspend_init(int (*idle)(u32 wfi_flags)) { int ret; @@ -102,12 +115,12 @@ static int am33xx_suspend_init(void) return -ENODEV; } - ret = amx3_common_init(); + ret = amx3_common_init(idle); return ret; } -static int am43xx_suspend_init(void) +static int am43xx_suspend_init(int (*idle)(u32 wfi_flags)) { int ret = 0; @@ -117,11 +130,17 @@ static int am43xx_suspend_init(void) return ret; } - ret = amx3_common_init(); + ret = amx3_common_init(idle); return ret; } +static int amx3_suspend_deinit(void) +{ + idle_fn = NULL; + return 0; +} + static void amx3_pre_suspend_common(void) { omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF); @@ -201,6 +220,43 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long), return ret; } +static int am33xx_cpu_suspend(int (*fn)(unsigned long), unsigned long args) +{ + int ret = 0; + + if (omap_irq_pending() || need_resched()) + return ret; + + ret = cpu_suspend(args, fn); + + return ret; +} + +static int am43xx_cpu_suspend(int (*fn)(unsigned long), unsigned long args) +{ + int ret = 0; + + if (!scu_base) + return 0; + + scu_power_mode(scu_base, SCU_PM_DORMANT); + ret = cpu_suspend(args, fn); + scu_power_mode(scu_base, SCU_PM_NORMAL); + + return ret; +} + +static void amx3_begin_suspend(void) +{ + cpu_idle_poll_ctrl(true); +} + +static void amx3_finish_suspend(void) +{ + cpu_idle_poll_ctrl(false); +} + + static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void) { if (soc_is_am33xx()) @@ -253,7 +309,11 @@ static void am43xx_prepare_rtc_resume(void) static struct am33xx_pm_platform_data am33xx_ops = { .init = am33xx_suspend_init, + .deinit = amx3_suspend_deinit, .soc_suspend = am33xx_suspend, + .cpu_suspend = am33xx_cpu_suspend, + .begin_suspend = amx3_begin_suspend, + .finish_suspend = amx3_finish_suspend, .get_sram_addrs = amx3_get_sram_addrs, .save_context = am33xx_save_context, .restore_context = am33xx_restore_context, @@ -265,7 +325,11 @@ static struct am33xx_pm_platform_data am33xx_ops = { static struct am33xx_pm_platform_data am43xx_ops = { .init = am43xx_suspend_init, + .deinit = amx3_suspend_deinit, .soc_suspend = am43xx_suspend, + .cpu_suspend = am43xx_cpu_suspend, + .begin_suspend = amx3_begin_suspend, + .finish_suspend = amx3_finish_suspend, .get_sram_addrs = amx3_get_sram_addrs, .save_context = am43xx_save_context, .restore_context = am43xx_restore_context, @@ -301,3 +365,64 @@ int __init amx3_common_pm_init(void) return 0; } + +static int __init amx3_idle_init(struct device_node *cpu_node, int cpu) +{ + struct device_node *state_node; + struct amx3_idle_state states[CPUIDLE_STATE_MAX]; + int i; + int state_count = 1; + + for (i = 0; ; i++) { + state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); + if (!state_node) + break; + + if (!of_device_is_available(state_node)) + continue; + + if (i == CPUIDLE_STATE_MAX) { + pr_warn("%s: cpuidle states reached max possible\n", + __func__); + break; + } + + states[state_count].wfi_flags = 0; + + if (of_property_read_bool(state_node, "ti,idle-wkup-m3")) + states[state_count].wfi_flags |= WFI_FLAG_WAKE_M3 | + WFI_FLAG_FLUSH_CACHE; + + state_count++; + } + + idle_states = kcalloc(state_count, sizeof(*idle_states), GFP_KERNEL); + if (!idle_states) + return -ENOMEM; + + for (i = 1; i < state_count; i++) + idle_states[i].wfi_flags = states[i].wfi_flags; + + return 0; +} + +static int amx3_idle_enter(unsigned long index) +{ + struct amx3_idle_state *idle_state = &idle_states[index]; + + if (!idle_state) + return -EINVAL; + + if (idle_fn) + idle_fn(idle_state->wfi_flags); + + return 0; +} + +static struct cpuidle_ops amx3_cpuidle_ops __initdata = { + .init = amx3_idle_init, + .suspend = amx3_idle_enter, +}; + +CPUIDLE_METHOD_OF_DECLARE(pm33xx_idle, "ti,am3352", &amx3_cpuidle_ops); +CPUIDLE_METHOD_OF_DECLARE(pm43xx_idle, "ti,am4372", &amx3_cpuidle_ops); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e66e9948636c..6df395fff971 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -191,6 +191,7 @@ void omap_sram_idle(void) int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON; u32 sdrc_pwr = 0; + int error; mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { @@ -219,8 +220,11 @@ void omap_sram_idle(void) pwrdm_pre_transition(NULL); /* PER */ - if (per_next_state == PWRDM_POWER_OFF) - cpu_cluster_pm_enter(); + if (per_next_state == PWRDM_POWER_OFF) { + error = cpu_cluster_pm_enter(); + if (error) + return; + } /* CORE */ if (core_next_state < PWRDM_POWER_ON) { diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 0d0a731cb476..8b09cdacc30d 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -91,12 +91,6 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction omap2_gp_timer_irq = { - .name = "gp_timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap2_gp_timer_interrupt, -}; - static int omap2_gp_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { @@ -382,8 +376,9 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, &clockevent_gpt.name, OMAP_TIMER_POSTED); BUG_ON(res); - omap2_gp_timer_irq.dev_id = &clkev; - setup_irq(clkev.irq, &omap2_gp_timer_irq); + if (request_irq(clkev.irq, omap2_gp_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", &clkev)) + pr_err("Failed to request irq %d (gp_timer)\n", clkev.irq); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index cf9cb3d2590e..e94a61901ffd 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -3,7 +3,6 @@ menuconfig ARCH_ORION5X bool "Marvell Orion" depends on MMU && ARCH_MULTI_V5 select CPU_FEROCEON - select GENERIC_CLOCKEVENTS select GPIOLIB select MVEBU_MBUS select FORCE_PCI @@ -18,7 +17,6 @@ if ARCH_ORION5X config ARCH_ORION5X_DT bool "Marvell Orion5x Flattened Device Tree" - select USE_OF select ORION_CLK select ORION_IRQCHIP select ORION_TIMER diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index fda9b75c3a33..a39764faf2a0 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -398,7 +398,6 @@ static int ts78xx_fpga_load_devices(void) static int ts78xx_fpga_unload_devices(void) { - int ret = 0; if (ts78xx_fpga.supports.ts_rtc.present == 1) ts78xx_ts_rtc_unload(); @@ -407,7 +406,7 @@ static int ts78xx_fpga_unload_devices(void) if (ts78xx_fpga.supports.ts_rng.present == 1) ts78xx_ts_rng_unload(); - return ret; + return 0; } static int ts78xx_fpga_load(void) diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 425855f456f2..2e35354b61f5 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -312,7 +312,6 @@ static struct pwm_lookup cm_x300_pwm_lookup[] = { static struct platform_pwm_backlight_data cm_x300_backlight_data = { .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, }; static struct platform_device cm_x300_backlight_device = { diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index dbad2f13706c..e5879e8b0682 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -202,7 +202,6 @@ static struct pwm_lookup income_pwm_lookup[] = { static struct platform_pwm_backlight_data income_backlight_data = { .max_brightness = 0x3ff, .dft_brightness = 0x1ff, - .enable_gpio = -1, }; static struct platform_device income_backlight = { diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f2d73289230f..593c7f793da5 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -563,13 +563,20 @@ static void corgi_bl_kick_battery(void) } } +static struct gpiod_lookup_table corgi_lcdcon_gpio_table = { + .dev_id = "spi1.1", + .table = { + GPIO_LOOKUP("gpio-pxa", CORGI_GPIO_BACKLIGHT_CONT, + "BL_CONT", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static struct corgi_lcd_platform_data corgi_lcdcon_info = { .init_mode = CORGI_LCD_MODE_VGA, .max_intensity = 0x2f, .default_intensity = 0x1f, .limit_mask = 0x0b, - .gpio_backlight_cont = CORGI_GPIO_BACKLIGHT_CONT, - .gpio_backlight_on = -1, .kick_battery = corgi_bl_kick_battery, }; @@ -609,6 +616,7 @@ static struct spi_board_info corgi_spi_devices[] = { static void __init corgi_init_spi(void) { pxa2xx_set_spi_info(1, &corgi_spi_info); + gpiod_add_lookup_table(&corgi_lcdcon_gpio_table); spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices)); } #else diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index ec10851b63cf..eb85950e7c0e 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -55,7 +55,6 @@ static struct pwm_lookup ezx_pwm_lookup[] __maybe_unused = { static struct platform_pwm_backlight_data ezx_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, - .enable_gpio = -1, }; static struct platform_device ezx_backlight_device = { diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 238a751a8797..1d4c5db54be2 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -556,7 +556,6 @@ static struct platform_device hx4700_lcd = { static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 200, .dft_brightness = 100, - .enable_gpio = -1, }; static struct platform_device backlight = { diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 20e00e970385..6fc40bc06910 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -277,7 +277,6 @@ static struct pwm_lookup lpd270_pwm_lookup[] = { static struct platform_pwm_backlight_data lpd270_backlight_data = { .max_brightness = 1, .dft_brightness = 1, - .enable_gpio = -1, }; static struct platform_device lpd270_backlight_device = { diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 5d0591f93f4d..cd9fa465b9b2 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -401,7 +401,6 @@ static void magician_backlight_exit(struct device *dev) static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 272, .dft_brightness = 100, - .enable_gpio = -1, .init = magician_backlight_init, .notify = magician_backlight_notify, .exit = magician_backlight_exit, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 1b7882920164..d1010ec26e9f 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -256,7 +256,6 @@ static struct pwm_lookup mainstone_pwm_lookup[] = { static struct platform_pwm_backlight_data mainstone_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, - .enable_gpio = -1, }; static struct platform_device mainstone_backlight_device = { diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 0b8bae9610f1..d3af80317f2d 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -176,7 +176,6 @@ static struct pwm_lookup mioa701_pwm_lookup[] = { static struct platform_pwm_backlight_data mioa701_backlight_data = { .max_brightness = 100, .dft_brightness = 50, - .enable_gpio = -1, }; /* diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index b600b63af3a6..0d246a1aebbc 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -318,7 +318,6 @@ static void palm27x_backlight_exit(struct device *dev) static struct platform_pwm_backlight_data palm27x_backlight_data = { .max_brightness = 0xfe, .dft_brightness = 0x7e, - .enable_gpio = -1, .init = palm27x_backlight_init, .notify = palm27x_backlight_notify, .exit = palm27x_backlight_exit, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index fda9deaaae02..455cb8ccaf26 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -174,6 +174,15 @@ static inline void palmtc_keys_init(void) {} * Backlight ******************************************************************************/ #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) + +static struct gpiod_lookup_table palmtc_pwm_bl_gpio_table = { + .dev_id = "pwm-backlight.0", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_BL_POWER, + "enable", GPIO_ACTIVE_HIGH), + }, +}; + static struct pwm_lookup palmtc_pwm_lookup[] = { PWM_LOOKUP("pxa25x-pwm.1", 0, "pwm-backlight.0", NULL, PALMTC_PERIOD_NS, PWM_POLARITY_NORMAL), @@ -182,7 +191,6 @@ static struct pwm_lookup palmtc_pwm_lookup[] = { static struct platform_pwm_backlight_data palmtc_backlight_data = { .max_brightness = PALMTC_MAX_INTENSITY, .dft_brightness = PALMTC_MAX_INTENSITY, - .enable_gpio = GPIO_NR_PALMTC_BL_POWER, }; static struct platform_device palmtc_backlight = { @@ -195,6 +203,7 @@ static struct platform_device palmtc_backlight = { static void __init palmtc_pwm_init(void) { + gpiod_add_lookup_table(&palmtc_pwm_bl_gpio_table); pwm_add_table(palmtc_pwm_lookup, ARRAY_SIZE(palmtc_pwm_lookup)); platform_device_register(&palmtc_backlight); } diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 7171014fd311..e3bcf58b4e63 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -175,7 +175,6 @@ static void palmte2_backlight_exit(struct device *dev) static struct platform_pwm_backlight_data palmte2_backlight_data = { .max_brightness = PALMTE2_MAX_INTENSITY, .dft_brightness = PALMTE2_MAX_INTENSITY, - .enable_gpio = -1, .init = palmte2_backlight_init, .notify = palmte2_backlight_notify, .exit = palmte2_backlight_exit, diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index cb1c56769fbc..bf613f88d70b 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -154,7 +154,6 @@ static struct pwm_lookup pcm990_pwm_lookup[] = { static struct platform_pwm_backlight_data pcm990_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, - .enable_gpio = -1, }; static struct platform_device pcm990_backlight_device = { diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index a4fdc399d152..371008e9bb02 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -525,13 +525,33 @@ static void spitz_bl_kick_battery(void) } } +static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { + .dev_id = "spi2.1", + .table = { + GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_CONT, + "BL_CONT", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_ON, + "BL_ON", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct gpiod_lookup_table akita_lcdcon_gpio_table = { + .dev_id = "spi2.1", + .table = { + GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_CONT, + "BL_CONT", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_ON, + "BL_ON", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static struct corgi_lcd_platform_data spitz_lcdcon_info = { .init_mode = CORGI_LCD_MODE_VGA, .max_intensity = 0x2f, .default_intensity = 0x1f, .limit_mask = 0x0b, - .gpio_backlight_cont = SPITZ_GPIO_BACKLIGHT_CONT, - .gpio_backlight_on = SPITZ_GPIO_BACKLIGHT_ON, .kick_battery = spitz_bl_kick_battery, }; @@ -574,12 +594,10 @@ static struct pxa2xx_spi_controller spitz_spi_info = { static void __init spitz_spi_init(void) { - struct corgi_lcd_platform_data *lcd_data = &spitz_lcdcon_info; - - if (machine_is_akita()) { - lcd_data->gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT; - lcd_data->gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON; - } + if (machine_is_akita()) + gpiod_add_lookup_table(&akita_lcdcon_gpio_table); + else + gpiod_add_lookup_table(&spitz_lcdcon_gpio_table); pxa2xx_set_spi_info(2, &spitz_spi_info); spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices)); diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 93466fa3b0fe..a15eb3b9484d 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -178,13 +178,11 @@ static struct platform_pwm_backlight_data tavorevb_backlight_data[] = { /* primary backlight */ .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, }, [1] = { /* secondary backlight */ .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, }, }; diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index c06031da6676..3aa34e9a15d3 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -404,7 +404,6 @@ static void viper_backlight_exit(struct device *dev) static struct platform_pwm_backlight_data viper_backlight_data = { .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, .init = viper_backlight_init, .notify = viper_backlight_notify, .exit = viper_backlight_exit, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index 900cefc4c5ea..21fd76bb09cd 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -210,13 +210,11 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { /* Keypad Backlight */ .max_brightness = 1023, .dft_brightness = 0, - .enable_gpio = -1, }, [1] = { /* LCD Backlight */ .max_brightness = 1023, .dft_brightness = 512, - .enable_gpio = -1, }, }; diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index bf2ab5bd49ec..79f0025fa17a 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -117,7 +117,6 @@ static struct pwm_lookup zylonite_pwm_lookup[] = { static struct platform_pwm_backlight_data zylonite_backlight_data = { .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, }; static struct platform_device zylonite_backlight_device = { diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index ecbf3c4eb878..1772eccb5caf 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -12,6 +12,11 @@ menuconfig ARCH_QCOM if ARCH_QCOM +config ARCH_IPQ40XX + bool "Enable support for IPQ40XX" + select CLKSRC_QCOM + select HAVE_ARM_ARCH_TIMER + config ARCH_MSM8X60 bool "Enable support for MSM8X60" select CLKSRC_QCOM diff --git a/arch/arm/mach-rpc/time.c b/arch/arm/mach-rpc/time.c index 1d750152b160..da85cac761ba 100644 --- a/arch/arm/mach-rpc/time.c +++ b/arch/arm/mach-rpc/time.c @@ -85,11 +85,6 @@ ioc_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction ioc_timer_irq = { - .name = "timer", - .handler = ioc_timer_interrupt -}; - /* * Set up timer interrupt. */ @@ -97,5 +92,6 @@ void __init ioc_timer_init(void) { WARN_ON(clocksource_register_hz(&ioctime_clocksource, RPC_CLOCK_FREQ)); ioctime_init(); - setup_irq(IRQ_TIMER0, &ioc_timer_irq); + if (request_irq(IRQ_TIMER0, ioc_timer_interrupt, 0, "timer", NULL)) + pr_err("Failed to request irq %d (timer)\n", IRQ_TIMER0); } diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index 74d6b68e91c7..e1c372e5447b 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -516,7 +516,6 @@ static void h1940_backlight_exit(struct device *dev) static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 100, .dft_brightness = 50, - .enable_gpio = -1, .init = h1940_backlight_init, .notify = h1940_backlight_notify, .exit = h1940_backlight_exit, diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 03d8f27cdc32..fde98b175c75 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -534,7 +534,6 @@ static int rx1950_backlight_notify(struct device *dev, int brightness) static struct platform_pwm_backlight_data rx1950_backlight_data = { .max_brightness = 24, .dft_brightness = 4, - .enable_gpio = -1, .init = rx1950_backlight_init, .notify = rx1950_backlight_notify, .exit = rx1950_backlight_exit, diff --git a/arch/arm/mach-s3c64xx/dev-backlight.c b/arch/arm/mach-s3c64xx/dev-backlight.c index 799cfdf0606b..09e6da305f60 100644 --- a/arch/arm/mach-s3c64xx/dev-backlight.c +++ b/arch/arm/mach-s3c64xx/dev-backlight.c @@ -65,7 +65,6 @@ static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = { .plat_data = { .max_brightness = 255, .dft_brightness = 255, - .enable_gpio = -1, .init = samsung_bl_init, .exit = samsung_bl_exit, }, @@ -111,8 +110,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, samsung_bl_data->dft_brightness = bl_data->dft_brightness; if (bl_data->lth_brightness) samsung_bl_data->lth_brightness = bl_data->lth_brightness; - if (bl_data->enable_gpio >= 0) - samsung_bl_data->enable_gpio = bl_data->enable_gpio; if (bl_data->init) samsung_bl_data->init = bl_data->init; if (bl_data->notify) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8ec6a4f5eb05..da9654255e3f 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -114,7 +114,6 @@ static struct pwm_lookup crag6410_pwm_lookup[] = { static struct platform_pwm_backlight_data crag6410_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, - .enable_gpio = -1, }; static struct platform_device crag6410_backlight_device = { diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index bfe9881d12cc..e7080215c624 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -115,7 +115,6 @@ static void hmt_bl_exit(struct device *dev) static struct platform_pwm_backlight_data hmt_backlight_data = { .max_brightness = 100 * 256, .dft_brightness = 40 * 256, - .enable_gpio = -1, .init = hmt_bl_init, .notify = hmt_bl_notify, .exit = hmt_bl_exit, diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 829d5dbd69ee..5025db607c0f 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -150,7 +150,6 @@ static int smartq_bl_init(struct device *dev) static struct platform_pwm_backlight_data smartq_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, - .enable_gpio = -1, .init = smartq_bl_init, }; diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 908e5aa831c8..56f406c0c3dd 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -623,7 +623,7 @@ static struct pwm_lookup smdk6410_pwm_lookup[] = { }; static struct platform_pwm_backlight_data smdk6410_bl_data = { - .enable_gpio = -1, + /* Intentionally blank */ }; static struct dwc2_hsotg_plat smdk6410_hsotg_pdata; diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index b13ec9088ce5..86406e3f9b22 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -72,7 +72,6 @@ static const char *const r8a7779_compat_dt[] __initconst = { DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .smp = smp_ops(r8a7779_smp_ops), .map_io = r8a7779_map_io, - .init_early = shmobile_init_delay, .init_irq = r8a7779_init_irq_dt, .init_late = shmobile_init_late, .dt_compat = r8a7779_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 2fd3aa6f3212..1ee5cd2840e0 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -7,7 +7,6 @@ * Copyright (C) 2014 Ulrich Hecht */ -#include <linux/clk-provider.h> #include <linux/clocksource.h> #include <linux/device.h> #include <linux/dma-contiguous.h> @@ -15,6 +14,7 @@ #include <linux/kernel.h> #include <linux/memblock.h> #include <linux/of.h> +#include <linux/of_clk.h> #include <linux/of_fdt.h> #include <linux/of_platform.h> #include <linux/psci.h> diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index cc08aa752244..eb4a62fa4289 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -56,7 +56,6 @@ static const char *const sh73a0_boards_compat_dt[] __initconst = { DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, - .init_early = shmobile_init_delay, .init_machine = sh73a0_generic_init, .init_late = shmobile_init_late, .dt_compat = sh73a0_boards_compat_dt, diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c index 289e036c9c30..d1fdb6066f7b 100644 --- a/arch/arm/mach-spear/time.c +++ b/arch/arm/mach-spear/time.c @@ -181,12 +181,6 @@ static irqreturn_t spear_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction spear_timer_irq = { - .name = "timer", - .flags = IRQF_TIMER, - .handler = spear_timer_interrupt -}; - static void __init spear_clockevent_init(int irq) { u32 tick_rate; @@ -201,7 +195,8 @@ static void __init spear_clockevent_init(int irq) clockevents_config_and_register(&clkevt, tick_rate, 3, 0xfff0); - setup_irq(irq, &spear_timer_irq); + if (request_irq(irq, spear_timer_interrupt, IRQF_TIMER, "timer", NULL)) + pr_err("Failed to request irq %d (timer)\n", irq); } static const struct of_device_id timer_of_match[] __initconst = { diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index 933b6930f024..06da2747a90b 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -10,9 +10,9 @@ * warranty of any kind, whether express or implied. */ -#include <linux/clk-provider.h> #include <linux/clocksource.h> #include <linux/init.h> +#include <linux/of_clk.h> #include <linux/platform_device.h> #include <linux/reset/sunxi.h> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 6c1dff2eccc2..07572b5373b8 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -8,29 +8,14 @@ obj-y += reset.o obj-y += reset-handler.o obj-y += sleep.o obj-y += tegra.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o +obj-y += sleep-tegra20.o +obj-y += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o -endif -obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o -endif obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o -endif -obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o -endif obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c deleted file mode 100644 index 5118f777fd66..000000000000 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. - */ - -#include <asm/firmware.h> -#include <linux/tick.h> -#include <linux/cpuidle.h> -#include <linux/cpu_pm.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <linux/firmware/trusted_foundations.h> - -#include <asm/cpuidle.h> -#include <asm/smp_plat.h> -#include <asm/suspend.h> -#include <asm/psci.h> - -#include "cpuidle.h" -#include "pm.h" -#include "sleep.h" - -#ifdef CONFIG_PM_SLEEP -#define TEGRA114_MAX_STATES 2 -#else -#define TEGRA114_MAX_STATES 1 -#endif - -#ifdef CONFIG_PM_SLEEP -static int tegra114_idle_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - local_fiq_disable(); - - tegra_set_cpu_in_lp2(); - cpu_pm_enter(); - - call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2); - - /* Do suspend by ourselves if the firmware does not implement it */ - if (call_firmware_op(do_idle, 0) == -ENOSYS) - cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); - - cpu_pm_exit(); - tegra_clear_cpu_in_lp2(); - - local_fiq_enable(); - - return index; -} - -static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - tegra114_idle_power_down(dev, drv, index); -} -#endif - -static struct cpuidle_driver tegra_idle_driver = { - .name = "tegra_idle", - .owner = THIS_MODULE, - .state_count = TEGRA114_MAX_STATES, - .states = { - [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), -#ifdef CONFIG_PM_SLEEP - [1] = { - .enter = tegra114_idle_power_down, - .enter_s2idle = tegra114_idle_enter_s2idle, - .exit_latency = 500, - .target_residency = 1000, - .flags = CPUIDLE_FLAG_TIMER_STOP, - .power_usage = 0, - .name = "powered-down", - .desc = "CPU power gated", - }, -#endif - }, -}; - -int __init tegra114_cpuidle_init(void) -{ - if (!psci_smp_available()) - return cpuidle_register(&tegra_idle_driver, NULL); - - return 0; -} diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c deleted file mode 100644 index 69f3fa270fbe..000000000000 --- a/arch/arm/mach-tegra/cpuidle-tegra20.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * CPU idle driver for Tegra CPUs - * - * Copyright (c) 2010-2012, NVIDIA Corporation. - * Copyright (c) 2011 Google, Inc. - * Author: Colin Cross <ccross@android.com> - * Gary King <gking@nvidia.com> - * - * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> - */ - -#include <linux/clk/tegra.h> -#include <linux/tick.h> -#include <linux/cpuidle.h> -#include <linux/cpu_pm.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <soc/tegra/flowctrl.h> - -#include <asm/cpuidle.h> -#include <asm/smp_plat.h> -#include <asm/suspend.h> - -#include "cpuidle.h" -#include "iomap.h" -#include "irq.h" -#include "pm.h" -#include "reset.h" -#include "sleep.h" - -#ifdef CONFIG_PM_SLEEP -static bool abort_flag; -static atomic_t abort_barrier; -static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index); -#define TEGRA20_MAX_STATES 2 -#else -#define TEGRA20_MAX_STATES 1 -#endif - -static struct cpuidle_driver tegra_idle_driver = { - .name = "tegra_idle", - .owner = THIS_MODULE, - .states = { - ARM_CPUIDLE_WFI_STATE_PWR(600), -#ifdef CONFIG_PM_SLEEP - { - .enter = tegra20_idle_lp2_coupled, - .exit_latency = 5000, - .target_residency = 10000, - .power_usage = 0, - .flags = CPUIDLE_FLAG_COUPLED | - CPUIDLE_FLAG_TIMER_STOP, - .name = "powered-down", - .desc = "CPU power gated", - }, -#endif - }, - .state_count = TEGRA20_MAX_STATES, - .safe_state_index = 0, -}; - -#ifdef CONFIG_PM_SLEEP -#ifdef CONFIG_SMP -static int tegra20_reset_sleeping_cpu_1(void) -{ - int ret = 0; - - tegra_pen_lock(); - - if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE) - tegra20_cpu_shutdown(1); - else - ret = -EINVAL; - - tegra_pen_unlock(); - - return ret; -} - -static void tegra20_wake_cpu1_from_reset(void) -{ - tegra_pen_lock(); - - tegra20_cpu_clear_resettable(); - - /* enable cpu clock on cpu */ - tegra_enable_cpu_clock(1); - - /* take the CPU out of reset */ - tegra_cpu_out_of_reset(1); - - /* unhalt the cpu */ - flowctrl_write_cpu_halt(1, 0); - - tegra_pen_unlock(); -} - -static int tegra20_reset_cpu_1(void) -{ - if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1()) - return 0; - - tegra20_wake_cpu1_from_reset(); - return -EBUSY; -} -#else -static inline void tegra20_wake_cpu1_from_reset(void) -{ -} - -static inline int tegra20_reset_cpu_1(void) -{ - return 0; -} -#endif - -static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - while (tegra20_cpu_is_resettable_soon()) - cpu_relax(); - - if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready()) - return false; - - tegra_idle_lp2_last(); - - if (cpu_online(1)) - tegra20_wake_cpu1_from_reset(); - - return true; -} - -#ifdef CONFIG_SMP -static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - cpu_suspend(0, tegra20_sleep_cpu_secondary_finish); - - tegra20_cpu_clear_resettable(); - - return true; -} -#else -static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - return true; -} -#endif - -static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - bool entered_lp2 = false; - - if (tegra_pending_sgi()) - WRITE_ONCE(abort_flag, true); - - cpuidle_coupled_parallel_barrier(dev, &abort_barrier); - - if (abort_flag) { - cpuidle_coupled_parallel_barrier(dev, &abort_barrier); - abort_flag = false; /* clean flag for next coming */ - return -EINTR; - } - - local_fiq_disable(); - - tegra_set_cpu_in_lp2(); - cpu_pm_enter(); - - if (dev->cpu == 0) - entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index); - else - entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index); - - cpu_pm_exit(); - tegra_clear_cpu_in_lp2(); - - local_fiq_enable(); - - smp_rmb(); - - return entered_lp2 ? index : 0; -} -#endif - -/* - * Tegra20 HW appears to have a bug such that PCIe device interrupts, whether - * they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around - * this, simply disable LP2 if the PCI driver and DT node are both enabled. - */ -void tegra20_cpuidle_pcie_irqs_in_use(void) -{ - pr_info_once( - "Disabling cpuidle LP2 state, since PCIe IRQs are in use\n"); - cpuidle_driver_state_disabled(&tegra_idle_driver, 1, true); -} - -int __init tegra20_cpuidle_init(void) -{ - return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); -} diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c deleted file mode 100644 index c6128526877d..000000000000 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * CPU idle driver for Tegra CPUs - * - * Copyright (c) 2010-2012, NVIDIA Corporation. - * Copyright (c) 2011 Google, Inc. - * Author: Colin Cross <ccross@android.com> - * Gary King <gking@nvidia.com> - * - * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> - */ - -#include <linux/clk/tegra.h> -#include <linux/tick.h> -#include <linux/cpuidle.h> -#include <linux/cpu_pm.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/cpuidle.h> -#include <asm/smp_plat.h> -#include <asm/suspend.h> - -#include "cpuidle.h" -#include "pm.h" -#include "sleep.h" - -#ifdef CONFIG_PM_SLEEP -static int tegra30_idle_lp2(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index); -#endif - -static struct cpuidle_driver tegra_idle_driver = { - .name = "tegra_idle", - .owner = THIS_MODULE, -#ifdef CONFIG_PM_SLEEP - .state_count = 2, -#else - .state_count = 1, -#endif - .states = { - [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), -#ifdef CONFIG_PM_SLEEP - [1] = { - .enter = tegra30_idle_lp2, - .exit_latency = 2000, - .target_residency = 2200, - .power_usage = 0, - .flags = CPUIDLE_FLAG_TIMER_STOP, - .name = "powered-down", - .desc = "CPU power gated", - }, -#endif - }, -}; - -#ifdef CONFIG_PM_SLEEP -static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - /* All CPUs entering LP2 is not working. - * Don't let CPU0 enter LP2 when any secondary CPU is online. - */ - if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) { - cpu_do_idle(); - return false; - } - - tegra_idle_lp2_last(); - - return true; -} - -#ifdef CONFIG_SMP -static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - smp_wmb(); - - cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); - - return true; -} -#else -static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - return true; -} -#endif - -static int tegra30_idle_lp2(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - bool entered_lp2 = false; - bool last_cpu; - - local_fiq_disable(); - - last_cpu = tegra_set_cpu_in_lp2(); - cpu_pm_enter(); - - if (dev->cpu == 0) { - if (last_cpu) - entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv, - index); - else - cpu_do_idle(); - } else { - entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index); - } - - cpu_pm_exit(); - tegra_clear_cpu_in_lp2(); - - local_fiq_enable(); - - smp_rmb(); - - return (entered_lp2) ? index : 0; -} -#endif - -int __init tegra30_cpuidle_init(void) -{ - return cpuidle_register(&tegra_idle_driver, NULL); -} diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c deleted file mode 100644 index d565c44cfc93..000000000000 --- a/arch/arm/mach-tegra/cpuidle.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/arm/mach-tegra/cpuidle.c - * - * CPU idle driver for Tegra CPUs - * - * Copyright (c) 2010-2012, NVIDIA Corporation. - * Copyright (c) 2011 Google, Inc. - * Author: Colin Cross <ccross@android.com> - * Gary King <gking@nvidia.com> - * - * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> - */ - -#include <linux/kernel.h> -#include <linux/module.h> - -#include <soc/tegra/fuse.h> - -#include "cpuidle.h" - -void __init tegra_cpuidle_init(void) -{ - switch (tegra_get_chip_id()) { - case TEGRA20: - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) - tegra20_cpuidle_init(); - break; - case TEGRA30: - if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC)) - tegra30_cpuidle_init(); - break; - case TEGRA114: - case TEGRA124: - if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) || - IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)) - tegra114_cpuidle_init(); - break; - } -} - -void tegra_cpuidle_pcie_irqs_in_use(void) -{ - switch (tegra_get_chip_id()) { - case TEGRA20: - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) - tegra20_cpuidle_pcie_irqs_in_use(); - break; - } -} diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h deleted file mode 100644 index 4e1f459f5bd8..000000000000 --- a/arch/arm/mach-tegra/cpuidle.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. - */ - -#ifndef __MACH_TEGRA_CPUIDLE_H -#define __MACH_TEGRA_CPUIDLE_H - -#ifdef CONFIG_CPU_IDLE -int tegra20_cpuidle_init(void); -void tegra20_cpuidle_pcie_irqs_in_use(void); -int tegra30_cpuidle_init(void); -int tegra114_cpuidle_init(void); -void tegra_cpuidle_init(void); -void tegra_cpuidle_pcie_irqs_in_use(void); -#else -static inline void tegra_cpuidle_init(void) {} -static inline void tegra_cpuidle_pcie_irqs_in_use(void) {} -#endif - -#endif diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index ace7a390b5fe..4e1ee70b2a3f 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -18,9 +18,10 @@ #include <linux/of.h> #include <linux/syscore_ops.h> +#include <soc/tegra/irq.h> + #include "board.h" #include "iomap.h" -#include "irq.h" #define SGI_MASK 0xFFFF diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h deleted file mode 100644 index 7a94cf121448..000000000000 --- a/arch/arm/mach-tegra/irq.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. - */ - -#ifndef __TEGRA_IRQ_H -#define __TEGRA_IRQ_H - -bool tegra_pending_sgi(void); - -#endif diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 3cab81b82866..d1e1a61b12cf 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -110,7 +110,7 @@ static void suspend_cpu_complex(void) flowctrl_cpu_suspend_enter(cpu); } -void tegra_clear_cpu_in_lp2(void) +void tegra_pm_clear_cpu_in_lp2(void) { int phy_cpu_id = cpu_logical_map(smp_processor_id()); u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void) spin_unlock(&tegra_lp2_lock); } -bool tegra_set_cpu_in_lp2(void) +void tegra_pm_set_cpu_in_lp2(void) { int phy_cpu_id = cpu_logical_map(smp_processor_id()); - bool last_cpu = false; - cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; spin_lock(&tegra_lp2_lock); @@ -135,22 +133,15 @@ bool tegra_set_cpu_in_lp2(void) BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id))); *cpu_in_lp2 |= BIT(phy_cpu_id); - if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) - last_cpu = true; - else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1) - tegra20_cpu_set_resettable_soon(); - spin_unlock(&tegra_lp2_lock); - return last_cpu; -} - -int tegra_cpu_do_idle(void) -{ - return cpu_do_idle(); } static int tegra_sleep_cpu(unsigned long v2p) { + if (tegra_cpu_car_ops->rail_off_ready && + WARN_ON(!tegra_cpu_rail_off_ready())) + return -EBUSY; + /* * L2 cache disabling using kernel API only allowed when all * secondary CPU's are offline. Cache have to be disabled with @@ -159,9 +150,10 @@ static int tegra_sleep_cpu(unsigned long v2p) * if any of secondary CPU's is online and this is the LP2-idle * code-path only for Tegra20/30. */ - if (trusted_foundations_registered()) - outer_disable(); - +#ifdef CONFIG_OUTER_CACHE + if (trusted_foundations_registered() && outer_cache.disable) + outer_cache.disable(); +#endif /* * Note that besides of setting up CPU reset vector this firmware * call may also do the following, depending on the FW version: @@ -202,14 +194,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode) tegra_pmc_enter_suspend_mode(mode); } -void tegra_idle_lp2_last(void) +int tegra_pm_enter_lp2(void) { + int err; + tegra_pm_set(TEGRA_SUSPEND_LP2); cpu_cluster_pm_enter(); suspend_cpu_complex(); - cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); + err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); /* * Resume L2 cache if it wasn't re-enabled early during resume, @@ -221,6 +215,8 @@ void tegra_idle_lp2_last(void) restore_cpu_complex(); cpu_cluster_pm_exit(); + + return err; } enum tegra_suspend_mode tegra_pm_validate_suspend_mode( @@ -365,7 +361,7 @@ static int tegra_suspend_enter(suspend_state_t state) tegra_suspend_enter_lp1(); break; case TEGRA_SUSPEND_LP2: - tegra_set_cpu_in_lp2(); + tegra_pm_set_cpu_in_lp2(); break; default: break; @@ -386,7 +382,7 @@ static int tegra_suspend_enter(suspend_state_t state) tegra_suspend_exit_lp1(); break; case TEGRA_SUSPEND_LP2: - tegra_clear_cpu_in_lp2(); + tegra_pm_clear_cpu_in_lp2(); break; default: break; @@ -436,4 +432,18 @@ void __init tegra_init_suspend(void) suspend_set_ops(&tegra_suspend_ops); } + +int tegra_pm_park_secondary_cpu(unsigned long cpu) +{ + if (cpu > 0) { + tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS); + + if (tegra_get_chip_id() == TEGRA20) + tegra20_hotplug_shutdown(); + else + tegra30_hotplug_shutdown(); + } + + return -EINVAL; +} #endif diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index 569151b3edc0..81525f5f4a44 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h @@ -23,10 +23,6 @@ void tegra20_sleep_core_init(void); void tegra30_lp1_iram_hook(void); void tegra30_sleep_core_init(void); -void tegra_clear_cpu_in_lp2(void); -bool tegra_set_cpu_in_lp2(void); -int tegra_cpu_do_idle(void); -void tegra_idle_lp2_last(void); extern void (*tegra_tear_down_cpu)(void); #ifdef CONFIG_PM_SLEEP diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S index e3f34815c9da..53123ae4ac3b 100644 --- a/arch/arm/mach-tegra/reset-handler.S +++ b/arch/arm/mach-tegra/reset-handler.S @@ -183,17 +183,6 @@ after_errata: bleq __die @ CPU not present (to OS) #endif -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* Are we on Tegra20? */ - cmp r6, #TEGRA20 - bne 1f - /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ - mov r0, #CPU_NOT_RESETTABLE - cmp r10, #0 - strbne r0, [r12, #RESET_DATA(RESETTABLE_STATUS)] -1: -#endif - /* Waking up from LP1? */ ldr r8, [r12, #RESET_DATA(MASK_LP1)] tst r8, r11 @ if in_lp1 diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h index a4cfc08159f6..51265592cb1a 100644 --- a/arch/arm/mach-tegra/reset.h +++ b/arch/arm/mach-tegra/reset.h @@ -16,9 +16,8 @@ #define TEGRA_RESET_STARTUP_SECONDARY 3 #define TEGRA_RESET_STARTUP_LP2 4 #define TEGRA_RESET_STARTUP_LP1 5 -#define TEGRA_RESET_RESETTABLE_STATUS 6 -#define TEGRA_RESET_TF_PRESENT 7 -#define TEGRA_RESET_DATA_SIZE 8 +#define TEGRA_RESET_TF_PRESENT 6 +#define TEGRA_RESET_DATA_SIZE 7 #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) @@ -42,10 +41,6 @@ void __tegra_cpu_reset_handler_end(void); (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \ (u32)__tegra_cpu_reset_handler_start))) -#define tegra20_cpu1_resettable_status \ - (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ - ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \ - (u32)__tegra_cpu_reset_handler_start))) #endif #define tegra_cpu_reset_handler_offset \ diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index 9a89f30d53ca..0e00ba8cf646 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S @@ -43,9 +43,6 @@ #define APB_MISC_XM2CFGCPADCTRL2 0x8e4 #define APB_MISC_XM2CFGDPADCTRL2 0x8e8 -#define __tegra20_cpu1_resettable_status_offset \ - (__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS)) - .macro pll_enable, rd, r_car_base, pll_base ldr \rd, [\r_car_base, #\pll_base] tst \rd, #(1 << 30) @@ -90,10 +87,6 @@ ENDPROC(tegra20_hotplug_shutdown) ENTRY(tegra20_cpu_shutdown) cmp r0, #0 reteq lr @ must not be called for CPU 0 - mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT - ldr r2, =__tegra20_cpu1_resettable_status_offset - mov r12, #CPU_RESETTABLE - strb r12, [r1, r2] cpu_to_halt_reg r1, r0 ldr r3, =TEGRA_FLOW_CTRL_VIRT @@ -117,107 +110,6 @@ ENDPROC(tegra20_cpu_shutdown) #ifdef CONFIG_PM_SLEEP /* - * tegra_pen_lock - * - * spinlock implementation with no atomic test-and-set and no coherence - * using Peterson's algorithm on strongly-ordered registers - * used to synchronize a cpu waking up from wfi with entering lp2 on idle - * - * The reference link of Peterson's algorithm: - * http://en.wikipedia.org/wiki/Peterson's_algorithm - * - * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm) - * on cpu 0: - * r2 = flag[0] (in SCRATCH38) - * r3 = flag[1] (in SCRATCH39) - * on cpu1: - * r2 = flag[1] (in SCRATCH39) - * r3 = flag[0] (in SCRATCH38) - * - * must be called with MMU on - * corrupts r0-r3, r12 - */ -ENTRY(tegra_pen_lock) - mov32 r3, TEGRA_PMC_VIRT - cpu_id r0 - add r1, r3, #PMC_SCRATCH37 - cmp r0, #0 - addeq r2, r3, #PMC_SCRATCH38 - addeq r3, r3, #PMC_SCRATCH39 - addne r2, r3, #PMC_SCRATCH39 - addne r3, r3, #PMC_SCRATCH38 - - mov r12, #1 - str r12, [r2] @ flag[cpu] = 1 - dsb - str r12, [r1] @ !turn = cpu -1: dsb - ldr r12, [r3] - cmp r12, #1 @ flag[!cpu] == 1? - ldreq r12, [r1] - cmpeq r12, r0 @ !turn == cpu? - beq 1b @ while !turn == cpu && flag[!cpu] == 1 - - ret lr @ locked -ENDPROC(tegra_pen_lock) - -ENTRY(tegra_pen_unlock) - dsb - mov32 r3, TEGRA_PMC_VIRT - cpu_id r0 - cmp r0, #0 - addeq r2, r3, #PMC_SCRATCH38 - addne r2, r3, #PMC_SCRATCH39 - mov r12, #0 - str r12, [r2] - ret lr -ENDPROC(tegra_pen_unlock) - -/* - * tegra20_cpu_clear_resettable(void) - * - * Called to clear the "resettable soon" flag in IRAM variable when - * it is expected that the secondary CPU will be idle soon. - */ -ENTRY(tegra20_cpu_clear_resettable) - mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT - ldr r2, =__tegra20_cpu1_resettable_status_offset - mov r12, #CPU_NOT_RESETTABLE - strb r12, [r1, r2] - ret lr -ENDPROC(tegra20_cpu_clear_resettable) - -/* - * tegra20_cpu_set_resettable_soon(void) - * - * Called to set the "resettable soon" flag in IRAM variable when - * it is expected that the secondary CPU will be idle soon. - */ -ENTRY(tegra20_cpu_set_resettable_soon) - mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT - ldr r2, =__tegra20_cpu1_resettable_status_offset - mov r12, #CPU_RESETTABLE_SOON - strb r12, [r1, r2] - ret lr -ENDPROC(tegra20_cpu_set_resettable_soon) - -/* - * tegra20_cpu_is_resettable_soon(void) - * - * Returns true if the "resettable soon" flag in IRAM variable has been - * set because it is expected that the secondary CPU will be idle soon. - */ -ENTRY(tegra20_cpu_is_resettable_soon) - mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT - ldr r2, =__tegra20_cpu1_resettable_status_offset - ldrb r12, [r1, r2] - cmp r12, #CPU_RESETTABLE_SOON - moveq r0, #1 - movne r0, #0 - ret lr -ENDPROC(tegra20_cpu_is_resettable_soon) - -/* * tegra20_sleep_core_finish(unsigned long v2p) * * Enters suspend in LP0 or LP1 by turning off the mmu and jumping to @@ -243,68 +135,6 @@ ENTRY(tegra20_sleep_core_finish) ENDPROC(tegra20_sleep_core_finish) /* - * tegra20_sleep_cpu_secondary_finish(unsigned long v2p) - * - * Enters WFI on secondary CPU by exiting coherency. - */ -ENTRY(tegra20_sleep_cpu_secondary_finish) - stmfd sp!, {r4-r11, lr} - - mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency - - /* Flush and disable the L1 data cache */ - mov r0, #TEGRA_FLUSH_CACHE_LOUIS - bl tegra_disable_clean_inv_dcache - - mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT - ldr r4, =__tegra20_cpu1_resettable_status_offset - mov r3, #CPU_RESETTABLE - strb r3, [r0, r4] - - bl tegra_cpu_do_idle - - /* - * cpu may be reset while in wfi, which will return through - * tegra_resume to cpu_resume - * or interrupt may wake wfi, which will return here - * cpu state is unchanged - MMU is on, cache is on, coherency - * is off, and the data cache is off - * - * r11 contains the original actlr - */ - - bl tegra_pen_lock - - mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT - ldr r4, =__tegra20_cpu1_resettable_status_offset - mov r3, #CPU_NOT_RESETTABLE - strb r3, [r0, r4] - - bl tegra_pen_unlock - - /* Re-enable the data cache */ - mrc p15, 0, r10, c1, c0, 0 - orr r10, r10, #CR_C - mcr p15, 0, r10, c1, c0, 0 - isb - - mcr p15, 0, r11, c1, c0, 1 @ reenable coherency - - /* Invalidate the TLBs & BTAC */ - mov r1, #0 - mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs - mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC - dsb - isb - - /* the cpu was running with coherency disabled, - * caches may be out of date */ - bl v7_flush_kern_cache_louis - - ldmfd sp!, {r4 - r11, pc} -ENDPROC(tegra20_sleep_cpu_secondary_finish) - -/* * tegra20_tear_down_cpu * * Switches the CPU cluster to PLL-P and enters sleep. diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index 02cc6ff96f30..e7bcf7dc4675 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S @@ -265,11 +265,11 @@ ENTRY(tegra30_sleep_core_finish) ENDPROC(tegra30_sleep_core_finish) /* - * tegra30_sleep_cpu_secondary_finish(unsigned long v2p) + * tegra30_pm_secondary_cpu_suspend(unsigned long unused_arg) * * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU. */ -ENTRY(tegra30_sleep_cpu_secondary_finish) +ENTRY(tegra30_pm_secondary_cpu_suspend) mov r7, lr /* Flush and disable the L1 data cache */ @@ -281,7 +281,7 @@ ENTRY(tegra30_sleep_cpu_secondary_finish) bl tegra30_cpu_shutdown mov r0, #1 @ never return here ret r7 -ENDPROC(tegra30_sleep_cpu_secondary_finish) +ENDPROC(tegra30_pm_secondary_cpu_suspend) /* * tegra30_tear_down_cpu diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 78ef32a907c8..4718a3cb45a1 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h @@ -114,29 +114,14 @@ .endm #else -void tegra_pen_lock(void); -void tegra_pen_unlock(void); void tegra_resume(void); int tegra_sleep_cpu_finish(unsigned long); void tegra_disable_clean_inv_dcache(u32 flag); -#ifdef CONFIG_HOTPLUG_CPU void tegra20_hotplug_shutdown(void); void tegra30_hotplug_shutdown(void); -#endif - -void tegra20_cpu_shutdown(int cpu); -int tegra20_cpu_is_resettable_soon(void); -void tegra20_cpu_clear_resettable(void); -#ifdef CONFIG_ARCH_TEGRA_2x_SOC -void tegra20_cpu_set_resettable_soon(void); -#else -static inline void tegra20_cpu_set_resettable_soon(void) {} -#endif -int tegra20_sleep_cpu_secondary_finish(unsigned long); void tegra20_tear_down_cpu(void); -int tegra30_sleep_cpu_secondary_finish(unsigned long); void tegra30_tear_down_cpu(void); #endif diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index e512e606eabd..f1ce2857a251 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -36,13 +36,12 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach-types.h> +#include <asm/psci.h> #include <asm/setup.h> #include "board.h" #include "common.h" -#include "cpuidle.h" #include "iomap.h" -#include "irq.h" #include "pm.h" #include "reset.h" #include "sleep.h" @@ -86,7 +85,6 @@ static void __init tegra_dt_init(void) static void __init tegra_dt_init_late(void) { tegra_init_suspend(); - tegra_cpuidle_init(); if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && of_machine_is_compatible("compal,paz00")) @@ -95,6 +93,9 @@ static void __init tegra_dt_init_late(void) if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && of_machine_is_compatible("nvidia,tegra20")) platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0); + + if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available()) + platform_device_register_simple("tegra-cpuidle", -1, NULL, 0); } static const char * const tegra_dt_board_compat[] = { diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 3a4248fd7962..a9dd2f71cd19 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -12,10 +12,10 @@ #include <linux/cpumask.h> #include <linux/platform_device.h> #include <linux/clk.h> -#include <linux/clk-provider.h> #include <linux/clk/zynq.h> #include <linux/clocksource.h> #include <linux/of_address.h> +#include <linux/of_clk.h> #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/of.h> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 9414d72f664b..8a8949174b1c 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -179,6 +179,23 @@ static void arm_dma_sync_single_for_device(struct device *dev, __dma_page_cpu_to_dev(page, offset, size, dir); } +/* + * Return whether the given device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits + * during bus mastering, then you would pass 0x00ffffff as the mask + * to this function. + */ +static int arm_dma_supported(struct device *dev, u64 mask) +{ + unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit); + + /* + * Translate the device's DMA mask to a PFN limit. This + * PFN number includes the page which we can DMA to. + */ + return dma_to_pfn(dev, mask) >= max_dma_pfn; +} + const struct dma_map_ops arm_dma_ops = { .alloc = arm_dma_alloc, .free = arm_dma_free, @@ -219,49 +236,6 @@ const struct dma_map_ops arm_coherent_dma_ops = { }; EXPORT_SYMBOL(arm_coherent_dma_ops); -static int __dma_supported(struct device *dev, u64 mask, bool warn) -{ - unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit); - - /* - * Translate the device's DMA mask to a PFN limit. This - * PFN number includes the page which we can DMA to. - */ - if (dma_to_pfn(dev, mask) < max_dma_pfn) { - if (warn) - dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", - mask, - dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, - max_dma_pfn + 1); - return 0; - } - - return 1; -} - -static u64 get_coherent_dma_mask(struct device *dev) -{ - u64 mask = (u64)DMA_BIT_MASK(32); - - if (dev) { - mask = dev->coherent_dma_mask; - - /* - * Sanity check the DMA mask - it must be non-zero, and - * must be able to be satisfied by a DMA allocation. - */ - if (mask == 0) { - dev_warn(dev, "coherent DMA mask is unset\n"); - return 0; - } - - if (!__dma_supported(dev, mask, true)) - return 0; - } - - return mask; -} - static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) { /* @@ -688,7 +662,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, pgprot_t prot, bool is_coherent, unsigned long attrs, const void *caller) { - u64 mask = get_coherent_dma_mask(dev); + u64 mask = min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit); struct page *page = NULL; void *addr; bool allowblock, cma; @@ -712,9 +686,6 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, } #endif - if (!mask) - return NULL; - buf = kzalloc(sizeof(*buf), gfp & ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM)); if (!buf) @@ -1087,17 +1058,6 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, dir); } -/* - * Return whether the given device DMA address mask can be supported - * properly. For example, if your device can only drive the low 24-bits - * during bus mastering, then you would pass 0x00ffffff as the mask - * to this function. - */ -int arm_dma_supported(struct device *dev, u64 mask) -{ - return __dma_supported(dev, mask, false); -} - static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent) { /* diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index b598e6978b29..2dd5c41cbb8d 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -189,7 +189,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) */ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) { - unsigned int mask = VM_READ | VM_WRITE | VM_EXEC; + unsigned int mask = VM_ACCESS_FLAGS; if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) mask = VM_WRITE; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 69a337df619f..ec8d0008bfa1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1646,3 +1646,17 @@ void __init early_mm_init(const struct machine_desc *mdesc) build_mem_type_table(); early_paging_init(mdesc); } + +void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval) +{ + unsigned long ext = 0; + + if (addr < TASK_SIZE && pte_valid_user(pteval)) { + if (!pte_special(pteval)) + __sync_icache_dcache(pteval); + ext |= PTE_EXT_NG; + } + + set_pte_ext(ptep, pteval, ext); +} diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index cc29869d12a3..bf85d6db4931 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[], rd = arm_bpf_get_reg64(dst, tmp, ctx); /* Do LSR operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for LSR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx); @@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[], rd = arm_bpf_get_reg64(dst, tmp, ctx); /* Do ARSH operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for ASR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx); @@ -992,21 +1000,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[], arm_bpf_put_reg32(dst_hi, rd[0], ctx); } +static bool is_ldst_imm(s16 off, const u8 size) +{ + s16 off_max = 0; + + switch (size) { + case BPF_B: + case BPF_W: + off_max = 0xfff; + break; + case BPF_H: + off_max = 0xff; + break; + case BPF_DW: + /* Need to make sure off+4 does not overflow. */ + off_max = 0xfff - 4; + break; + } + return -off_max <= off && off <= off_max; +} + /* *(size *)(dst + off) = src */ static inline void emit_str_r(const s8 dst, const s8 src[], - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; - s32 off_max; s8 rd; rd = arm_bpf_get_reg32(dst, tmp[1], ctx); - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); rd = tmp[0]; @@ -1035,18 +1057,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[], /* dst = *(size*)(src + off) */ static inline void emit_ldx_r(const s8 dst[], const s8 src, - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *rd = is_stacked(dst_lo) ? tmp : dst; s8 rm = src; - s32 off_max; - - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); rm = tmp[0]; diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index ffb93db68e9c..509d4824dc1c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -177,12 +177,6 @@ static irqreturn_t orion_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction orion_timer_irq = { - .name = "orion_tick", - .flags = IRQF_TIMER, - .handler = orion_timer_interrupt -}; - void __init orion_time_set_base(void __iomem *_timer_base) { @@ -236,7 +230,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, /* * Setup clockevent timer (interrupt-driven). */ - setup_irq(irq, &orion_timer_irq); + if (request_irq(irq, orion_timer_interrupt, IRQF_TIMER, "orion_tick", + NULL)) + pr_err("Failed to request irq %u (orion_tick)\n", irq); orion_clkevt.cpumask = cpumask_of(0); clockevents_config_and_register(&orion_clkevt, tclk, 1, 0xfffffffe); } diff --git a/arch/arm/vdso/.gitignore b/arch/arm/vdso/.gitignore index 6b47f6e0b032..dfa06f5365cf 100644 --- a/arch/arm/vdso/.gitignore +++ b/arch/arm/vdso/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds vdso.so.raw vdsomunge diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index dd6804a64f1a..fd4e1ce1daf9 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -36,7 +36,7 @@ #include <linux/mm.h> -struct start_info _xen_start_info; +static struct start_info _xen_start_info; struct start_info *xen_start_info = &_xen_start_info; EXPORT_SYMBOL(xen_start_info); diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 6e41c4b62607..40fb05d96c60 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1502,7 +1502,10 @@ config ARM64_PTR_AUTH default y depends on !KVM || ARM64_VHE depends on (CC_HAS_SIGN_RETURN_ADDRESS || CC_HAS_BRANCH_PROT_PAC_RET) && AS_HAS_PAC - depends on CC_IS_GCC || (CC_IS_CLANG && AS_HAS_CFI_NEGATE_RA_STATE) + # GCC 9.1 and later inserts a .note.gnu.property section note for PAC + # which is only understood by binutils starting with version 2.33.1. + depends on !CC_IS_GCC || GCC_VERSION < 90100 || LD_VERSION >= 233010000 + depends on !CC_IS_CLANG || AS_HAS_CFI_NEGATE_RA_STATE depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS) help Pointer authentication (part of the ARMv8.3 Extensions) provides diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 1c906d932d6b..a1efa246c9ed 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -52,19 +52,6 @@ config DEBUG_WX If in doubt, say "Y". -config DEBUG_ALIGN_RODATA - depends on STRICT_KERNEL_RWX - bool "Align linker sections up to SECTION_SIZE" - help - If this option is enabled, sections that may potentially be marked as - read only or non-executable will be aligned up to the section size of - the kernel. This prevents sections from being split into pages and - avoids a potential TLB penalty. The downside is an increase in - alignment and potentially wasted space. Turn on this option if - performance is more important than memory pressure. - - If in doubt, say N. - config DEBUG_EFI depends on EFI && DEBUG_INFO bool "UEFI debugging" diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 76778b2f520d..55d70cfe0f9e 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -39,7 +39,6 @@ config ARCH_BCM2835 select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 - select HAVE_ARM_ARCH_TIMER help This enables support for the Broadcom BCM2837 and BCM2711 SoC. These SoCs are used in the Raspberry Pi 3 and 4 devices. @@ -301,7 +300,6 @@ config ARCH_ZX config ARCH_ZYNQMP bool "Xilinx ZynqMP Family" - select ZYNQMP_FIRMWARE help This enables support for Xilinx ZynqMP Family diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index f15f92ba53e6..85e4149cc5d5 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -65,6 +65,10 @@ stack_protector_prepare: prepare0 include/generated/asm-offsets.h)) endif +# Ensure that if the compiler supports branch protection we default it +# off, this will be overridden if we are using branch protection. +branch-prot-flags-y += $(call cc-option,-mbranch-protection=none) + ifeq ($(CONFIG_ARM64_PTR_AUTH),y) branch-prot-flags-$(CONFIG_CC_HAS_SIGN_RETURN_ADDRESS) := -msign-return-address=all branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET) := -mbranch-protection=pac-ret+leaf @@ -73,9 +77,10 @@ branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET) := -mbranch-protection=pa # we pass it only to the assembler. This option is utilized only in case of non # integrated assemblers. branch-prot-flags-$(CONFIG_AS_HAS_PAC) += -Wa,-march=armv8.3-a -KBUILD_CFLAGS += $(branch-prot-flags-y) endif +KBUILD_CFLAGS += $(branch-prot-flags-y) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore index 8dab0bb6ae66..9a7a9009d43a 100644 --- a/arch/arm64/boot/.gitignore +++ b/arch/arm64/boot/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only Image Image.gz diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index cf4f78617c3f..e4d3cd0ac5bb 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -9,6 +9,9 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-lts.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinephone-1.0.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinephone-1.1.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts index 6dfafa1c879b..5fa9ca0191a8 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts @@ -158,6 +158,17 @@ */ }; +&pio { + vcc-pa-supply = <®_dcdc1>; + vcc-pb-supply = <®_dcdc1>; + vcc-pc-supply = <®_dcdc1>; + vcc-pd-supply = <®_dcdc1>; + vcc-pe-supply = <®_aldo1>; + vcc-pf-supply = <®_dcdc1>; + vcc-pg-supply = <®_dldo4>; + vcc-ph-supply = <®_dcdc1>; +}; + &r_rsb { status = "okay"; @@ -170,6 +181,12 @@ }; }; +/* VCC-PL is powered by aldo2 but we cannot add it as the RSB */ +/* interface used to talk to the PMIC in on the PL pins */ +/* &r_pio { */ +/* vcc-pl-supply = <®_aldo2>; */ +/* }; */ + #include "axp803.dtsi" &ac_power_supply { diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts index 3d894b208901..64b1c54f87c0 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts @@ -21,32 +21,17 @@ ethernet0 = &rtl8723cs; }; - vdd_bl: regulator@0 { - compatible = "regulator-fixed"; - regulator-name = "bl-3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ - enable-active-high; - }; - backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm 0 50000 0>; brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>; default-brightness-level = <2>; enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */ - power-supply = <&vdd_bl>; + power-supply = <®_vbklt>; }; chosen { stdout-path = "serial0:115200n8"; - - framebuffer-lcd { - panel-supply = <®_dc1sw>; - dvdd25-supply = <®_dldo2>; - dvdd12-supply = <®_fldo1>; - }; }; gpio_keys { @@ -63,11 +48,34 @@ }; }; - reg_vcc3v3: vcc3v3 { + panel_edp: panel-edp { + compatible = "neweast,wjfh116008a"; + backlight = <&backlight>; + power-supply = <®_dc1sw>; + + port { + panel_edp_in: endpoint { + remote-endpoint = <&anx6345_out_edp>; + }; + }; + }; + + reg_vbklt: vbklt { + compatible = "regulator-fixed"; + regulator-name = "vbklt"; + regulator-min-microvolt = <18000000>; + regulator-max-microvolt = <18000000>; + gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ + enable-active-high; + }; + + reg_vcc5v0: vcc5v0 { compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&axp_gpio 0 GPIO_ACTIVE_HIGH>; + enable-active-high; }; wifi_pwrseq: wifi_pwrseq { @@ -77,12 +85,7 @@ speaker_amp: audio-amplifier { compatible = "simple-audio-amplifier"; - /* - * TODO This is actually a fixed regulator controlled by - * the GPIO line on the PMIC. This should be corrected - * once GPIO support is added for this PMIC. - */ - VCC-supply = <®_ldo_io0>; + VCC-supply = <®_vcc5v0>; enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */ sound-name-prefix = "Speaker Amp"; }; @@ -118,6 +121,10 @@ status = "okay"; }; +&de { + status = "okay"; +}; + &ehci0 { phys = <&usbphy 0>; phy-names = "usb"; @@ -128,11 +135,15 @@ status = "okay"; }; +&mixer0 { + status = "okay"; +}; + &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; vmmc-supply = <®_dcdc1>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ disable-wp; bus-width = <4>; status = "okay"; @@ -175,10 +186,61 @@ status = "okay"; }; +&pio { + vcc-pc-supply = <®_eldo1>; + vcc-pd-supply = <®_dcdc1>; + vcc-pe-supply = <®_aldo1>; + vcc-pg-supply = <®_eldo1>; +}; + &pwm { status = "okay"; }; +&r_i2c { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&r_i2c_pl89_pins>; + status = "okay"; + + anx6345: anx6345@38 { + compatible = "analogix,anx6345"; + reg = <0x38>; + reset-gpios = <&pio 3 24 GPIO_ACTIVE_LOW>; /* PD24 */ + dvdd25-supply = <®_dldo2>; + dvdd12-supply = <®_fldo1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + anx6345_in: port@0 { + reg = <0>; + anx6345_in_tcon0: endpoint { + remote-endpoint = <&tcon0_out_anx6345>; + }; + }; + + anx6345_out: port@1 { + reg = <1>; + anx6345_out_edp: endpoint { + remote-endpoint = <&panel_edp_in>; + }; + }; + }; + }; +}; + +&r_pio { + /* + * FIXME: We can't add that supply for now since it would + * create a circular dependency between pinctrl, the regulator + * and the RSB Bus. + * + * vcc-pl-supply = <®_aldo2>; + */ +}; + &r_rsb { status = "okay"; @@ -190,14 +252,6 @@ }; }; -/* The ANX6345 eDP-bridge is on r_i2c */ -&r_i2c { - clock-frequency = <100000>; - pinctrl-names = "default"; - pinctrl-0 = <&r_i2c_pl89_pins>; - status = "okay"; -}; - #include "axp803.dtsi" &ac_power_supply { @@ -209,9 +263,7 @@ }; ®_aldo1 { - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-name = "vcc-csi"; + regulator-name = "vcc-pe"; }; ®_aldo2 { @@ -274,12 +326,6 @@ regulator-name = "vcc-edp"; }; -®_dldo3 { - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "avdd-csi"; -}; - ®_dldo4 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -293,12 +339,6 @@ regulator-name = "cpvdd"; }; -®_eldo3 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vdd-1v8-csi"; -}; - ®_fldo1 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -312,17 +352,16 @@ regulator-name = "vdd-cpus"; }; -®_ldo_io0 { - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc-usb"; - status = "okay"; -}; - ®_rtc_ldo { regulator-name = "vcc-rtc"; }; +&simplefb_lcd { + panel-supply = <®_dc1sw>; + dvdd25-supply = <®_dldo2>; + dvdd12-supply = <®_fldo1>; +}; + &simplefb_hdmi { vcc-hdmi-supply = <®_dldo1>; }; @@ -350,6 +389,19 @@ "MIC2", "Internal Microphone Right"; }; +&tcon0 { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rgb666_pins>; + + status = "okay"; +}; + +&tcon0_out { + tcon0_out_anx6345: endpoint { + remote-endpoint = <&anx6345_in_tcon0>; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pb_pins>; @@ -361,7 +413,7 @@ }; &usbphy { - usb0_vbus-supply = <®_ldo_io0>; - usb1_vbus-supply = <®_ldo_io0>; + usb0_vbus-supply = <®_vcc5v0>; + usb1_vbus-supply = <®_vcc5v0>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts new file mode 100644 index 000000000000..0c42272106af --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2020 Ondrej Jirman <megous@megous.com> + +/dts-v1/; + +#include "sun50i-a64-pinephone.dtsi" + +/ { + model = "Pine64 PinePhone Developer Batch (1.0)"; + compatible = "pine64,pinephone-1.0", "allwinner,sun50i-a64"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts new file mode 100644 index 000000000000..06a775c41664 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2020 Ondrej Jirman <megous@megous.com> + +/dts-v1/; + +#include "sun50i-a64-pinephone.dtsi" + +/ { + model = "Pine64 PinePhone Braveheart (1.1)"; + compatible = "pine64,pinephone-1.1", "allwinner,sun50i-a64"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi new file mode 100644 index 000000000000..cefda145c3c9 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.xyz> +// Copyright (C) 2020 Martijn Braam <martijn@brixit.nl> +// Copyright (C) 2020 Ondrej Jirman <megous@megous.com> + +#include "sun50i-a64.dtsi" +#include "sun50i-a64-cpu-opp.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pwm/pwm.h> + +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + blue { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_BLUE>; + gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */ + }; + + green { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */ + }; + + red { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_RED>; + gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */ + }; + }; + + speaker_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&pio 2 7 GPIO_ACTIVE_HIGH>; /* PC7 */ + sound-name-prefix = "Speaker Amp"; + }; + + vibrator { + compatible = "gpio-vibrator"; + enable-gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */ + vcc-supply = <®_dcdc1>; + }; +}; + +&codec { + status = "okay"; +}; + +&codec_analog { + cpvdd-supply = <®_eldo1>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&cpu1 { + cpu-supply = <®_dcdc2>; +}; + +&cpu2 { + cpu-supply = <®_dcdc2>; +}; + +&cpu3 { + cpu-supply = <®_dcdc2>; +}; + +&dai { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + /* Magnetometer */ + lis3mdl@1e { + compatible = "st,lis3mdl-magn"; + reg = <0x1e>; + vdd-supply = <®_dldo1>; + vddio-supply = <®_dldo1>; + }; + + /* Accelerometer/gyroscope */ + mpu6050@68 { + compatible = "invensense,mpu6050"; + reg = <0x68>; + interrupt-parent = <&pio>; + interrupts = <7 5 IRQ_TYPE_EDGE_RISING>; /* PH5 */ + vdd-supply = <®_dldo1>; + vddio-supply = <®_dldo1>; + }; +}; + +/* Connected to pogo pins (external spring based pinheader for user addons) */ +&i2c2 { + status = "okay"; +}; + +&lradc { + vref-supply = <®_aldo3>; + status = "okay"; + + button-200 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + channel = <0>; + voltage = <200000>; + }; + + button-400 { + label = "Volume Down"; + linux,code = <KEY_VOLUMEDOWN>; + channel = <0>; + voltage = <400000>; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_dcdc1>; + vcc-pc-supply = <®_dcdc1>; + vcc-pd-supply = <®_dcdc1>; + vcc-pe-supply = <®_aldo1>; + vcc-pf-supply = <®_dcdc1>; + vcc-pg-supply = <®_dldo4>; + vcc-ph-supply = <®_dcdc1>; +}; + +&r_pio { + /* + * FIXME: We can't add that supply for now since it would + * create a circular dependency between pinctrl, the regulator + * and the RSB Bus. + * + * vcc-pl-supply = <®_aldo2>; + */ +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +&battery_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "dovdd-csi"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-dsi-sensor"; +}; + +®_dldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-mipi-io"; +}; + +®_dldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "avdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-io"; +}; + +®_eldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-lpddr"; +}; + +®_eldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "dvdd-1v8-csi"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_ldo_io0 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-lcd-ctp-stk"; + status = "okay"; +}; + +®_ldo_io1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-1v8-typec"; + status = "okay"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&sound { + status = "okay"; + simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>; + simple-audio-card,widgets = "Microphone", "Headset Microphone", + "Microphone", "Internal Microphone", + "Headphone", "Headphone Jack", + "Speaker", "Internal Earpiece", + "Speaker", "Internal Speaker"; + simple-audio-card,routing = + "Headphone Jack", "HP", + "Internal Earpiece", "EARPIECE", + "Internal Speaker", "Speaker Amp OUTL", + "Internal Speaker", "Speaker Amp OUTR", + "Speaker Amp INL", "LINEOUT", + "Speaker Amp INR", "LINEOUT", + "Left DAC", "AIF1 Slot 0 Left", + "Right DAC", "AIF1 Slot 0 Right", + "AIF1 Slot 0 Left ADC", "Left ADC", + "AIF1 Slot 0 Right ADC", "Right ADC", + "Internal Microphone", "MBIAS", + "MIC1", "Internal Microphone", + "Headset Microphone", "HBIAS", + "MIC2", "Headset Microphone"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +/* Connected to the modem (hardware flow control can't be used) */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts new file mode 100644 index 000000000000..316e8a443913 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts @@ -0,0 +1,460 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.xyz> + * + */ + +/dts-v1/; + +#include "sun50i-a64.dtsi" +#include "sun50i-a64-cpu-opp.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pwm/pwm.h> + +/ { + model = "PineTab"; + compatible = "pine64,pinetab", "allwinner,sun50i-a64"; + + aliases { + serial0 = &uart0; + ethernet0 = &rtl8723cs; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; + brightness-levels = <0 16 18 20 22 24 26 29 32 35 38 42 46 51 56 62 68 75 83 91 100>; + default-brightness-level = <15>; + enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */ + power-supply = <&vdd_bl>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + i2c-csi { + compatible = "i2c-gpio"; + sda-gpios = <&pio 4 13 GPIO_ACTIVE_HIGH>; /* PE13 */ + scl-gpios = <&pio 4 12 GPIO_ACTIVE_HIGH>; /* PE12 */ + i2c-gpio,delay-us = <5>; + #address-cells = <1>; + #size-cells = <0>; + + /* Rear camera */ + ov5640: camera@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&csi_mclk_pin>; + clocks = <&ccu CLK_CSI_MCLK>; + clock-names = "xclk"; + + AVDD-supply = <®_dldo3>; + DOVDD-supply = <®_aldo1>; + DVDD-supply = <®_eldo3>; + reset-gpios = <&pio 4 14 GPIO_ACTIVE_LOW>; /* PE14 */ + powerdown-gpios = <&pio 4 15 GPIO_ACTIVE_HIGH>; /* PE15 */ + + port { + ov5640_ep: endpoint { + remote-endpoint = <&csi_ep>; + bus-width = <8>; + hsync-active = <1>; /* Active high */ + vsync-active = <0>; /* Active low */ + data-active = <1>; /* Active high */ + pclk-sample = <1>; /* Rising */ + }; + }; + }; + }; + + speaker_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */ + sound-name-prefix = "Speaker Amp"; + }; + + vdd_bl: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "bl-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ + enable-active-high; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ + post-power-on-delay-ms = <200>; + }; +}; + +&codec { + status = "okay"; +}; + +&codec_analog { + hpvcc-supply = <®_eldo1>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&cpu1 { + cpu-supply = <®_dcdc2>; +}; + +&cpu2 { + cpu-supply = <®_dcdc2>; +}; + +&cpu3 { + cpu-supply = <®_dcdc2>; +}; + +&csi { + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + csi_ep: endpoint { + remote-endpoint = <&ov5640_ep>; + bus-width = <8>; + hsync-active = <1>; /* Active high */ + vsync-active = <0>; /* Active low */ + data-active = <1>; /* Active high */ + pclk-sample = <1>; /* Rising */ + }; + }; +}; + +&dai { + status = "okay"; +}; + +&de { + status = "okay"; +}; + +&dphy { + status = "okay"; +}; + +&dsi { + vcc-dsi-supply = <®_dldo1>; + status = "okay"; + + panel@0 { + compatible = "feixin,k101-im2ba02"; + reg = <0>; + avdd-supply = <®_dc1sw>; + dvdd-supply = <®_dc1sw>; + cvdd-supply = <®_ldo_io1>; + reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ + backlight = <&backlight>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + touchscreen@5d { + compatible = "goodix,gt9271"; + reg = <0x5d>; + interrupt-parent = <&pio>; + interrupts = <7 4 IRQ_TYPE_LEVEL_HIGH>; /* PH4 */ + irq-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + reset-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; /* PH8 */ + AVDD28-supply = <®_ldo_io1>; + }; +}; + +&i2c0_pins { + bias-pull-up; +}; + +&i2c1 { + status = "okay"; + + /* TODO: add Bochs BMA223 accelerometer here */ +}; + +&lradc { + vref-supply = <®_aldo3>; + status = "okay"; + + button-200 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + channel = <0>; + voltage = <200000>; + }; + + button-400 { + label = "Volume Down"; + linux,code = <KEY_VOLUMEDOWN>; + channel = <0>; + voltage = <400000>; + }; +}; + +&mixer1 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <®_dldo4>; + vqmmc-supply = <®_eldo1>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; + + rtl8723cs: wifi@1 { + reg = <1>; + }; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&pwm { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + x-powers,drive-vbus-en; + }; +}; + +#include "axp803.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +&battery_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "dovdd-csi"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-lcd"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi-dsi-sensor"; +}; + +®_dldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "avdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +®_eldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_eldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca-1v8"; +}; + +®_eldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "dvdd-1v8-csi"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_ldo_io0 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-usb"; + status = "okay"; +}; + +®_ldo_io1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <3500000>; + regulator-name = "vcc-touchscreen"; + status = "okay"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&sound { + status = "okay"; + simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>; + simple-audio-card,widgets = "Microphone", "Internal Microphone Left", + "Microphone", "Internal Microphone Right", + "Headphone", "Headphone Jack", + "Speaker", "Internal Speaker"; + simple-audio-card,routing = + "Left DAC", "AIF1 Slot 0 Left", + "Right DAC", "AIF1 Slot 0 Right", + "Speaker Amp INL", "LINEOUT", + "Speaker Amp INR", "LINEOUT", + "Internal Speaker", "Speaker Amp OUTL", + "Internal Speaker", "Speaker Amp OUTR", + "Headphone Jack", "HP", + "AIF1 Slot 0 Left ADC", "Left ADC", + "AIF1 Slot 0 Right ADC", "Right ADC", + "Internal Microphone Left", "MBIAS", + "MIC1", "Internal Microphone Left", + "Internal Microphone Right", "HBIAS", + "MIC2", "Internal Microphone Right"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb0_vbus-supply = <®_drivevbus>; + usb1_vbus-supply = <®_ldo_io0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 862b47dc9dc9..31143fe64d91 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -264,7 +264,7 @@ display_clocks: clock@0 { compatible = "allwinner,sun50i-a64-de2-clk"; - reg = <0x0 0x100000>; + reg = <0x0 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -274,6 +274,18 @@ #reset-cells = <1>; }; + rotate: rotate@20000 { + compatible = "allwinner,sun50i-a64-de2-rotate", + "allwinner,sun8i-a83t-de2-rotate"; + reg = <0x20000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&display_clocks CLK_BUS_ROT>, + <&display_clocks CLK_ROT>; + clock-names = "bus", + "mod"; + resets = <&display_clocks RST_ROT>; + }; + mixer0: mixer@100000 { compatible = "allwinner,sun50i-a64-de2-mixer-0"; reg = <0x100000 0x100000>; @@ -671,6 +683,11 @@ function = "i2c1"; }; + i2c2_pins: i2c2-pins { + pins = "PE14", "PE15"; + function = "i2c2"; + }; + /omit-if-no-ref/ lcd_rgb666_pins: lcd-rgb666-pins { pins = "PD0", "PD1", "PD2", "PD3", "PD4", @@ -958,12 +975,13 @@ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_I2C2>; resets = <&ccu RST_BUS_I2C2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; - spi0: spi@1c68000 { compatible = "allwinner,sun8i-h3-spi"; reg = <0x01c68000 0x1000>; @@ -1061,6 +1079,14 @@ status = "disabled"; }; + mbus: dram-controller@1c62000 { + compatible = "allwinner,sun50i-a64-mbus"; + reg = <0x01c62000 0x1000>; + clocks = <&ccu 112>; + dma-ranges = <0x00000000 0x40000000 0xc0000000>; + #interconnect-cells = <1>; + }; + csi: csi@1cb0000 { compatible = "allwinner,sun50i-a64-csi"; reg = <0x01cb0000 0x1000>; @@ -1106,6 +1132,20 @@ #phy-cells = <0>; }; + deinterlace: deinterlace@1e00000 { + compatible = "allwinner,sun50i-a64-deinterlace", + "allwinner,sun8i-h3-deinterlace"; + reg = <0x01e00000 0x20000>; + clocks = <&ccu CLK_BUS_DEINTERLACE>, + <&ccu CLK_DEINTERLACE>, + <&ccu CLK_DRAM_DEINTERLACE>; + clock-names = "bus", "mod", "ram"; + resets = <&ccu RST_BUS_DEINTERLACE>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + interconnects = <&mbus 9>; + interconnect-names = "dma-mem"; + }; + hdmi: hdmi@1ee0000 { compatible = "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts index 70b5f0998421..7d7aad18f078 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts @@ -61,6 +61,7 @@ label = "sw4"; linux,code = <BTN_0>; gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + wakeup-source; }; }; @@ -93,6 +94,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + &de { status = "okay"; }; @@ -168,6 +173,22 @@ status = "okay"; }; +&r_i2c { + status = "okay"; + + reg_vdd_cpux: regulator@65 { + compatible = "silergy,sy8106a"; + reg = <0x65>; + regulator-name = "vdd-cpux"; + silergy,fixed-microvolt = <1100000>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-ramp-delay = <200>; + regulator-boot-on; + regulator-always-on; + }; +}; + &spi0 { status = "okay"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 9893aa64dd0b..4462a68c0681 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -38,8 +38,7 @@ }; pmu { - compatible = "arm,cortex-a53-pmu", - "arm,armv8-pmuv3"; + compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts index df6d872c34e2..8f09d209359b 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts @@ -32,6 +32,13 @@ }; }; + ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + leds { compatible = "gpio-leds"; @@ -275,6 +282,10 @@ vcc-pm-supply = <®_aldo1>; }; +&rtc { + clocks = <&ext_osc32k>; +}; + &spdif { status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts index c311eee52a35..47f579610dcc 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts @@ -32,6 +32,13 @@ }; }; + ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + leds { compatible = "gpio-leds"; @@ -144,6 +151,15 @@ }; }; +&mmc2 { + vmmc-supply = <®_cldo1>; + vqmmc-supply = <®_bldo2>; + cap-mmc-hw-reset; + non-removable; + bus-width = <8>; + status = "okay"; +}; + &ohci0 { status = "okay"; }; @@ -276,6 +292,10 @@ status = "okay"; }; +&rtc { + clocks = <&ext_osc32k>; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_ph_pins>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts index 83aab7368889..fceb298bfd53 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts @@ -7,4 +7,37 @@ / { model = "OrangePi One Plus"; compatible = "xunlong,orangepi-one-plus", "allwinner,sun50i-h6"; + + aliases { + ethernet0 = &emac; + }; + + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc-gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ + vin-supply = <®_aldo2>; + }; +}; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&ext_rgmii_pins>; + phy-mode = "rgmii"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_gmac_3v3>; + allwinner,rx-delay-ps = <200>; + allwinner,tx-delay-ps = <200>; + status = "okay"; +}; + +&mdio { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi index 37f4c57597d4..9287976c4a50 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi @@ -20,6 +20,25 @@ stdout-path = "serial0:115200n8"; }; + connector { + compatible = "hdmi-connector"; + type = "a"; + ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + leds { compatible = "gpio-leds"; @@ -45,6 +64,10 @@ }; }; +&de { + status = "okay"; +}; + &ehci0 { status = "okay"; }; @@ -58,6 +81,16 @@ status = "okay"; }; +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + &mmc0 { vmmc-supply = <®_cldo1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; @@ -197,6 +230,10 @@ status = "okay"; }; +&rtc { + clocks = <&ext_osc32k>; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_ph_pins>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts index d1c2aa5b3a20..b0642d841933 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts @@ -14,12 +14,20 @@ aliases { ethernet0 = &emac; serial0 = &uart0; + spi0 = &spi0; }; chosen { stdout-path = "serial0:115200n8"; }; + ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + hdmi_connector: connector { compatible = "hdmi-connector"; type = "a"; @@ -278,6 +286,28 @@ vcc-pm-supply = <®_aldo1>; }; +&rtc { + clocks = <&ext_osc32k>; +}; + +/* + * The CS pin is shared with the MMC2 CMD pin, so we cannot have the SPI + * flash and eMMC at the same time, as one of them would fail probing. + * Disable SPI0 in here, to prefer the more useful eMMC. U-Boot can + * fix this up in no eMMC is connected. + */ +&spi0 { + pinctrl-0 = <&spi0_pins>, <&spi0_cs_pin>; + pinctrl-names = "default"; + status = "disabled"; + + flash@0 { + compatible = "winbond,w25q128", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <4000000>; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_ph_pins>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index 3329283e38ab..b9ab7d8fa8af 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi @@ -62,16 +62,8 @@ clock-output-names = "osc24M"; }; - ext_osc32k: ext_osc32k_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "ext_osc32k"; - }; - pmu { - compatible = "arm,cortex-a53-pmu", - "arm,armv8-pmuv3"; + compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, @@ -338,6 +330,31 @@ bias-pull-up; }; + /omit-if-no-ref/ + spi0_pins: spi0-pins { + pins = "PC0", "PC2", "PC3"; + function = "spi0"; + }; + + /* pin shared with MMC2-CMD (eMMC) */ + /omit-if-no-ref/ + spi0_cs_pin: spi0-cs-pin { + pins = "PC5"; + function = "spi0"; + }; + + /omit-if-no-ref/ + spi1_pins: spi1-pins { + pins = "PH4", "PH5", "PH6"; + function = "spi1"; + }; + + /omit-if-no-ref/ + spi1_cs_pin: spi1-cs-pin { + pins = "PH3"; + function = "spi1"; + }; + spdif_tx_pin: spdif-tx-pin { pins = "PH7"; function = "spdif"; @@ -504,6 +521,36 @@ #size-cells = <0>; }; + spi0: spi@5010000 { + compatible = "allwinner,sun50i-h6-spi", + "allwinner,sun8i-h3-spi"; + reg = <0x05010000 0x1000>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + dmas = <&dma 22>, <&dma 22>; + dma-names = "rx", "tx"; + resets = <&ccu RST_BUS_SPI0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@5011000 { + compatible = "allwinner,sun50i-h6-spi", + "allwinner,sun8i-h3-spi"; + reg = <0x05011000 0x1000>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; + clock-names = "ahb", "mod"; + dmas = <&dma 23>, <&dma 23>; + dma-names = "rx", "tx"; + resets = <&ccu RST_BUS_SPI1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + emac: ethernet@5020000 { compatible = "allwinner,sun50i-h6-emac", "allwinner,sun50i-a64-emac"; @@ -800,7 +847,6 @@ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; clock-output-names = "osc32k", "osc32k-out", "iosc"; - clocks = <&ext_osc32k>; #clock-cells = <1>; }; diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts index fb11ef05d556..f6c4a15079d3 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts @@ -178,12 +178,12 @@ qspi_boot: partition@0 { label = "Boot and fpga data"; - reg = <0x0 0x034B0000>; + reg = <0x0 0x03FE0000>; }; - qspi_rootfs: partition@4000000 { + qspi_rootfs: partition@3FE0000 { label = "Root Filesystem - JFFS2"; - reg = <0x034B0000 0x0EB50000>; + reg = <0x03FE0000 0x0C020000>; }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi index 4dec518c4dde..755b4ad15184 100644 --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi @@ -60,6 +60,12 @@ sm: secure-monitor { compatible = "amlogic,meson-gxbb-sm"; + + pwrc: power-controller { + compatible = "amlogic,meson-a1-pwrc"; + #power-domain-cells = <1>; + status = "okay"; + }; }; soc { diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts index 4cd2d5951822..cb1360ae1211 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts @@ -313,15 +313,15 @@ dai-tdm-slot-rx-mask-1 = <1 1>; mclk-fs = <256>; - codec@0 { + codec-0 { sound-dai = <&lineout>; }; - codec@1 { + codec-1 { sound-dai = <&speaker_amp1>; }; - codec@2 { + codec-2 { sound-dai = <&linein>; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index abe04f4ad7d8..0882ea215b88 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -295,17 +295,9 @@ }; }; - emmc_pins: emmc { + emmc_ctrl_pins: emmc-ctrl { mux-0 { - groups = "emmc_nand_d0", - "emmc_nand_d1", - "emmc_nand_d2", - "emmc_nand_d3", - "emmc_nand_d4", - "emmc_nand_d5", - "emmc_nand_d6", - "emmc_nand_d7", - "emmc_cmd"; + groups = "emmc_cmd"; function = "emmc"; bias-pull-up; drive-strength-microamp = <4000>; @@ -319,6 +311,34 @@ }; }; + emmc_data_4b_pins: emmc-data-4b { + mux-0 { + groups = "emmc_nand_d0", + "emmc_nand_d1", + "emmc_nand_d2", + "emmc_nand_d3"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <4000>; + }; + }; + + emmc_data_8b_pins: emmc-data-8b { + mux-0 { + groups = "emmc_nand_d0", + "emmc_nand_d1", + "emmc_nand_d2", + "emmc_nand_d3", + "emmc_nand_d4", + "emmc_nand_d5", + "emmc_nand_d6", + "emmc_nand_d7"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <4000>; + }; + }; + emmc_ds_pins: emmc-ds { mux { groups = "emmc_nand_ds"; @@ -573,6 +593,17 @@ }; }; + nor_pins: nor { + mux { + groups = "nor_d", + "nor_q", + "nor_c", + "nor_cs"; + function = "nor"; + bias-disable; + }; + }; + pdm_din0_a_pins: pdm-din0-a { mux { groups = "pdm_din0_a"; @@ -957,6 +988,57 @@ }; }; + spicc0_x_pins: spicc0-x { + mux { + groups = "spi0_mosi_x", + "spi0_miso_x", + "spi0_clk_x"; + function = "spi0"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + + spicc0_ss0_x_pins: spicc0-ss0-x { + mux { + groups = "spi0_ss0_x"; + function = "spi0"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + + spicc0_c_pins: spicc0-c { + mux { + groups = "spi0_mosi_c", + "spi0_miso_c", + "spi0_ss0_c", + "spi0_clk_c"; + function = "spi0"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + + spicc1_pins: spicc1 { + mux { + groups = "spi1_mosi", + "spi1_miso", + "spi1_clk"; + function = "spi1"; + drive-strength-microamp = <4000>; + }; + }; + + spicc1_ss0_pins: spicc1-ss0 { + mux { + groups = "spi1_ss0"; + function = "spi1"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + tdm_a_din0_pins: tdm-a-din0 { mux { groups = "tdm_a_din0"; @@ -2051,6 +2133,39 @@ amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; }; + spicc0: spi@13000 { + compatible = "amlogic,meson-g12a-spicc"; + reg = <0x0 0x13000 0x0 0x44>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc CLKID_SPICC0>, + <&clkc CLKID_SPICC0_SCLK>; + clock-names = "core", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spicc1: spi@15000 { + compatible = "amlogic,meson-g12a-spicc"; + reg = <0x0 0x15000 0x0 0x44>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc CLKID_SPICC1>, + <&clkc CLKID_SPICC1_SCLK>; + clock-names = "core", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spifc: spi@14000 { + compatible = "amlogic,meson-gxbb-spifc"; + status = "disabled"; + reg = <0x0 0x14000 0x0 0x80>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_CLK81>; + }; + pwm_ef: pwm@19000 { compatible = "amlogic,meson-g12a-ee-pwm"; reg = <0x0 0x19000 0x0 0x20>; @@ -2220,6 +2335,7 @@ dr_mode = "host"; snps,dis_u2_susphy_quirk; snps,quirk-frame-length-adjustment; + snps,parkmode-disable-ss-quirk; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi index 03054c478896..783e5a397f86 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi @@ -1,3 +1,4 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2019 BayLibre, SAS @@ -56,6 +57,7 @@ <&clkc_audio AUD_CLKID_PDM_DCLK>, <&clkc_audio AUD_CLKID_PDM_SYSCLK>; clock-names = "pclk", "dclk", "sysclk"; + resets = <&clkc_audio AUD_RESET_PDM>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts index 2ac9e3a43b96..b00d0468c753 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts @@ -269,7 +269,7 @@ dai-tdm-slot-tx-mask-3 = <1 1>; mclk-fs = <256>; - codec@0 { + codec { sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; }; }; @@ -472,7 +472,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts index 2a324f0136e3..a26bfe72550f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts @@ -271,7 +271,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts index 4f2596d82989..1b07c8c06eac 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts @@ -443,7 +443,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi index 554863429aa6..c33e85fbdaba 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi @@ -8,6 +8,8 @@ #include <dt-bindings/sound/meson-g12a-tohdmitx.h> / { + model = "Khadas VIM3"; + vddcpu_a: regulator-vddcpu-a { /* * MP8756GD Regulator. @@ -48,7 +50,7 @@ sound { compatible = "amlogic,axg-sound-card"; - model = "G12A-KHADAS-VIM3"; + model = "G12B-KHADAS-VIM3"; audio-aux-devs = <&tdmout_b>; audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", "TDMOUT_B IN 1", "FRDDR_B OUT 1", diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts index 0e54c1dc2842..169ea283d4ee 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts @@ -208,7 +208,7 @@ sound { compatible = "amlogic,axg-sound-card"; - model = "G12A-ODROIDN2"; + model = "G12B-ODROID-N2"; audio-aux-devs = <&tdmout_b>; audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", "TDMOUT_B IN 1", "FRDDR_B OUT 1", @@ -435,7 +435,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; @@ -451,6 +451,27 @@ vqmmc-supply = <&flash_1v8>; }; +/* + * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins + * and eMMC Data 4 to 7 pins. + * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, + * and change bus-width to 4 then spifc can be enabled. + * The SW1 slide should also be set to the correct position. + */ +&spifc { + status = "disabled"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + mx25u64: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + }; +}; + &tdmif_b { status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts index ccd0bced01e8..325e448eb09c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts @@ -485,7 +485,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 40db06e28b66..03f79fe045b7 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -12,6 +12,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/thermal/thermal.h> / { interrupt-parent = <&gic>; @@ -83,6 +84,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 0>; + #cooling-cells = <2>; }; cpu1: cpu@1 { @@ -92,6 +94,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 0>; + #cooling-cells = <2>; }; cpu2: cpu@2 { @@ -101,6 +104,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 0>; + #cooling-cells = <2>; }; cpu3: cpu@3 { @@ -110,6 +114,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 0>; + #cooling-cells = <2>; }; l2: l2-cache0 { @@ -117,6 +122,53 @@ }; }; + thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = <&scpi_sensors 0>; + + trips { + cpu_passive: cpu-passive { + temperature = <80000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + + cpu_hot: cpu-hot { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "hot"; + }; + + cpu_critical: cpu-critical { + temperature = <110000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cpu_cooling_maps: cooling-maps { + map0 { + trip = <&cpu_passive>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + arm-pmu { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index 6ded279c40c8..b46ef985bb44 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -248,6 +248,7 @@ status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; pinctrl-names = "default"; + linux,rc-map-name = "rc-odroid"; }; &gpio_ao { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index 5eab3dfdbd55..45cb83625951 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -245,6 +245,9 @@ bluetooth { compatible = "brcm,bcm43438-bt"; shutdown-gpios = <&gpio GPIOX_20 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi index 43eb7d149e36..6ac678f88bd8 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi @@ -15,7 +15,6 @@ / { aliases { serial0 = &uart_AO; - serial1 = &uart_A; ethernet0 = ðmac; }; @@ -180,6 +179,14 @@ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; pinctrl-names = "default"; uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + }; }; &uart_AO { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts index d5dc12878dfe..27eeab71ec77 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts @@ -8,7 +8,6 @@ /dts-v1/; #include <dt-bindings/input/input.h> -#include <dt-bindings/thermal/thermal.h> #include "meson-gxm.dtsi" @@ -100,49 +99,6 @@ clock-names = "ext_clock"; }; - thermal-zones { - cpu-thermal { - polling-delay-passive = <250>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ - - thermal-sensors = <&scpi_sensors 0>; - - trips { - cpu_alert0: cpu-alert0 { - temperature = <70000>; /* millicelsius */ - hysteresis = <2000>; /* millicelsius */ - type = "active"; - }; - - cpu_alert1: cpu-alert1 { - temperature = <80000>; /* millicelsius */ - hysteresis = <2000>; /* millicelsius */ - type = "passive"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu_alert0>; - cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>; - }; - - map1 { - trip = <&cpu_alert1>; - cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>, - <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - }; - hdmi_5v: regulator-hdmi-5v { compatible = "regulator-fixed"; @@ -198,36 +154,23 @@ hdmi-phandle = <&hdmi_tx>; }; -&cpu0 { - #cooling-cells = <2>; -}; - -&cpu1 { - #cooling-cells = <2>; -}; - -&cpu2 { - #cooling-cells = <2>; -}; - -&cpu3 { - #cooling-cells = <2>; -}; - -&cpu4 { - #cooling-cells = <2>; -}; -&cpu5 { - #cooling-cells = <2>; -}; - -&cpu6 { - #cooling-cells = <2>; -}; +&cpu_cooling_maps { + map0 { + cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>; + }; -&cpu7 { - #cooling-cells = <2>; + map1 { + cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>, + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; }; ðmac { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index 5ff64a0d2dcf..b6f89f108e28 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -49,6 +49,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; + #cooling-cells = <2>; }; cpu5: cpu@101 { @@ -58,6 +59,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; + #cooling-cells = <2>; }; cpu6: cpu@102 { @@ -67,6 +69,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; + #cooling-cells = <2>; }; cpu7: cpu@103 { @@ -76,6 +79,7 @@ enable-method = "psci"; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; + #cooling-cells = <2>; }; }; }; @@ -124,6 +128,30 @@ compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc"; }; +&cpu_cooling_maps { + map0 { + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; +}; + &saradc { compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi index 90815fa25ec6..094ecf2222bb 100644 --- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi @@ -9,8 +9,6 @@ #include <dt-bindings/gpio/meson-g12a-gpio.h> / { - model = "Khadas VIM3"; - aliases { serial0 = &uart_AO; ethernet0 = ðmac; @@ -312,7 +310,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; @@ -328,6 +326,26 @@ vqmmc-supply = <&emmc_1v8>; }; +/* + * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR CS + * and eMMC Data 4 to 7 pins. + * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, + * and change bus-width to 4 then spifc can be enabled. + */ +&spifc { + status = "disabled"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + w25q32: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "winbond,w25q128fw", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + }; +}; + &uart_A { status = "okay"; pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts index cb1b48f5b8b1..dfb2438851c0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts @@ -518,7 +518,7 @@ /* eMMC */ &sd_emmc_c { status = "okay"; - pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; pinctrl-1 = <&emmc_clk_gate_pins>; pinctrl-names = "default", "clk-gate"; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi index d847a3fcbc85..d4ec735fb1a5 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi @@ -448,6 +448,7 @@ <&clkc_audio AUD_CLKID_PDM_DCLK>, <&clkc_audio AUD_CLKID_PDM_SYSCLK>; clock-names = "pclk", "dclk", "sysclk"; + resets = <&clkc_audio AUD_RESET_PDM>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi index 3f78373f708a..12f039fa3dad 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dtsi +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -92,7 +92,7 @@ timeout-sec = <30>; }; - smb@8000000 { + bus@8000000 { compatible = "arm,vexpress,v2m-p1", "simple-bus"; arm,v2m-memory-map = "rs1"; #address-cells = <2>; /* SMB chipselect number and offset */ diff --git a/arch/arm64/boot/dts/arm/fvp-base-revc.dts b/arch/arm64/boot/dts/arm/fvp-base-revc.dts index 335fff762451..66381d89c1ce 100644 --- a/arch/arm64/boot/dts/arm/fvp-base-revc.dts +++ b/arch/arm64/boot/dts/arm/fvp-base-revc.dts @@ -206,7 +206,7 @@ }; }; - smb@8000000 { + bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index 1f3c80aafbd7..f5889281545f 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -800,7 +800,7 @@ <0x00000008 0x80000000 0x1 0x80000000>; }; - smb@8000000 { + bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi index 9f60dacb4f80..e3983ded3c3c 100644 --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -8,7 +8,7 @@ */ / { - smb@8000000 { + bus@8000000 { mb_clk24mhz: clk24mhz { compatible = "fixed-clock"; #clock-cells = <0>; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index 6e685d883303..c5d15cbd8cf6 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts @@ -132,7 +132,7 @@ }; }; - smb@8000000 { + bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi index 57b0b9d7f3fa..60703b5763c6 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi @@ -5,7 +5,7 @@ * "rs2" extension for the v2m motherboard */ / { - smb@8000000 { + bus@8000000 { motherboard { arm,v2m-memory-map = "rs2"; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 03a7bf079c8f..e333c8d2d0e4 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -8,7 +8,7 @@ * VEMotherBoard.lisa */ / { - smb@8000000 { + bus@8000000 { motherboard { arm,v2m-memory-map = "rs1"; compatible = "arm,vexpress,v2m-p1", "simple-bus"; diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts index 22383c26bb03..d859914500a7 100644 --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts @@ -144,7 +144,7 @@ }; }; - smb: smb@8000000 { + smb: bus@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index bac293e6ee33..a39f0a1723e0 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -4,6 +4,11 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-qds.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-kbox-a-230-ls.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb @@ -26,6 +31,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts new file mode 100644 index 000000000000..4b4cc6a1573d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree File for the Kontron KBox A-230-LS. + * + * This consists of a Kontron SMARC-sAL28 (Dual PHY) and a special + * carrier (s1914). + * + * Copyright (C) 2019 Michael Walle <michael@walle.cc> + * + */ + +/dts-v1/; +#include "fsl-ls1028a-kontron-sl28-var4.dts" + +/ { + model = "Kontron KBox A-230-LS"; + compatible = "kontron,kbox-a-230-ls", "kontron,sl28-var4", + "kontron,sl28", "fsl,ls1028a"; +}; + +&enetc_mdio_pf3 { + /* BCM54140 QSGMII quad PHY */ + qsgmii_phy0: ethernet-phy@7 { + reg = <7>; + }; + + qsgmii_phy1: ethernet-phy@8 { + reg = <8>; + }; + + qsgmii_phy2: ethernet-phy@9 { + reg = <9>; + }; + + qsgmii_phy3: ethernet-phy@10 { + reg = <10>; + }; +}; + +&enetc_port2 { + status = "okay"; +}; + +&i2c3 { + eeprom@57 { + compatible = "atmel,24c32"; + reg = <0x57>; + pagesize = <32>; + }; +}; + +&mscc_felix { + status = "okay"; +}; + +&mscc_felix_port0 { + label = "swp0"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy0>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port1 { + label = "swp1"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy1>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port2 { + label = "swp2"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy2>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port3 { + label = "swp3"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy3>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port4 { + ethernet = <&enetc_port2>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts new file mode 100644 index 000000000000..901b5b161def --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree file for the Kontron SMARC-sAL28 board. + * + * This is for the network variant 2 which has two ethernet ports. These + * ports are connected to the internal switch. + * + * Copyright (C) 2020 Michael Walle <michael@walle.cc> + * + */ + +/dts-v1/; +#include "fsl-ls1028a-kontron-sl28.dts" + +/ { + model = "Kontron SMARC-sAL28 (TSN-on-module)"; + compatible = "kontron,sl28-var2", "kontron,sl28", "fsl,ls1028a"; +}; + +&enetc_mdio_pf3 { + phy0: ethernet-phy@5 { + reg = <0x5>; + eee-broken-1000t; + eee-broken-100tx; + }; + + phy1: ethernet-phy@4 { + reg = <0x4>; + eee-broken-1000t; + eee-broken-100tx; + }; +}; + +&enetc_port0 { + status = "disabled"; + /* + * In the base device tree the PHY was registered in the mdio + * subnode as it is PHY for this port. On this module this PHY + * is connected to a switch port instead and registered above. + * Therefore, delete the mdio subnode as well as the phy-handle + * property here. + */ + /delete-property/ phy-handle; + /delete-node/ mdio; +}; + +&enetc_port2 { + status = "okay"; +}; + +&mscc_felix { + status = "okay"; +}; + +&mscc_felix_port0 { + label = "gbe0"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + status = "okay"; +}; + +&mscc_felix_port1 { + label = "gbe1"; + phy-handle = <&phy1>; + phy-mode = "sgmii"; + status = "okay"; +}; + +&mscc_felix_port4 { + ethernet = <&enetc_port2>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts new file mode 100644 index 000000000000..0973a6a45217 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree file for the Kontron SMARC-sAL28 board on a SMARC Eval 2.0 + * carrier (ADS2). + * + * Copyright (C) 2019 Michael Walle <michael@walle.cc> + * + */ + +/dts-v1/; +#include "fsl-ls1028a-kontron-sl28.dts" + +/ { + model = "Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier"; + compatible = "kontron,sl28-var3-ads2", "kontron,sl28-var3", + "kontron,sl28", "fsl,ls1028a"; + + sound { + #address-cells = <1>; + #size-cells = <0>; + compatible = "simple-audio-card"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Out Jack", + "Microphone", "Microphone Jack", + "Line", "Line In Jack"; + simple-audio-card,routing = + "Line Out Jack", "LINEOUTR", + "Line Out Jack", "LINEOUTL", + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "IN1L", "Line In Jack", + "IN1R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN2L", "Microphone Jack", + "IN2R", "Microphone Jack"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,dai-link@0 { + reg = <0>; + bitclock-master = <&dailink0_master>; + frame-master = <&dailink0_master>; + format = "i2s"; + + cpu { + sound-dai = <&sai6>; + }; + + dailink0_master: codec { + sound-dai = <&wm8904>; + }; + }; + + simple-audio-card,dai-link@1 { + reg = <1>; + bitclock-master = <&dailink1_master>; + frame-master = <&dailink1_master>; + format = "i2s"; + + cpu { + sound-dai = <&sai5>; + }; + + dailink1_master: codec { + sound-dai = <&wm8904>; + }; + }; + }; +}; + +&dspi2 { + flash@0 { + compatible = "jedec,spi-nor"; + m25p,fast-read; + spi-max-frequency = <100000000>; + reg = <0>; + }; +}; + +&i2c3 { + eeprom@57 { + compatible = "atmel,24c64"; + reg = <0x57>; + pagesize = <32>; + }; +}; + +&i2c4 { + status = "okay"; + + wm8904: audio-codec@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&mclk>; + clock-names = "mclk"; + assigned-clocks = <&mclk>; + assigned-clock-rates = <1250000>; + }; +}; + +&sai5 { + status = "okay"; +}; + +&sai6 { + status = "okay"; +}; + +&soc { + mclk: clock-mclk@f130080 { + compatible = "fsl,vf610-sai-clock"; + reg = <0x0 0xf130080 0x0 0x80>; + clocks = <&clockgen 4 1>; + #clock-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts new file mode 100644 index 000000000000..df212ed5bb94 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree file for the Kontron SMARC-sAL28 board. + * + * This is for the network variant 4 which has two ethernet ports. It + * extends the base and provides one more port connected via RGMII. + * + * Copyright (C) 2019 Michael Walle <michael@walle.cc> + * + */ + +/dts-v1/; +#include "fsl-ls1028a-kontron-sl28.dts" +#include <dt-bindings/net/qca-ar803x.h> + +/ { + model = "Kontron SMARC-sAL28 (Dual PHY)"; + compatible = "kontron,sl28-var4", "kontron,sl28", "fsl,ls1028a"; +}; + +&enetc_port1 { + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy1: ethernet-phy@4 { + reg = <0x4>; + eee-broken-1000t; + eee-broken-100tx; + + qca,clk-out-frequency = <125000000>; + qca,clk-out-strength = <AR803X_STRENGTH_FULL>; + + vddio-supply = <&vddh>; + + vddio: vddio-regulator { + regulator-name = "VDDIO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vddh: vddh-regulator { + regulator-name = "VDDH"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts new file mode 100644 index 000000000000..1648a04ea79f --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree file for the Kontron SMARC-sAL28 board. + * + * Copyright (C) 2019 Michael Walle <michael@walle.cc> + * + */ + +/dts-v1/; +#include "fsl-ls1028a.dtsi" + +/ { + model = "Kontron SMARC-sAL28"; + compatible = "kontron,sl28", "fsl,ls1028a"; + + aliases { + crypto = &crypto; + serial0 = &duart0; + serial1 = &duart1; + spi0 = &fspi; + spi1 = &dspi2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&dspi2 { + status = "okay"; +}; + +&duart0 { + status = "okay"; +}; + +&duart1 { + status = "okay"; +}; + +&enetc_port0 { + phy-handle = <&phy0>; + phy-connection-type = "sgmii"; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@5 { + reg = <0x5>; + eee-broken-1000t; + eee-broken-100tx; + }; + }; +}; + +&esdhc { + sd-uhs-sdr104; + sd-uhs-sdr50; + sd-uhs-sdr25; + sd-uhs-sdr12; + status = "okay"; +}; + +&esdhc1 { + mmc-hs200-1_8v; + mmc-hs400-1_8v; + bus-width = <8>; + status = "okay"; +}; + +&fspi { + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + m25p,fast-read; + spi-max-frequency = <133000000>; + reg = <0>; + /* The following setting enables 1-1-2 (CMD-ADDR-DATA) mode */ + spi-rx-bus-width = <2>; /* 2 SPI Rx lines */ + spi-tx-bus-width = <1>; /* 1 SPI Tx line */ + + partition@0 { + reg = <0x000000 0x010000>; + label = "rcw"; + read-only; + }; + + partition@10000 { + reg = <0x010000 0x0f0000>; + label = "failsafe bootloader"; + read-only; + }; + + partition@100000 { + reg = <0x100000 0x040000>; + label = "failsafe DP firmware"; + read-only; + }; + + partition@140000 { + reg = <0x140000 0x0a0000>; + label = "failsafe trusted firmware"; + read-only; + }; + + partition@1e0000 { + reg = <0x1e0000 0x020000>; + label = "reserved"; + read-only; + }; + + partition@200000 { + reg = <0x200000 0x010000>; + label = "configuration store"; + }; + + partition@210000 { + reg = <0x210000 0x0f0000>; + label = "bootloader"; + }; + + partition@300000 { + reg = <0x300000 0x040000>; + label = "DP firmware"; + }; + + partition@340000 { + reg = <0x340000 0x0a0000>; + label = "trusted firmware"; + }; + + partition@3e0000 { + reg = <0x3e0000 0x020000>; + label = "bootloader environment"; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "TDO", "TCK", + "", "", "", "", "", "", "", ""; +}; + +&gpio2 { + gpio-line-names = + "", "", "", "", "", "", "TMS", "TDI", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&i2c0 { + status = "okay"; + + rtc@32 { + compatible = "microcrystal,rv8803"; + reg = <0x32>; + }; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts index ca409d907b36..dd69c5b821e9 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts @@ -225,6 +225,7 @@ &enetc_port1 { phy-handle = <&qds_phy1>; phy-connection-type = "rgmii-id"; + status = "okay"; }; &sai1 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts index afb55653850d..c2dc1232f93f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts @@ -177,9 +177,29 @@ status = "okay"; }; +&enetc_mdio_pf3 { + /* VSC8514 QSGMII quad PHY */ + qsgmii_phy0: ethernet-phy@10 { + reg = <0x10>; + }; + + qsgmii_phy1: ethernet-phy@11 { + reg = <0x11>; + }; + + qsgmii_phy2: ethernet-phy@12 { + reg = <0x12>; + }; + + qsgmii_phy3: ethernet-phy@13 { + reg = <0x13>; + }; +}; + &enetc_port0 { phy-handle = <&sgmii_phy0>; phy-connection-type = "sgmii"; + status = "okay"; mdio { #address-cells = <1>; @@ -190,8 +210,49 @@ }; }; -&enetc_port1 { - status = "disabled"; +&enetc_port2 { + status = "okay"; +}; + +&mscc_felix { + status = "okay"; +}; + +&mscc_felix_port0 { + label = "swp0"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy0>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port1 { + label = "swp1"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy1>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port2 { + label = "swp2"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy2>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port3 { + label = "swp3"; + managed = "in-band-status"; + phy-handle = <&qsgmii_phy3>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +&mscc_felix_port4 { + ethernet = <&enetc_port2>; + status = "okay"; }; &sai4 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index c28a25b145ae..2a7f70b71149 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -290,6 +290,45 @@ status = "disabled"; }; + dspi0: spi@2100000 { + compatible = "fsl,ls1028a-dspi", "fsl,ls1021a-v1.0-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x2100000 0x0 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dspi"; + clocks = <&clockgen 4 1>; + spi-num-chipselects = <4>; + little-endian; + status = "disabled"; + }; + + dspi1: spi@2110000 { + compatible = "fsl,ls1028a-dspi", "fsl,ls1021a-v1.0-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x2110000 0x0 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dspi"; + clocks = <&clockgen 4 1>; + spi-num-chipselects = <4>; + little-endian; + status = "disabled"; + }; + + dspi2: spi@2120000 { + compatible = "fsl,ls1028a-dspi", "fsl,ls1021a-v1.0-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x2120000 0x0 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dspi"; + clocks = <&clockgen 4 1>; + spi-num-chipselects = <3>; + little-endian; + status = "disabled"; + }; + esdhc: mmc@2140000 { compatible = "fsl,ls1028a-esdhc", "fsl,esdhc"; reg = <0x0 0x2140000 0x0 0x10000>; @@ -484,6 +523,60 @@ status = "disabled"; }; + pcie@3400000 { + compatible = "fsl,ls1028a-pcie"; + reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ + 0x80 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */ + interrupt-names = "pme", "aer"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + num-viewport = <8>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x80 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3500000 { + compatible = "fsl,ls1028a-pcie"; + reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ + 0x88 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "pme", "aer"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + num-viewport = <8>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x88 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + smmu: iommu@5000000 { compatible = "arm,mmu-500"; reg = <0 0x5000000 0 0x800000>; @@ -756,7 +849,6 @@ reg = <0x01 0xf0000000 0x0 0x100000>; #address-cells = <3>; #size-cells = <2>; - #interrupt-cells = <1>; msi-parent = <&its>; device_type = "pci"; bus-range = <0x0 0x0>; @@ -774,27 +866,115 @@ /* PF1: VF0-1 BAR0 - non-prefetchable memory */ 0x82000000 0x0 0x00000000 0x1 0xf8210000 0x0 0x020000 /* PF1: VF0-1 BAR2 - prefetchable memory */ - 0xc2000000 0x0 0x00000000 0x1 0xf8230000 0x0 0x020000>; + 0xc2000000 0x0 0x00000000 0x1 0xf8230000 0x0 0x020000 + /* BAR4 (PF5) - non-prefetchable memory */ + 0x82000000 0x0 0x00000000 0x1 0xfc000000 0x0 0x400000>; enetc_port0: ethernet@0,0 { compatible = "fsl,enetc"; reg = <0x000000 0 0 0 0>; + status = "disabled"; }; + enetc_port1: ethernet@0,1 { compatible = "fsl,enetc"; reg = <0x000100 0 0 0 0>; + status = "disabled"; + }; + + enetc_port2: ethernet@0,2 { + compatible = "fsl,enetc"; + reg = <0x000200 0 0 0 0>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; + enetc_mdio_pf3: mdio@0,3 { compatible = "fsl,enetc-mdio"; reg = <0x000300 0 0 0 0>; #address-cells = <1>; #size-cells = <0>; }; + ethernet@0,4 { compatible = "fsl,enetc-ptp"; reg = <0x000400 0 0 0 0>; clocks = <&clockgen 4 0>; little-endian; + fsl,extts-fifo; + }; + + mscc_felix: ethernet-switch@0,5 { + reg = <0x000500 0 0 0 0>; + /* IEP INT_B */ + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* External ports */ + mscc_felix_port0: port@0 { + reg = <0>; + status = "disabled"; + }; + + mscc_felix_port1: port@1 { + reg = <1>; + status = "disabled"; + }; + + mscc_felix_port2: port@2 { + reg = <2>; + status = "disabled"; + }; + + mscc_felix_port3: port@3 { + reg = <3>; + status = "disabled"; + }; + + /* Internal ports */ + mscc_felix_port4: port@4 { + reg = <4>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <2500>; + full-duplex; + }; + }; + + mscc_felix_port5: port@5 { + reg = <5>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + + enetc_port3: ethernet@0,6 { + compatible = "fsl,enetc"; + reg = <0x000600 0 0 0 0>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 4d77b345cebd..5633e59febc3 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -83,6 +83,7 @@ }; &esdhc { + mmc-hs200-1_8v; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 594566265e3d..36a799554620 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -393,6 +393,7 @@ reg = <0x0 0x2140000 0x0 0x10000>; interrupts = <0 28 0x4>; /* Level high type */ clock-frequency = <0>; + clocks = <&clockgen 2 1>; voltage-ranges = <1800 1800 3300 3300>; sdhci,auto-cmd12; little-endian; @@ -493,6 +494,7 @@ <0000 0 0 2 &gic 0 0 0 110 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 3 &gic 0 0 0 111 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 4 &gic 0 0 0 112 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; @@ -518,6 +520,7 @@ <0000 0 0 2 &gic 0 0 0 115 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 3 &gic 0 0 0 116 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 4 &gic 0 0 0 117 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; @@ -543,6 +546,7 @@ <0000 0 0 2 &gic 0 0 0 120 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 3 &gic 0 0 0 121 IRQ_TYPE_LEVEL_HIGH>, <0000 0 0 4 &gic 0 0 0 122 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index f96d06da96be..3944ef16ec60 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -648,6 +648,7 @@ <0000 0 0 2 &gic 0 0 0 110 4>, <0000 0 0 3 &gic 0 0 0 111 4>, <0000 0 0 4 &gic 0 0 0 112 4>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; @@ -669,6 +670,7 @@ <0000 0 0 2 &gic 0 0 0 115 4>, <0000 0 0 3 &gic 0 0 0 116 4>, <0000 0 0 4 &gic 0 0 0 117 4>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; @@ -690,6 +692,7 @@ <0000 0 0 2 &gic 0 0 0 120 4>, <0000 0 0 3 &gic 0 0 0 121 4>, <0000 0 0 4 &gic 0 0 0 122 4>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; @@ -711,6 +714,7 @@ <0000 0 0 2 &gic 0 0 0 125 4>, <0000 0 0 3 &gic 0 0 0 126 4>, <0000 0 0 4 &gic 0 0 0 127 4>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi index 071e21678f77..d87d16460875 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi @@ -59,6 +59,32 @@ #size-cells = <0>; reg = <0x77>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + eeprom@50 { + compatible = "atmel,24c512"; + reg = <0x50>; + }; + + eeprom@51 { + compatible = "atmel,spd"; + reg = <0x51>; + }; + + eeprom@53 { + compatible = "atmel,spd"; + reg = <0x53>; + }; + + eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; + }; + }; + i2c@1 { #address-cells = <1>; #size-cells = <0>; @@ -73,6 +99,17 @@ }; }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + regulator@5c { + compatible = "lltc,ltc3882"; + reg = <0x5c>; + }; + }; + i2c@3 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts index 1a5acf62f23c..3b88e1efe4db 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts @@ -43,6 +43,21 @@ status = "okay"; }; +&fspi { + status = "okay"; + + mt35xu512aba0: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + m25p,fast-read; + spi-max-frequency = <50000000>; + reg = <0>; + spi-rx-bus-width = <8>; + spi-tx-bus-width = <8>; + }; +}; + &i2c0 { status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts index 51615de102fe..22d0308eb13b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts @@ -84,7 +84,7 @@ mt35xu512aba0: flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80"; + compatible = "jedec,spi-nor"; m25p,fast-read; spi-max-frequency = <50000000>; reg = <0>; @@ -95,7 +95,7 @@ mt35xu512aba1: flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80"; + compatible = "jedec,spi-nor"; m25p,fast-read; spi-max-frequency = <50000000>; reg = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index e5ee5591e52b..ae1b113ab162 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -834,6 +834,174 @@ status = "disabled"; }; + pcie@3400000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ + 0x80 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <8>; + ppio-wins = <8>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3500000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ + 0x88 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <8>; + ppio-wins = <8>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3600000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ + 0x90 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <256>; + ppio-wins = <24>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3700000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ + 0x98 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <8>; + ppio-wins = <8>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3800000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03800000 0x0 0x00100000 /* controller registers */ + 0xa0 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <256>; + ppio-wins = <24>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + + pcie@3900000 { + compatible = "fsl,lx2160a-pcie"; + reg = <0x00 0x03900000 0x0 0x00100000 /* controller registers */ + 0xa8 0x00000000 0x0 0x00001000>; /* configuration space */ + reg-names = "csr_axi_slave", "config_axi_slave"; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */ + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */ + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "aer", "pme", "intr"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + apio-wins = <8>; + ppio-wins = <8>; + bus-range = <0x0 0xff>; + ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + msi-parent = <&its>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic 0 0 GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic 0 0 GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic 0 0 GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ + status = "disabled"; + }; + smmu: iommu@5000000 { compatible = "arm,mmu-500"; reg = <0 0x5000000 0 0x800000>; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts index 9e54747cf4e6..951e14a3de0e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts @@ -107,6 +107,8 @@ pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; phy-handle = <ðphy0>; + phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; + phy-reset-duration = <10>; fsl,magic-packet; status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi index 1e5e11592f7b..cc7152ecedd9 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -68,6 +68,7 @@ nvmem-cells = <&cpu_speed_grade>; nvmem-cell-names = "speed_grade"; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_1: cpu@1 { @@ -80,6 +81,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_2: cpu@2 { @@ -92,6 +94,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_3: cpu@3 { @@ -104,6 +107,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_L2: l2-cache0 { @@ -204,6 +208,38 @@ arm,no-tick-in-suspend; }; + thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tmu>; + trips { + cpu_alert0: trip0 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_crit0: trip1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + usbphynop1: usbphynop1 { compatible = "usb-nop-xceiv"; clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; @@ -227,7 +263,8 @@ ranges = <0x0 0x0 0x0 0x3e000000>; aips1: bus@30000000 { - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x301f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x30000000 0x30000000 0x400000>; @@ -363,6 +400,13 @@ gpio-ranges = <&iomuxc 0 119 30>; }; + tmu: tmu@30260000 { + compatible = "fsl,imx8mm-tmu"; + reg = <0x30260000 0x10000>; + clocks = <&clk IMX8MM_CLK_TMU_ROOT>; + #thermal-sensor-cells = <0>; + }; + wdog1: watchdog@30280000 { compatible = "fsl,imx8mm-wdt", "fsl,imx21-wdt"; reg = <0x30280000 0x10000>; @@ -455,6 +499,8 @@ compatible = "fsl,sec-v4.0-pwrkey"; regmap = <&snvs>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SNVS_ROOT>; + clock-names = "snvs-pwrkey"; linux,keycode = <KEY_POWER>; wakeup-source; status = "disabled"; @@ -496,7 +542,8 @@ }; aips2: bus@30400000 { - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x305f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x30400000 0x30400000 0x400000>; @@ -555,10 +602,12 @@ }; aips3: bus@30800000 { - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x309f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x30800000 0x30800000 0x400000>; + ranges = <0x30800000 0x30800000 0x400000>, + <0x8000000 0x8000000 0x10000000>; ecspi1: spi@30820000 { compatible = "fsl,imx8mm-ecspi", "fsl,imx51-ecspi"; @@ -760,6 +809,19 @@ status = "disabled"; }; + flexspi: spi@30bb0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nxp,imx8mm-fspi"; + reg = <0x30bb0000 0x10000>, <0x8000000 0x10000000>; + reg-names = "fspi_base", "fspi_mmap"; + interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_QSPI_ROOT>, + <&clk IMX8MM_CLK_QSPI_ROOT>; + clock-names = "fspi", "fspi_en"; + status = "disabled"; + }; + sdma1: dma-controller@30bd0000 { compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma"; reg = <0x30bd0000 0x10000>; @@ -800,7 +862,8 @@ }; aips4: bus@32c00000 { - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x32df0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x32c00000 0x32c00000 0x400000>; @@ -896,7 +959,6 @@ ddr-pmu@3d800000 { compatible = "fsl,imx8mm-ddr-pmu", "fsl,imx8m-ddr-pmu"; reg = <0x3d800000 0x400000>; - interrupt-parent = <&gic>; interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi index 0d2ec4a2c7f2..85fc0aa38c4f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi @@ -102,6 +102,20 @@ }; }; +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + pca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + &snvs_pwrkey { status = "okay"; }; @@ -202,6 +216,13 @@ >; }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MN_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MN_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { fsl,pins = < MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi index a44b5438e842..fa78f0163270 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -7,6 +7,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/thermal/thermal.h> #include "imx8mn-pinfunc.h" @@ -67,6 +68,7 @@ nvmem-cells = <&cpu_speed_grade>; nvmem-cell-names = "speed_grade"; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_1: cpu@1 { @@ -79,6 +81,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_2: cpu@2 { @@ -91,6 +94,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_3: cpu@3 { @@ -103,6 +107,7 @@ next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; cpu-idle-states = <&cpu_pd_wait>; + #cooling-cells = <2>; }; A53_L2: l2-cache0 { @@ -116,7 +121,7 @@ opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <850000>; + opp-microvolt = <950000>; opp-supported-hw = <0xb00>, <0x7>; clock-latency-ns = <150000>; opp-suspend; @@ -186,6 +191,38 @@ method = "smc"; }; + thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tmu>; + trips { + cpu_alert0: trip0 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_crit0: trip1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, @@ -203,8 +240,8 @@ ranges = <0x0 0x0 0x0 0x3e000000>; aips1: bus@30000000 { - compatible = "simple-bus"; - reg = <0x30000000 0x400000>; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x301f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -274,6 +311,13 @@ gpio-ranges = <&iomuxc 0 119 30>; }; + tmu: tmu@30260000 { + compatible = "fsl,imx8mn-tmu", "fsl,imx8mm-tmu"; + reg = <0x30260000 0x10000>; + clocks = <&clk IMX8MN_CLK_TMU_ROOT>; + #thermal-sensor-cells = <0>; + }; + wdog1: watchdog@30280000 { compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt"; reg = <0x30280000 0x10000>; @@ -358,6 +402,7 @@ offset = <0x34>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SNVS_ROOT>; clock-names = "snvs-rtc"; }; @@ -365,6 +410,8 @@ compatible = "fsl,sec-v4.0-pwrkey"; regmap = <&snvs>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SNVS_ROOT>; + clock-names = "snvs-pwrkey"; linux,keycode = <KEY_POWER>; wakeup-source; status = "disabled"; @@ -379,6 +426,16 @@ <&clk_ext3>, <&clk_ext4>; clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4"; + assigned-clocks = <&clk IMX8MN_CLK_NOC>, + <&clk IMX8MN_CLK_AUDIO_AHB>, + <&clk IMX8MN_CLK_IPG_AUDIO_ROOT>, + <&clk IMX8MN_SYS_PLL3>; + assigned-clock-parents = <&clk IMX8MN_SYS_PLL3_OUT>, + <&clk IMX8MN_SYS_PLL1_800M>; + assigned-clock-rates = <0>, + <400000000>, + <400000000>, + <600000000>; }; src: reset-controller@30390000 { @@ -390,8 +447,8 @@ }; aips2: bus@30400000 { - compatible = "simple-bus"; - reg = <0x30400000 0x400000>; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x305f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -450,8 +507,8 @@ }; aips3: bus@30800000 { - compatible = "simple-bus"; - reg = <0x30800000 0x400000>; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x309f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -543,19 +600,19 @@ <&clk IMX8MN_CLK_IPG_ROOT>; clock-names = "aclk", "ipg"; - sec_jr0: jr0@1000 { + sec_jr0: jr@1000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr1: jr1@2000 { + sec_jr1: jr@2000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; }; - sec_jr2: jr2@3000 { + sec_jr2: jr@3000 { compatible = "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; @@ -696,8 +753,8 @@ }; aips4: bus@32c00000 { - compatible = "simple-bus"; - reg = <0x32c00000 0x400000>; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x32df0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts new file mode 100644 index 000000000000..3da1fff3d6fd --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 NXP + */ + +/dts-v1/; + +#include "imx8mp.dtsi" + +/ { + model = "NXP i.MX8MPlus EVK board"; + compatible = "fsl,imx8mp-evk", "fsl,imx8mp"; + + chosen { + stdout-path = &uart2; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_led>; + + status { + label = "yellow:status"; + gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0xc0000000>, + <0x1 0x00000000 0 0xc0000000>; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy1>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + eee-broken-1000t; + reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + pca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&uart2 { + /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&usdhc2 { + assigned-clocks = <&clk IMX8MP_CLK_USDHC2>; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + bus-width = <4>; + status = "okay"; +}; + +&usdhc3 { + assigned-clocks = <&clk IMX8MP_CLK_USDHC3>; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 + MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 + MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 + MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 + MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 + MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 + MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 + MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f + MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f + MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f + MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f + MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f + MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f + MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x19 + >; + }; + + pinctrl_gpio_led: gpioledgrp { + fsl,pins = < + MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 + MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { + fsl,pins = < + MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x49 + MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x49 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp-100mhz { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp-200mhz { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grp-gpio { + fsl,pins = < + MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h new file mode 100644 index 000000000000..da78f89b6c98 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h @@ -0,0 +1,931 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 NXP + */ + +#ifndef __DTS_IMX8MP_PINFUNC_H +#define __DTS_IMX8MP_PINFUNC_H + +/* + * The pin function ID is a tuple of + * <mux_reg conf_reg input_reg mux_mode input_val> + */ +#define MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00 0x014 0x274 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT 0x014 0x274 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__MEDIAMIX_ISP_FL_TRIG_0 0x014 0x274 0x5D4 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__ANAMIX_REF_CLK_32K 0x014 0x274 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__CCMSRCGPCMIX_EXT_CLK1 0x014 0x274 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__SJC_FAIL 0x014 0x274 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01 0x018 0x278 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__PWM1_OUT 0x018 0x278 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__MEDIAMIX_ISP_SHUTTER_TRIG_0 0x018 0x278 0x5DC 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__ANAMIX_REF_CLK_24M 0x018 0x278 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__CCMSRCGPCMIX_EXT_CLK2 0x018 0x278 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__SJC_ACTIVE 0x018 0x278 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__GPIO1_IO02 0x01C 0x27C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x01C 0x27C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__MEDIAMIX_ISP_FLASH_TRIG_0 0x01C 0x27C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_ANY 0x01C 0x27C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__SJC_DE_B 0x01C 0x27C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x020 0x280 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__USDHC1_VSELECT 0x020 0x280 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__MEDIAMIX_ISP_PRELIGHT_TRIG_0 0x020 0x280 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__SDMA1_EXT_EVENT00 0x020 0x280 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__ANAMIX_XTAL_OK 0x020 0x280 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__SJC_DONE 0x020 0x280 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x024 0x284 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x024 0x284 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__MEDIAMIX_ISP_SHUTTER_OPEN_0 0x024 0x284 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__SDMA1_EXT_EVENT01 0x024 0x284 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__ANAMIX_XTAL_OK_LV 0x024 0x284 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__USDHC1_TEST_TRIG 0x024 0x284 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x028 0x288 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__M7_NMI 0x028 0x288 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__MEDIAMIX_ISP_FL_TRIG_1 0x028 0x288 0x5D8 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__CCMSRCGPCMIX_PMIC_READY 0x028 0x288 0x554 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__CCMSRCGPCMIX_INT_BOOT 0x028 0x288 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__USDHC2_TEST_TRIG 0x028 0x288 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x02C 0x28C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__ENET_QOS_MDC 0x02C 0x28C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__MEDIAMIX_ISP_SHUTTER_TRIG_1 0x02C 0x28C 0x5E0 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__USDHC1_CD_B 0x02C 0x28C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__CCMSRCGPCMIX_EXT_CLK3 0x02C 0x28C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__ECSPI1_TEST_TRIG 0x02C 0x28C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x030 0x290 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__ENET_QOS_MDIO 0x030 0x290 0x590 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__MEDIAMIX_ISP_FLASH_TRIG_1 0x030 0x290 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__USDHC1_WP 0x030 0x290 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__CCMSRCGPCMIX_EXT_CLK4 0x030 0x290 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__ECSPI2_TEST_TRIG 0x030 0x290 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__GPIO1_IO08 0x034 0x294 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__ENET_QOS_1588_EVENT0_IN 0x034 0x294 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__PWM1_OUT 0x034 0x294 0x000 0x2 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__MEDIAMIX_ISP_PRELIGHT_TRIG_1 0x034 0x294 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__ENET_QOS_1588_EVENT0_AUX_IN 0x034 0x294 0x000 0x4 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__USDHC2_RESET_B 0x034 0x294 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__CCMSRCGPCMIX_WAIT 0x034 0x294 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__FLEXSPI_TEST_TRIG 0x034 0x294 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__GPIO1_IO09 0x038 0x298 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__ENET_QOS_1588_EVENT0_OUT 0x038 0x298 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__PWM2_OUT 0x038 0x298 0x000 0x2 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__MEDIAMIX_ISP_SHUTTER_OPEN_1 0x038 0x298 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__USDHC3_RESET_B 0x038 0x298 0x000 0x4 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__AUDIOMIX_EXT_EVENT00 0x038 0x298 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__CCMSRCGPCMIX_STOP 0x038 0x298 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__RAWNAND_TEST_TRIG 0x038 0x298 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x03C 0x29C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO10__HSIOMIX_usb1_OTG_ID 0x03C 0x29C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO10__PWM3_OUT 0x03C 0x29C 0x000 0x2 0x0 +#define MX8MP_IOMUXC_GPIO1_IO10__OCOTP_FUSE_LATCHED 0x03C 0x29C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x040 0x2A0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__HSIOMIX_usb2_OTG_ID 0x040 0x2A0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__PWM2_OUT 0x040 0x2A0 0x000 0x2 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__USDHC3_VSELECT 0x040 0x2A0 0x000 0x4 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__CCMSRCGPCMIX_PMIC_READY 0x040 0x2A0 0x554 0x5 0x1 +#define MX8MP_IOMUXC_GPIO1_IO11__CCMSRCGPCMIX_OUT0 0x040 0x2A0 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__CAAM_RNG_OSC_OBS 0x040 0x2A0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x044 0x2A4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__HSIOMIX_usb1_OTG_PWR 0x044 0x2A4 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__AUDIOMIX_EXT_EVENT01 0x044 0x2A4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__CCMSRCGPCMIX_OUT1 0x044 0x2A4 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__CSU_CSU_ALARM_AUT00 0x044 0x2A4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x048 0x2A8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__HSIOMIX_usb1_OTG_OC 0x048 0x2A8 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__PWM2_OUT 0x048 0x2A8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__CCMSRCGPCMIX_OUT2 0x048 0x2A8 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__CSU_CSU_ALARM_AUT01 0x048 0x2A8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x04C 0x2AC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__HSIOMIX_usb2_OTG_PWR 0x04C 0x2AC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__USDHC3_CD_B 0x04C 0x2AC 0x608 0x4 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__PWM3_OUT 0x04C 0x2AC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__CCMSRCGPCMIX_CLKO1 0x04C 0x2AC 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__CSU_CSU_ALARM_AUT02 0x04C 0x2AC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x050 0x2B0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__HSIOMIX_usb2_OTG_OC 0x050 0x2B0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__USDHC3_WP 0x050 0x2B0 0x634 0x4 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT 0x050 0x2B0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__CCMSRCGPCMIX_CLKO2 0x050 0x2B0 0x000 0x6 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__CSU_CSU_INT_DEB 0x050 0x2B0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x054 0x2B4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_MDC__AUDIOMIX_SAI6_TX_DATA00 0x054 0x2B4 0x000 0x2 0x0 +#define MX8MP_IOMUXC_ENET_MDC__GPIO1_IO16 0x054 0x2B4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_MDC__USDHC3_STROBE 0x054 0x2B4 0x630 0x6 0x0 +#define MX8MP_IOMUXC_ENET_MDC__SIM_M_HADDR15 0x054 0x2B4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x058 0x2B8 0x590 0x0 0x1 +#define MX8MP_IOMUXC_ENET_MDIO__AUDIOMIX_SAI6_TX_SYNC 0x058 0x2B8 0x528 0x2 0x0 +#define MX8MP_IOMUXC_ENET_MDIO__GPIO1_IO17 0x058 0x2B8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_MDIO__USDHC3_DATA5 0x058 0x2B8 0x624 0x6 0x0 +#define MX8MP_IOMUXC_ENET_MDIO__SIM_M_HADDR16 0x058 0x2B8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x05C 0x2BC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TD3__AUDIOMIX_SAI6_TX_BCLK 0x05C 0x2BC 0x524 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD3__GPIO1_IO18 0x05C 0x2BC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TD3__USDHC3_DATA6 0x05C 0x2BC 0x628 0x6 0x0 +#define MX8MP_IOMUXC_ENET_TD3__SIM_M_HADDR17 0x05C 0x2BC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x060 0x2C0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TD2__CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x060 0x2C0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ENET_TD2__AUDIOMIX_SAI6_RX_DATA00 0x060 0x2C0 0x51C 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD2__GPIO1_IO19 0x060 0x2C0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TD2__USDHC3_DATA7 0x060 0x2C0 0x62C 0x6 0x0 +#define MX8MP_IOMUXC_ENET_TD2__SIM_M_HADDR18 0x060 0x2C0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x064 0x2C4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TD1__AUDIOMIX_SAI6_RX_SYNC 0x064 0x2C4 0x520 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD1__GPIO1_IO20 0x064 0x2C4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TD1__USDHC3_CD_B 0x064 0x2C4 0x608 0x6 0x1 +#define MX8MP_IOMUXC_ENET_TD1__SIM_M_HADDR19 0x064 0x2C4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x068 0x2C8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TD0__AUDIOMIX_SAI6_RX_BCLK 0x068 0x2C8 0x518 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD0__GPIO1_IO21 0x068 0x2C8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TD0__USDHC3_WP 0x068 0x2C8 0x634 0x6 0x1 +#define MX8MP_IOMUXC_ENET_TD0__SIM_M_HADDR20 0x068 0x2C8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x06C 0x2CC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__AUDIOMIX_SAI6_MCLK 0x06C 0x2CC 0x514 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__AUDIOMIX_SPDIF_OUT 0x06C 0x2CC 0x000 0x3 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__GPIO1_IO22 0x06C 0x2CC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__USDHC3_DATA0 0x06C 0x2CC 0x610 0x6 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__SIM_M_HADDR21 0x06C 0x2CC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x070 0x2D0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_TXC__ENET_QOS_TX_ER 0x070 0x2D0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ENET_TXC__AUDIOMIX_SAI7_TX_DATA00 0x070 0x2D0 0x000 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TXC__GPIO1_IO23 0x070 0x2D0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_TXC__USDHC3_DATA1 0x070 0x2D0 0x614 0x6 0x0 +#define MX8MP_IOMUXC_ENET_TXC__SIM_M_HADDR22 0x070 0x2D0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x074 0x2D4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_SAI7_TX_SYNC 0x074 0x2D4 0x540 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_BIT_STREAM03 0x074 0x2D4 0x4CC 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__GPIO1_IO24 0x074 0x2D4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__USDHC3_DATA2 0x074 0x2D4 0x618 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RX_CTL__SIM_M_HADDR23 0x074 0x2D4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x078 0x2D8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RXC__ENET_QOS_RX_ER 0x078 0x2D8 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_SAI7_TX_BCLK 0x078 0x2D8 0x53C 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_BIT_STREAM02 0x078 0x2D8 0x4C8 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RXC__GPIO1_IO25 0x078 0x2D8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RXC__USDHC3_DATA3 0x078 0x2D8 0x61C 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RXC__SIM_M_HADDR24 0x078 0x2D8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x07C 0x2DC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_SAI7_RX_DATA00 0x07C 0x2DC 0x534 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_BIT_STREAM01 0x07C 0x2DC 0x4C4 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD0__GPIO1_IO26 0x07C 0x2DC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RD0__USDHC3_DATA4 0x07C 0x2DC 0x620 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RD0__SIM_M_HADDR25 0x07C 0x2DC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x080 0x2E0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_SAI7_RX_SYNC 0x080 0x2E0 0x538 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_BIT_STREAM00 0x080 0x2E0 0x4C0 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD1__GPIO1_IO27 0x080 0x2E0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RD1__USDHC3_RESET_B 0x080 0x2E0 0x000 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RD1__SIM_M_HADDR26 0x080 0x2E0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x084 0x2E4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RD2__AUDIOMIX_SAI7_RX_BCLK 0x084 0x2E4 0x530 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RD2__AUDIOMIX_CLK 0x084 0x2E4 0x000 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD2__GPIO1_IO28 0x084 0x2E4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RD2__USDHC3_CLK 0x084 0x2E4 0x604 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RD2__SIM_M_HADDR27 0x084 0x2E4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x088 0x2E8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_ENET_RD3__AUDIOMIX_SAI7_MCLK 0x088 0x2E8 0x52C 0x2 0x0 +#define MX8MP_IOMUXC_ENET_RD3__AUDIOMIX_SPDIF_IN 0x088 0x2E8 0x544 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD3__GPIO1_IO29 0x088 0x2E8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ENET_RD3__USDHC3_CMD 0x088 0x2E8 0x60C 0x6 0x0 +#define MX8MP_IOMUXC_ENET_RD3__SIM_M_HADDR28 0x088 0x2E8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x08C 0x2EC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_CLK__ENET1_MDC 0x08C 0x2EC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SD1_CLK__I2C5_SCL 0x08C 0x2EC 0x5C4 0x3 0x0 +#define MX8MP_IOMUXC_SD1_CLK__UART1_DCE_TX 0x08C 0x2EC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_CLK__UART1_DTE_RX 0x08C 0x2EC 0x5E8 0x4 0x0 +#define MX8MP_IOMUXC_SD1_CLK__GPIO2_IO00 0x08C 0x2EC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_CLK__SIM_M_HADDR29 0x08C 0x2EC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x090 0x2F0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_CMD__ENET1_MDIO 0x090 0x2F0 0x57C 0x1 0x0 +#define MX8MP_IOMUXC_SD1_CMD__I2C5_SDA 0x090 0x2F0 0x5C8 0x3 0x0 +#define MX8MP_IOMUXC_SD1_CMD__UART1_DCE_RX 0x090 0x2F0 0x5E8 0x4 0x1 +#define MX8MP_IOMUXC_SD1_CMD__UART1_DTE_TX 0x090 0x2F0 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_CMD__GPIO2_IO01 0x090 0x2F0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_CMD__SIM_M_HADDR30 0x090 0x2F0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x094 0x2F4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__ENET1_RGMII_TD1 0x094 0x2F4 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__I2C6_SCL 0x094 0x2F4 0x5CC 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__UART1_DCE_RTS 0x094 0x2F4 0x5E4 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__UART1_DTE_CTS 0x094 0x2F4 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__GPIO2_IO02 0x094 0x2F4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA0__SIM_M_HADDR31 0x094 0x2F4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x098 0x2F8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__ENET1_RGMII_TD0 0x098 0x2F8 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__I2C6_SDA 0x098 0x2F8 0x5D0 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__UART1_DCE_CTS 0x098 0x2F8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__UART1_DTE_RTS 0x098 0x2F8 0x5E4 0x4 0x1 +#define MX8MP_IOMUXC_SD1_DATA1__GPIO2_IO03 0x098 0x2F8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA1__SIM_M_HBURST00 0x098 0x2F8 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x09C 0x2FC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__ENET1_RGMII_RD0 0x09C 0x2FC 0x580 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__I2C4_SCL 0x09C 0x2FC 0x5BC 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__UART2_DCE_TX 0x09C 0x2FC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__UART2_DTE_RX 0x09C 0x2FC 0x5F0 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__GPIO2_IO04 0x09C 0x2FC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA2__SIM_M_HBURST01 0x09C 0x2FC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x0A0 0x300 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__ENET1_RGMII_RD1 0x0A0 0x300 0x584 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__I2C4_SDA 0x0A0 0x300 0x5C0 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__UART2_DCE_RX 0x0A0 0x300 0x5F0 0x4 0x1 +#define MX8MP_IOMUXC_SD1_DATA3__UART2_DTE_TX 0x0A0 0x300 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__GPIO2_IO05 0x0A0 0x300 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA3__SIM_M_HBURST02 0x0A0 0x300 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__USDHC1_DATA4 0x0A4 0x304 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__ENET1_RGMII_TX_CTL 0x0A4 0x304 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__I2C1_SCL 0x0A4 0x304 0x5A4 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__UART2_DCE_RTS 0x0A4 0x304 0x5EC 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__UART2_DTE_CTS 0x0A4 0x304 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x0A4 0x304 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA4__SIM_M_HRESP 0x0A4 0x304 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__USDHC1_DATA5 0x0A8 0x308 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__ENET1_TX_ER 0x0A8 0x308 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__I2C1_SDA 0x0A8 0x308 0x5A8 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__UART2_DCE_CTS 0x0A8 0x308 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__UART2_DTE_RTS 0x0A8 0x308 0x5EC 0x4 0x1 +#define MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x0A8 0x308 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA5__TPSMP_HDATA05 0x0A8 0x308 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__USDHC1_DATA6 0x0AC 0x30C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__ENET1_RGMII_RX_CTL 0x0AC 0x30C 0x588 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__I2C2_SCL 0x0AC 0x30C 0x5AC 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__UART3_DCE_TX 0x0AC 0x30C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__UART3_DTE_RX 0x0AC 0x30C 0x5F8 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x0AC 0x30C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA6__TPSMP_HDATA06 0x0AC 0x30C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__USDHC1_DATA7 0x0B0 0x310 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__ENET1_RX_ER 0x0B0 0x310 0x58C 0x1 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__I2C2_SDA 0x0B0 0x310 0x5B0 0x3 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__UART3_DCE_RX 0x0B0 0x310 0x5F8 0x4 0x1 +#define MX8MP_IOMUXC_SD1_DATA7__UART3_DTE_TX 0x0B0 0x310 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0x0B0 0x310 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_DATA7__TPSMP_HDATA07 0x0B0 0x310 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__USDHC1_RESET_B 0x0B4 0x314 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__ENET1_TX_CLK 0x0B4 0x314 0x578 0x1 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__I2C3_SCL 0x0B4 0x314 0x5B4 0x3 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__UART3_DCE_RTS 0x0B4 0x314 0x5F4 0x4 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__UART3_DTE_CTS 0x0B4 0x314 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x0B4 0x314 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_RESET_B__ECSPI3_TEST_TRIG 0x0B4 0x314 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD1_STROBE__USDHC1_STROBE 0x0B8 0x318 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD1_STROBE__I2C3_SDA 0x0B8 0x318 0x5B8 0x3 0x0 +#define MX8MP_IOMUXC_SD1_STROBE__UART3_DCE_CTS 0x0B8 0x318 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD1_STROBE__UART3_DTE_RTS 0x0B8 0x318 0x5F4 0x4 0x1 +#define MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x0B8 0x318 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD1_STROBE__USDHC3_TEST_TRIG 0x0B8 0x318 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_CD_B__USDHC2_CD_B 0x0BC 0x31C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x0BC 0x31C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_CD_B__CCMSRCGPCMIX_TESTER_ACK 0x0BC 0x31C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x0C0 0x320 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_CLK__ECSPI2_SCLK 0x0C0 0x320 0x568 0x2 0x0 +#define MX8MP_IOMUXC_SD2_CLK__UART4_DCE_RX 0x0C0 0x320 0x600 0x3 0x0 +#define MX8MP_IOMUXC_SD2_CLK__UART4_DTE_TX 0x0C0 0x320 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_CLK__GPIO2_IO13 0x0C0 0x320 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_CLK__CCMSRCGPCMIX_OBSERVE0 0x0C0 0x320 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_CLK__OBSERVE_MUX_OUT00 0x0C0 0x320 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x0C4 0x324 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_CMD__ECSPI2_MOSI 0x0C4 0x324 0x570 0x2 0x0 +#define MX8MP_IOMUXC_SD2_CMD__UART4_DCE_TX 0x0C4 0x324 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_CMD__UART4_DTE_RX 0x0C4 0x324 0x600 0x3 0x1 +#define MX8MP_IOMUXC_SD2_CMD__AUDIOMIX_CLK 0x0C4 0x324 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD2_CMD__GPIO2_IO14 0x0C4 0x324 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_CMD__CCMSRCGPCMIX_OBSERVE1 0x0C4 0x324 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_CMD__OBSERVE_MUX_OUT01 0x0C4 0x324 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x0C8 0x328 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_DATA0__I2C4_SDA 0x0C8 0x328 0x5C0 0x2 0x1 +#define MX8MP_IOMUXC_SD2_DATA0__UART2_DCE_RX 0x0C8 0x328 0x5F0 0x3 0x2 +#define MX8MP_IOMUXC_SD2_DATA0__UART2_DTE_TX 0x0C8 0x328 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_DATA0__AUDIOMIX_BIT_STREAM00 0x0C8 0x328 0x4C0 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA0__GPIO2_IO15 0x0C8 0x328 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_DATA0__CCMSRCGPCMIX_OBSERVE2 0x0C8 0x328 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_DATA0__OBSERVE_MUX_OUT02 0x0C8 0x328 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x0CC 0x32C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_DATA1__I2C4_SCL 0x0CC 0x32C 0x5BC 0x2 0x1 +#define MX8MP_IOMUXC_SD2_DATA1__UART2_DCE_TX 0x0CC 0x32C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_DATA1__UART2_DTE_RX 0x0CC 0x32C 0x5F0 0x3 0x3 +#define MX8MP_IOMUXC_SD2_DATA1__AUDIOMIX_BIT_STREAM01 0x0CC 0x32C 0x4C4 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16 0x0CC 0x32C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_DATA1__CCMSRCGPCMIX_WAIT 0x0CC 0x32C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_DATA1__OBSERVE_MUX_OUT03 0x0CC 0x32C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x0D0 0x330 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__ECSPI2_SS0 0x0D0 0x330 0x574 0x2 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_SPDIF_OUT 0x0D0 0x330 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_BIT_STREAM02 0x0D0 0x330 0x4C8 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17 0x0D0 0x330 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__CCMSRCGPCMIX_STOP 0x0D0 0x330 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__OBSERVE_MUX_OUT04 0x0D0 0x330 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x0D4 0x334 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_DATA3__ECSPI2_MISO 0x0D4 0x334 0x56C 0x2 0x0 +#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_SPDIF_IN 0x0D4 0x334 0x544 0x3 0x1 +#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_BIT_STREAM03 0x0D4 0x334 0x4CC 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x0D4 0x334 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_DATA3__CCMSRCGPCMIX_EARLY_RESET 0x0D4 0x334 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_RESET_B__USDHC2_RESET_B 0x0D8 0x338 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x0D8 0x338 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_RESET_B__CCMSRCGPCMIX_SYSTEM_RESET 0x0D8 0x338 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_WP__USDHC2_WP 0x0DC 0x33C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SD2_WP__GPIO2_IO20 0x0DC 0x33C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SD2_WP__CORESIGHT_EVENTI 0x0DC 0x33C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_WP__SIM_M_HMASTLOCK 0x0DC 0x33C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_ALE__RAWNAND_ALE 0x0E0 0x340 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x0E0 0x340 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_ALE__AUDIOMIX_SAI3_TX_BCLK 0x0E0 0x340 0x4E8 0x2 0x0 +#define MX8MP_IOMUXC_NAND_ALE__MEDIAMIX_ISP_FL_TRIG_0 0x0E0 0x340 0x5D4 0x3 0x1 +#define MX8MP_IOMUXC_NAND_ALE__UART3_DCE_RX 0x0E0 0x340 0x5F8 0x4 0x2 +#define MX8MP_IOMUXC_NAND_ALE__UART3_DTE_TX 0x0E0 0x340 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x0E0 0x340 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_ALE__CORESIGHT_TRACE_CLK 0x0E0 0x340 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_ALE__SIM_M_HPROT00 0x0E0 0x340 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__RAWNAND_CE0_B 0x0E4 0x344 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x0E4 0x344 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__AUDIOMIX_SAI3_TX_DATA00 0x0E4 0x344 0x000 0x2 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__MEDIAMIX_ISP_SHUTTER_TRIG_0 0x0E4 0x344 0x5DC 0x3 0x1 +#define MX8MP_IOMUXC_NAND_CE0_B__UART3_DCE_TX 0x0E4 0x344 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__UART3_DTE_RX 0x0E4 0x344 0x5F8 0x4 0x3 +#define MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01 0x0E4 0x344 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__CORESIGHT_TRACE_CTL 0x0E4 0x344 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__SIM_M_HPROT01 0x0E4 0x344 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__RAWNAND_CE1_B 0x0E8 0x348 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__FLEXSPI_A_SS1_B 0x0E8 0x348 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x0E8 0x348 0x630 0x2 0x1 +#define MX8MP_IOMUXC_NAND_CE1_B__I2C4_SCL 0x0E8 0x348 0x5BC 0x4 0x2 +#define MX8MP_IOMUXC_NAND_CE1_B__GPIO3_IO02 0x0E8 0x348 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__CORESIGHT_TRACE00 0x0E8 0x348 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__SIM_M_HPROT02 0x0E8 0x348 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__RAWNAND_CE2_B 0x0EC 0x34C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__FLEXSPI_B_SS0_B 0x0EC 0x34C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x0EC 0x34C 0x624 0x2 0x1 +#define MX8MP_IOMUXC_NAND_CE2_B__I2C4_SDA 0x0EC 0x34C 0x5C0 0x4 0x2 +#define MX8MP_IOMUXC_NAND_CE2_B__GPIO3_IO03 0x0EC 0x34C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__CORESIGHT_TRACE01 0x0EC 0x34C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__SIM_M_HPROT03 0x0EC 0x34C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__RAWNAND_CE3_B 0x0F0 0x350 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__FLEXSPI_B_SS1_B 0x0F0 0x350 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x0F0 0x350 0x628 0x2 0x1 +#define MX8MP_IOMUXC_NAND_CE3_B__I2C3_SDA 0x0F0 0x350 0x5B8 0x4 0x1 +#define MX8MP_IOMUXC_NAND_CE3_B__GPIO3_IO04 0x0F0 0x350 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__CORESIGHT_TRACE02 0x0F0 0x350 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__SIM_M_HADDR00 0x0F0 0x350 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_CLE__RAWNAND_CLE 0x0F4 0x354 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CLE__FLEXSPI_B_SCLK 0x0F4 0x354 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x0F4 0x354 0x62C 0x2 0x1 +#define MX8MP_IOMUXC_NAND_CLE__UART4_DCE_RX 0x0F4 0x354 0x600 0x4 0x2 +#define MX8MP_IOMUXC_NAND_CLE__UART4_DTE_TX 0x0F4 0x354 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_CLE__GPIO3_IO05 0x0F4 0x354 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_CLE__CORESIGHT_TRACE03 0x0F4 0x354 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_CLE__SIM_M_HADDR01 0x0F4 0x354 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__RAWNAND_DATA00 0x0F8 0x358 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x0F8 0x358 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__AUDIOMIX_SAI3_RX_DATA00 0x0F8 0x358 0x4E4 0x2 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__MEDIAMIX_ISP_FLASH_TRIG_0 0x0F8 0x358 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__UART4_DCE_RX 0x0F8 0x358 0x600 0x4 0x3 +#define MX8MP_IOMUXC_NAND_DATA00__UART4_DTE_TX 0x0F8 0x358 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__GPIO3_IO06 0x0F8 0x358 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__CORESIGHT_TRACE04 0x0F8 0x358 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__SIM_M_HADDR02 0x0F8 0x358 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__RAWNAND_DATA01 0x0FC 0x35C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x0FC 0x35C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__AUDIOMIX_SAI3_TX_SYNC 0x0FC 0x35C 0x4EC 0x2 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__MEDIAMIX_ISP_PRELIGHT_TRIG_0 0x0FC 0x35C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__UART4_DCE_TX 0x0FC 0x35C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__UART4_DTE_RX 0x0FC 0x35C 0x600 0x4 0x4 +#define MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x0FC 0x35C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__CORESIGHT_TRACE05 0x0FC 0x35C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__SIM_M_HADDR03 0x0FC 0x35C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__RAWNAND_DATA02 0x100 0x360 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x100 0x360 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__USDHC3_CD_B 0x100 0x360 0x608 0x2 0x2 +#define MX8MP_IOMUXC_NAND_DATA02__UART4_DCE_CTS 0x100 0x360 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__UART4_DTE_RTS 0x100 0x360 0x5FC 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__I2C4_SDA 0x100 0x360 0x5C0 0x4 0x3 +#define MX8MP_IOMUXC_NAND_DATA02__GPIO3_IO08 0x100 0x360 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__CORESIGHT_TRACE06 0x100 0x360 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__SIM_M_HADDR04 0x100 0x360 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__RAWNAND_DATA03 0x104 0x364 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x104 0x364 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__USDHC3_WP 0x104 0x364 0x634 0x2 0x2 +#define MX8MP_IOMUXC_NAND_DATA03__UART4_DCE_RTS 0x104 0x364 0x5FC 0x3 0x1 +#define MX8MP_IOMUXC_NAND_DATA03__UART4_DTE_CTS 0x104 0x364 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__MEDIAMIX_ISP_FL_TRIG_1 0x104 0x364 0x5D8 0x4 0x1 +#define MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x104 0x364 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__CORESIGHT_TRACE07 0x104 0x364 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__SIM_M_HADDR05 0x104 0x364 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__RAWNAND_DATA04 0x108 0x368 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__FLEXSPI_B_DATA00 0x108 0x368 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x108 0x368 0x610 0x2 0x1 +#define MX8MP_IOMUXC_NAND_DATA04__FLEXSPI_A_DATA04 0x108 0x368 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__MEDIAMIX_ISP_SHUTTER_TRIG_1 0x108 0x368 0x5E0 0x4 0x1 +#define MX8MP_IOMUXC_NAND_DATA04__GPIO3_IO10 0x108 0x368 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__CORESIGHT_TRACE08 0x108 0x368 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__SIM_M_HADDR06 0x108 0x368 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__RAWNAND_DATA05 0x10C 0x36C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__FLEXSPI_B_DATA01 0x10C 0x36C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x10C 0x36C 0x614 0x2 0x1 +#define MX8MP_IOMUXC_NAND_DATA05__FLEXSPI_A_DATA05 0x10C 0x36C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__MEDIAMIX_ISP_FLASH_TRIG_1 0x10C 0x36C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__GPIO3_IO11 0x10C 0x36C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__CORESIGHT_TRACE09 0x10C 0x36C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__SIM_M_HADDR07 0x10C 0x36C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__RAWNAND_DATA06 0x110 0x370 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__FLEXSPI_B_DATA02 0x110 0x370 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x110 0x370 0x618 0x2 0x1 +#define MX8MP_IOMUXC_NAND_DATA06__FLEXSPI_A_DATA06 0x110 0x370 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__MEDIAMIX_ISP_PRELIGHT_TRIG_1 0x110 0x370 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__GPIO3_IO12 0x110 0x370 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__CORESIGHT_TRACE10 0x110 0x370 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__SIM_M_HADDR08 0x110 0x370 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__RAWNAND_DATA07 0x114 0x374 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__FLEXSPI_B_DATA03 0x114 0x374 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x114 0x374 0x61C 0x2 0x1 +#define MX8MP_IOMUXC_NAND_DATA07__FLEXSPI_A_DATA07 0x114 0x374 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__MEDIAMIX_ISP_SHUTTER_OPEN_1 0x114 0x374 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__GPIO3_IO13 0x114 0x374 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__CORESIGHT_TRACE11 0x114 0x374 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__SIM_M_HADDR09 0x114 0x374 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_DQS__RAWNAND_DQS 0x118 0x378 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DQS__FLEXSPI_A_DQS 0x118 0x378 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_DQS__AUDIOMIX_SAI3_MCLK 0x118 0x378 0x4E0 0x2 0x0 +#define MX8MP_IOMUXC_NAND_DQS__MEDIAMIX_ISP_SHUTTER_OPEN_0 0x118 0x378 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DQS__I2C3_SCL 0x118 0x378 0x5B4 0x4 0x1 +#define MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x118 0x378 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_DQS__CORESIGHT_TRACE12 0x118 0x378 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_DQS__SIM_M_HADDR10 0x118 0x378 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__RAWNAND_RE_B 0x11C 0x37C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__FLEXSPI_B_DQS 0x11C 0x37C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x11C 0x37C 0x620 0x2 0x1 +#define MX8MP_IOMUXC_NAND_RE_B__UART4_DCE_TX 0x11C 0x37C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__UART4_DTE_RX 0x11C 0x37C 0x600 0x4 0x5 +#define MX8MP_IOMUXC_NAND_RE_B__GPIO3_IO15 0x11C 0x37C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__CORESIGHT_TRACE13 0x11C 0x37C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__SIM_M_HADDR11 0x11C 0x37C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__RAWNAND_READY_B 0x120 0x380 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__USDHC3_RESET_B 0x120 0x380 0x000 0x2 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__I2C3_SCL 0x120 0x380 0x5B4 0x4 0x2 +#define MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x120 0x380 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__CORESIGHT_TRACE14 0x120 0x380 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__SIM_M_HADDR12 0x120 0x380 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_WE_B__RAWNAND_WE_B 0x124 0x384 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x124 0x384 0x604 0x2 0x1 +#define MX8MP_IOMUXC_NAND_WE_B__I2C3_SDA 0x124 0x384 0x5B8 0x4 0x2 +#define MX8MP_IOMUXC_NAND_WE_B__GPIO3_IO17 0x124 0x384 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_WE_B__CORESIGHT_TRACE15 0x124 0x384 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_WE_B__SIM_M_HADDR13 0x124 0x384 0x000 0x7 0x0 +#define MX8MP_IOMUXC_NAND_WP_B__RAWNAND_WP_B 0x128 0x388 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x128 0x388 0x60C 0x2 0x1 +#define MX8MP_IOMUXC_NAND_WP_B__I2C4_SCL 0x128 0x388 0x5BC 0x4 0x3 +#define MX8MP_IOMUXC_NAND_WP_B__GPIO3_IO18 0x128 0x388 0x000 0x5 0x0 +#define MX8MP_IOMUXC_NAND_WP_B__CORESIGHT_EVENTO 0x128 0x388 0x000 0x6 0x0 +#define MX8MP_IOMUXC_NAND_WP_B__SIM_M_HADDR14 0x128 0x388 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x12C 0x38C 0x508 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI1_TX_DATA00 0x12C 0x38C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXFS__PWM4_OUT 0x12C 0x38C 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL 0x12C 0x38C 0x5CC 0x3 0x1 +#define MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x12C 0x38C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_SAI5_RX_BCLK 0x130 0x390 0x4F4 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_SAI1_TX_DATA01 0x130 0x390 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__PWM3_OUT 0x130 0x390 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x130 0x390 0x5D0 0x3 0x1 +#define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_CLK 0x130 0x390 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x130 0x390 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x134 0x394 0x4F8 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI1_TX_DATA02 0x134 0x394 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXD0__PWM2_OUT 0x134 0x394 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI5_RXD0__I2C5_SCL 0x134 0x394 0x5C4 0x3 0x1 +#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_BIT_STREAM00 0x134 0x394 0x4C0 0x4 0x2 +#define MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x134 0x394 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x138 0x398 0x4FC 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_DATA03 0x138 0x398 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_SYNC 0x138 0x398 0x4D8 0x2 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_TX_SYNC 0x138 0x398 0x510 0x3 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_BIT_STREAM01 0x138 0x398 0x4C4 0x4 0x2 +#define MX8MP_IOMUXC_SAI5_RXD1__GPIO3_IO22 0x138 0x398 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXD1__CAN1_TX 0x138 0x398 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x13C 0x39C 0x500 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_DATA04 0x13C 0x39C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_SYNC 0x13C 0x39C 0x4D8 0x2 0x1 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_TX_BCLK 0x13C 0x39C 0x50C 0x3 0x0 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_BIT_STREAM02 0x13C 0x39C 0x4C8 0x4 0x2 +#define MX8MP_IOMUXC_SAI5_RXD2__GPIO3_IO23 0x13C 0x39C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXD2__CAN1_RX 0x13C 0x39C 0x54C 0x6 0x0 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x140 0x3A0 0x504 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_DATA05 0x140 0x3A0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_SYNC 0x140 0x3A0 0x4D8 0x2 0x2 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_TX_DATA00 0x140 0x3A0 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_BIT_STREAM03 0x140 0x3A0 0x4CC 0x4 0x2 +#define MX8MP_IOMUXC_SAI5_RXD3__GPIO3_IO24 0x140 0x3A0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX 0x140 0x3A0 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI5_MCLK 0x144 0x3A4 0x4F0 0x0 0x0 +#define MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI1_TX_BCLK 0x144 0x3A4 0x4D4 0x1 0x0 +#define MX8MP_IOMUXC_SAI5_MCLK__PWM1_OUT 0x144 0x3A4 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI5_MCLK__I2C5_SDA 0x144 0x3A4 0x5C8 0x3 0x1 +#define MX8MP_IOMUXC_SAI5_MCLK__GPIO3_IO25 0x144 0x3A4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI5_MCLK__CAN2_RX 0x144 0x3A4 0x550 0x6 0x0 +#define MX8MP_IOMUXC_SAI1_RXFS__AUDIOMIX_SAI1_RX_SYNC 0x148 0x3A8 0x4D0 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x148 0x3A8 0x508 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXFS__ENET1_1588_EVENT0_IN 0x148 0x3A8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXFS__GPIO4_IO00 0x148 0x3A8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_SAI1_RX_BCLK 0x14C 0x3AC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_SAI5_RX_BCLK 0x14C 0x3AC 0x4F4 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_CLK 0x14C 0x3AC 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI1_RXC__ENET1_1588_EVENT0_OUT 0x14C 0x3AC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXC__GPIO4_IO01 0x14C 0x3AC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_RX_DATA00 0x150 0x3B0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x150 0x3B0 0x4F8 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_TX_DATA01 0x150 0x3B0 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_BIT_STREAM00 0x150 0x3B0 0x4C0 0x3 0x3 +#define MX8MP_IOMUXC_SAI1_RXD0__ENET1_1588_EVENT1_IN 0x150 0x3B0 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x150 0x3B0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI1_RX_DATA01 0x154 0x3B4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x154 0x3B4 0x4FC 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_BIT_STREAM01 0x154 0x3B4 0x4C4 0x3 0x3 +#define MX8MP_IOMUXC_SAI1_RXD1__ENET1_1588_EVENT1_OUT 0x154 0x3B4 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03 0x154 0x3B4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI1_RX_DATA02 0x158 0x3B8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x158 0x3B8 0x500 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_BIT_STREAM02 0x158 0x3B8 0x4C8 0x3 0x3 +#define MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x158 0x3B8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXD2__GPIO4_IO04 0x158 0x3B8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI1_RX_DATA03 0x15C 0x3BC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x15C 0x3BC 0x504 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_BIT_STREAM03 0x15C 0x3BC 0x4CC 0x3 0x3 +#define MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x15C 0x3BC 0x57C 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_RXD3__GPIO4_IO05 0x15C 0x3BC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD4__AUDIOMIX_SAI1_RX_DATA04 0x160 0x3C0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD4__AUDIOMIX_SAI6_TX_BCLK 0x160 0x3C0 0x524 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD4__AUDIOMIX_SAI6_RX_BCLK 0x160 0x3C0 0x518 0x2 0x1 +#define MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x160 0x3C0 0x580 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_RXD4__GPIO4_IO06 0x160 0x3C0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD5__AUDIOMIX_SAI1_RX_DATA05 0x164 0x3C4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD5__AUDIOMIX_SAI6_TX_DATA00 0x164 0x3C4 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI1_RXD5__AUDIOMIX_SAI6_RX_DATA00 0x164 0x3C4 0x51C 0x2 0x1 +#define MX8MP_IOMUXC_SAI1_RXD5__AUDIOMIX_SAI1_RX_SYNC 0x164 0x3C4 0x4D0 0x3 0x1 +#define MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x164 0x3C4 0x584 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_RXD5__GPIO4_IO07 0x164 0x3C4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD6__AUDIOMIX_SAI1_RX_DATA06 0x168 0x3C8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD6__AUDIOMIX_SAI6_TX_SYNC 0x168 0x3C8 0x528 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD6__AUDIOMIX_SAI6_RX_SYNC 0x168 0x3C8 0x520 0x2 0x1 +#define MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x168 0x3C8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXD6__GPIO4_IO08 0x168 0x3C8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_RXD7__AUDIOMIX_SAI1_RX_DATA07 0x16C 0x3CC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_RXD7__AUDIOMIX_SAI6_MCLK 0x16C 0x3CC 0x514 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_RXD7__AUDIOMIX_SAI1_TX_SYNC 0x16C 0x3CC 0x4D8 0x2 0x3 +#define MX8MP_IOMUXC_SAI1_RXD7__AUDIOMIX_SAI1_TX_DATA04 0x16C 0x3CC 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x16C 0x3CC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_RXD7__GPIO4_IO09 0x16C 0x3CC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXFS__AUDIOMIX_SAI1_TX_SYNC 0x170 0x3D0 0x4D8 0x0 0x4 +#define MX8MP_IOMUXC_SAI1_TXFS__AUDIOMIX_SAI5_TX_SYNC 0x170 0x3D0 0x510 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x170 0x3D0 0x588 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_TXFS__GPIO4_IO10 0x170 0x3D0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXC__AUDIOMIX_SAI1_TX_BCLK 0x174 0x3D4 0x4D4 0x0 0x1 +#define MX8MP_IOMUXC_SAI1_TXC__AUDIOMIX_SAI5_TX_BCLK 0x174 0x3D4 0x50C 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x174 0x3D4 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXC__GPIO4_IO11 0x174 0x3D4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD0__AUDIOMIX_SAI1_TX_DATA00 0x178 0x3D8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD0__AUDIOMIX_SAI5_TX_DATA00 0x178 0x3D8 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x178 0x3D8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD0__GPIO4_IO12 0x178 0x3D8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD1__AUDIOMIX_SAI1_TX_DATA01 0x17C 0x3DC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD1__AUDIOMIX_SAI5_TX_DATA01 0x17C 0x3DC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x17C 0x3DC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD1__GPIO4_IO13 0x17C 0x3DC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD2__AUDIOMIX_SAI1_TX_DATA02 0x180 0x3E0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD2__AUDIOMIX_SAI5_TX_DATA02 0x180 0x3E0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x180 0x3E0 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD2__GPIO4_IO14 0x180 0x3E0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD3__AUDIOMIX_SAI1_TX_DATA03 0x184 0x3E4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD3__AUDIOMIX_SAI5_TX_DATA03 0x184 0x3E4 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x184 0x3E4 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD3__GPIO4_IO15 0x184 0x3E4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD4__AUDIOMIX_SAI1_TX_DATA04 0x188 0x3E8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD4__AUDIOMIX_SAI6_RX_BCLK 0x188 0x3E8 0x518 0x1 0x2 +#define MX8MP_IOMUXC_SAI1_TXD4__AUDIOMIX_SAI6_TX_BCLK 0x188 0x3E8 0x524 0x2 0x2 +#define MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x188 0x3E8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD4__GPIO4_IO16 0x188 0x3E8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD5__AUDIOMIX_SAI1_TX_DATA05 0x18C 0x3EC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD5__AUDIOMIX_SAI6_RX_DATA00 0x18C 0x3EC 0x51C 0x1 0x2 +#define MX8MP_IOMUXC_SAI1_TXD5__AUDIOMIX_SAI6_TX_DATA00 0x18C 0x3EC 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x18C 0x3EC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD5__GPIO4_IO17 0x18C 0x3EC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD6__AUDIOMIX_SAI1_TX_DATA06 0x190 0x3F0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD6__AUDIOMIX_SAI6_RX_SYNC 0x190 0x3F0 0x520 0x1 0x2 +#define MX8MP_IOMUXC_SAI1_TXD6__AUDIOMIX_SAI6_TX_SYNC 0x190 0x3F0 0x528 0x2 0x2 +#define MX8MP_IOMUXC_SAI1_TXD6__ENET1_RX_ER 0x190 0x3F0 0x58C 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x190 0x3F0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_SAI1_TX_DATA07 0x194 0x3F4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_SAI6_MCLK 0x194 0x3F4 0x514 0x1 0x2 +#define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_CLK 0x194 0x3F4 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI1_TXD7__ENET1_TX_ER 0x194 0x3F4 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x194 0x3F4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI1_MCLK 0x198 0x3F8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI5_MCLK 0x198 0x3F8 0x4F0 0x1 0x1 +#define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI1_TX_BCLK 0x198 0x3F8 0x4D4 0x2 0x2 +#define MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK 0x198 0x3F8 0x578 0x4 0x1 +#define MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x198 0x3F8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI2_RX_SYNC 0x19C 0x3FC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI5_TX_SYNC 0x19C 0x3FC 0x510 0x1 0x2 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI5_TX_DATA01 0x19C 0x3FC 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI2_RX_DATA01 0x19C 0x3FC 0x4DC 0x3 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__UART1_DCE_TX 0x19C 0x3FC 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__UART1_DTE_RX 0x19C 0x3FC 0x5E8 0x4 0x2 +#define MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x19C 0x3FC 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_BIT_STREAM02 0x19C 0x3FC 0x4C8 0x6 0x4 +#define MX8MP_IOMUXC_SAI2_RXFS__SIM_M_HSIZE00 0x19C 0x3FC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI2_RX_BCLK 0x1A0 0x400 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI5_TX_BCLK 0x1A0 0x400 0x50C 0x1 0x2 +#define MX8MP_IOMUXC_SAI2_RXC__CAN1_TX 0x1A0 0x400 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__UART1_DCE_RX 0x1A0 0x400 0x5E8 0x4 0x3 +#define MX8MP_IOMUXC_SAI2_RXC__UART1_DTE_TX 0x1A0 0x400 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x1A0 0x400 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_BIT_STREAM01 0x1A0 0x400 0x4C4 0x6 0x4 +#define MX8MP_IOMUXC_SAI2_RXC__SIM_M_HSIZE01 0x1A0 0x400 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0x1A4 0x404 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI5_TX_DATA00 0x1A4 0x404 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__ENET_QOS_1588_EVENT2_OUT 0x1A4 0x404 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_TX_DATA01 0x1A4 0x404 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__UART1_DCE_RTS 0x1A4 0x404 0x5E4 0x4 0x2 +#define MX8MP_IOMUXC_SAI2_RXD0__UART1_DTE_CTS 0x1A4 0x404 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__GPIO4_IO23 0x1A4 0x404 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_BIT_STREAM03 0x1A4 0x404 0x4CC 0x6 0x4 +#define MX8MP_IOMUXC_SAI2_RXD0__SIM_M_HSIZE02 0x1A4 0x404 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0x1A8 0x408 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI5_TX_DATA01 0x1A8 0x408 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__ENET_QOS_1588_EVENT3_OUT 0x1A8 0x408 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_DATA01 0x1A8 0x408 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS 0x1A8 0x408 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__UART1_DTE_RTS 0x1A8 0x408 0x5E4 0x4 0x3 +#define MX8MP_IOMUXC_SAI2_TXFS__GPIO4_IO24 0x1A8 0x408 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_BIT_STREAM02 0x1A8 0x408 0x4C8 0x6 0x5 +#define MX8MP_IOMUXC_SAI2_TXFS__SIM_M_HWRITE 0x1A8 0x408 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0x1AC 0x40C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI5_TX_DATA02 0x1AC 0x40C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI2_TXC__CAN1_RX 0x1AC 0x40C 0x54C 0x3 0x1 +#define MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x1AC 0x40C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_BIT_STREAM01 0x1AC 0x40C 0x4C4 0x6 0x5 +#define MX8MP_IOMUXC_SAI2_TXC__SIM_M_HREADYOUT 0x1AC 0x40C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0x1B0 0x410 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI5_TX_DATA03 0x1B0 0x410 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__ENET_QOS_1588_EVENT2_IN 0x1B0 0x410 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__CAN2_TX 0x1B0 0x410 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__ENET_QOS_1588_EVENT2_AUX_IN 0x1B0 0x410 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x1B0 0x410 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__CCMSRCGPCMIX_BOOT_MODE04 0x1B0 0x410 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SAI2_TXD0__TPSMP_CLK 0x1B0 0x410 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI2_MCLK 0x1B4 0x414 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI5_MCLK 0x1B4 0x414 0x4F0 0x1 0x2 +#define MX8MP_IOMUXC_SAI2_MCLK__ENET_QOS_1588_EVENT3_IN 0x1B4 0x414 0x000 0x2 0x0 +#define MX8MP_IOMUXC_SAI2_MCLK__CAN2_RX 0x1B4 0x414 0x550 0x3 0x1 +#define MX8MP_IOMUXC_SAI2_MCLK__ENET_QOS_1588_EVENT3_AUX_IN 0x1B4 0x414 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x1B4 0x414 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI3_MCLK 0x1B4 0x414 0x4E0 0x6 0x1 +#define MX8MP_IOMUXC_SAI2_MCLK__TPSMP_HDATA_DIR 0x1B4 0x414 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_SYNC 0x1B8 0x418 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI2_RX_DATA01 0x1B8 0x418 0x4DC 0x1 0x1 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x1B8 0x418 0x508 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_DATA01 0x1B8 0x418 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SPDIF_IN 0x1B8 0x418 0x544 0x4 0x2 +#define MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x1B8 0x418 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_BIT_STREAM00 0x1B8 0x418 0x4C0 0x6 0x4 +#define MX8MP_IOMUXC_SAI3_RXFS__TPSMP_HTRANS00 0x1B8 0x418 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI3_RX_BCLK 0x1BC 0x41C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI2_RX_DATA02 0x1BC 0x41C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI5_RX_BCLK 0x1BC 0x41C 0x4F4 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_RXC__GPT1_CLK 0x1BC 0x41C 0x59C 0x3 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__UART2_DCE_CTS 0x1BC 0x41C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__UART2_DTE_RTS 0x1BC 0x41C 0x5EC 0x4 0x2 +#define MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x1BC 0x41C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_CLK 0x1BC 0x41C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__TPSMP_HTRANS01 0x1BC 0x41C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0x1C0 0x420 0x4E4 0x0 0x1 +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI2_RX_DATA03 0x1C0 0x420 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI5_RX_DATA00 0x1C0 0x420 0x4F8 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS 0x1C0 0x420 0x5EC 0x4 0x3 +#define MX8MP_IOMUXC_SAI3_RXD__UART2_DTE_CTS 0x1C0 0x420 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_RXD__GPIO4_IO30 0x1C0 0x420 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_BIT_STREAM01 0x1C0 0x420 0x4C4 0x6 0x6 +#define MX8MP_IOMUXC_SAI3_RXD__TPSMP_HDATA00 0x1C0 0x420 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0x1C4 0x424 0x4EC 0x0 0x1 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI2_TX_DATA01 0x1C4 0x424 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI5_RX_DATA01 0x1C4 0x424 0x4FC 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_DATA01 0x1C4 0x424 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__UART2_DCE_RX 0x1C4 0x424 0x5F0 0x4 0x4 +#define MX8MP_IOMUXC_SAI3_TXFS__UART2_DTE_TX 0x1C4 0x424 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__GPIO4_IO31 0x1C4 0x424 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_BIT_STREAM03 0x1C4 0x424 0x4CC 0x6 0x5 +#define MX8MP_IOMUXC_SAI3_TXFS__TPSMP_HDATA01 0x1C4 0x424 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0x1C8 0x428 0x4E8 0x0 0x1 +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI2_TX_DATA02 0x1C8 0x428 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI5_RX_DATA02 0x1C8 0x428 0x500 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_TXC__GPT1_CAPTURE1 0x1C8 0x428 0x594 0x3 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__UART2_DCE_TX 0x1C8 0x428 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__UART2_DTE_RX 0x1C8 0x428 0x5F0 0x4 0x5 +#define MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x1C8 0x428 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_BIT_STREAM02 0x1C8 0x428 0x4C8 0x6 0x6 +#define MX8MP_IOMUXC_SAI3_TXC__TPSMP_HDATA02 0x1C8 0x428 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0x1CC 0x42C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI2_TX_DATA03 0x1CC 0x42C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI5_RX_DATA03 0x1CC 0x42C 0x504 0x2 0x2 +#define MX8MP_IOMUXC_SAI3_TXD__GPT1_CAPTURE2 0x1CC 0x42C 0x598 0x3 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SPDIF_EXT_CLK 0x1CC 0x42C 0x548 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x1CC 0x42C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__CCMSRCGPCMIX_BOOT_MODE05 0x1CC 0x42C 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__TPSMP_HDATA03 0x1CC 0x42C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0x1D0 0x430 0x4E0 0x0 0x2 +#define MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT 0x1D0 0x430 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI5_MCLK 0x1D0 0x430 0x4F0 0x2 0x3 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF_OUT 0x1D0 0x430 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x1D0 0x430 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF_IN 0x1D0 0x430 0x544 0x6 0x3 +#define MX8MP_IOMUXC_SAI3_MCLK__TPSMP_HDATA04 0x1D0 0x430 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SPDIF_TX__AUDIOMIX_SPDIF_OUT 0x1D4 0x434 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SPDIF_TX__PWM3_OUT 0x1D4 0x434 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x1D4 0x434 0x5C4 0x2 0x2 +#define MX8MP_IOMUXC_SPDIF_TX__GPT1_COMPARE1 0x1D4 0x434 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x1D4 0x434 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SPDIF_TX__GPIO5_IO03 0x1D4 0x434 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SPDIF_RX__AUDIOMIX_SPDIF_IN 0x1D8 0x438 0x544 0x0 0x4 +#define MX8MP_IOMUXC_SPDIF_RX__PWM2_OUT 0x1D8 0x438 0x000 0x1 0x0 +#define MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x1D8 0x438 0x5C8 0x2 0x2 +#define MX8MP_IOMUXC_SPDIF_RX__GPT1_COMPARE2 0x1D8 0x438 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x1D8 0x438 0x54C 0x4 0x2 +#define MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x1D8 0x438 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SPDIF_EXT_CLK__GPT1_COMPARE3 0x1DC 0x43C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x1DC 0x43C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_SPDIF_EXT_CLK__AUDIOMIX_SPDIF_EXT_CLK 0x1DC 0x43C 0x548 0x0 0x1 +#define MX8MP_IOMUXC_SPDIF_EXT_CLK__PWM1_OUT 0x1DC 0x43C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK 0x1E0 0x440 0x558 0x0 0x0 +#define MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x1E0 0x440 0x5F8 0x1 0x4 +#define MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DTE_TX 0x1E0 0x440 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI1_SCLK__I2C1_SCL 0x1E0 0x440 0x5A4 0x2 0x1 +#define MX8MP_IOMUXC_ECSPI1_SCLK__AUDIOMIX_SAI7_RX_SYNC 0x1E0 0x440 0x538 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI1_SCLK__GPIO5_IO06 0x1E0 0x440 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI1_SCLK__TPSMP_HDATA08 0x1E0 0x440 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI 0x1E4 0x444 0x560 0x0 0x0 +#define MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DCE_TX 0x1E4 0x444 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DTE_RX 0x1E4 0x444 0x5F8 0x1 0x5 +#define MX8MP_IOMUXC_ECSPI1_MOSI__I2C1_SDA 0x1E4 0x444 0x5A8 0x2 0x1 +#define MX8MP_IOMUXC_ECSPI1_MOSI__AUDIOMIX_SAI7_RX_BCLK 0x1E4 0x444 0x530 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI1_MOSI__GPIO5_IO07 0x1E4 0x444 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI1_MOSI__TPSMP_HDATA09 0x1E4 0x444 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO 0x1E8 0x448 0x55C 0x0 0x0 +#define MX8MP_IOMUXC_ECSPI1_MISO__UART3_DCE_CTS 0x1E8 0x448 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI1_MISO__UART3_DTE_RTS 0x1E8 0x448 0x5F4 0x1 0x2 +#define MX8MP_IOMUXC_ECSPI1_MISO__I2C2_SCL 0x1E8 0x448 0x5AC 0x2 0x1 +#define MX8MP_IOMUXC_ECSPI1_MISO__AUDIOMIX_SAI7_RX_DATA00 0x1E8 0x448 0x534 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI1_MISO__GPIO5_IO08 0x1E8 0x448 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI1_MISO__TPSMP_HDATA10 0x1E8 0x448 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI1_SS0__ECSPI1_SS0 0x1EC 0x44C 0x564 0x0 0x0 +#define MX8MP_IOMUXC_ECSPI1_SS0__UART3_DCE_RTS 0x1EC 0x44C 0x5F4 0x1 0x3 +#define MX8MP_IOMUXC_ECSPI1_SS0__UART3_DTE_CTS 0x1EC 0x44C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI1_SS0__I2C2_SDA 0x1EC 0x44C 0x5B0 0x2 0x1 +#define MX8MP_IOMUXC_ECSPI1_SS0__AUDIOMIX_SAI7_TX_SYNC 0x1EC 0x44C 0x540 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x1EC 0x44C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI1_SS0__TPSMP_HDATA11 0x1EC 0x44C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x1F0 0x450 0x568 0x0 0x1 +#define MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DCE_RX 0x1F0 0x450 0x600 0x1 0x6 +#define MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DTE_TX 0x1F0 0x450 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI2_SCLK__I2C3_SCL 0x1F0 0x450 0x5B4 0x2 0x3 +#define MX8MP_IOMUXC_ECSPI2_SCLK__AUDIOMIX_SAI7_TX_BCLK 0x1F0 0x450 0x53C 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10 0x1F0 0x450 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI2_SCLK__TPSMP_HDATA12 0x1F0 0x450 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x1F4 0x454 0x570 0x0 0x1 +#define MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DCE_TX 0x1F4 0x454 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DTE_RX 0x1F4 0x454 0x600 0x1 0x7 +#define MX8MP_IOMUXC_ECSPI2_MOSI__I2C3_SDA 0x1F4 0x454 0x5B8 0x2 0x3 +#define MX8MP_IOMUXC_ECSPI2_MOSI__AUDIOMIX_SAI7_TX_DATA00 0x1F4 0x454 0x000 0x3 0x0 +#define MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11 0x1F4 0x454 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI2_MOSI__TPSMP_HDATA13 0x1F4 0x454 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12 0x1F8 0x458 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI2_MISO__TPSMP_HDATA14 0x1F8 0x458 0x000 0x7 0x0 +#define MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x1F8 0x458 0x56C 0x0 0x1 +#define MX8MP_IOMUXC_ECSPI2_MISO__UART4_DCE_CTS 0x1F8 0x458 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI2_MISO__UART4_DTE_RTS 0x1F8 0x458 0x5FC 0x1 0x2 +#define MX8MP_IOMUXC_ECSPI2_MISO__I2C4_SCL 0x1F8 0x458 0x5BC 0x2 0x4 +#define MX8MP_IOMUXC_ECSPI2_MISO__AUDIOMIX_SAI7_MCLK 0x1F8 0x458 0x52C 0x3 0x1 +#define MX8MP_IOMUXC_ECSPI2_MISO__CCMSRCGPCMIX_CLKO1 0x1F8 0x458 0x000 0x4 0x0 +#define MX8MP_IOMUXC_ECSPI2_SS0__ECSPI2_SS0 0x1FC 0x45C 0x574 0x0 0x1 +#define MX8MP_IOMUXC_ECSPI2_SS0__UART4_DCE_RTS 0x1FC 0x45C 0x5FC 0x1 0x3 +#define MX8MP_IOMUXC_ECSPI2_SS0__UART4_DTE_CTS 0x1FC 0x45C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_ECSPI2_SS0__I2C4_SDA 0x1FC 0x45C 0x5C0 0x2 0x4 +#define MX8MP_IOMUXC_ECSPI2_SS0__CCMSRCGPCMIX_CLKO2 0x1FC 0x45C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x1FC 0x45C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_ECSPI2_SS0__TPSMP_HDATA15 0x1FC 0x45C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x200 0x460 0x5A4 0x0 0x2 +#define MX8MP_IOMUXC_I2C1_SCL__ENET_QOS_MDC 0x200 0x460 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C1_SCL__ECSPI1_SCLK 0x200 0x460 0x558 0x3 0x1 +#define MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x200 0x460 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C1_SCL__TPSMP_HDATA16 0x200 0x460 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x204 0x464 0x5A8 0x0 0x2 +#define MX8MP_IOMUXC_I2C1_SDA__ENET_QOS_MDIO 0x204 0x464 0x590 0x1 0x2 +#define MX8MP_IOMUXC_I2C1_SDA__ECSPI1_MOSI 0x204 0x464 0x560 0x3 0x1 +#define MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x204 0x464 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C1_SDA__TPSMP_HDATA17 0x204 0x464 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x208 0x468 0x5AC 0x0 0x2 +#define MX8MP_IOMUXC_I2C2_SCL__ENET_QOS_1588_EVENT1_IN 0x208 0x468 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C2_SCL__USDHC3_CD_B 0x208 0x468 0x608 0x2 0x3 +#define MX8MP_IOMUXC_I2C2_SCL__ECSPI1_MISO 0x208 0x468 0x55C 0x3 0x1 +#define MX8MP_IOMUXC_I2C2_SCL__ENET_QOS_1588_EVENT1_AUX_IN 0x208 0x468 0x000 0x4 0x0 +#define MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x208 0x468 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C2_SCL__TPSMP_HDATA18 0x208 0x468 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x20C 0x46C 0x5B0 0x0 0x2 +#define MX8MP_IOMUXC_I2C2_SDA__ENET_QOS_1588_EVENT1_OUT 0x20C 0x46C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C2_SDA__USDHC3_WP 0x20C 0x46C 0x634 0x2 0x3 +#define MX8MP_IOMUXC_I2C2_SDA__ECSPI1_SS0 0x20C 0x46C 0x564 0x3 0x1 +#define MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x20C 0x46C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C2_SDA__TPSMP_HDATA19 0x20C 0x46C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x210 0x470 0x5B4 0x0 0x4 +#define MX8MP_IOMUXC_I2C3_SCL__PWM4_OUT 0x210 0x470 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C3_SCL__GPT2_CLK 0x210 0x470 0x000 0x2 0x0 +#define MX8MP_IOMUXC_I2C3_SCL__ECSPI2_SCLK 0x210 0x470 0x568 0x3 0x2 +#define MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x210 0x470 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C3_SCL__TPSMP_HDATA20 0x210 0x470 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x214 0x474 0x5B8 0x0 0x4 +#define MX8MP_IOMUXC_I2C3_SDA__PWM3_OUT 0x214 0x474 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C3_SDA__GPT3_CLK 0x214 0x474 0x000 0x2 0x0 +#define MX8MP_IOMUXC_I2C3_SDA__ECSPI2_MOSI 0x214 0x474 0x570 0x3 0x2 +#define MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x214 0x474 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C3_SDA__TPSMP_HDATA21 0x214 0x474 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x218 0x478 0x5BC 0x0 0x5 +#define MX8MP_IOMUXC_I2C4_SCL__PWM2_OUT 0x218 0x478 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C4_SCL__HSIOMIX_PCIE_CLKREQ_B 0x218 0x478 0x5A0 0x2 0x0 +#define MX8MP_IOMUXC_I2C4_SCL__ECSPI2_MISO 0x218 0x478 0x56C 0x3 0x2 +#define MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x218 0x478 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C4_SCL__TPSMP_HDATA22 0x218 0x478 0x000 0x7 0x0 +#define MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x21C 0x47C 0x5C0 0x0 0x5 +#define MX8MP_IOMUXC_I2C4_SDA__PWM1_OUT 0x21C 0x47C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_I2C4_SDA__ECSPI2_SS0 0x21C 0x47C 0x574 0x3 0x2 +#define MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x21C 0x47C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_I2C4_SDA__TPSMP_HDATA23 0x21C 0x47C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x220 0x480 0x5E8 0x0 0x4 +#define MX8MP_IOMUXC_UART1_RXD__UART1_DTE_TX 0x220 0x480 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART1_RXD__ECSPI3_SCLK 0x220 0x480 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART1_RXD__GPIO5_IO22 0x220 0x480 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART1_RXD__TPSMP_HDATA24 0x220 0x480 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x224 0x484 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART1_TXD__UART1_DTE_RX 0x224 0x484 0x5E8 0x0 0x5 +#define MX8MP_IOMUXC_UART1_TXD__ECSPI3_MOSI 0x224 0x484 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART1_TXD__GPIO5_IO23 0x224 0x484 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART1_TXD__TPSMP_HDATA25 0x224 0x484 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x228 0x488 0x5F0 0x0 0x6 +#define MX8MP_IOMUXC_UART2_RXD__UART2_DTE_TX 0x228 0x488 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART2_RXD__ECSPI3_MISO 0x228 0x488 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART2_RXD__GPT1_COMPARE3 0x228 0x488 0x000 0x3 0x0 +#define MX8MP_IOMUXC_UART2_RXD__GPIO5_IO24 0x228 0x488 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART2_RXD__TPSMP_HDATA26 0x228 0x488 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x22C 0x48C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART2_TXD__UART2_DTE_RX 0x22C 0x48C 0x5F0 0x0 0x7 +#define MX8MP_IOMUXC_UART2_TXD__ECSPI3_SS0 0x22C 0x48C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART2_TXD__GPT1_COMPARE2 0x22C 0x48C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_UART2_TXD__GPIO5_IO25 0x22C 0x48C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART2_TXD__TPSMP_HDATA27 0x22C 0x48C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x230 0x490 0x5F8 0x0 0x6 +#define MX8MP_IOMUXC_UART3_RXD__UART3_DTE_TX 0x230 0x490 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART3_RXD__UART1_DCE_CTS 0x230 0x490 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART3_RXD__UART1_DTE_RTS 0x230 0x490 0x5E4 0x1 0x4 +#define MX8MP_IOMUXC_UART3_RXD__USDHC3_RESET_B 0x230 0x490 0x000 0x2 0x0 +#define MX8MP_IOMUXC_UART3_RXD__GPT1_CAPTURE2 0x230 0x490 0x598 0x3 0x1 +#define MX8MP_IOMUXC_UART3_RXD__CAN2_TX 0x230 0x490 0x000 0x4 0x0 +#define MX8MP_IOMUXC_UART3_RXD__GPIO5_IO26 0x230 0x490 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART3_RXD__TPSMP_HDATA28 0x230 0x490 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x234 0x494 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART3_TXD__UART3_DTE_RX 0x234 0x494 0x5F8 0x0 0x7 +#define MX8MP_IOMUXC_UART3_TXD__UART1_DCE_RTS 0x234 0x494 0x5E4 0x1 0x5 +#define MX8MP_IOMUXC_UART3_TXD__UART1_DTE_CTS 0x234 0x494 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART3_TXD__USDHC3_VSELECT 0x234 0x494 0x000 0x2 0x0 +#define MX8MP_IOMUXC_UART3_TXD__GPT1_CLK 0x234 0x494 0x59C 0x3 0x1 +#define MX8MP_IOMUXC_UART3_TXD__CAN2_RX 0x234 0x494 0x550 0x4 0x2 +#define MX8MP_IOMUXC_UART3_TXD__GPIO5_IO27 0x234 0x494 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART3_TXD__TPSMP_HDATA29 0x234 0x494 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x238 0x498 0x600 0x0 0x8 +#define MX8MP_IOMUXC_UART4_RXD__UART4_DTE_TX 0x238 0x498 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART4_RXD__UART2_DCE_CTS 0x238 0x498 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART4_RXD__UART2_DTE_RTS 0x238 0x498 0x5EC 0x1 0x4 +#define MX8MP_IOMUXC_UART4_RXD__HSIOMIX_PCIE_CLKREQ_B 0x238 0x498 0x5A0 0x2 0x1 +#define MX8MP_IOMUXC_UART4_RXD__GPT1_COMPARE1 0x238 0x498 0x000 0x3 0x0 +#define MX8MP_IOMUXC_UART4_RXD__I2C6_SCL 0x238 0x498 0x5CC 0x4 0x2 +#define MX8MP_IOMUXC_UART4_RXD__GPIO5_IO28 0x238 0x498 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART4_RXD__TPSMP_HDATA30 0x238 0x498 0x000 0x7 0x0 +#define MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x23C 0x49C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_UART4_TXD__UART4_DTE_RX 0x23C 0x49C 0x600 0x0 0x9 +#define MX8MP_IOMUXC_UART4_TXD__UART2_DCE_RTS 0x23C 0x49C 0x5EC 0x1 0x5 +#define MX8MP_IOMUXC_UART4_TXD__UART2_DTE_CTS 0x23C 0x49C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_UART4_TXD__GPT1_CAPTURE1 0x23C 0x49C 0x594 0x3 0x1 +#define MX8MP_IOMUXC_UART4_TXD__I2C6_SDA 0x23C 0x49C 0x5D0 0x4 0x2 +#define MX8MP_IOMUXC_UART4_TXD__GPIO5_IO29 0x23C 0x49C 0x000 0x5 0x0 +#define MX8MP_IOMUXC_UART4_TXD__TPSMP_HDATA31 0x23C 0x49C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_EARC_SCL 0x240 0x4A0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL 0x240 0x4A0 0x5C4 0x3 0x3 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__CAN1_TX 0x240 0x4A0 0x000 0x4 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26 0x240 0x4A0 0x000 0x5 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__AUDIOMIX_test_out00 0x240 0x4A0 0x000 0x6 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_EARC_SDA 0x244 0x4A4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA 0x244 0x4A4 0x5C8 0x3 0x3 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__CAN1_RX 0x244 0x4A4 0x54C 0x4 0x3 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27 0x244 0x4A4 0x000 0x5 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__AUDIOMIX_test_out01 0x244 0x4A4 0x000 0x6 0x0 +#define MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_EARC_CEC 0x248 0x4A8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_CEC__I2C6_SCL 0x248 0x4A8 0x5CC 0x3 0x3 +#define MX8MP_IOMUXC_HDMI_CEC__CAN2_TX 0x248 0x4A8 0x000 0x4 0x0 +#define MX8MP_IOMUXC_HDMI_CEC__GPIO3_IO28 0x248 0x4A8 0x000 0x5 0x0 +#define MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_EARC_DC_HPD 0x24C 0x4AC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_HPD__AUDIOMIX_EARC_HDMI_HPD_O 0x24C 0x4AC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_HDMI_HPD__I2C6_SDA 0x24C 0x4AC 0x5D0 0x3 0x3 +#define MX8MP_IOMUXC_HDMI_HPD__CAN2_RX 0x24C 0x4AC 0x550 0x4 0x3 +#define MX8MP_IOMUXC_HDMI_HPD__GPIO3_IO29 0x24C 0x4AC 0x000 0x5 0x0 + +#endif /* __DTS_IMX8MP_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi new file mode 100644 index 000000000000..9b1616e59d58 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -0,0 +1,654 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 NXP + */ + +#include <dt-bindings/clock/imx8mp-clock.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +#include "imx8mp-pinfunc.h" + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + ethernet0 = &fec; + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + gpio4 = &gpio5; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + A53_0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + clock-latency = <61036>; + clocks = <&clk IMX8MP_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + }; + + A53_1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + clock-latency = <61036>; + clocks = <&clk IMX8MP_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + }; + + A53_2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + clock-latency = <61036>; + clocks = <&clk IMX8MP_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + }; + + A53_3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + clock-latency = <61036>; + clocks = <&clk IMX8MP_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + }; + + A53_L2: l2-cache0 { + compatible = "cache"; + }; + }; + + osc_32k: clock-osc-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "osc_32k"; + }; + + osc_24m: clock-osc-24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "osc_24m"; + }; + + clk_ext1: clock-ext1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext1"; + }; + + clk_ext2: clock-ext2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext2"; + }; + + clk_ext3: clock-ext3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext3"; + }; + + clk_ext4: clock-ext4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency= <133000000>; + clock-output-names = "clk_ext4"; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + clock-frequency = <8000000>; + arm,no-tick-in-suspend; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x3e000000>; + + aips1: bus@30000000 { + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x301f0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio1: gpio@30200000 { + compatible = "fsl,imx8mp-gpio", "fsl,imx35-gpio"; + reg = <0x30200000 0x10000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_GPIO1_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 5 30>; + }; + + gpio2: gpio@30210000 { + compatible = "fsl,imx8mp-gpio", "fsl,imx35-gpio"; + reg = <0x30210000 0x10000>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_GPIO2_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 35 21>; + }; + + gpio3: gpio@30220000 { + compatible = "fsl,imx8mp-gpio", "fsl,imx35-gpio"; + reg = <0x30220000 0x10000>; + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_GPIO3_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 0 144 4>; + }; + + gpio4: gpio@30230000 { + compatible = "fsl,imx8mp-gpio", "fsl,imx35-gpio"; + reg = <0x30230000 0x10000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_GPIO4_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 82 32>; + }; + + gpio5: gpio@30240000 { + compatible = "fsl,imx8mp-gpio", "fsl,imx35-gpio"; + reg = <0x30240000 0x10000>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_GPIO5_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 114 30>; + }; + + wdog1: watchdog@30280000 { + compatible = "fsl,imx8mp-wdt", "fsl,imx21-wdt"; + reg = <0x30280000 0x10000>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_WDOG1_ROOT>; + status = "disabled"; + }; + + iomuxc: pinctrl@30330000 { + compatible = "fsl,imx8mp-iomuxc"; + reg = <0x30330000 0x10000>; + }; + + gpr: iomuxc-gpr@30340000 { + compatible = "fsl,imx8mp-iomuxc-gpr", "syscon"; + reg = <0x30340000 0x10000>; + }; + + ocotp: ocotp-ctrl@30350000 { + compatible = "fsl,imx8mp-ocotp", "syscon"; + reg = <0x30350000 0x10000>; + clocks = <&clk IMX8MP_CLK_OCOTP_ROOT>; + /* For nvmem subnodes */ + #address-cells = <1>; + #size-cells = <1>; + + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; + }; + + anatop: anatop@30360000 { + compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop", + "syscon"; + reg = <0x30360000 0x10000>; + }; + + snvs: snvs@30370000 { + compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd"; + reg = <0x30370000 0x10000>; + + snvs_rtc: snvs-rtc-lp { + compatible = "fsl,sec-v4.0-mon-rtc-lp"; + regmap =<&snvs>; + offset = <0x34>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_SNVS_ROOT>; + clock-names = "snvs-rtc"; + }; + + snvs_pwrkey: snvs-powerkey { + compatible = "fsl,sec-v4.0-pwrkey"; + regmap = <&snvs>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_SNVS_ROOT>; + clock-names = "snvs-pwrkey"; + linux,keycode = <KEY_POWER>; + wakeup-source; + status = "disabled"; + }; + }; + + clk: clock-controller@30380000 { + compatible = "fsl,imx8mp-ccm"; + reg = <0x30380000 0x10000>; + #clock-cells = <1>; + clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>, + <&clk_ext3>, <&clk_ext4>; + clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4"; + assigned-clocks = <&clk IMX8MP_CLK_NOC>, + <&clk IMX8MP_CLK_NOC_IO>, + <&clk IMX8MP_CLK_GIC>, + <&clk IMX8MP_CLK_AUDIO_AHB>, + <&clk IMX8MP_CLK_AUDIO_AXI_SRC>, + <&clk IMX8MP_CLK_IPG_AUDIO_ROOT>, + <&clk IMX8MP_AUDIO_PLL1>, + <&clk IMX8MP_AUDIO_PLL2>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>, + <&clk IMX8MP_SYS_PLL1_800M>, + <&clk IMX8MP_SYS_PLL2_500M>, + <&clk IMX8MP_SYS_PLL1_800M>, + <&clk IMX8MP_SYS_PLL1_800M>; + assigned-clock-rates = <1000000000>, + <800000000>, + <500000000>, + <400000000>, + <800000000>, + <400000000>, + <393216000>, + <361267200>; + }; + + src: reset-controller@30390000 { + compatible = "fsl,imx8mp-src", "syscon"; + reg = <0x30390000 0x10000>; + #reset-cells = <1>; + }; + }; + + aips2: bus@30400000 { + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x305f0000 0x400000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pwm1: pwm@30660000 { + compatible = "fsl,imx8mp-pwm", "fsl,imx27-pwm"; + reg = <0x30660000 0x10000>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_PWM1_ROOT>, + <&clk IMX8MP_CLK_PWM1_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm@30670000 { + compatible = "fsl,imx8mp-pwm", "fsl,imx27-pwm"; + reg = <0x30670000 0x10000>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_PWM2_ROOT>, + <&clk IMX8MP_CLK_PWM2_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm@30680000 { + compatible = "fsl,imx8mp-pwm", "fsl,imx27-pwm"; + reg = <0x30680000 0x10000>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_PWM3_ROOT>, + <&clk IMX8MP_CLK_PWM3_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm@30690000 { + compatible = "fsl,imx8mp-pwm", "fsl,imx27-pwm"; + reg = <0x30690000 0x10000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_PWM4_ROOT>, + <&clk IMX8MP_CLK_PWM4_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + system_counter: timer@306a0000 { + compatible = "nxp,sysctr-timer"; + reg = <0x306a0000 0x20000>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc_24m>; + clock-names = "per"; + }; + }; + + aips3: bus@30800000 { + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x309f0000 0x400000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + ecspi1: spi@30820000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi"; + reg = <0x30820000 0x10000>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_ECSPI1_ROOT>, + <&clk IMX8MP_CLK_ECSPI1_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + ecspi2: spi@30830000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi"; + reg = <0x30830000 0x10000>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_ECSPI2_ROOT>, + <&clk IMX8MP_CLK_ECSPI2_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + ecspi3: spi@30840000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi"; + reg = <0x30840000 0x10000>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_ECSPI3_ROOT>, + <&clk IMX8MP_CLK_ECSPI3_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart1: serial@30860000 { + compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart"; + reg = <0x30860000 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_UART1_ROOT>, + <&clk IMX8MP_CLK_UART1_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart3: serial@30880000 { + compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart"; + reg = <0x30880000 0x10000>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_UART3_ROOT>, + <&clk IMX8MP_CLK_UART3_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart2: serial@30890000 { + compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart"; + reg = <0x30890000 0x10000>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_UART2_ROOT>, + <&clk IMX8MP_CLK_UART2_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + crypto: crypto@30900000 { + compatible = "fsl,sec-v4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x30900000 0x40000>; + ranges = <0 0x30900000 0x40000>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_AHB>, + <&clk IMX8MP_CLK_IPG_ROOT>; + clock-names = "aclk", "ipg"; + + sec_jr0: jr@1000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + }; + + sec_jr1: jr@2000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + }; + + sec_jr2: jr@3000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + i2c1: i2c@30a20000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a20000 0x10000>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C1_ROOT>; + status = "disabled"; + }; + + i2c2: i2c@30a30000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a30000 0x10000>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C2_ROOT>; + status = "disabled"; + }; + + i2c3: i2c@30a40000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a40000 0x10000>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C3_ROOT>; + status = "disabled"; + }; + + i2c4: i2c@30a50000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a50000 0x10000>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C4_ROOT>; + status = "disabled"; + }; + + uart4: serial@30a60000 { + compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart"; + reg = <0x30a60000 0x10000>; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_UART4_ROOT>, + <&clk IMX8MP_CLK_UART4_ROOT>; + clock-names = "ipg", "per"; + dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c5: i2c@30ad0000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30ad0000 0x10000>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C5_ROOT>; + status = "disabled"; + }; + + i2c6: i2c@30ae0000 { + compatible = "fsl,imx8mp-i2c", "fsl,imx21-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30ae0000 0x10000>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_I2C6_ROOT>; + status = "disabled"; + }; + + usdhc1: mmc@30b40000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b40000 0x10000>; + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_DUMMY>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC1_ROOT>; + clock-names = "ipg", "ahb", "per"; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; + bus-width = <4>; + status = "disabled"; + }; + + usdhc2: mmc@30b50000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b50000 0x10000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_DUMMY>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC2_ROOT>; + clock-names = "ipg", "ahb", "per"; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; + bus-width = <4>; + status = "disabled"; + }; + + usdhc3: mmc@30b60000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b60000 0x10000>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_DUMMY>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC3_ROOT>; + clock-names = "ipg", "ahb", "per"; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; + bus-width = <4>; + status = "disabled"; + }; + + sdma1: dma-controller@30bd0000 { + compatible = "fsl,imx8mp-sdma", "fsl,imx8mq-sdma"; + reg = <0x30bd0000 0x10000>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_SDMA1_ROOT>, + <&clk IMX8MP_CLK_SDMA1_ROOT>; + clock-names = "ipg", "ahb"; + #dma-cells = <3>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; + }; + + fec: ethernet@30be0000 { + compatible = "fsl,imx8mp-fec", "fsl,imx8mq-fec"; + reg = <0x30be0000 0x10000>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_ENET1_ROOT>, + <&clk IMX8MP_CLK_SIM_ENET_ROOT>, + <&clk IMX8MP_CLK_ENET_TIMER>, + <&clk IMX8MP_CLK_ENET_REF>, + <&clk IMX8MP_CLK_ENET_PHY_REF>; + clock-names = "ipg", "ahb", "ptp", + "enet_clk_ref", "enet_out"; + assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>, + <&clk IMX8MP_CLK_ENET_TIMER>, + <&clk IMX8MP_CLK_ENET_REF>, + <&clk IMX8MP_CLK_ENET_TIMER>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>, + <&clk IMX8MP_SYS_PLL2_100M>, + <&clk IMX8MP_SYS_PLL2_125M>; + assigned-clock-rates = <0>, <0>, <125000000>, <100000000>; + fsl,num-tx-queues = <3>; + fsl,num-rx-queues = <3>; + status = "disabled"; + }; + }; + + gic: interrupt-controller@38800000 { + compatible = "arm,gic-v3"; + reg = <0x38800000 0x10000>, + <0x38880000 0xc0000>; + #interrupt-cells = <3>; + interrupt-controller; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts index 94066d49d6ed..c9241abf0df3 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts @@ -137,6 +137,8 @@ pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; phy-handle = <ðphy0>; + phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + phy-reset-duration = <10>; fsl,magic-packet; status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts index 764a4cb4e125..10eca94194be 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts @@ -55,6 +55,15 @@ wakeup-source; linux,code = <KEY_HP>; }; + + wwan-wake { + label = "WWAN_WAKE"; + gpios = <&gpio3 8 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <8 GPIO_ACTIVE_LOW>; + wakeup-source; + linux,code = <KEY_PHONE>; + }; }; leds { @@ -148,6 +157,55 @@ regulator-always-on; }; + wwan_codec: sound-wwan-codec { + compatible = "option,gtm601"; + #sound-dai-cells = <0>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Speaker", "Speaker Ext", + "Line", "Line In Jack"; + simple-audio-card,routing = + "MIC_IN", "Microphone Jack", + "Microphone Jack", "Mic Bias", + "LINE_IN", "Line In Jack", + "Headphone Jack", "HP_OUT", + "Speaker Ext", "LINE_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + simple-audio-card,codec { + sound-dai = <&sgtl5000>; + clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; + frame-master; + bitclock-master; + }; + }; + + sound-wwan { + compatible = "simple-audio-card"; + simple-audio-card,name = "SIMCom SIM7100"; + simple-audio-card,format = "dsp_a"; + + simple-audio-card,cpu { + sound-dai = <&sai6>; + }; + + telephony_link_master: simple-audio-card,codec { + sound-dai = <&wwan_codec>; + frame-master; + bitclock-master; + }; + }; + vibrator { compatible = "gpio-vibrator"; pinctrl-names = "default"; @@ -169,6 +227,22 @@ }; }; +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + &clk { assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL2>; assigned-clock-rates = <786432000>, <722534400>; @@ -354,10 +428,10 @@ PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP )>; - sink-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM | + sink-pdos = <PDO_FIXED(5000, 3500, PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP ) - PDO_VAR(5000, 3000, 3000)>; + PDO_VAR(5000, 5000, 3500)>; op-sink-microwatt = <10000000>; ports { @@ -426,6 +500,19 @@ vddio-supply = <®_3v3_p>; }; + sgtl5000: audio-codec@a { + compatible = "fsl,sgtl5000"; + clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + #sound-dai-cells = <0>; + reg = <0x0a>; + VDDD-supply = <®_1v8_p>; + VDDIO-supply = <®_3v3_p>; + VDDA-supply = <®_3v3_p>; + }; + touchscreen@5d { compatible = "goodix,gt5688"; reg = <0x5d>; @@ -441,11 +528,20 @@ VDDIO-supply = <®_1v8_p>; }; + proximity-sensor@60 { + compatible = "vishay,vcnl4040"; + reg = <0x60>; + pinctrl-0 = <&pinctrl_prox>; + }; + accel-gyro@6a { compatible = "st,lsm9ds1-imu"; reg = <0x6a>; vdd-supply = <®_3v3_p>; vddio-supply = <®_3v3_p>; + mount-matrix = "1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; }; }; @@ -508,6 +604,7 @@ MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x16 MX8MQ_IOMUXC_SAI2_RXC_GPIO4_IO22 0x16 MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x180 /* HP_DET */ + MX8MQ_IOMUXC_NAND_DATA02_GPIO3_IO8 0x80 /* nWoWWAN */ >; }; @@ -543,6 +640,12 @@ >; }; + pinctrl_prox: proxgrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x80 /* prox intr */ + >; + }; + pinctrl_pwr_en: pwrengrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x06 @@ -555,6 +658,25 @@ >; }; + pinctrl_sai2: sai2grp { + fsl,pins = < + MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 + MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 + MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 + >; + }; + + pinctrl_sai6: sai6grp { + fsl,pins = < + MX8MQ_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC 0xd6 + MX8MQ_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK 0xd6 + MX8MQ_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0 0xd6 + >; + }; + pinctrl_typec: typecgrp { fsl,pins = < MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12 0x16 @@ -730,6 +852,25 @@ status = "okay"; }; +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + status = "okay"; +}; + +&sai6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai6>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI6>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + fsl,sai-synchronous-rx; + status = "okay"; +}; + &uart1 { /* console */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -750,6 +891,7 @@ }; &usb3_phy0 { + vbus-supply = <®_5v_p>; status = "okay"; }; @@ -808,7 +950,7 @@ bus-width = <4>; vmmc-supply = <®_usdhc2_vmmc>; power-supply = <&wifi_pwr_en>; - non-removable; + broken-cd; disable-wp; cap-sdio-irq; keep-power-in-suspend; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts b/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts index 3f2a489a4ad8..77ab568fae67 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts @@ -35,6 +35,16 @@ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + fan: gpio-fan { + compatible = "gpio-fan"; + gpio-fan,speed-map = <0 0 8600 1>; + gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>; + #cooling-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_fan>; + status = "okay"; + }; }; &A53_0 { @@ -53,6 +63,53 @@ cpu-supply = <&buck2>; }; +&cpu_thermal { + trips { + cpu_alert0: trip0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_alert1: trip1 { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_crit0: trip3 { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + + fan_toggle0: trip4 { + temperature = <65000>; + hysteresis = <10000>; + type = "active"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&A53_0 0 1>; /* Exclude highest OPP */ + }; + + map1 { + trip = <&cpu_alert1>; + cooling-device = + <&A53_0 0 2>; /* Exclude two highest OPPs */ + }; + + map4 { + trip = <&fan_toggle0>; + cooling-device = <&fan 0 1>; + }; + }; +}; + &i2c1 { clock-frequency = <400000>; pinctrl-names = "default"; @@ -201,6 +258,27 @@ }; }; +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + phy-reset-duration = <10>; + phy-reset-post-delay = <50>; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -254,6 +332,32 @@ }; &iomuxc { + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 + MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + >; + }; + + pinctrl_gpio_fan: gpiofangrp { + fsl,pins = < + MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5 0x16 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index 6a1e83922c71..75b384217a23 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -198,7 +198,7 @@ }; thermal-zones { - cpu-thermal { + cpu_thermal: cpu-thermal { polling-delay-passive = <250>; polling-delay = <2000>; thermal-sensors = <&tmu 0>; @@ -290,7 +290,8 @@ dma-ranges = <0x40000000 0x0 0x40000000 0xc0000000>; bus@30000000 { /* AIPS1 */ - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x301f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x30000000 0x30000000 0x400000>; @@ -521,7 +522,7 @@ status = "disabled"; }; - iomuxc: iomuxc@30330000 { + iomuxc: pinctrl@30330000 { compatible = "fsl,imx8mq-iomuxc"; reg = <0x30330000 0x10000>; }; @@ -574,6 +575,8 @@ compatible = "fsl,sec-v4.0-pwrkey"; regmap = <&snvs>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_SNVS_ROOT>; + clock-names = "snvs-pwrkey"; linux,keycode = <KEY_POWER>; wakeup-source; status = "disabled"; @@ -692,7 +695,8 @@ }; bus@30400000 { /* AIPS2 */ - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x305f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x30400000 0x30400000 0x400000>; @@ -751,7 +755,8 @@ }; bus@30800000 { /* AIPS3 */ - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x309f0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x30800000 0x30800000 0x400000>, @@ -1023,7 +1028,8 @@ }; bus@32c00000 { /* AIPS4 */ - compatible = "simple-bus"; + compatible = "fsl,aips-bus", "simple-bus"; + reg = <0x32df0000 0x10000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x32c00000 0x32c00000 0x400000>; diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi index fb5f752b15fe..e8ffb7590656 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi @@ -11,6 +11,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/pinctrl/pads-imx8qxp.h> +#include <dt-bindings/thermal/thermal.h> / { interrupt-parent = <&gic>; @@ -189,6 +190,11 @@ compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt"; timeout-sec = <60>; }; + + tsens: thermal-sensor { + compatible = "fsl,imx8qxp-sc-thermal", "fsl,imx-sc-thermal"; + #thermal-sensor-cells = <1>; + }; }; timer { @@ -586,4 +592,37 @@ #clock-cells = <1>; }; }; + + thermal_zones: thermal-zones { + cpu-thermal0 { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tsens IMX_SC_R_SYSTEM>; + + trips { + cpu_alert0: trip0 { + temperature = <107000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_crit0: trip1 { + temperature = <127000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A35_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A35_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/freescale/s32v234.dtsi b/arch/arm64/boot/dts/freescale/s32v234.dtsi index e746b9c48f7a..ba0b5305d481 100644 --- a/arch/arm64/boot/dts/freescale/s32v234.dtsi +++ b/arch/arm64/boot/dts/freescale/s32v234.dtsi @@ -104,7 +104,7 @@ interrupt-parent = <&gic>; ranges; - aips0: aips-bus@40000000 { + aips0: bus@40000000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -120,7 +120,7 @@ }; }; - aips1: aips-bus@40080000 { + aips1: bus@40080000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts index e794a12ba7c5..51d948323bfd 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts +++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts @@ -121,12 +121,12 @@ qspi_boot: partition@0 { label = "Boot and fpga data"; - reg = <0x0 0x034B0000>; + reg = <0x0 0x03FE0000>; }; - qspi_rootfs: partition@34B0000 { + qspi_rootfs: partition@3FE0000 { label = "Root Filesystem - JFFS2"; - reg = <0x034B0000 0x0EB50000>; + reg = <0x03FE0000 0x0C020000>; }; }; }; diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index f1b5127f0b89..3e5f2e7a040c 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -2,6 +2,9 @@ # Mvebu SoC Family dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-emmc.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-v7.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-v7-emmc.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-turris-mox.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-uDPU.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts index bd9ed9dc9c3e..ec72a11ed80f 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts @@ -11,6 +11,8 @@ * Schematic available at http://espressobin.net/wp-content/uploads/2017/08/ESPRESSObin_V5_Schematics.pdf */ +/dts-v1/; + #include "armada-3720-espressobin.dtsi" / { diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts index 6e876a6d9532..03733fd92732 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts @@ -11,6 +11,8 @@ * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200 */ +/dts-v1/; + #include "armada-3720-espressobin.dtsi" / { diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts index 0f8405d085fd..8570c5f47d7d 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts @@ -11,6 +11,8 @@ * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200 */ +/dts-v1/; + #include "armada-3720-espressobin.dtsi" / { diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi index 53b8ac55a7f3..42e992f9c8a5 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi @@ -7,12 +7,16 @@ * */ -/dts-v1/; - #include <dt-bindings/gpio/gpio.h> #include "armada-372x.dtsi" / { + aliases { + ethernet0 = ð0; + serial0 = &uart0; + serial1 = &uart1; + }; + chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts index a211a046b2f2..b90d78a5724b 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts @@ -367,6 +367,7 @@ pinctrl-0 = <&cp0_copper_eth_phy_reset>; reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; + reset-deassert-us = <10000>; }; switch0: switch0@4 { diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi index 572e2610e0a3..cbcb210cb6d8 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi @@ -71,6 +71,7 @@ tx-fault-gpio = <&cp1_gpio1 26 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp1_sfpp0_pins>; + maximum-power-milliwatt = <2000>; }; sfp_eth1: sfp-eth1 { @@ -83,6 +84,7 @@ tx-fault-gpio = <&cp0_gpio2 30 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp1_sfpp1_pins &cp0_sfpp1_pins>; + maximum-power-milliwatt = <2000>; }; sfp_eth3: sfp-eth3 { @@ -95,6 +97,7 @@ tx-fault-gpio = <&cp0_gpio2 19 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp0_sfp_1g_pins &cp1_sfp_1g_pins>; + maximum-power-milliwatt = <2000>; }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi index 09849558a776..fcab5173fe67 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi @@ -53,4 +53,9 @@ cache-sets = <512>; }; }; + + thermal-zones { + /delete-node/ ap-thermal-cpu2; + /delete-node/ ap-thermal-cpu3; + }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi index 840466e143b4..68782f161f12 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi @@ -17,7 +17,7 @@ cpu0: cpu@0 { device_type = "cpu"; - compatible = "arm,cortex-a72", "arm,armv8"; + compatible = "arm,cortex-a72"; reg = <0x000>; enable-method = "psci"; #cooling-cells = <2>; @@ -32,7 +32,7 @@ }; cpu1: cpu@1 { device_type = "cpu"; - compatible = "arm,cortex-a72", "arm,armv8"; + compatible = "arm,cortex-a72"; reg = <0x001>; enable-method = "psci"; #cooling-cells = <2>; @@ -47,7 +47,7 @@ }; cpu2: cpu@100 { device_type = "cpu"; - compatible = "arm,cortex-a72", "arm,armv8"; + compatible = "arm,cortex-a72"; reg = <0x100>; enable-method = "psci"; #cooling-cells = <2>; @@ -62,7 +62,7 @@ }; cpu3: cpu@101 { device_type = "cpu"; - compatible = "arm,cortex-a72", "arm,armv8"; + compatible = "arm,cortex-a72"; reg = <0x101>; enable-method = "psci"; #cooling-cells = <2>; diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 458bbc422a94..2f8967cb8717 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -8,3 +8,4 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi index 43307bad3f0d..2cd8b33886e5 100644 --- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi @@ -278,7 +278,7 @@ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt2712-scpsys", "syscon"; #power-domain-cells = <1>; reg = <0 0x10006000 0 0x1000>; @@ -303,6 +303,12 @@ status = "disabled"; }; + rtc: rtc@10011000 { + compatible = "mediatek,mt2712-rtc"; + reg = <0 0x10011000 0 0x1000>; + interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_LOW>; + }; + spis1: spi@10013000 { compatible = "mediatek,mt2712-spi-slave"; reg = <0 0x10013000 0 0x100>; diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi index 2b2a69c7567f..136ef9527a0d 100644 --- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi @@ -157,7 +157,7 @@ }; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt6797-scpsys"; #power-domain-cells = <1>; reg = <0 0x10006000 0 0x1000>; diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi index dac51e98204c..339dc9f88f43 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -230,7 +230,7 @@ #reset-cells = <1>; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt7622-scpsys", "syscon"; #power-domain-cells = <1>; diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 8b4e806d5119..ccb8e88a60c5 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -331,6 +331,7 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + arm,no-tick-in-suspend; }; soc { @@ -436,7 +437,7 @@ }; }; - scpsys: scpsys@10006000 { + scpsys: power-controller@10006000 { compatible = "mediatek,mt8173-scpsys"; #power-domain-cells = <1>; reg = <0 0x10006000 0 0x1000>; diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 124f9d3e09f5..97863adb7bc0 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -74,6 +74,9 @@ reg = <0x000>; enable-method = "psci"; capacity-dmips-mhz = <741>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <84>; + #cooling-cells = <2>; }; cpu1: cpu@1 { @@ -82,6 +85,9 @@ reg = <0x001>; enable-method = "psci"; capacity-dmips-mhz = <741>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <84>; + #cooling-cells = <2>; }; cpu2: cpu@2 { @@ -90,6 +96,9 @@ reg = <0x002>; enable-method = "psci"; capacity-dmips-mhz = <741>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <84>; + #cooling-cells = <2>; }; cpu3: cpu@3 { @@ -98,6 +107,9 @@ reg = <0x003>; enable-method = "psci"; capacity-dmips-mhz = <741>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <84>; + #cooling-cells = <2>; }; cpu4: cpu@100 { @@ -106,6 +118,9 @@ reg = <0x100>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <211>; + #cooling-cells = <2>; }; cpu5: cpu@101 { @@ -114,6 +129,9 @@ reg = <0x101>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <211>; + #cooling-cells = <2>; }; cpu6: cpu@102 { @@ -122,6 +140,9 @@ reg = <0x102>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <211>; + #cooling-cells = <2>; }; cpu7: cpu@103 { @@ -130,6 +151,31 @@ reg = <0x103>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <211>; + #cooling-cells = <2>; + }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP: cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x00010001>; + entry-latency-us = <200>; + exit-latency-us = <200>; + min-residency-us = <800>; + }; + + CLUSTER_SLEEP: cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x01010001>; + entry-latency-us = <250>; + exit-latency-us = <400>; + min-residency-us = <1300>; + }; }; }; @@ -255,6 +301,13 @@ #interrupt-cells = <2>; }; + watchdog: watchdog@10007000 { + compatible = "mediatek,mt8183-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; + #reset-cells = <1>; + }; + apmixedsys: syscon@1000c000 { compatible = "mediatek,mt8183-apmixedsys", "syscon"; reg = <0 0x1000c000 0 0x1000>; diff --git a/arch/arm64/boot/dts/mediatek/mt8516-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt8516-pinfunc.h new file mode 100644 index 000000000000..73339bb48f0d --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8516-pinfunc.h @@ -0,0 +1,663 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + */ +#ifndef __DTS_MT8516_PINFUNC_H +#define __DTS_MT8516_PINFUNC_H + +#include <dt-bindings/pinctrl/mt65xx.h> + +#define MT8516_PIN_0_EINT0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define MT8516_PIN_0_EINT0__FUNC_PWM_B (MTK_PIN_NO(0) | 1) +#define MT8516_PIN_0_EINT0__FUNC_I2S2_BCK (MTK_PIN_NO(0) | 3) +#define MT8516_PIN_0_EINT0__FUNC_EXT_TXD0 (MTK_PIN_NO(0) | 4) +#define MT8516_PIN_0_EINT0__FUNC_SQICS (MTK_PIN_NO(0) | 6) +#define MT8516_PIN_0_EINT0__FUNC_DBG_MON_A_6 (MTK_PIN_NO(0) | 7) + +#define MT8516_PIN_1_EINT1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define MT8516_PIN_1_EINT1__FUNC_PWM_C (MTK_PIN_NO(1) | 1) +#define MT8516_PIN_1_EINT1__FUNC_I2S2_DI (MTK_PIN_NO(1) | 3) +#define MT8516_PIN_1_EINT1__FUNC_EXT_TXD1 (MTK_PIN_NO(1) | 4) +#define MT8516_PIN_1_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(1) | 5) +#define MT8516_PIN_1_EINT1__FUNC_SQISO (MTK_PIN_NO(1) | 6) +#define MT8516_PIN_1_EINT1__FUNC_DBG_MON_A_7 (MTK_PIN_NO(1) | 7) + +#define MT8516_PIN_2_EINT2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define MT8516_PIN_2_EINT2__FUNC_CLKM0 (MTK_PIN_NO(2) | 1) +#define MT8516_PIN_2_EINT2__FUNC_I2S2_LRCK (MTK_PIN_NO(2) | 3) +#define MT8516_PIN_2_EINT2__FUNC_EXT_TXD2 (MTK_PIN_NO(2) | 4) +#define MT8516_PIN_2_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(2) | 5) +#define MT8516_PIN_2_EINT2__FUNC_SQISI (MTK_PIN_NO(2) | 6) +#define MT8516_PIN_2_EINT2__FUNC_DBG_MON_A_8 (MTK_PIN_NO(2) | 7) + +#define MT8516_PIN_3_EINT3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define MT8516_PIN_3_EINT3__FUNC_CLKM1 (MTK_PIN_NO(3) | 1) +#define MT8516_PIN_3_EINT3__FUNC_SPI_MI (MTK_PIN_NO(3) | 3) +#define MT8516_PIN_3_EINT3__FUNC_EXT_TXD3 (MTK_PIN_NO(3) | 4) +#define MT8516_PIN_3_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(3) | 5) +#define MT8516_PIN_3_EINT3__FUNC_SQIWP (MTK_PIN_NO(3) | 6) +#define MT8516_PIN_3_EINT3__FUNC_DBG_MON_A_9 (MTK_PIN_NO(3) | 7) + +#define MT8516_PIN_4_EINT4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define MT8516_PIN_4_EINT4__FUNC_CLKM2 (MTK_PIN_NO(4) | 1) +#define MT8516_PIN_4_EINT4__FUNC_SPI_MO (MTK_PIN_NO(4) | 3) +#define MT8516_PIN_4_EINT4__FUNC_EXT_TXC (MTK_PIN_NO(4) | 4) +#define MT8516_PIN_4_EINT4__FUNC_CONN_MCU_TCK (MTK_PIN_NO(4) | 5) +#define MT8516_PIN_4_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(4) | 6) +#define MT8516_PIN_4_EINT4__FUNC_DBG_MON_A_10 (MTK_PIN_NO(4) | 7) + +#define MT8516_PIN_5_EINT5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define MT8516_PIN_5_EINT5__FUNC_UCTS2 (MTK_PIN_NO(5) | 1) +#define MT8516_PIN_5_EINT5__FUNC_SPI_CSB (MTK_PIN_NO(5) | 3) +#define MT8516_PIN_5_EINT5__FUNC_EXT_RXER (MTK_PIN_NO(5) | 4) +#define MT8516_PIN_5_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(5) | 5) +#define MT8516_PIN_5_EINT5__FUNC_CONN_TEST_CK (MTK_PIN_NO(5) | 6) +#define MT8516_PIN_5_EINT5__FUNC_DBG_MON_A_11 (MTK_PIN_NO(5) | 7) + +#define MT8516_PIN_6_EINT6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define MT8516_PIN_6_EINT6__FUNC_URTS2 (MTK_PIN_NO(6) | 1) +#define MT8516_PIN_6_EINT6__FUNC_SPI_CLK (MTK_PIN_NO(6) | 3) +#define MT8516_PIN_6_EINT6__FUNC_EXT_RXC (MTK_PIN_NO(6) | 4) +#define MT8516_PIN_6_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(6) | 5) +#define MT8516_PIN_6_EINT6__FUNC_DBG_MON_A_12 (MTK_PIN_NO(6) | 7) + +#define MT8516_PIN_7_EINT7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define MT8516_PIN_7_EINT7__FUNC_SQIRST (MTK_PIN_NO(7) | 1) +#define MT8516_PIN_7_EINT7__FUNC_SDA1_0 (MTK_PIN_NO(7) | 3) +#define MT8516_PIN_7_EINT7__FUNC_EXT_RXDV (MTK_PIN_NO(7) | 4) +#define MT8516_PIN_7_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(7) | 5) +#define MT8516_PIN_7_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(7) | 6) +#define MT8516_PIN_7_EINT7__FUNC_DBG_MON_A_13 (MTK_PIN_NO(7) | 7) + +#define MT8516_PIN_8_EINT8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define MT8516_PIN_8_EINT8__FUNC_SQICK (MTK_PIN_NO(8) | 1) +#define MT8516_PIN_8_EINT8__FUNC_CLKM3 (MTK_PIN_NO(8) | 2) +#define MT8516_PIN_8_EINT8__FUNC_SCL1_0 (MTK_PIN_NO(8) | 3) +#define MT8516_PIN_8_EINT8__FUNC_EXT_RXD0 (MTK_PIN_NO(8) | 4) +#define MT8516_PIN_8_EINT8__FUNC_ANT_SEL0 (MTK_PIN_NO(8) | 5) +#define MT8516_PIN_8_EINT8__FUNC_DBG_MON_A_14 (MTK_PIN_NO(8) | 7) + +#define MT8516_PIN_9_EINT9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define MT8516_PIN_9_EINT9__FUNC_CLKM4 (MTK_PIN_NO(9) | 1) +#define MT8516_PIN_9_EINT9__FUNC_SDA2_0 (MTK_PIN_NO(9) | 2) +#define MT8516_PIN_9_EINT9__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(9) | 3) +#define MT8516_PIN_9_EINT9__FUNC_EXT_RXD1 (MTK_PIN_NO(9) | 4) +#define MT8516_PIN_9_EINT9__FUNC_ANT_SEL1 (MTK_PIN_NO(9) | 5) +#define MT8516_PIN_9_EINT9__FUNC_DBG_MON_A_15 (MTK_PIN_NO(9) | 7) + +#define MT8516_PIN_10_EINT10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define MT8516_PIN_10_EINT10__FUNC_CLKM5 (MTK_PIN_NO(10) | 1) +#define MT8516_PIN_10_EINT10__FUNC_SCL2_0 (MTK_PIN_NO(10) | 2) +#define MT8516_PIN_10_EINT10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(10) | 3) +#define MT8516_PIN_10_EINT10__FUNC_EXT_RXD2 (MTK_PIN_NO(10) | 4) +#define MT8516_PIN_10_EINT10__FUNC_ANT_SEL2 (MTK_PIN_NO(10) | 5) +#define MT8516_PIN_10_EINT10__FUNC_DBG_MON_A_16 (MTK_PIN_NO(10) | 7) + +#define MT8516_PIN_11_EINT11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define MT8516_PIN_11_EINT11__FUNC_CLKM4 (MTK_PIN_NO(11) | 1) +#define MT8516_PIN_11_EINT11__FUNC_PWM_C (MTK_PIN_NO(11) | 2) +#define MT8516_PIN_11_EINT11__FUNC_CONN_TEST_CK (MTK_PIN_NO(11) | 3) +#define MT8516_PIN_11_EINT11__FUNC_ANT_SEL3 (MTK_PIN_NO(11) | 4) +#define MT8516_PIN_11_EINT11__FUNC_EXT_RXD3 (MTK_PIN_NO(11) | 6) +#define MT8516_PIN_11_EINT11__FUNC_DBG_MON_A_17 (MTK_PIN_NO(11) | 7) + +#define MT8516_PIN_12_EINT12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define MT8516_PIN_12_EINT12__FUNC_CLKM5 (MTK_PIN_NO(12) | 1) +#define MT8516_PIN_12_EINT12__FUNC_PWM_A (MTK_PIN_NO(12) | 2) +#define MT8516_PIN_12_EINT12__FUNC_SPDIF_OUT (MTK_PIN_NO(12) | 3) +#define MT8516_PIN_12_EINT12__FUNC_ANT_SEL4 (MTK_PIN_NO(12) | 4) +#define MT8516_PIN_12_EINT12__FUNC_EXT_TXEN (MTK_PIN_NO(12) | 6) +#define MT8516_PIN_12_EINT12__FUNC_DBG_MON_A_18 (MTK_PIN_NO(12) | 7) + +#define MT8516_PIN_13_EINT13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define MT8516_PIN_13_EINT13__FUNC_TSF_IN (MTK_PIN_NO(13) | 3) +#define MT8516_PIN_13_EINT13__FUNC_ANT_SEL5 (MTK_PIN_NO(13) | 4) +#define MT8516_PIN_13_EINT13__FUNC_SPDIF_IN (MTK_PIN_NO(13) | 6) +#define MT8516_PIN_13_EINT13__FUNC_DBG_MON_A_19 (MTK_PIN_NO(13) | 7) + +#define MT8516_PIN_14_EINT14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define MT8516_PIN_14_EINT14__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(14) | 2) +#define MT8516_PIN_14_EINT14__FUNC_TDM_RX_MCK (MTK_PIN_NO(14) | 3) +#define MT8516_PIN_14_EINT14__FUNC_ANT_SEL1 (MTK_PIN_NO(14) | 4) +#define MT8516_PIN_14_EINT14__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(14) | 5) +#define MT8516_PIN_14_EINT14__FUNC_NCLE (MTK_PIN_NO(14) | 6) +#define MT8516_PIN_14_EINT14__FUNC_DBG_MON_B_8 (MTK_PIN_NO(14) | 7) + +#define MT8516_PIN_15_EINT15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define MT8516_PIN_15_EINT15__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(15) | 2) +#define MT8516_PIN_15_EINT15__FUNC_TDM_RX_BCK (MTK_PIN_NO(15) | 3) +#define MT8516_PIN_15_EINT15__FUNC_ANT_SEL2 (MTK_PIN_NO(15) | 4) +#define MT8516_PIN_15_EINT15__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(15) | 5) +#define MT8516_PIN_15_EINT15__FUNC_NCEB1 (MTK_PIN_NO(15) | 6) +#define MT8516_PIN_15_EINT15__FUNC_DBG_MON_B_9 (MTK_PIN_NO(15) | 7) + +#define MT8516_PIN_16_EINT16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define MT8516_PIN_16_EINT16__FUNC_I2S_8CH_BCK (MTK_PIN_NO(16) | 2) +#define MT8516_PIN_16_EINT16__FUNC_TDM_RX_LRCK (MTK_PIN_NO(16) | 3) +#define MT8516_PIN_16_EINT16__FUNC_ANT_SEL3 (MTK_PIN_NO(16) | 4) +#define MT8516_PIN_16_EINT16__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(16) | 5) +#define MT8516_PIN_16_EINT16__FUNC_NCEB0 (MTK_PIN_NO(16) | 6) +#define MT8516_PIN_16_EINT16__FUNC_DBG_MON_B_10 (MTK_PIN_NO(16) | 7) + +#define MT8516_PIN_17_EINT17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define MT8516_PIN_17_EINT17__FUNC_I2S_8CH_MCK (MTK_PIN_NO(17) | 2) +#define MT8516_PIN_17_EINT17__FUNC_TDM_RX_DI (MTK_PIN_NO(17) | 3) +#define MT8516_PIN_17_EINT17__FUNC_IDDIG (MTK_PIN_NO(17) | 4) +#define MT8516_PIN_17_EINT17__FUNC_ANT_SEL4 (MTK_PIN_NO(17) | 5) +#define MT8516_PIN_17_EINT17__FUNC_NREB (MTK_PIN_NO(17) | 6) +#define MT8516_PIN_17_EINT17__FUNC_DBG_MON_B_11 (MTK_PIN_NO(17) | 7) + +#define MT8516_PIN_18_EINT18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define MT8516_PIN_18_EINT18__FUNC_USB_DRVVBUS (MTK_PIN_NO(18) | 2) +#define MT8516_PIN_18_EINT18__FUNC_I2S3_LRCK (MTK_PIN_NO(18) | 3) +#define MT8516_PIN_18_EINT18__FUNC_CLKM1 (MTK_PIN_NO(18) | 4) +#define MT8516_PIN_18_EINT18__FUNC_ANT_SEL3 (MTK_PIN_NO(18) | 5) +#define MT8516_PIN_18_EINT18__FUNC_I2S2_BCK (MTK_PIN_NO(18) | 6) +#define MT8516_PIN_18_EINT18__FUNC_DBG_MON_A_20 (MTK_PIN_NO(18) | 7) + +#define MT8516_PIN_19_EINT19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define MT8516_PIN_19_EINT19__FUNC_UCTS1 (MTK_PIN_NO(19) | 1) +#define MT8516_PIN_19_EINT19__FUNC_IDDIG (MTK_PIN_NO(19) | 2) +#define MT8516_PIN_19_EINT19__FUNC_I2S3_BCK (MTK_PIN_NO(19) | 3) +#define MT8516_PIN_19_EINT19__FUNC_CLKM2 (MTK_PIN_NO(19) | 4) +#define MT8516_PIN_19_EINT19__FUNC_ANT_SEL4 (MTK_PIN_NO(19) | 5) +#define MT8516_PIN_19_EINT19__FUNC_I2S2_DI (MTK_PIN_NO(19) | 6) +#define MT8516_PIN_19_EINT19__FUNC_DBG_MON_A_21 (MTK_PIN_NO(19) | 7) + +#define MT8516_PIN_20_EINT20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define MT8516_PIN_20_EINT20__FUNC_URTS1 (MTK_PIN_NO(20) | 1) +#define MT8516_PIN_20_EINT20__FUNC_I2S3_DO (MTK_PIN_NO(20) | 3) +#define MT8516_PIN_20_EINT20__FUNC_CLKM3 (MTK_PIN_NO(20) | 4) +#define MT8516_PIN_20_EINT20__FUNC_ANT_SEL5 (MTK_PIN_NO(20) | 5) +#define MT8516_PIN_20_EINT20__FUNC_I2S2_LRCK (MTK_PIN_NO(20) | 6) +#define MT8516_PIN_20_EINT20__FUNC_DBG_MON_A_22 (MTK_PIN_NO(20) | 7) + +#define MT8516_PIN_21_EINT21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define MT8516_PIN_21_EINT21__FUNC_NRNB (MTK_PIN_NO(21) | 1) +#define MT8516_PIN_21_EINT21__FUNC_ANT_SEL0 (MTK_PIN_NO(21) | 2) +#define MT8516_PIN_21_EINT21__FUNC_I2S_8CH_DO4 (MTK_PIN_NO(21) | 3) +#define MT8516_PIN_21_EINT21__FUNC_DBG_MON_B_31 (MTK_PIN_NO(21) | 7) + +#define MT8516_PIN_22_EINT22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define MT8516_PIN_22_EINT22__FUNC_I2S_8CH_DO2 (MTK_PIN_NO(22) | 2) +#define MT8516_PIN_22_EINT22__FUNC_TSF_IN (MTK_PIN_NO(22) | 3) +#define MT8516_PIN_22_EINT22__FUNC_USB_DRVVBUS (MTK_PIN_NO(22) | 4) +#define MT8516_PIN_22_EINT22__FUNC_SPDIF_OUT (MTK_PIN_NO(22) | 5) +#define MT8516_PIN_22_EINT22__FUNC_NRE_C (MTK_PIN_NO(22) | 6) +#define MT8516_PIN_22_EINT22__FUNC_DBG_MON_B_12 (MTK_PIN_NO(22) | 7) + +#define MT8516_PIN_23_EINT23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define MT8516_PIN_23_EINT23__FUNC_I2S_8CH_DO3 (MTK_PIN_NO(23) | 2) +#define MT8516_PIN_23_EINT23__FUNC_CLKM0 (MTK_PIN_NO(23) | 3) +#define MT8516_PIN_23_EINT23__FUNC_IR (MTK_PIN_NO(23) | 4) +#define MT8516_PIN_23_EINT23__FUNC_SPDIF_IN (MTK_PIN_NO(23) | 5) +#define MT8516_PIN_23_EINT23__FUNC_NDQS_C (MTK_PIN_NO(23) | 6) +#define MT8516_PIN_23_EINT23__FUNC_DBG_MON_B_13 (MTK_PIN_NO(23) | 7) + +#define MT8516_PIN_24_EINT24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define MT8516_PIN_24_EINT24__FUNC_ANT_SEL1 (MTK_PIN_NO(24) | 3) +#define MT8516_PIN_24_EINT24__FUNC_UCTS2 (MTK_PIN_NO(24) | 4) +#define MT8516_PIN_24_EINT24__FUNC_PWM_A (MTK_PIN_NO(24) | 5) +#define MT8516_PIN_24_EINT24__FUNC_I2S0_MCK (MTK_PIN_NO(24) | 6) +#define MT8516_PIN_24_EINT24__FUNC_DBG_MON_A_0 (MTK_PIN_NO(24) | 7) + +#define MT8516_PIN_25_EINT25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define MT8516_PIN_25_EINT25__FUNC_ANT_SEL0 (MTK_PIN_NO(25) | 3) +#define MT8516_PIN_25_EINT25__FUNC_URTS2 (MTK_PIN_NO(25) | 4) +#define MT8516_PIN_25_EINT25__FUNC_PWM_B (MTK_PIN_NO(25) | 5) +#define MT8516_PIN_25_EINT25__FUNC_I2S_8CH_MCK (MTK_PIN_NO(25) | 6) +#define MT8516_PIN_25_EINT25__FUNC_DBG_MON_A_1 (MTK_PIN_NO(25) | 7) + +#define MT8516_PIN_26_PWRAP_SPI0_MI__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define MT8516_PIN_26_PWRAP_SPI0_MI__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(26) | 1) +#define MT8516_PIN_26_PWRAP_SPI0_MI__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(26) | 2) + +#define MT8516_PIN_27_PWRAP_SPI0_MO__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define MT8516_PIN_27_PWRAP_SPI0_MO__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(27) | 1) +#define MT8516_PIN_27_PWRAP_SPI0_MO__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(27) | 2) + +#define MT8516_PIN_28_PWRAP_INT__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define MT8516_PIN_28_PWRAP_INT__FUNC_I2S0_MCK (MTK_PIN_NO(28) | 1) +#define MT8516_PIN_28_PWRAP_INT__FUNC_I2S_8CH_MCK (MTK_PIN_NO(28) | 4) +#define MT8516_PIN_28_PWRAP_INT__FUNC_I2S2_MCK (MTK_PIN_NO(28) | 5) +#define MT8516_PIN_28_PWRAP_INT__FUNC_I2S3_MCK (MTK_PIN_NO(28) | 6) + +#define MT8516_PIN_29_PWRAP_SPI0_CK__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define MT8516_PIN_29_PWRAP_SPI0_CK__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(29) | 1) + +#define MT8516_PIN_30_PWRAP_SPI0_CSN__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define MT8516_PIN_30_PWRAP_SPI0_CSN__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(30) | 1) + +#define MT8516_PIN_31_RTC32K_CK__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define MT8516_PIN_31_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(31) | 1) + +#define MT8516_PIN_32_WATCHDOG__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define MT8516_PIN_32_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(32) | 1) + +#define MT8516_PIN_33_SRCLKENA__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define MT8516_PIN_33_SRCLKENA__FUNC_SRCLKENA0 (MTK_PIN_NO(33) | 1) + +#define MT8516_PIN_34_URXD2__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define MT8516_PIN_34_URXD2__FUNC_URXD2 (MTK_PIN_NO(34) | 1) +#define MT8516_PIN_34_URXD2__FUNC_UTXD2 (MTK_PIN_NO(34) | 3) +#define MT8516_PIN_34_URXD2__FUNC_DBG_SCL (MTK_PIN_NO(34) | 4) +#define MT8516_PIN_34_URXD2__FUNC_I2S2_MCK (MTK_PIN_NO(34) | 6) +#define MT8516_PIN_34_URXD2__FUNC_DBG_MON_B_0 (MTK_PIN_NO(34) | 7) + +#define MT8516_PIN_35_UTXD2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define MT8516_PIN_35_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(35) | 1) +#define MT8516_PIN_35_UTXD2__FUNC_URXD2 (MTK_PIN_NO(35) | 3) +#define MT8516_PIN_35_UTXD2__FUNC_DBG_SDA (MTK_PIN_NO(35) | 4) +#define MT8516_PIN_35_UTXD2__FUNC_I2S3_MCK (MTK_PIN_NO(35) | 6) +#define MT8516_PIN_35_UTXD2__FUNC_DBG_MON_B_1 (MTK_PIN_NO(35) | 7) + +#define MT8516_PIN_36_MRG_CLK__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define MT8516_PIN_36_MRG_CLK__FUNC_MRG_CLK (MTK_PIN_NO(36) | 1) +#define MT8516_PIN_36_MRG_CLK__FUNC_I2S0_BCK (MTK_PIN_NO(36) | 3) +#define MT8516_PIN_36_MRG_CLK__FUNC_I2S3_BCK (MTK_PIN_NO(36) | 4) +#define MT8516_PIN_36_MRG_CLK__FUNC_PCM0_CLK (MTK_PIN_NO(36) | 5) +#define MT8516_PIN_36_MRG_CLK__FUNC_IR (MTK_PIN_NO(36) | 6) +#define MT8516_PIN_36_MRG_CLK__FUNC_DBG_MON_A_2 (MTK_PIN_NO(36) | 7) + +#define MT8516_PIN_37_MRG_SYNC__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define MT8516_PIN_37_MRG_SYNC__FUNC_MRG_SYNC (MTK_PIN_NO(37) | 1) +#define MT8516_PIN_37_MRG_SYNC__FUNC_I2S0_LRCK (MTK_PIN_NO(37) | 3) +#define MT8516_PIN_37_MRG_SYNC__FUNC_I2S3_LRCK (MTK_PIN_NO(37) | 4) +#define MT8516_PIN_37_MRG_SYNC__FUNC_PCM0_SYNC (MTK_PIN_NO(37) | 5) +#define MT8516_PIN_37_MRG_SYNC__FUNC_EXT_COL (MTK_PIN_NO(37) | 6) +#define MT8516_PIN_37_MRG_SYNC__FUNC_DBG_MON_A_3 (MTK_PIN_NO(37) | 7) + +#define MT8516_PIN_38_MRG_DI__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define MT8516_PIN_38_MRG_DI__FUNC_MRG_DI (MTK_PIN_NO(38) | 1) +#define MT8516_PIN_38_MRG_DI__FUNC_I2S0_DI (MTK_PIN_NO(38) | 3) +#define MT8516_PIN_38_MRG_DI__FUNC_I2S3_DO (MTK_PIN_NO(38) | 4) +#define MT8516_PIN_38_MRG_DI__FUNC_PCM0_DI (MTK_PIN_NO(38) | 5) +#define MT8516_PIN_38_MRG_DI__FUNC_EXT_MDIO (MTK_PIN_NO(38) | 6) +#define MT8516_PIN_38_MRG_DI__FUNC_DBG_MON_A_4 (MTK_PIN_NO(38) | 7) + +#define MT8516_PIN_39_MRG_DO__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define MT8516_PIN_39_MRG_DO__FUNC_MRG_DO (MTK_PIN_NO(39) | 1) +#define MT8516_PIN_39_MRG_DO__FUNC_I2S0_MCK (MTK_PIN_NO(39) | 3) +#define MT8516_PIN_39_MRG_DO__FUNC_I2S3_MCK (MTK_PIN_NO(39) | 4) +#define MT8516_PIN_39_MRG_DO__FUNC_PCM0_DO (MTK_PIN_NO(39) | 5) +#define MT8516_PIN_39_MRG_DO__FUNC_EXT_MDC (MTK_PIN_NO(39) | 6) +#define MT8516_PIN_39_MRG_DO__FUNC_DBG_MON_A_5 (MTK_PIN_NO(39) | 7) + +#define MT8516_PIN_40_KPROW0__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define MT8516_PIN_40_KPROW0__FUNC_KPROW0 (MTK_PIN_NO(40) | 1) +#define MT8516_PIN_40_KPROW0__FUNC_DBG_MON_B_4 (MTK_PIN_NO(40) | 7) + +#define MT8516_PIN_41_KPROW1__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define MT8516_PIN_41_KPROW1__FUNC_KPROW1 (MTK_PIN_NO(41) | 1) +#define MT8516_PIN_41_KPROW1__FUNC_IDDIG (MTK_PIN_NO(41) | 2) +#define MT8516_PIN_41_KPROW1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(41) | 3) +#define MT8516_PIN_41_KPROW1__FUNC_DBG_MON_B_5 (MTK_PIN_NO(41) | 7) + +#define MT8516_PIN_42_KPCOL0__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define MT8516_PIN_42_KPCOL0__FUNC_KPCOL0 (MTK_PIN_NO(42) | 1) +#define MT8516_PIN_42_KPCOL0__FUNC_DBG_MON_B_6 (MTK_PIN_NO(42) | 7) + +#define MT8516_PIN_43_KPCOL1__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define MT8516_PIN_43_KPCOL1__FUNC_KPCOL1 (MTK_PIN_NO(43) | 1) +#define MT8516_PIN_43_KPCOL1__FUNC_USB_DRVVBUS (MTK_PIN_NO(43) | 2) +#define MT8516_PIN_43_KPCOL1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(43) | 3) +#define MT8516_PIN_43_KPCOL1__FUNC_TSF_IN (MTK_PIN_NO(43) | 4) +#define MT8516_PIN_43_KPCOL1__FUNC_DBG_MON_B_7 (MTK_PIN_NO(43) | 7) + +#define MT8516_PIN_44_JTMS__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define MT8516_PIN_44_JTMS__FUNC_JTMS (MTK_PIN_NO(44) | 1) +#define MT8516_PIN_44_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(44) | 2) +#define MT8516_PIN_44_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(44) | 3) +#define MT8516_PIN_44_JTMS__FUNC_DFD_TMS_XI (MTK_PIN_NO(44) | 5) +#define MT8516_PIN_44_JTMS__FUNC_UDI_TMS_XI (MTK_PIN_NO(44) | 6) + +#define MT8516_PIN_45_JTCK__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define MT8516_PIN_45_JTCK__FUNC_JTCK (MTK_PIN_NO(45) | 1) +#define MT8516_PIN_45_JTCK__FUNC_CONN_MCU_TCK (MTK_PIN_NO(45) | 2) +#define MT8516_PIN_45_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(45) | 3) + +#define MT8516_PIN_46_JTDI__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define MT8516_PIN_46_JTDI__FUNC_JTDI (MTK_PIN_NO(46) | 1) +#define MT8516_PIN_46_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(46) | 2) + +#define MT8516_PIN_47_JTDO__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define MT8516_PIN_47_JTDO__FUNC_JTDO (MTK_PIN_NO(47) | 1) +#define MT8516_PIN_47_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(47) | 2) + +#define MT8516_PIN_48_SPI_CS__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define MT8516_PIN_48_SPI_CS__FUNC_SPI_CSB (MTK_PIN_NO(48) | 1) +#define MT8516_PIN_48_SPI_CS__FUNC_I2S0_DI (MTK_PIN_NO(48) | 3) +#define MT8516_PIN_48_SPI_CS__FUNC_I2S2_BCK (MTK_PIN_NO(48) | 4) +#define MT8516_PIN_48_SPI_CS__FUNC_DBG_MON_A_23 (MTK_PIN_NO(48) | 7) + +#define MT8516_PIN_49_SPI_CK__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define MT8516_PIN_49_SPI_CK__FUNC_SPI_CLK (MTK_PIN_NO(49) | 1) +#define MT8516_PIN_49_SPI_CK__FUNC_I2S0_LRCK (MTK_PIN_NO(49) | 3) +#define MT8516_PIN_49_SPI_CK__FUNC_I2S2_DI (MTK_PIN_NO(49) | 4) +#define MT8516_PIN_49_SPI_CK__FUNC_DBG_MON_A_24 (MTK_PIN_NO(49) | 7) + +#define MT8516_PIN_50_SPI_MI__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define MT8516_PIN_50_SPI_MI__FUNC_SPI_MI (MTK_PIN_NO(50) | 1) +#define MT8516_PIN_50_SPI_MI__FUNC_SPI_MO (MTK_PIN_NO(50) | 2) +#define MT8516_PIN_50_SPI_MI__FUNC_I2S0_BCK (MTK_PIN_NO(50) | 3) +#define MT8516_PIN_50_SPI_MI__FUNC_I2S2_LRCK (MTK_PIN_NO(50) | 4) +#define MT8516_PIN_50_SPI_MI__FUNC_DBG_MON_A_25 (MTK_PIN_NO(50) | 7) + +#define MT8516_PIN_51_SPI_MO__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define MT8516_PIN_51_SPI_MO__FUNC_SPI_MO (MTK_PIN_NO(51) | 1) +#define MT8516_PIN_51_SPI_MO__FUNC_SPI_MI (MTK_PIN_NO(51) | 2) +#define MT8516_PIN_51_SPI_MO__FUNC_I2S0_MCK (MTK_PIN_NO(51) | 3) +#define MT8516_PIN_51_SPI_MO__FUNC_I2S2_MCK (MTK_PIN_NO(51) | 4) +#define MT8516_PIN_51_SPI_MO__FUNC_DBG_MON_A_26 (MTK_PIN_NO(51) | 7) + +#define MT8516_PIN_52_SDA1__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define MT8516_PIN_52_SDA1__FUNC_SDA1_0 (MTK_PIN_NO(52) | 1) + +#define MT8516_PIN_53_SCL1__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define MT8516_PIN_53_SCL1__FUNC_SCL1_0 (MTK_PIN_NO(53) | 1) + +#define MT8516_PIN_54_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define MT8516_PIN_54_GPIO54__FUNC_PWM_B (MTK_PIN_NO(54) | 2) +#define MT8516_PIN_54_GPIO54__FUNC_DBG_MON_B_2 (MTK_PIN_NO(54) | 7) + +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_I2S0_DI (MTK_PIN_NO(55) | 1) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_UCTS0 (MTK_PIN_NO(55) | 2) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_I2S3_DO (MTK_PIN_NO(55) | 3) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(55) | 4) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_PWM_A (MTK_PIN_NO(55) | 5) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_I2S2_BCK (MTK_PIN_NO(55) | 6) +#define MT8516_PIN_55_I2S_DATA_IN__FUNC_DBG_MON_A_28 (MTK_PIN_NO(55) | 7) + +#define MT8516_PIN_56_I2S_LRCK__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define MT8516_PIN_56_I2S_LRCK__FUNC_I2S0_LRCK (MTK_PIN_NO(56) | 1) +#define MT8516_PIN_56_I2S_LRCK__FUNC_I2S3_LRCK (MTK_PIN_NO(56) | 3) +#define MT8516_PIN_56_I2S_LRCK__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(56) | 4) +#define MT8516_PIN_56_I2S_LRCK__FUNC_PWM_B (MTK_PIN_NO(56) | 5) +#define MT8516_PIN_56_I2S_LRCK__FUNC_I2S2_DI (MTK_PIN_NO(56) | 6) +#define MT8516_PIN_56_I2S_LRCK__FUNC_DBG_MON_A_29 (MTK_PIN_NO(56) | 7) + +#define MT8516_PIN_57_I2S_BCK__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT8516_PIN_57_I2S_BCK__FUNC_I2S0_BCK (MTK_PIN_NO(57) | 1) +#define MT8516_PIN_57_I2S_BCK__FUNC_URTS0 (MTK_PIN_NO(57) | 2) +#define MT8516_PIN_57_I2S_BCK__FUNC_I2S3_BCK (MTK_PIN_NO(57) | 3) +#define MT8516_PIN_57_I2S_BCK__FUNC_I2S_8CH_BCK (MTK_PIN_NO(57) | 4) +#define MT8516_PIN_57_I2S_BCK__FUNC_PWM_C (MTK_PIN_NO(57) | 5) +#define MT8516_PIN_57_I2S_BCK__FUNC_I2S2_LRCK (MTK_PIN_NO(57) | 6) +#define MT8516_PIN_57_I2S_BCK__FUNC_DBG_MON_A_30 (MTK_PIN_NO(57) | 7) + +#define MT8516_PIN_58_SDA0__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT8516_PIN_58_SDA0__FUNC_SDA0_0 (MTK_PIN_NO(58) | 1) + +#define MT8516_PIN_59_SCL0__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define MT8516_PIN_59_SCL0__FUNC_SCL0_0 (MTK_PIN_NO(59) | 1) + +#define MT8516_PIN_60_SDA2__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define MT8516_PIN_60_SDA2__FUNC_SDA2_0 (MTK_PIN_NO(60) | 1) +#define MT8516_PIN_60_SDA2__FUNC_PWM_B (MTK_PIN_NO(60) | 2) + +#define MT8516_PIN_61_SCL2__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define MT8516_PIN_61_SCL2__FUNC_SCL2_0 (MTK_PIN_NO(61) | 1) +#define MT8516_PIN_61_SCL2__FUNC_PWM_C (MTK_PIN_NO(61) | 2) + +#define MT8516_PIN_62_URXD0__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define MT8516_PIN_62_URXD0__FUNC_URXD0 (MTK_PIN_NO(62) | 1) +#define MT8516_PIN_62_URXD0__FUNC_UTXD0 (MTK_PIN_NO(62) | 2) + +#define MT8516_PIN_63_UTXD0__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define MT8516_PIN_63_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(63) | 1) +#define MT8516_PIN_63_UTXD0__FUNC_URXD0 (MTK_PIN_NO(63) | 2) + +#define MT8516_PIN_64_URXD1__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define MT8516_PIN_64_URXD1__FUNC_URXD1 (MTK_PIN_NO(64) | 1) +#define MT8516_PIN_64_URXD1__FUNC_UTXD1 (MTK_PIN_NO(64) | 2) +#define MT8516_PIN_64_URXD1__FUNC_DBG_MON_A_27 (MTK_PIN_NO(64) | 7) + +#define MT8516_PIN_65_UTXD1__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define MT8516_PIN_65_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(65) | 1) +#define MT8516_PIN_65_UTXD1__FUNC_URXD1 (MTK_PIN_NO(65) | 2) +#define MT8516_PIN_65_UTXD1__FUNC_DBG_MON_A_31 (MTK_PIN_NO(65) | 7) + +#define MT8516_PIN_68_MSDC2_CMD__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(68) | 1) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_I2S_8CH_DO4 (MTK_PIN_NO(68) | 2) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_SDA1_0 (MTK_PIN_NO(68) | 3) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_USB_SDA (MTK_PIN_NO(68) | 5) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_I2S3_BCK (MTK_PIN_NO(68) | 6) +#define MT8516_PIN_68_MSDC2_CMD__FUNC_DBG_MON_B_15 (MTK_PIN_NO(68) | 7) + +#define MT8516_PIN_69_MSDC2_CLK__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(69) | 1) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_I2S_8CH_DO3 (MTK_PIN_NO(69) | 2) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_SCL1_0 (MTK_PIN_NO(69) | 3) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_USB_SCL (MTK_PIN_NO(69) | 5) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_I2S3_LRCK (MTK_PIN_NO(69) | 6) +#define MT8516_PIN_69_MSDC2_CLK__FUNC_DBG_MON_B_16 (MTK_PIN_NO(69) | 7) + +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(70) | 1) +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_I2S_8CH_DO2 (MTK_PIN_NO(70) | 2) +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_UTXD0 (MTK_PIN_NO(70) | 5) +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_I2S3_DO (MTK_PIN_NO(70) | 6) +#define MT8516_PIN_70_MSDC2_DAT0__FUNC_DBG_MON_B_17 (MTK_PIN_NO(70) | 7) + +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(71) | 1) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(71) | 2) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_PWM_A (MTK_PIN_NO(71) | 3) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_I2S3_MCK (MTK_PIN_NO(71) | 4) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_URXD0 (MTK_PIN_NO(71) | 5) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_PWM_B (MTK_PIN_NO(71) | 6) +#define MT8516_PIN_71_MSDC2_DAT1__FUNC_DBG_MON_B_18 (MTK_PIN_NO(71) | 7) + +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(72) | 1) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(72) | 2) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_SDA2_0 (MTK_PIN_NO(72) | 3) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_UTXD1 (MTK_PIN_NO(72) | 5) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_PWM_C (MTK_PIN_NO(72) | 6) +#define MT8516_PIN_72_MSDC2_DAT2__FUNC_DBG_MON_B_19 (MTK_PIN_NO(72) | 7) + +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(73) | 1) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_I2S_8CH_BCK (MTK_PIN_NO(73) | 2) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_SCL2_0 (MTK_PIN_NO(73) | 3) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(73) | 4) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_URXD1 (MTK_PIN_NO(73) | 5) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_PWM_A (MTK_PIN_NO(73) | 6) +#define MT8516_PIN_73_MSDC2_DAT3__FUNC_DBG_MON_B_20 (MTK_PIN_NO(73) | 7) + +#define MT8516_PIN_74_TDN3__FUNC_GPI74 (MTK_PIN_NO(74) | 0) +#define MT8516_PIN_74_TDN3__FUNC_TDN3 (MTK_PIN_NO(74) | 1) + +#define MT8516_PIN_75_TDP3__FUNC_GPI75 (MTK_PIN_NO(75) | 0) +#define MT8516_PIN_75_TDP3__FUNC_TDP3 (MTK_PIN_NO(75) | 1) + +#define MT8516_PIN_76_TDN2__FUNC_GPI76 (MTK_PIN_NO(76) | 0) +#define MT8516_PIN_76_TDN2__FUNC_TDN2 (MTK_PIN_NO(76) | 1) + +#define MT8516_PIN_77_TDP2__FUNC_GPI77 (MTK_PIN_NO(77) | 0) +#define MT8516_PIN_77_TDP2__FUNC_TDP2 (MTK_PIN_NO(77) | 1) + +#define MT8516_PIN_78_TCN__FUNC_GPI78 (MTK_PIN_NO(78) | 0) +#define MT8516_PIN_78_TCN__FUNC_TCN (MTK_PIN_NO(78) | 1) + +#define MT8516_PIN_79_TCP__FUNC_GPI79 (MTK_PIN_NO(79) | 0) +#define MT8516_PIN_79_TCP__FUNC_TCP (MTK_PIN_NO(79) | 1) + +#define MT8516_PIN_80_TDN1__FUNC_GPI80 (MTK_PIN_NO(80) | 0) +#define MT8516_PIN_80_TDN1__FUNC_TDN1 (MTK_PIN_NO(80) | 1) + +#define MT8516_PIN_81_TDP1__FUNC_GPI81 (MTK_PIN_NO(81) | 0) +#define MT8516_PIN_81_TDP1__FUNC_TDP1 (MTK_PIN_NO(81) | 1) + +#define MT8516_PIN_82_TDN0__FUNC_GPI82 (MTK_PIN_NO(82) | 0) +#define MT8516_PIN_82_TDN0__FUNC_TDN0 (MTK_PIN_NO(82) | 1) + +#define MT8516_PIN_83_TDP0__FUNC_GPI83 (MTK_PIN_NO(83) | 0) +#define MT8516_PIN_83_TDP0__FUNC_TDP0 (MTK_PIN_NO(83) | 1) + +#define MT8516_PIN_84_RDN0__FUNC_GPI84 (MTK_PIN_NO(84) | 0) +#define MT8516_PIN_84_RDN0__FUNC_RDN0 (MTK_PIN_NO(84) | 1) + +#define MT8516_PIN_85_RDP0__FUNC_GPI85 (MTK_PIN_NO(85) | 0) +#define MT8516_PIN_85_RDP0__FUNC_RDP0 (MTK_PIN_NO(85) | 1) + +#define MT8516_PIN_86_RDN1__FUNC_GPI86 (MTK_PIN_NO(86) | 0) +#define MT8516_PIN_86_RDN1__FUNC_RDN1 (MTK_PIN_NO(86) | 1) + +#define MT8516_PIN_87_RDP1__FUNC_GPI87 (MTK_PIN_NO(87) | 0) +#define MT8516_PIN_87_RDP1__FUNC_RDP1 (MTK_PIN_NO(87) | 1) + +#define MT8516_PIN_88_RCN__FUNC_GPI88 (MTK_PIN_NO(88) | 0) +#define MT8516_PIN_88_RCN__FUNC_RCN (MTK_PIN_NO(88) | 1) + +#define MT8516_PIN_89_RCP__FUNC_GPI89 (MTK_PIN_NO(89) | 0) +#define MT8516_PIN_89_RCP__FUNC_RCP (MTK_PIN_NO(89) | 1) + +#define MT8516_PIN_90_RDN2__FUNC_GPI90 (MTK_PIN_NO(90) | 0) +#define MT8516_PIN_90_RDN2__FUNC_RDN2 (MTK_PIN_NO(90) | 1) +#define MT8516_PIN_90_RDN2__FUNC_CMDAT8 (MTK_PIN_NO(90) | 2) + +#define MT8516_PIN_91_RDP2__FUNC_GPI91 (MTK_PIN_NO(91) | 0) +#define MT8516_PIN_91_RDP2__FUNC_RDP2 (MTK_PIN_NO(91) | 1) +#define MT8516_PIN_91_RDP2__FUNC_CMDAT9 (MTK_PIN_NO(91) | 2) + +#define MT8516_PIN_92_RDN3__FUNC_GPI92 (MTK_PIN_NO(92) | 0) +#define MT8516_PIN_92_RDN3__FUNC_RDN3 (MTK_PIN_NO(92) | 1) +#define MT8516_PIN_92_RDN3__FUNC_CMDAT4 (MTK_PIN_NO(92) | 2) + +#define MT8516_PIN_93_RDP3__FUNC_GPI93 (MTK_PIN_NO(93) | 0) +#define MT8516_PIN_93_RDP3__FUNC_RDP3 (MTK_PIN_NO(93) | 1) +#define MT8516_PIN_93_RDP3__FUNC_CMDAT5 (MTK_PIN_NO(93) | 2) + +#define MT8516_PIN_94_RCN_A__FUNC_GPI94 (MTK_PIN_NO(94) | 0) +#define MT8516_PIN_94_RCN_A__FUNC_RCN_A (MTK_PIN_NO(94) | 1) +#define MT8516_PIN_94_RCN_A__FUNC_CMDAT6 (MTK_PIN_NO(94) | 2) + +#define MT8516_PIN_95_RCP_A__FUNC_GPI95 (MTK_PIN_NO(95) | 0) +#define MT8516_PIN_95_RCP_A__FUNC_RCP_A (MTK_PIN_NO(95) | 1) +#define MT8516_PIN_95_RCP_A__FUNC_CMDAT7 (MTK_PIN_NO(95) | 2) + +#define MT8516_PIN_96_RDN1_A__FUNC_GPI96 (MTK_PIN_NO(96) | 0) +#define MT8516_PIN_96_RDN1_A__FUNC_RDN1_A (MTK_PIN_NO(96) | 1) +#define MT8516_PIN_96_RDN1_A__FUNC_CMDAT2 (MTK_PIN_NO(96) | 2) +#define MT8516_PIN_96_RDN1_A__FUNC_CMCSD2 (MTK_PIN_NO(96) | 3) + +#define MT8516_PIN_97_RDP1_A__FUNC_GPI97 (MTK_PIN_NO(97) | 0) +#define MT8516_PIN_97_RDP1_A__FUNC_RDP1_A (MTK_PIN_NO(97) | 1) +#define MT8516_PIN_97_RDP1_A__FUNC_CMDAT3 (MTK_PIN_NO(97) | 2) +#define MT8516_PIN_97_RDP1_A__FUNC_CMCSD3 (MTK_PIN_NO(97) | 3) + +#define MT8516_PIN_98_RDN0_A__FUNC_GPI98 (MTK_PIN_NO(98) | 0) +#define MT8516_PIN_98_RDN0_A__FUNC_RDN0_A (MTK_PIN_NO(98) | 1) +#define MT8516_PIN_98_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(98) | 2) + +#define MT8516_PIN_99_RDP0_A__FUNC_GPI99 (MTK_PIN_NO(99) | 0) +#define MT8516_PIN_99_RDP0_A__FUNC_RDP0_A (MTK_PIN_NO(99) | 1) +#define MT8516_PIN_99_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(99) | 2) + +#define MT8516_PIN_100_CMDAT0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define MT8516_PIN_100_CMDAT0__FUNC_CMDAT0 (MTK_PIN_NO(100) | 1) +#define MT8516_PIN_100_CMDAT0__FUNC_CMCSD0 (MTK_PIN_NO(100) | 2) +#define MT8516_PIN_100_CMDAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(100) | 3) +#define MT8516_PIN_100_CMDAT0__FUNC_TDM_RX_MCK (MTK_PIN_NO(100) | 5) +#define MT8516_PIN_100_CMDAT0__FUNC_DBG_MON_B_21 (MTK_PIN_NO(100) | 7) + +#define MT8516_PIN_101_CMDAT1__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define MT8516_PIN_101_CMDAT1__FUNC_CMDAT1 (MTK_PIN_NO(101) | 1) +#define MT8516_PIN_101_CMDAT1__FUNC_CMCSD1 (MTK_PIN_NO(101) | 2) +#define MT8516_PIN_101_CMDAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(101) | 3) +#define MT8516_PIN_101_CMDAT1__FUNC_CMFLASH (MTK_PIN_NO(101) | 4) +#define MT8516_PIN_101_CMDAT1__FUNC_TDM_RX_BCK (MTK_PIN_NO(101) | 5) +#define MT8516_PIN_101_CMDAT1__FUNC_DBG_MON_B_22 (MTK_PIN_NO(101) | 7) + +#define MT8516_PIN_102_CMMCLK__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define MT8516_PIN_102_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(102) | 1) +#define MT8516_PIN_102_CMMCLK__FUNC_ANT_SEL4 (MTK_PIN_NO(102) | 3) +#define MT8516_PIN_102_CMMCLK__FUNC_TDM_RX_LRCK (MTK_PIN_NO(102) | 5) +#define MT8516_PIN_102_CMMCLK__FUNC_DBG_MON_B_23 (MTK_PIN_NO(102) | 7) + +#define MT8516_PIN_103_CMPCLK__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define MT8516_PIN_103_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(103) | 1) +#define MT8516_PIN_103_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(103) | 2) +#define MT8516_PIN_103_CMPCLK__FUNC_ANT_SEL5 (MTK_PIN_NO(103) | 3) +#define MT8516_PIN_103_CMPCLK__FUNC_TDM_RX_DI (MTK_PIN_NO(103) | 5) +#define MT8516_PIN_103_CMPCLK__FUNC_DBG_MON_B_24 (MTK_PIN_NO(103) | 7) + +#define MT8516_PIN_104_MSDC1_CMD__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define MT8516_PIN_104_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(104) | 1) +#define MT8516_PIN_104_MSDC1_CMD__FUNC_SQICS (MTK_PIN_NO(104) | 4) +#define MT8516_PIN_104_MSDC1_CMD__FUNC_DBG_MON_B_25 (MTK_PIN_NO(104) | 7) + +#define MT8516_PIN_105_MSDC1_CLK__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define MT8516_PIN_105_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(105) | 1) +#define MT8516_PIN_105_MSDC1_CLK__FUNC_SQISO (MTK_PIN_NO(105) | 4) +#define MT8516_PIN_105_MSDC1_CLK__FUNC_DBG_MON_B_26 (MTK_PIN_NO(105) | 7) + +#define MT8516_PIN_106_MSDC1_DAT0__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define MT8516_PIN_106_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(106) | 1) +#define MT8516_PIN_106_MSDC1_DAT0__FUNC_SQISI (MTK_PIN_NO(106) | 4) +#define MT8516_PIN_106_MSDC1_DAT0__FUNC_DBG_MON_B_27 (MTK_PIN_NO(106) | 7) + +#define MT8516_PIN_107_MSDC1_DAT1__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define MT8516_PIN_107_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(107) | 1) +#define MT8516_PIN_107_MSDC1_DAT1__FUNC_SQIWP (MTK_PIN_NO(107) | 4) +#define MT8516_PIN_107_MSDC1_DAT1__FUNC_DBG_MON_B_28 (MTK_PIN_NO(107) | 7) + +#define MT8516_PIN_108_MSDC1_DAT2__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define MT8516_PIN_108_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(108) | 1) +#define MT8516_PIN_108_MSDC1_DAT2__FUNC_SQIRST (MTK_PIN_NO(108) | 4) +#define MT8516_PIN_108_MSDC1_DAT2__FUNC_DBG_MON_B_29 (MTK_PIN_NO(108) | 7) + +#define MT8516_PIN_109_MSDC1_DAT3__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define MT8516_PIN_109_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(109) | 1) +#define MT8516_PIN_109_MSDC1_DAT3__FUNC_SQICK (MTK_PIN_NO(109) | 4) +#define MT8516_PIN_109_MSDC1_DAT3__FUNC_DBG_MON_B_30 (MTK_PIN_NO(109) | 7) + +#define MT8516_PIN_110_MSDC0_DAT7__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define MT8516_PIN_110_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(110) | 1) +#define MT8516_PIN_110_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(110) | 4) + +#define MT8516_PIN_111_MSDC0_DAT6__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define MT8516_PIN_111_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(111) | 1) +#define MT8516_PIN_111_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(111) | 4) + +#define MT8516_PIN_112_MSDC0_DAT5__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define MT8516_PIN_112_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(112) | 1) +#define MT8516_PIN_112_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(112) | 4) + +#define MT8516_PIN_113_MSDC0_DAT4__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define MT8516_PIN_113_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(113) | 1) +#define MT8516_PIN_113_MSDC0_DAT4__FUNC_NLD3 (MTK_PIN_NO(113) | 4) + +#define MT8516_PIN_114_MSDC0_RSTB__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define MT8516_PIN_114_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(114) | 1) +#define MT8516_PIN_114_MSDC0_RSTB__FUNC_NLD0 (MTK_PIN_NO(114) | 4) + +#define MT8516_PIN_115_MSDC0_CMD__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define MT8516_PIN_115_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(115) | 1) +#define MT8516_PIN_115_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(115) | 4) + +#define MT8516_PIN_116_MSDC0_CLK__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define MT8516_PIN_116_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(116) | 1) +#define MT8516_PIN_116_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(116) | 4) + +#define MT8516_PIN_117_MSDC0_DAT3__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define MT8516_PIN_117_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(117) | 1) +#define MT8516_PIN_117_MSDC0_DAT3__FUNC_NLD1 (MTK_PIN_NO(117) | 4) + +#define MT8516_PIN_118_MSDC0_DAT2__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define MT8516_PIN_118_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(118) | 1) +#define MT8516_PIN_118_MSDC0_DAT2__FUNC_NLD5 (MTK_PIN_NO(118) | 4) + +#define MT8516_PIN_119_MSDC0_DAT1__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define MT8516_PIN_119_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(119) | 1) +#define MT8516_PIN_119_MSDC0_DAT1__FUNC_NLD8 (MTK_PIN_NO(119) | 4) + +#define MT8516_PIN_120_MSDC0_DAT0__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define MT8516_PIN_120_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(120) | 1) +#define MT8516_PIN_120_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(120) | 4) +#define MT8516_PIN_120_MSDC0_DAT0__FUNC_NLD2 (MTK_PIN_NO(120) | 5) + +#endif /* __DTS_MT8516_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts new file mode 100644 index 000000000000..cce642c53812 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8516-pumpkin.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Fabien Parent <fparent@baylibre.com> + */ + +/dts-v1/; + +#include "mt8516.dtsi" +#include "pumpkin-common.dtsi" + +/ { + model = "Pumpkin MT8516"; + compatible = "mediatek,mt8516"; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x40000000>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi new file mode 100644 index 000000000000..2f8adf042195 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi @@ -0,0 +1,457 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Copyright (c) 2019 BayLibre, SAS. + * Author: Fabien Parent <fparent@baylibre.com> + */ + +#include <dt-bindings/clock/mt8516-clk.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/phy/phy.h> + +#include "mt8516-pinfunc.h" + +/ { + compatible = "mediatek,mt8516"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cluster0_opp: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1150000>; + }; + opp-747500000 { + opp-hz = /bits/ 64 <747500000>; + opp-microvolt = <1150000>; + }; + opp-1040000000 { + opp-hz = /bits/ 64 <1040000000>; + opp-microvolt = <1200000>; + }; + opp-1196000000 { + opp-hz = /bits/ 64 <1196000000>; + opp-microvolt = <1250000>; + }; + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1300000>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x0>; + enable-method = "psci"; + cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, + <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; + clocks = <&infracfg CLK_IFR_MUX1_SEL>, + <&topckgen CLK_TOP_MAINPLL_D2>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x1>; + enable-method = "psci"; + cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, + <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; + clocks = <&infracfg CLK_IFR_MUX1_SEL>, + <&topckgen CLK_TOP_MAINPLL_D2>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x2>; + enable-method = "psci"; + cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, + <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; + clocks = <&infracfg CLK_IFR_MUX1_SEL>, + <&topckgen CLK_TOP_MAINPLL_D2>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x3>; + enable-method = "psci"; + cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, + <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; + clocks = <&infracfg CLK_IFR_MUX1_SEL>, + <&topckgen CLK_TOP_MAINPLL_D2>; + clock-names = "cpu", "intermediate", "armpll"; + operating-points-v2 = <&cluster0_opp>; + }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0_0: cpu-sleep-0-0 { + compatible = "arm,idle-state"; + entry-latency-us = <600>; + exit-latency-us = <600>; + min-residency-us = <1200>; + arm,psci-suspend-param = <0x0010000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + entry-latency-us = <800>; + exit-latency-us = <1000>; + min-residency-us = <2000>; + arm,psci-suspend-param = <0x2010000>; + }; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + clk26m: clk26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + + clk32k: clk32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32000>; + clock-output-names = "clk32k"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 128 KiB reserved for ARM Trusted Firmware (BL31) */ + bl31_secmon_reserved: secmon@43000000 { + no-map; + reg = <0 0x43000000 0 0x20000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 5 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + ranges; + + topckgen: topckgen@10000000 { + compatible = "mediatek,mt8516-topckgen", "syscon"; + reg = <0 0x10000000 0 0x1000>; + #clock-cells = <1>; + }; + + infracfg: infracfg@10001000 { + compatible = "mediatek,mt8516-infracfg", "syscon"; + reg = <0 0x10001000 0 0x1000>; + #clock-cells = <1>; + }; + + apmixedsys: apmixedsys@10018000 { + compatible = "mediatek,mt8516-apmixedsys", "syscon"; + reg = <0 0x10018000 0 0x710>; + #clock-cells = <1>; + }; + + toprgu: toprgu@10007000 { + compatible = "mediatek,mt8516-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x1000>; + interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_FALLING>; + #reset-cells = <1>; + }; + + timer: timer@10008000 { + compatible = "mediatek,mt8516-timer", + "mediatek,mt6577-timer"; + reg = <0 0x10008000 0 0x1000>; + interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_CLK26M_D2>, + <&topckgen CLK_TOP_APXGPT>; + clock-names = "clk13m", "bus"; + }; + + syscfg_pctl: syscfg-pctl@10005000 { + compatible = "syscon"; + reg = <0 0x10005000 0 0x1000>; + }; + + pio: pinctrl@1000b000 { + compatible = "mediatek,mt8516-pinctrl"; + reg = <0 0x1000b000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + }; + + pwrap: pwrap@1000f000 { + compatible = "mediatek,mt8516-pwrap"; + reg = <0 0x1000f000 0 0x1000>; + reg-names = "pwrap"; + interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_PMICWRAP_26M>, + <&topckgen CLK_TOP_PMICWRAP_AP>; + clock-names = "spi", "wrap"; + }; + + sysirq: interrupt-controller@10200620 { + compatible = "mediatek,mt8516-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200620 0 0x20>; + }; + + gic: interrupt-controller@10310000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x10310000 0 0x1000>, + <0 0x10320000 0 0x1000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + interrupts = <GIC_PPI 9 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + uart0: serial@11005000 { + compatible = "mediatek,mt8516-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11005000 0 0x1000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_UART0_SEL>, + <&topckgen CLK_TOP_UART0>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11006000 { + compatible = "mediatek,mt8516-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11006000 0 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_UART1_SEL>, + <&topckgen CLK_TOP_UART1>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart2: serial@11007000 { + compatible = "mediatek,mt8516-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11007000 0 0x1000>; + interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_UART2_SEL>, + <&topckgen CLK_TOP_UART2>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + i2c0: i2c@11009000 { + compatible = "mediatek,mt8516-i2c", + "mediatek,mt2712-i2c"; + reg = <0 0x11009000 0 0x90>, + <0 0x11000180 0 0x80>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, + <&infracfg CLK_IFR_I2C0_SEL>, + <&topckgen CLK_TOP_I2C0>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main-source", + "main-sel", + "main", + "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@1100a000 { + compatible = "mediatek,mt8516-i2c", + "mediatek,mt2712-i2c"; + reg = <0 0x1100a000 0 0x90>, + <0 0x11000200 0 0x80>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, + <&infracfg CLK_IFR_I2C1_SEL>, + <&topckgen CLK_TOP_I2C1>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main-source", + "main-sel", + "main", + "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@1100b000 { + compatible = "mediatek,mt8516-i2c", + "mediatek,mt2712-i2c"; + reg = <0 0x1100b000 0 0x90>, + <0 0x11000280 0 0x80>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, + <&infracfg CLK_IFR_I2C2_SEL>, + <&topckgen CLK_TOP_I2C2>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main-source", + "main-sel", + "main", + "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi: spi@1100c000 { + compatible = "mediatek,mt8516-spi", + "mediatek,mt2712-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1100c000 0 0x1000>; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_UNIVPLL_D12>, + <&topckgen CLK_TOP_SPI_SEL>, + <&topckgen CLK_TOP_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + mmc0: mmc@11120000 { + compatible = "mediatek,mt8516-mmc"; + reg = <0 0x11120000 0 0x1000>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_MSDC0>, + <&topckgen CLK_TOP_AHB_INFRA_SEL>, + <&topckgen CLK_TOP_MSDC0_INFRA>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + + mmc1: mmc@11130000 { + compatible = "mediatek,mt8516-mmc"; + reg = <0 0x11130000 0 0x1000>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_MSDC1>, + <&topckgen CLK_TOP_AHB_INFRA_SEL>, + <&topckgen CLK_TOP_MSDC1_INFRA>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + + mmc2: mmc@11170000 { + compatible = "mediatek,mt8516-mmc"; + reg = <0 0x11170000 0 0x1000>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_MSDC2>, + <&topckgen CLK_TOP_RG_MSDC2>, + <&topckgen CLK_TOP_MSDC2_INFRA>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + + rng: rng@1020c000 { + compatible = "mediatek,mt8516-rng", + "mediatek,mt7623-rng"; + reg = <0 0x1020c000 0 0x100>; + clocks = <&topckgen CLK_TOP_TRNG>; + clock-names = "rng"; + }; + + pwm: pwm@11008000 { + compatible = "mediatek,mt8516-pwm"; + reg = <0 0x11008000 0 0x1000>; + #pwm-cells = <2>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_PWM>, + <&topckgen CLK_TOP_PWM_B>, + <&topckgen CLK_TOP_PWM1_FB>, + <&topckgen CLK_TOP_PWM2_FB>, + <&topckgen CLK_TOP_PWM3_FB>, + <&topckgen CLK_TOP_PWM4_FB>, + <&topckgen CLK_TOP_PWM5_FB>; + clock-names = "top", "main", "pwm1", "pwm2", "pwm3", + "pwm4", "pwm5"; + }; + + usb0: usb@11100000 { + compatible = "mediatek,mtk-musb"; + reg = <0 0x11100000 0 0x1000>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "mc"; + phys = <&usb0_port PHY_TYPE_USB2>; + clocks = <&topckgen CLK_TOP_USB>, + <&topckgen CLK_TOP_USBIF>, + <&topckgen CLK_TOP_USB_1P>; + clock-names = "main","mcu","univpll"; + status = "disabled"; + }; + + usb0_phy: usb@11110000 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0 0x11110000 0 0x800>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + usb0_port: usb-phy@11110800 { + reg = <0 0x11110800 0 0x100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi new file mode 100644 index 000000000000..a31093d7142b --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Fabien Parent <fparent@baylibre.com> + */ + +#include <dt-bindings/gpio/gpio.h> + +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; + + firmware { + optee: optee@4fd00000 { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys_default>; + + volume-up { + gpios = <&pio 42 GPIO_ACTIVE_LOW>; + label = "volume_up"; + linux,code = <115>; + wakeup-source; + debounce-interval = <15>; + }; + + volume-down { + gpios = <&pio 43 GPIO_ACTIVE_LOW>; + label = "volume_down"; + linux,code = <114>; + wakeup-source; + debounce-interval = <15>; + }; + }; +}; + +&i2c0 { + clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + tca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + rst-gpio = <&pio 65 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&tca6416_pins>; + + gpio-controller; + #gpio-cells = <2>; + + eint20_mux_sel0 { + gpio-hog; + gpios = <0 0>; + input; + line-name = "eint20_mux_sel0"; + }; + + expcon_mux_sel1 { + gpio-hog; + gpios = <1 0>; + input; + line-name = "expcon_mux_sel1"; + }; + + mrg_di_mux_sel2 { + gpio-hog; + gpios = <2 0>; + input; + line-name = "mrg_di_mux_sel2"; + }; + + sd_sdio_mux_sel3 { + gpio-hog; + gpios = <3 0>; + input; + line-name = "sd_sdio_mux_sel3"; + }; + + sd_sdio_mux_ctrl7 { + gpio-hog; + gpios = <7 0>; + output-low; + line-name = "sd_sdio_mux_ctrl7"; + }; + + hw_id0 { + gpio-hog; + gpios = <8 0>; + input; + line-name = "hw_id0"; + }; + + hw_id1 { + gpio-hog; + gpios = <9 0>; + input; + line-name = "hw_id1"; + }; + + hw_id2 { + gpio-hog; + gpios = <10 0>; + input; + line-name = "hw_id2"; + }; + + fg_int_n { + gpio-hog; + gpios = <11 0>; + input; + line-name = "fg_int_n"; + }; + + usba_pwr_en { + gpio-hog; + gpios = <12 0>; + output-high; + line-name = "usba_pwr_en"; + }; + + wifi_3v3_pg { + gpio-hog; + gpios = <13 0>; + input; + line-name = "wifi_3v3_pg"; + }; + + cam_rst { + gpio-hog; + gpios = <14 0>; + output-low; + line-name = "cam_rst"; + }; + + cam_pwdn { + gpio-hog; + gpios = <15 0>; + output-low; + line-name = "cam_pwdn"; + }; + }; +}; + +&i2c2 { + clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "peripheral"; + + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + }; +}; + +&usb0_phy { + status = "okay"; +}; + +&pio { + gpio_keys_default: gpiodefault { + pins_cmd_dat { + pinmux = <MT8516_PIN_42_KPCOL0__FUNC_GPIO42>, + <MT8516_PIN_43_KPCOL1__FUNC_GPIO43>; + bias-pull-up; + input-enable; + }; + }; + + i2c0_pins_a: i2c0@0 { + pins1 { + pinmux = <MT8516_PIN_58_SDA0__FUNC_SDA0_0>, + <MT8516_PIN_59_SCL0__FUNC_SCL0_0>; + bias-disable; + }; + }; + + i2c2_pins_a: i2c2@0 { + pins1 { + pinmux = <MT8516_PIN_60_SDA2__FUNC_SDA2_0>, + <MT8516_PIN_61_SCL2__FUNC_SCL2_0>; + bias-disable; + }; + }; + + tca6416_pins: pinmux_tca6416_pins { + gpio_mux_rst_n_pin { + pinmux = <MT8516_PIN_65_UTXD1__FUNC_GPIO65>; + output-high; + }; + + gpio_mux_int_n_pin { + pinmux = <MT8516_PIN_64_URXD1__FUNC_GPIO64>; + input-enable; + bias-pull-up; + }; + }; +}; diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 6238e6e274b4..11a1bb428595 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -6,6 +6,7 @@ #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/thermal/tegra124-soctherm.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra132", "nvidia,tegra124"; @@ -577,11 +578,12 @@ clock-names = "rtc"; }; - pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra124-pmc"; reg = <0x0 0x7000e400 0x0 0x400>; clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; }; fuse@7000f800 { diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts index f1de4ff6230a..1af7f9ffb7b6 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts @@ -131,7 +131,7 @@ status = "okay"; lanes { - usb2-0 { + micro_b: usb2-0 { nvidia,function = "xusb"; status = "okay"; }; @@ -174,8 +174,20 @@ usb2-0 { status = "okay"; mode = "otg"; - vbus-supply = <&vdd_usb0>; + + usb-role-switch; + connector { + compatible = "usb-b-connector", + "gpio-usb-b-connector"; + label = "micro-USB"; + type = "micro"; + vbus-gpio = <&gpio + TEGRA186_MAIN_GPIO(X, 7) + GPIO_ACTIVE_LOW>; + id-gpio = <&pmic 0 GPIO_ACTIVE_HIGH>; + }; + }; usb2-1 { @@ -201,12 +213,20 @@ phy-names = "usb2-0", "usb2-1", "usb3-0"; }; + usb@3550000 { + status = "okay"; + + phys = <µ_b>; + phy-names = "usb2-0"; + }; + i2c@c250000 { /* carrier board ID EEPROM */ eeprom@57 { compatible = "atmel,24c02"; reg = <0x57>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; @@ -258,7 +278,7 @@ status = "okay"; avdd-io-hdmi-dp-supply = <&vdd_hdmi_1v05>; - vdd-hdmi-dp-pll = <&vdd_1v8_ap>; + vdd-hdmi-dp-pll-supply = <&vdd_1v8_ap>; nvidia,dpaux = <&dpaux>; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi index 947744d0f04c..da96de04d003 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi @@ -171,6 +171,7 @@ compatible = "atmel,24c02"; reg = <0x50>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index c905527c26ef..58100fb9cd8b 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -572,6 +572,25 @@ nvidia,xusb-padctl = <&padctl>; }; + usb@3550000 { + compatible = "nvidia,tegra186-xudc"; + reg = <0x0 0x03550000 0x0 0x8000>, + <0x0 0x03558000 0x0 0x1000>; + reg-names = "base", "fpci"; + interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&bpmp TEGRA186_CLK_XUSB_CORE_DEV>, + <&bpmp TEGRA186_CLK_XUSB_SS>, + <&bpmp TEGRA186_CLK_XUSB_CORE_SS>, + <&bpmp TEGRA186_CLK_XUSB_FS>; + clock-names = "dev", "ss", "ss_src", "fs_src"; + iommus = <&smmu TEGRA186_SID_XUSB_DEV>; + power-domains = <&bpmp TEGRA186_POWER_DOMAIN_XUSBB>, + <&bpmp TEGRA186_POWER_DOMAIN_XUSBA>; + power-domain-names = "dev", "ss"; + nvidia,xusb-padctl = <&padctl>; + status = "disabled"; + }; + fuse@3820000 { compatible = "nvidia,tegra186-efuse"; reg = <0x0 0x03820000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi index bdd33ff4e324..623f7d7d216b 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi @@ -71,6 +71,29 @@ vmmc-supply = <&vdd_emmc_3v3>; }; + padctl@3520000 { + avdd-usb-supply = <&vdd_usb_3v3>; + vclamp-usb-supply = <&vdd_1v8ao>; + + ports { + usb2-1 { + vbus-supply = <&vdd_5v0_sys>; + }; + + usb2-3 { + vbus-supply = <&vdd_5v_sata>; + }; + + usb3-0 { + vbus-supply = <&vdd_5v0_sys>; + }; + + usb3-3 { + vbus-supply = <&vdd_5v0_sys>; + }; + }; + }; + rtc@c2a0000 { status = "okay"; }; @@ -234,7 +257,7 @@ regulator-max-microvolt = <3300000>; }; - ldo5 { + vdd_usb_3v3: ldo5 { regulator-name = "VDD_USB_3V3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -317,5 +340,16 @@ gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_HIGH>; regulator-boot-on; }; + + vdd_5v_sata: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + + regulator-name = "VDD_5V_SATA"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA194_MAIN_GPIO(Z, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts index 985e7d84f161..e15d1eac05f5 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts @@ -37,6 +37,69 @@ status = "okay"; }; + padctl@3520000 { + status = "okay"; + + pads { + usb2 { + lanes { + usb2-1 { + status = "okay"; + }; + + usb2-3 { + status = "okay"; + }; + }; + }; + + usb3 { + lanes { + usb3-0 { + status = "okay"; + }; + + usb3-3 { + status = "okay"; + }; + }; + }; + }; + + ports { + usb2-1 { + mode = "host"; + status = "okay"; + }; + + usb2-3 { + mode = "host"; + status = "okay"; + }; + + usb3-0 { + nvidia,usb2-companion = <1>; + status = "okay"; + }; + + usb3-3 { + nvidia,usb2-companion = <3>; + maximum-speed = "super-speed"; + status = "okay"; + }; + }; + }; + + usb@3610000 { + status = "okay"; + + phys = <&{/cbb@0/padctl@3520000/pads/usb2/lanes/usb2-1}>, + <&{/cbb@0/padctl@3520000/pads/usb2/lanes/usb2-3}>, + <&{/cbb@0/padctl@3520000/pads/usb3/lanes/usb3-0}>, + <&{/cbb@0/padctl@3520000/pads/usb3/lanes/usb3-3}>; + phy-names = "usb2-1", "usb2-3", "usb3-0", "usb3-3"; + }; + pwm@c340000 { status = "okay"; }; @@ -136,6 +199,24 @@ "p2u-5", "p2u-6", "p2u-7"; }; + pcie_ep@141a0000 { + status = "disabled"; + + vddio-pex-ctl-supply = <&vdd_1v8ao>; + + reset-gpios = <&gpio TEGRA194_MAIN_GPIO(GG, 1) GPIO_ACTIVE_LOW>; + + nvidia,refclk-select-gpios = <&gpio_aon TEGRA194_AON_GPIO(AA, 5) + GPIO_ACTIVE_HIGH>; + + phys = <&p2u_nvhs_0>, <&p2u_nvhs_1>, <&p2u_nvhs_2>, + <&p2u_nvhs_3>, <&p2u_nvhs_4>, <&p2u_nvhs_5>, + <&p2u_nvhs_6>, <&p2u_nvhs_7>; + + phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3", "p2u-4", + "p2u-5", "p2u-6", "p2u-7"; + }; + fan: fan { compatible = "pwm-fan"; pwms = <&pwm4 0 45334>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index ccac43be12ac..f4ede86e32b4 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -537,6 +537,145 @@ status = "disabled"; }; + xusb_padctl: padctl@3520000 { + compatible = "nvidia,tegra194-xusb-padctl"; + reg = <0x03520000 0x1000>, + <0x03540000 0x1000>; + reg-names = "padctl", "ao"; + + resets = <&bpmp TEGRA194_RESET_XUSB_PADCTL>; + reset-names = "padctl"; + + status = "disabled"; + + pads { + usb2 { + clocks = <&bpmp TEGRA194_CLK_USB2_TRK>; + clock-names = "trk"; + + lanes { + usb2-0 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb2-1 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb2-2 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb2-3 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + }; + }; + + usb3 { + lanes { + usb3-0 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb3-1 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb3-2 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + + usb3-3 { + nvidia,function = "xusb"; + status = "disabled"; + #phy-cells = <0>; + }; + }; + }; + }; + + ports { + usb2-0 { + status = "disabled"; + }; + + usb2-1 { + status = "disabled"; + }; + + usb2-2 { + status = "disabled"; + }; + + usb2-3 { + status = "disabled"; + }; + + usb3-0 { + status = "disabled"; + }; + + usb3-1 { + status = "disabled"; + }; + + usb3-2 { + status = "disabled"; + }; + + usb3-3 { + status = "disabled"; + }; + }; + }; + + usb@3610000 { + compatible = "nvidia,tegra194-xusb"; + reg = <0x03610000 0x40000>, + <0x03600000 0x10000>; + reg-names = "hcd", "fpci"; + + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&bpmp TEGRA194_CLK_XUSB_CORE_HOST>, + <&bpmp TEGRA194_CLK_XUSB_FALCON>, + <&bpmp TEGRA194_CLK_XUSB_CORE_SS>, + <&bpmp TEGRA194_CLK_XUSB_SS>, + <&bpmp TEGRA194_CLK_CLK_M>, + <&bpmp TEGRA194_CLK_XUSB_FS>, + <&bpmp TEGRA194_CLK_UTMIPLL>, + <&bpmp TEGRA194_CLK_CLK_M>, + <&bpmp TEGRA194_CLK_PLLE>; + clock-names = "xusb_host", "xusb_falcon_src", + "xusb_ss", "xusb_ss_src", "xusb_hs_src", + "xusb_fs_src", "pll_u_480m", "clk_m", + "pll_e"; + + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_XUSBC>, + <&bpmp TEGRA194_POWER_DOMAIN_XUSBA>; + power-domain-names = "xusb_host", "xusb_ss"; + + nvidia,xusb-padctl = <&xusb_padctl>; + status = "disabled"; + }; + fuse@3820000 { compatible = "nvidia,tegra194-efuse"; reg = <0x03820000 0x10000>; @@ -1208,7 +1347,7 @@ }; pcie@14100000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14100000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x30000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1253,7 +1392,7 @@ }; pcie@14120000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14120000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x32000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1298,7 +1437,7 @@ }; pcie@14140000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14140000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x34000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1343,7 +1482,7 @@ }; pcie@14160000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x36000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1388,7 +1527,7 @@ }; pcie@14180000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1433,7 +1572,7 @@ }; pcie@141a0000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1481,6 +1620,105 @@ 0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */ }; + pcie_ep@14160000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; + reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x36040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x36080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x14 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <4>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_4>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_4_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_4>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 4>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@14180000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; + reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x38040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x38080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x18 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_0_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_0>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 0>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@141a0000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; + reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x1c 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + pinctrl-names = "default"; + pinctrl-0 = <&clkreq_c5_bi_dir_state>; + + clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX1_CORE_5_APB>, + <&bpmp TEGRA194_RESET_PEX1_CORE_5>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 5>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + sysram@40000000 { compatible = "nvidia,tegra194-sysram", "mmio-sram"; reg = <0x0 0x40000000 0x0 0x50000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi index cb58f79deb48..f87d2437d11c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi @@ -265,11 +265,14 @@ }; i2c@7000c500 { + status = "okay"; + /* module ID EEPROM */ eeprom@50 { compatible = "atmel,24c02"; reg = <0x50>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index a3cafe39ba4c..ea0e1efa6973 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts @@ -56,6 +56,7 @@ backlight: backlight@2c { compatible = "ti,lp8557"; reg = <0x2c>; + power-supply = <&vdd_3v3_sys>; dev-ctrl = /bits/ 8 <0x80>; init-brt = /bits/ 8 <0xff>; @@ -85,6 +86,7 @@ compatible = "atmel,24c02"; reg = <0x57>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi index b0095072bc28..313a4c29d37a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi @@ -5,6 +5,10 @@ model = "NVIDIA Tegra210 P2597 I/O board"; compatible = "nvidia,p2597", "nvidia,tegra210"; + aliases { + ethernet = "/usb@70090000/ethernet@1"; + }; + host1x@50000000 { dpaux@54040000 { status = "okay"; @@ -1336,7 +1340,6 @@ <&{/padctl@7009f000/pads/pcie/lanes/pcie-5}>; phy-names = "usb2-0", "usb2-1", "usb2-2", "usb2-3", "usb3-0", "usb3-1"; - dvddio-pex-supply = <&vdd_pex_1v05>; hvddio-pex-supply = <&vdd_1v8>; avdd-usb-supply = <&vdd_3v3_sys>; @@ -1347,6 +1350,13 @@ hvdd-usb-ss-pll-e-supply = <&vdd_1v8>; status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + ethernet@1 { + reg = <1>; + }; }; padctl@7009f000 { @@ -1362,7 +1372,7 @@ status = "okay"; lanes { - usb2-0 { + micro_b: usb2-0 { nvidia,function = "xusb"; status = "okay"; }; @@ -1440,7 +1450,19 @@ ports { usb2-0 { status = "okay"; + vbus-supply = <&vdd_usb_vbus_otg>; mode = "otg"; + + usb-role-switch; + connector { + compatible = "usb-b-connector", + "gpio-usb-b-connector"; + label = "micro-USB"; + type = "micro"; + vbus-gpio = <&gpio TEGRA_GPIO(Z, 0) + GPIO_ACTIVE_LOW>; + id-gpio = <&pmic 0 0>; + }; }; usb2-1 { @@ -1483,6 +1505,14 @@ vmmc-supply = <&vdd_3v3_sd>; }; + usb@700d0000 { + status = "okay"; + phys = <µ_b>; + phy-names = "usb2-0"; + avddio-usb-supply = <&vdd_3v3_sys>; + hvdd-usb-supply = <&vdd_1v8>; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -1606,6 +1636,17 @@ vin-supply = <&vdd_5v0_sys>; }; + vdd_usb_vbus_otg: regulator@11 { + compatible = "regulator-fixed"; + reg = <9>; + regulator-name = "USB_VBUS_EN0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA_GPIO(CC, 4) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_5v0_sys>; + }; + vdd_hdmi: regulator@10 { compatible = "regulator-fixed"; reg = <10>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts index 9101d3a39cd2..21ed1756b889 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts @@ -114,6 +114,7 @@ compatible = "atmel,24c02"; reg = <0x50>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; @@ -124,6 +125,7 @@ compatible = "atmel,24c02"; reg = <0x57>; + vcc-supply = <&vdd_1v8>; address-bits = <8>; page-size = <8>; size = <256>; @@ -443,7 +445,7 @@ status = "okay"; lanes { - usb2-0 { + micro_b: usb2-0 { nvidia,function = "xusb"; status = "okay"; }; @@ -505,7 +507,17 @@ ports { usb2-0 { status = "okay"; - mode = "otg"; + mode = "peripheral"; + + usb-role-switch; + connector { + compatible = "usb-b-connector", + "gpio-usb-b-connector"; + label = "micro-USB"; + type = "micro"; + vbus-gpio = <&gpio TEGRA_GPIO(CC, 4) + GPIO_ACTIVE_LOW>; + }; }; usb2-1 { @@ -536,6 +548,14 @@ vmmc-supply = <&vdd_3v3_sd>; }; + usb@700d0000 { + status = "okay"; + phys = <µ_b>; + phy-names = "usb2-0"; + avddio-usb-supply = <&vdd_3v3_sys>; + hvdd-usb-supply = <&vdd_1v8>; + }; + sdhci@700b0400 { status = "okay"; bus-width = <4>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index 72c7a04ac1df..2faab6390552 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1592,7 +1592,7 @@ reg = <0x1a>; interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>; - clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>; + clocks = <&tegra_pmc TEGRA_PMC_CLK_OUT_2>; clock-names = "mclk"; nuvoton,jkdet-enable; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 48c63256ba7f..64c46ce3849d 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -7,6 +7,7 @@ #include <dt-bindings/reset/tegra210-car.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/thermal/tegra124-soctherm.h> +#include <dt-bindings/soc/tegra-pmc.h> / { compatible = "nvidia,tegra210"; @@ -770,16 +771,17 @@ compatible = "nvidia,tegra210-rtc", "nvidia,tegra20-rtc"; reg = <0x0 0x7000e000 0x0 0x100>; interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&pmc>; + interrupt-parent = <&tegra_pmc>; clocks = <&tegra_car TEGRA210_CLK_RTC>; clock-names = "rtc"; }; - pmc: pmc@7000e400 { + tegra_pmc: pmc@7000e400 { compatible = "nvidia,tegra210-pmc"; reg = <0x0 0x7000e400 0x0 0x400>; clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; + #clock-cells = <1>; #interrupt-cells = <2>; interrupt-controller; @@ -1207,6 +1209,25 @@ status = "disabled"; }; + usb@700d0000 { + compatible = "nvidia,tegra210-xudc"; + reg = <0x0 0x700d0000 0x0 0x8000>, + <0x0 0x700d8000 0x0 0x1000>, + <0x0 0x700d9000 0x0 0x1000>; + reg-names = "base", "fpci", "ipfs"; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>, + <&tegra_car TEGRA210_CLK_XUSB_SS>, + <&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>, + <&tegra_car TEGRA210_CLK_XUSB_FS_SRC>, + <&tegra_car TEGRA210_CLK_XUSB_HS_SRC>; + clock-names = "dev", "ss", "ss_src", "fs_src", "hs_src"; + power-domains = <&pd_xusbdev>, <&pd_xusbss>; + power-domain-names = "dev", "ss"; + nvidia,xusb-padctl = <&padctl>; + status = "disabled"; + }; + mipi: mipi@700e3000 { compatible = "nvidia,tegra210-mipi"; reg = <0x0 0x700e3000 0x0 0x100>; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 973c0f079659..cc103f7020fd 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -2,6 +2,7 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb +dtb-$(CONFIG_ARCH_QCOM) += ipq6018-cp01-c1.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq8074-hk01.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-longcheer-l8150.dtb @@ -22,5 +23,6 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 037e26b3f8d5..06aab44d798c 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -562,7 +562,6 @@ &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; - vdd_l5-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; vdd_l7-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index fff6115f2670..af87350b5547 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -999,13 +999,7 @@ vdda-phy-supply = <&vreg_l28a_0p925>; vdda-pll-supply = <&vreg_l12a_1p8>; - - vdda-phy-max-microamp = <18380>; - vdda-pll-max-microamp = <9440>; - vddp-ref-clk-supply = <&vreg_l25a_1p2>; - vddp-ref-clk-max-microamp = <100>; - vddp-ref-clk-always-on; }; &ufshc { diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts new file mode 100644 index 000000000000..b31117a93995 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * IPQ6018 CP01 board device tree source + * + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +/dts-v1/; + +#include "ipq6018.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C1"; + compatible = "qcom,ipq6018-cp01", "qcom,ipq6018"; + + aliases { + serial0 = &blsp1_uart3; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-append = " swiotlb=1"; + }; +}; + +&blsp1_uart3 { + pinctrl-0 = <&serial_3_pins>; + pinctrl-names = "default"; + status = "ok"; +}; + +&i2c_1 { + pinctrl-0 = <&i2c_1_pins>; + pinctrl-names = "default"; + status = "ok"; +}; + +&spi_0 { + cs-select = <0>; + status = "ok"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + compatible = "n25q128a11"; + spi-max-frequency = <50000000>; + }; +}; + +&tlmm { + i2c_1_pins: i2c-1-pins { + pins = "gpio42", "gpio43"; + function = "blsp2_i2c"; + drive-strength = <8>; + }; + + spi_0_pins: spi-0-pins { + pins = "gpio38", "gpio39", "gpio40", "gpio41"; + function = "blsp0_spi"; + drive-strength = <8>; + bias-pull-down; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi new file mode 100644 index 000000000000..1aa8d8579463 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * IPQ6018 SoC device tree source + * + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/qcom,gcc-ipq6018.h> +#include <dt-bindings/reset/qcom,gcc-ipq6018.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&intc>; + + clocks { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + xo: xo { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + }; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + enable-method = "psci"; + reg = <0x1>; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + enable-method = "psci"; + reg = <0x2>; + next-level-cache = <&L2_0>; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + enable-method = "psci"; + reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <0x2>; + }; + }; + + firmware { + scm { + compatible = "qcom,scm"; + }; + }; + + tcsr_mutex: hwlock { + compatible = "qcom,tcsr-mutex"; + syscon = <&tcsr_mutex_regs 0 0x80>; + #hwlock-cells = <1>; + }; + + pmuv8: pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_HIGH)>; + }; + + psci: psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + tz: tz@48500000 { + reg = <0x0 0x48500000 0x0 0x00200000>; + no-map; + }; + + smem_region: memory@4aa00000 { + reg = <0x0 0x4aa00000 0x0 0x00100000>; + no-map; + }; + + q6_region: memory@4ab00000 { + reg = <0x0 0x4ab00000 0x0 0x02800000>; + no-map; + }; + }; + + smem { + compatible = "qcom,smem"; + memory-region = <&smem_region>; + hwlocks = <&tcsr_mutex 0>; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + dma-ranges; + compatible = "simple-bus"; + + prng: qrng@e1000 { + compatible = "qcom,prng-ee"; + reg = <0xe3000 0x1000>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + }; + + cryptobam: dma@704000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x00704000 0x20000>; + interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_CRYPTO_AHB_CLK>; + clock-names = "bam_clk"; + #dma-cells = <1>; + qcom,ee = <1>; + qcom,controlled-remotely = <1>; + qcom,config-pipe-trust-reg = <0>; + }; + + crypto: crypto@73a000 { + compatible = "qcom,crypto-v5.1"; + reg = <0x0073a000 0x6000>; + clocks = <&gcc GCC_CRYPTO_AHB_CLK>, + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc GCC_CRYPTO_CLK>; + clock-names = "iface", "bus", "core"; + dmas = <&cryptobam 2>, <&cryptobam 3>; + dma-names = "rx", "tx"; + }; + + tlmm: pinctrl@1000000 { + compatible = "qcom,ipq6018-pinctrl"; + reg = <0x01000000 0x300000>; + interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 80>; + interrupt-controller; + #interrupt-cells = <2>; + + serial_3_pins: serial3-pinmux { + pins = "gpio44", "gpio45"; + function = "blsp2_uart"; + drive-strength = <8>; + bias-pull-down; + }; + }; + + gcc: gcc@1800000 { + compatible = "qcom,gcc-ipq6018"; + reg = <0x01800000 0x80000>; + clocks = <&xo>, <&sleep_clk>; + clock-names = "xo", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + tcsr_mutex_regs: syscon@1905000 { + compatible = "syscon"; + reg = <0x01905000 0x8000>; + }; + + tcsr_q6: syscon@1945000 { + compatible = "syscon"; + reg = <0x01945000 0xe000>; + }; + + blsp_dma: dma@7884000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x07884000 0x2b000>; + interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "bam_clk"; + #dma-cells = <1>; + qcom,ee = <0>; + }; + + blsp1_uart3: serial@78b1000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x078b1000 0x200>; + interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + spi_0: spi@78b5000 { + compatible = "qcom,spi-qup-v2.2.1"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x078b5000 0x600>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + spi-max-frequency = <50000000>; + clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 12>, <&blsp_dma 13>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + spi_1: spi@78b6000 { + compatible = "qcom,spi-qup-v2.2.1"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x078b6000 0x600>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + spi-max-frequency = <50000000>; + clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 14>, <&blsp_dma 15>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2c_0: i2c@78b6000 { + compatible = "qcom,i2c-qup-v2.2.1"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x078b6000 0x600>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; + clock-names = "iface", "core"; + clock-frequency = <400000>; + dmas = <&blsp_dma 15>, <&blsp_dma 14>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c_1: i2c@78b7000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-qup-v2.2.1"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x078b7000 0x600>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>; + clock-names = "iface", "core"; + clock-frequency = <400000>; + dmas = <&blsp_dma 17>, <&blsp_dma 16>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + intc: interrupt-controller@b000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <0x3>; + reg = <0x0b000000 0x1000>, /*GICD*/ + <0x0b002000 0x1000>, /*GICC*/ + <0x0b001000 0x1000>, /*GICH*/ + <0x0b004000 0x1000>; /*GICV*/ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + }; + + watchdog@b017000 { + compatible = "qcom,kpss-wdt"; + interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>; + reg = <0x0b017000 0x40>; + clocks = <&sleep_clk>; + timeout-sec = <10>; + }; + + apcs_glb: mailbox@b111000 { + compatible = "qcom,ipq8074-apcs-apps-global"; + reg = <0x0b111000 0xc>; + + #mbox-cells = <1>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; + + timer@b120000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x0b120000 0x1000>; + clock-frequency = <19200000>; + + frame@b120000 { + frame-number = <0>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b121000 0x1000>, + <0x0b122000 0x1000>; + }; + + frame@b123000 { + frame-number = <1>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xb123000 0x1000>; + status = "disabled"; + }; + + frame@b124000 { + frame-number = <2>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b124000 0x1000>; + status = "disabled"; + }; + + frame@b125000 { + frame-number = <3>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b125000 0x1000>; + status = "disabled"; + }; + + frame@b126000 { + frame-number = <4>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b126000 0x1000>; + status = "disabled"; + }; + + frame@b127000 { + frame-number = <5>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b127000 0x1000>; + status = "disabled"; + }; + + frame@b128000 { + frame-number = <6>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b128000 0x1000>; + status = "disabled"; + }; + }; + + q6v5_wcss: remoteproc@cd00000 { + compatible = "qcom,ipq8074-wcss-pil"; + reg = <0x0cd00000 0x4040>, + <0x004ab000 0x20>; + reg-names = "qdsp6", + "rmb"; + interrupts-extended = <&intc GIC_SPI 325 IRQ_TYPE_EDGE_RISING>, + <&wcss_smp2p_in 0 0>, + <&wcss_smp2p_in 1 0>, + <&wcss_smp2p_in 2 0>, + <&wcss_smp2p_in 3 0>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + resets = <&gcc GCC_WCSSAON_RESET>, + <&gcc GCC_WCSS_BCR>, + <&gcc GCC_WCSS_Q6_BCR>; + + reset-names = "wcss_aon_reset", + "wcss_reset", + "wcss_q6_reset"; + + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "prng"; + + qcom,halt-regs = <&tcsr_q6 0xa000 0xd000 0x0>; + + qcom,smem-states = <&wcss_smp2p_out 0>, + <&wcss_smp2p_out 1>; + qcom,smem-state-names = "shutdown", + "stop"; + + memory-region = <&q6_region>; + + glink-edge { + interrupts = <GIC_SPI 321 IRQ_TYPE_EDGE_RISING>; + qcom,remote-pid = <1>; + mboxes = <&apcs_glb 8>; + + qrtr_requests { + qcom,glink-channels = "IPCRTR"; + }; + }; + }; + + }; + + wcss: wcss-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupt-parent = <&intc>; + interrupts = <GIC_SPI 322 IRQ_TYPE_EDGE_RISING>; + + mboxes = <&apcs_glb 9>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + wcss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + wcss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 67ee5f560104..2b31823d3ccd 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -21,6 +21,7 @@ reg = <0x1000000 0x300000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; + gpio-ranges = <&tlmm 0 0 70>; #gpio-cells = <0x2>; interrupt-controller; #interrupt-cells = <0x2>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi index bd1eb3eeca53..43c5e0f882f1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi @@ -15,6 +15,14 @@ stdout-path = "serial0"; }; + reserved-memory { + /* Additional memory used by Samsung firmware modifications */ + tz-apps@85500000 { + reg = <0x0 0x85500000 0x0 0xb00000>; + no-map; + }; + }; + soc { sdhci@7824000 { status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 9f31064f2374..a88a15f2352b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -423,6 +423,7 @@ reg = <0x1000000 0x300000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; + gpio-ranges = <&msmgpio 0 0 122>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; @@ -860,7 +861,7 @@ }; tsens: thermal-sensor@4a9000 { - compatible = "qcom,msm8916-tsens"; + compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; reg = <0x4a9000 0x1000>, /* TM */ <0x4a8000 0x1000>; /* SROT */ nvmem-cells = <&tsens_caldata>, <&tsens_calsel>; @@ -1129,6 +1130,20 @@ qcom,remote-pid = <1>; label = "hexagon"; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,smd-channels = "fastrpcsmd-apps-dsp"; + label = "adsp"; + + #address-cells = <1>; + #size-cells = <0>; + + cb@1{ + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + }; + }; }; }; @@ -1415,6 +1430,7 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + arm,coresight-loses-context-with-cpu; cpu = <&CPU0>; @@ -1433,6 +1449,7 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + arm,coresight-loses-context-with-cpu; cpu = <&CPU1>; @@ -1451,6 +1468,7 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + arm,coresight-loses-context-with-cpu; cpu = <&CPU2>; @@ -1469,6 +1487,7 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + arm,coresight-loses-context-with-cpu; cpu = <&CPU3>; diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi index 8be60c08a9ab..2021795c99ad 100644 --- a/arch/arm64/boot/dts/qcom/msm8992.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi @@ -171,6 +171,7 @@ reg = <0xfd510000 0x4000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; + gpio-ranges = <&msmgpio 0 0 146>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 3932757f78b7..b1c2d7d6a0f2 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -133,6 +133,7 @@ reg = <0xfd510000 0x4000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; + gpio-ranges = <&msmgpio 0 0 146>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 7ae082ea14ea..14827adebd94 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -443,10 +443,13 @@ #reset-cells = <1>; #power-domain-cells = <1>; reg = <0x00300000 0x90000>; + + clocks = <&rpmcc RPM_SMD_LN_BB_CLK>; + clock-names = "cxo2"; }; tsens0: thermal-sensor@4a9000 { - compatible = "qcom,msm8996-tsens"; + compatible = "qcom,msm8996-tsens", "qcom,tsens-v2"; reg = <0x004a9000 0x1000>, /* TM */ <0x004a8000 0x1000>; /* SROT */ #qcom,sensors = <13>; @@ -457,7 +460,7 @@ }; tsens1: thermal-sensor@4ad000 { - compatible = "qcom,msm8996-tsens"; + compatible = "qcom,msm8996-tsens", "qcom,tsens-v2"; reg = <0x004ad000 0x1000>, /* TM */ <0x004ac000 0x1000>; /* SROT */ #qcom,sensors = <8>; @@ -695,6 +698,7 @@ reg = <0x01010000 0x300000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; + gpio-ranges = <&msmgpio 0 0 150>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; @@ -882,7 +886,7 @@ reg = <0x00624000 0x2500>; interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; - phys = <&ufsphy>; + phys = <&ufsphy_lane>; phy-names = "ufsphy"; power-domains = <&gcc UFS_GDSC>; @@ -934,16 +938,25 @@ }; ufsphy: phy@627000 { - compatible = "qcom,msm8996-ufs-phy-qmp-14nm"; - reg = <0x00627000 0xda8>; - reg-names = "phy_mem"; - #phy-cells = <0>; + compatible = "qcom,msm8996-qmp-ufs-phy"; + reg = <0x00627000 0x1c4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_UFS_CLKREF_CLK>; + clock-names = "ref"; - clock-names = "ref_clk_src", "ref_clk"; - clocks = <&rpmcc RPM_SMD_LN_BB_CLK>, - <&gcc GCC_UFS_CLKREF_CLK>; resets = <&ufshc 0>; + reset-names = "ufsphy"; status = "disabled"; + + ufsphy_lane: lanes@627400 { + reg = <0x627400 0x12c>, + <0x627600 0x200>, + <0x627c00 0x1b4>; + #phy-cells = <0>; + }; }; camss: camss@a00000 { diff --git a/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi index 0e0b9bc12945..8a14b2bf7bca 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi @@ -95,11 +95,15 @@ }; &funnel4 { - status = "okay"; + // FIXME: Figure out why clock late_initcall crashes the board with + // this enabled. + // status = "okay"; }; &funnel5 { - status = "okay"; + // FIXME: Figure out why clock late_initcall crashes the board with + // this enabled. + // status = "okay"; }; &pm8005_lsid1 { diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 91f7f2d07597..c07fee6fd7eb 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -130,7 +130,7 @@ CPU0: cpu@0 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x0>; enable-method = "psci"; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; @@ -149,7 +149,7 @@ CPU1: cpu@1 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x1>; enable-method = "psci"; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; @@ -164,7 +164,7 @@ CPU2: cpu@2 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x2>; enable-method = "psci"; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; @@ -179,7 +179,7 @@ CPU3: cpu@3 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x3>; enable-method = "psci"; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; @@ -194,7 +194,7 @@ CPU4: cpu@100 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x100>; enable-method = "psci"; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; @@ -213,7 +213,7 @@ CPU5: cpu@101 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x101>; enable-method = "psci"; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; @@ -228,7 +228,7 @@ CPU6: cpu@102 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x102>; enable-method = "psci"; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; @@ -243,7 +243,7 @@ CPU7: cpu@103 { device_type = "cpu"; - compatible = "arm,armv8"; + compatible = "qcom,kryo280"; reg = <0x0 0x103>; enable-method = "psci"; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi index 23534639f455..57af0b4a384d 100644 --- a/arch/arm64/boot/dts/qcom/pm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi @@ -20,7 +20,7 @@ mode-bootloader = <0x2>; mode-recovery = <0x1>; - pwrkey { + pm6150_pwrkey: pwrkey { compatible = "qcom,pm8941-pwrkey"; interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; debounce = <15625>; diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi index dc2ce23cde05..67283d60e2ac 100644 --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi @@ -45,7 +45,7 @@ mode-bootloader = <0x2>; mode-recovery = <0x1>; - pwrkey { + pm8998_pwrkey: pwrkey { compatible = "qcom,pm8941-pwrkey"; interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; debounce = <15625>; diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi index 522d3ef72df5..afe69e8f3114 100644 --- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi @@ -200,6 +200,7 @@ &sdcc1 { status = "ok"; + supports-cqe; mmc-ddr-1_8v; mmc-hs400-1_8v; bus-width = <8>; diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 4ee1e3d5f123..f149a538c1cc 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -685,9 +685,9 @@ }; sdcc1: sdcc@7804000 { - compatible = "qcom,sdhci-msm-v5"; + compatible = "qcom,qcs404-sdhci", "qcom,sdhci-msm-v5"; reg = <0x07804000 0x1000>, <0x7805000 0x1000>; - reg-names = "hc_mem", "cmdq_mem"; + reg-names = "hc", "cqhci"; interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts index 388f50ad4fde..043c9b9b5024 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts @@ -7,6 +7,7 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h> #include "sc7180.dtsi" #include "pm6150.dtsi" @@ -17,6 +18,7 @@ compatible = "qcom,sc7180-idp", "qcom,sc7180"; aliases { + bluetooth0 = &bluetooth; hsuart0 = &uart3; serial0 = &uart8; }; @@ -101,9 +103,9 @@ }; vreg_l12a_1p8: ldo12 { - regulator-min-microvolt = <1696000>; - regulator-max-microvolt = <1952000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; vreg_l13a_1p8: ldo13 { @@ -143,9 +145,9 @@ }; vreg_l19a_2p9: ldo19 { - regulator-min-microvolt = <2696000>; - regulator-max-microvolt = <3304000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; }; @@ -189,9 +191,9 @@ }; vreg_l6c_2p9: ldo6 { - regulator-min-microvolt = <2696000>; - regulator-max-microvolt = <3304000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; vreg_l7c_3p0: ldo7 { @@ -207,9 +209,9 @@ }; vreg_l9c_2p9: ldo9 { - regulator-min-microvolt = <2952000>; - regulator-max-microvolt = <3304000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; vreg_l10c_3p3: ldo10 { @@ -254,8 +256,40 @@ status = "okay"; }; +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_on>; + pinctrl-1 = <&sdc1_off>; + vmmc-supply = <&vreg_l19a_2p9>; + vqmmc-supply = <&vreg_l12a_1p8>; +}; + +&sdhc_2 { + status = "okay"; + + pinctrl-names = "default","sleep"; + pinctrl-0 = <&sdc2_on>; + pinctrl-1 = <&sdc2_off>; + vmmc-supply = <&vreg_l9c_2p9>; + vqmmc-supply = <&vreg_l6c_2p9>; + + cd-gpios = <&tlmm 69 GPIO_ACTIVE_LOW>; +}; + &uart3 { status = "okay"; + + bluetooth: wcn3990-bt { + compatible = "qcom,wcn3990-bt"; + vddio-supply = <&vreg_l10a_1p8>; + vddxo-supply = <&vreg_l1c_1p8>; + vddrf-supply = <&vreg_l2c_1p3>; + vddch0-supply = <&vreg_l10c_3p3>; + max-speed = <3200000>; + clocks = <&rpmhcc RPMH_RF_CLK2>; + }; }; &uart8 { @@ -287,6 +321,12 @@ vdda-pll-supply = <&vreg_l4a_0p8>; }; +&venus { + video-firmware { + iommus = <&apps_smmu 0x0c42 0x0>; + }; +}; + /* PINCTRL - additions to nodes defined in sc7180.dtsi */ &qspi_clk { diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 8011c5fe2a31..998f101ad623 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -5,8 +5,11 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ +#include <dt-bindings/clock/qcom,dispcc-sc7180.h> #include <dt-bindings/clock/qcom,gcc-sc7180.h> +#include <dt-bindings/clock/qcom,gpucc-sc7180.h> #include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/clock/qcom,videocc-sc7180.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/phy/phy-qcom-qusb2.h> #include <dt-bindings/power/qcom-aoss-qmp.h> @@ -75,6 +78,11 @@ reg = <0x0 0x80900000 0x0 0x200000>; no-map; }; + + venus_mem: memory@8f600000 { + reg = <0 0x8f600000 0 0x500000>; + no-map; + }; }; cpus { @@ -86,6 +94,8 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_0>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -103,6 +113,8 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_100>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -117,6 +129,8 @@ compatible = "arm,armv8"; reg = <0x0 0x200>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_200>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -131,6 +145,8 @@ compatible = "arm,armv8"; reg = <0x0 0x300>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_300>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -145,6 +161,8 @@ compatible = "arm,armv8"; reg = <0x0 0x400>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_400>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -159,6 +177,8 @@ compatible = "arm,armv8"; reg = <0x0 0x500>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <100>; next-level-cache = <&L2_500>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -173,6 +193,8 @@ compatible = "arm,armv8"; reg = <0x0 0x600>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; + dynamic-power-coefficient = <405>; next-level-cache = <&L2_600>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 1>; @@ -187,6 +209,8 @@ compatible = "arm,armv8"; reg = <0x0 0x700>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; + dynamic-power-coefficient = <405>; next-level-cache = <&L2_700>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 1>; @@ -195,6 +219,42 @@ next-level-cache = <&L3_0>; }; }; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + + core1 { + cpu = <&CPU1>; + }; + + core2 { + cpu = <&CPU2>; + }; + + core3 { + cpu = <&CPU3>; + }; + + core4 { + cpu = <&CPU4>; + }; + + core5 { + cpu = <&CPU5>; + }; + + core6 { + cpu = <&CPU6>; + }; + + core7 { + cpu = <&CPU7>; + }; + }; + }; }; memory@80000000 { @@ -299,7 +359,7 @@ method = "smc"; }; - soc: soc { + soc: soc@0 { #address-cells = <2>; #size-cells = <2>; ranges = <0 0 0 0 0x10 0>; @@ -310,8 +370,9 @@ compatible = "qcom,gcc-sc7180"; reg = <0 0x00100000 0 0x1f0000>; clocks = <&rpmhcc RPMH_CXO_CLK>, - <&rpmhcc RPMH_CXO_CLK_A>; - clock-names = "bi_tcxo", "bi_tcxo_ao"; + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -329,6 +390,33 @@ }; }; + sdhc_1: sdhci@7c4000 { + compatible = "qcom,sc7180-sdhci", "qcom,sdhci-msm-v5"; + reg = <0 0x7c4000 0 0x1000>, + <0 0x07c5000 0 0x1000>; + reg-names = "hc", "cqhci"; + + iommus = <&apps_smmu 0x60 0x0>; + interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC1_APPS_CLK>, + <&gcc GCC_SDCC1_AHB_CLK>; + clock-names = "core", "iface"; + + bus-width = <8>; + non-removable; + supports-cqe; + + mmc-ddr-1_8v; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + + status = "disabled"; + }; + qupv3_id_0: geniqup@8c0000 { compatible = "qcom,geni-se-qup"; reg = <0 0x008c0000 0 0x6000>; @@ -338,6 +426,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + iommus = <&apps_smmu 0x43 0x0>; status = "disabled"; i2c0: i2c@880000 { @@ -546,6 +635,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + iommus = <&apps_smmu 0x4c3 0x0>; status = "disabled"; i2c6: i2c@a80000 { @@ -745,6 +835,69 @@ }; }; + config_noc: interconnect@1500000 { + compatible = "qcom,sc7180-config-noc"; + reg = <0 0x01500000 0 0x28000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1620000 { + compatible = "qcom,sc7180-system-noc"; + reg = <0 0x01620000 0 0x17080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect@1638000 { + compatible = "qcom,sc7180-mc-virt"; + reg = <0 0x01638000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + qup_virt: interconnect@1650000 { + compatible = "qcom,sc7180-qup-virt"; + reg = <0 0x01650000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,sc7180-aggre1-noc"; + reg = <0 0x016e0000 0 0x15080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc: interconnect@1705000 { + compatible = "qcom,sc7180-aggre2-noc"; + reg = <0 0x01705000 0 0x9000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + compute_noc: interconnect@170e000 { + compatible = "qcom,sc7180-compute-noc"; + reg = <0 0x0170e000 0 0x6000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mmss_noc: interconnect@1740000 { + compatible = "qcom,sc7180-mmss-noc"; + reg = <0 0x01740000 0 0x1c100>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + ipa_virt: interconnect@1e00000 { + compatible = "qcom,sc7180-ipa-virt"; + reg = <0 0x01e00000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + tcsr_mutex_regs: syscon@1f40000 { compatible = "syscon"; reg = <0 0x01f40000 0 0x40000>; @@ -1037,6 +1190,140 @@ function = "qup15"; }; }; + + sdc1_on: sdc1-on { + pinconf-clk { + pins = "sdc1_clk"; + bias-disable; + drive-strength = <16>; + }; + + pinconf-cmd { + pins = "sdc1_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + pinconf-data { + pins = "sdc1_data"; + bias-pull-up; + drive-strength = <10>; + }; + + pinconf-rclk { + pins = "sdc1_rclk"; + bias-pull-down; + }; + }; + + sdc1_off: sdc1-off { + pinconf-clk { + pins = "sdc1_clk"; + bias-disable; + drive-strength = <2>; + }; + + pinconf-cmd { + pins = "sdc1_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + pinconf-data { + pins = "sdc1_data"; + bias-pull-up; + drive-strength = <2>; + }; + + pinconf-rclk { + pins = "sdc1_rclk"; + bias-pull-down; + }; + }; + + sdc2_on: sdc2-on { + pinconf-clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + pinconf-cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + pinconf-data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + + pinconf-sd-cd { + pins = "gpio69"; + bias-pull-up; + drive-strength = <2>; + }; + }; + + sdc2_off: sdc2-off { + pinconf-clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <2>; + }; + + pinconf-cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + pinconf-data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <2>; + }; + + pinconf-sd-cd { + pins = "gpio69"; + bias-disable; + drive-strength = <2>; + }; + }; + }; + + sdhc_2: sdhci@8804000 { + compatible = "qcom,sc7180-sdhci", "qcom,sdhci-msm-v5"; + reg = <0 0x08804000 0 0x1000>; + + iommus = <&apps_smmu 0x80 0>; + interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_APPS_CLK>, + <&gcc GCC_SDCC2_AHB_CLK>; + clock-names = "core", "iface"; + + bus-width = <4>; + + status = "disabled"; + }; + + gpucc: clock-controller@5090000 { + compatible = "qcom,sc7180-gpucc"; + reg = <0 0x05090000 0 0x9000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + clock-names = "bi_tcxo", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; }; qspi: spi@88dc000 { @@ -1081,8 +1368,8 @@ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; clock-names = "aux", "cfg_ahb", "ref", "com_aux"; - resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>, - <&gcc GCC_USB3_PHY_PRIM_BCR>; + resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, + <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; reset-names = "phy", "common"; usb_1_ssphy: phy@88e9200 { @@ -1100,6 +1387,13 @@ }; }; + dc_noc: interconnect@9160000 { + compatible = "qcom,sc7180-dc-noc"; + reg = <0 0x09160000 0 0x03200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + system-cache-controller@9200000 { compatible = "qcom,sc7180-llcc"; reg = <0 0x09200000 0 0x200000>, <0 0x09600000 0 0x50000>; @@ -1107,6 +1401,20 @@ interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>; }; + gem_noc: interconnect@9680000 { + compatible = "qcom,sc7180-gem-noc"; + reg = <0 0x09680000 0 0x3e200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + npu_noc: interconnect@9990000 { + compatible = "qcom,sc7180-npu-noc"; + reg = <0 0x09990000 0 0x1600>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + usb_1: usb@a6f8800 { compatible = "qcom,sc7180-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; @@ -1151,6 +1459,201 @@ }; }; + venus: video-codec@aa00000 { + compatible = "qcom,sc7180-venus"; + reg = <0 0x0aa00000 0 0xff000>; + interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&videocc VENUS_GDSC>, + <&videocc VCODEC0_GDSC>; + power-domain-names = "venus", "vcodec0"; + clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, + <&videocc VIDEO_CC_VENUS_AHB_CLK>, + <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>, + <&videocc VIDEO_CC_VCODEC0_CORE_CLK>, + <&videocc VIDEO_CC_VCODEC0_AXI_CLK>; + clock-names = "core", "iface", "bus", + "vcodec0_core", "vcodec0_bus"; + iommus = <&apps_smmu 0x0c00 0x60>; + memory-region = <&venus_mem>; + + video-decoder { + compatible = "venus-decoder"; + }; + + video-encoder { + compatible = "venus-encoder"; + }; + }; + + videocc: clock-controller@ab00000 { + compatible = "qcom,sc7180-videocc"; + reg = <0 0x0ab00000 0 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "bi_tcxo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + camnoc_virt: interconnect@ac00000 { + compatible = "qcom,sc7180-camnoc-virt"; + reg = <0 0x0ac00000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mdss: mdss@ae00000 { + compatible = "qcom,sc7180-mdss"; + reg = <0 0x0ae00000 0 0x1000>; + reg-names = "mdss"; + + power-domains = <&dispcc MDSS_GDSC>; + + clocks = <&gcc GCC_DISP_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>; + clock-names = "iface", "bus", "ahb", "core"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>; + assigned-clock-rates = <300000000>; + + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x800 0x2>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdp: mdp@ae01000 { + compatible = "qcom,sc7180-dpu"; + reg = <0 0x0ae01000 0 0x8f000>, + <0 0x0aeb0000 0 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_ROT_CLK>, + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "iface", "rot", "lut", "core", + "vsync"; + assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <300000000>, + <19200000>; + + interrupt-parent = <&mdss>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + }; + }; + + dsi0: dsi@ae94000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0 0x0ae94000 0 0x400>; + reg-names = "dsi_ctrl"; + + interrupt-parent = <&mdss>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK>, + <&dispcc DISP_CC_MDSS_ESC0_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>; + clock-names = "byte", + "byte_intf", + "pixel", + "core", + "iface", + "bus"; + + phys = <&dsi_phy>; + phy-names = "dsi"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi0_in: endpoint { + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + dsi0_out: endpoint { + }; + }; + }; + }; + + dsi_phy: dsi-phy@ae94400 { + compatible = "qcom,dsi-phy-10nm"; + reg = <0 0x0ae94400 0 0x200>, + <0 0x0ae94600 0 0x280>, + <0 0x0ae94a00 0 0x1e0>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "ref"; + + status = "disabled"; + }; + }; + + dispcc: clock-controller@af00000 { + compatible = "qcom,sc7180-dispcc"; + reg = <0 0x0af00000 0 0x200000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_DISP_GPLL0_CLK_SRC>, + <&dsi_phy 0>, + <&dsi_phy 1>, + <0>, + <0>; + clock-names = "bi_tcxo", + "gcc_disp_gpll0_clk_src", + "dsi0_phy_pll_out_byteclk", + "dsi0_phy_pll_out_dsiclk", + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sc7180-pdc", "qcom,pdc"; reg = <0 0x0b220000 0 0x30000>; @@ -1478,6 +1981,20 @@ }; }; }; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,bcm-voter"; + }; + }; + + osm_l3: interconnect@18321000 { + compatible = "qcom,sc7180-osm-l3"; + reg = <0 0x18321000 0 0x1400>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #interconnect-cells = <1>; }; cpufreq_hw: cpufreq@18323000 { @@ -1953,6 +2470,12 @@ hysteresis = <2000>; type = "hot"; }; + + aoss0_crit: aoss0_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2008,6 +2531,12 @@ hysteresis = <2000>; type = "hot"; }; + + gpuss0_crit: gpuss0_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2023,6 +2552,12 @@ hysteresis = <2000>; type = "hot"; }; + + gpuss1_crit: gpuss1_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2038,6 +2573,12 @@ hysteresis = <2000>; type = "hot"; }; + + aoss1_crit: aoss1_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2053,6 +2594,12 @@ hysteresis = <2000>; type = "hot"; }; + + cwlan_crit: cwlan_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2068,6 +2615,12 @@ hysteresis = <2000>; type = "hot"; }; + + audio_crit: audio_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2083,6 +2636,12 @@ hysteresis = <2000>; type = "hot"; }; + + ddr_crit: ddr_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2098,6 +2657,12 @@ hysteresis = <2000>; type = "hot"; }; + + q6_hvx_crit: q6_hvx_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2113,6 +2678,12 @@ hysteresis = <2000>; type = "hot"; }; + + camera_crit: camera_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2128,6 +2699,12 @@ hysteresis = <2000>; type = "hot"; }; + + mdm_crit: mdm_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2143,6 +2720,12 @@ hysteresis = <2000>; type = "hot"; }; + + mdm_dsp_crit: mdm_dsp_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2158,6 +2741,12 @@ hysteresis = <2000>; type = "hot"; }; + + npu_crit: npu_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; @@ -2173,6 +2762,12 @@ hysteresis = <2000>; type = "hot"; }; + + video_crit: video_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi index 7b53b3c7ffe6..9070be43a309 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi @@ -614,6 +614,11 @@ ap_ts_i2c: &i2c14 { }; }; +&ipa { + status = "okay"; + modem-init; +}; + &lpasscc { status = "okay"; }; @@ -626,6 +631,10 @@ ap_ts_i2c: &i2c14 { status = "okay"; }; +&pm8998_pwrkey { + status = "disabled"; +}; + &qupv3_id_0 { status = "okay"; }; @@ -1292,3 +1301,9 @@ ap_ts_i2c: &i2c14 { }; }; }; + +&venus { + video-firmware { + iommus = <&apps_smmu 0x10b2 0x0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index eb77aaa6a819..a2e05926b429 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -8,6 +8,8 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/sound/qcom,q6afe.h> +#include <dt-bindings/sound/qcom,q6asm.h> #include "sdm845.dtsi" #include "pm8998.dtsi" #include "pmi8998.dtsi" @@ -359,11 +361,56 @@ }; }; +&i2c11 { + /* On Low speed expansion */ + label = "LS-I2C1"; + status = "okay"; +}; + +&i2c14 { + /* On Low speed expansion */ + label = "LS-I2C0"; + status = "okay"; +}; + &mss_pil { status = "okay"; firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem.mbn"; }; +&pcie0 { + status = "okay"; + perst-gpio = <&tlmm 35 GPIO_ACTIVE_LOW>; + enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>; + + vddpe-3v3-supply = <&pcie0_3p3v_dual>; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_default_state>; +}; + +&pcie0_phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l1a_0p875>; + vdda-pll-supply = <&vreg_l26a_1p2>; +}; + +&pcie1 { + status = "okay"; + perst-gpio = <&tlmm 102 GPIO_ACTIVE_LOW>; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_default_state>; +}; + +&pcie1_phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l1a_0p875>; + vdda-pll-supply = <&vreg_l26a_1p2>; +}; + &pm8998_gpio { vol_up_pin_a: vol-up-active { pins = "gpio6"; @@ -384,6 +431,37 @@ }; }; +/* QUAT I2S Uses 4 I2S SD Lines for audio on LT9611 HDMI Bridge */ +&q6afedai { + qi2s@22 { + reg = <22>; + qcom,sd-lines = <0 1 2 3>; + }; +}; + +&q6asmdai { + dai@0 { + reg = <0>; + direction = <2>; + }; + + dai@1 { + reg = <1>; + direction = <2>; + }; + + dai@2 { + reg = <2>; + direction = <1>; + }; + + dai@3 { + reg = <3>; + direction = <2>; + is-compress-dai; + }; +}; + &qupv3_id_0 { status = "okay"; }; @@ -405,7 +483,121 @@ cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>; }; +&sound { + compatible = "qcom,db845c-sndcard"; + pinctrl-0 = <&quat_mi2s_active + &quat_mi2s_sd0_active + &quat_mi2s_sd1_active + &quat_mi2s_sd2_active + &quat_mi2s_sd3_active>; + pinctrl-names = "default"; + model = "DB845c"; + audio-routing = + "RX_BIAS", "MCLK", + "AMIC1", "MIC BIAS1", + "AMIC2", "MIC BIAS2", + "DMIC0", "MIC BIAS1", + "DMIC1", "MIC BIAS1", + "DMIC2", "MIC BIAS3", + "DMIC3", "MIC BIAS3", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT", + "MM_DL1", "MultiMedia1 Playback", + "MM_DL2", "MultiMedia2 Playback", + "MM_DL4", "MultiMedia4 Playback", + "MultiMedia3 Capture", "MM_UL3"; + + mm1-dai-link { + link-name = "MultiMedia1"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + link-name = "MultiMedia3"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + mm4-dai-link { + link-name = "MultiMedia4"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA4>; + }; + }; + + slim-dai-link { + link-name = "SLIM Playback"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9340 0>; + }; + }; + + slimcap-dai-link { + link-name = "SLIM Capture"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_TX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9340 1>; + }; + }; +}; + +&spi2 { + /* On Low speed expansion */ + label = "LS-SPI0"; + status = "okay"; +}; + &tlmm { + pcie0_default_state: pcie0-default { + clkreq { + pins = "gpio36"; + function = "pci_e0"; + bias-pull-up; + }; + + reset-n { + pins = "gpio35"; + function = "gpio"; + + drive-strength = <2>; + output-low; + bias-pull-down; + }; + + wake-n { + pins = "gpio37"; + function = "gpio"; + + drive-strength = <2>; + bias-pull-up; + }; + }; + pcie0_pwren_state: pcie0-pwren { pins = "gpio90"; function = "gpio"; @@ -414,6 +606,39 @@ bias-disable; }; + pcie1_default_state: pcie1-default { + perst-n { + pins = "gpio102"; + function = "gpio"; + + drive-strength = <16>; + bias-disable; + }; + + clkreq { + pins = "gpio103"; + function = "pci_e1"; + bias-pull-up; + }; + + wake-n { + pins = "gpio11"; + function = "gpio"; + + drive-strength = <2>; + bias-pull-up; + }; + + reset-n { + pins = "gpio75"; + function = "gpio"; + + drive-strength = <16>; + bias-pull-up; + output-high; + }; + }; + sdc2_default_state: sdc2-default { clk { pins = "sdc2_clk"; @@ -444,6 +669,20 @@ function = "gpio"; bias-pull-up; }; + + wcd_intr_default: wcd_intr_default { + pins = <54>; + function = "gpio"; + + input-enable; + bias-pull-down; + drive-strength = <2>; + }; +}; + +&uart3 { + label = "LS-UART0"; + status = "disabled"; }; &uart6 { @@ -461,6 +700,7 @@ }; &uart9 { + label = "LS-UART1"; status = "okay"; }; @@ -534,6 +774,39 @@ vdda-pll-supply = <&vreg_l26a_1p2>; }; +&wcd9340{ + pinctrl-0 = <&wcd_intr_default>; + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; + reset-gpios = <&tlmm 64 0>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; + vdd-rx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; + + swm: swm@c85 { + left_spkr: wsa8810-left{ + compatible = "sdw10217201000"; + reg = <0 1>; + powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #sound-dai-cells = <0>; + }; + + right_spkr: wsa8810-right{ + compatible = "sdw10217201000"; + powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + reg = <0 2>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrRight"; + #sound-dai-cells = <0>; + }; + }; +}; + &wifi { status = "okay"; @@ -546,6 +819,16 @@ }; /* PINCTRL - additions to nodes defined in sdm845.dtsi */ +&qup_spi2_default { + drive-strength = <16>; +}; + +&qup_uart3_default{ + pinmux { + pins = "gpio41", "gpio42", "gpio43", "gpio44"; + function = "qup3"; + }; +}; &qup_uart6_default { pinmux { diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 09ad37b0dd71..023e8b04c7f6 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -50,6 +50,7 @@ &adsp_pas { status = "okay"; + firmware-name = "qcom/sdm845/adsp.mdt"; }; &apps_rsc { @@ -350,6 +351,81 @@ &cdsp_pas { status = "okay"; + firmware-name = "qcom/sdm845/cdsp.mdt"; +}; + +&dsi0 { + status = "okay"; + vdda-supply = <&vdda_mipi_dsi0_1p2>; + + qcom,dual-dsi-mode; + qcom,master-dsi; + + #address-cells = <1>; + #size-cells = <0>; + + ports { + port@1 { + endpoint { + remote-endpoint = <&truly_in_0>; + data-lanes = <0 1 2 3>; + }; + }; + }; + + panel@0 { + compatible = "truly,nt35597-2K-display"; + reg = <0>; + vdda-supply = <&vreg_l14a_1p88>; + + reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; + mode-gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + truly_in_0: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + truly_in_1: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + }; + }; +}; + +&dsi0_phy { + status = "okay"; + vdds-supply = <&vdda_mipi_dsi0_pll>; +}; + +&dsi1 { + status = "okay"; + vdda-supply = <&vdda_mipi_dsi1_1p2>; + + qcom,dual-dsi-mode; + + ports { + port@1 { + endpoint { + remote-endpoint = <&truly_in_1>; + data-lanes = <0 1 2 3>; + }; + }; + }; +}; + +&dsi1_phy { + status = "okay"; + vdds-supply = <&vdda_mipi_dsi1_pll>; }; &gcc { @@ -372,6 +448,19 @@ clock-frequency = <400000>; }; +&mdss { + status = "okay"; +}; + +&mdss_mdp { + status = "okay"; +}; + +&mss_pil { + status = "okay"; + firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem.mbn"; +}; + &qupv3_id_1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index d42302b8889b..8f926b5234d4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -17,6 +17,7 @@ #include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/reset/qcom,sdm845-aoss.h> #include <dt-bindings/reset/qcom,sdm845-pdc.h> +#include <dt-bindings/soc/qcom,apr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> #include <dt-bindings/thermal/thermal.h> @@ -491,6 +492,57 @@ label = "lpass"; qcom,remote-pid = <2>; mboxes = <&apss_shared 8>; + + apr { + compatible = "qcom,apr-v2"; + qcom,glink-channels = "apr_audio_svc"; + qcom,apr-domain = <APR_DOMAIN_ADSP>; + #address-cells = <1>; + #size-cells = <0>; + qcom,intents = <512 20>; + + apr-service@3 { + reg = <APR_SVC_ADSP_CORE>; + compatible = "qcom,q6core"; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + }; + + q6afe: apr-service@4 { + compatible = "qcom,q6afe"; + reg = <APR_SVC_AFE>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6afedai: dais { + compatible = "qcom,q6afe-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + }; + }; + + q6asm: apr-service@7 { + compatible = "qcom,q6asm"; + reg = <APR_SVC_ASM>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6asmdai: dais { + compatible = "qcom,q6asm-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + iommus = <&apps_smmu 0x1821 0x0>; + }; + }; + + q6adm: apr-service@8 { + compatible = "qcom,q6adm"; + reg = <APR_SVC_ADM>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6routing: routing { + compatible = "qcom,q6adm-routing"; + #sound-dai-cells = <0>; + }; + }; + }; + fastrpc { compatible = "qcom,fastrpc"; qcom,glink-channels = "fastrpcglink-apps-dsp"; @@ -675,6 +727,17 @@ interrupt-controller; #interrupt-cells = <2>; }; + + ipa_smp2p_out: ipa-ap-to-modem { + qcom,entry-name = "ipa"; + #qcom,smem-state-cells = <1>; + }; + + ipa_smp2p_in: ipa-modem-to-ap { + qcom,entry-name = "ipa"; + interrupt-controller; + #interrupt-cells = <2>; + }; }; smp2p-slpi { @@ -1364,6 +1427,267 @@ interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>; }; + pcie0: pci@1c00000 { + compatible = "qcom,pcie-sdm845", "snps,dw-pcie"; + reg = <0 0x01c00000 0 0x2000>, + <0 0x60000000 0 0xf1d>, + <0 0x60000f20 0 0xa8>, + <0 0x60100000 0 0x100000>; + reg-names = "parf", "dbi", "elbi", "config"; + device_type = "pci"; + linux,pci-domain = <0>; + bus-range = <0x00 0xff>; + num-lanes = <1>; + + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>, + <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0xd00000>; + + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ + <0 0 0 2 &intc 0 150 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ + <0 0 0 3 &intc 0 151 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ + <0 0 0 4 &intc 0 152 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ + + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>, + <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>; + clock-names = "pipe", + "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "tbu"; + + iommus = <&apps_smmu 0x1c10 0xf>; + iommu-map = <0x0 &apps_smmu 0x1c10 0x1>, + <0x100 &apps_smmu 0x1c11 0x1>, + <0x200 &apps_smmu 0x1c12 0x1>, + <0x300 &apps_smmu 0x1c13 0x1>, + <0x400 &apps_smmu 0x1c14 0x1>, + <0x500 &apps_smmu 0x1c15 0x1>, + <0x600 &apps_smmu 0x1c16 0x1>, + <0x700 &apps_smmu 0x1c17 0x1>, + <0x800 &apps_smmu 0x1c18 0x1>, + <0x900 &apps_smmu 0x1c19 0x1>, + <0xa00 &apps_smmu 0x1c1a 0x1>, + <0xb00 &apps_smmu 0x1c1b 0x1>, + <0xc00 &apps_smmu 0x1c1c 0x1>, + <0xd00 &apps_smmu 0x1c1d 0x1>, + <0xe00 &apps_smmu 0x1c1e 0x1>, + <0xf00 &apps_smmu 0x1c1f 0x1>; + + resets = <&gcc GCC_PCIE_0_BCR>; + reset-names = "pci"; + + power-domains = <&gcc PCIE_0_GDSC>; + + phys = <&pcie0_lane>; + phy-names = "pciephy"; + + status = "disabled"; + }; + + pcie0_phy: phy@1c06000 { + compatible = "qcom,sdm845-qmp-pcie-phy"; + reg = <0 0x01c06000 0 0x18c>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_CLKREF_CLK>, + <&gcc GCC_PCIE_PHY_REFGEN_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "refgen"; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "phy"; + + assigned-clocks = <&gcc GCC_PCIE_PHY_REFGEN_CLK>; + assigned-clock-rates = <100000000>; + + status = "disabled"; + + pcie0_lane: lanes@1c06200 { + reg = <0 0x01c06200 0 0x128>, + <0 0x01c06400 0 0x1fc>, + <0 0x01c06800 0 0x218>, + <0 0x01c06600 0 0x70>; + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "pipe0"; + + #phy-cells = <0>; + clock-output-names = "pcie_0_pipe_clk"; + }; + }; + + pcie1: pci@1c08000 { + compatible = "qcom,pcie-sdm845", "snps,dw-pcie"; + reg = <0 0x01c08000 0 0x2000>, + <0 0x40000000 0 0xf1d>, + <0 0x40000f20 0 0xa8>, + <0 0x40100000 0 0x100000>; + reg-names = "parf", "dbi", "elbi", "config"; + device_type = "pci"; + linux,pci-domain = <1>; + bus-range = <0x00 0xff>; + num-lanes = <1>; + + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>; + + interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ + <0 0 0 2 &intc 0 435 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ + <0 0 0 3 &intc 0 438 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ + <0 0 0 4 &intc 0 439 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ + + clocks = <&gcc GCC_PCIE_1_PIPE_CLK>, + <&gcc GCC_PCIE_1_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>, + <&gcc GCC_PCIE_1_CLKREF_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>; + clock-names = "pipe", + "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "ref", + "tbu"; + + assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>; + assigned-clock-rates = <19200000>; + + iommus = <&apps_smmu 0x1c00 0xf>; + iommu-map = <0x0 &apps_smmu 0x1c00 0x1>, + <0x100 &apps_smmu 0x1c01 0x1>, + <0x200 &apps_smmu 0x1c02 0x1>, + <0x300 &apps_smmu 0x1c03 0x1>, + <0x400 &apps_smmu 0x1c04 0x1>, + <0x500 &apps_smmu 0x1c05 0x1>, + <0x600 &apps_smmu 0x1c06 0x1>, + <0x700 &apps_smmu 0x1c07 0x1>, + <0x800 &apps_smmu 0x1c08 0x1>, + <0x900 &apps_smmu 0x1c09 0x1>, + <0xa00 &apps_smmu 0x1c0a 0x1>, + <0xb00 &apps_smmu 0x1c0b 0x1>, + <0xc00 &apps_smmu 0x1c0c 0x1>, + <0xd00 &apps_smmu 0x1c0d 0x1>, + <0xe00 &apps_smmu 0x1c0e 0x1>, + <0xf00 &apps_smmu 0x1c0f 0x1>; + + resets = <&gcc GCC_PCIE_1_BCR>; + reset-names = "pci"; + + power-domains = <&gcc PCIE_1_GDSC>; + + phys = <&pcie1_lane>; + phy-names = "pciephy"; + + status = "disabled"; + }; + + pcie1_phy: phy@1c0a000 { + compatible = "qcom,sdm845-qhp-pcie-phy"; + reg = <0 0x01c0a000 0 0x800>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_CLKREF_CLK>, + <&gcc GCC_PCIE_PHY_REFGEN_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "refgen"; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "phy"; + + assigned-clocks = <&gcc GCC_PCIE_PHY_REFGEN_CLK>; + assigned-clock-rates = <100000000>; + + status = "disabled"; + + pcie1_lane: lanes@1c06200 { + reg = <0 0x01c0a800 0 0x800>, + <0 0x01c0a800 0 0x800>, + <0 0x01c0b800 0 0x400>; + clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; + clock-names = "pipe0"; + + #phy-cells = <0>; + clock-output-names = "pcie_1_pipe_clk"; + }; + }; + + mem_noc: interconnect@1380000 { + compatible = "qcom,sdm845-mem-noc"; + reg = <0 0x01380000 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + dc_noc: interconnect@14e0000 { + compatible = "qcom,sdm845-dc-noc"; + reg = <0 0x014e0000 0 0x400>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + config_noc: interconnect@1500000 { + compatible = "qcom,sdm845-config-noc"; + reg = <0 0x01500000 0 0x5080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1620000 { + compatible = "qcom,sdm845-system-noc"; + reg = <0 0x01620000 0 0x18080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,sdm845-aggre1-noc"; + reg = <0 0x016e0000 0 0x15080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc: interconnect@1700000 { + compatible = "qcom,sdm845-aggre2-noc"; + reg = <0 0x01700000 0 0x1f300>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mmss_noc: interconnect@1740000 { + compatible = "qcom,sdm845-mmss-noc"; + reg = <0 0x01740000 0 0x1c100>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + ufs_mem_hc: ufshc@1d84000 { compatible = "qcom,sdm845-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; @@ -1435,6 +1759,44 @@ }; }; + ipa: ipa@1e40000 { + compatible = "qcom,sdm845-ipa"; + reg = <0 0x1e40000 0 0x7000>, + <0 0x1e47000 0 0x2000>, + <0 0x1e04000 0 0x2c000>; + reg-names = "ipa-reg", + "ipa-shared", + "gsi"; + + interrupts-extended = <&intc 0 311 IRQ_TYPE_EDGE_RISING>, + <&intc 0 432 IRQ_TYPE_LEVEL_HIGH>, + <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ipa", + "gsi", + "ipa-clock-query", + "ipa-setup-ready"; + + clocks = <&rpmhcc RPMH_IPA_CLK>; + clock-names = "core"; + + interconnects = <&aggre2_noc MASTER_IPA &mem_noc SLAVE_EBI1>, + <&aggre2_noc MASTER_IPA &system_noc SLAVE_IMEM>, + <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_IPA_CFG>; + interconnect-names = "memory", + "imem", + "config"; + + qcom,smem-states = <&ipa_smp2p_out 0>, + <&ipa_smp2p_out 1>; + qcom,smem-state-names = "ipa-clock-enabled-valid", + "ipa-clock-enabled"; + + modem-remoteproc = <&mss_pil>; + + status = "disabled"; + }; + tcsr_mutex_regs: syscon@1f40000 { compatible = "syscon"; reg = <0 0x01f40000 0 0x40000>; @@ -1837,6 +2199,142 @@ function = "qup15"; }; }; + + quat_mi2s_sleep: quat_mi2s_sleep { + mux { + pins = "gpio58", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio58", "gpio59"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + + quat_mi2s_active: quat_mi2s_active { + mux { + pins = "gpio58", "gpio59"; + function = "qua_mi2s"; + }; + + config { + pins = "gpio58", "gpio59"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + + quat_mi2s_sd0_sleep: quat_mi2s_sd0_sleep { + mux { + pins = "gpio60"; + function = "gpio"; + }; + + config { + pins = "gpio60"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + + quat_mi2s_sd0_active: quat_mi2s_sd0_active { + mux { + pins = "gpio60"; + function = "qua_mi2s"; + }; + + config { + pins = "gpio60"; + drive-strength = <8>; + bias-disable; + }; + }; + + quat_mi2s_sd1_sleep: quat_mi2s_sd1_sleep { + mux { + pins = "gpio61"; + function = "gpio"; + }; + + config { + pins = "gpio61"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + + quat_mi2s_sd1_active: quat_mi2s_sd1_active { + mux { + pins = "gpio61"; + function = "qua_mi2s"; + }; + + config { + pins = "gpio61"; + drive-strength = <8>; + bias-disable; + }; + }; + + quat_mi2s_sd2_sleep: quat_mi2s_sd2_sleep { + mux { + pins = "gpio62"; + function = "gpio"; + }; + + config { + pins = "gpio62"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + + quat_mi2s_sd2_active: quat_mi2s_sd2_active { + mux { + pins = "gpio62"; + function = "qua_mi2s"; + }; + + config { + pins = "gpio62"; + drive-strength = <8>; + bias-disable; + }; + }; + + quat_mi2s_sd3_sleep: quat_mi2s_sd3_sleep { + mux { + pins = "gpio63"; + function = "gpio"; + }; + + config { + pins = "gpio63"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + + quat_mi2s_sd3_active: quat_mi2s_sd3_active { + mux { + pins = "gpio63"; + function = "qua_mi2s"; + }; + + config { + pins = "gpio63"; + drive-strength = <8>; + bias-disable; + }; + }; }; mss_pil: remoteproc@4080000 { @@ -1903,8 +2401,12 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + clock-names = "bi_tcxo", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src"; }; stm@6002000 { @@ -2386,6 +2888,87 @@ status = "disabled"; }; + slim: slim@171c0000 { + compatible = "qcom,slim-ngd-v2.1.0"; + reg = <0 0x171c0000 0 0x2c000>; + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; + + qcom,apps-ch-pipes = <0x780000>; + qcom,ea-pc = <0x270>; + status = "okay"; + dmas = <&slimbam 3>, <&slimbam 4>, + <&slimbam 5>, <&slimbam 6>; + dma-names = "rx", "tx", "tx2", "rx2"; + + iommus = <&apps_smmu 0x1806 0x0>; + #address-cells = <1>; + #size-cells = <0>; + + ngd@1 { + reg = <1>; + #address-cells = <2>; + #size-cells = <0>; + + wcd9340_ifd: ifd@0{ + compatible = "slim217,250"; + reg = <0 0>; + }; + + wcd9340: codec@1{ + compatible = "slim217,250"; + reg = <1 0>; + slim-ifc-dev = <&wcd9340_ifd>; + + #sound-dai-cells = <1>; + + interrupts-extended = <&tlmm 54 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + + #clock-cells = <0>; + clock-frequency = <9600000>; + clock-output-names = "mclk"; + qcom,micbias1-millivolt = <1800>; + qcom,micbias2-millivolt = <1800>; + qcom,micbias3-millivolt = <1800>; + qcom,micbias4-millivolt = <1800>; + + #address-cells = <1>; + #size-cells = <1>; + + wcdgpio: gpio-controller@42 { + compatible = "qcom,wcd9340-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x42 0x2>; + }; + + swm: swm@c85 { + compatible = "qcom,soundwire-v1.3.0"; + reg = <0xc85 0x40>; + interrupts-extended = <&wcd9340 20>; + + qcom,dout-ports = <6>; + qcom,din-ports = <2>; + qcom,ports-sinterval-low =/bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>; + + #sound-dai-cells = <1>; + clocks = <&wcd9340>; + clock-names = "iface"; + #address-cells = <2>; + #size-cells = <0>; + + + }; + }; + }; + }; + + sound: sound { + }; + usb_1_hsphy: phy@88e2000 { compatible = "qcom,sdm845-qusb2-phy"; reg = <0 0x088e2000 0 0x400>; @@ -2570,39 +3153,42 @@ }; }; - video-codec@aa00000 { - compatible = "qcom,sdm845-venus"; + venus: video-codec@aa00000 { + compatible = "qcom,sdm845-venus-v2"; reg = <0 0x0aa00000 0 0xff000>; interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; - power-domains = <&videocc VENUS_GDSC>; + power-domains = <&videocc VENUS_GDSC>, + <&videocc VCODEC0_GDSC>, + <&videocc VCODEC1_GDSC>; + power-domain-names = "venus", "vcodec0", "vcodec1"; clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, <&videocc VIDEO_CC_VENUS_AHB_CLK>, - <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>; - clock-names = "core", "iface", "bus"; + <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>, + <&videocc VIDEO_CC_VCODEC0_CORE_CLK>, + <&videocc VIDEO_CC_VCODEC0_AXI_CLK>, + <&videocc VIDEO_CC_VCODEC1_CORE_CLK>, + <&videocc VIDEO_CC_VCODEC1_AXI_CLK>; + clock-names = "core", "iface", "bus", + "vcodec0_core", "vcodec0_bus", + "vcodec1_core", "vcodec1_bus"; iommus = <&apps_smmu 0x10a0 0x8>, <&apps_smmu 0x10b0 0x0>; memory-region = <&venus_mem>; video-core0 { compatible = "venus-decoder"; - clocks = <&videocc VIDEO_CC_VCODEC0_CORE_CLK>, - <&videocc VIDEO_CC_VCODEC0_AXI_CLK>; - clock-names = "core", "bus"; - power-domains = <&videocc VCODEC0_GDSC>; }; video-core1 { compatible = "venus-encoder"; - clocks = <&videocc VIDEO_CC_VCODEC1_CORE_CLK>, - <&videocc VIDEO_CC_VCODEC1_AXI_CLK>; - clock-names = "core", "bus"; - power-domains = <&videocc VCODEC1_GDSC>; }; }; videocc: clock-controller@ab00000 { compatible = "qcom,sdm845-videocc"; reg = <0 0x0ab00000 0 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "bi_tcxo"; #clock-cells = <1>; #power-domain-cells = <1>; #reset-cells = <1>; @@ -2933,6 +3519,24 @@ dispcc: clock-controller@af00000 { compatible = "qcom,sdm845-dispcc"; reg = <0 0x0af00000 0 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_DISP_GPLL0_CLK_SRC>, + <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>, + <&dsi0_phy 0>, + <&dsi0_phy 1>, + <&dsi1_phy 0>, + <&dsi1_phy 1>, + <0>, + <0>; + clock-names = "bi_tcxo", + "gcc_disp_gpll0_clk_src", + "gcc_disp_gpll0_div_clk_src", + "dsi0_phy_pll_out_byteclk", + "dsi0_phy_pll_out_dsiclk", + "dsi1_phy_pll_out_byteclk", + "dsi1_phy_pll_out_dsiclk", + "dp_link_clk_divsel_ten", + "dp_vco_divided_clk_src_mux"; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -3098,6 +3702,13 @@ status = "disabled"; }; + gladiator_noc: interconnect@17900000 { + compatible = "qcom,sdm845-gladiator-noc"; + reg = <0 0x17900000 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + watchdog@17980000 { compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt"; reg = <0 0x17980000 0 0x1000>; @@ -3127,6 +3738,10 @@ <WAKE_TCS 3>, <CONTROL_TCS 1>; + apps_bcm_voter: bcm-voter { + compatible = "qcom,bcm-voter"; + }; + rpmhcc: clock-controller { compatible = "qcom,sdm845-rpmh-clk"; #clock-cells = <1>; @@ -3183,11 +3798,6 @@ }; }; }; - - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; - }; }; intc: interrupt-controller@17a00000 { @@ -3210,6 +3820,18 @@ }; }; + slimbam: dma@17184000 { + compatible = "qcom,bam-v1.7.0"; + qcom,controlled-remotely; + reg = <0 0x17184000 0 0x2a000>; + num-channels = <31>; + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + qcom,ee = <1>; + qcom,num-ees = <2>; + iommus = <&apps_smmu 0x1806 0x0>; + }; + timer@17c90000 { #address-cells = <2>; #size-cells = <2>; @@ -3268,6 +3890,16 @@ }; }; + osm_l3: interconnect@17d41000 { + compatible = "qcom,sdm845-osm-l3"; + reg = <0 0x17d41000 0 0x1400>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #interconnect-cells = <1>; + }; + cpufreq_hw: cpufreq@17d43000 { compatible = "qcom,cpufreq-hw"; reg = <0 0x17d43000 0 0x1400>, <0 0x17d45800 0 0x1400>; diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index b255be3a4a0a..3b617a75fafa 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -7,7 +7,10 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/sound/qcom,q6afe.h> +#include <dt-bindings/sound/qcom,q6asm.h> #include "sdm845.dtsi" #include "pm8998.dtsi" @@ -353,6 +356,75 @@ status = "okay"; }; +&q6asmdai { + dai@0 { + reg = <0>; + direction = <2>; + }; + + dai@1 { + reg = <1>; + direction = <1>; + }; +}; + +&sound { + compatible = "qcom,db845c-sndcard"; + model = "Lenovo-YOGA-C630-13Q50"; + + audio-routing = + "RX_BIAS", "MCLK", + "AMIC2", "MIC BIAS2", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT", + "MM_DL1", "MultiMedia1 Playback", + "MultiMedia2 Capture", "MM_UL2"; + + mm1-dai-link { + link-name = "MultiMedia1"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + slim-dai-link { + link-name = "SLIM Playback"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9340 0>; + }; + }; + + slimcap-dai-link { + link-name = "SLIM Capture"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_TX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9340 1>; + }; + }; +}; + &tlmm { gpio-reserved-ranges = <0 4>, <81 4>; @@ -382,6 +454,15 @@ bias-pull-up; drive-strength = <2>; }; + + wcd_intr_default: wcd_intr_default { + pins = <54>; + function = "gpio"; + + input-enable; + bias-pull-down; + drive-strength = <2>; + }; }; &uart6 { @@ -465,3 +546,36 @@ vdda-phy-supply = <&vdda_usb2_ss_1p2>; vdda-pll-supply = <&vdda_usb2_ss_core>; }; + +&wcd9340{ + pinctrl-0 = <&wcd_intr_default>; + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; + reset-gpios = <&tlmm 64 0>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; + vdd-rx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; + + swm: swm@c85 { + left_spkr: wsa8810-left{ + compatible = "sdw10217211000"; + reg = <0 3>; + powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #sound-dai-cells = <0>; + }; + + right_spkr: wsa8810-right{ + compatible = "sdw10217211000"; + powerdown-gpios = <&wcdgpio 3 GPIO_ACTIVE_HIGH>; + reg = <0 4>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrRight"; + #sound-dai-cells = <0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts new file mode 100644 index 000000000000..224d0f1ea6f9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +/dts-v1/; + +#include "sm8250.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8250 MTP"; + compatible = "qcom,sm8250-mtp"; + + aliases { + serial0 = &uart2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi new file mode 100644 index 000000000000..891d83b2afea --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/soc/qcom,rpmh-rsc.h> + +/ { + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <38400000>; + clock-output-names = "xo_board"; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + L3_0: l3-cache { + compatible = "cache"; + }; + }; + }; + + CPU1: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x100>; + enable-method = "psci"; + next-level-cache = <&L2_100>; + L2_100: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + + CPU2: cpu@200 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x200>; + enable-method = "psci"; + next-level-cache = <&L2_200>; + L2_200: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + + CPU3: cpu@300 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x300>; + enable-method = "psci"; + next-level-cache = <&L2_300>; + L2_300: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + + CPU4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x400>; + enable-method = "psci"; + next-level-cache = <&L2_400>; + L2_400: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + + CPU5: cpu@500 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x500>; + enable-method = "psci"; + next-level-cache = <&L2_500>; + L2_500: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + + }; + + CPU6: cpu@600 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x600>; + enable-method = "psci"; + next-level-cache = <&L2_600>; + L2_600: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + + CPU7: cpu@700 { + device_type = "cpu"; + compatible = "qcom,kryo485"; + reg = <0x0 0x700>; + enable-method = "psci"; + next-level-cache = <&L2_700>; + L2_700: l2-cache { + compatible = "cache"; + next-level-cache = <&L3_0>; + }; + }; + }; + + firmware { + scm: scm { + compatible = "qcom,scm"; + #reset-cells = <1>; + }; + }; + + tcsr_mutex: hwlock { + compatible = "qcom,tcsr-mutex"; + syscon = <&tcsr_mutex_regs 0 0x1000>; + #hwlock-cells = <1>; + }; + + memory@80000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the size */ + reg = <0x0 0x80000000 0x0 0x0>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + hyp_mem: memory@80000000 { + reg = <0x0 0x80000000 0x0 0x600000>; + no-map; + }; + + xbl_aop_mem: memory@80700000 { + reg = <0x0 0x80700000 0x0 0x160000>; + no-map; + }; + + cmd_db: memory@80860000 { + compatible = "qcom,cmd-db"; + reg = <0x0 0x80860000 0x0 0x20000>; + no-map; + }; + + smem_mem: memory@80900000 { + reg = <0x0 0x80900000 0x0 0x200000>; + no-map; + }; + + removed_mem: memory@80b00000 { + reg = <0x0 0x80b00000 0x0 0x5300000>; + no-map; + }; + + camera_mem: memory@86200000 { + reg = <0x0 0x86200000 0x0 0x500000>; + no-map; + }; + + wlan_mem: memory@86700000 { + reg = <0x0 0x86700000 0x0 0x100000>; + no-map; + }; + + ipa_fw_mem: memory@86800000 { + reg = <0x0 0x86800000 0x0 0x10000>; + no-map; + }; + + ipa_gsi_mem: memory@86810000 { + reg = <0x0 0x86810000 0x0 0xa000>; + no-map; + }; + + gpu_mem: memory@8681a000 { + reg = <0x0 0x8681a000 0x0 0x2000>; + no-map; + }; + + npu_mem: memory@86900000 { + reg = <0x0 0x86900000 0x0 0x500000>; + no-map; + }; + + video_mem: memory@86e00000 { + reg = <0x0 0x86e00000 0x0 0x500000>; + no-map; + }; + + cvp_mem: memory@87300000 { + reg = <0x0 0x87300000 0x0 0x500000>; + no-map; + }; + + cdsp_mem: memory@87800000 { + reg = <0x0 0x87800000 0x0 0x1400000>; + no-map; + }; + + slpi_mem: memory@88c00000 { + reg = <0x0 0x88c00000 0x0 0x1500000>; + no-map; + }; + + adsp_mem: memory@8a100000 { + reg = <0x0 0x8a100000 0x0 0x1d00000>; + no-map; + }; + + spss_mem: memory@8be00000 { + reg = <0x0 0x8be00000 0x0 0x100000>; + no-map; + }; + + cdsp_secure_heap: memory@8bf00000 { + reg = <0x0 0x8bf00000 0x0 0x4600000>; + no-map; + }; + }; + + smem: qcom,smem { + compatible = "qcom,smem"; + memory-region = <&smem_mem>; + hwlocks = <&tcsr_mutex 3>; + }; + + soc: soc@0 { + #address-cells = <2>; + #size-cells = <2>; + ranges = <0 0 0 0 0x10 0>; + dma-ranges = <0 0 0 0 0x10 0>; + compatible = "simple-bus"; + + gcc: clock-controller@100000 { + compatible = "qcom,gcc-sm8250"; + reg = <0x0 0x00100000 0x0 0x1f0000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + clock-names = "bi_tcxo", "sleep_clk"; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; + }; + + qupv3_id_1: geniqup@ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x00ac0000 0x0 0x6000>; + clock-names = "m-ahb", "s-ahb"; + clocks = <&gcc 133>, <&gcc 134>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + uart2: serial@a90000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00a90000 0x0 0x4000>; + clock-names = "se"; + clocks = <&gcc 113>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + }; + + intc: interrupt-controller@17a00000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x17a00000 0x0 0x10000>, /* GICD */ + <0x0 0x17a60000 0x0 0x100000>; /* GICR * 8 */ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + }; + + pdc: interrupt-controller@b220000 { + compatible = "qcom,sm8250-pdc"; + reg = <0x0b220000 0x30000>, <0x17c000f0 0x60>; + qcom,pdc-ranges = <0 480 94>, <94 609 31>, + <125 63 1>, <126 716 12>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + + spmi: qcom,spmi@c440000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x0 0x0c440000 0x0 0x0001100>, + <0x0 0x0c600000 0x0 0x2000000>, + <0x0 0x0e600000 0x0 0x0100000>, + <0x0 0x0e700000 0x0 0x00a0000>, + <0x0 0x0c40a000 0x0 0x0026000>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + + apps_rsc: rsc@18200000 { + label = "apps_rsc"; + compatible = "qcom,rpmh-rsc"; + reg = <0x0 0x18200000 0x0 0x10000>, + <0x0 0x18210000 0x0 0x10000>, + <0x0 0x18220000 0x0 0x10000>; + reg-names = "drv-0", "drv-1", "drv-2"; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + qcom,tcs-offset = <0xd00>; + qcom,drv-id = <2>; + qcom,tcs-config = <ACTIVE_TCS 2>, <SLEEP_TCS 3>, + <WAKE_TCS 3>, <CONTROL_TCS 1>; + + rpmhcc: clock-controller { + compatible = "qcom,sm8250-rpmh-clk"; + #clock-cells = <1>; + clock-names = "xo"; + clocks = <&xo_board>; + }; + }; + + tcsr_mutex_regs: syscon@1f40000 { + compatible = "syscon"; + reg = <0x0 0x01f40000 0x0 0x40000>; + }; + + timer@17c20000 { + #address-cells = <2>; + #size-cells = <2>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x17c20000 0x0 0x1000>; + clock-frequency = <19200000>; + + frame@17c21000 { + frame-number = <0>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c21000 0x0 0x1000>, + <0x0 0x17c22000 0x0 0x1000>; + }; + + frame@17c23000 { + frame-number = <1>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c23000 0x0 0x1000>; + status = "disabled"; + }; + + frame@17c25000 { + frame-number = <2>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c25000 0x0 0x1000>; + status = "disabled"; + }; + + frame@17c27000 { + frame-number = <3>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c27000 0x0 0x1000>; + status = "disabled"; + }; + + frame@17c29000 { + frame-number = <4>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c29000 0x0 0x1000>; + status = "disabled"; + }; + + frame@17c2b000 { + frame-number = <5>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c2b000 0x0 0x1000>; + status = "disabled"; + }; + + frame@17c2d000 { + frame-number = <6>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x17c2d000 0x0 0x1000>; + status = "disabled"; + }; + }; + + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 + (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 + (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 12 + (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index 2153842321ce..a7ec7a7065d5 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -1,14 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex.dtb +dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex-idk-1110wr.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex.dtb dtb-$(CONFIG_ARCH_R8A774C0) += r8a774c0-cat874.dtb r8a774c0-ek874.dtb \ r8a774c0-ek874-idk-2121wr.dtb -dtb-$(CONFIG_ARCH_R8A7795) += r8a77950-salvator-x.dtb -dtb-$(CONFIG_ARCH_R8A7795) += r8a77950-ulcb.dtb r8a77950-ulcb-kf.dtb -dtb-$(CONFIG_ARCH_R8A7795) += r8a77951-salvator-x.dtb r8a77951-salvator-xs.dtb -dtb-$(CONFIG_ARCH_R8A7795) += r8a77951-ulcb.dtb r8a77951-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-ulcb.dtb r8a77950-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-x.dtb r8a77951-salvator-xs.dtb @@ -16,6 +13,7 @@ dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-ulcb.dtb r8a77951-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-x.dtb r8a77960-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-ulcb.dtb r8a77960-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-salvator-xs.dtb +dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-ulcb.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb r8a77965-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb.dtb r8a77965-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb r8a77970-v3msk.dtb diff --git a/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-idk-1110wr.dts b/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-idk-1110wr.dts new file mode 100644 index 000000000000..2ab5edd84e9b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-idk-1110wr.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2M sub board connected to an + * Advantech IDK-1110WR 10.1" LVDS panel + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#include "r8a774a1-hihope-rzg2m-ex.dts" +#include "rzg2-advantech-idk-1110wr-panel.dtsi" + +/ { + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 50000>; + + brightness-levels = <0 2 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + +}; + +&gpio1 { + /* + * When GP1_20 is LOW LVDS0 is connected to the LVDS connector + * When GP1_20 is HIGH LVDS0 is connected to the LT8918L + */ + lvds-connector-en-gpio { + gpio-hog; + gpios = <20 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "lvds-connector-en-gpio"; + }; +}; + +&lvds0 { + status = "okay"; +}; + +&pfc { + pwm0_pins: pwm0 { + groups = "pwm0"; + function = "pwm0"; + }; +}; + +&pwm0 { + pinctrl-0 = <&pwm0_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index 8f950dabca54..79023433a740 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -2634,13 +2634,14 @@ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>; clock-names = "du.0", "du.1", "du.2"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.2"; status = "disabled"; - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>; ports { #address-cells = <1>; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index c40ea300968e..3137f735974b 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi @@ -2480,13 +2480,14 @@ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 721>; clock-names = "du.0", "du.1", "du.3"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.3"; status = "disabled"; - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>; ports { #address-cells = <1>; diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index a53cd5fcc401..22785cbddff5 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -1810,10 +1810,12 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; - vsps = <&vspd0 0>, <&vspd1 0>; + resets = <&cpg 724>; + reset-names = "du.0"; + renesas,vsps = <&vspd0 0>, <&vspd1 0>; + status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/renesas/r8a77950.dtsi b/arch/arm64/boot/dts/renesas/r8a77950.dtsi index 15216495e1c8..3975eecd50c4 100644 --- a/arch/arm64/boot/dts/renesas/r8a77950.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77950.dtsi @@ -30,7 +30,7 @@ }; &du { - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd3 0>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd3 0>; }; &fcpvb1 { diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi index a8729eb744db..52229546454c 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi @@ -3177,14 +3177,15 @@ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, - <&cpg CPG_MOD 722>, - <&cpg CPG_MOD 721>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, <&cpg CPG_MOD 721>; clock-names = "du.0", "du.1", "du.2", "du.3"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.2"; renesas,cmms = <&cmm0>, <&cmm1>, <&cmm2>, <&cmm3>; - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, + <&vspd0 1>; status = "disabled"; diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index 60f156cfd2d6..31282367d3ac 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi @@ -862,6 +862,15 @@ status = "disabled"; }; + arm_cc630p: crypto@e6601000 { + compatible = "arm,cryptocell-630p-ree"; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0xe6601000 0 0x1000>; + clocks = <&cpg CPG_MOD 229>; + resets = <&cpg 229>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7796", "renesas,rcar-dmac"; @@ -2818,13 +2827,14 @@ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>; clock-names = "du.0", "du.1", "du.2"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.2"; renesas,cmms = <&cmm0>, <&cmm1>, <&cmm2>; - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>; status = "disabled"; diff --git a/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts index 4abd78ac1cd5..2ffc7e31dd58 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts @@ -19,7 +19,7 @@ reg = <0x0 0x48000000 0x0 0x78000000>; }; - memory@400000000 { + memory@480000000 { device_type = "memory"; reg = <0x4 0x80000000 0x0 0x80000000>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77961-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a77961-ulcb.dts new file mode 100644 index 000000000000..7c6e60f6f32d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77961-ulcb.dts @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the M3ULCB (R-Car Starter Kit Pro) board with R-Car + * M3-W+ + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a77961.dtsi" +#include "ulcb.dtsi" + +/ { + model = "Renesas M3ULCB board based on r8a77961"; + compatible = "renesas,m3ulcb", "renesas,r8a77961"; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x78000000>; + }; + + memory@480000000 { + device_type = "memory"; + reg = <0x4 0x80000000 0x0 0x80000000>; + }; + + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x1 0x00000000>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index be3824bda632..0d96f2d3492b 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi @@ -474,6 +474,20 @@ #power-domain-cells = <1>; }; + tsc: thermal@e6198000 { + compatible = "renesas,r8a77961-thermal"; + reg = <0 0xe6198000 0 0x100>, + <0 0xe61a0000 0 0x100>, + <0 0xe61a8000 0 0x100>; + interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 522>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 522>; + #thermal-sensor-cells = <1>; + }; + intc_ex: interrupt-controller@e61c0000 { #interrupt-cells = <2>; interrupt-controller; @@ -629,6 +643,15 @@ /* placeholder */ }; + arm_cc630p: crypto@e6601000 { + compatible = "arm,cryptocell-630p-ree"; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0xe6601000 0 0x1000>; + clocks = <&cpg CPG_MOD 229>; + resets = <&cpg 229>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a77961", "renesas,rcar-dmac"; @@ -861,6 +884,7 @@ rcar_sound,ssi { ssi0: ssi-0 { }; ssi1: ssi-1 { }; + ssi2: ssi-2 { }; }; }; @@ -1064,6 +1088,71 @@ }; }; + thermal-zones { + sensor_thermal1: sensor-thermal1 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsc 0>; + sustainable-power = <3874>; + + trips { + sensor1_crit: sensor1-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + sensor_thermal2: sensor-thermal2 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsc 1>; + sustainable-power = <3874>; + + trips { + sensor2_crit: sensor2-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + sensor_thermal3: sensor-thermal3 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsc 2>; + sustainable-power = <3874>; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&a57_0 2 4>; + contribution = <1024>; + }; + map1 { + trip = <&target>; + cooling-device = <&a53_0 0 2>; + contribution = <1024>; + }; + }; + trips { + target: trip-point1 { + temperature = <100000>; + hysteresis = <1000>; + type = "passive"; + }; + + sensor3_crit: sensor3-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi index c17d90bd160e..d82dd4e67b62 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi @@ -111,6 +111,7 @@ power-domains = <&sysc R8A77965_PD_CA57_CPU0>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; #cooling-cells = <2>; dynamic-power-coefficient = <854>; clocks = <&cpg CPG_CORE R8A77965_CLK_Z>; @@ -124,6 +125,7 @@ power-domains = <&sysc R8A77965_PD_CA57_CPU1>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; clocks = <&cpg CPG_CORE R8A77965_CLK_Z>; operating-points-v2 = <&cluster0_opp>; }; @@ -134,6 +136,19 @@ cache-unified; cache-level = <2>; }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <500>; + min-residency-us = <4000>; + }; + }; }; extal_clk: extal { @@ -717,6 +732,15 @@ status = "disabled"; }; + arm_cc630p: crypto@e6601000 { + compatible = "arm,cryptocell-630p-ree"; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0xe6601000 0 0x1000>; + clocks = <&cpg CPG_MOD 229>; + resets = <&cpg 229>; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a77965", "renesas,rcar-dmac"; @@ -2494,13 +2518,14 @@ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 721>; clock-names = "du.0", "du.1", "du.3"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.3"; renesas,cmms = <&cmm0>, <&cmm1>, <&cmm3>; - vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>; status = "disabled"; diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 664a73a2cc69..a009c0ebc8b4 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -1121,7 +1121,9 @@ clock-names = "du.0"; power-domains = <&sysc R8A77970_PD_ALWAYS_ON>; resets = <&cpg 724>; - vsps = <&vspd0 0>; + reset-names = "du.0"; + renesas,vsps = <&vspd0 0>; + status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi index b340fb469999..e01b0508a18f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi @@ -1484,15 +1484,16 @@ }; du: display@feb00000 { - compatible = "renesas,du-r8a77980", - "renesas,du-r8a77970"; + compatible = "renesas,du-r8a77980"; reg = <0 0xfeb00000 0 0x80000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cpg CPG_MOD 724>; clock-names = "du.0"; power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; resets = <&cpg 724>; - vsps = <&vspd0 0>; + reset-names = "du.0"; + renesas,vsps = <&vspd0 0>; + status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index 32d91f210246..1543f18e834f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -88,6 +88,7 @@ power-domains = <&sysc R8A77990_PD_CA53_CPU0>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; dynamic-power-coefficient = <277>; clocks =<&cpg CPG_CORE R8A77990_CLK_Z2>; operating-points-v2 = <&cluster1_opp>; @@ -100,6 +101,7 @@ power-domains = <&sysc R8A77990_PD_CA53_CPU1>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; clocks =<&cpg CPG_CORE R8A77990_CLK_Z2>; operating-points-v2 = <&cluster1_opp>; }; @@ -110,6 +112,19 @@ cache-unified; cache-level = <2>; }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <700>; + exit-latency-us = <700>; + min-residency-us = <5000>; + }; + }; }; extal_clk: extal { @@ -667,6 +682,15 @@ dma-channels = <2>; }; + arm_cc630p: crypto@e6601000 { + compatible = "arm,cryptocell-630p-ree"; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0xe6601000 0 0x1000>; + clocks = <&cpg CPG_MOD 229>; + resets = <&cpg 229>; + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a77990", "renesas,rcar-dmac"; @@ -1784,14 +1808,13 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; resets = <&cpg 724>; reset-names = "du.0"; renesas,cmms = <&cmm0>, <&cmm1>; - vsps = <&vspd0 0>, <&vspd1 0>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>; status = "disabled"; diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 9503007c34c0..e8d2290fe79d 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -389,6 +389,15 @@ dma-channels = <2>; }; + arm_cc630p: crypto@e6601000 { + compatible = "arm,cryptocell-630p-ree"; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0xe6601000 0 0x1000>; + clocks = <&cpg CPG_MOD 229>; + resets = <&cpg 229>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + }; + canfd: can@e66c0000 { compatible = "renesas,r8a77995-canfd", "renesas,rcar-gen3-canfd"; @@ -1017,14 +1026,13 @@ reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>; clock-names = "du.0", "du.1"; resets = <&cpg 724>; reset-names = "du.0"; renesas,cmms = <&cmm0>, <&cmm1>; - vsps = <&vspd0 0>, <&vspd1 0>; + renesas,vsps = <&vspd0 0>, <&vspd1 0>; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 60d9437096c7..ae7621309e92 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -28,6 +28,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 75908c587511..f809dd6d5dc3 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -413,27 +413,30 @@ lvds: lvds { compatible = "rockchip,px30-lvds"; - #address-cells = <1>; - #size-cells = <0>; phys = <&dsi_dphy>; phy-names = "dphy"; rockchip,grf = <&grf>; rockchip,output = "lvds"; status = "disabled"; - port@0 { - reg = <0>; + ports { #address-cells = <1>; #size-cells = <0>; - lvds_vopb_in: endpoint@0 { + port@0 { reg = <0>; - remote-endpoint = <&vopb_out_lvds>; - }; - - lvds_vopl_in: endpoint@1 { - reg = <1>; - remote-endpoint = <&vopl_out_lvds>; + #address-cells = <1>; + #size-cells = <0>; + + lvds_vopb_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_lvds>; + }; + + lvds_vopl_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_lvds>; + }; }; }; }; @@ -700,7 +703,7 @@ clock-names = "pclk", "timer"; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -870,7 +873,6 @@ g-np-tx-fifo-size = <16>; g-rx-fifo-size = <280>; g-tx-fifo-size = <256 128 128 64 32 16>; - g-use-dma; phys = <&u2phy_otg>; phy-names = "usb2-phy"; power-domains = <&power PX30_PD_USB>; @@ -882,7 +884,6 @@ reg = <0x0 0xff340000 0x0 0x10000>; interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST>; - clock-names = "usbhost"; phys = <&u2phy_host>; phy-names = "usb"; power-domains = <&power PX30_PD_USB>; @@ -894,7 +895,6 @@ reg = <0x0 0xff350000 0x0 0x10000>; interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST>; - clock-names = "usbhost"; phys = <&u2phy_host>; phy-names = "usb"; power-domains = <&power PX30_PD_USB>; @@ -1031,7 +1031,6 @@ reset-names = "axi", "ahb", "dclk"; iommus = <&vopb_mmu>; power-domains = <&power PX30_PD_VO>; - rockchip,grf = <&grf>; status = "disabled"; vopb_out: port { @@ -1073,7 +1072,6 @@ reset-names = "axi", "ahb", "dclk"; iommus = <&vopl_mmu>; power-domains = <&power PX30_PD_VO>; - rockchip,grf = <&grf>; status = "disabled"; vopl_out: port { diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi index 116f1900effb..ac43bc3f7031 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi @@ -40,7 +40,7 @@ cpu0: cpu@0 { device_type = "cpu"; - compatible = "arm,cortex-a35", "arm,armv8"; + compatible = "arm,cortex-a35"; reg = <0x0 0x0>; enable-method = "psci"; clocks = <&cru ARMCLK>; @@ -53,7 +53,7 @@ cpu1: cpu@1 { device_type = "cpu"; - compatible = "arm,cortex-a35", "arm,armv8"; + compatible = "arm,cortex-a35"; reg = <0x0 0x1>; enable-method = "psci"; operating-points-v2 = <&cpu0_opp_table>; @@ -63,7 +63,7 @@ cpu2: cpu@2 { device_type = "cpu"; - compatible = "arm,cortex-a35", "arm,armv8"; + compatible = "arm,cortex-a35"; reg = <0x0 0x2>; enable-method = "psci"; operating-points-v2 = <&cpu0_opp_table>; @@ -73,7 +73,7 @@ cpu3: cpu@3 { device_type = "cpu"; - compatible = "arm,cortex-a35", "arm,armv8"; + compatible = "arm,cortex-a35"; reg = <0x0 0x3>; enable-method = "psci"; operating-points-v2 = <&cpu0_opp_table>; @@ -513,7 +513,7 @@ status = "disabled"; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts index 16f1656d5203..797e90a3ac92 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts @@ -60,6 +60,7 @@ }; &codec { + mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index 62936b432f9a..bf3e546f5266 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -104,6 +104,7 @@ }; &codec { + mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; status = "okay"; port@0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 1f53ead52c7f..7e88d88aab98 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -142,7 +142,7 @@ }; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -906,6 +906,7 @@ resets = <&cru SRST_GMAC2IO_A>; reset-names = "stmmaceth"; rockchip,grf = <&grf>; + snps,txpbl = <0x4>; status = "disabled"; }; @@ -927,6 +928,7 @@ reset-names = "stmmaceth", "mac-phy"; phy-mode = "rmii"; phy-handle = <&phy>; + snps,txpbl = <0x4>; status = "disabled"; mdio { @@ -957,7 +959,6 @@ g-np-tx-fifo-size = <16>; g-rx-fifo-size = <280>; g-tx-fifo-size = <256 128 128 64 32 16>; - g-use-dma; phys = <&u2phy_otg>; phy-names = "usb2-phy"; status = "disabled"; @@ -968,7 +969,6 @@ reg = <0x0 0xff5c0000 0x0 0x10000>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy>; - clock-names = "usbhost", "utmi"; phys = <&u2phy_host>; phy-names = "usb"; status = "disabled"; @@ -979,7 +979,6 @@ reg = <0x0 0xff5d0000 0x0 0x10000>; interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>, <&u2phy>; - clock-names = "usbhost", "utmi"; phys = <&u2phy_host>; phy-names = "usb"; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts index 231db0305a03..5ffd7b4d3036 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts @@ -239,7 +239,6 @@ cap-mmc-highspeed; cap-sd-highspeed; card-detect-delay = <200>; - no-emmc; no-sdio; sd-uhs-sdr12; sd-uhs-sdr25; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index a0df61c61925..1ebb0eef42da 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -136,7 +136,7 @@ }; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -513,7 +513,6 @@ reg = <0x0 0xff500000 0x0 0x100>; interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru HCLK_HOST0>; - clock-names = "usbhost"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts index 77008dca45bc..694b0d08d644 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts @@ -9,8 +9,7 @@ / { model = "Rockchip RK3399 Evaluation Board"; - compatible = "rockchip,rk3399-evb", "rockchip,rk3399", - "google,rk3399evb-rev2"; + compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; backlight: backlight { compatible = "pwm-backlight"; @@ -48,10 +47,22 @@ 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255>; default-brightness-level = <200>; - enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; pwms = <&pwm0 0 25000 0>; }; + edp_panel: edp-panel { + compatible ="lg,lp079qx1-sp0v"; + backlight = <&backlight>; + enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + power-supply = <&vcc3v3_s0>; + + port { + panel_in_edp: endpoint { + remote-endpoint = <&edp_out_panel>; + }; + }; + }; + clkin_gmac: external-gmac-clock { compatible = "fixed-clock"; clock-frequency = <125000000>; @@ -114,6 +125,24 @@ }; +&edp { + status = "okay"; + force-hpd; + + ports { + edp_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + edp_out_panel: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_in_edp>; + }; + }; + }; +}; + &emmc_phy { status = "okay"; }; @@ -134,6 +163,228 @@ status = "okay"; }; +&i2c0 { + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + vcc10-supply = <&vcc3v3_sys>; + vcc11-supply = <&vcc3v3_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v0_tp: LDO_REG2 { + regulator-name = "vcc3v0_tp"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG4 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + &pwm0 { status = "okay"; }; @@ -210,11 +461,6 @@ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; }; - - pmic_dvs2: pmic-dvs2 { - rockchip,pins = - <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; - }; }; usb2 { @@ -224,3 +470,11 @@ }; }; }; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi index 7cd6d470c1cb..1384dabbdf40 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi @@ -291,11 +291,9 @@ ap_i2c_tp: &i2c5 { #pwm-cells = <1>; }; - usbc_extcon1: extcon@1 { + usbc_extcon1: extcon1 { compatible = "google,extcon-usbc-cros-ec"; google,usb-port-id = <1>; - - #extcon-cells = <0>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index dd5624975c9b..2f3997740068 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -570,11 +570,9 @@ ap_i2c_audio: &i2c8 { #size-cells = <0>; }; - usbc_extcon0: extcon@0 { + usbc_extcon0: extcon0 { compatible = "google,extcon-usbc-cros-ec"; google,usb-port-id = <0>; - - #extcon-cells = <0>; }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts b/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts index d69a613fb65a..aee484a05181 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts @@ -29,6 +29,26 @@ regulator-max-microvolt = <5000000>; }; + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&ir_rx>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&power_led_gpio>; + + led-0 { + label = "blue:power"; + gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "default-on"; + }; + }; + vcc_sys: vcc-sys { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -483,6 +503,18 @@ }; }; + ir { + ir_rx: ir-rx { + rockchip,pins = <0 RK_PA6 1 &pcfg_pull_none>; + }; + }; + + leds { + power_led_gpio: power-led-gpio { + rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int_l: pmic-int-l { rockchip,pins = @@ -539,10 +571,6 @@ }; }; -&pwm0 { - status = "okay"; -}; - &pwm2 { status = "okay"; pinctrl-0 = <&pwm2_pin_pull_down>; @@ -555,7 +583,7 @@ &sdmmc { clock-frequency = <150000000>; - clock-freq-min-max = <200000 150000000>; + max-frequency = <150000000>; bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; @@ -610,7 +638,6 @@ &spi1 { status = "okay"; - max-freq = <10000000>; flash@0 { compatible = "jedec,spi-nor"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts index 9c659f3115c8..f9f7246d4d2f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts @@ -202,14 +202,27 @@ clock_in_out = "input"; phy-supply = <&vcc3v3_s3>; phy-mode = "rgmii"; + phy-handle = <&rtl8211e>; pinctrl-names = "default"; - pinctrl-0 = <&rgmii_pins>; - snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; - snps,reset-active-low; - snps,reset-delays-us = <0 10000 50000>; + pinctrl-0 = <&rgmii_pins>, <&phy_intb>, <&phy_rstb>; tx_delay = <0x28>; rx_delay = <0x11>; status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + rtl8211e: phy@1 { + reg = <1>; + interrupt-parent = <&gpio3>; + interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <30000>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + }; + }; }; &gpu { @@ -419,6 +432,8 @@ compatible = "silergy,syr827"; reg = <0x40>; fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&cpu_b_sleep>; regulator-name = "vdd_cpu_b"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; @@ -436,6 +451,8 @@ compatible = "silergy,syr828"; reg = <0x41>; fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&gpu_sleep>; regulator-name = "vdd_gpu"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; @@ -537,7 +554,25 @@ }; }; + phy { + phy_intb: phy-intb { + rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + phy_rstb: phy-rstb { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { + cpu_b_sleep: cpu-b-sleep { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + gpu_sleep: gpu-sleep { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + pmic_int_l: pmic-int-l { rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts new file mode 100644 index 000000000000..5ea281b55fe2 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts @@ -0,0 +1,1096 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.com> + * Copyright (c) 2020 Tobias Schramm <t.schramm@manjaro.org> + */ + +/dts-v1/; +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/pwm/pwm.h> +#include <dt-bindings/usb/pd.h> +#include <dt-bindings/leds/common.h> +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Pine64 Pinebook Pro"; + compatible = "pine64,pinebook-pro", "rockchip,rk3399"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + backlight: edp-backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_12v>; + pwms = <&pwm0 0 740740 0>; + }; + + edp_panel: edp-panel { + compatible = "boe,nv140fhmn49"; + backlight = <&backlight>; + enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&panel_en_gpio>; + power-supply = <&vcc3v3_panel>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_in_edp: endpoint@0 { + reg = <0>; + remote-endpoint = <&edp_out_panel>; + }; + }; + }; + }; + + /* + * Use separate nodes for gpio-keys to allow for selective deactivation + * of wakeup sources via sysfs without disabling the whole key + */ + gpio-key-lid { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&lidbtn_gpio>; + + lid { + debounce-interval = <20>; + gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>; + label = "Lid"; + linux,code = <SW_LID>; + linux,input-type = <EV_SW>; + wakeup-event-action = <EV_ACT_DEASSERTED>; + wakeup-source; + }; + }; + + gpio-key-power { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn_gpio>; + + power { + debounce-interval = <20>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "Power"; + linux,code = <KEY_POWER>; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pwrled_gpio &slpled_gpio>; + + green-led { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + function = LED_FUNCTION_POWER; + gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + label = "green:power"; + }; + + red-led { + color = <LED_COLOR_ID_RED>; + default-state = "off"; + function = LED_FUNCTION_STANDBY; + gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + label = "red:standby"; + panic-indicator; + retain-state-suspended; + }; + }; + + /* Power sequence for SDIO WiFi module */ + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h_gpio>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <500000>; + + /* WL_REG_ON on module */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + /* Audio components */ + es8316-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det_gpio>; + simple-audio-card,name = "rockchip,es8316-codec"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MIC1", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker Amplifier INL", "HPOL", + "Speaker Amplifier INR", "HPOR", + "Speaker", "Speaker Amplifier OUTL", + "Speaker", "Speaker Amplifier OUTR"; + + simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>; + simple-audio-card,aux-devs = <&speaker_amp>; + simple-audio-card,pin-switches = "Speaker"; + + simple-audio-card,cpu { + sound-dai = <&i2s1>; + }; + + simple-audio-card,codec { + sound-dai = <&es8316>; + }; + }; + + speaker_amp: speaker-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; + sound-name-prefix = "Speaker Amplifier"; + VCC-supply = <&pa_5v>; + }; + + /* Power tree */ + /* Root power source */ + vcc_sysin: vcc-sysin { + compatible = "regulator-fixed"; + regulator-name = "vcc_sysin"; + regulator-always-on; + regulator-boot-on; + }; + + /* Regulators supplied by vcc_sysin */ + /* LCD backlight supply */ + vcc_12v: vcc-12v { + compatible = "regulator-fixed"; + regulator-name = "vcc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Main 3.3 V supply */ + vcc3v3_sys: wifi_bat: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + /* 5 V USB power supply */ + vcc5v0_usb: pa_5v: vcc5v0-usb-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_5v_gpio>; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* RK3399 logic supply */ + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + /* Regulators supplied by vcc3v3_sys */ + /* 0.9 V supply, always on */ + vcc_0v9: vcc-0v9 { + compatible = "regulator-fixed"; + regulator-name = "vcc_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + /* S3 1.8 V supply, switched by vcc1v8_s3 */ + vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcca1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + /* micro SD card power */ + vcc3v0_sd: vcc3v0-sd { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_pwr_h_gpio>; + regulator-name = "vcc3v0_sd"; + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* LCD panel power, called VCC3V3_S0 in schematic */ + vcc3v3_panel: vcc3v3-panel { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&lcdvcc_en_gpio>; + regulator-name = "vcc3v3_panel"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <100000>; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* M.2 adapter power, switched by vcc1v8_s3 */ + vcc3v3_ssd: vcc3v3-ssd { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_ssd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_sys>; + }; + + /* Regulators supplied by vcc5v0_usb */ + /* USB 3 port power supply regulator */ + vcc5v0_otg: vcc5v0-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en_gpio>; + regulator-name = "vcc5v0_otg"; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Regulators supplied by vcc5v0_usb */ + /* Type C port power supply regulator */ + vbus_5vout: vbus_typec: vbus-5vout { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_typec0_en_gpio>; + regulator-name = "vbus_5vout"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Regulators supplied by vcc_1v8 */ + /* Primary 0.9 V LDO */ + vcca0v9_s3: vcca0v9-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc0v9_s3"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_1v8>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + mains_charger: dc-charger { + compatible = "gpio-charger"; + charger-type = "mains"; + gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>; + + /* Also triggered by USB charger */ + pinctrl-names = "default"; + pinctrl-0 = <&dc_det_gpio>; + }; +}; + +&cdn_dp { + status = "okay"; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&edp { + force-hpd; + pinctrl-names = "default"; + pinctrl-0 = <&edp_hpd>; + status = "okay"; + + ports { + edp_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + edp_out_panel: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_in_edp>; + }; + }; + }; +}; + +&emmc_phy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <4>; + i2c-scl-rising-time-ns = <168>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + interrupt-parent = <&gpio3>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l_gpio>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sysin>; + vcc2-supply = <&vcc_sysin>; + vcc3-supply = <&vcc_sysin>; + vcc4-supply = <&vcc_sysin>; + vcc6-supply = <&vcc_sysin>; + vcc7-supply = <&vcc_sysin>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sysin>; + vcc10-supply = <&vcc_sysin>; + vcc11-supply = <&vcc_sysin>; + vcc12-supply = <&vcc3v3_sys>; + vcc13-supply = <&vcc_sysin>; + vcc14-supply = <&vcc_sysin>; + + regulators { + /* rk3399 center logic supply */ + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: vcc_wl: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + /* not used */ + LDO_REG1 { + }; + + /* not used */ + LDO_REG2 { + }; + + vcc1v8_pmupll: LDO_REG3 { + regulator-name = "vcc1v8_pmupll"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel1_gpio>; + regulator-name = "vdd_cpu_b"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + vin-supply = <&vcc_1v8>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel2_gpio>; + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + vin-supply = <&vcc_1v8>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + i2c-scl-falling-time-ns = <4>; + i2c-scl-rising-time-ns = <168>; + status = "okay"; + + es8316: es8316@11 { + compatible = "everest,es8316"; + reg = <0x11>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + }; +}; + +&i2c3 { + i2c-scl-falling-time-ns = <15>; + i2c-scl-rising-time-ns = <450>; + status = "okay"; +}; + +&i2c4 { + i2c-scl-falling-time-ns = <20>; + i2c-scl-rising-time-ns = <600>; + status = "okay"; + + fusb0: fusb30x@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + fcs,int_n = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&fusb0_int_gpio>; + vbus-supply = <&vbus_typec>; + + connector { + compatible = "usb-c-connector"; + data-role = "host"; + label = "USB-C"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + sink-pdos = + <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>; + source-pdos = + <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usbc_hs: endpoint { + remote-endpoint = + <&u2phy0_typec_hs>; + }; + }; + + port@1 { + reg = <1>; + + usbc_ss: endpoint { + remote-endpoint = + <&tcphy0_typec_ss>; + }; + }; + + port@2 { + reg = <2>; + + usbc_dp: endpoint { + remote-endpoint = + <&tcphy0_typec_dp>; + }; + }; + }; + }; + }; +}; + +&i2s1 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_8ch_mclk_gpio>, <&i2s1_2ch_bus>; + rockchip,capture-channels = <8>; + rockchip,playback-channels = <8>; + status = "okay"; +}; + +&io_domains { + audio-supply = <&vcc_3v0>; + gpio1830-supply = <&vcc_3v0>; + sdmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + bus-scan-delay-ms = <1000>; + ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; + max-link-speed = <2>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + vpcie0v9-supply = <&vcca0v9_s3>; + vpcie1v8-supply = <&vcca1v8_s3>; + vpcie3v3-supply = <&vcc3v3_ssd>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwrbtn_gpio: pwrbtn-gpio { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + lidbtn_gpio: lidbtn-gpio { + rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + dc-charger { + dc_det_gpio: dc-det-gpio { + rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + es8316 { + hp_det_gpio: hp-det-gpio { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + fusb302x { + fusb0_int_gpio: fusb0-int-gpio { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + i2s1 { + i2s_8ch_mclk_gpio: i2s-8ch-mclk-gpio { + rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; + }; + }; + + lcd-panel { + lcdvcc_en_gpio: lcdvcc-en-gpio { + rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + panel_en_gpio: panel-en-gpio { + rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + lcd_panel_reset_gpio: lcd-panel-reset-gpio { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + pwrled_gpio: pwrled_gpio { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + slpled_gpio: slpled_gpio { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l_gpio: pmic-int-l-gpio { + rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + sdcard { + sdmmc0_pwr_h_gpio: sdmmc0-pwr-h-gpio { + rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + }; + + sdio-pwrseq { + wifi_enable_h_gpio: wifi-enable-h-gpio { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb-typec { + vcc5v0_typec0_en_gpio: vcc5v0-typec0-en-gpio { + rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + pwr_5v_gpio: pwr-5v-gpio { + rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_host_en_gpio: vcc5v0-host-en-gpio { + rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-bluetooth { + bt_wake_gpio: bt-wake-gpio { + rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_host_wake_gpio: bt-host-wake-gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_reset_gpio: bt-reset-gpio { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v0_sd>; + vqmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&spi1 { + max-freq = <10000000>; + status = "okay"; + + spiflash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + m25p,fast-read; + spi-max-frequency = <10000000>; + }; +}; + +&tcphy0 { + status = "okay"; +}; + +&tcphy0_dp { + port { + tcphy0_typec_dp: endpoint { + remote-endpoint = <&usbc_dp>; + }; + }; +}; + +&tcphy0_usb3 { + port { + tcphy0_typec_ss: endpoint { + remote-endpoint = <&usbc_ss>; + }; + }; +}; + +&tcphy1 { + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_otg>; + status = "okay"; + }; + + port { + u2phy0_typec_hs: endpoint { + remote-endpoint = <&usbc_hs>; + }; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_otg>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm4345c5"; + clocks = <&rk808 1>; + clock-names = "lpo"; + device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + max-speed = <1500000>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_host_wake_gpio &bt_wake_gpio &bt_reset_gpio>; + shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + vbat-supply = <&wifi_bat>; + vddio-supply = <&vcc_wl>; + }; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "host"; + status = "okay"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi index c1edca3872c7..07694b196fdb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -480,7 +480,7 @@ }; &sdmmc { - vqmmc = <&vcc_sd>; + vqmmc-supply = <&vcc_sd>; }; &spi1 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi index b69f0f2cbd67..ba7c75c9f2a1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi @@ -542,7 +542,7 @@ cap-mmc-highspeed; cap-sd-highspeed; clock-frequency = <100000000>; - clock-freq-min-max = <100000 100000000>; + max-frequency = <100000000>; cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; disable-wp; sd-uhs-sdr104; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts index b4d8f60b7e44..73e269a8ae0c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts @@ -230,7 +230,5 @@ }; &spdif { - i2c-scl-rising-time-ns = <450>; - i2c-scl-falling-time-ns = <15>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 33cc21fcf4c1..74f2c3d49095 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -197,7 +197,7 @@ #clock-cells = <0>; }; - amba { + amba: bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -288,6 +288,7 @@ resets = <&cru SRST_A_GMAC>; reset-names = "stmmaceth"; rockchip,grf = <&grf>; + snps,txpbl = <0x4>; status = "disabled"; }; @@ -349,8 +350,6 @@ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>, <&u2phy0>; - clock-names = "usbhost", "arbiter", - "utmi"; phys = <&u2phy0_host>; phy-names = "usb"; status = "disabled"; @@ -362,8 +361,6 @@ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>, <&u2phy0>; - clock-names = "usbhost", "arbiter", - "utmi"; phys = <&u2phy0_host>; phy-names = "usb"; status = "disabled"; @@ -375,8 +372,6 @@ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>, <&u2phy1>; - clock-names = "usbhost", "arbiter", - "utmi"; phys = <&u2phy1_host>; phy-names = "usb"; status = "disabled"; @@ -388,8 +383,6 @@ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>, <&u2phy1>; - clock-names = "usbhost", "arbiter", - "utmi"; phys = <&u2phy1_host>; phy-names = "usb"; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts index b42f94179538..a1783e7f769a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts @@ -13,5 +13,6 @@ / { model = "Radxa ROCK Pi N10"; - compatible = "radxa,rockpi-n10", "rockchip,rk3399pro"; + compatible = "radxa,rockpi-n10", "vamrs,rk3399pro-vmarc-som", + "rockchip,rk3399pro"; }; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi index 5b18bda9c5a6..2ca2d3dc8d6c 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi @@ -143,8 +143,8 @@ interrupts = <0 216 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 12>; + resets = <&peri_rst 12>; }; serial0: serial@54006800 { @@ -433,7 +433,7 @@ }; }; - emmc: sdhc@5a000000 { + emmc: mmc@5a000000 { compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc"; reg = <0x5a000000 0x400>; interrupts = <0 78 4>; @@ -566,7 +566,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-ld11-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -621,7 +621,7 @@ }; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5b"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi index f2dc5f695020..a93148c2088f 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi @@ -248,8 +248,8 @@ interrupts = <0 216 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 12>; + resets = <&peri_rst 12>; }; spi2: spi@54006200 { @@ -259,8 +259,8 @@ interrupts = <0 229 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi2>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 13>; + resets = <&peri_rst 13>; }; spi3: spi@54006300 { @@ -270,8 +270,8 @@ interrupts = <0 230 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi3>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 14>; + resets = <&peri_rst 14>; }; serial0: serial@54006800 { @@ -559,7 +559,7 @@ }; }; - emmc: sdhc@5a000000 { + emmc: mmc@5a000000 { compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc"; reg = <0x5a000000 0x400>; interrupts = <0 78 4>; @@ -578,7 +578,7 @@ cdns,phy-dll-delay-sdclk-hsmmc = <21>; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v3.1.1"; status = "disabled"; reg = <0x5a400000 0x800>; @@ -664,7 +664,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-ld20-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -925,7 +925,7 @@ socionext,syscon = <&soc_glue>; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5b"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts index 754315bbd1c8..4d00ff9548e1 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts @@ -27,6 +27,8 @@ i2c2 = &i2c2; i2c3 = &i2c3; i2c6 = &i2c6; + spi0 = &spi0; + spi1 = &spi1; }; memory@80000000 { @@ -39,6 +41,14 @@ interrupts = <4 8>; }; +&spi0 { + status = "okay"; +}; + +&spi1 { + status = "okay"; +}; + &serial0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi index 73e7e1203b09..616835b38106 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi @@ -7,6 +7,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/uniphier-gpio.h> +#include <dt-bindings/thermal/thermal.h> / { compatible = "socionext,uniphier-pxs3"; @@ -42,6 +43,7 @@ clocks = <&sys_clk 33>; enable-method = "psci"; operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; }; cpu1: cpu@1 { @@ -51,6 +53,7 @@ clocks = <&sys_clk 33>; enable-method = "psci"; operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; }; cpu2: cpu@2 { @@ -60,6 +63,7 @@ clocks = <&sys_clk 33>; enable-method = "psci"; operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; }; cpu3: cpu@3 { @@ -69,6 +73,7 @@ clocks = <&sys_clk 33>; enable-method = "psci"; operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; }; }; @@ -136,6 +141,37 @@ <1 10 4>; }; + thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; /* 250ms */ + polling-delay = <1000>; /* 1000ms */ + thermal-sensors = <&pvtctl>; + + trips { + cpu_crit: cpu-crit { + temperature = <110000>; /* 110C */ + hysteresis = <2000>; + type = "critical"; + }; + cpu_alert: cpu-alert { + temperature = <100000>; /* 100C */ + hysteresis = <2000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -171,8 +207,8 @@ interrupts = <0 216 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; - clocks = <&peri_clk 11>; - resets = <&peri_rst 11>; + clocks = <&peri_clk 12>; + resets = <&peri_rst 12>; }; serial0: serial@54006800 { @@ -353,7 +389,7 @@ }; }; - emmc: sdhc@5a000000 { + emmc: mmc@5a000000 { compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc"; reg = <0x5a000000 0x400>; interrupts = <0 78 4>; @@ -372,7 +408,7 @@ cdns,phy-dll-delay-sdclk-hsmmc = <21>; }; - sd: sdhc@5a400000 { + sd: mmc@5a400000 { compatible = "socionext,uniphier-sd-v3.1.1"; status = "disabled"; reg = <0x5a400000 0x800>; @@ -462,7 +498,7 @@ }; }; - aidet: aidet@5fc20000 { + aidet: interrupt-controller@5fc20000 { compatible = "socionext,uniphier-pxs3-aidet"; reg = <0x5fc20000 0x200>; interrupt-controller; @@ -496,6 +532,13 @@ watchdog { compatible = "socionext,uniphier-wdt"; }; + + pvtctl: pvtctl { + compatible = "socionext,uniphier-pxs3-thermal"; + interrupts = <0 3 4>; + #thermal-sensor-cells = <0>; + socionext,tmod-calibration = <0x0f22 0x68ee>; + }; }; eth0: ethernet@65000000 { @@ -783,7 +826,7 @@ socionext,syscon = <&soc_glue>; }; - nand: nand@68000000 { + nand: nand-controller@68000000 { compatible = "socionext,uniphier-denali-nand-v5b"; status = "disabled"; reg-names = "nand_data", "denali_reg"; diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi index e5df20a2d2f9..11887c72f23a 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -189,6 +189,8 @@ power-domains = <&k3_pds 137 TI_SCI_PD_EXCLUSIVE>; #address-cells = <1>; #size-cells = <0>; + dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>; + dma-names = "tx0", "rx0"; }; main_spi1: spi@2110000 { @@ -296,6 +298,7 @@ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; dma-coherent; power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ <&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */ @@ -335,6 +338,7 @@ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; dma-coherent; power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 152 2>; assigned-clocks = <&k3_clks 152 2>; assigned-clock-parents = <&k3_clks 152 4>; /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi index cbf97b621931..353d1e2532a7 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi @@ -12,6 +12,12 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x40f00000 0x20000>; + + phy_gmii_sel: phy@4040 { + compatible = "ti,am654-phy-gmii-sel"; + reg = <0x4040 0x4>; + #phy-cells = <1>; + }; }; mcu_uart0: serial@40a00000 { @@ -82,6 +88,9 @@ assigned-clocks = <&k3_clks 0 2>; assigned-clock-rates = <60000000>; clock-names = "adc_tsc_fck"; + dmas = <&mcu_udmap 0x7100>, + <&mcu_udmap 0x7101 >; + dma-names = "fifo0", "fifo1"; adc { #io-channel-cells = <1>; @@ -97,6 +106,9 @@ assigned-clocks = <&k3_clks 1 2>; assigned-clock-rates = <60000000>; clock-names = "adc_tsc_fck"; + dmas = <&mcu_udmap 0x7102>, + <&mcu_udmap 0x7103>; + dma-names = "fifo0", "fifo1"; adc { #io-channel-cells = <1>; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi index bfe91f2a52cb..3d6064125b40 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi @@ -34,6 +34,20 @@ }; }; + mcu_conf: syscon@40f00000 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0x40f00000 0x0 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x40f00000 0x20000>; + + phy_gmii_sel: phy@4040 { + compatible = "ti,am654-phy-gmii-sel"; + reg = <0x4040 0x4>; + #phy-cells = <1>; + }; + }; + wkup_pmx0: pinmux@4301c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ @@ -203,6 +217,9 @@ assigned-clocks = <&k3_clks 0 3>; assigned-clock-rates = <60000000>; clock-names = "adc_tsc_fck"; + dmas = <&main_udmap 0x7400>, + <&main_udmap 0x7401>; + dma-names = "fifo0", "fifo1"; adc { #io-channel-cells = <1>; @@ -219,6 +236,9 @@ assigned-clocks = <&k3_clks 1 3>; assigned-clock-rates = <60000000>; clock-names = "adc_tsc_fck"; + dmas = <&main_udmap 0x7402>, + <&main_udmap 0x7403>; + dma-names = "fifo0", "fifo1"; adc { #io-channel-cells = <1>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index a6c0d02d9928..24e534d85045 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -91,6 +91,7 @@ CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y CONFIG_ARM_QCOM_CPUFREQ_HW=y CONFIG_ARM_RASPBERRYPI_CPUFREQ=m CONFIG_ARM_TEGRA186_CPUFREQ=y +CONFIG_QORIQ_CPUFREQ=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_INTEL_STRATIX10_SERVICE=y @@ -155,6 +156,7 @@ CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_BRIDGE=m CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_NET_DSA=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y @@ -162,6 +164,10 @@ CONFIG_QRTR=m CONFIG_QRTR_SMD=m CONFIG_QRTR_TUN=m CONFIG_BPF_JIT=y +CONFIG_CAN=m +CONFIG_CAN_RCAR=m +CONFIG_CAN_RCAR_CANFD=m +CONFIG_CAN_FLEXCAN=m CONFIG_BT=m CONFIG_BT_HIDP=m # CONFIG_BT_HS is not set @@ -196,6 +202,7 @@ CONFIG_PCI_HOST_THUNDER_ECAM=y CONFIG_PCIE_ROCKCHIP_HOST=m CONFIG_PCIE_BRCMSTB=m CONFIG_PCI_LAYERSCAPE=y +CONFIG_PCIE_LAYERSCAPE_GEN4=y CONFIG_PCI_HISI=y CONFIG_PCIE_QCOM=y CONFIG_PCIE_ARMADA_8K=y @@ -208,11 +215,22 @@ CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_HISILICON_LPC=y CONFIG_SIMPLE_PM_BUS=y +CONFIG_FSL_MC_BUS=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_SST25L=y CONFIG_MTD_RAW_NAND=y CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_MARVELL=y +CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_NAND_QCOM=y CONFIG_MTD_SPI_NOR=y CONFIG_SPI_CADENCE_QUADSPI=y @@ -221,12 +239,14 @@ CONFIG_BLK_DEV_NBD=m CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_NVME=m CONFIG_SRAM=y +CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_MEGARAID_SAS=y CONFIG_SCSI_MPT3SAS=m CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PLATFORM=y @@ -254,6 +274,7 @@ CONFIG_MACVTAP=m CONFIG_TUN=y CONFIG_VETH=m CONFIG_VIRTIO_NET=y +CONFIG_NET_DSA_MSCC_FELIX=m CONFIG_AMD_XGBE=y CONFIG_NET_XGENE=y CONFIG_ATL1C=m @@ -262,12 +283,18 @@ CONFIG_BNX2X=m CONFIG_MACB=y CONFIG_THUNDER_NIC_PF=y CONFIG_FEC=y +CONFIG_FSL_FMAN=y +CONFIG_FSL_DPAA_ETH=y +CONFIG_FSL_DPAA2_ETH=y +CONFIG_FSL_ENETC=y +CONFIG_FSL_ENETC_VF=y CONFIG_HIX5HD2_GMAC=y CONFIG_HNS_DSAF=y CONFIG_HNS_ENET=y CONFIG_HNS3=y CONFIG_HNS3_HCLGE=y CONFIG_HNS3_ENET=y +CONFIG_E1000=y CONFIG_E1000E=y CONFIG_IGB=y CONFIG_IGBVF=y @@ -286,13 +313,17 @@ CONFIG_SNI_NETSEC=y CONFIG_STMMAC_ETH=m CONFIG_TI_K3_AM65_CPSW_NUSS=y CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_AQUANTIA_PHY=y CONFIG_MARVELL_PHY=m CONFIG_MARVELL_10G_PHY=m CONFIG_MESON_GXL_PHY=m CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y CONFIG_AT803X_PHY=y CONFIG_REALTEK_PHY=m CONFIG_ROCKCHIP_PHY=y +CONFIG_VITESSE_PHY=y CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m @@ -322,6 +353,7 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y +CONFIG_INPUT_PM8XXX_VIBRATOR=m CONFIG_INPUT_HISI_POWERKEY=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_AMBAKMI=y @@ -390,8 +422,11 @@ CONFIG_SPI=y CONFIG_SPI_ARMADA_3700=y CONFIG_SPI_BCM2835=m CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_FSL_LPSPI=y +CONFIG_SPI_FSL_QUADSPI=y CONFIG_SPI_NXP_FLEXSPI=y CONFIG_SPI_IMX=m +CONFIG_SPI_FSL_DSPI=y CONFIG_SPI_MESON_SPICC=m CONFIG_SPI_MESON_SPIFC=m CONFIG_SPI_ORION=y @@ -401,6 +436,7 @@ CONFIG_SPI_QCOM_QSPI=m CONFIG_SPI_QUP=y CONFIG_SPI_QCOM_GENI=m CONFIG_SPI_S3C64XX=y +CONFIG_SPI_SH_MSIOF=m CONFIG_SPI_SUN6I=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y @@ -411,9 +447,11 @@ CONFIG_PINCTRL_S700=y CONFIG_PINCTRL_S900=y CONFIG_PINCTRL_IMX8MM=y CONFIG_PINCTRL_IMX8MN=y +CONFIG_PINCTRL_IMX8MP=y CONFIG_PINCTRL_IMX8MQ=y CONFIG_PINCTRL_IMX8QXP=y CONFIG_PINCTRL_IPQ8074=y +CONFIG_PINCTRL_IPQ6018=y CONFIG_PINCTRL_MSM8916=y CONFIG_PINCTRL_MSM8994=y CONFIG_PINCTRL_MSM8996=y @@ -426,14 +464,17 @@ CONFIG_PINCTRL_SM8150=y CONFIG_GPIO_ALTERA=m CONFIG_GPIO_DWAPB=y CONFIG_GPIO_MB86S7X=y +CONFIG_GPIO_MPC8XXX=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_UNIPHIER=y +CONFIG_GPIO_WCD934X=m CONFIG_GPIO_XGENE=y CONFIG_GPIO_XGENE_SB=y CONFIG_GPIO_MAX732X=y CONFIG_GPIO_PCA953X=y CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_BD9571MWV=m CONFIG_GPIO_MAX77620=y CONFIG_POWER_AVS=y CONFIG_QCOM_CPR=y @@ -455,6 +496,8 @@ CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_QORIQ_THERMAL=m CONFIG_SUN8I_THERMAL=y +CONFIG_IMX_SC_THERMAL=m +CONFIG_IMX8MM_THERMAL=m CONFIG_ROCKCHIP_THERMAL=m CONFIG_RCAR_THERMAL=y CONFIG_RCAR_GEN3_THERMAL=y @@ -469,14 +512,15 @@ CONFIG_QCOM_SPMI_TEMP_ALARM=m CONFIG_UNIPHIER_THERMAL=y CONFIG_WATCHDOG=y CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ARM_SBSA_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_DW_WATCHDOG=y CONFIG_SUNXI_WATCHDOG=m CONFIG_IMX2_WDT=y CONFIG_IMX_SC_WDT=m +CONFIG_QCOM_WDT=m CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m -CONFIG_QCOM_WDT=m CONFIG_RENESAS_WDT=y CONFIG_UNIPHIER_WATCHDOG=y CONFIG_BCM2835_WDT=y @@ -492,6 +536,7 @@ CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y CONFIG_MFD_ROHM_BD718XX=y +CONFIG_MFD_WCD934X=m CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_BD718XX=y @@ -519,21 +564,28 @@ CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_DVB_NET is not set CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_RCAR_CSI2=m +CONFIG_VIDEO_RCAR_VIN=m CONFIG_VIDEO_SUN6I_CSI=m CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m CONFIG_VIDEO_SAMSUNG_S5P_MFC=m CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m +CONFIG_VIDEO_RENESAS_FDP1=m CONFIG_VIDEO_RENESAS_FCP=m CONFIG_VIDEO_RENESAS_VSP1=m +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_VIDEO_RCAR_DRIF=m CONFIG_DRM=m CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_MALI_DISPLAY=m CONFIG_DRM_NOUVEAU=m CONFIG_DRM_EXYNOS=m CONFIG_DRM_EXYNOS5433_DECON=y @@ -549,16 +601,23 @@ CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_RCAR_DU=m +CONFIG_DRM_RCAR_DW_HDMI=m CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN6I_DSI=m CONFIG_DRM_SUN8I_DW_HDMI=m CONFIG_DRM_SUN8I_MIXER=m CONFIG_DRM_MSM=m CONFIG_DRM_TEGRA=m +CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_DUMB_VGA_DAC=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m CONFIG_DRM_SII902X=m +CONFIG_DRM_THINE_THC63LVD1024=m CONFIG_DRM_TI_SN65DSI86=m CONFIG_DRM_I2C_ADV7511=m +CONFIG_DRM_DW_HDMI_AHB_AUDIO=m +CONFIG_DRM_DW_HDMI_CEC=m CONFIG_DRM_VC4=m CONFIG_DRM_ETNAVIV=m CONFIG_DRM_HISI_HIBMC=m @@ -583,6 +642,7 @@ CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_MESON_AXG_SOUND_CARD=m +CONFIG_SND_SOC_SDM845=m CONFIG_SND_SOC_ROCKCHIP=m CONFIG_SND_SOC_ROCKCHIP_SPDIF=m CONFIG_SND_SOC_ROCKCHIP_RT5645=m @@ -595,11 +655,13 @@ CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_PCM3168A_I2C=m CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m CONFIG_I2C_HID=m -CONFIG_USB=y CONFIG_USB_CONN_GPIO=m +CONFIG_USB=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_TEGRA=y @@ -609,6 +671,7 @@ CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_EXYNOS=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_RENESAS_USBHS_HCD=m CONFIG_USB_RENESAS_USBHS=m CONFIG_USB_STORAGE=y CONFIG_USB_MUSB_HDRC=y @@ -621,7 +684,6 @@ CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y CONFIG_USB_HSIC_USB3503=y CONFIG_NOP_USB_XCEIV=y -CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_USB_RENESAS_USB3=m @@ -669,11 +731,14 @@ CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_EDAC=y CONFIG_EDAC_GHES=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m +CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_PCF2127=m CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_CROS_EC=y CONFIG_RTC_DRV_S3C=y @@ -716,8 +781,8 @@ CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCPI=y CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_S2MPS11=y -CONFIG_CLK_QORIQ=y CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_VC5=y CONFIG_CLK_RASPBERRYPI=m CONFIG_CLK_IMX8MM=y CONFIG_CLK_IMX8MN=y @@ -731,12 +796,15 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_QCOM_CLK_RPMH=y CONFIG_IPQ_GCC_8074=y +CONFIG_IPQ_GCC_6018=y CONFIG_MSM_GCC_8916=y CONFIG_MSM_GCC_8994=y CONFIG_MSM_MMCC_8996=y CONFIG_MSM_GCC_8998=y CONFIG_QCS_GCC_404=y CONFIG_SDM_GCC_845=y +CONFIG_SDM_GPUCC_845=y +CONFIG_SDM_DISPCC_845=y CONFIG_SM_GCC_8150=y CONFIG_QCOM_HFPLL=y CONFIG_HWSPINLOCK=y @@ -758,11 +826,14 @@ CONFIG_QCOM_SYSMON=m CONFIG_RPMSG_QCOM_GLINK_RPM=y CONFIG_RPMSG_QCOM_GLINK_SMEM=m CONFIG_RPMSG_QCOM_SMD=y +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_QCOM=m CONFIG_OWL_PM_DOMAINS=y CONFIG_RASPBERRYPI_POWER=y +CONFIG_FSL_DPAA=y +CONFIG_FSL_MC_DPIO=y CONFIG_IMX_SCU_SOC=y CONFIG_QCOM_AOSS_QMP=y -CONFIG_QCOM_COMMAND_DB=y CONFIG_QCOM_GENI_SE=y CONFIG_QCOM_GLINK_SSR=m CONFIG_QCOM_RMTFS_MEM=m @@ -773,6 +844,7 @@ CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y CONFIG_QCOM_SOCINFO=m +CONFIG_QCOM_APR=m CONFIG_ARCH_R8A774A1=y CONFIG_ARCH_R8A774B1=y CONFIG_ARCH_R8A774C0=y @@ -784,7 +856,6 @@ CONFIG_ARCH_R8A77970=y CONFIG_ARCH_R8A77980=y CONFIG_ARCH_R8A77990=y CONFIG_ARCH_R8A77995=y -CONFIG_QCOM_PDC=y CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y @@ -795,9 +866,9 @@ CONFIG_ARCH_K3_J721E_SOC=y CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_EXTCON_USB_GPIO=y CONFIG_EXTCON_USBC_CROS_EC=y -CONFIG_MEMORY=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y +CONFIG_MAX9611=m CONFIG_QCOM_SPMI_ADC5=m CONFIG_ROCKCHIP_SARADC=m CONFIG_IIO_CROS_EC_SENSORS_CORE=m @@ -815,6 +886,7 @@ CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y CONFIG_PWM_SUN4I=m CONFIG_PWM_TEGRA=m +CONFIG_QCOM_PDC=y CONFIG_RESET_QCOM_AOSS=y CONFIG_RESET_QCOM_PDC=m CONFIG_RESET_TI_SCI=y @@ -858,6 +930,10 @@ CONFIG_FPGA_REGION=m CONFIG_OF_FPGA_REGION=m CONFIG_TEE=y CONFIG_OPTEE=y +CONFIG_SLIMBUS=m +CONFIG_SLIM_QCOM_CTRL=m +CONFIG_SLIM_QCOM_NGD_CTRL=m +CONFIG_MUX_MMIO=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_POSIX_ACL=y @@ -886,16 +962,18 @@ CONFIG_NLS_ISO8859_1=y CONFIG_SECURITY=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_DEV_SUN8I_CE=m CONFIG_CRYPTO_DEV_FSL_CAAM=m -CONFIG_CRYPTO_DEV_HISI_ZIP=m -CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m CONFIG_CRYPTO_DEV_QCOM_RNG=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_HISI_ZIP=m CONFIG_CMA_SIZE_MBYTES=32 CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arm64/crypto/.gitignore b/arch/arm64/crypto/.gitignore index e403b1343328..fcf2d731e6c1 100644 --- a/arch/arm64/crypto/.gitignore +++ b/arch/arm64/crypto/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only sha256-core.S sha512-core.S poly1305-core.S diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index 3fe02da70004..fc1594a0710e 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -4,6 +4,8 @@ #ifdef CONFIG_ARCH_RANDOM +#include <linux/bug.h> +#include <linux/kernel.h> #include <linux/random.h> #include <asm/cpufeature.h> @@ -66,6 +68,18 @@ static inline bool __init __early_cpu_has_rndr(void) return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf; } +static inline bool __init __must_check +arch_get_random_seed_long_early(unsigned long *v) +{ + WARN_ON(system_state != SYSTEM_BOOTING); + + if (!__early_cpu_has_rndr()) + return false; + + return __arm64_rndr(v); +} +#define arch_get_random_seed_long_early arch_get_random_seed_long_early + #else static inline bool __arm64_rndr(unsigned long *v) { return false; } diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 2be67b232499..a1871bb32bb1 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -120,22 +120,12 @@ /* * Alignment of kernel segments (e.g. .text, .data). - */ -#if defined(CONFIG_DEBUG_ALIGN_RODATA) -/* - * 4 KB granule: 1 level 2 entry - * 16 KB granule: 128 level 3 entries, with contiguous bit - * 64 KB granule: 32 level 3 entries, with contiguous bit - */ -#define SEGMENT_ALIGN SZ_2M -#else -/* + * * 4 KB granule: 16 level 3 entries, with contiguous bit * 16 KB granule: 4 level 3 entries, without contiguous bit * 64 KB granule: 1 level 3 entry */ #define SEGMENT_ALIGN SZ_64K -#endif /* * Memory types available. diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 75d6cd23a679..c01b52add377 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -36,9 +36,7 @@ extern int pfn_valid(unsigned long); #endif /* !__ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #include <asm-generic/getorder.h> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index ebc622432831..c4ac0ac25a00 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -49,7 +49,9 @@ #ifndef CONFIG_BROKEN_GAS_INST #ifdef __ASSEMBLY__ -#define __emit_inst(x) .inst (x) +// The space separator is omitted so that __emit_inst(x) can be parsed as +// either an assembler directive or an assembler macro argument. +#define __emit_inst(x) .inst(x) #else #define __emit_inst(x) ".inst " __stringify((x)) "\n\t" #endif diff --git a/arch/arm64/kernel/.gitignore b/arch/arm64/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/arm64/kernel/.gitignore +++ b/arch/arm64/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 4cc581af2d96..c19aa81ddc8c 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -601,7 +601,7 @@ static struct undef_hook setend_hooks[] = { }, { /* Thumb mode */ - .instr_mask = 0x0000fff7, + .instr_mask = 0xfffffff7, .instr_val = 0x0000b650, .pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK), .pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR), diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 354b11e27c07..033a48f30dbb 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -260,18 +260,7 @@ static int __aarch32_alloc_vdso_pages(void) if (ret) return ret; - ret = aarch32_alloc_kuser_vdso_page(); - if (ret) { - unsigned long c_vvar = - (unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]); - unsigned long c_vdso = - (unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]); - - free_page(c_vvar); - free_page(c_vdso); - } - - return ret; + return aarch32_alloc_kuser_vdso_page(); } #else static int __aarch32_alloc_vdso_pages(void) diff --git a/arch/arm64/kernel/vdso/.gitignore b/arch/arm64/kernel/vdso/.gitignore index f8b69d84238e..652e31d82582 100644 --- a/arch/arm64/kernel/vdso/.gitignore +++ b/arch/arm64/kernel/vdso/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds diff --git a/arch/arm64/kernel/vdso32/.gitignore b/arch/arm64/kernel/vdso32/.gitignore index 4fea950fa5ed..3542fa24e26b 100644 --- a/arch/arm64/kernel/vdso32/.gitignore +++ b/arch/arm64/kernel/vdso32/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds vdso.so.raw diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index a475c68cbfec..449386d76441 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -64,6 +64,4 @@ config KVM_ARM_PMU config KVM_INDIRECT_VECTORS def_bool KVM && (HARDEN_BRANCH_PREDICTOR || HARDEN_EL2_VECTORS) -source "drivers/vhost/Kconfig" - endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 8417b200bec9..863a0d158fb8 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -197,6 +197,13 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) } memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id)); + + if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { + int i; + + for (i = 0; i < 16; i++) + *vcpu_reg32(vcpu, i) = (u32)*vcpu_reg32(vcpu, i); + } out: return err; } diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S index d22d0534dd60..90186cf6473e 100644 --- a/arch/arm64/kvm/hyp/entry.S +++ b/arch/arm64/kvm/hyp/entry.S @@ -18,6 +18,7 @@ #define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x) #define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x) +#define CPU_SP_EL0_OFFSET (CPU_XREG_OFFSET(30) + 8) .text .pushsection .hyp.text, "ax" @@ -47,6 +48,16 @@ ldp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] .endm +.macro save_sp_el0 ctxt, tmp + mrs \tmp, sp_el0 + str \tmp, [\ctxt, #CPU_SP_EL0_OFFSET] +.endm + +.macro restore_sp_el0 ctxt, tmp + ldr \tmp, [\ctxt, #CPU_SP_EL0_OFFSET] + msr sp_el0, \tmp +.endm + /* * u64 __guest_enter(struct kvm_vcpu *vcpu, * struct kvm_cpu_context *host_ctxt); @@ -60,6 +71,9 @@ SYM_FUNC_START(__guest_enter) // Store the host regs save_callee_saved_regs x1 + // Save the host's sp_el0 + save_sp_el0 x1, x2 + // Now the host state is stored if we have a pending RAS SError it must // affect the host. If any asynchronous exception is pending we defer // the guest entry. The DSB isn't necessary before v8.2 as any SError @@ -83,6 +97,9 @@ alternative_else_nop_endif // when this feature is enabled for kernel code. ptrauth_switch_to_guest x29, x0, x1, x2 + // Restore the guest's sp_el0 + restore_sp_el0 x29, x0 + // Restore guest regs x0-x17 ldp x0, x1, [x29, #CPU_XREG_OFFSET(0)] ldp x2, x3, [x29, #CPU_XREG_OFFSET(2)] @@ -130,6 +147,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) // Store the guest regs x18-x29, lr save_callee_saved_regs x1 + // Store the guest's sp_el0 + save_sp_el0 x1, x2 + get_host_ctxt x2, x3 // Macro ptrauth_switch_to_guest format: @@ -139,6 +159,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) // when this feature is enabled for kernel code. ptrauth_switch_to_host x1, x2, x3, x4, x5 + // Restore the hosts's sp_el0 + restore_sp_el0 x2, x3 + // Now restore the host regs restore_callee_saved_regs x2 diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index c2a13ab3c471..9c5cfb04170e 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -198,7 +198,6 @@ SYM_CODE_END(__hyp_panic) .macro invalid_vector label, target = __hyp_panic .align 2 SYM_CODE_START(\label) -\label: b \target SYM_CODE_END(\label) .endm diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 75b1925763f1..6d2df9fe0b5d 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -15,8 +15,9 @@ /* * Non-VHE: Both host and guest must save everything. * - * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and pstate, - * which are handled as part of the el2 return state) on every switch. + * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and + * pstate, which are handled as part of the el2 return state) on every + * switch (sp_el0 is being dealt with in the assembly code). * tpidr_el0 and tpidrro_el0 only need to be switched when going * to host userspace or a different VCPU. EL1 registers only need to be * switched when potentially going to run a different VCPU. The latter two @@ -26,12 +27,6 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1); - - /* - * The host arm64 Linux uses sp_el0 to point to 'current' and it must - * therefore be saved/restored on every entry/exit to/from the guest. - */ - ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); } static void __hyp_text __sysreg_save_user_state(struct kvm_cpu_context *ctxt) @@ -99,12 +94,6 @@ NOKPROBE_SYMBOL(sysreg_save_guest_state_vhe); static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) { write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1); - - /* - * The host arm64 Linux uses sp_el0 to point to 'current' and it must - * therefore be saved/restored on every entry/exit to/from the guest. - */ - write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); } static void __hyp_text __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 1027851d469a..c9cedc0432d2 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -445,7 +445,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, const struct fault_info *inf; struct mm_struct *mm = current->mm; vm_fault_t fault, major = 0; - unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; + unsigned long vm_flags = VM_ACCESS_FLAGS; unsigned int mm_flags = FAULT_FLAG_DEFAULT; if (kprobe_page_fault(regs, esr)) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index b65dffdfb201..e42727e3568e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -29,6 +29,7 @@ #include <linux/mm.h> #include <linux/kexec.h> #include <linux/crash_dump.h> +#include <linux/hugetlb.h> #include <asm/boot.h> #include <asm/fixmap.h> @@ -457,6 +458,11 @@ void __init arm64_memblock_init(void) high_memory = __va(memblock_end_of_DRAM() - 1) + 1; dma_contiguous_reserve(arm64_dma32_phys_limit); + +#ifdef CONFIG_ARM64_4K_PAGES + hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); +#endif + } void __init bootmem_init(void) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 9b08f7c7e6f0..a374e4f51a62 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1374,7 +1374,7 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) } int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { int ret, flags = 0; @@ -1382,12 +1382,13 @@ int arch_add_memory(int nid, u64 start, u64 size, flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), - size, PAGE_KERNEL, __pgd_pgtable_alloc, flags); + size, params->pgprot, __pgd_pgtable_alloc, + flags); memblock_clear_nomap(start, size); ret = __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, - restrictions); + params); if (ret) __remove_pgd_mapping(swapper_pg_dir, __phys_to_virt(start), size); diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h index 70db1e7632bc..40079899084d 100644 --- a/arch/c6x/include/asm/page.h +++ b/arch/c6x/include/asm/page.h @@ -2,10 +2,7 @@ #ifndef _ASM_C6X_PAGE_H #define _ASM_C6X_PAGE_H -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #include <asm-generic/page.h> diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h index b56ba7110f5a..d628cc170564 100644 --- a/arch/c6x/include/asm/unaligned.h +++ b/arch/c6x/include/asm/unaligned.h @@ -10,6 +10,7 @@ #define _ASM_C6X_UNALIGNED_H #include <linux/swab.h> +#include <linux/unaligned/generic.h> /* * The C64x+ can do unaligned word and dword accesses in hardware @@ -100,68 +101,4 @@ static inline void put_unaligned64(u64 val, const void *p) #endif -/* - * Cause a link-time error if we try an unaligned access other than - * 1,2,4 or 8 bytes long - */ -extern int __bad_unaligned_access_size(void); - -#define __get_unaligned_le(ptr) (typeof(*(ptr)))({ \ - sizeof(*(ptr)) == 1 ? *(ptr) : \ - (sizeof(*(ptr)) == 2 ? get_unaligned_le16((ptr)) : \ - (sizeof(*(ptr)) == 4 ? get_unaligned_le32((ptr)) : \ - (sizeof(*(ptr)) == 8 ? get_unaligned_le64((ptr)) : \ - __bad_unaligned_access_size()))); \ - }) - -#define __get_unaligned_be(ptr) (__force typeof(*(ptr)))({ \ - sizeof(*(ptr)) == 1 ? *(ptr) : \ - (sizeof(*(ptr)) == 2 ? get_unaligned_be16((ptr)) : \ - (sizeof(*(ptr)) == 4 ? get_unaligned_be32((ptr)) : \ - (sizeof(*(ptr)) == 8 ? get_unaligned_be64((ptr)) : \ - __bad_unaligned_access_size()))); \ - }) - -#define __put_unaligned_le(val, ptr) ({ \ - void *__gu_p = (ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - *(u8 *)__gu_p = (__force u8)(val); \ - break; \ - case 2: \ - put_unaligned_le16((__force u16)(val), __gu_p); \ - break; \ - case 4: \ - put_unaligned_le32((__force u32)(val), __gu_p); \ - break; \ - case 8: \ - put_unaligned_le64((__force u64)(val), __gu_p); \ - break; \ - default: \ - __bad_unaligned_access_size(); \ - break; \ - } \ - (void)0; }) - -#define __put_unaligned_be(val, ptr) ({ \ - void *__gu_p = (ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - *(u8 *)__gu_p = (__force u8)(val); \ - break; \ - case 2: \ - put_unaligned_be16((__force u16)(val), __gu_p); \ - break; \ - case 4: \ - put_unaligned_be32((__force u32)(val), __gu_p); \ - break; \ - case 8: \ - put_unaligned_be64((__force u64)(val), __gu_p); \ - break; \ - default: \ - __bad_unaligned_access_size(); \ - break; \ - } \ - (void)0; }) - #endif /* _ASM_C6X_UNALIGNED_H */ diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 047427f71d83..94545d50d40f 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -3,6 +3,7 @@ config CSKY def_bool y select ARCH_32BIT_OFF_T select ARCH_HAS_DMA_PREP_COHERENT + select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_USE_BUILTIN_BSWAP @@ -38,16 +39,22 @@ config CSKY select HAVE_ARCH_AUDITSYSCALL select HAVE_COPY_THREAD_TLS select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FTRACE_MCOUNT_RECORD select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA + select HAVE_KPROBES if !CPU_CK610 + select HAVE_KPROBES_ON_FTRACE if !CPU_CK610 + select HAVE_KRETPROBES if !CPU_CK610 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_DMA_CONTIGUOUS + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RSEQ select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS select MAY_HAVE_SPARSE_IRQ @@ -65,6 +72,12 @@ config CSKY select PCI_SYSCALL if PCI select PCI_MSI if PCI +config LOCKDEP_SUPPORT + def_bool y + +config ARCH_SUPPORTS_UPROBES + def_bool y if !CPU_CK610 + config CPU_HAS_CACHEV2 bool diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h index f35a9f3315ee..5056ebb902d1 100644 --- a/arch/csky/abiv1/inc/abi/entry.h +++ b/arch/csky/abiv1/inc/abi/entry.h @@ -172,10 +172,7 @@ addi r6, 0xe cpwcr r6, cpcr30 - lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0xe + movi r6, 0 cpwcr r6, cpcr31 .endm diff --git a/arch/csky/abiv2/fpu.c b/arch/csky/abiv2/fpu.c index 86d187d4e5af..5acc5c2e544e 100644 --- a/arch/csky/abiv2/fpu.c +++ b/arch/csky/abiv2/fpu.c @@ -10,11 +10,6 @@ #define MTCR_DIST 0xC0006420 #define MFCR_DIST 0xC0006020 -void __init init_fpu(void) -{ - mtcr("cr<1, 2>", 0); -} - /* * fpu_libc_helper() is to help libc to excute: * - mfcr %a, cr<1, 2> diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index 94a7a58765df..a99aff555a0a 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -100,6 +100,66 @@ rte .endm +.macro SAVE_REGS_FTRACE + subi sp, 152 + stw tls, (sp, 0) + stw lr, (sp, 4) + + mfcr lr, psr + stw lr, (sp, 12) + + addi lr, sp, 152 + stw lr, (sp, 16) + + stw a0, (sp, 20) + stw a0, (sp, 24) + stw a1, (sp, 28) + stw a2, (sp, 32) + stw a3, (sp, 36) + + addi sp, 40 + stm r4-r13, (sp) + + addi sp, 40 + stm r16-r30, (sp) +#ifdef CONFIG_CPU_HAS_HILO + mfhi lr + stw lr, (sp, 60) + mflo lr + stw lr, (sp, 64) + mfcr lr, cr14 + stw lr, (sp, 68) +#endif + subi sp, 80 +.endm + +.macro RESTORE_REGS_FTRACE + ldw tls, (sp, 0) + ldw a0, (sp, 16) + mtcr a0, ss0 + +#ifdef CONFIG_CPU_HAS_HILO + ldw a0, (sp, 140) + mthi a0 + ldw a0, (sp, 144) + mtlo a0 + ldw a0, (sp, 148) + mtcr a0, cr14 +#endif + + ldw a0, (sp, 24) + ldw a1, (sp, 28) + ldw a2, (sp, 32) + ldw a3, (sp, 36) + + addi sp, 40 + ldm r4-r13, (sp) + addi sp, 40 + ldm r16-r30, (sp) + addi sp, 72 + mfcr sp, ss0 +.endm + .macro SAVE_SWITCH_STACK subi sp, 64 stm r4-r11, (sp) @@ -230,11 +290,8 @@ addi r6, 0x1ce mtcr r6, cr<30, 15> /* Set MSA0 */ - lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0x1ce - mtcr r6, cr<31, 15> /* Set MSA1 */ + movi r6, 0 + mtcr r6, cr<31, 15> /* Clr MSA1 */ /* enable MMU */ mfcr r6, cr18 diff --git a/arch/csky/abiv2/inc/abi/fpu.h b/arch/csky/abiv2/inc/abi/fpu.h index 22ca3cf2794a..09e2700a3693 100644 --- a/arch/csky/abiv2/inc/abi/fpu.h +++ b/arch/csky/abiv2/inc/abi/fpu.h @@ -9,7 +9,8 @@ int fpu_libc_helper(struct pt_regs *regs); void fpu_fpe(struct pt_regs *regs); -void __init init_fpu(void); + +static inline void init_fpu(void) { mtcr("cr<1, 2>", 0); } void save_to_user_fp(struct user_fp *user_fp); void restore_from_user_fp(struct user_fp *user_fp); diff --git a/arch/csky/abiv2/mcount.S b/arch/csky/abiv2/mcount.S index 326402e65f9e..9331c7ed5958 100644 --- a/arch/csky/abiv2/mcount.S +++ b/arch/csky/abiv2/mcount.S @@ -3,6 +3,8 @@ #include <linux/linkage.h> #include <asm/ftrace.h> +#include <abi/entry.h> +#include <asm/asm-offsets.h> /* * csky-gcc with -pg will put the following asm after prologue: @@ -44,6 +46,22 @@ jmp t1 .endm +.macro mcount_enter_regs + subi sp, 8 + stw lr, (sp, 0) + stw r8, (sp, 4) + SAVE_REGS_FTRACE +.endm + +.macro mcount_exit_regs + RESTORE_REGS_FTRACE + ldw t1, (sp, 0) + ldw r8, (sp, 4) + ldw lr, (sp, 8) + addi sp, 12 + jmp t1 +.endm + .macro save_return_regs subi sp, 16 stw a0, (sp, 0) @@ -122,6 +140,8 @@ ENTRY(ftrace_caller) ldw a0, (sp, 16) subi a0, 4 ldw a1, (sp, 24) + lrw a2, function_trace_op + ldw a2, (a2, 0) nop GLOBAL(ftrace_call) @@ -157,3 +177,31 @@ ENTRY(return_to_handler) jmp lr END(return_to_handler) #endif + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +ENTRY(ftrace_regs_caller) + mcount_enter_regs + + lrw t1, PT_FRAME_SIZE + add t1, sp + + ldw a0, (t1, 0) + subi a0, 4 + ldw a1, (t1, 8) + lrw a2, function_trace_op + ldw a2, (a2, 0) + mov a3, sp + + nop +GLOBAL(ftrace_regs_call) + nop32_stub + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + nop +GLOBAL(ftrace_graph_regs_call) + nop32_stub +#endif + + mcount_exit_regs +ENDPROC(ftrace_regs_caller) +#endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h index ba35d93ecda2..fae72b0b1374 100644 --- a/arch/csky/include/asm/ftrace.h +++ b/arch/csky/include/asm/ftrace.h @@ -10,6 +10,8 @@ #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +#define ARCH_SUPPORTS_FTRACE_OPS 1 + #define MCOUNT_ADDR ((unsigned long)_mcount) #ifndef __ASSEMBLY__ diff --git a/arch/csky/include/asm/kprobes.h b/arch/csky/include/asm/kprobes.h new file mode 100644 index 000000000000..b647bbde4d6d --- /dev/null +++ b/arch/csky/include/asm/kprobes.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_CSKY_KPROBES_H +#define __ASM_CSKY_KPROBES_H + +#include <asm-generic/kprobes.h> + +#ifdef CONFIG_KPROBES +#include <linux/types.h> +#include <linux/ptrace.h> +#include <linux/percpu.h> + +#define __ARCH_WANT_KPROBES_INSN_SLOT +#define MAX_INSN_SIZE 1 + +#define flush_insn_slot(p) do { } while (0) +#define kretprobe_blacklist_size 0 + +#include <asm/probes.h> + +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* Single step context for kprobe */ +struct kprobe_step_ctx { + unsigned long ss_pending; + unsigned long match_addr; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + unsigned long saved_sr; + struct prev_kprobe prev_kprobe; + struct kprobe_step_ctx ss_ctx; +}; + +void arch_remove_kprobe(struct kprobe *p); +int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); +int kprobe_breakpoint_handler(struct pt_regs *regs); +int kprobe_single_step_handler(struct pt_regs *regs); +void kretprobe_trampoline(void); +void __kprobes *trampoline_probe_handler(struct pt_regs *regs); + +#endif /* CONFIG_KPROBES */ +#endif /* __ASM_CSKY_KPROBES_H */ diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h index 9738eacefdc7..9b98bf31d57c 100644 --- a/arch/csky/include/asm/page.h +++ b/arch/csky/include/asm/page.h @@ -85,9 +85,6 @@ extern unsigned long va_pa_offset; PHYS_OFFSET_OFFSET) #define virt_to_page(x) (mem_map + MAP_NR(x)) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #define pfn_to_kaddr(x) __va(PFN_PHYS(x)) #include <asm-generic/memory_model.h> diff --git a/arch/csky/include/asm/pgtable.h b/arch/csky/include/asm/pgtable.h index 9b7764cb7645..9ab4a445ad99 100644 --- a/arch/csky/include/asm/pgtable.h +++ b/arch/csky/include/asm/pgtable.h @@ -110,9 +110,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; extern void load_pgd(unsigned long pg_dir); extern pte_t invalid_pte_table[PTRS_PER_PTE]; -static inline int pte_special(pte_t pte) { return 0; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - static inline void set_pte(pte_t *p, pte_t pte) { *p = pte; diff --git a/arch/csky/include/asm/probes.h b/arch/csky/include/asm/probes.h new file mode 100644 index 000000000000..5e526334e6f9 --- /dev/null +++ b/arch/csky/include/asm/probes.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_PROBES_H +#define __ASM_CSKY_PROBES_H + +typedef u32 probe_opcode_t; +typedef void (probes_handler_t) (u32 opcode, long addr, struct pt_regs *); + +/* architecture specific copy of original instruction */ +struct arch_probe_insn { + probe_opcode_t *insn; + probes_handler_t *handler; + /* restore address after simulation */ + unsigned long restore; +}; + +#ifdef CONFIG_KPROBES +typedef u32 kprobe_opcode_t; +struct arch_specific_insn { + struct arch_probe_insn api; +}; +#endif + +#endif /* __ASM_CSKY_PROBES_H */ diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h index 21e0bd5293dd..c6bcd7f7c720 100644 --- a/arch/csky/include/asm/processor.h +++ b/arch/csky/include/asm/processor.h @@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[]; struct thread_struct { unsigned long ksp; /* kernel stack pointer */ unsigned long sr; /* saved status register */ + unsigned long trap_no; /* saved status register */ /* FPU regs */ struct user_fp __aligned(16) user_fp; diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index d0aba7b32417..aae5aa96cf54 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -7,11 +7,14 @@ #include <uapi/asm/ptrace.h> #include <asm/traps.h> #include <linux/types.h> +#include <linux/compiler.h> #ifndef __ASSEMBLY__ #define PS_S 0x80000000 /* Supervisor Mode */ +#define USR_BKPT 0x1464 + #define arch_has_single_step() (1) #define current_pt_regs() \ ({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) @@ -22,6 +25,18 @@ #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +static inline void instruction_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->pc = val; +} + +#if defined(__CSKYABIV2__) +#define MAX_REG_OFFSET offsetof(struct pt_regs, dcsr) +#else +#define MAX_REG_OFFSET offsetof(struct pt_regs, regs[9]) +#endif + static inline bool in_syscall(struct pt_regs const *regs) { return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; @@ -37,5 +52,33 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) return regs->a0; } +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->usp; +} + +extern int regs_query_register_offset(const char *name); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +/* + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + + return *(unsigned long *)((unsigned long)regs + offset); +} + #endif /* __ASSEMBLY__ */ #endif /* __ASM_CSKY_PTRACE_H */ diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h index 0b546a55a8bf..442fedad0260 100644 --- a/arch/csky/include/asm/thread_info.h +++ b/arch/csky/include/asm/thread_info.h @@ -57,6 +57,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_TRACE 3 /* syscall trace active */ #define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing */ +#define TIF_UPROBE 6 /* uprobe breakpoint or singlestep */ #define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ @@ -68,6 +69,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +#define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) diff --git a/arch/csky/include/asm/uprobes.h b/arch/csky/include/asm/uprobes.h new file mode 100644 index 000000000000..600388eb93c6 --- /dev/null +++ b/arch/csky/include/asm/uprobes.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_CSKY_UPROBES_H +#define __ASM_CSKY_UPROBES_H + +#include <asm/probes.h> + +#define MAX_UINSN_BYTES 4 + +#define UPROBE_SWBP_INSN USR_BKPT +#define UPROBE_SWBP_INSN_SIZE 2 +#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES + +typedef u32 uprobe_opcode_t; + +struct arch_uprobe_task { + unsigned long saved_trap_no; +}; + +struct arch_uprobe { + union { + u8 insn[MAX_UINSN_BYTES]; + u8 ixol[MAX_UINSN_BYTES]; + }; + struct arch_probe_insn api; + unsigned long insn_size; + bool simulate; +}; + +int uprobe_breakpoint_handler(struct pt_regs *regs); +int uprobe_single_step_handler(struct pt_regs *regs); + +#endif /* __ASM_CSKY_UPROBES_H */ diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile index 071d659f37b7..fd6d9dc8b7f3 100644 --- a/arch/csky/kernel/Makefile +++ b/arch/csky/kernel/Makefile @@ -4,6 +4,7 @@ extra-y := head.o vmlinux.lds obj-y += entry.o atomic.o signal.o traps.o irq.o time.o vdso.o obj-y += power.o syscall.o syscall_table.o setup.o obj-y += process.o cpu-probe.o ptrace.o dumpstack.o +obj-y += probes/ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/csky/kernel/asm-offsets.c b/arch/csky/kernel/asm-offsets.c index 9b48b1b1a61b..f8be348df9e4 100644 --- a/arch/csky/kernel/asm-offsets.c +++ b/arch/csky/kernel/asm-offsets.c @@ -72,6 +72,7 @@ int main(void) DEFINE(PT_RLO, offsetof(struct pt_regs, rlo)); #endif DEFINE(PT_USP, offsetof(struct pt_regs, usp)); + DEFINE(PT_FRAME_SIZE, sizeof(struct pt_regs)); /* offsets into the irq_cpustat_t struct */ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index 007706328000..364819536f2e 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -128,7 +128,10 @@ tlbop_end 1 ENTRY(csky_systemcall) SAVE_ALL TRAP0_SIZE zero_fp - +#ifdef CONFIG_RSEQ_DEBUG + mov a0, sp + jbsr rseq_syscall +#endif psrset ee, ie lrw r11, __NR_syscalls @@ -218,10 +221,17 @@ ret_from_exception: andn r9, r10 ldw r12, (r9, TINFO_FLAGS) - andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED) + andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | _TIF_UPROBE) cmpnei r12, 0 bt exit_work 1: +#ifdef CONFIG_TRACE_IRQFLAGS + ld r10, (sp, LSAVE_PSR) + btsti r10, 6 + bf 2f + jbsr trace_hardirqs_on +2: +#endif RESTORE_ALL exit_work: @@ -277,6 +287,10 @@ ENTRY(csky_irq) zero_fp psrset ee +#ifdef CONFIG_TRACE_IRQFLAGS + jbsr trace_hardirqs_off +#endif + #ifdef CONFIG_PREEMPTION mov r9, sp /* Get current stack pointer */ bmaski r10, THREAD_SHIFT diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c index 44f4880179b7..44628e3f7fa6 100644 --- a/arch/csky/kernel/ftrace.c +++ b/arch/csky/kernel/ftrace.c @@ -3,6 +3,7 @@ #include <linux/ftrace.h> #include <linux/uaccess.h> +#include <linux/stop_machine.h> #include <asm/cacheflush.h> #ifdef CONFIG_DYNAMIC_FTRACE @@ -126,6 +127,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func) { int ret = ftrace_modify_code((unsigned long)&ftrace_call, (unsigned long)func, true, true); + if (!ret) + ret = ftrace_modify_code((unsigned long)&ftrace_regs_call, + (unsigned long)func, true, true); return ret; } @@ -135,6 +139,14 @@ int __init ftrace_dyn_arch_init(void) } #endif /* CONFIG_DYNAMIC_FTRACE */ +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, + unsigned long addr) +{ + return ftrace_modify_code(rec->ip, addr, true, true); +} +#endif + #ifdef CONFIG_FUNCTION_GRAPH_TRACER void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, unsigned long frame_pointer) @@ -190,5 +202,35 @@ int ftrace_disable_ftrace_graph_caller(void) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ +#ifndef CONFIG_CPU_HAS_ICACHE_INS +struct ftrace_modify_param { + int command; + atomic_t cpu_count; +}; + +static int __ftrace_modify_code(void *data) +{ + struct ftrace_modify_param *param = data; + + if (atomic_inc_return(¶m->cpu_count) == 1) { + ftrace_modify_all_code(param->command); + atomic_inc(¶m->cpu_count); + } else { + while (atomic_read(¶m->cpu_count) <= num_online_cpus()) + cpu_relax(); + local_icache_inv_all(NULL); + } + + return 0; +} + +void arch_ftrace_update_code(int command) +{ + struct ftrace_modify_param param = { command, ATOMIC_INIT(0) }; + + stop_machine(__ftrace_modify_code, ¶m, cpu_online_mask); +} +#endif + /* _mcount is defined in abi's mcount.S */ EXPORT_SYMBOL(_mcount); diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S index 61989f9241c0..17ed9d250480 100644 --- a/arch/csky/kernel/head.S +++ b/arch/csky/kernel/head.S @@ -21,6 +21,11 @@ END(_start) ENTRY(_start_smp_secondary) SETUP_MMU + /* copy msa1 from CPU0 */ + lrw r6, secondary_msa1 + ld.w r6, (r6, 0) + mtcr r6, cr<31, 15> + /* set stack point */ lrw r6, secondary_stack ld.w r6, (r6, 0) diff --git a/arch/csky/kernel/probes/Makefile b/arch/csky/kernel/probes/Makefile new file mode 100644 index 000000000000..1c7c6e6cb25b --- /dev/null +++ b/arch/csky/kernel/probes/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o +obj-$(CONFIG_KPROBES) += kprobes_trampoline.o +obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o +obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o + +CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE) diff --git a/arch/csky/kernel/probes/decode-insn.c b/arch/csky/kernel/probes/decode-insn.c new file mode 100644 index 000000000000..bbc4edc25dc9 --- /dev/null +++ b/arch/csky/kernel/probes/decode-insn.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <linux/kernel.h> +#include <linux/kprobes.h> +#include <linux/module.h> +#include <linux/kallsyms.h> +#include <asm/sections.h> + +#include "decode-insn.h" +#include "simulate-insn.h" + +/* Return: + * INSN_REJECTED If instruction is one not allowed to kprobe, + * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot. + */ +enum probe_insn __kprobes +csky_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api) +{ + probe_opcode_t insn = le32_to_cpu(*addr); + + CSKY_INSN_SET_SIMULATE(br16, insn); + CSKY_INSN_SET_SIMULATE(bt16, insn); + CSKY_INSN_SET_SIMULATE(bf16, insn); + CSKY_INSN_SET_SIMULATE(jmp16, insn); + CSKY_INSN_SET_SIMULATE(jsr16, insn); + CSKY_INSN_SET_SIMULATE(lrw16, insn); + CSKY_INSN_SET_SIMULATE(pop16, insn); + + CSKY_INSN_SET_SIMULATE(br32, insn); + CSKY_INSN_SET_SIMULATE(bt32, insn); + CSKY_INSN_SET_SIMULATE(bf32, insn); + CSKY_INSN_SET_SIMULATE(jmp32, insn); + CSKY_INSN_SET_SIMULATE(jsr32, insn); + CSKY_INSN_SET_SIMULATE(lrw32, insn); + CSKY_INSN_SET_SIMULATE(pop32, insn); + + CSKY_INSN_SET_SIMULATE(bez32, insn); + CSKY_INSN_SET_SIMULATE(bnez32, insn); + CSKY_INSN_SET_SIMULATE(bnezad32, insn); + CSKY_INSN_SET_SIMULATE(bhsz32, insn); + CSKY_INSN_SET_SIMULATE(bhz32, insn); + CSKY_INSN_SET_SIMULATE(blsz32, insn); + CSKY_INSN_SET_SIMULATE(blz32, insn); + CSKY_INSN_SET_SIMULATE(bsr32, insn); + CSKY_INSN_SET_SIMULATE(jmpi32, insn); + CSKY_INSN_SET_SIMULATE(jsri32, insn); + + return INSN_GOOD; +} diff --git a/arch/csky/kernel/probes/decode-insn.h b/arch/csky/kernel/probes/decode-insn.h new file mode 100644 index 000000000000..9c4ad48fee0d --- /dev/null +++ b/arch/csky/kernel/probes/decode-insn.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __CSKY_KERNEL_KPROBES_DECODE_INSN_H +#define __CSKY_KERNEL_KPROBES_DECODE_INSN_H + +#include <asm/sections.h> +#include <asm/kprobes.h> + +enum probe_insn { + INSN_REJECTED, + INSN_GOOD_NO_SLOT, + INSN_GOOD, +}; + +#define is_insn32(insn) ((insn & 0xc000) == 0xc000) + +enum probe_insn __kprobes +csky_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *asi); + +#endif /* __CSKY_KERNEL_KPROBES_DECODE_INSN_H */ diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c new file mode 100644 index 000000000000..5264763d05be --- /dev/null +++ b/arch/csky/kernel/probes/ftrace.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/kprobes.h> + +int arch_check_ftrace_location(struct kprobe *p) +{ + if (ftrace_location((unsigned long)p->addr)) + p->flags |= KPROBE_FLAG_FTRACE; + return 0; +} + +/* Ftrace callback handler for kprobes -- called under preepmt disabed */ +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *ops, struct pt_regs *regs) +{ + bool lr_saver = false; + struct kprobe *p; + struct kprobe_ctlblk *kcb; + + /* Preempt is disabled by ftrace */ + p = get_kprobe((kprobe_opcode_t *)ip); + if (!p) { + p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE)); + if (unlikely(!p) || kprobe_disabled(p)) + return; + lr_saver = true; + } + + kcb = get_kprobe_ctlblk(); + if (kprobe_running()) { + kprobes_inc_nmissed_count(p); + } else { + unsigned long orig_ip = instruction_pointer(regs); + + if (lr_saver) + ip -= MCOUNT_INSN_SIZE; + instruction_pointer_set(regs, ip); + __this_cpu_write(current_kprobe, p); + kcb->kprobe_status = KPROBE_HIT_ACTIVE; + if (!p->pre_handler || !p->pre_handler(p, regs)) { + /* + * Emulate singlestep (and also recover regs->pc) + * as if there is a nop + */ + instruction_pointer_set(regs, + (unsigned long)p->addr + MCOUNT_INSN_SIZE); + if (unlikely(p->post_handler)) { + kcb->kprobe_status = KPROBE_HIT_SSDONE; + p->post_handler(p, regs, 0); + } + instruction_pointer_set(regs, orig_ip); + } + /* + * If pre_handler returns !0, it changes regs->pc. We have to + * skip emulating post_handler. + */ + __this_cpu_write(current_kprobe, NULL); + } +} +NOKPROBE_SYMBOL(kprobe_ftrace_handler); + +int arch_prepare_kprobe_ftrace(struct kprobe *p) +{ + p->ainsn.api.insn = NULL; + return 0; +} diff --git a/arch/csky/kernel/probes/kprobes.c b/arch/csky/kernel/probes/kprobes.c new file mode 100644 index 000000000000..f0f733b7ac5a --- /dev/null +++ b/arch/csky/kernel/probes/kprobes.c @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <linux/kprobes.h> +#include <linux/extable.h> +#include <linux/slab.h> +#include <linux/stop_machine.h> +#include <asm/ptrace.h> +#include <linux/uaccess.h> +#include <asm/sections.h> +#include <asm/cacheflush.h> + +#include "decode-insn.h" + +DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; +DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); + +static void __kprobes +post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); + +struct csky_insn_patch { + kprobe_opcode_t *addr; + u32 opcode; + atomic_t cpu_count; +}; + +static int __kprobes patch_text_cb(void *priv) +{ + struct csky_insn_patch *param = priv; + unsigned int addr = (unsigned int)param->addr; + + if (atomic_inc_return(¶m->cpu_count) == 1) { + *(u16 *) addr = cpu_to_le16(param->opcode); + dcache_wb_range(addr, addr + 2); + atomic_inc(¶m->cpu_count); + } else { + while (atomic_read(¶m->cpu_count) <= num_online_cpus()) + cpu_relax(); + } + + icache_inv_range(addr, addr + 2); + + return 0; +} + +static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode) +{ + struct csky_insn_patch param = { addr, opcode, ATOMIC_INIT(0) }; + + return stop_machine_cpuslocked(patch_text_cb, ¶m, cpu_online_mask); +} + +static void __kprobes arch_prepare_ss_slot(struct kprobe *p) +{ + unsigned long offset = is_insn32(p->opcode) ? 4 : 2; + + p->ainsn.api.restore = (unsigned long)p->addr + offset; + + patch_text(p->ainsn.api.insn, p->opcode); +} + +static void __kprobes arch_prepare_simulate(struct kprobe *p) +{ + p->ainsn.api.restore = 0; +} + +static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs) +{ + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + + if (p->ainsn.api.handler) + p->ainsn.api.handler((u32)p->opcode, (long)p->addr, regs); + + post_kprobe_handler(kcb, regs); +} + +int __kprobes arch_prepare_kprobe(struct kprobe *p) +{ + unsigned long probe_addr = (unsigned long)p->addr; + + if (probe_addr & 0x1) { + pr_warn("Address not aligned.\n"); + return -EINVAL; + } + + /* copy instruction */ + p->opcode = le32_to_cpu(*p->addr); + + /* decode instruction */ + switch (csky_probe_decode_insn(p->addr, &p->ainsn.api)) { + case INSN_REJECTED: /* insn not supported */ + return -EINVAL; + + case INSN_GOOD_NO_SLOT: /* insn need simulation */ + p->ainsn.api.insn = NULL; + break; + + case INSN_GOOD: /* instruction uses slot */ + p->ainsn.api.insn = get_insn_slot(); + if (!p->ainsn.api.insn) + return -ENOMEM; + break; + } + + /* prepare the instruction */ + if (p->ainsn.api.insn) + arch_prepare_ss_slot(p); + else + arch_prepare_simulate(p); + + return 0; +} + +/* install breakpoint in text */ +void __kprobes arch_arm_kprobe(struct kprobe *p) +{ + patch_text(p->addr, USR_BKPT); +} + +/* remove breakpoint from text */ +void __kprobes arch_disarm_kprobe(struct kprobe *p) +{ + patch_text(p->addr, p->opcode); +} + +void __kprobes arch_remove_kprobe(struct kprobe *p) +{ +} + +static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) +{ + kcb->prev_kprobe.kp = kprobe_running(); + kcb->prev_kprobe.status = kcb->kprobe_status; +} + +static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) +{ + __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); + kcb->kprobe_status = kcb->prev_kprobe.status; +} + +static void __kprobes set_current_kprobe(struct kprobe *p) +{ + __this_cpu_write(current_kprobe, p); +} + +/* + * Interrupts need to be disabled before single-step mode is set, and not + * reenabled until after single-step mode ends. + * Without disabling interrupt on local CPU, there is a chance of + * interrupt occurrence in the period of exception return and start of + * out-of-line single-step, that result in wrongly single stepping + * into the interrupt handler. + */ +static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, + struct pt_regs *regs) +{ + kcb->saved_sr = regs->sr; + regs->sr &= ~BIT(6); +} + +static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, + struct pt_regs *regs) +{ + regs->sr = kcb->saved_sr; +} + +static void __kprobes +set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr, struct kprobe *p) +{ + unsigned long offset = is_insn32(p->opcode) ? 4 : 2; + + kcb->ss_ctx.ss_pending = true; + kcb->ss_ctx.match_addr = addr + offset; +} + +static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb) +{ + kcb->ss_ctx.ss_pending = false; + kcb->ss_ctx.match_addr = 0; +} + +#define TRACE_MODE_SI BIT(14) +#define TRACE_MODE_MASK ~(0x3 << 14) +#define TRACE_MODE_RUN 0 + +static void __kprobes setup_singlestep(struct kprobe *p, + struct pt_regs *regs, + struct kprobe_ctlblk *kcb, int reenter) +{ + unsigned long slot; + + if (reenter) { + save_previous_kprobe(kcb); + set_current_kprobe(p); + kcb->kprobe_status = KPROBE_REENTER; + } else { + kcb->kprobe_status = KPROBE_HIT_SS; + } + + if (p->ainsn.api.insn) { + /* prepare for single stepping */ + slot = (unsigned long)p->ainsn.api.insn; + + set_ss_context(kcb, slot, p); /* mark pending ss */ + + /* IRQs and single stepping do not mix well. */ + kprobes_save_local_irqflag(kcb, regs); + regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_SI; + instruction_pointer_set(regs, slot); + } else { + /* insn simulation */ + arch_simulate_insn(p, regs); + } +} + +static int __kprobes reenter_kprobe(struct kprobe *p, + struct pt_regs *regs, + struct kprobe_ctlblk *kcb) +{ + switch (kcb->kprobe_status) { + case KPROBE_HIT_SSDONE: + case KPROBE_HIT_ACTIVE: + kprobes_inc_nmissed_count(p); + setup_singlestep(p, regs, kcb, 1); + break; + case KPROBE_HIT_SS: + case KPROBE_REENTER: + pr_warn("Unrecoverable kprobe detected.\n"); + dump_kprobe(p); + BUG(); + break; + default: + WARN_ON(1); + return 0; + } + + return 1; +} + +static void __kprobes +post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs) +{ + struct kprobe *cur = kprobe_running(); + + if (!cur) + return; + + /* return addr restore if non-branching insn */ + if (cur->ainsn.api.restore != 0) + regs->pc = cur->ainsn.api.restore; + + /* restore back original saved kprobe variables and continue */ + if (kcb->kprobe_status == KPROBE_REENTER) { + restore_previous_kprobe(kcb); + return; + } + + /* call post handler */ + kcb->kprobe_status = KPROBE_HIT_SSDONE; + if (cur->post_handler) { + /* post_handler can hit breakpoint and single step + * again, so we enable D-flag for recursive exception. + */ + cur->post_handler(cur, regs, 0); + } + + reset_current_kprobe(); +} + +int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr) +{ + struct kprobe *cur = kprobe_running(); + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + + switch (kcb->kprobe_status) { + case KPROBE_HIT_SS: + case KPROBE_REENTER: + /* + * We are here because the instruction being single + * stepped caused a page fault. We reset the current + * kprobe and the ip points back to the probe address + * and allow the page fault handler to continue as a + * normal page fault. + */ + regs->pc = (unsigned long) cur->addr; + if (!instruction_pointer(regs)) + BUG(); + + if (kcb->kprobe_status == KPROBE_REENTER) + restore_previous_kprobe(kcb); + else + reset_current_kprobe(); + + break; + case KPROBE_HIT_ACTIVE: + case KPROBE_HIT_SSDONE: + /* + * We increment the nmissed count for accounting, + * we can also use npre/npostfault count for accounting + * these specific fault cases. + */ + kprobes_inc_nmissed_count(cur); + + /* + * We come here because instructions in the pre/post + * handler caused the page_fault, this could happen + * if handler tries to access user space by + * copy_from_user(), get_user() etc. Let the + * user-specified handler try to fix it first. + */ + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) + return 1; + + /* + * In case the user-specified fault handler returned + * zero, try to fix up. + */ + if (fixup_exception(regs)) + return 1; + } + return 0; +} + +int __kprobes +kprobe_breakpoint_handler(struct pt_regs *regs) +{ + struct kprobe *p, *cur_kprobe; + struct kprobe_ctlblk *kcb; + unsigned long addr = instruction_pointer(regs); + + kcb = get_kprobe_ctlblk(); + cur_kprobe = kprobe_running(); + + p = get_kprobe((kprobe_opcode_t *) addr); + + if (p) { + if (cur_kprobe) { + if (reenter_kprobe(p, regs, kcb)) + return 1; + } else { + /* Probe hit */ + set_current_kprobe(p); + kcb->kprobe_status = KPROBE_HIT_ACTIVE; + + /* + * If we have no pre-handler or it returned 0, we + * continue with normal processing. If we have a + * pre-handler and it returned non-zero, it will + * modify the execution path and no need to single + * stepping. Let's just reset current kprobe and exit. + * + * pre_handler can hit a breakpoint and can step thru + * before return. + */ + if (!p->pre_handler || !p->pre_handler(p, regs)) + setup_singlestep(p, regs, kcb, 0); + else + reset_current_kprobe(); + } + return 1; + } + + /* + * The breakpoint instruction was removed right + * after we hit it. Another cpu has removed + * either a probepoint or a debugger breakpoint + * at this address. In either case, no further + * handling of this interrupt is appropriate. + * Return back to original instruction, and continue. + */ + return 0; +} + +int __kprobes +kprobe_single_step_handler(struct pt_regs *regs) +{ + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + + if ((kcb->ss_ctx.ss_pending) + && (kcb->ss_ctx.match_addr == instruction_pointer(regs))) { + clear_ss_context(kcb); /* clear pending ss */ + + kprobes_restore_local_irqflag(kcb, regs); + regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_RUN; + + post_kprobe_handler(kcb, regs); + return 1; + } + return 0; +} + +/* + * Provide a blacklist of symbols identifying ranges which cannot be kprobed. + * This blacklist is exposed to userspace via debugfs (kprobes/blacklist). + */ +int __init arch_populate_kprobe_blacklist(void) +{ + int ret; + + ret = kprobe_add_area_blacklist((unsigned long)__irqentry_text_start, + (unsigned long)__irqentry_text_end); + return ret; +} + +void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) +{ + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *tmp; + unsigned long flags, orig_ret_address = 0; + unsigned long trampoline_address = + (unsigned long)&kretprobe_trampoline; + kprobe_opcode_t *correct_ret_addr = NULL; + + INIT_HLIST_HEAD(&empty_rp); + kretprobe_hash_lock(current, &head, &flags); + + /* + * It is possible to have multiple instances associated with a given + * task either because multiple functions in the call path have + * return probes installed on them, and/or more than one + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always pushed into the head of the list + * - when multiple return probes are registered for the same + * function, the (chronologically) first instance's ret_addr + * will be the real return address, and all the rest will + * point to kretprobe_trampoline. + */ + hlist_for_each_entry_safe(ri, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + orig_ret_address = (unsigned long)ri->ret_addr; + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + kretprobe_assert(ri, orig_ret_address, trampoline_address); + + correct_ret_addr = ri->ret_addr; + hlist_for_each_entry_safe(ri, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + orig_ret_address = (unsigned long)ri->ret_addr; + if (ri->rp && ri->rp->handler) { + __this_cpu_write(current_kprobe, &ri->rp->kp); + get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; + ri->ret_addr = correct_ret_addr; + ri->rp->handler(ri, regs); + __this_cpu_write(current_kprobe, NULL); + } + + recycle_rp_inst(ri, &empty_rp); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + kretprobe_hash_unlock(current, &flags); + + hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } + return (void *)orig_ret_address; +} + +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + ri->ret_addr = (kprobe_opcode_t *)regs->lr; + regs->lr = (unsigned long) &kretprobe_trampoline; +} + +int __kprobes arch_trampoline_kprobe(struct kprobe *p) +{ + return 0; +} + +int __init arch_init_kprobes(void) +{ + return 0; +} diff --git a/arch/csky/kernel/probes/kprobes_trampoline.S b/arch/csky/kernel/probes/kprobes_trampoline.S new file mode 100644 index 000000000000..b1fe3af24f03 --- /dev/null +++ b/arch/csky/kernel/probes/kprobes_trampoline.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#include <linux/linkage.h> + +#include <abi/entry.h> + +ENTRY(kretprobe_trampoline) + SAVE_REGS_FTRACE + + mov a0, sp /* pt_regs */ + + jbsr trampoline_probe_handler + + /* use the result as the return-address */ + mov lr, a0 + + RESTORE_REGS_FTRACE + rts +ENDPROC(kretprobe_trampoline) diff --git a/arch/csky/kernel/probes/simulate-insn.c b/arch/csky/kernel/probes/simulate-insn.c new file mode 100644 index 000000000000..4e464fed52ec --- /dev/null +++ b/arch/csky/kernel/probes/simulate-insn.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/kprobes.h> + +#include "decode-insn.h" +#include "simulate-insn.h" + +static inline bool csky_insn_reg_get_val(struct pt_regs *regs, + unsigned long index, + unsigned long *ptr) +{ + if (index < 14) + *ptr = *(®s->a0 + index); + + if (index > 15 && index < 31) + *ptr = *(®s->exregs[0] + index - 16); + + switch (index) { + case 14: + *ptr = regs->usp; + break; + case 15: + *ptr = regs->lr; + break; + case 31: + *ptr = regs->tls; + break; + default: + goto fail; + } + + return true; +fail: + return false; +} + +static inline bool csky_insn_reg_set_val(struct pt_regs *regs, + unsigned long index, + unsigned long val) +{ + if (index < 14) + *(®s->a0 + index) = val; + + if (index > 15 && index < 31) + *(®s->exregs[0] + index - 16) = val; + + switch (index) { + case 14: + regs->usp = val; + break; + case 15: + regs->lr = val; + break; + case 31: + regs->tls = val; + break; + default: + goto fail; + } + + return true; +fail: + return false; +} + +void __kprobes +simulate_br16(u32 opcode, long addr, struct pt_regs *regs) +{ + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0x3ff) << 1, 9)); +} + +void __kprobes +simulate_br32(u32 opcode, long addr, struct pt_regs *regs) +{ + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); +} + +void __kprobes +simulate_bt16(u32 opcode, long addr, struct pt_regs *regs) +{ + if (regs->sr & 1) + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0x3ff) << 1, 9)); + else + instruction_pointer_set(regs, addr + 2); +} + +void __kprobes +simulate_bt32(u32 opcode, long addr, struct pt_regs *regs) +{ + if (regs->sr & 1) + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + else + instruction_pointer_set(regs, addr + 4); +} + +void __kprobes +simulate_bf16(u32 opcode, long addr, struct pt_regs *regs) +{ + if (!(regs->sr & 1)) + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0x3ff) << 1, 9)); + else + instruction_pointer_set(regs, addr + 2); +} + +void __kprobes +simulate_bf32(u32 opcode, long addr, struct pt_regs *regs) +{ + if (!(regs->sr & 1)) + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + else + instruction_pointer_set(regs, addr + 4); +} + +void __kprobes +simulate_jmp16(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = (opcode >> 2) & 0xf; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + instruction_pointer_set(regs, tmp & 0xfffffffe); +} + +void __kprobes +simulate_jmp32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + instruction_pointer_set(regs, tmp & 0xfffffffe); +} + +void __kprobes +simulate_jsr16(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = (opcode >> 2) & 0xf; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + regs->lr = addr + 2; + + instruction_pointer_set(regs, tmp & 0xfffffffe); +} + +void __kprobes +simulate_jsr32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + regs->lr = addr + 4; + + instruction_pointer_set(regs, tmp & 0xfffffffe); +} + +void __kprobes +simulate_lrw16(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long val; + unsigned long tmp = (opcode & 0x300) >> 3; + unsigned long offset = ((opcode & 0x1f) | tmp) << 2; + + tmp = (opcode & 0xe0) >> 5; + + val = *(unsigned int *)(instruction_pointer(regs) + offset); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_lrw32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long val; + unsigned long offset = (opcode & 0xffff0000) >> 14; + unsigned long tmp = opcode & 0x0000001f; + + val = *(unsigned int *) + ((instruction_pointer(regs) + offset) & 0xfffffffc); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_pop16(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long *tmp = (unsigned long *)regs->usp; + int i; + + for (i = 0; i < (opcode & 0xf); i++) { + csky_insn_reg_set_val(regs, i + 4, *tmp); + tmp += 1; + } + + if (opcode & 0x10) { + csky_insn_reg_set_val(regs, 15, *tmp); + tmp += 1; + } + + regs->usp = (unsigned long)tmp; + + instruction_pointer_set(regs, regs->lr); +} + +void __kprobes +simulate_pop32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long *tmp = (unsigned long *)regs->usp; + int i; + + for (i = 0; i < ((opcode & 0xf0000) >> 16); i++) { + csky_insn_reg_set_val(regs, i + 4, *tmp); + tmp += 1; + } + + if (opcode & 0x100000) { + csky_insn_reg_set_val(regs, 15, *tmp); + tmp += 1; + } + + for (i = 0; i < ((opcode & 0xe00000) >> 21); i++) { + csky_insn_reg_set_val(regs, i + 16, *tmp); + tmp += 1; + } + + if (opcode & 0x1000000) { + csky_insn_reg_set_val(regs, 29, *tmp); + tmp += 1; + } + + regs->usp = (unsigned long)tmp; + + instruction_pointer_set(regs, regs->lr); +} + +void __kprobes +simulate_bez32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + if (tmp == 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); +} + +void __kprobes +simulate_bnez32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + + csky_insn_reg_get_val(regs, tmp, &tmp); + + if (tmp != 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); +} + +void __kprobes +simulate_bnezad32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + unsigned long val; + + csky_insn_reg_get_val(regs, tmp, &val); + + val -= 1; + + if (val > 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_bhsz32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + unsigned long val; + + csky_insn_reg_get_val(regs, tmp, &val); + + if (val >= 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_bhz32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + unsigned long val; + + csky_insn_reg_get_val(regs, tmp, &val); + + if (val > 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_blsz32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + unsigned long val; + + csky_insn_reg_get_val(regs, tmp, &val); + + if (val <= 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_blz32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp = opcode & 0x1f; + unsigned long val; + + csky_insn_reg_get_val(regs, tmp, &val); + + if (val < 0) { + instruction_pointer_set(regs, + addr + sign_extend32((opcode & 0xffff0000) >> 15, 15)); + } else + instruction_pointer_set(regs, addr + 4); + + csky_insn_reg_set_val(regs, tmp, val); +} + +void __kprobes +simulate_bsr32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long tmp; + + tmp = (opcode & 0xffff) << 16; + tmp |= (opcode & 0xffff0000) >> 16; + + instruction_pointer_set(regs, + addr + sign_extend32((tmp & 0x3ffffff) << 1, 15)); + + regs->lr = addr + 4; +} + +void __kprobes +simulate_jmpi32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long val; + unsigned long offset = ((opcode & 0xffff0000) >> 14); + + val = *(unsigned int *) + ((instruction_pointer(regs) + offset) & 0xfffffffc); + + instruction_pointer_set(regs, val); +} + +void __kprobes +simulate_jsri32(u32 opcode, long addr, struct pt_regs *regs) +{ + unsigned long val; + unsigned long offset = ((opcode & 0xffff0000) >> 14); + + val = *(unsigned int *) + ((instruction_pointer(regs) + offset) & 0xfffffffc); + + regs->lr = addr + 4; + + instruction_pointer_set(regs, val); +} diff --git a/arch/csky/kernel/probes/simulate-insn.h b/arch/csky/kernel/probes/simulate-insn.h new file mode 100644 index 000000000000..ba4cb7ef062e --- /dev/null +++ b/arch/csky/kernel/probes/simulate-insn.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __CSKY_KERNEL_PROBES_SIMULATE_INSN_H +#define __CSKY_KERNEL_PROBES_SIMULATE_INSN_H + +#define __CSKY_INSN_FUNCS(name, mask, val) \ +static __always_inline bool csky_insn_is_##name(probe_opcode_t code) \ +{ \ + BUILD_BUG_ON(~(mask) & (val)); \ + return (code & (mask)) == (val); \ +} \ +void simulate_##name(u32 opcode, long addr, struct pt_regs *regs); + +#define CSKY_INSN_SET_SIMULATE(name, code) \ + do { \ + if (csky_insn_is_##name(code)) { \ + api->handler = simulate_##name; \ + return INSN_GOOD_NO_SLOT; \ + } \ + } while (0) + +__CSKY_INSN_FUNCS(br16, 0xfc00, 0x0400) +__CSKY_INSN_FUNCS(bt16, 0xfc00, 0x0800) +__CSKY_INSN_FUNCS(bf16, 0xfc00, 0x0c00) +__CSKY_INSN_FUNCS(jmp16, 0xffc3, 0x7800) +__CSKY_INSN_FUNCS(jsr16, 0xffc3, 0x7801) +__CSKY_INSN_FUNCS(lrw16, 0xfc00, 0x1000) +__CSKY_INSN_FUNCS(pop16, 0xffe0, 0x1480) + +__CSKY_INSN_FUNCS(br32, 0x0000ffff, 0x0000e800) +__CSKY_INSN_FUNCS(bt32, 0x0000ffff, 0x0000e860) +__CSKY_INSN_FUNCS(bf32, 0x0000ffff, 0x0000e840) +__CSKY_INSN_FUNCS(jmp32, 0xffffffe0, 0x0000e8c0) +__CSKY_INSN_FUNCS(jsr32, 0xffffffe0, 0x0000e8e0) +__CSKY_INSN_FUNCS(lrw32, 0x0000ffe0, 0x0000ea80) +__CSKY_INSN_FUNCS(pop32, 0xfe00ffff, 0x0000ebc0) + +__CSKY_INSN_FUNCS(bez32, 0x0000ffe0, 0x0000e900) +__CSKY_INSN_FUNCS(bnez32, 0x0000ffe0, 0x0000e920) +__CSKY_INSN_FUNCS(bnezad32, 0x0000ffe0, 0x0000e820) +__CSKY_INSN_FUNCS(bhsz32, 0x0000ffe0, 0x0000e9a0) +__CSKY_INSN_FUNCS(bhz32, 0x0000ffe0, 0x0000e940) +__CSKY_INSN_FUNCS(blsz32, 0x0000ffe0, 0x0000e960) +__CSKY_INSN_FUNCS(blz32, 0x0000ffe0, 0x0000e980) +__CSKY_INSN_FUNCS(bsr32, 0x0000fc00, 0x0000e000) +__CSKY_INSN_FUNCS(jmpi32, 0x0000ffff, 0x0000eac0) +__CSKY_INSN_FUNCS(jsri32, 0x0000ffff, 0x0000eae0) + +#endif /* __CSKY_KERNEL_PROBES_SIMULATE_INSN_H */ diff --git a/arch/csky/kernel/probes/uprobes.c b/arch/csky/kernel/probes/uprobes.c new file mode 100644 index 000000000000..b3a56c260e3e --- /dev/null +++ b/arch/csky/kernel/probes/uprobes.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2014-2016 Pratyush Anand <panand@redhat.com> + */ +#include <linux/highmem.h> +#include <linux/ptrace.h> +#include <linux/uprobes.h> +#include <asm/cacheflush.h> + +#include "decode-insn.h" + +#define UPROBE_TRAP_NR UINT_MAX + +unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) +{ + return instruction_pointer(regs); +} + +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, + unsigned long addr) +{ + probe_opcode_t insn; + + insn = *(probe_opcode_t *)(&auprobe->insn[0]); + + auprobe->insn_size = is_insn32(insn) ? 4 : 2; + + switch (csky_probe_decode_insn(&insn, &auprobe->api)) { + case INSN_REJECTED: + return -EINVAL; + + case INSN_GOOD_NO_SLOT: + auprobe->simulate = true; + break; + + default: + break; + } + + return 0; +} + +int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) +{ + struct uprobe_task *utask = current->utask; + + utask->autask.saved_trap_no = current->thread.trap_no; + current->thread.trap_no = UPROBE_TRAP_NR; + + instruction_pointer_set(regs, utask->xol_vaddr); + + user_enable_single_step(current); + + return 0; +} + +int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) +{ + struct uprobe_task *utask = current->utask; + + WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR); + + instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size); + + user_disable_single_step(current); + + return 0; +} + +bool arch_uprobe_xol_was_trapped(struct task_struct *t) +{ + if (t->thread.trap_no != UPROBE_TRAP_NR) + return true; + + return false; +} + +bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) +{ + probe_opcode_t insn; + unsigned long addr; + + if (!auprobe->simulate) + return false; + + insn = *(probe_opcode_t *)(&auprobe->insn[0]); + addr = instruction_pointer(regs); + + if (auprobe->api.handler) + auprobe->api.handler(insn, addr, regs); + + return true; +} + +void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) +{ + struct uprobe_task *utask = current->utask; + + /* + * Task has received a fatal signal, so reset back to probbed + * address. + */ + instruction_pointer_set(regs, utask->vaddr); + + user_disable_single_step(current); +} + +bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, + struct pt_regs *regs) +{ + if (ctx == RP_CHECK_CHAIN_CALL) + return regs->usp <= ret->stack; + else + return regs->usp < ret->stack; +} + +unsigned long +arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, + struct pt_regs *regs) +{ + unsigned long ra; + + ra = regs->lr; + + regs->lr = trampoline_vaddr; + + return ra; +} + +int arch_uprobe_exception_notify(struct notifier_block *self, + unsigned long val, void *data) +{ + return NOTIFY_DONE; +} + +int uprobe_breakpoint_handler(struct pt_regs *regs) +{ + if (uprobe_pre_sstep_notifier(regs)) + return 1; + + return 0; +} + +int uprobe_single_step_handler(struct pt_regs *regs) +{ + if (uprobe_post_sstep_notifier(regs)) + return 1; + + return 0; +} diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index 313623a19ecb..21ac2608f205 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c @@ -193,6 +193,109 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) return &user_csky_view; } +struct pt_regs_offset { + const char *name; + int offset; +}; + +#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +static const struct pt_regs_offset regoffset_table[] = { + REG_OFFSET_NAME(tls), + REG_OFFSET_NAME(lr), + REG_OFFSET_NAME(pc), + REG_OFFSET_NAME(sr), + REG_OFFSET_NAME(usp), + REG_OFFSET_NAME(orig_a0), + REG_OFFSET_NAME(a0), + REG_OFFSET_NAME(a1), + REG_OFFSET_NAME(a2), + REG_OFFSET_NAME(a3), + REG_OFFSET_NAME(regs[0]), + REG_OFFSET_NAME(regs[1]), + REG_OFFSET_NAME(regs[2]), + REG_OFFSET_NAME(regs[3]), + REG_OFFSET_NAME(regs[4]), + REG_OFFSET_NAME(regs[5]), + REG_OFFSET_NAME(regs[6]), + REG_OFFSET_NAME(regs[7]), + REG_OFFSET_NAME(regs[8]), + REG_OFFSET_NAME(regs[9]), +#if defined(__CSKYABIV2__) + REG_OFFSET_NAME(exregs[0]), + REG_OFFSET_NAME(exregs[1]), + REG_OFFSET_NAME(exregs[2]), + REG_OFFSET_NAME(exregs[3]), + REG_OFFSET_NAME(exregs[4]), + REG_OFFSET_NAME(exregs[5]), + REG_OFFSET_NAME(exregs[6]), + REG_OFFSET_NAME(exregs[7]), + REG_OFFSET_NAME(exregs[8]), + REG_OFFSET_NAME(exregs[9]), + REG_OFFSET_NAME(exregs[10]), + REG_OFFSET_NAME(exregs[11]), + REG_OFFSET_NAME(exregs[12]), + REG_OFFSET_NAME(exregs[13]), + REG_OFFSET_NAME(exregs[14]), + REG_OFFSET_NAME(rhi), + REG_OFFSET_NAME(rlo), + REG_OFFSET_NAME(dcsr), +#endif + REG_OFFSET_END, +}; + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + + for (roff = regoffset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ +static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ + return (addr & ~(THREAD_SIZE - 1)) == + (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} + void ptrace_disable(struct task_struct *child) { singlestep_disable(child); diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 3821e55742f4..819a9a7bf786 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -24,26 +24,9 @@ struct screen_info screen_info = { }; #endif -phys_addr_t __init_memblock memblock_end_of_REG0(void) -{ - return (memblock.memory.regions[0].base + - memblock.memory.regions[0].size); -} - -phys_addr_t __init_memblock memblock_start_of_REG1(void) -{ - return memblock.memory.regions[1].base; -} - -size_t __init_memblock memblock_size_of_REG1(void) -{ - return memblock.memory.regions[1].size; -} - static void __init csky_memblock_init(void) { unsigned long zone_size[MAX_NR_ZONES]; - unsigned long zhole_size[MAX_NR_ZONES]; signed long size; memblock_reserve(__pa(_stext), _end - _stext); @@ -54,54 +37,36 @@ static void __init csky_memblock_init(void) memblock_dump_all(); memset(zone_size, 0, sizeof(zone_size)); - memset(zhole_size, 0, sizeof(zhole_size)); min_low_pfn = PFN_UP(memblock_start_of_DRAM()); - max_pfn = PFN_DOWN(memblock_end_of_DRAM()); - - max_low_pfn = PFN_UP(memblock_end_of_REG0()); - if (max_low_pfn == 0) - max_low_pfn = max_pfn; + max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM()); size = max_pfn - min_low_pfn; - if (memblock.memory.cnt > 1) { - zone_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn; - zhole_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn; + if (size <= PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET)) + zone_size[ZONE_NORMAL] = size; + else if (size < PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) { + zone_size[ZONE_NORMAL] = + PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET); + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; } else { - if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) - zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn; - else { - zone_size[ZONE_NORMAL] = + zone_size[ZONE_NORMAL] = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; - } + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; + write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE); } #ifdef CONFIG_HIGHMEM - size = 0; - if (memblock.memory.cnt > 1) { - size = PFN_DOWN(memblock_size_of_REG1()); - highstart_pfn = PFN_DOWN(memblock_start_of_REG1()); - } else { - size = max_pfn - min_low_pfn - - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - highstart_pfn = min_low_pfn + - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - } - - if (size > 0) - zone_size[ZONE_HIGHMEM] = size; + zone_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; - highend_pfn = max_pfn; + highstart_pfn = max_low_pfn; + highend_pfn = max_pfn; #endif memblock_set_current_limit(PFN_PHYS(max_low_pfn)); dma_contiguous_reserve(0); - free_area_init_node(0, zone_size, min_low_pfn, zhole_size); + free_area_init_node(0, zone_size, min_low_pfn, NULL); } void __init setup_arch(char **cmdline_p) diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c index 9b1b7c039ddf..9452d6570b7e 100644 --- a/arch/csky/kernel/signal.c +++ b/arch/csky/kernel/signal.c @@ -175,6 +175,8 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) sigset_t *oldset = sigmask_to_save(); int ret; + rseq_signal_deliver(ksig, regs); + /* Are we from a system call? */ if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_from_exception */ @@ -251,6 +253,9 @@ static void do_signal(struct pt_regs *regs) asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { + if (thread_info_flags & _TIF_UPROBE) + uprobe_notify_resume(regs); + /* Handle pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); @@ -258,5 +263,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); + rseq_handle_notify_resume(NULL, regs); } } diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index 0bb0954d5570..b5c5bc3afeb5 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -22,6 +22,9 @@ #include <asm/sections.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> +#ifdef CONFIG_CPU_HAS_FPU +#include <abi/fpu.h> +#endif struct ipi_data_struct { unsigned long bits ____cacheline_aligned; @@ -156,6 +159,8 @@ volatile unsigned int secondary_hint; volatile unsigned int secondary_ccr; volatile unsigned int secondary_stack; +unsigned long secondary_msa1; + int __cpu_up(unsigned int cpu, struct task_struct *tidle) { unsigned long mask = 1 << cpu; @@ -164,6 +169,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) (unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8; secondary_hint = mfcr("cr31"); secondary_ccr = mfcr("cr18"); + secondary_msa1 = read_mmu_msa1(); /* * Because other CPUs are in reset status, we must flush data diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c index b057480e7463..fcc3a69831ad 100644 --- a/arch/csky/kernel/traps.c +++ b/arch/csky/kernel/traps.c @@ -14,6 +14,7 @@ #include <linux/kallsyms.h> #include <linux/rtc.h> #include <linux/uaccess.h> +#include <linux/kprobes.h> #include <asm/setup.h> #include <asm/traps.h> @@ -109,14 +110,14 @@ void buserr(struct pt_regs *regs) force_sig_fault(SIGSEGV, 0, (void __user *)regs->pc); } -#define USR_BKPT 0x1464 asmlinkage void trap_c(struct pt_regs *regs) { int sig; unsigned long vector; siginfo_t info; + struct task_struct *tsk = current; - vector = (mfcr("psr") >> 16) & 0xff; + vector = (regs->sr >> 16) & 0xff; switch (vector) { case VEC_ZERODIV: @@ -125,10 +126,27 @@ asmlinkage void trap_c(struct pt_regs *regs) break; /* ptrace */ case VEC_TRACE: +#ifdef CONFIG_KPROBES + if (kprobe_single_step_handler(regs)) + return; +#endif +#ifdef CONFIG_UPROBES + if (uprobe_single_step_handler(regs)) + return; +#endif info.si_code = TRAP_TRACE; sig = SIGTRAP; break; case VEC_ILLEGAL: + tsk->thread.trap_no = vector; +#ifdef CONFIG_KPROBES + if (kprobe_breakpoint_handler(regs)) + return; +#endif +#ifdef CONFIG_UPROBES + if (uprobe_breakpoint_handler(regs)) + return; +#endif die_if_kernel("Kernel mode ILLEGAL", regs, vector); #ifndef CONFIG_CPU_NO_USER_BKPT if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) @@ -146,16 +164,20 @@ asmlinkage void trap_c(struct pt_regs *regs) sig = SIGTRAP; break; case VEC_ACCESS: + tsk->thread.trap_no = vector; return buserr(regs); #ifdef CONFIG_CPU_NEED_SOFTALIGN case VEC_ALIGN: + tsk->thread.trap_no = vector; return csky_alignment(regs); #endif #ifdef CONFIG_CPU_HAS_FPU case VEC_FPE: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode FPE", regs, vector); return fpu_fpe(regs); case VEC_PRIV: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode PRIV", regs, vector); if (fpu_libc_helper(regs)) return; @@ -164,5 +186,8 @@ asmlinkage void trap_c(struct pt_regs *regs) sig = SIGSEGV; break; } + + tsk->thread.trap_no = vector; + send_sig(sig, current, 0); } diff --git a/arch/csky/mm/cachev2.c b/arch/csky/mm/cachev2.c index bc419f8039d3..7a9664adce43 100644 --- a/arch/csky/mm/cachev2.c +++ b/arch/csky/mm/cachev2.c @@ -7,8 +7,12 @@ #include <asm/cache.h> #include <asm/barrier.h> +/* for L1-cache */ #define INS_CACHE (1 << 0) +#define DATA_CACHE (1 << 1) #define CACHE_INV (1 << 4) +#define CACHE_CLR (1 << 5) +#define CACHE_OMS (1 << 6) void local_icache_inv_all(void *priv) { @@ -16,11 +20,6 @@ void local_icache_inv_all(void *priv) sync_is(); } -void icache_inv_all(void) -{ - on_each_cpu(local_icache_inv_all, NULL, 1); -} - #ifdef CONFIG_CPU_HAS_ICACHE_INS void icache_inv_range(unsigned long start, unsigned long end) { @@ -31,9 +30,43 @@ void icache_inv_range(unsigned long start, unsigned long end) sync_is(); } #else +struct cache_range { + unsigned long start; + unsigned long end; +}; + +static DEFINE_SPINLOCK(cache_lock); + +static inline void cache_op_line(unsigned long i, unsigned int val) +{ + mtcr("cr22", i); + mtcr("cr17", val); +} + +void local_icache_inv_range(void *priv) +{ + struct cache_range *param = priv; + unsigned long i = param->start & ~(L1_CACHE_BYTES - 1); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + + for (; i < param->end; i += L1_CACHE_BYTES) + cache_op_line(i, INS_CACHE | CACHE_INV | CACHE_OMS); + + spin_unlock_irqrestore(&cache_lock, flags); + + sync_is(); +} + void icache_inv_range(unsigned long start, unsigned long end) { - icache_inv_all(); + struct cache_range param = { start, end }; + + if (irqs_disabled()) + local_icache_inv_range(¶m); + else + on_each_cpu(local_icache_inv_range, ¶m, 1); } #endif diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index f76618b630f9..4e6dc68f3258 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -18,6 +18,7 @@ #include <linux/extable.h> #include <linux/uaccess.h> #include <linux/perf_event.h> +#include <linux/kprobes.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> @@ -53,6 +54,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, int fault; unsigned long address = mmu_meh & PAGE_MASK; + if (kprobe_page_fault(regs, tsk->thread.trap_no)) + return; + si_code = SEGV_MAPERR; #ifndef CONFIG_CPU_HAS_TLBI @@ -137,7 +141,7 @@ good_area: if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) + if (unlikely(!vma_is_accessible(vma))) goto bad_area; } @@ -179,11 +183,14 @@ bad_area: bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; force_sig_fault(SIGSEGV, si_code, (void __user *)address); return; } no_context: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) return; @@ -198,6 +205,8 @@ no_context: die_if_kernel("Oops", regs, write); out_of_memory: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* * We ran out of memory, call the OOM killer, and return the userspace * (which will retry the fault, or kill us if we got oom-killed). @@ -206,6 +215,8 @@ out_of_memory: return; do_sigbus: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + up_read(&mm->mmap_sem); /* Kernel mode? Handle exceptions or die */ diff --git a/arch/h8300/include/asm/page.h b/arch/h8300/include/asm/page.h index 8da5124ad344..53e037544239 100644 --- a/arch/h8300/include/asm/page.h +++ b/arch/h8300/include/asm/page.h @@ -6,8 +6,6 @@ #include <linux/types.h> #define MAP_NR(addr) (((uintptr_t)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #ifndef __ASSEMBLY__ extern unsigned long rom_length; diff --git a/arch/h8300/include/uapi/asm/bitsperlong.h b/arch/h8300/include/uapi/asm/bitsperlong.h deleted file mode 100644 index a33e358f1c1b..000000000000 --- a/arch/h8300/include/uapi/asm/bitsperlong.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _UAPI__ASM_H8300_BITS_PER_LONG -#define _UAPI__ASM_H8300_BITS_PER_LONG - -#include <asm-generic/bitsperlong.h> - -#if !defined(__ASSEMBLY__) -/* h8300-unknown-linux required long */ -#define __kernel_size_t __kernel_size_t -typedef unsigned long __kernel_size_t; -typedef long __kernel_ssize_t; -typedef long __kernel_ptrdiff_t; -#endif - -#endif /* _UAPI__ASM_H8300_BITS_PER_LONG */ diff --git a/arch/h8300/include/uapi/asm/posix_types.h b/arch/h8300/include/uapi/asm/posix_types.h new file mode 100644 index 000000000000..3efc9dd59476 --- /dev/null +++ b/arch/h8300/include/uapi/asm/posix_types.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +#ifndef _UAPI_ASM_POSIX_TYPES_H +#define _UAPI_ASM_POSIX_TYPES_H + +/* h8300-unknown-linux required long */ +#define __kernel_size_t __kernel_size_t +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; + +#include <asm-generic/posix_types.h> + +#endif /* _UAPI_ASM_POSIX_TYPES_H */ diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index ee31f36f48f3..7cbf719c578e 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -93,8 +93,7 @@ struct page; #define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(__pa(kaddr))) /* Default vm area behavior is non-executable. */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC #define pfn_valid(pfn) ((pfn) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h index 2fec20ad939e..d383e8bea5b2 100644 --- a/arch/hexagon/include/asm/pgtable.h +++ b/arch/hexagon/include/asm/pgtable.h @@ -158,8 +158,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* located in head.S */ /* Seems to be zero even in architectures where the zero page is firewalled? */ #define FIRST_USER_ADDRESS 0UL -#define pte_special(pte) 0 -#define pte_mkspecial(pte) (pte) /* HUGETLB not working currently */ #ifdef CONFIG_HUGETLB_PAGE diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index b630bd7351c4..f3ba813a5b80 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -57,7 +57,8 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_AGP=m diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 661d90b3e148..cb267a07c57f 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -94,7 +94,8 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_RAW_DRIVER=m CONFIG_HPET=y CONFIG_AGP=m diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 7844e6a956a4..7e25f2f031b6 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -82,7 +82,8 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_RAW_DRIVER=m CONFIG_HPET=y CONFIG_AGP=m diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 1d6e2a01452b..3f486d5bdc2d 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -86,7 +86,8 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_RAW_DRIVER=m CONFIG_HPET=y CONFIG_AGP=m diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 8c92e095f8bb..261e98e1f5fe 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -35,7 +35,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -69,7 +68,8 @@ CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_I2C_CHARDEV=y CONFIG_AGP=y CONFIG_AGP_HP_ZX1=y diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h index 5798bd2b462c..b69a5499d75b 100644 --- a/arch/ia64/include/asm/page.h +++ b/arch/ia64/include/asm/page.h @@ -218,10 +218,7 @@ get_order (unsigned long size) #define PAGE_OFFSET RGN_BASE(RGN_KERNEL) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | \ - (((current->personality & READ_IMPLIES_EXEC) != 0) \ - ? VM_EXEC : 0)) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #define GATE_ADDR RGN_BASE(RGN_GATE) diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h index d602e7c622db..0e7b645b76c6 100644 --- a/arch/ia64/include/asm/pgtable.h +++ b/arch/ia64/include/asm/pgtable.h @@ -298,7 +298,6 @@ extern unsigned long VMALLOC_END; #define pte_exec(pte) ((pte_val(pte) & _PAGE_AR_RX) != 0) #define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0) #define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0) -#define pte_special(pte) 0 /* * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the @@ -311,7 +310,6 @@ extern unsigned long VMALLOC_END; #define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D)) #define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D)) #define pte_mkhuge(pte) (__pte(pte_val(pte))) -#define pte_mkspecial(pte) (pte) /* * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to diff --git a/arch/ia64/kernel/.gitignore b/arch/ia64/kernel/.gitignore index 21cb0da5ded8..0374827206e7 100644 --- a/arch/ia64/kernel/.gitignore +++ b/arch/ia64/kernel/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only gate.lds vmlinux.lds diff --git a/arch/ia64/kernel/syscalls/syscallhdr.sh b/arch/ia64/kernel/syscalls/syscallhdr.sh index 0c2d2c748565..f407b6e53283 100644 --- a/arch/ia64/kernel/syscalls/syscallhdr.sh +++ b/arch/ia64/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 1ec6b703c5b4..6b5652ee76f9 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -54,6 +54,8 @@ SECTIONS { CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.gnu.linkonce.t*) } diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index b01d68a2d5d9..d637b4ea3147 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -670,13 +670,16 @@ mem_init (void) #ifdef CONFIG_MEMORY_HOTPLUG int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - ret = __add_pages(nid, start_pfn, nr_pages, restrictions); + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) + return -EINVAL; + + ret = __add_pages(nid, start_pfn, nr_pages, params); if (ret) printk("%s: Problem encountered in __add_pages() as ret=%d\n", __func__, ret); diff --git a/arch/m68k/68000/timers.c b/arch/m68k/68000/timers.c index 71ddb4c98726..1c8e8a83c325 100644 --- a/arch/m68k/68000/timers.c +++ b/arch/m68k/68000/timers.c @@ -68,14 +68,6 @@ static irqreturn_t hw_tick(int irq, void *dummy) /***************************************************************************/ -static struct irqaction m68328_timer_irq = { - .name = "timer", - .flags = IRQF_TIMER, - .handler = hw_tick, -}; - -/***************************************************************************/ - static u64 m68328_read_clk(struct clocksource *cs) { unsigned long flags; @@ -102,11 +94,17 @@ static struct clocksource m68328_clk = { void hw_timer_init(irq_handler_t handler) { + int ret; + /* disable timer 1 */ TCTL = 0; /* set ISR */ - setup_irq(TMR_IRQ_NUM, &m68328_timer_irq); + ret = request_irq(TMR_IRQ_NUM, hw_tick, IRQF_TIMER, "timer", NULL); + if (ret) { + pr_err("Failed to request irq %d (timer): %pe\n", TMR_IRQ_NUM, + ERR_PTR(ret)); + } /* Restart mode, Enable int, Set clock source */ TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE; diff --git a/arch/m68k/coldfire/pit.c b/arch/m68k/coldfire/pit.c index eb6f16b0e2e6..fd1d9c915daa 100644 --- a/arch/m68k/coldfire/pit.c +++ b/arch/m68k/coldfire/pit.c @@ -111,14 +111,6 @@ static irqreturn_t pit_tick(int irq, void *dummy) /***************************************************************************/ -static struct irqaction pit_irq = { - .name = "timer", - .flags = IRQF_TIMER, - .handler = pit_tick, -}; - -/***************************************************************************/ - static u64 pit_read_clk(struct clocksource *cs) { unsigned long flags; @@ -146,6 +138,8 @@ static struct clocksource pit_clk = { void hw_timer_init(irq_handler_t handler) { + int ret; + cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id()); cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); cf_pit_clockevent.max_delta_ns = @@ -156,7 +150,11 @@ void hw_timer_init(irq_handler_t handler) cf_pit_clockevent.min_delta_ticks = 0x3f; clockevents_register_device(&cf_pit_clockevent); - setup_irq(MCF_IRQ_PIT1, &pit_irq); + ret = request_irq(MCF_IRQ_PIT1, pit_tick, IRQF_TIMER, "timer", NULL); + if (ret) { + pr_err("Failed to request irq %d (timer): %pe\n", MCF_IRQ_PIT1, + ERR_PTR(ret)); + } clocksource_register_hz(&pit_clk, FREQ); } diff --git a/arch/m68k/coldfire/sltimers.c b/arch/m68k/coldfire/sltimers.c index 1b11e7bacab3..5ab81c9c552d 100644 --- a/arch/m68k/coldfire/sltimers.c +++ b/arch/m68k/coldfire/sltimers.c @@ -50,18 +50,19 @@ irqreturn_t mcfslt_profile_tick(int irq, void *dummy) return IRQ_HANDLED; } -static struct irqaction mcfslt_profile_irq = { - .name = "profile timer", - .flags = IRQF_TIMER, - .handler = mcfslt_profile_tick, -}; - void mcfslt_profile_init(void) { + int ret; + printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n", PROFILEHZ); - setup_irq(MCF_IRQ_PROFILER, &mcfslt_profile_irq); + ret = request_irq(MCF_IRQ_PROFILER, mcfslt_profile_tick, IRQF_TIMER, + "profile timer", NULL); + if (ret) { + pr_err("Failed to request irq %d (profile timer): %pe\n", + MCF_IRQ_PROFILER, ERR_PTR(ret)); + } /* Set up TIMER 2 as high speed profile clock */ __raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT)); @@ -92,12 +93,6 @@ static irqreturn_t mcfslt_tick(int irq, void *dummy) return timer_interrupt(irq, dummy); } -static struct irqaction mcfslt_timer_irq = { - .name = "timer", - .flags = IRQF_TIMER, - .handler = mcfslt_tick, -}; - static u64 mcfslt_read_clk(struct clocksource *cs) { unsigned long flags; @@ -126,6 +121,8 @@ static struct clocksource mcfslt_clk = { void hw_timer_init(irq_handler_t handler) { + int r; + mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ; /* * The coldfire slice timer (SLT) runs from STCNT to 0 included, @@ -140,7 +137,11 @@ void hw_timer_init(irq_handler_t handler) mcfslt_cnt = mcfslt_cycles_per_jiffy; timer_interrupt = handler; - setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq); + r = request_irq(MCF_IRQ_TIMER, mcfslt_tick, IRQF_TIMER, "timer", NULL); + if (r) { + pr_err("Failed to request irq %d (timer): %pe\n", MCF_IRQ_TIMER, + ERR_PTR(r)); + } clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK); diff --git a/arch/m68k/coldfire/timers.c b/arch/m68k/coldfire/timers.c index 227aa5d13709..b8301fddf901 100644 --- a/arch/m68k/coldfire/timers.c +++ b/arch/m68k/coldfire/timers.c @@ -82,14 +82,6 @@ static irqreturn_t mcftmr_tick(int irq, void *dummy) /***************************************************************************/ -static struct irqaction mcftmr_timer_irq = { - .name = "timer", - .flags = IRQF_TIMER, - .handler = mcftmr_tick, -}; - -/***************************************************************************/ - static u64 mcftmr_read_clk(struct clocksource *cs) { unsigned long flags; @@ -118,6 +110,8 @@ static struct clocksource mcftmr_clk = { void hw_timer_init(irq_handler_t handler) { + int r; + __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); mcftmr_cycles_per_jiffy = FREQ / HZ; /* @@ -134,7 +128,11 @@ void hw_timer_init(irq_handler_t handler) timer_interrupt = handler; init_timer_irq(); - setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq); + r = request_irq(MCF_IRQ_TIMER, mcftmr_tick, IRQF_TIMER, "timer", NULL); + if (r) { + pr_err("Failed to request irq %d (timer): %pe\n", MCF_IRQ_TIMER, + ERR_PTR(r)); + } #ifdef CONFIG_HIGHPROFILE coldfire_profile_init(); @@ -170,14 +168,10 @@ irqreturn_t coldfire_profile_tick(int irq, void *dummy) /***************************************************************************/ -static struct irqaction coldfire_profile_irq = { - .name = "profile timer", - .flags = IRQF_TIMER, - .handler = coldfire_profile_tick, -}; - void coldfire_profile_init(void) { + int ret; + printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); @@ -188,7 +182,12 @@ void coldfire_profile_init(void) __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); - setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq); + ret = request_irq(MCF_IRQ_PROFILER, coldfire_profile_tick, IRQF_TIMER, + "profile timer", NULL); + if (ret) { + pr_err("Failed to request irq %d (profile timer): %pe\n", + MCF_IRQ_PROFILER, ERR_PTR(ret)); + } } /***************************************************************************/ diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 9818d0ed143e..5b3a273ae3da 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -333,7 +333,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index db2402c75300..0bf0907a7c80 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -318,7 +318,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 07a28b48eb43..876e69292294 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -333,7 +333,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 033589367cb1..aa59c242e715 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -315,7 +315,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index ee4d02a90214..308cd93929a9 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -317,7 +317,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 442eed608ebc..0bc210ace870 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -324,7 +324,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 1de7da7c1041..3b3b832dee80 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -357,7 +357,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index ced341e047db..e3633c66926f 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -314,7 +314,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 006188f1f063..88b3f7f9f146 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -315,7 +315,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index c65d985ee642..3dd5b536921e 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -323,7 +323,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 32905fe56cd7..715e015ed270 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -312,7 +312,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 32b0969668fe..f9ff129ac7c2 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -312,7 +312,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index a0765aa60ea9..1bff55aa2d54 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 generated-y += syscall_table.h generic-y += extable.h -generic-y += hardirq.h generic-y += kvm_para.h generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h index b9f45aeded25..0031cd387b75 100644 --- a/arch/m68k/include/asm/mcf_pgtable.h +++ b/arch/m68k/include/asm/mcf_pgtable.h @@ -235,11 +235,6 @@ static inline int pte_young(pte_t pte) return pte_val(pte) & CF_PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) -{ - return 0; -} - static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~CF_PAGE_WRITABLE; @@ -312,11 +307,6 @@ static inline pte_t pte_mkcache(pte_t pte) return pte; } -static inline pte_t pte_mkspecial(pte_t pte) -{ - return pte; -} - #define swapper_pg_dir kernel_pg_dir extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h index 4b91a470ad58..48f19f0ab1e7 100644 --- a/arch/m68k/include/asm/motorola_pgtable.h +++ b/arch/m68k/include/asm/motorola_pgtable.h @@ -174,7 +174,6 @@ static inline void pud_set(pud_t *pudp, pmd_t *pmdp) static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } @@ -192,7 +191,6 @@ static inline pte_t pte_mkcache(pte_t pte) pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index da546487e177..2614a1206f2f 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -65,9 +65,6 @@ extern unsigned long _ramend; #define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) #define __pfn_to_phys(pfn) PFN_PHYS(pfn) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/getorder.h> #endif /* _M68K_PAGE_H */ diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h index bc4155264810..0caa18a08437 100644 --- a/arch/m68k/include/asm/sun3_pgtable.h +++ b/arch/m68k/include/asm/sun3_pgtable.h @@ -155,7 +155,6 @@ static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } static inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEABLE; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } @@ -168,7 +167,6 @@ static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE //static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } // until then, use: static inline pte_t pte_mkcache(pte_t pte) { return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; diff --git a/arch/m68k/kernel/.gitignore b/arch/m68k/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/m68k/kernel/.gitignore +++ b/arch/m68k/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index f7afb9897966..3bfb5c8ac3c7 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -125,7 +125,7 @@ good_area: case 1: /* read, present */ goto acc_err; case 0: /* read, not present */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (unlikely(!vma_is_accessible(vma))) goto acc_err; } diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 242f58ec086b..9606c244b5b8 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -8,7 +8,7 @@ config MICROBLAZE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select ARCH_HAS_UNCACHED_SEGMENT if !MMU + select ARCH_HAS_DMA_SET_UNCACHED if !MMU select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_TABLE_SORT @@ -47,8 +47,6 @@ config MICROBLAZE select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE if MMU select SPARSE_IRQ - select GENERIC_IRQ_MULTI_HANDLER - select HANDLE_DOMAIN_IRQ # Endianness selection choice diff --git a/arch/microblaze/boot/.gitignore b/arch/microblaze/boot/.gitignore index 679502d64a97..11a9e229f3c0 100644 --- a/arch/microblaze/boot/.gitignore +++ b/arch/microblaze/boot/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only linux.bin* simpleImage.* diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index cb6ab55d1d01..0a28e80bbab0 100644 --- a/arch/microblaze/include/asm/irq.h +++ b/arch/microblaze/include/asm/irq.h @@ -11,4 +11,7 @@ struct pt_regs; extern void do_IRQ(struct pt_regs *regs); +/* should be defined in each interrupt controller driver */ +extern unsigned int xintc_get_irq(void); + #endif /* _ASM_MICROBLAZE_IRQ_H */ diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index ae7215c94706..b13463d39b38 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -194,8 +194,6 @@ extern int page_is_ram(unsigned long pfn); #ifdef CONFIG_MMU -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #endif /* CONFIG_MMU */ #endif /* __KERNEL__ */ diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index 45b30878fc17..6b056f6545d8 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -77,10 +77,6 @@ extern pte_t *va_to_pte(unsigned long address); * Undefined behaviour if not.. */ -static inline int pte_special(pte_t pte) { return 0; } - -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - /* Start and end of the vmalloc area. */ /* Make sure to map the vmalloc area above the pinned kernel memory area of 32Mb. */ diff --git a/arch/microblaze/kernel/.gitignore b/arch/microblaze/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/microblaze/kernel/.gitignore +++ b/arch/microblaze/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 0b37dde60a1e..903dad822fad 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -20,10 +20,29 @@ #include <linux/irqchip.h> #include <linux/of_irq.h> +static u32 concurrent_irq; + void __irq_entry do_IRQ(struct pt_regs *regs) { + unsigned int irq; + struct pt_regs *old_regs = set_irq_regs(regs); trace_hardirqs_off(); - handle_arch_irq(regs); + + irq_enter(); + irq = xintc_get_irq(); +next_irq: + BUG_ON(!irq); + generic_handle_irq(irq); + + irq = xintc_get_irq(); + if (irq != -1U) { + pr_debug("next irq: %d\n", irq); + ++concurrent_irq; + goto next_irq; + } + + irq_exit(); + set_irq_regs(old_regs); trace_hardirqs_on(); } diff --git a/arch/microblaze/kernel/syscalls/syscallhdr.sh b/arch/microblaze/kernel/syscalls/syscallhdr.sh index 2e9062a926a3..a914854f8d9f 100644 --- a/arch/microblaze/kernel/syscalls/syscallhdr.sh +++ b/arch/microblaze/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c index 8c5f0c332d8b..e09b66e43cb6 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -40,7 +40,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size) #define UNCACHED_SHADOW_MASK 0 #endif /* CONFIG_XILINX_UNCACHED_SHADOW */ -void *uncached_kernel_address(void *ptr) +void *arch_dma_set_uncached(void *ptr, size_t size) { unsigned long addr = (unsigned long)ptr; @@ -49,11 +49,4 @@ void *uncached_kernel_address(void *ptr) pr_warn("ERROR: Your cache coherent area is CACHED!!!\n"); return (void *)addr; } - -void *cached_kernel_address(void *ptr) -{ - unsigned long addr = (unsigned long)ptr; - - return (void *)(addr & ~UNCACHED_SHADOW_MASK); -} #endif /* CONFIG_MMU */ diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 58cc4965bd3e..60a58c0015f2 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -433,10 +433,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, pr_debug("Parsing ranges property...\n"); for_each_of_pci_range(&parser, &range) { /* Read next ranges element */ - pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ", - range.pci_space, range.pci_addr); - pr_debug("cpu_addr:0x%016llx size:0x%016llx\n", - range.cpu_addr, range.size); /* If we failed translation or got a zero-sized region * (some FW try to feed us with non sensical zero sized regions @@ -486,7 +482,7 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", range.cpu_addr, range.cpu_addr + range.size - 1, range.pci_addr, - (range.pci_space & 0x40000000) ? + (range.flags & IORESOURCE_PREFETCH) ? "Prefetch" : ""); /* We support only 3 memory ranges */ @@ -1121,4 +1117,3 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn, { return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); } - diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f8f3dbdd7ad5..690718b3701a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1192,8 +1192,9 @@ config DMA_NONCOHERENT # significant advantages. # select ARCH_HAS_DMA_WRITE_COMBINE + select ARCH_HAS_DMA_PREP_COHERENT select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select ARCH_HAS_UNCACHED_SEGMENT + select ARCH_HAS_DMA_SET_UNCACHED select DMA_NONCOHERENT_MMAP select DMA_NONCOHERENT_CACHE_SYNC select NEED_DMA_MAP_STATE diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore index a73d6e2c4f64..2adc8581a175 100644 --- a/arch/mips/boot/.gitignore +++ b/arch/mips/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only mkboot elf2ecoff vmlinux.* diff --git a/arch/mips/boot/compressed/.gitignore b/arch/mips/boot/compressed/.gitignore index ebae133f1d00..d358395614c9 100644 --- a/arch/mips/boot/compressed/.gitignore +++ b/arch/mips/boot/compressed/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only ashldi3.c bswapsi.c diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 410e61ebaf9e..aa0b2d39c902 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -403,8 +403,8 @@ compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; #address-cells = <1>; #size-cells = <0>; - reg-names = "nand"; - reg = <0x41b800 0x400>; + reg-names = "nand", "flash-edu"; + reg = <0x41b800 0x400>, <0x41bc00 0x24>; interrupt-parent = <&hif_l2_intc>; interrupts = <24>; status = "disabled"; diff --git a/arch/mips/boot/tools/.gitignore b/arch/mips/boot/tools/.gitignore index be0ed065249b..d36dc7cf9115 100644 --- a/arch/mips/boot/tools/.gitignore +++ b/arch/mips/boot/tools/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only relocs diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index f14ad0538f4e..eea9b613bb74 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -112,7 +112,6 @@ CONFIG_BLK_DEV_TC86C001=m CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m CONFIG_ATA=y diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index 1788ae23bff9..6466e83067b4 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -99,7 +99,6 @@ CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOWLEVEL is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 82d942a6026e..638d7cf5ef01 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -99,7 +99,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_CONSTANTS=y diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 370884018aad..7b1fab518317 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -50,7 +50,6 @@ CONFIG_RAID_ATTRS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 92085df3e367..8c223035921f 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -42,7 +42,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ISCSI_TCP=m diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 59eedf55419d..211bd3d6e6cb 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -239,7 +239,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 8ef612552a19..62b1969b4f55 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -247,7 +247,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index d2a008c9907c..9185e0a0aa45 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -245,7 +245,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 970df6d42728..636311d67a53 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -245,7 +245,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 2c7adea7638f..30d7c3db884e 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -203,7 +203,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_FC_ATTRS=y diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c index dbbcddc82823..89fa6e62a3b3 100644 --- a/arch/mips/fw/arc/memory.c +++ b/arch/mips/fw/arc/memory.c @@ -117,7 +117,7 @@ static int __init prom_memtype_classify(union linux_memtypes type) return memtype_classify_arc(type); } -void __init prom_meminit(void) +void __weak __init prom_meminit(void) { struct linux_mdesc *p; @@ -162,7 +162,7 @@ void __weak __init prom_cleanup(void) { } -void __init prom_free_prom_memory(void) +void __weak __init prom_free_prom_memory(void) { int i; diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 0ba4ce6e2bf3..e2f503fc7a84 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -253,10 +253,7 @@ extern bool __virt_addr_valid(const volatile void *kaddr); #define virt_addr_valid(kaddr) \ __virt_addr_valid((const volatile void *) (kaddr)) -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index aef5378f909c..f1801e7a4b15 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -270,6 +270,36 @@ cache_sync_done: extern pgd_t swapper_pg_dir[]; /* + * Platform specific pte_special() and pte_mkspecial() definitions + * are required only when ARCH_HAS_PTE_SPECIAL is enabled. + */ +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) +static inline int pte_special(pte_t pte) +{ + return pte.pte_low & _PAGE_SPECIAL; +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + pte.pte_low |= _PAGE_SPECIAL; + return pte; +} +#else +static inline int pte_special(pte_t pte) +{ + return pte_val(pte) & _PAGE_SPECIAL; +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + pte_val(pte) |= _PAGE_SPECIAL; + return pte; +} +#endif +#endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */ + +/* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ @@ -277,7 +307,6 @@ extern pgd_t swapper_pg_dir[]; static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return pte.pte_low & _PAGE_SPECIAL; } static inline pte_t pte_wrprotect(pte_t pte) { @@ -338,17 +367,10 @@ static inline pte_t pte_mkyoung(pte_t pte) } return pte; } - -static inline pte_t pte_mkspecial(pte_t pte) -{ - pte.pte_low |= _PAGE_SPECIAL; - return pte; -} #else static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } static inline pte_t pte_wrprotect(pte_t pte) { @@ -392,12 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte) return pte; } -static inline pte_t pte_mkspecial(pte_t pte) -{ - pte_val(pte) |= _PAGE_SPECIAL; - return pte; -} - #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; } diff --git a/arch/mips/kernel/.gitignore b/arch/mips/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/mips/kernel/.gitignore +++ b/arch/mips/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/mips/kernel/syscalls/syscallhdr.sh b/arch/mips/kernel/syscalls/syscallhdr.sh index d2bcfa8f4d1a..2e241e713a7d 100644 --- a/arch/mips/kernel/syscalls/syscallhdr.sh +++ b/arch/mips/kernel/syscalls/syscallhdr.sh @@ -32,6 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" - printf "\n" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig index eac25aef21e0..b91d145aa2d5 100644 --- a/arch/mips/kvm/Kconfig +++ b/arch/mips/kvm/Kconfig @@ -72,6 +72,4 @@ config KVM_MIPS_DEBUG_COP0_COUNTERS If unsure, say N. -source "drivers/vhost/Kconfig" - endif # VIRTUALIZATION diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index dc42ffc83825..fcea92d95d86 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -49,16 +49,11 @@ void arch_dma_prep_coherent(struct page *page, size_t size) dma_cache_wback_inv((unsigned long)page_address(page), size); } -void *uncached_kernel_address(void *addr) +void *arch_dma_set_uncached(void *addr, size_t size) { return (void *)(__pa(addr) + UNCAC_BASE); } -void *cached_kernel_address(void *addr) -{ - return __va(addr) - UNCAC_BASE; -} - static inline void dma_sync_virt(void *addr, size_t size, enum dma_data_direction dir) { diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 4a0eafe3d932..f8d62cd83b36 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -142,7 +142,7 @@ good_area: goto bad_area; } } else { - if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) + if (unlikely(!vma_is_accessible(vma))) goto bad_area; } } diff --git a/arch/mips/tools/.gitignore b/arch/mips/tools/.gitignore index b0209450d9ff..794817dfb389 100644 --- a/arch/mips/tools/.gitignore +++ b/arch/mips/tools/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only elf-entry loongson3-llsc-check diff --git a/arch/mips/vdso/.gitignore b/arch/mips/vdso/.gitignore index 5286a7d73d79..1f43f6dd8142 100644 --- a/arch/mips/vdso/.gitignore +++ b/arch/mips/vdso/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only *.so* vdso-*image.c genvdso diff --git a/arch/nds32/include/asm/page.h b/arch/nds32/include/asm/page.h index 86b32014c5f9..add33a7f02c8 100644 --- a/arch/nds32/include/asm/page.h +++ b/arch/nds32/include/asm/page.h @@ -59,9 +59,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #endif /* __KERNEL__ */ #endif diff --git a/arch/nds32/include/asm/pgtable.h b/arch/nds32/include/asm/pgtable.h index 6abc58ac406d..476cc4dd1709 100644 --- a/arch/nds32/include/asm/pgtable.h +++ b/arch/nds32/include/asm/pgtable.h @@ -286,15 +286,6 @@ PTE_BIT_FUNC(mkclean, &=~_PAGE_D); PTE_BIT_FUNC(mkdirty, |=_PAGE_D); PTE_BIT_FUNC(mkold, &=~_PAGE_YOUNG); PTE_BIT_FUNC(mkyoung, |=_PAGE_YOUNG); -static inline int pte_special(pte_t pte) -{ - return 0; -} - -static inline pte_t pte_mkspecial(pte_t pte) -{ - return pte; -} /* * Mark the prot value as uncacheable and unbufferable. diff --git a/arch/nds32/kernel/.gitignore b/arch/nds32/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/nds32/kernel/.gitignore +++ b/arch/nds32/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/nds32/kernel/vdso/.gitignore b/arch/nds32/kernel/vdso/.gitignore index f8b69d84238e..652e31d82582 100644 --- a/arch/nds32/kernel/vdso/.gitignore +++ b/arch/nds32/kernel/vdso/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S index f679d3397436..7a6c1cefe3fe 100644 --- a/arch/nds32/kernel/vmlinux.lds.S +++ b/arch/nds32/kernel/vmlinux.lds.S @@ -47,6 +47,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) } diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c index 0cf0c08c7da2..f331e533edc2 100644 --- a/arch/nds32/mm/fault.c +++ b/arch/nds32/mm/fault.c @@ -79,7 +79,7 @@ void do_page_fault(unsigned long entry, unsigned long addr, struct vm_area_struct *vma; int si_code; vm_fault_t fault; - unsigned int mask = VM_READ | VM_WRITE | VM_EXEC; + unsigned int mask = VM_ACCESS_FLAGS; unsigned int flags = FAULT_FLAG_DEFAULT; error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE); diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 44b5da37e8bd..c6645141bb2a 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -2,10 +2,12 @@ config NIOS2 def_bool y select ARCH_32BIT_OFF_T + select ARCH_HAS_DMA_PREP_COHERENT select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select ARCH_HAS_UNCACHED_SEGMENT + select ARCH_HAS_DMA_SET_UNCACHED select ARCH_NO_SWAP + select COMMON_CLK select TIMER_OF select GENERIC_ATOMIC64 select GENERIC_CLOCKEVENTS diff --git a/arch/nios2/boot/.gitignore b/arch/nios2/boot/.gitignore index 64386a8dedd8..ef37cac5bcc0 100644 --- a/arch/nios2/boot/.gitignore +++ b/arch/nios2/boot/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmImage diff --git a/arch/nios2/boot/dts/10m50_devboard.dts b/arch/nios2/boot/dts/10m50_devboard.dts index 5e4ab032c1e8..56339bef3247 100644 --- a/arch/nios2/boot/dts/10m50_devboard.dts +++ b/arch/nios2/boot/dts/10m50_devboard.dts @@ -179,8 +179,7 @@ led_pio: gpio@180014d0 { compatible = "altr,pio-1.0"; reg = <0x180014d0 0x00000010>; - altr,gpio-bank-width = <4>; - resetvalue = <15>; + altr,ngpio = <4>; #gpio-cells = <2>; gpio-controller; }; @@ -190,11 +189,10 @@ reg = <0x180014c0 0x00000010>; interrupt-parent = <&cpu>; interrupts = <6>; - altr,gpio-bank-width = <3>; + altr,ngpio = <3>; altr,interrupt-type = <2>; edge_type = <1>; level_trigger = <0>; - resetvalue = <0>; #gpio-cells = <2>; gpio-controller; }; diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h index 79fcac61f6ef..6a989819a7c1 100644 --- a/arch/nios2/include/asm/page.h +++ b/arch/nios2/include/asm/page.h @@ -98,8 +98,7 @@ static inline bool pfn_valid(unsigned long pfn) # define virt_to_page(vaddr) pfn_to_page(PFN_DOWN(virt_to_phys(vaddr))) # define virt_addr_valid(vaddr) pfn_valid(PFN_DOWN(virt_to_phys(vaddr))) -# define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +# define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC #include <asm-generic/memory_model.h> diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h index 99985d8b7166..f98b7f4519ba 100644 --- a/arch/nios2/include/asm/pgtable.h +++ b/arch/nios2/include/asm/pgtable.h @@ -113,7 +113,6 @@ static inline int pte_dirty(pte_t pte) \ { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) \ { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } #define pgprot_noncached pgprot_noncached @@ -168,8 +167,6 @@ static inline pte_t pte_mkdirty(pte_t pte) return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; diff --git a/arch/nios2/kernel/.gitignore b/arch/nios2/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/nios2/kernel/.gitignore +++ b/arch/nios2/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c index 0ed711e37902..fd887d5f3f9a 100644 --- a/arch/nios2/mm/dma-mapping.c +++ b/arch/nios2/mm/dma-mapping.c @@ -67,7 +67,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size) flush_dcache_range(start, start + size); } -void *uncached_kernel_address(void *ptr) +void *arch_dma_set_uncached(void *ptr, size_t size) { unsigned long addr = (unsigned long)ptr; @@ -75,13 +75,3 @@ void *uncached_kernel_address(void *ptr) return (void *)ptr; } - -void *cached_kernel_address(void *ptr) -{ - unsigned long addr = (unsigned long)ptr; - - addr &= ~CONFIG_NIOS2_IO_REGION_BASE; - addr |= CONFIG_NIOS2_KERNEL_REGION_BASE; - - return (void *)ptr; -} diff --git a/arch/nios2/platform/platform.c b/arch/nios2/platform/platform.c index 2a35154ca153..9737a87121fa 100644 --- a/arch/nios2/platform/platform.c +++ b/arch/nios2/platform/platform.c @@ -15,6 +15,12 @@ #include <linux/slab.h> #include <linux/sys_soc.h> #include <linux/io.h> +#include <linux/clk-provider.h> + +static const struct of_device_id clk_match[] __initconst = { + { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, + {} +}; static int __init nios2_soc_device_init(void) { @@ -38,6 +44,8 @@ static int __init nios2_soc_device_init(void) } } + of_clk_init(clk_match); + return 0; } diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 1928e061ff96..8588996165ae 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -7,6 +7,8 @@ config OPENRISC def_bool y select ARCH_32BIT_OFF_T + select ARCH_HAS_DMA_SET_UNCACHED + select ARCH_HAS_DMA_CLEAR_UNCACHED select ARCH_HAS_SYNC_DMA_FOR_DEVICE select OF select OF_EARLY_FLATTREE @@ -14,6 +16,7 @@ config OPENRISC select HANDLE_DOMAIN_IRQ select GPIOLIB select HAVE_ARCH_TRACEHOOK + select HAVE_COPY_THREAD_TLS select SPARSE_IRQ select GENERIC_IRQ_CHIP select GENERIC_IRQ_PROBE diff --git a/arch/openrisc/configs/or1ksim_defconfig b/arch/openrisc/configs/or1ksim_defconfig index d8ff4f8ffb88..75f2da324d0e 100644 --- a/arch/openrisc/configs/or1ksim_defconfig +++ b/arch/openrisc/configs/or1ksim_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="or1k-linux-" CONFIG_NO_HZ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y diff --git a/arch/openrisc/configs/simple_smp_defconfig b/arch/openrisc/configs/simple_smp_defconfig index 64278992df9c..ff49d868e040 100644 --- a/arch/openrisc/configs/simple_smp_defconfig +++ b/arch/openrisc/configs/simple_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="or1k-linux-" CONFIG_LOCALVERSION="-simple-smp" CONFIG_NO_HZ=y CONFIG_LOG_BUF_SHIFT=14 diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h index 01069db59454..aab6e64d6db4 100644 --- a/arch/openrisc/include/asm/page.h +++ b/arch/openrisc/include/asm/page.h @@ -86,11 +86,6 @@ typedef struct page *pgtable_t; #endif /* __ASSEMBLY__ */ - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - - #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h index 248d22d8faa7..7f3fb9ceb083 100644 --- a/arch/openrisc/include/asm/pgtable.h +++ b/arch/openrisc/include/asm/pgtable.h @@ -236,8 +236,6 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } static inline pte_t pte_wrprotect(pte_t pte) { diff --git a/arch/openrisc/include/uapi/asm/unistd.h b/arch/openrisc/include/uapi/asm/unistd.h index 566f8c4f8047..fae34c60fa88 100644 --- a/arch/openrisc/include/uapi/asm/unistd.h +++ b/arch/openrisc/include/uapi/asm/unistd.h @@ -24,6 +24,7 @@ #define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_SYS_CLONE3 #define __ARCH_WANT_TIME32_SYSCALLS #include <asm-generic/unistd.h> diff --git a/arch/openrisc/kernel/.gitignore b/arch/openrisc/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/openrisc/kernel/.gitignore +++ b/arch/openrisc/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index adec711ad39d..c152a68811dd 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c @@ -11,8 +11,6 @@ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> * * DMA mapping callbacks... - * As alloc_coherent is the only DMA callback being used currently, that's - * the only thing implemented properly. The rest need looking into... */ #include <linux/dma-noncoherent.h> @@ -67,62 +65,29 @@ static const struct mm_walk_ops clear_nocache_walk_ops = { .pte_entry = page_clear_nocache, }; -/* - * Alloc "coherent" memory, which for OpenRISC means simply uncached. - * - * This function effectively just calls __get_free_pages, sets the - * cache-inhibit bit on those pages, and makes sure that the pages are - * flushed out of the cache before they are used. - * - * If the NON_CONSISTENT attribute is set, then this function just - * returns "normal", cachable memory. - * - * There are additional flags WEAK_ORDERING and WRITE_COMBINE to take - * into consideration here, too. All current known implementations of - * the OR1K support only strongly ordered memory accesses, so that flag - * is being ignored for now; uncached but write-combined memory is a - * missing feature of the OR1K. - */ -void * -arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t gfp, unsigned long attrs) +void *arch_dma_set_uncached(void *cpu_addr, size_t size) { - unsigned long va; - void *page; - - page = alloc_pages_exact(size, gfp | __GFP_ZERO); - if (!page) - return NULL; - - /* This gives us the real physical address of the first page. */ - *dma_handle = __pa(page); - - va = (unsigned long)page; + unsigned long va = (unsigned long)cpu_addr; + int error; /* * We need to iterate through the pages, clearing the dcache for * them and setting the cache-inhibit bit. */ - if (walk_page_range(&init_mm, va, va + size, &set_nocache_walk_ops, - NULL)) { - free_pages_exact(page, size); - return NULL; - } - - return (void *)va; + error = walk_page_range(&init_mm, va, va + size, &set_nocache_walk_ops, + NULL); + if (error) + return ERR_PTR(error); + return cpu_addr; } -void -arch_dma_free(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, unsigned long attrs) +void arch_dma_clear_uncached(void *cpu_addr, size_t size) { - unsigned long va = (unsigned long)vaddr; + unsigned long va = (unsigned long)cpu_addr; /* walk_page_range shouldn't be able to fail here */ WARN_ON(walk_page_range(&init_mm, va, va + size, &clear_nocache_walk_ops, NULL)); - - free_pages_exact(vaddr, size); } void arch_sync_dma_for_device(phys_addr_t addr, size_t size, diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index b06f84f6676f..6bcdca424e11 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c @@ -117,12 +117,12 @@ void release_thread(struct task_struct *dead_task) extern asmlinkage void ret_from_fork(void); /* - * copy_thread + * copy_thread_tls * @clone_flags: flags * @usp: user stack pointer or fn for kernel thread * @arg: arg to fn for kernel thread; always NULL for userspace thread * @p: the newly created task - * @regs: CPU context to copy for userspace thread; always NULL for kthread + * @tls: the Thread Local Storage pointer for the new process * * At the top of a newly initialized kernel stack are two stacked pt_reg * structures. The first (topmost) is the userspace context of the thread. @@ -148,8 +148,8 @@ extern asmlinkage void ret_from_fork(void); */ int -copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, struct task_struct *p) +copy_thread_tls(unsigned long clone_flags, unsigned long usp, + unsigned long arg, struct task_struct *p, unsigned long tls) { struct pt_regs *userregs; struct pt_regs *kregs; @@ -179,16 +179,10 @@ copy_thread(unsigned long clone_flags, unsigned long usp, userregs->sp = usp; /* - * For CLONE_SETTLS set "tp" (r10) to the TLS pointer passed to sys_clone. - * - * The kernel entry is: - * int clone (long flags, void *child_stack, int *parent_tid, - * int *child_tid, struct void *tls) - * - * This makes the source r7 in the kernel registers. + * For CLONE_SETTLS set "tp" (r10) to the TLS pointer. */ if (clone_flags & CLONE_SETTLS) - userregs->gpr[10] = userregs->gpr[7]; + userregs->gpr[10] = tls; userregs->gpr[11] = 0; /* Result from fork() */ diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c index 7d518ee8bddc..bd1e660bbc89 100644 --- a/arch/openrisc/kernel/smp.c +++ b/arch/openrisc/kernel/smp.c @@ -14,6 +14,7 @@ #include <linux/smp.h> #include <linux/cpu.h> #include <linux/sched.h> +#include <linux/sched/mm.h> #include <linux/irq.h> #include <asm/cpuinfo.h> #include <asm/mmu_context.h> @@ -113,7 +114,7 @@ asmlinkage __init void secondary_start_kernel(void) * All kernel threads share the same mm context; grab a * reference and switch to it. */ - atomic_inc(&mm->mm_count); + mmgrab(mm); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c index 932a8ec2b520..c11aa2e17ce0 100644 --- a/arch/openrisc/kernel/traps.c +++ b/arch/openrisc/kernel/traps.c @@ -55,13 +55,6 @@ void show_stack(struct task_struct *task, unsigned long *esp) unwind_stack(NULL, esp, print_trace); } -void show_trace_task(struct task_struct *tsk) -{ - /* - * TODO: SysRq-T trace dump... - */ -} - void show_registers(struct pt_regs *regs) { int i; diff --git a/arch/parisc/boot/.gitignore b/arch/parisc/boot/.gitignore index 017d5912ad2d..adf2ae0e7eda 100644 --- a/arch/parisc/boot/.gitignore +++ b/arch/parisc/boot/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only image bzImage diff --git a/arch/parisc/boot/compressed/.gitignore b/arch/parisc/boot/compressed/.gitignore index 926cd41c1069..b9853a356ab2 100644 --- a/arch/parisc/boot/compressed/.gitignore +++ b/arch/parisc/boot/compressed/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only firmware.c real2.S sizes.h diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 796ae29e9b9a..6b3f6740a6a6 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -180,9 +180,6 @@ extern int npmem_ranges; #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> #include <asm/pdc.h> diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index f0a365950536..9832c73a7021 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -377,7 +377,6 @@ static inline void pud_clear(pud_t *pud) { static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } -static inline int pte_special(pte_t pte) { return 0; } static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } @@ -385,7 +384,6 @@ static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; ret static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } /* * Huge pte definitions. diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 197d2247e4db..70fecb8dc4e2 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -10,25 +10,34 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); + smp_mb(); return *a == 0; } -#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) +static inline void arch_spin_lock(arch_spinlock_t *x) +{ + volatile unsigned int *a; + + a = __ldcw_align(x); + while (__ldcw(a) == 0) + while (*a == 0) + cpu_relax(); +} static inline void arch_spin_lock_flags(arch_spinlock_t *x, unsigned long flags) { volatile unsigned int *a; + unsigned long flags_dis; a = __ldcw_align(x); - while (__ldcw(a) == 0) + while (__ldcw(a) == 0) { + local_save_flags(flags_dis); + local_irq_restore(flags); while (*a == 0) - if (flags & PSW_SM_I) { - local_irq_enable(); - cpu_relax(); - local_irq_disable(); - } else - cpu_relax(); + cpu_relax(); + local_irq_restore(flags_dis); + } } #define arch_spin_lock_flags arch_spin_lock_flags @@ -58,116 +67,93 @@ static inline int arch_spin_trylock(arch_spinlock_t *x) /* * Read-write spinlocks, allowing multiple readers but only one writer. - * Linux rwlocks are unfair to writers; they can be starved for an indefinite - * time by readers. With care, they can also be taken in interrupt context. + * Unfair locking as Writers could be starved indefinitely by Reader(s) * - * In the PA-RISC implementation, we have a spinlock and a counter. - * Readers use the lock to serialise their access to the counter (which - * records how many readers currently hold the lock). - * Writers hold the spinlock, preventing any readers or other writers from - * grabbing the rwlock. + * The spinlock itself is contained in @counter and access to it is + * serialized with @lock_mutex. */ -/* Note that we have to ensure interrupts are disabled in case we're - * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void arch_read_lock(arch_rwlock_t *rw) +/* 1 - lock taken successfully */ +static inline int arch_read_trylock(arch_rwlock_t *rw) { + int ret = 0; unsigned long flags; - local_irq_save(flags); - arch_spin_lock_flags(&rw->lock, flags); - rw->counter++; - arch_spin_unlock(&rw->lock); - local_irq_restore(flags); -} -/* Note that we have to ensure interrupts are disabled in case we're - * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void arch_read_unlock(arch_rwlock_t *rw) -{ - unsigned long flags; local_irq_save(flags); - arch_spin_lock_flags(&rw->lock, flags); - rw->counter--; - arch_spin_unlock(&rw->lock); + arch_spin_lock(&(rw->lock_mutex)); + + /* + * zero means writer holds the lock exclusively, deny Reader. + * Otherwise grant lock to first/subseq reader + */ + if (rw->counter > 0) { + rw->counter--; + ret = 1; + } + + arch_spin_unlock(&(rw->lock_mutex)); local_irq_restore(flags); + + return ret; } -/* Note that we have to ensure interrupts are disabled in case we're - * interrupted by some other code that wants to grab the same read lock */ -static __inline__ int arch_read_trylock(arch_rwlock_t *rw) +/* 1 - lock taken successfully */ +static inline int arch_write_trylock(arch_rwlock_t *rw) { + int ret = 0; unsigned long flags; - retry: + local_irq_save(flags); - if (arch_spin_trylock(&rw->lock)) { - rw->counter++; - arch_spin_unlock(&rw->lock); - local_irq_restore(flags); - return 1; + arch_spin_lock(&(rw->lock_mutex)); + + /* + * If reader(s) hold lock (lock < __ARCH_RW_LOCK_UNLOCKED__), + * deny writer. Otherwise if unlocked grant to writer + * Hence the claim that Linux rwlocks are unfair to writers. + * (can be starved for an indefinite time by readers). + */ + if (rw->counter == __ARCH_RW_LOCK_UNLOCKED__) { + rw->counter = 0; + ret = 1; } - + arch_spin_unlock(&(rw->lock_mutex)); local_irq_restore(flags); - /* If write-locked, we fail to acquire the lock */ - if (rw->counter < 0) - return 0; - /* Wait until we have a realistic chance at the lock */ - while (arch_spin_is_locked(&rw->lock) && rw->counter >= 0) + return ret; +} + +static inline void arch_read_lock(arch_rwlock_t *rw) +{ + while (!arch_read_trylock(rw)) cpu_relax(); +} - goto retry; +static inline void arch_write_lock(arch_rwlock_t *rw) +{ + while (!arch_write_trylock(rw)) + cpu_relax(); } -/* Note that we have to ensure interrupts are disabled in case we're - * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ void arch_write_lock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned long flags; -retry: - local_irq_save(flags); - arch_spin_lock_flags(&rw->lock, flags); - if (rw->counter != 0) { - arch_spin_unlock(&rw->lock); - local_irq_restore(flags); - - while (rw->counter != 0) - cpu_relax(); - - goto retry; - } - - rw->counter = -1; /* mark as write-locked */ - mb(); + local_irq_save(flags); + arch_spin_lock(&(rw->lock_mutex)); + rw->counter++; + arch_spin_unlock(&(rw->lock_mutex)); local_irq_restore(flags); } -static __inline__ void arch_write_unlock(arch_rwlock_t *rw) -{ - rw->counter = 0; - arch_spin_unlock(&rw->lock); -} - -/* Note that we have to ensure interrupts are disabled in case we're - * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ int arch_write_trylock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { unsigned long flags; - int result = 0; local_irq_save(flags); - if (arch_spin_trylock(&rw->lock)) { - if (rw->counter == 0) { - rw->counter = -1; - result = 1; - } else { - /* Read-locked. Oh well. */ - arch_spin_unlock(&rw->lock); - } - } + arch_spin_lock(&(rw->lock_mutex)); + rw->counter = __ARCH_RW_LOCK_UNLOCKED__; + arch_spin_unlock(&(rw->lock_mutex)); local_irq_restore(flags); - - return result; } #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 42979c5704dc..ca39ee350c3f 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -12,11 +12,19 @@ typedef struct { #endif } arch_spinlock_t; + +/* counter: + * Unlocked : 0x0100_0000 + * Read lock(s) : 0x00FF_FFFF to 0x01 (Multiple Readers decrement it) + * Write lock : 0x0, but only if prior value is "unlocked" 0x0100_0000 + */ typedef struct { - arch_spinlock_t lock; - volatile int counter; + arch_spinlock_t lock_mutex; + volatile unsigned int counter; } arch_rwlock_t; -#define __ARCH_RW_LOCK_UNLOCKED { __ARCH_SPIN_LOCK_UNLOCKED, 0 } +#define __ARCH_RW_LOCK_UNLOCKED__ 0x01000000 +#define __ARCH_RW_LOCK_UNLOCKED { .lock_mutex = __ARCH_SPIN_LOCK_UNLOCKED, \ + .counter = __ARCH_RW_LOCK_UNLOCKED__ } #endif diff --git a/arch/parisc/kernel/.gitignore b/arch/parisc/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/parisc/kernel/.gitignore +++ b/arch/parisc/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/parisc/kernel/alternative.c b/arch/parisc/kernel/alternative.c index 3c66d5c4d90d..fa28c4c9f972 100644 --- a/arch/parisc/kernel/alternative.c +++ b/arch/parisc/kernel/alternative.c @@ -25,6 +25,22 @@ void __init_or_module apply_alternatives(struct alt_instr *start, struct alt_instr *entry; int index = 0, applied = 0; int num_cpus = num_online_cpus(); + u32 cond_check; + + cond_check = ALT_COND_ALWAYS | + ((num_cpus == 1) ? ALT_COND_NO_SMP : 0) | + ((cache_info.dc_size == 0) ? ALT_COND_NO_DCACHE : 0) | + ((cache_info.ic_size == 0) ? ALT_COND_NO_ICACHE : 0) | + (running_on_qemu ? ALT_COND_RUN_ON_QEMU : 0) | + ((split_tlb == 0) ? ALT_COND_NO_SPLIT_TLB : 0) | + /* + * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit + * set (bit #61, big endian), we have to flush and sync every + * time IO-PDIR is changed in Ike/Astro. + */ + (((boot_cpu_data.cpu_type > pcxw_) && + ((boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) == 0)) + ? ALT_COND_NO_IOC_FDC : 0); for (entry = start; entry < end; entry++, index++) { @@ -38,29 +54,14 @@ void __init_or_module apply_alternatives(struct alt_instr *start, WARN_ON(!cond); - if (cond != ALT_COND_ALWAYS && no_alternatives) + if ((cond & ALT_COND_ALWAYS) == 0 && no_alternatives) continue; pr_debug("Check %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n", index, cond, len, from, replacement); - if ((cond & ALT_COND_NO_SMP) && (num_cpus != 1)) - continue; - if ((cond & ALT_COND_NO_DCACHE) && (cache_info.dc_size != 0)) - continue; - if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0)) - continue; - if ((cond & ALT_COND_RUN_ON_QEMU) && !running_on_qemu) - continue; - - /* - * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit - * set (bit #61, big endian), we have to flush and sync every - * time IO-PDIR is changed in Ike/Astro. - */ - if ((cond & ALT_COND_NO_IOC_FDC) && - ((boot_cpu_data.cpu_type <= pcxw_) || - (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC))) + /* Bounce out if none of the conditions are true. */ + if ((cond & cond_check) == 0) continue; /* Want to replace pdtlb by a pdtlb,l instruction? */ diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index e5fcfb70cc7c..e76c86619949 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -560,33 +560,23 @@ void do_cpu_irq_mask(struct pt_regs *regs) goto out; } -static struct irqaction timer_action = { - .handler = timer_interrupt, - .name = "timer", - .flags = IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL, -}; - -#ifdef CONFIG_SMP -static struct irqaction ipi_action = { - .handler = ipi_interrupt, - .name = "IPI", - .flags = IRQF_PERCPU, -}; -#endif - static void claim_cpu_irqs(void) { + unsigned long flags = IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL; int i; + for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { irq_set_chip_and_handler(i, &cpu_interrupt_type, handle_percpu_irq); } irq_set_handler(TIMER_IRQ, handle_percpu_irq); - setup_irq(TIMER_IRQ, &timer_action); + if (request_irq(TIMER_IRQ, timer_interrupt, flags, "timer", NULL)) + pr_err("Failed to register timer interrupt\n"); #ifdef CONFIG_SMP irq_set_handler(IPI_IRQ, handle_percpu_irq); - setup_irq(IPI_IRQ, &ipi_action); + if (request_irq(IPI_IRQ, ipi_interrupt, IRQF_PERCPU, "IPI", NULL)) + pr_err("Failed to register IPI interrupt\n"); #endif } diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 97ac707c6bff..f05c9d5b6b9e 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -935,7 +935,7 @@ ENTRY(lws_table) END(lws_table) /* End of lws table */ -#define __SYSCALL(nr, entry, nargs) ASM_ULONG_INSN entry +#define __SYSCALL(nr, entry) ASM_ULONG_INSN entry .align 8 ENTRY(sys_call_table) .export sys_call_table,data diff --git a/arch/parisc/kernel/syscalls/syscallhdr.sh b/arch/parisc/kernel/syscalls/syscallhdr.sh index 50242b747d7c..730db288fe54 100644 --- a/arch/parisc/kernel/syscalls/syscallhdr.sh +++ b/arch/parisc/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/parisc/kernel/syscalls/syscalltbl.sh b/arch/parisc/kernel/syscalls/syscalltbl.sh index 45b5bae26240..f7393a7b18aa 100644 --- a/arch/parisc/kernel/syscalls/syscalltbl.sh +++ b/arch/parisc/kernel/syscalls/syscalltbl.sh @@ -13,10 +13,10 @@ emit() { t_entry="$3" while [ $t_nxt -lt $t_nr ]; do - printf "__SYSCALL(%s, sys_ni_syscall, )\n" "${t_nxt}" + printf "__SYSCALL(%s,sys_ni_syscall)\n" "${t_nxt}" t_nxt=$((t_nxt+1)) done - printf "__SYSCALL(%s, %s, )\n" "${t_nxt}" "${t_entry}" + printf "__SYSCALL(%s,%s)\n" "${t_nxt}" "${t_entry}" } grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5fc45364e86e..924c541a9260 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -122,6 +122,7 @@ config PPC select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOV select ARCH_HAS_HUGEPD if HUGETLB_PAGE + select ARCH_HAS_MEMREMAP_COMPAT_ALIGN select ARCH_HAS_MMIOWB if PPC64 select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PMEM_API @@ -265,8 +266,9 @@ config PANIC_TIMEOUT default 180 config COMPAT - bool - default y if PPC64 + bool "Enable support for 32bit binaries" + depends on PPC64 + default y if !CPU_LITTLE_ENDIAN select COMPAT_BINFMT_ELF select ARCH_WANT_OLD_COMPAT_IPC select COMPAT_OLD_SIGACTION diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index f35730548e42..f310c32e88a4 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -239,10 +239,8 @@ KBUILD_CFLAGS += $(call cc-option,-mno-vsx) KBUILD_CFLAGS += $(call cc-option,-mno-spe) KBUILD_CFLAGS += $(call cc-option,-mspe=no) -# FIXME: the module load should be taught about the additional relocs -# generated by this. -# revert to pre-gcc-4.4 behaviour of .eh_frame -KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) +# Don't emit .eh_frame since we have no use for it +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables # Never use string load/store instructions as they are # often slow when they are implemented at all @@ -298,6 +296,7 @@ $(BOOT_TARGETS2): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) +PHONY += bootwrapper_install bootwrapper_install: $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@) @@ -403,9 +402,11 @@ define archhelp @echo ' (minus the .dts extension).' endef +PHONY += install install: $(Q)$(MAKE) $(build)=$(boot) install +PHONY += vdso_install vdso_install: ifdef CONFIG_PPC64 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ @@ -425,6 +426,7 @@ archheaders: ifdef CONFIG_STACKPROTECTOR prepare: stack_protector_prepare +PHONY += stack_protector_prepare stack_protector_prepare: prepare0 ifdef CONFIG_PPC64 $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) @@ -436,10 +438,12 @@ endif ifdef CONFIG_SMP prepare: task_cpu_prepare +PHONY += task_cpu_prepare task_cpu_prepare: prepare0 $(eval KBUILD_CFLAGS += -D_TASK_CPU=$(shell awk '{if ($$2 == "TASK_CPU") print $$3;}' include/generated/asm-offsets.h)) endif +PHONY += checkbin # Check toolchain versions: # - gcc-4.6 is the minimum kernel-wide version so nothing required. checkbin: diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore index 6610665fcf5e..1eee61b82341 100644 --- a/arch/powerpc/boot/.gitignore +++ b/arch/powerpc/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only addnote decompress_inflate.c empty.c diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 0556bf4fc9e9..c53a1b8bba8b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -445,6 +445,8 @@ install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) zInstall: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ +PHONY += install zInstall + # anything not in $(targets) clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 92608f34d312..1d83966f5ef6 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S @@ -44,9 +44,6 @@ p_end: .long _end p_pstack: .long _platform_stack_top #endif - .globl _zimage_start - /* Clang appears to require the .weak directive to be after the symbol - * is defined. See https://bugs.llvm.org/show_bug.cgi?id=38921 */ .weak _zimage_start _zimage_start: .globl _zimage_start_lib diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config index 9575a38c9155..b507df6ac69f 100644 --- a/arch/powerpc/configs/85xx-hw.config +++ b/arch/powerpc/configs/85xx-hw.config @@ -2,7 +2,6 @@ CONFIG_AQUANTIA_PHY=y CONFIG_AT803X_PHY=y CONFIG_ATA=y CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_BLK_DEV_SR=y CONFIG_BROADCOM_PHY=y CONFIG_C293_PCIE=y diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index f6d140f2d922..200bb1ecb560 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -44,7 +44,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SYM53C8XX_2=y diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index 502a75d49789..a4a805b87469 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -42,7 +42,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SYM53C8XX_2=y diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index fbfcc85e4dc0..a68c7f3af10e 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -62,7 +62,6 @@ CONFIG_CDROM_PKTCDVD=m CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 2975e64629aa..161351a18517 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -41,7 +41,6 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_IPR=y CONFIG_ATA=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 4b6d31d4474e..08b7f4cef243 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -60,7 +60,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=y CONFIG_SCSI_CONSTANTS=y diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index f492e7d35925..05e325ca3fbd 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -117,7 +117,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index 71749377d164..df8bdbaa5d8f 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -108,7 +108,6 @@ CONFIG_BLK_DEV_NVME=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 7e68cb222c7b..bae8170d7401 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -110,7 +110,6 @@ CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 0d746774c2bd..33a01a9e86be 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -60,7 +60,6 @@ CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 3e2f44f38ac5..feb5d47d8d1e 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -368,7 +368,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_ENCLOSURE=m diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index 4db51719342a..81b55c880fc3 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -60,6 +60,8 @@ CONFIG_CFG80211=m CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m # CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65535 diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 6b68109e248f..0bea4d3ffb85 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -97,7 +97,6 @@ CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y diff --git a/arch/powerpc/configs/skiroot_defconfig b/arch/powerpc/configs/skiroot_defconfig index 1b6bdad36b13..ad6739ac63dc 100644 --- a/arch/powerpc/configs/skiroot_defconfig +++ b/arch/powerpc/configs/skiroot_defconfig @@ -84,7 +84,6 @@ CONFIG_EEPROM_AT24=m # CONFIG_OCXL is not set CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index 983c0084fb3f..7d81e86a1e5d 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -97,6 +97,10 @@ ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, unsigned long __init early_init(unsigned long dt_ptr); void __init machine_init(u64 dt_ptr); #endif +long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8, unsigned long r0, struct pt_regs *regs); +notrace unsigned long syscall_exit_prepare(unsigned long r3, struct pt_regs *regs); +notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned long msr); +notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr); long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, u32 len_high, u32 len_low); @@ -104,14 +108,6 @@ long sys_switch_endian(void); notrace unsigned int __check_irq_replay(void); void notrace restore_interrupts(void); -/* ptrace */ -long do_syscall_trace_enter(struct pt_regs *regs); -void do_syscall_trace_leave(struct pt_regs *regs); - -/* process */ -void restore_math(struct pt_regs *regs); -void restore_tm_state(struct pt_regs *regs); - /* prom_init (OpenFirmware) */ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp, @@ -122,9 +118,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, void __init early_setup(unsigned long dt_ptr); void early_setup_secondary(void); -/* time */ -void accumulate_stolen_time(void); - /* misc runtime */ extern u64 __bswapdi2(u64); extern s64 __lshrdi3(s64, int); diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h index 2a0a467d2985..34a7215ae81e 100644 --- a/arch/powerpc/include/asm/book3s/32/hash.h +++ b/arch/powerpc/include/asm/book3s/32/hash.h @@ -17,9 +17,9 @@ * updating the accessed and modified bits in the page table tree. */ -#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ -#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */ -#define _PAGE_USER 0x004 /* usermode access allowed */ +#define _PAGE_USER 0x001 /* usermode access allowed */ +#define _PAGE_RW 0x002 /* software: user write access allowed */ +#define _PAGE_PRESENT 0x004 /* software: pte contains a translation */ #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */ @@ -27,7 +27,7 @@ #define _PAGE_DIRTY 0x080 /* C: page changed */ #define _PAGE_ACCESSED 0x100 /* R: page referenced */ #define _PAGE_EXEC 0x200 /* software: exec allowed */ -#define _PAGE_RW 0x400 /* software: user write access allowed */ +#define _PAGE_HASHPTE 0x400 /* hash_page has made an HPTE for this pte */ #define _PAGE_SPECIAL 0x800 /* software: Special page */ #ifdef CONFIG_PTE_64BIT diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 5b39c11e884a..7549393c4c43 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -366,10 +366,8 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma, (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, addr) \ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr)) -#define pte_offset_map(dir, addr) \ - ((pte_t *)(kmap_atomic(pmd_page(*(dir))) + \ - (pmd_page_vaddr(*(dir)) & ~PAGE_MASK)) + pte_index(addr)) -#define pte_unmap(pte) kunmap_atomic(pte) +#define pte_offset_map(dir, addr) pte_offset_kernel((dir), (addr)) +static inline void pte_unmap(pte_t *pte) { } /* * Encode and decode a swap entry. diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 8fd8599c9395..3f9ae3585ab9 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -156,6 +156,12 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, extern int hash__has_transparent_hugepage(void); #endif +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd) +{ + BUG(); + return pmd; +} + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index d1d9177d9ebd..0729c034e56f 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -246,7 +246,7 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, */ static inline int hash__pmd_trans_huge(pmd_t pmd) { - return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE)) == + return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)) == (_PAGE_PTE | H_PAGE_THP_HUGE)); } @@ -272,6 +272,12 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp); extern int hash__has_transparent_hugepage(void); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)); +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 2781ebf6add4..6fc4520092c7 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -251,7 +251,8 @@ extern int __meminit hash__vmemmap_create_mapping(unsigned long start, extern void hash__vmemmap_remove_mapping(unsigned long start, unsigned long page_size); -int hash__create_section_mapping(unsigned long start, unsigned long end, int nid); +int hash__create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot); int hash__remove_section_mapping(unsigned long start, unsigned long end); #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/book3s/64/kup-radix.h b/arch/powerpc/include/asm/book3s/64/kup-radix.h index 90dd3a3fc8c7..3bcef989a35d 100644 --- a/arch/powerpc/include/asm/book3s/64/kup-radix.h +++ b/arch/powerpc/include/asm/book3s/64/kup-radix.h @@ -3,6 +3,7 @@ #define _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H #include <linux/const.h> +#include <asm/reg.h> #define AMR_KUAP_BLOCK_READ UL(0x4000000000000000) #define AMR_KUAP_BLOCK_WRITE UL(0x8000000000000000) @@ -56,7 +57,20 @@ #ifdef CONFIG_PPC_KUAP -#include <asm/reg.h> +#include <asm/mmu.h> +#include <asm/ptrace.h> + +static inline void kuap_restore_amr(struct pt_regs *regs) +{ + if (mmu_has_feature(MMU_FTR_RADIX_KUAP)) + mtspr(SPRN_AMR, regs->kuap); +} + +static inline void kuap_check_amr(void) +{ + if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && mmu_has_feature(MMU_FTR_RADIX_KUAP)) + WARN_ON_ONCE(mfspr(SPRN_AMR) != AMR_KUAP_BLOCKED); +} /* * We support individually allowing read or write, but we don't support nesting @@ -127,6 +141,14 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)), "Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read"); } +#else /* CONFIG_PPC_KUAP */ +static inline void kuap_restore_amr(struct pt_regs *regs) +{ +} + +static inline void kuap_check_amr(void) +{ +} #endif /* CONFIG_PPC_KUAP */ #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 201a69e6a355..368b136517e0 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -1303,7 +1303,9 @@ extern void serialize_against_pte_lookup(struct mm_struct *mm); static inline pmd_t pmd_mkdevmap(pmd_t pmd) { - return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); + if (radix_enabled()) + return radix__pmd_mkdevmap(pmd); + return hash__pmd_mkdevmap(pmd); } static inline int pmd_devmap(pmd_t pmd) diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index d97db3ad9aae..08c222d5b764 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -263,6 +263,11 @@ static inline int radix__has_transparent_hugepage(void) } #endif +static inline pmd_t radix__pmd_mkdevmap(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); +} + extern int __meminit radix__vmemmap_create_mapping(unsigned long start, unsigned long page_size, unsigned long phys); @@ -289,7 +294,8 @@ static inline unsigned long radix__get_tree_size(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int radix__create_section_mapping(unsigned long start, unsigned long end, int nid); +int radix__create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot); int radix__remove_section_mapping(unsigned long start, unsigned long end); #endif /* CONFIG_MEMORY_HOTPLUG */ #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 72b81015cebe..609cab1d58f2 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -97,7 +97,7 @@ static inline u32 l1_icache_bytes(void) #endif -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(.data..read_mostly) #ifdef CONFIG_PPC_BOOK3S_32 extern long _get_L2CR(void); diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 4a1c9f0200e1..e92191b390f3 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -65,17 +65,13 @@ static inline void flush_dcache_range(unsigned long start, unsigned long stop) unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; - if (IS_ENABLED(CONFIG_PPC64)) { + if (IS_ENABLED(CONFIG_PPC64)) mb(); /* sync */ - isync(); - } for (i = 0; i < size >> shift; i++, addr += bytes) dcbf(addr); mb(); /* sync */ - if (IS_ENABLED(CONFIG_PPC64)) - isync(); } /* diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 2431b4ada2fa..0fccd5ea1e9a 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -43,9 +43,12 @@ static inline unsigned long cputime_to_usecs(const cputime_t ct) */ #ifdef CONFIG_PPC64 #define get_accounting(tsk) (&get_paca()->accounting) +#define raw_get_accounting(tsk) (&local_paca->accounting) static inline void arch_vtime_task_switch(struct task_struct *tsk) { } + #else #define get_accounting(tsk) (&task_thread_info(tsk)->accounting) +#define raw_get_accounting(tsk) get_accounting(tsk) /* * Called from the context switch with interrupts disabled, to charge all * accumulated times to the current process, and to prepare accounting on @@ -60,6 +63,36 @@ static inline void arch_vtime_task_switch(struct task_struct *prev) } #endif +/* + * account_cpu_user_entry/exit runs "unreconciled", so can't trace, + * can't use use get_paca() + */ +static notrace inline void account_cpu_user_entry(void) +{ + unsigned long tb = mftb(); + struct cpu_accounting_data *acct = raw_get_accounting(current); + + acct->utime += (tb - acct->starttime_user); + acct->starttime = tb; +} + +static notrace inline void account_cpu_user_exit(void) +{ + unsigned long tb = mftb(); + struct cpu_accounting_data *acct = raw_get_accounting(current); + + acct->stime += (tb - acct->starttime); + acct->starttime_user = tb; +} + + #endif /* __KERNEL__ */ +#else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ +static inline void account_cpu_user_entry(void) +{ +} +static inline void account_cpu_user_exit(void) +{ +} #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* __POWERPC_CPUTIME_H */ diff --git a/arch/powerpc/include/asm/dma.h b/arch/powerpc/include/asm/dma.h index 1b4f0254868f..6161a9596196 100644 --- a/arch/powerpc/include/asm/dma.h +++ b/arch/powerpc/include/asm/dma.h @@ -151,10 +151,9 @@ #define DMA2_EXT_REG 0x4D6 #ifndef __powerpc64__ - /* in arch/ppc/kernel/setup.c -- Cort */ + /* in arch/powerpc/kernel/setup_32.c -- Cort */ extern unsigned int DMA_MODE_WRITE; extern unsigned int DMA_MODE_READ; - extern unsigned long ISA_DMA_THRESHOLD; #else #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h index 3d76e1c388c2..28c3d936fdf3 100644 --- a/arch/powerpc/include/asm/drmem.h +++ b/arch/powerpc/include/asm/drmem.h @@ -27,12 +27,12 @@ struct drmem_lmb_info { extern struct drmem_lmb_info *drmem_info; #define for_each_drmem_lmb_in_range(lmb, start, end) \ - for ((lmb) = (start); (lmb) <= (end); (lmb)++) + for ((lmb) = (start); (lmb) < (end); (lmb)++) #define for_each_drmem_lmb(lmb) \ for_each_drmem_lmb_in_range((lmb), \ &drmem_info->lmbs[0], \ - &drmem_info->lmbs[drmem_info->n_lmbs - 1]) + &drmem_info->lmbs[drmem_info->n_lmbs]) /* * The of_drconf_cell_v1 struct defines the layout of the LMB data diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 6f9b2a12540a..964a54292b36 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -215,7 +215,7 @@ enum { struct eeh_ops { char *name; int (*init)(void); - void* (*probe)(struct pci_dn *pdn, void *data); + struct eeh_dev *(*probe)(struct pci_dev *pdev); int (*set_option)(struct eeh_pe *pe, int option); int (*get_pe_addr)(struct eeh_pe *pe); int (*get_state)(struct eeh_pe *pe, int *delay); @@ -301,11 +301,7 @@ int __exit eeh_ops_unregister(const char *name); int eeh_check_failure(const volatile void __iomem *token); int eeh_dev_check_failure(struct eeh_dev *edev); void eeh_addr_cache_init(void); -void eeh_add_device_early(struct pci_dn *); -void eeh_add_device_tree_early(struct pci_dn *); -void eeh_add_device_late(struct pci_dev *); -void eeh_add_device_tree_late(struct pci_bus *); -void eeh_add_sysfs_files(struct pci_bus *); +void eeh_probe_device(struct pci_dev *pdev); void eeh_remove_device(struct pci_dev *); int eeh_unfreeze_pe(struct eeh_pe *pe); int eeh_pe_reset_and_recover(struct eeh_pe *pe); @@ -360,15 +356,7 @@ static inline int eeh_check_failure(const volatile void __iomem *token) static inline void eeh_addr_cache_init(void) { } -static inline void eeh_add_device_early(struct pci_dn *pdn) { } - -static inline void eeh_add_device_tree_early(struct pci_dn *pdn) { } - -static inline void eeh_add_device_late(struct pci_dev *dev) { } - -static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } - -static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } +static inline void eeh_probe_device(struct pci_dev *dev) { } static inline void eeh_remove_device(struct pci_dev *dev) { } @@ -376,6 +364,14 @@ static inline void eeh_remove_device(struct pci_dev *dev) { } #define EEH_IO_ERROR_VALUE(size) (-1UL) #endif /* CONFIG_EEH */ +#if defined(CONFIG_PPC_PSERIES) && defined(CONFIG_EEH) +void pseries_eeh_init_edev(struct pci_dn *pdn); +void pseries_eeh_init_edev_recursive(struct pci_dn *pdn); +#else +static inline void pseries_eeh_add_device_early(struct pci_dn *pdn) { } +static inline void pseries_eeh_add_device_tree_early(struct pci_dn *pdn) { } +#endif + #ifdef CONFIG_PPC64 /* * MMIO read/write operations with EEH support. diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 33f4f72eb035..47bd4ea0837d 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -33,11 +33,7 @@ #include <asm/feature-fixups.h> /* PACA save area size in u64 units (exgen, exmc, etc) */ -#if defined(CONFIG_RELOCATABLE) #define EX_SIZE 10 -#else -#define EX_SIZE 9 -#endif /* * maximum recursive depth of MCE exceptions diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index e3a905e3d573..e0e71777961f 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -52,7 +52,7 @@ #ifndef __ASSEMBLY__ extern void replay_system_reset(void); -extern void __replay_interrupt(unsigned int vector); +extern void replay_soft_interrupts(void); extern void timer_interrupt(struct pt_regs *); extern void timer_broadcast_interrupt(void); @@ -228,9 +228,13 @@ static inline bool arch_irqs_disabled(void) #ifdef CONFIG_PPC_BOOK3E #define __hard_irq_enable() wrtee(MSR_EE) #define __hard_irq_disable() wrtee(0) +#define __hard_EE_RI_disable() wrtee(0) +#define __hard_RI_enable() do { } while (0) #else #define __hard_irq_enable() __mtmsrd(MSR_EE|MSR_RI, 1) #define __hard_irq_disable() __mtmsrd(MSR_RI, 1) +#define __hard_EE_RI_disable() __mtmsrd(0, 1) +#define __hard_RI_enable() __mtmsrd(MSR_RI, 1) #endif #define hard_irq_disable() do { \ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index f99b4333dfba..1dc63101ffe1 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -309,8 +309,6 @@ struct kvm_arch { pgd_t *pgtable; u64 process_table; struct dentry *debugfs_dir; - struct dentry *htab_dentry; - struct dentry *radix_dentry; struct kvm_resize_hpt *resize_hpt; /* protected by kvm->lock */ #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE @@ -831,7 +829,6 @@ struct kvm_vcpu_arch { struct kvmhv_tb_accumulator cede_time; /* time napping inside guest */ struct dentry *debugfs_dir; - struct dentry *debugfs_timings; #endif /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */ }; diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index 6a6ddaabdb34..376a395daf32 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h @@ -218,6 +218,8 @@ extern void machine_check_queue_event(void); extern void machine_check_print_event_info(struct machine_check_event *evt, bool user_mode, bool in_guest); unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr); +extern void mce_common_process_ue(struct pt_regs *regs, + struct mce_error_info *mce_err); #ifdef CONFIG_PPC_BOOK3S_64 void flush_and_reload_slb(void); #endif /* CONFIG_PPC_BOOK3S_64 */ diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index 60c4d829152e..b04ba257fddb 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -372,10 +372,8 @@ static inline int pte_young(pte_t pte) #define pte_offset_kernel(dir, addr) \ (pmd_bad(*(dir)) ? NULL : (pte_t *)pmd_page_vaddr(*(dir)) + \ pte_index(addr)) -#define pte_offset_map(dir, addr) \ - ((pte_t *)(kmap_atomic(pmd_page(*(dir))) + \ - (pmd_page_vaddr(*(dir)) & ~PAGE_MASK)) + pte_index(addr)) -#define pte_unmap(pte) kunmap_atomic(pte) +#define pte_offset_map(dir, addr) pte_offset_kernel((dir), (addr)) +static inline void pte_unmap(pte_t *pte) { } /* * Encode and decode a swap entry. diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index c1f25a760eb1..1dffa3cb16ba 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -1067,6 +1067,7 @@ enum { OPAL_REBOOT_PLATFORM_ERROR = 1, OPAL_REBOOT_FULL_IPL = 2, OPAL_REBOOT_MPIPL = 3, + OPAL_REBOOT_FAST = 4, }; /* Argument to OPAL_PCI_TCE_KILL */ diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 080a0bf8e54b..3ee8df0f66e0 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -240,13 +240,8 @@ static inline bool pfn_valid(unsigned long pfn) * and needs to be executable. This means the whole heap ends * up being executable. */ -#define VM_DATA_DEFAULT_FLAGS32 \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ - VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS32 VM_DATA_FLAGS_TSK_EXEC +#define VM_DATA_DEFAULT_FLAGS64 VM_DATA_FLAGS_NON_EXEC #ifdef __powerpc64__ #include <asm/page_64.h> diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index 5962797f784a..79a9b7c6a132 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h @@ -94,11 +94,8 @@ extern u64 ppc64_pft_size; * stack by default, so in the absence of a PT_GNU_STACK program header * we turn execute permission off. */ -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS32 VM_DATA_FLAGS_EXEC +#define VM_STACK_DEFAULT_FLAGS64 VM_DATA_FLAGS_NON_EXEC #define VM_STACK_DEFAULT_FLAGS \ (is_32bit_task() ? \ diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h index 7426d7a90e1e..eed3954082fa 100644 --- a/arch/powerpc/include/asm/perf_event.h +++ b/arch/powerpc/include/asm/perf_event.h @@ -32,7 +32,7 @@ do { \ (regs)->result = 0; \ (regs)->nip = __ip; \ - (regs)->gpr[1] = current_stack_pointer(); \ + (regs)->gpr[1] = current_stack_frame(); \ asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \ } while (0) diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 8cc543ed114c..b1f1d5339735 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -41,6 +41,25 @@ struct mm_struct; #ifndef __ASSEMBLY__ +#ifdef CONFIG_PPC32 +static inline pmd_t *pmd_ptr(struct mm_struct *mm, unsigned long va) +{ + return pmd_offset(pud_offset(pgd_offset(mm, va), va), va); +} + +static inline pmd_t *pmd_ptr_k(unsigned long va) +{ + return pmd_offset(pud_offset(pgd_offset_k(va), va), va); +} + +static inline pte_t *virt_to_kpte(unsigned long vaddr) +{ + pmd_t *pmd = pmd_ptr_k(vaddr); + + return pmd_none(*pmd) ? NULL : pte_offset_kernel(pmd, vaddr); +} +#endif + #include <asm/tlbflush.h> /* Keep these as a macros to avoid include dependency mess */ diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index ee3ada66deb5..e0195e6b892b 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -138,6 +138,9 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define profile_pc(regs) instruction_pointer(regs) #endif +long do_syscall_trace_enter(struct pt_regs *regs); +void do_syscall_trace_leave(struct pt_regs *regs); + #define kernel_stack_pointer(regs) ((regs)->gpr[1]) static inline int is_syscall_success(struct pt_regs *regs) { @@ -276,6 +279,8 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, #endif /* __ASSEMBLY__ */ #ifndef __powerpc64__ +/* We need PT_SOFTE defined at all time to avoid #ifdefs */ +#define PT_SOFTE PT_MQ #else /* __powerpc64__ */ #define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */ #define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1aa46dff0957..da5cab038e25 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1448,7 +1448,9 @@ static inline void mtsrin(u32 val, u32 idx) #define proc_trap() asm volatile("trap") -extern unsigned long current_stack_pointer(void); +extern unsigned long current_stack_frame(void); + +register unsigned long current_stack_pointer asm("r1"); extern unsigned long scom970_read(unsigned int address); extern void scom970_write(unsigned int address, unsigned long value); diff --git a/arch/powerpc/include/asm/setjmp.h b/arch/powerpc/include/asm/setjmp.h index e9f81bb3f83b..f798e80e4106 100644 --- a/arch/powerpc/include/asm/setjmp.h +++ b/arch/powerpc/include/asm/setjmp.h @@ -7,7 +7,9 @@ #define JMP_BUF_LEN 23 -extern long setjmp(long *) __attribute__((returns_twice)); -extern void longjmp(long *, long) __attribute__((noreturn)); +typedef long jmp_buf[JMP_BUF_LEN]; + +extern int setjmp(jmp_buf env) __attribute__((returns_twice)); +extern void longjmp(jmp_buf env, int val) __attribute__((noreturn)); #endif /* _ASM_POWERPC_SETJMP_H */ diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h index 0803ca8b9149..99e1c6de27bc 100644 --- a/arch/powerpc/include/asm/signal.h +++ b/arch/powerpc/include/asm/signal.h @@ -6,4 +6,7 @@ #include <uapi/asm/signal.h> #include <uapi/asm/ptrace.h> +struct pt_regs; +void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); + #endif /* _ASM_POWERPC_SIGNAL_H */ diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index 3192d454a733..c89b32443cff 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -13,7 +13,8 @@ #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_MEMORY_HOTPLUG -extern int create_section_mapping(unsigned long start, unsigned long end, int nid); +extern int create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot); extern int remove_section_mapping(unsigned long start, unsigned long end); #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 5b03d8a82409..b867b58b1093 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -5,6 +5,7 @@ #ifndef _ASM_POWERPC_SWITCH_TO_H #define _ASM_POWERPC_SWITCH_TO_H +#include <linux/sched.h> #include <asm/reg.h> struct thread_struct; @@ -22,6 +23,16 @@ extern void switch_booke_debug_regs(struct debug_reg *new_debug); extern int emulate_altivec(struct pt_regs *); +#ifdef CONFIG_PPC_BOOK3S_64 +void restore_math(struct pt_regs *regs); +#else +static inline void restore_math(struct pt_regs *regs) +{ +} +#endif + +void restore_tm_state(struct pt_regs *regs); + extern void flush_all_to_thread(struct task_struct *); extern void giveup_all(struct task_struct *); diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index a2270749b282..ca6c97025704 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -162,10 +162,10 @@ static inline bool test_thread_local_flags(unsigned int flags) return (ti->local_flags & flags) != 0; } -#ifdef CONFIG_PPC64 +#ifdef CONFIG_COMPAT #define is_32bit_task() (test_thread_flag(TIF_32BIT)) #else -#define is_32bit_task() (1) +#define is_32bit_task() (IS_ENABLED(CONFIG_PPC32)) #endif #if defined(CONFIG_PPC64) diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 08dbe3e6831c..39ce95016a3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -24,7 +24,6 @@ extern struct clock_event_device decrementer_clockevent; extern void generic_calibrate_decr(void); -extern void hdec_interrupt(struct pt_regs *regs); /* Some sane defaults: 125 MHz timebase, 1GHz processor */ extern unsigned long ppc_proc_freq; @@ -195,5 +194,8 @@ DECLARE_PER_CPU(u64, decrementers_next_tb); /* Convert timebase ticks to nanoseconds */ unsigned long long tb_to_ns(unsigned long long tb_ticks); +/* SPLPAR */ +void accumulate_stolen_time(void); + #endif /* __KERNEL__ */ #endif /* __POWERPC_TIME_H */ diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 2f7e1ea5089e..2db7ba789720 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -98,7 +98,6 @@ extern int stop_topology_update(void); extern int prrn_is_enabled(void); extern int find_and_online_cpu_nid(int cpu); extern int timed_topology_update(int nsecs); -extern void __init shared_proc_topology_init(void); #else static inline int start_topology_update(void) { @@ -121,9 +120,6 @@ static inline int timed_topology_update(int nsecs) return 0; } -#ifdef CONFIG_SMP -static inline void shared_proc_topology_init(void) {} -#endif #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ #include <asm-generic/topology.h> @@ -134,7 +130,13 @@ static inline void shared_proc_topology_init(void) {} #ifdef CONFIG_PPC64 #include <asm/smp.h> +#ifdef CONFIG_PPC_SPLPAR +int get_physical_package_id(int cpu); +#define topology_physical_package_id(cpu) (get_physical_package_id(cpu)) +#else #define topology_physical_package_id(cpu) (cpu_to_chip_id(cpu)) +#endif + #define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_core_id(cpu) (cpu_to_core_id(cpu)) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index b0720c7c3fcf..700fcdac2e3c 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -31,6 +31,7 @@ #define __ARCH_WANT_SYS_SOCKETCALL #define __ARCH_WANT_SYS_FADVISE64 #define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_NICE #define __ARCH_WANT_SYS_OLD_GETRLIMIT #define __ARCH_WANT_SYS_OLD_UNAME diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h index b5e1f8f8a05c..2ff884853f97 100644 --- a/arch/powerpc/include/asm/vdso.h +++ b/arch/powerpc/include/asm/vdso.h @@ -13,9 +13,6 @@ #define VDSO_VERSION_STRING LINUX_2.6.15 -/* Define if 64 bits VDSO has procedure descriptors */ -#undef VDS64_HAS_DESCRIPTORS - #ifndef __ASSEMBLY__ /* Offsets relative to thread->vdso_base */ @@ -28,25 +25,6 @@ int vdso_getcpu_init(void); #else /* __ASSEMBLY__ */ #ifdef __VDSO64__ -#ifdef VDS64_HAS_DESCRIPTORS -#define V_FUNCTION_BEGIN(name) \ - .globl name; \ - .section ".opd","a"; \ - .align 3; \ - name: \ - .quad .name,.TOC.@tocbase,0; \ - .previous; \ - .globl .name; \ - .type .name,@function; \ - .name: \ - -#define V_FUNCTION_END(name) \ - .size .name,.-.name; - -#define V_LOCAL_FUNC(name) (.name) - -#else /* VDS64_HAS_DESCRIPTORS */ - #define V_FUNCTION_BEGIN(name) \ .globl name; \ name: \ @@ -55,8 +33,6 @@ int vdso_getcpu_init(void); .size name,.-name; #define V_LOCAL_FUNC(name) (name) - -#endif /* VDS64_HAS_DESCRIPTORS */ #endif /* __VDSO64__ */ #ifdef __VDSO32__ diff --git a/arch/powerpc/kernel/.gitignore b/arch/powerpc/kernel/.gitignore index 67ebd3003c05..d71179d3ffe9 100644 --- a/arch/powerpc/kernel/.gitignore +++ b/arch/powerpc/kernel/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only prom_init_check vmlinux.lds diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 78a1b22d4fd8..1c4385852d3d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -3,8 +3,6 @@ # Makefile for the linux kernel. # -CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' - ifdef CONFIG_PPC64 CFLAGS_prom_init.o += $(NO_MINIMAL_TOC) endif @@ -41,16 +39,18 @@ CFLAGS_cputable.o += -DDISABLE_BRANCH_PROFILING CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING endif -obj-y := cputable.o ptrace.o syscalls.o \ - irq.o align.o signal_32.o pmc.o vdso.o \ +obj-y := cputable.o syscalls.o \ + irq.o align.o signal_$(BITS).o pmc.o vdso.o \ process.o systbl.o idle.o \ signal.o sysfs.o cacheinfo.o time.o \ prom.o traps.o setup-common.o \ udbg.o misc.o io.o misc_$(BITS).o \ of_platform.o prom_parse.o -obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ - signal_64.o ptrace32.o \ - paca.o nvram_64.o firmware.o note.o +obj-y += ptrace/ +obj-$(CONFIG_PPC64) += setup_64.o \ + paca.o nvram_64.o firmware.o note.o \ + syscall_64.o +obj-$(CONFIG_COMPAT) += sys_ppc32.o signal_32.o obj-$(CONFIG_VDSO32) += vdso32/ obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 6dfceaa820e4..f57712a55815 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -26,7 +26,7 @@ static void scrollscreen(void); #endif -#define __force_data __attribute__((__section__(".data"))) +#define __force_data __section(.data) static int g_loc_X __force_data; static int g_loc_Y __force_data; diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 245be4fafe13..13eba2eb46fe 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -2198,7 +2198,6 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, */ if (old.oprofile_cpu_type != NULL) { t->oprofile_cpu_type = old.oprofile_cpu_type; - t->oprofile_type = old.oprofile_type; t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; } } diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 182b4047c1ef..36bc0d5c4f3a 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -139,7 +139,6 @@ static void __init cpufeatures_setup_cpu(void) /* Initialize the base environment -- clear FSCR/HFSCR. */ hv_mode = !!(mfmsr() & MSR_HV); if (hv_mode) { - /* CPU_FTR_HVMODE is used early in PACA setup */ cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE; mtspr(SPRN_HFSCR, 0); } diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 17cb3e9b5697..7cdcb413bb44 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -1107,87 +1107,43 @@ static int eeh_init(void) core_initcall_sync(eeh_init); /** - * eeh_add_device_early - Enable EEH for the indicated device node - * @pdn: PCI device node for which to set up EEH - * - * This routine must be used to perform EEH initialization for PCI - * devices that were added after system boot (e.g. hotplug, dlpar). - * This routine must be called before any i/o is performed to the - * adapter (inluding any config-space i/o). - * Whether this actually enables EEH or not for this device depends - * on the CEC architecture, type of the device, on earlier boot - * command-line arguments & etc. - */ -void eeh_add_device_early(struct pci_dn *pdn) -{ - struct pci_controller *phb = pdn ? pdn->phb : NULL; - struct eeh_dev *edev = pdn_to_eeh_dev(pdn); - - if (!edev) - return; - - if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) - return; - - /* USB Bus children of PCI devices will not have BUID's */ - if (NULL == phb || - (eeh_has_flag(EEH_PROBE_MODE_DEVTREE) && 0 == phb->buid)) - return; - - eeh_ops->probe(pdn, NULL); -} - -/** - * eeh_add_device_tree_early - Enable EEH for the indicated device - * @pdn: PCI device node - * - * This routine must be used to perform EEH initialization for the - * indicated PCI device that was added after system boot (e.g. - * hotplug, dlpar). - */ -void eeh_add_device_tree_early(struct pci_dn *pdn) -{ - struct pci_dn *n; - - if (!pdn) - return; - - list_for_each_entry(n, &pdn->child_list, list) - eeh_add_device_tree_early(n); - eeh_add_device_early(pdn); -} -EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); - -/** - * eeh_add_device_late - Perform EEH initialization for the indicated pci device + * eeh_probe_device() - Perform EEH initialization for the indicated pci device * @dev: pci device for which to set up EEH * * This routine must be used to complete EEH initialization for PCI * devices that were added after system boot (e.g. hotplug, dlpar). */ -void eeh_add_device_late(struct pci_dev *dev) +void eeh_probe_device(struct pci_dev *dev) { - struct pci_dn *pdn; struct eeh_dev *edev; - if (!dev) + pr_debug("EEH: Adding device %s\n", pci_name(dev)); + + /* + * pci_dev_to_eeh_dev() can only work if eeh_probe_dev() was + * already called for this device. + */ + if (WARN_ON_ONCE(pci_dev_to_eeh_dev(dev))) { + pci_dbg(dev, "Already bound to an eeh_dev!\n"); return; + } - pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn); - edev = pdn_to_eeh_dev(pdn); - eeh_edev_dbg(edev, "Adding device\n"); - if (edev->pdev == dev) { - eeh_edev_dbg(edev, "Device already referenced!\n"); + edev = eeh_ops->probe(dev); + if (!edev) { + pr_debug("EEH: Adding device failed\n"); return; } /* - * The EEH cache might not be removed correctly because of - * unbalanced kref to the device during unplug time, which - * relies on pcibios_release_device(). So we have to remove - * that here explicitly. + * FIXME: We rely on pcibios_release_device() to remove the + * existing EEH state. The release function is only called if + * the pci_dev's refcount drops to zero so if something is + * keeping a ref to a device (e.g. a filesystem) we need to + * remove the old EEH state. + * + * FIXME: HEY MA, LOOK AT ME, NO LOCKING! */ - if (edev->pdev) { + if (edev->pdev && edev->pdev != dev) { eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(edev->pdev); eeh_sysfs_remove_device(edev->pdev); @@ -1198,69 +1154,16 @@ void eeh_add_device_late(struct pci_dev *dev) * into error handler afterwards. */ edev->mode |= EEH_DEV_NO_HANDLER; - - edev->pdev = NULL; - dev->dev.archdata.edev = NULL; } - if (eeh_has_flag(EEH_PROBE_MODE_DEV)) - eeh_ops->probe(pdn, NULL); - + /* bind the pdev and the edev together */ edev->pdev = dev; dev->dev.archdata.edev = edev; - eeh_addr_cache_insert_dev(dev); + eeh_sysfs_add_device(dev); } /** - * eeh_add_device_tree_late - Perform EEH initialization for the indicated PCI bus - * @bus: PCI bus - * - * This routine must be used to perform EEH initialization for PCI - * devices which are attached to the indicated PCI bus. The PCI bus - * is added after system boot through hotplug or dlpar. - */ -void eeh_add_device_tree_late(struct pci_bus *bus) -{ - struct pci_dev *dev; - - if (eeh_has_flag(EEH_FORCE_DISABLED)) - return; - list_for_each_entry(dev, &bus->devices, bus_list) { - eeh_add_device_late(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *subbus = dev->subordinate; - if (subbus) - eeh_add_device_tree_late(subbus); - } - } -} -EXPORT_SYMBOL_GPL(eeh_add_device_tree_late); - -/** - * eeh_add_sysfs_files - Add EEH sysfs files for the indicated PCI bus - * @bus: PCI bus - * - * This routine must be used to add EEH sysfs files for PCI - * devices which are attached to the indicated PCI bus. The PCI bus - * is added after system boot through hotplug or dlpar. - */ -void eeh_add_sysfs_files(struct pci_bus *bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - eeh_sysfs_add_device(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *subbus = dev->subordinate; - if (subbus) - eeh_add_sysfs_files(subbus); - } - } -} -EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); - -/** * eeh_remove_device - Undo EEH setup for the indicated pci device * @dev: pci device to be removed * diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 16af0d8d90a8..a6371fb8f761 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -246,9 +246,8 @@ reenable_mmu: * r3 can be different from GPR3(r1) at this point, r9 and r11 * contains the old MSR and handler address respectively, * r4 & r5 can contain page fault arguments that need to be passed - * along as well. r12, CCR, CTR, XER etc... are left clobbered as - * they aren't useful past this point (aren't syscall arguments), - * the rest is restored from the exception frame. + * along as well. r0, r6-r8, r12, CCR, CTR, XER etc... are left + * clobbered as they aren't useful past this point. */ stwu r1,-32(r1) @@ -262,16 +261,12 @@ reenable_mmu: * lockdep */ 1: bl trace_hardirqs_off -2: lwz r5,24(r1) + lwz r5,24(r1) lwz r4,20(r1) lwz r3,16(r1) lwz r11,12(r1) lwz r9,8(r1) addi r1,r1,32 - lwz r0,GPR0(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) mtctr r11 mtlr r9 bctr /* jump to handler */ @@ -575,6 +570,33 @@ syscall_exit_work: bl do_syscall_trace_leave b ret_from_except_full + /* + * System call was called from kernel. We get here with SRR1 in r9. + * Mark the exception as recoverable once we have retrieved SRR0, + * trap a warning and return ENOSYS with CR[SO] set. + */ + .globl ret_from_kernel_syscall +ret_from_kernel_syscall: + mfspr r9, SPRN_SRR0 + mfspr r10, SPRN_SRR1 +#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE) + LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR|MSR_DR)) + mtmsr r11 +#endif + +0: trap + EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING + + li r3, ENOSYS + crset so +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) + mtspr SPRN_NRI, r0 +#endif + mtspr SPRN_SRR0, r9 + mtspr SPRN_SRR1, r10 + SYNC + RFI + /* * The fork/clone functions need to copy the full register set into * the child process. Therefore we need to save all the nonvolatile diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 6ba675b0cf7d..9a1e5d636dea 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -16,6 +16,7 @@ #include <linux/errno.h> #include <linux/err.h> +#include <asm/cache.h> #include <asm/unistd.h> #include <asm/processor.h> #include <asm/page.h> @@ -51,8 +52,10 @@ SYS_CALL_TABLE: .tc sys_call_table[TC],sys_call_table +#ifdef CONFIG_COMPAT COMPAT_SYS_CALL_TABLE: .tc compat_sys_call_table[TC],compat_sys_call_table +#endif /* This value is used to mark exception frames on the stack. */ exception_marker: @@ -69,6 +72,7 @@ BEGIN_FTR_SECTION bne .Ltabort_syscall END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif +_ASM_NOKPROBE_SYMBOL(system_call_common) mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) @@ -76,342 +80,122 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1) + std r2,GPR2(r1) #ifdef CONFIG_PPC_FSL_BOOK3E START_BTB_FLUSH_SECTION BTB_FLUSH(r10) END_BTB_FLUSH_SECTION #endif - ACCOUNT_CPU_USER_ENTRY(r13, r10, r11) - std r2,GPR2(r1) + ld r2,PACATOC(r13) + mfcr r12 + li r11,0 + /* Can we avoid saving r3-r8 in common case? */ std r3,GPR3(r1) - mfcr r2 std r4,GPR4(r1) std r5,GPR5(r1) std r6,GPR6(r1) std r7,GPR7(r1) std r8,GPR8(r1) - li r11,0 + /* Zero r9-r12, this should only be required when restoring all GPRs */ std r11,GPR9(r1) std r11,GPR10(r1) std r11,GPR11(r1) std r11,GPR12(r1) + std r9,GPR13(r1) + SAVE_NVGPRS(r1) std r11,_XER(r1) std r11,_CTR(r1) - std r9,GPR13(r1) mflr r10 + /* * This clears CR0.SO (bit 28), which is the error indication on * return from this system call. */ - rldimi r2,r11,28,(63-28) - li r11,0xc01 + rldimi r12,r11,28,(63-28) + li r11,0xc00 std r10,_LINK(r1) std r11,_TRAP(r1) + std r12,_CCR(r1) std r3,ORIG_GPR3(r1) - std r2,_CCR(r1) - ld r2,PACATOC(r13) - addi r9,r1,STACK_FRAME_OVERHEAD + addi r10,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) - std r11,-16(r9) /* "regshere" marker */ - - kuap_check_amr r10, r11 - -#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR) -BEGIN_FW_FTR_SECTION - /* see if there are any DTL entries to process */ - ld r10,PACALPPACAPTR(r13) /* get ptr to VPA */ - ld r11,PACA_DTL_RIDX(r13) /* get log read index */ - addi r10,r10,LPPACA_DTLIDX - LDX_BE r10,0,r10 /* get log write index */ - cmpd r11,r10 - beq+ 33f - bl accumulate_stolen_time - REST_GPR(0,r1) - REST_4GPRS(3,r1) - REST_2GPRS(7,r1) - addi r9,r1,STACK_FRAME_OVERHEAD -33: -END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) -#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */ - - /* - * A syscall should always be called with interrupts enabled - * so we just unconditionally hard-enable here. When some kind - * of irq tracing is used, we additionally check that condition - * is correct - */ -#if defined(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && defined(CONFIG_BUG) - lbz r10,PACAIRQSOFTMASK(r13) -1: tdnei r10,IRQS_ENABLED - EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING -#endif - -#ifdef CONFIG_PPC_BOOK3E - wrteei 1 -#else - li r11,MSR_RI - ori r11,r11,MSR_EE - mtmsrd r11,1 -#endif /* CONFIG_PPC_BOOK3E */ - -system_call: /* label this so stack traces look sane */ - /* We do need to set SOFTE in the stack frame or the return - * from interrupt will be painful - */ - li r10,IRQS_ENABLED - std r10,SOFTE(r1) + std r11,-16(r10) /* "regshere" marker */ - ld r11, PACA_THREAD_INFO(r13) - ld r10,TI_FLAGS(r11) - andi. r11,r10,_TIF_SYSCALL_DOTRACE - bne .Lsyscall_dotrace /* does not return */ - cmpldi 0,r0,NR_syscalls - bge- .Lsyscall_enosys - -.Lsyscall: -/* - * Need to vector to 32 Bit or default sys_call_table here, - * based on caller's run-mode / personality. - */ - ld r11,SYS_CALL_TABLE@toc(2) - andis. r10,r10,_TIF_32BIT@h - beq 15f - ld r11,COMPAT_SYS_CALL_TABLE@toc(2) - clrldi r3,r3,32 - clrldi r4,r4,32 - clrldi r5,r5,32 - clrldi r6,r6,32 - clrldi r7,r7,32 - clrldi r8,r8,32 -15: - slwi r0,r0,3 - - barrier_nospec_asm /* - * Prevent the load of the handler below (based on the user-passed - * system call number) being speculatively executed until the test - * against NR_syscalls and branch to .Lsyscall_enosys above has - * committed. + * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which + * would clobber syscall parameters. Also we always enter with IRQs + * enabled and nothing pending. system_call_exception() will call + * trace_hardirqs_off(). */ + li r11,IRQS_ALL_DISABLED + li r12,PACA_IRQ_HARD_DIS + stb r11,PACAIRQSOFTMASK(r13) + stb r12,PACAIRQHAPPENED(r13) - ldx r12,r11,r0 /* Fetch system call handler [ptr] */ - mtctr r12 - bctrl /* Call handler */ + /* Calling convention has r9 = orig r0, r10 = regs */ + mr r9,r0 + bl system_call_exception - /* syscall_exit can exit to kernel mode, via ret_from_kernel_thread */ .Lsyscall_exit: - std r3,RESULT(r1) - -#ifdef CONFIG_DEBUG_RSEQ - /* Check whether the syscall is issued inside a restartable sequence */ - addi r3,r1,STACK_FRAME_OVERHEAD - bl rseq_syscall - ld r3,RESULT(r1) -#endif - - ld r12, PACA_THREAD_INFO(r13) - - ld r8,_MSR(r1) - -/* - * This is a few instructions into the actual syscall exit path (which actually - * starts at .Lsyscall_exit) to cater to kprobe blacklisting and to reduce the - * number of visible symbols for profiling purposes. - * - * We can probe from system_call until this point as MSR_RI is set. But once it - * is cleared below, we won't be able to take a trap. - * - * This is blacklisted from kprobes further below with _ASM_NOKPROBE_SYMBOL(). - */ -system_call_exit: - /* - * Disable interrupts so current_thread_info()->flags can't change, - * and so that we don't get interrupted after loading SRR0/1. - * - * Leave MSR_RI enabled for now, because with THREAD_INFO_IN_TASK we - * could fault on the load of the TI_FLAGS below. - */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - li r11,MSR_RI - mtmsrd r11,1 -#endif /* CONFIG_PPC_BOOK3E */ + addi r4,r1,STACK_FRAME_OVERHEAD + bl syscall_exit_prepare - ld r9,TI_FLAGS(r12) - li r11,-MAX_ERRNO - andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) - bne- .Lsyscall_exit_work + ld r2,_CCR(r1) + ld r4,_NIP(r1) + ld r5,_MSR(r1) + ld r6,_LINK(r1) - andi. r0,r8,MSR_FP - beq 2f -#ifdef CONFIG_ALTIVEC - andis. r0,r8,MSR_VEC@h - bne 3f -#endif -2: addi r3,r1,STACK_FRAME_OVERHEAD - bl restore_math - ld r8,_MSR(r1) - ld r3,RESULT(r1) - li r11,-MAX_ERRNO - -3: cmpld r3,r11 - ld r5,_CCR(r1) - bge- .Lsyscall_error -.Lsyscall_error_cont: - ld r7,_NIP(r1) BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) - andi. r6,r8,MSR_PR - ld r4,_LINK(r1) - kuap_check_amr r10, r11 + mtspr SPRN_SRR0,r4 + mtspr SPRN_SRR1,r5 + mtlr r6 -#ifdef CONFIG_PPC_BOOK3S - /* - * Clear MSR_RI, MSR_EE is already and remains disabled. We could do - * this later, but testing shows that doing it here causes less slow - * down than doing it closer to the rfid. - */ + cmpdi r3,0 + bne .Lsyscall_restore_regs + /* Zero volatile regs that may contain sensitive kernel data */ + li r0,0 + li r4,0 + li r5,0 + li r6,0 + li r7,0 + li r8,0 + li r9,0 + li r10,0 li r11,0 - mtmsrd r11,1 -#endif - - beq- 1f - ACCOUNT_CPU_USER_EXIT(r13, r11, r12) + li r12,0 + mtctr r0 + mtspr SPRN_XER,r0 +.Lsyscall_restore_regs_cont: BEGIN_FTR_SECTION HMT_MEDIUM_LOW END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - std r8, PACATMSCRATCH(r13) -#endif - /* * We don't need to restore AMR on the way back to userspace for KUAP. * The value of AMR only matters while we're in the kernel. */ - ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ + mtcr r2 ld r2,GPR2(r1) + ld r3,GPR3(r1) + ld r13,GPR13(r1) ld r1,GPR1(r1) - mtlr r4 - mtcr r5 - mtspr SPRN_SRR0,r7 - mtspr SPRN_SRR1,r8 RFI_TO_USER b . /* prevent speculative execution */ -1: /* exit to kernel */ - kuap_restore_amr r2 - - ld r2,GPR2(r1) - ld r1,GPR1(r1) - mtlr r4 - mtcr r5 - mtspr SPRN_SRR0,r7 - mtspr SPRN_SRR1,r8 - RFI_TO_KERNEL - b . /* prevent speculative execution */ - -.Lsyscall_error: - oris r5,r5,0x1000 /* Set SO bit in CR */ - neg r3,r3 - std r5,_CCR(r1) - b .Lsyscall_error_cont - -/* Traced system call support */ -.Lsyscall_dotrace: - bl save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_syscall_trace_enter - - /* - * We use the return value of do_syscall_trace_enter() as the syscall - * number. If the syscall was rejected for any reason do_syscall_trace_enter() - * returns an invalid syscall number and the test below against - * NR_syscalls will fail. - */ - mr r0,r3 - - /* Restore argument registers just clobbered and/or possibly changed. */ - ld r3,GPR3(r1) - ld r4,GPR4(r1) - ld r5,GPR5(r1) - ld r6,GPR6(r1) - ld r7,GPR7(r1) - ld r8,GPR8(r1) - - /* Repopulate r9 and r10 for the syscall path */ - addi r9,r1,STACK_FRAME_OVERHEAD - ld r10, PACA_THREAD_INFO(r13) - ld r10,TI_FLAGS(r10) - - cmpldi r0,NR_syscalls - blt+ .Lsyscall - - /* Return code is already in r3 thanks to do_syscall_trace_enter() */ - b .Lsyscall_exit - - -.Lsyscall_enosys: - li r3,-ENOSYS - b .Lsyscall_exit - -.Lsyscall_exit_work: - /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. - If TIF_NOERROR is set, just save r3 as it is. */ - - andi. r0,r9,_TIF_RESTOREALL - beq+ 0f +.Lsyscall_restore_regs: + ld r3,_CTR(r1) + ld r4,_XER(r1) REST_NVGPRS(r1) - b 2f -0: cmpld r3,r11 /* r11 is -MAX_ERRNO */ - blt+ 1f - andi. r0,r9,_TIF_NOERROR - bne- 1f - ld r5,_CCR(r1) - neg r3,r3 - oris r5,r5,0x1000 /* Set SO bit in CR */ - std r5,_CCR(r1) -1: std r3,GPR3(r1) -2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) - beq 4f - - /* Clear per-syscall TIF flags if any are set. */ - - li r11,_TIF_PERSYSCALL_MASK - addi r12,r12,TI_FLAGS -3: ldarx r10,0,r12 - andc r10,r10,r11 - stdcx. r10,0,r12 - bne- 3b - subi r12,r12,TI_FLAGS - -4: /* Anything else left to do? */ -BEGIN_FTR_SECTION - lis r3,DEFAULT_PPR@highest /* Set default PPR */ - sldi r3,r3,32 /* bits 11-13 are used for ppr */ - std r3,_PPR(r1) -END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) - - andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP) - beq ret_from_except_lite - - /* Re-enable interrupts */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 1 -#else - li r10,MSR_RI - ori r10,r10,MSR_EE - mtmsrd r10,1 -#endif /* CONFIG_PPC_BOOK3E */ - - bl save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_syscall_trace_leave - b ret_from_except + mtctr r3 + mtspr SPRN_XER,r4 + ld r0,GPR0(r1) + REST_8GPRS(4, r1) + ld r12,GPR12(r1) + b .Lsyscall_restore_regs_cont #ifdef CONFIG_PPC_TRANSACTIONAL_MEM .Ltabort_syscall: @@ -439,64 +223,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) RFI_TO_USER b . /* prevent speculative execution */ #endif -_ASM_NOKPROBE_SYMBOL(system_call_common); -_ASM_NOKPROBE_SYMBOL(system_call_exit); - -/* Save non-volatile GPRs, if not already saved. */ -_GLOBAL(save_nvgprs) - ld r11,_TRAP(r1) - andi. r0,r11,1 - beqlr- - SAVE_NVGPRS(r1) - clrrdi r0,r11,1 - std r0,_TRAP(r1) - blr -_ASM_NOKPROBE_SYMBOL(save_nvgprs); - - -/* - * The sigsuspend and rt_sigsuspend system calls can call do_signal - * and thus put the process into the stopped state where we might - * want to examine its user state with ptrace. Therefore we need - * to save all the nonvolatile registers (r14 - r31) before calling - * the C code. Similarly, fork, vfork and clone need the full - * register state on the stack so that it can be copied to the child. - */ - -_GLOBAL(ppc_fork) - bl save_nvgprs - bl sys_fork - b .Lsyscall_exit - -_GLOBAL(ppc_vfork) - bl save_nvgprs - bl sys_vfork - b .Lsyscall_exit - -_GLOBAL(ppc_clone) - bl save_nvgprs - bl sys_clone - b .Lsyscall_exit - -_GLOBAL(ppc_clone3) - bl save_nvgprs - bl sys_clone3 - b .Lsyscall_exit - -_GLOBAL(ppc32_swapcontext) - bl save_nvgprs - bl compat_sys_swapcontext - b .Lsyscall_exit - -_GLOBAL(ppc64_swapcontext) - bl save_nvgprs - bl sys_swapcontext - b .Lsyscall_exit - -_GLOBAL(ppc_switch_endian) - bl save_nvgprs - bl sys_switch_endian - b .Lsyscall_exit _GLOBAL(ret_from_fork) bl schedule_tail @@ -516,6 +242,19 @@ _GLOBAL(ret_from_kernel_thread) li r3,0 b .Lsyscall_exit +#ifdef CONFIG_PPC_BOOK3E +/* Save non-volatile GPRs, if not already saved. */ +_GLOBAL(save_nvgprs) + ld r11,_TRAP(r1) + andi. r0,r11,1 + beqlr- + SAVE_NVGPRS(r1) + clrrdi r0,r11,1 + std r0,_TRAP(r1) + blr +_ASM_NOKPROBE_SYMBOL(save_nvgprs); +#endif + #ifdef CONFIG_PPC_BOOK3S_64 #define FLUSH_COUNT_CACHE \ @@ -578,7 +317,7 @@ flush_count_cache: * state of one is saved on its kernel stack. Then the state * of the other is restored from its kernel stack. The memory * management hardware is updated to the second process's state. - * Finally, we can return to the second process, via ret_from_except. + * Finally, we can return to the second process, via interrupt_return. * On entry, r3 points to the THREAD for the current task, r4 * points to the THREAD for the new task. * @@ -730,408 +469,146 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) addi r1,r1,SWITCH_FRAME_SIZE blr - .align 7 -_GLOBAL(ret_from_except) - ld r11,_TRAP(r1) - andi. r0,r11,1 - bne ret_from_except_lite - REST_NVGPRS(r1) - -_GLOBAL(ret_from_except_lite) - /* - * Disable interrupts so that current_thread_info()->flags - * can't change between when we test it and when we return - * from the interrupt. - */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - li r10,MSR_RI - mtmsrd r10,1 /* Update machine state */ -#endif /* CONFIG_PPC_BOOK3E */ - - ld r9, PACA_THREAD_INFO(r13) - ld r3,_MSR(r1) -#ifdef CONFIG_PPC_BOOK3E - ld r10,PACACURRENT(r13) -#endif /* CONFIG_PPC_BOOK3E */ - ld r4,TI_FLAGS(r9) - andi. r3,r3,MSR_PR - beq resume_kernel -#ifdef CONFIG_PPC_BOOK3E - lwz r3,(THREAD+THREAD_DBCR0)(r10) -#endif /* CONFIG_PPC_BOOK3E */ - - /* Check current_thread_info()->flags */ - andi. r0,r4,_TIF_USER_WORK_MASK - bne 1f -#ifdef CONFIG_PPC_BOOK3E +#ifdef CONFIG_PPC_BOOK3S /* - * Check to see if the dbcr0 register is set up to debug. - * Use the internal debug mode bit to do this. - */ - andis. r0,r3,DBCR0_IDM@h - beq restore - mfmsr r0 - rlwinm r0,r0,0,~MSR_DE /* Clear MSR.DE */ - mtmsr r0 - mtspr SPRN_DBCR0,r3 - li r10, -1 - mtspr SPRN_DBSR,r10 - b restore -#else - addi r3,r1,STACK_FRAME_OVERHEAD - bl restore_math - b restore -#endif -1: andi. r0,r4,_TIF_NEED_RESCHED - beq 2f - bl restore_interrupts - SCHEDULE_USER - b ret_from_except_lite -2: -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - andi. r0,r4,_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM - bne 3f /* only restore TM if nothing else to do */ + * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not + * touched, AMR not set, no exit work created, then this can be used. + */ + .balign IFETCH_ALIGN_BYTES + .globl fast_interrupt_return +fast_interrupt_return: +_ASM_NOKPROBE_SYMBOL(fast_interrupt_return) + ld r4,_MSR(r1) + andi. r0,r4,MSR_PR + bne .Lfast_user_interrupt_return + andi. r0,r4,MSR_RI + li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ + bne+ .Lfast_kernel_interrupt_return addi r3,r1,STACK_FRAME_OVERHEAD - bl restore_tm_state - b restore -3: -#endif - bl save_nvgprs - /* - * Use a non volatile GPR to save and restore our thread_info flags - * across the call to restore_interrupts. - */ - mr r30,r4 - bl restore_interrupts - mr r4,r30 + bl unrecoverable_exception + b . /* should not get here */ + + .balign IFETCH_ALIGN_BYTES + .globl interrupt_return +interrupt_return: +_ASM_NOKPROBE_SYMBOL(interrupt_return) + ld r4,_MSR(r1) + andi. r0,r4,MSR_PR + beq .Lkernel_interrupt_return addi r3,r1,STACK_FRAME_OVERHEAD - bl do_notify_resume - b ret_from_except + bl interrupt_exit_user_prepare + cmpdi r3,0 + bne- .Lrestore_nvgprs -resume_kernel: - /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ - andis. r8,r4,_TIF_EMULATE_STACK_STORE@h - beq+ 1f - - addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ +.Lfast_user_interrupt_return: + ld r11,_NIP(r1) + ld r12,_MSR(r1) +BEGIN_FTR_SECTION + ld r10,_PPR(r1) + mtspr SPRN_PPR,r10 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 - ld r3,GPR1(r1) - subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ - mr r4,r1 /* src: current exception frame */ - mr r1,r3 /* Reroute the trampoline frame to r1 */ +BEGIN_FTR_SECTION + stdcx. r0,0,r1 /* to clear the reservation */ +FTR_SECTION_ELSE + ldarx r0,0,r1 +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) - /* Copy from the original to the trampoline. */ - li r5,INT_FRAME_SIZE/8 /* size: INT_FRAME_SIZE */ - li r6,0 /* start offset: 0 */ - mtctr r5 -2: ldx r0,r6,r4 - stdx r0,r6,r3 - addi r6,r6,8 - bdnz 2b - - /* Do real store operation to complete stdu */ - ld r5,GPR1(r1) - std r8,0(r5) - - /* Clear _TIF_EMULATE_STACK_STORE flag */ - lis r11,_TIF_EMULATE_STACK_STORE@h - addi r5,r9,TI_FLAGS -0: ldarx r4,0,r5 - andc r4,r4,r11 - stdcx. r4,0,r5 - bne- 0b -1: - -#ifdef CONFIG_PREEMPTION - /* Check if we need to preempt */ - andi. r0,r4,_TIF_NEED_RESCHED - beq+ restore - /* Check that preempt_count() == 0 and interrupts are enabled */ - lwz r8,TI_PREEMPT(r9) - cmpwi cr0,r8,0 - bne restore - ld r0,SOFTE(r1) - andi. r0,r0,IRQS_DISABLED - bne restore + ld r3,_CCR(r1) + ld r4,_LINK(r1) + ld r5,_CTR(r1) + ld r6,_XER(r1) + li r0,0 - /* - * Here we are preempting the current task. We want to make - * sure we are soft-disabled first and reconcile irq state. - */ - RECONCILE_IRQ_STATE(r3,r4) - bl preempt_schedule_irq + REST_4GPRS(7, r1) + REST_2GPRS(11, r1) + REST_GPR(13, r1) - /* - * arch_local_irq_restore() from preempt_schedule_irq above may - * enable hard interrupt but we really should disable interrupts - * when we return from the interrupt, and so that we don't get - * interrupted after loading SRR0/1. - */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - li r10,MSR_RI - mtmsrd r10,1 /* Update machine state */ -#endif /* CONFIG_PPC_BOOK3E */ -#endif /* CONFIG_PREEMPTION */ + mtcr r3 + mtlr r4 + mtctr r5 + mtspr SPRN_XER,r6 - .globl fast_exc_return_irq -fast_exc_return_irq: -restore: - /* - * This is the main kernel exit path. First we check if we - * are about to re-enable interrupts - */ - ld r5,SOFTE(r1) - lbz r6,PACAIRQSOFTMASK(r13) - andi. r5,r5,IRQS_DISABLED - bne .Lrestore_irq_off + REST_4GPRS(2, r1) + REST_GPR(6, r1) + REST_GPR(0, r1) + REST_GPR(1, r1) + RFI_TO_USER + b . /* prevent speculative execution */ - /* We are enabling, were we already enabled ? Yes, just return */ - andi. r6,r6,IRQS_DISABLED - beq cr0,.Ldo_restore +.Lrestore_nvgprs: + REST_NVGPRS(r1) + b .Lfast_user_interrupt_return - /* - * We are about to soft-enable interrupts (we are hard disabled - * at this point). We check if there's anything that needs to - * be replayed first. - */ - lbz r0,PACAIRQHAPPENED(r13) - cmpwi cr0,r0,0 - bne- .Lrestore_check_irq_replay + .balign IFETCH_ALIGN_BYTES +.Lkernel_interrupt_return: + addi r3,r1,STACK_FRAME_OVERHEAD + bl interrupt_exit_kernel_prepare - /* - * Get here when nothing happened while soft-disabled, just - * soft-enable and move-on. We will hard-enable as a side - * effect of rfi - */ -.Lrestore_no_replay: - TRACE_ENABLE_INTS - li r0,IRQS_ENABLED - stb r0,PACAIRQSOFTMASK(r13); +.Lfast_kernel_interrupt_return: + cmpdi cr1,r3,0 + ld r11,_NIP(r1) + ld r12,_MSR(r1) + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 - /* - * Final return path. BookE is handled in a different file - */ -.Ldo_restore: -#ifdef CONFIG_PPC_BOOK3E - b exception_return_book3e -#else - /* - * Clear the reservation. If we know the CPU tracks the address of - * the reservation then we can potentially save some cycles and use - * a larx. On POWER6 and POWER7 this is significantly faster. - */ BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */ FTR_SECTION_ELSE - ldarx r4,0,r1 + ldarx r0,0,r1 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) - /* - * Some code path such as load_up_fpu or altivec return directly - * here. They run entirely hard disabled and do not alter the - * interrupt state. They also don't use lwarx/stwcx. and thus - * are known not to leave dangling reservations. - */ - .globl fast_exception_return -fast_exception_return: - ld r3,_MSR(r1) + ld r3,_LINK(r1) ld r4,_CTR(r1) - ld r0,_LINK(r1) - mtctr r4 - mtlr r0 - ld r4,_XER(r1) - mtspr SPRN_XER,r4 - - kuap_check_amr r5, r6 - - REST_8GPRS(5, r1) - - andi. r0,r3,MSR_RI - beq- .Lunrecov_restore - - /* - * Clear RI before restoring r13. If we are returning to - * userspace and we take an exception after restoring r13, - * we end up corrupting the userspace r13 value. - */ - li r4,0 - mtmsrd r4,1 - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - /* TM debug */ - std r3, PACATMSCRATCH(r13) /* Stash returned-to MSR */ -#endif - /* - * r13 is our per cpu area, only restore it if we are returning to - * userspace the value stored in the stack frame may belong to - * another CPU. - */ - andi. r0,r3,MSR_PR - beq 1f -BEGIN_FTR_SECTION - /* Restore PPR */ - ld r2,_PPR(r1) - mtspr SPRN_PPR,r2 -END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) - ACCOUNT_CPU_USER_EXIT(r13, r2, r4) - REST_GPR(13, r1) - - /* - * We don't need to restore AMR on the way back to userspace for KUAP. - * The value of AMR only matters while we're in the kernel. - */ - mtspr SPRN_SRR1,r3 - - ld r2,_CCR(r1) - mtcrf 0xFF,r2 - ld r2,_NIP(r1) - mtspr SPRN_SRR0,r2 - - ld r0,GPR0(r1) - ld r2,GPR2(r1) - ld r3,GPR3(r1) - ld r4,GPR4(r1) - ld r1,GPR1(r1) - RFI_TO_USER - b . /* prevent speculative execution */ + ld r5,_XER(r1) + ld r6,_CCR(r1) + li r0,0 -1: mtspr SPRN_SRR1,r3 + REST_4GPRS(7, r1) + REST_2GPRS(11, r1) - ld r2,_CCR(r1) - mtcrf 0xFF,r2 - ld r2,_NIP(r1) - mtspr SPRN_SRR0,r2 + mtlr r3 + mtctr r4 + mtspr SPRN_XER,r5 /* * Leaving a stale exception_marker on the stack can confuse * the reliable stack unwinder later on. Clear it. */ - li r2,0 - std r2,STACK_FRAME_OVERHEAD-16(r1) - - ld r0,GPR0(r1) - ld r2,GPR2(r1) - ld r3,GPR3(r1) + std r0,STACK_FRAME_OVERHEAD-16(r1) - kuap_restore_amr r4 + REST_4GPRS(2, r1) - ld r4,GPR4(r1) - ld r1,GPR1(r1) + bne- cr1,1f /* emulate stack store */ + mtcr r6 + REST_GPR(6, r1) + REST_GPR(0, r1) + REST_GPR(1, r1) RFI_TO_KERNEL b . /* prevent speculative execution */ -#endif /* CONFIG_PPC_BOOK3E */ - - /* - * We are returning to a context with interrupts soft disabled. - * - * However, we may also about to hard enable, so we need to - * make sure that in this case, we also clear PACA_IRQ_HARD_DIS - * or that bit can get out of sync and bad things will happen - */ -.Lrestore_irq_off: - ld r3,_MSR(r1) - lbz r7,PACAIRQHAPPENED(r13) - andi. r0,r3,MSR_EE - beq 1f - rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS - stb r7,PACAIRQHAPPENED(r13) -1: -#if defined(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && defined(CONFIG_BUG) - /* The interrupt should not have soft enabled. */ - lbz r7,PACAIRQSOFTMASK(r13) -1: tdeqi r7,IRQS_ENABLED - EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING -#endif - b .Ldo_restore - - /* - * Something did happen, check if a re-emit is needed - * (this also clears paca->irq_happened) - */ -.Lrestore_check_irq_replay: - /* XXX: We could implement a fast path here where we check - * for irq_happened being just 0x01, in which case we can - * clear it and return. That means that we would potentially - * miss a decrementer having wrapped all the way around. - * - * Still, this might be useful for things like hash_page - */ - bl __check_irq_replay - cmpwi cr0,r3,0 - beq .Lrestore_no_replay - - /* - * We need to re-emit an interrupt. We do so by re-using our - * existing exception frame. We first change the trap value, - * but we need to ensure we preserve the low nibble of it - */ - ld r4,_TRAP(r1) - clrldi r4,r4,60 - or r4,r4,r3 - std r4,_TRAP(r1) - - /* - * PACA_IRQ_HARD_DIS won't always be set here, so set it now - * to reconcile the IRQ state. Tracing is already accounted for. - */ - lbz r4,PACAIRQHAPPENED(r13) - ori r4,r4,PACA_IRQ_HARD_DIS - stb r4,PACAIRQHAPPENED(r13) - - /* - * Then find the right handler and call it. Interrupts are - * still soft-disabled and we keep them that way. - */ - cmpwi cr0,r3,0x500 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl do_IRQ - b ret_from_except -1: cmpwi cr0,r3,0xf00 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl performance_monitor_exception - b ret_from_except -1: cmpwi cr0,r3,0xe60 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl handle_hmi_exception - b ret_from_except -1: cmpwi cr0,r3,0x900 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl timer_interrupt - b ret_from_except -#ifdef CONFIG_PPC_DOORBELL -1: -#ifdef CONFIG_PPC_BOOK3E - cmpwi cr0,r3,0x280 -#else - cmpwi cr0,r3,0xa00 -#endif /* CONFIG_PPC_BOOK3E */ - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl doorbell_exception -#endif /* CONFIG_PPC_DOORBELL */ -1: b ret_from_except /* What else to do here ? */ - -.Lunrecov_restore: - addi r3,r1,STACK_FRAME_OVERHEAD - bl unrecoverable_exception - b .Lunrecov_restore - -_ASM_NOKPROBE_SYMBOL(ret_from_except); -_ASM_NOKPROBE_SYMBOL(ret_from_except_lite); -_ASM_NOKPROBE_SYMBOL(resume_kernel); -_ASM_NOKPROBE_SYMBOL(fast_exc_return_irq); -_ASM_NOKPROBE_SYMBOL(restore); -_ASM_NOKPROBE_SYMBOL(fast_exception_return); +1: /* + * Emulate stack store with update. New r1 value was already calculated + * and updated in our interrupt regs by emulate_loadstore, but we can't + * store the previous value of r1 to the stack before re-loading our + * registers from it, otherwise they could be clobbered. Use + * PACA_EXGEN as temporary storage to hold the store data, as + * interrupts are disabled here so it won't be clobbered. + */ + mtcr r6 + std r9,PACA_EXGEN+0(r13) + addi r9,r1,INT_FRAME_SIZE /* get original r1 */ + REST_GPR(6, r1) + REST_GPR(0, r1) + REST_GPR(1, r1) + std r9,0(r1) /* perform store component of stdu */ + ld r9,PACA_EXGEN+0(r13) + RFI_TO_KERNEL + b . /* prevent speculative execution */ +#endif /* CONFIG_PPC_BOOK3S */ #ifdef CONFIG_PPC_RTAS /* diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index e4076e3c072d..d9ed79415100 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -24,6 +24,7 @@ #include <asm/kvm_asm.h> #include <asm/kvm_booke_hv_asm.h> #include <asm/feature-fixups.h> +#include <asm/context_tracking.h> /* XXX This will ultimately add space for a special exception save * structure used to save things like SRR0/SRR1, SPRGs, MAS, etc... @@ -1003,38 +1004,6 @@ masked_interrupt_book3e_0x2c0: masked_interrupt_book3e PACA_IRQ_DBELL 0 /* - * Called from arch_local_irq_enable when an interrupt needs - * to be resent. r3 contains either 0x500,0x900,0x260 or 0x280 - * to indicate the kind of interrupt. MSR:EE is already off. - * We generate a stackframe like if a real interrupt had happened. - * - * Note: While MSR:EE is off, we need to make sure that _MSR - * in the generated frame has EE set to 1 or the exception - * handler will not properly re-enable them. - */ -_GLOBAL(__replay_interrupt) - /* We are going to jump to the exception common code which - * will retrieve various register values from the PACA which - * we don't give a damn about. - */ - mflr r10 - mfmsr r11 - mfcr r4 - mtspr SPRN_SPRG_GEN_SCRATCH,r13; - std r1,PACA_EXGEN+EX_R1(r13); - stw r4,PACA_EXGEN+EX_CR(r13); - ori r11,r11,MSR_EE - subi r1,r1,INT_FRAME_SIZE; - cmpwi cr0,r3,0x500 - beq exc_0x500_common - cmpwi cr0,r3,0x900 - beq exc_0x900_common - cmpwi cr0,r3,0x280 - beq exc_0x280_common - blr - - -/* * This is called from 0x300 and 0x400 handlers after the prologs with * r14 and r15 containing the fault address and error code, with the * original values stashed away in the PACA @@ -1073,17 +1042,161 @@ alignment_more: bl alignment_exception b ret_from_except -/* - * We branch here from entry_64.S for the last stage of the exception - * return code path. MSR:EE is expected to be off at that point - */ -_GLOBAL(exception_return_book3e) - b 1f + .align 7 +_GLOBAL(ret_from_except) + ld r11,_TRAP(r1) + andi. r0,r11,1 + bne ret_from_except_lite + REST_NVGPRS(r1) + +_GLOBAL(ret_from_except_lite) + /* + * Disable interrupts so that current_thread_info()->flags + * can't change between when we test it and when we return + * from the interrupt. + */ + wrteei 0 + + ld r9, PACA_THREAD_INFO(r13) + ld r3,_MSR(r1) + ld r10,PACACURRENT(r13) + ld r4,TI_FLAGS(r9) + andi. r3,r3,MSR_PR + beq resume_kernel + lwz r3,(THREAD+THREAD_DBCR0)(r10) + + /* Check current_thread_info()->flags */ + andi. r0,r4,_TIF_USER_WORK_MASK + bne 1f + /* + * Check to see if the dbcr0 register is set up to debug. + * Use the internal debug mode bit to do this. + */ + andis. r0,r3,DBCR0_IDM@h + beq restore + mfmsr r0 + rlwinm r0,r0,0,~MSR_DE /* Clear MSR.DE */ + mtmsr r0 + mtspr SPRN_DBCR0,r3 + li r10, -1 + mtspr SPRN_DBSR,r10 + b restore +1: andi. r0,r4,_TIF_NEED_RESCHED + beq 2f + bl restore_interrupts + SCHEDULE_USER + b ret_from_except_lite +2: + bl save_nvgprs + /* + * Use a non volatile GPR to save and restore our thread_info flags + * across the call to restore_interrupts. + */ + mr r30,r4 + bl restore_interrupts + mr r4,r30 + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_notify_resume + b ret_from_except + +resume_kernel: + /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ + andis. r8,r4,_TIF_EMULATE_STACK_STORE@h + beq+ 1f + + addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ + + ld r3,GPR1(r1) + subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ + mr r4,r1 /* src: current exception frame */ + mr r1,r3 /* Reroute the trampoline frame to r1 */ + + /* Copy from the original to the trampoline. */ + li r5,INT_FRAME_SIZE/8 /* size: INT_FRAME_SIZE */ + li r6,0 /* start offset: 0 */ + mtctr r5 +2: ldx r0,r6,r4 + stdx r0,r6,r3 + addi r6,r6,8 + bdnz 2b + + /* Do real store operation to complete stdu */ + ld r5,GPR1(r1) + std r8,0(r5) + + /* Clear _TIF_EMULATE_STACK_STORE flag */ + lis r11,_TIF_EMULATE_STACK_STORE@h + addi r5,r9,TI_FLAGS +0: ldarx r4,0,r5 + andc r4,r4,r11 + stdcx. r4,0,r5 + bne- 0b +1: + +#ifdef CONFIG_PREEMPT + /* Check if we need to preempt */ + andi. r0,r4,_TIF_NEED_RESCHED + beq+ restore + /* Check that preempt_count() == 0 and interrupts are enabled */ + lwz r8,TI_PREEMPT(r9) + cmpwi cr0,r8,0 + bne restore + ld r0,SOFTE(r1) + andi. r0,r0,IRQS_DISABLED + bne restore + + /* + * Here we are preempting the current task. We want to make + * sure we are soft-disabled first and reconcile irq state. + */ + RECONCILE_IRQ_STATE(r3,r4) + bl preempt_schedule_irq + + /* + * arch_local_irq_restore() from preempt_schedule_irq above may + * enable hard interrupt but we really should disable interrupts + * when we return from the interrupt, and so that we don't get + * interrupted after loading SRR0/1. + */ + wrteei 0 +#endif /* CONFIG_PREEMPT */ + +restore: + /* + * This is the main kernel exit path. First we check if we + * are about to re-enable interrupts + */ + ld r5,SOFTE(r1) + lbz r6,PACAIRQSOFTMASK(r13) + andi. r5,r5,IRQS_DISABLED + bne .Lrestore_irq_off + + /* We are enabling, were we already enabled ? Yes, just return */ + andi. r6,r6,IRQS_DISABLED + beq cr0,fast_exception_return + + /* + * We are about to soft-enable interrupts (we are hard disabled + * at this point). We check if there's anything that needs to + * be replayed first. + */ + lbz r0,PACAIRQHAPPENED(r13) + cmpwi cr0,r0,0 + bne- .Lrestore_check_irq_replay + + /* + * Get here when nothing happened while soft-disabled, just + * soft-enable and move-on. We will hard-enable as a side + * effect of rfi + */ +.Lrestore_no_replay: + TRACE_ENABLE_INTS + li r0,IRQS_ENABLED + stb r0,PACAIRQSOFTMASK(r13); /* This is the return from load_up_fpu fast path which could do with * less GPR restores in fact, but for now we have a single return path */ - .globl fast_exception_return fast_exception_return: wrteei 0 1: mr r0,r13 @@ -1124,6 +1237,102 @@ fast_exception_return: mfspr r13,SPRN_SPRG_GEN_SCRATCH rfi + /* + * We are returning to a context with interrupts soft disabled. + * + * However, we may also about to hard enable, so we need to + * make sure that in this case, we also clear PACA_IRQ_HARD_DIS + * or that bit can get out of sync and bad things will happen + */ +.Lrestore_irq_off: + ld r3,_MSR(r1) + lbz r7,PACAIRQHAPPENED(r13) + andi. r0,r3,MSR_EE + beq 1f + rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS + stb r7,PACAIRQHAPPENED(r13) +1: +#if defined(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && defined(CONFIG_BUG) + /* The interrupt should not have soft enabled. */ + lbz r7,PACAIRQSOFTMASK(r13) +1: tdeqi r7,IRQS_ENABLED + EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING +#endif + b fast_exception_return + + /* + * Something did happen, check if a re-emit is needed + * (this also clears paca->irq_happened) + */ +.Lrestore_check_irq_replay: + /* XXX: We could implement a fast path here where we check + * for irq_happened being just 0x01, in which case we can + * clear it and return. That means that we would potentially + * miss a decrementer having wrapped all the way around. + * + * Still, this might be useful for things like hash_page + */ + bl __check_irq_replay + cmpwi cr0,r3,0 + beq .Lrestore_no_replay + + /* + * We need to re-emit an interrupt. We do so by re-using our + * existing exception frame. We first change the trap value, + * but we need to ensure we preserve the low nibble of it + */ + ld r4,_TRAP(r1) + clrldi r4,r4,60 + or r4,r4,r3 + std r4,_TRAP(r1) + + /* + * PACA_IRQ_HARD_DIS won't always be set here, so set it now + * to reconcile the IRQ state. Tracing is already accounted for. + */ + lbz r4,PACAIRQHAPPENED(r13) + ori r4,r4,PACA_IRQ_HARD_DIS + stb r4,PACAIRQHAPPENED(r13) + + /* + * Then find the right handler and call it. Interrupts are + * still soft-disabled and we keep them that way. + */ + cmpwi cr0,r3,0x500 + bne 1f + addi r3,r1,STACK_FRAME_OVERHEAD; + bl do_IRQ + b ret_from_except +1: cmpwi cr0,r3,0xf00 + bne 1f + addi r3,r1,STACK_FRAME_OVERHEAD; + bl performance_monitor_exception + b ret_from_except +1: cmpwi cr0,r3,0xe60 + bne 1f + addi r3,r1,STACK_FRAME_OVERHEAD; + bl handle_hmi_exception + b ret_from_except +1: cmpwi cr0,r3,0x900 + bne 1f + addi r3,r1,STACK_FRAME_OVERHEAD; + bl timer_interrupt + b ret_from_except +#ifdef CONFIG_PPC_DOORBELL +1: + cmpwi cr0,r3,0x280 + bne 1f + addi r3,r1,STACK_FRAME_OVERHEAD; + bl doorbell_exception +#endif /* CONFIG_PPC_DOORBELL */ +1: b ret_from_except /* What else to do here ? */ + +_ASM_NOKPROBE_SYMBOL(ret_from_except); +_ASM_NOKPROBE_SYMBOL(ret_from_except_lite); +_ASM_NOKPROBE_SYMBOL(resume_kernel); +_ASM_NOKPROBE_SYMBOL(restore); +_ASM_NOKPROBE_SYMBOL(fast_exception_return); + /* * Trampolines used when spotting a bad kernel stack pointer in * the exception entry code. diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index ffc15f4f079d..728ccb0f560c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -32,16 +32,10 @@ #define EX_CCR 52 #define EX_CFAR 56 #define EX_PPR 64 -#if defined(CONFIG_RELOCATABLE) #define EX_CTR 72 .if EX_SIZE != 10 .error "EX_SIZE is wrong" .endif -#else -.if EX_SIZE != 9 - .error "EX_SIZE is wrong" -.endif -#endif /* * Following are fixed section helper macros. @@ -50,7 +44,6 @@ * EXC_VIRT_BEGIN/END - virt (AIL), unrelocated exception vectors * TRAMP_REAL_BEGIN - real, unrelocated helpers (virt may call these) * TRAMP_VIRT_BEGIN - virt, unreloc helpers (in practice, real can use) - * TRAMP_KVM_BEGIN - KVM handlers, these are put into real, unrelocated * EXC_COMMON - After switching to virtual, relocated mode. */ @@ -80,13 +73,6 @@ name: #define TRAMP_VIRT_BEGIN(name) \ FIXED_SECTION_ENTRY_BEGIN(virt_trampolines, name) -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER -#define TRAMP_KVM_BEGIN(name) \ - TRAMP_VIRT_BEGIN(name) -#else -#define TRAMP_KVM_BEGIN(name) -#endif - #define EXC_REAL_NONE(start, size) \ FIXED_SECTION_ENTRY_BEGIN_LOCATION(real_vectors, exc_real_##start##_##unused, start, size); \ FIXED_SECTION_ENTRY_END_LOCATION(real_vectors, exc_real_##start##_##unused, start, size) @@ -119,67 +105,6 @@ name: ori reg,reg,(ABS_ADDR(label))@l; \ addis reg,reg,(ABS_ADDR(label))@h -/* Exception register prefixes */ -#define EXC_HV_OR_STD 2 /* depends on HVMODE */ -#define EXC_HV 1 -#define EXC_STD 0 - -#if defined(CONFIG_RELOCATABLE) -/* - * If we support interrupts with relocation on AND we're a relocatable kernel, - * we need to use CTR to get to the 2nd level handler. So, save/restore it - * when required. - */ -#define SAVE_CTR(reg, area) mfctr reg ; std reg,area+EX_CTR(r13) -#define GET_CTR(reg, area) ld reg,area+EX_CTR(r13) -#define RESTORE_CTR(reg, area) ld reg,area+EX_CTR(r13) ; mtctr reg -#else -/* ...else CTR is unused and in register. */ -#define SAVE_CTR(reg, area) -#define GET_CTR(reg, area) mfctr reg -#define RESTORE_CTR(reg, area) -#endif - -/* - * PPR save/restore macros used in exceptions-64s.S - * Used for P7 or later processors - */ -#define SAVE_PPR(area, ra) \ -BEGIN_FTR_SECTION_NESTED(940) \ - ld ra,area+EX_PPR(r13); /* Read PPR from paca */ \ - std ra,_PPR(r1); \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940) - -#define RESTORE_PPR_PACA(area, ra) \ -BEGIN_FTR_SECTION_NESTED(941) \ - ld ra,area+EX_PPR(r13); \ - mtspr SPRN_PPR,ra; \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941) - -/* - * Get an SPR into a register if the CPU has the given feature - */ -#define OPT_GET_SPR(ra, spr, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - mfspr ra,spr; \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - -/* - * Set an SPR from a register if the CPU has the given feature - */ -#define OPT_SET_SPR(ra, spr, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - mtspr spr,ra; \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - -/* - * Save a register to the PACA if the CPU has the given feature - */ -#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - std ra,offset(r13); \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - /* * Branch to label using its 0xC000 address. This results in instruction * address suitable for MSR[IR]=0 or 1, which allows relocation to be turned @@ -193,89 +118,199 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtctr reg; \ bctr -.macro INT_KVM_HANDLER name, vec, hsrr, area, skip - TRAMP_KVM_BEGIN(\name\()_kvm) - KVM_HANDLER \vec, \hsrr, \area, \skip +/* + * Interrupt code generation macros + */ +#define IVEC .L_IVEC_\name\() /* Interrupt vector address */ +#define IHSRR .L_IHSRR_\name\() /* Sets SRR or HSRR registers */ +#define IHSRR_IF_HVMODE .L_IHSRR_IF_HVMODE_\name\() /* HSRR if HV else SRR */ +#define IAREA .L_IAREA_\name\() /* PACA save area */ +#define IVIRT .L_IVIRT_\name\() /* Has virt mode entry point */ +#define IISIDE .L_IISIDE_\name\() /* Uses SRR0/1 not DAR/DSISR */ +#define IDAR .L_IDAR_\name\() /* Uses DAR (or SRR0) */ +#define IDSISR .L_IDSISR_\name\() /* Uses DSISR (or SRR1) */ +#define ISET_RI .L_ISET_RI_\name\() /* Run common code w/ MSR[RI]=1 */ +#define IBRANCH_TO_COMMON .L_IBRANCH_TO_COMMON_\name\() /* ENTRY branch to common */ +#define IREALMODE_COMMON .L_IREALMODE_COMMON_\name\() /* Common runs in realmode */ +#define IMASK .L_IMASK_\name\() /* IRQ soft-mask bit */ +#define IKVM_SKIP .L_IKVM_SKIP_\name\() /* Generate KVM skip handler */ +#define IKVM_REAL .L_IKVM_REAL_\name\() /* Real entry tests KVM */ +#define __IKVM_REAL(name) .L_IKVM_REAL_ ## name +#define IKVM_VIRT .L_IKVM_VIRT_\name\() /* Virt entry tests KVM */ +#define ISTACK .L_ISTACK_\name\() /* Set regular kernel stack */ +#define __ISTACK(name) .L_ISTACK_ ## name +#define IRECONCILE .L_IRECONCILE_\name\() /* Do RECONCILE_IRQ_STATE */ +#define IKUAP .L_IKUAP_\name\() /* Do KUAP lock */ + +#define INT_DEFINE_BEGIN(n) \ +.macro int_define_ ## n name + +#define INT_DEFINE_END(n) \ +.endm ; \ +int_define_ ## n n ; \ +do_define_int n + +.macro do_define_int name + .ifndef IVEC + .error "IVEC not defined" + .endif + .ifndef IHSRR + IHSRR=0 + .endif + .ifndef IHSRR_IF_HVMODE + IHSRR_IF_HVMODE=0 + .endif + .ifndef IAREA + IAREA=PACA_EXGEN + .endif + .ifndef IVIRT + IVIRT=1 + .endif + .ifndef IISIDE + IISIDE=0 + .endif + .ifndef IDAR + IDAR=0 + .endif + .ifndef IDSISR + IDSISR=0 + .endif + .ifndef ISET_RI + ISET_RI=1 + .endif + .ifndef IBRANCH_TO_COMMON + IBRANCH_TO_COMMON=1 + .endif + .ifndef IREALMODE_COMMON + IREALMODE_COMMON=0 + .else + .if ! IBRANCH_TO_COMMON + .error "IREALMODE_COMMON=1 but IBRANCH_TO_COMMON=0" + .endif + .endif + .ifndef IMASK + IMASK=0 + .endif + .ifndef IKVM_SKIP + IKVM_SKIP=0 + .endif + .ifndef IKVM_REAL + IKVM_REAL=0 + .endif + .ifndef IKVM_VIRT + IKVM_VIRT=0 + .endif + .ifndef ISTACK + ISTACK=1 + .endif + .ifndef IRECONCILE + IRECONCILE=1 + .endif + .ifndef IKUAP + IKUAP=1 + .endif .endm #ifdef CONFIG_KVM_BOOK3S_64_HANDLER #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* - * If hv is possible, interrupts come into to the hv version - * of the kvmppc_interrupt code, which then jumps to the PR handler, - * kvmppc_interrupt_pr, if the guest is a PR guest. + * All interrupts which set HSRR registers, as well as SRESET and MCE and + * syscall when invoked with "sc 1" switch to MSR[HV]=1 (HVMODE) to be taken, + * so they all generally need to test whether they were taken in guest context. + * + * Note: SRESET and MCE may also be sent to the guest by the hypervisor, and be + * taken with MSR[HV]=0. + * + * Interrupts which set SRR registers (with the above exceptions) do not + * elevate to MSR[HV]=1 mode, though most can be taken when running with + * MSR[HV]=1 (e.g., bare metal kernel and userspace). So these interrupts do + * not need to test whether a guest is running because they get delivered to + * the guest directly, including nested HV KVM guests. + * + * The exception is PR KVM, where the guest runs with MSR[PR]=1 and the host + * runs with MSR[HV]=0, so the host takes all interrupts on behalf of the + * guest. PR KVM runs with LPCR[AIL]=0 which causes interrupts to always be + * delivered to the real-mode entry point, therefore such interrupts only test + * KVM in their real mode handlers, and only when PR KVM is possible. + * + * Interrupts that are taken in MSR[HV]=0 and escalate to MSR[HV]=1 are always + * delivered in real-mode when the MMU is in hash mode because the MMU + * registers are not set appropriately to translate host addresses. In nested + * radix mode these can be delivered in virt-mode as the host translations are + * used implicitly (see: effective LPID, effective PID). + */ + +/* + * If an interrupt is taken while a guest is running, it is immediately routed + * to KVM to handle. If both HV and PR KVM arepossible, KVM interrupts go first + * to kvmppc_interrupt_hv, which handles the PR guest case. */ #define kvmppc_interrupt kvmppc_interrupt_hv #else #define kvmppc_interrupt kvmppc_interrupt_pr #endif -.macro KVMTEST name, hsrr, n +.macro KVMTEST name lbz r10,HSTATE_IN_GUEST(r13) cmpwi r10,0 bne \name\()_kvm .endm -.macro KVM_HANDLER vec, hsrr, area, skip - .if \skip +.macro GEN_KVM name + .balign IFETCH_ALIGN_BYTES +\name\()_kvm: + + .if IKVM_SKIP cmpwi r10,KVM_GUEST_MODE_SKIP beq 89f .else -BEGIN_FTR_SECTION_NESTED(947) - ld r10,\area+EX_CFAR(r13) +BEGIN_FTR_SECTION + ld r10,IAREA+EX_CFAR(r13) std r10,HSTATE_CFAR(r13) -END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) +END_FTR_SECTION_IFSET(CPU_FTR_CFAR) .endif -BEGIN_FTR_SECTION_NESTED(948) - ld r10,\area+EX_PPR(r13) + ld r10,PACA_EXGEN+EX_CTR(r13) + mtctr r10 +BEGIN_FTR_SECTION + ld r10,IAREA+EX_PPR(r13) std r10,HSTATE_PPR(r13) -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) - ld r10,\area+EX_R10(r13) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + ld r11,IAREA+EX_R11(r13) + ld r12,IAREA+EX_R12(r13) std r12,HSTATE_SCRATCH0(r13) sldi r12,r9,32 + ld r9,IAREA+EX_R9(r13) + ld r10,IAREA+EX_R10(r13) /* HSRR variants have the 0x2 bit added to their trap number */ - .if \hsrr == EXC_HV_OR_STD + .if IHSRR_IF_HVMODE BEGIN_FTR_SECTION - ori r12,r12,(\vec + 0x2) + ori r12,r12,(IVEC + 0x2) FTR_SECTION_ELSE - ori r12,r12,(\vec) + ori r12,r12,(IVEC) ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - ori r12,r12,(\vec + 0x2) + .elseif IHSRR + ori r12,r12,(IVEC+ 0x2) .else - ori r12,r12,(\vec) + ori r12,r12,(IVEC) .endif - -#ifdef CONFIG_RELOCATABLE - /* - * KVM requires __LOAD_FAR_HANDLER beause kvmppc_interrupt lives - * outside the head section. CONFIG_RELOCATABLE KVM expects CTR - * to be saved in HSTATE_SCRATCH1. - */ - mfctr r9 - std r9,HSTATE_SCRATCH1(r13) - __LOAD_FAR_HANDLER(r9, kvmppc_interrupt) - mtctr r9 - ld r9,\area+EX_R9(r13) - bctr -#else - ld r9,\area+EX_R9(r13) b kvmppc_interrupt -#endif - - .if \skip + .if IKVM_SKIP 89: mtocrf 0x80,r9 - ld r9,\area+EX_R9(r13) - ld r10,\area+EX_R10(r13) - .if \hsrr == EXC_HV_OR_STD + ld r10,PACA_EXGEN+EX_CTR(r13) + mtctr r10 + ld r9,IAREA+EX_R9(r13) + ld r10,IAREA+EX_R10(r13) + ld r11,IAREA+EX_R11(r13) + ld r12,IAREA+EX_R12(r13) + .if IHSRR_IF_HVMODE BEGIN_FTR_SECTION b kvmppc_skip_Hinterrupt FTR_SECTION_ELSE b kvmppc_skip_interrupt ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr + .elseif IHSRR b kvmppc_skip_Hinterrupt .else b kvmppc_skip_interrupt @@ -284,107 +319,12 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) .endm #else -.macro KVMTEST name, hsrr, n +.macro KVMTEST name .endm -.macro KVM_HANDLER name, vec, hsrr, area, skip +.macro GEN_KVM name .endm #endif -.macro INT_SAVE_SRR_AND_JUMP label, hsrr, set_ri - ld r10,PACAKMSR(r13) /* get MSR value for kernel */ - .if ! \set_ri - xori r10,r10,MSR_RI /* Clear MSR_RI */ - .endif - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - FTR_SECTION_ELSE - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - .endif - LOAD_HANDLER(r10, \label\()) - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - mtspr SPRN_HSRR0,r10 - HRFI_TO_KERNEL - FTR_SECTION_ELSE - mtspr SPRN_SRR0,r10 - RFI_TO_KERNEL - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - mtspr SPRN_HSRR0,r10 - HRFI_TO_KERNEL - .else - mtspr SPRN_SRR0,r10 - RFI_TO_KERNEL - .endif - b . /* prevent speculative execution */ -.endm - -/* INT_SAVE_SRR_AND_JUMP works for real or virt, this is faster but virt only */ -.macro INT_VIRT_SAVE_SRR_AND_JUMP label, hsrr -#ifdef CONFIG_RELOCATABLE - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - FTR_SECTION_ELSE - mfspr r11,SPRN_SRR0 /* save SRR0 */ - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12, \label\()) - mtctr r12 - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - FTR_SECTION_ELSE - mfspr r12,SPRN_SRR1 /* and HSRR1 */ - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r12,SPRN_SRR1 /* and HSRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - bctr -#else - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - FTR_SECTION_ELSE - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - b \label -#endif -.endm - /* * This is the BOOK3S interrupt entry code macro. * @@ -405,14 +345,41 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) * - Fall through and continue executing in real, unrelocated mode. * This is done if early=2. */ -.macro INT_HANDLER name, vec, ool=0, early=0, virt=0, hsrr=0, area=PACA_EXGEN, ri=1, dar=0, dsisr=0, bitmask=0, kvm=0 + +.macro GEN_BRANCH_TO_COMMON name, virt + .if IREALMODE_COMMON + LOAD_HANDLER(r10, \name\()_common) + mtctr r10 + bctr + .else + .if \virt +#ifndef CONFIG_RELOCATABLE + b \name\()_common_virt +#else + LOAD_HANDLER(r10, \name\()_common_virt) + mtctr r10 + bctr +#endif + .else + LOAD_HANDLER(r10, \name\()_common_real) + mtctr r10 + bctr + .endif + .endif +.endm + +.macro GEN_INT_ENTRY name, virt, ool=0 SET_SCRATCH0(r13) /* save r13 */ GET_PACA(r13) - std r9,\area\()+EX_R9(r13) /* save r9 */ - OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR) + std r9,IAREA+EX_R9(r13) /* save r9 */ +BEGIN_FTR_SECTION + mfspr r9,SPRN_PPR +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) HMT_MEDIUM - std r10,\area\()+EX_R10(r13) /* save r10 - r12 */ - OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) + std r10,IAREA+EX_R10(r13) /* save r10 - r12 */ +BEGIN_FTR_SECTION + mfspr r10,SPRN_CFAR +END_FTR_SECTION_IFSET(CPU_FTR_CFAR) .if \ool .if !\virt b tramp_real_\name @@ -425,47 +392,18 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) .endif .endif - OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) - OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR) +BEGIN_FTR_SECTION + std r9,IAREA+EX_PPR(r13) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) +BEGIN_FTR_SECTION + std r10,IAREA+EX_CFAR(r13) +END_FTR_SECTION_IFSET(CPU_FTR_CFAR) INTERRUPT_TO_KERNEL - SAVE_CTR(r10, \area\()) + mfctr r10 + std r10,IAREA+EX_CTR(r13) mfcr r9 - .if \kvm - KVMTEST \name \hsrr \vec - .endif - .if \bitmask - lbz r10,PACAIRQSOFTMASK(r13) - andi. r10,r10,\bitmask - /* Associate vector numbers with bits in paca->irq_happened */ - .if \vec == 0x500 || \vec == 0xea0 - li r10,PACA_IRQ_EE - .elseif \vec == 0x900 - li r10,PACA_IRQ_DEC - .elseif \vec == 0xa00 || \vec == 0xe80 - li r10,PACA_IRQ_DBELL - .elseif \vec == 0xe60 - li r10,PACA_IRQ_HMI - .elseif \vec == 0xf00 - li r10,PACA_IRQ_PMI - .else - .abort "Bad maskable vector" - .endif - - .if \hsrr == EXC_HV_OR_STD - BEGIN_FTR_SECTION - bne masked_Hinterrupt - FTR_SECTION_ELSE - bne masked_interrupt - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) - .elseif \hsrr - bne masked_Hinterrupt - .else - bne masked_interrupt - .endif - .endif - - std r11,\area\()+EX_R11(r13) - std r12,\area\()+EX_R12(r13) + std r11,IAREA+EX_R11(r13) + std r12,IAREA+EX_R12(r13) /* * DAR/DSISR, SCRATCH0 must be read before setting MSR[RI], @@ -473,49 +411,134 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) * not recoverable if they are live. */ GET_SCRATCH0(r10) - std r10,\area\()+EX_R13(r13) - .if \dar - .if \hsrr + std r10,IAREA+EX_R13(r13) + .if IDAR && !IISIDE + .if IHSRR mfspr r10,SPRN_HDAR .else mfspr r10,SPRN_DAR .endif - std r10,\area\()+EX_DAR(r13) + std r10,IAREA+EX_DAR(r13) .endif - .if \dsisr - .if \hsrr + .if IDSISR && !IISIDE + .if IHSRR mfspr r10,SPRN_HDSISR .else mfspr r10,SPRN_DSISR .endif - stw r10,\area\()+EX_DSISR(r13) + stw r10,IAREA+EX_DSISR(r13) .endif - .if \early == 2 - /* nothing more */ - .elseif \early - mfctr r10 /* save ctr, even for !RELOCATABLE */ - BRANCH_TO_C000(r11, \name\()_early_common) - .elseif !\virt - INT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr, \ri + .if IHSRR_IF_HVMODE + BEGIN_FTR_SECTION + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + FTR_SECTION_ELSE + mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) + .elseif IHSRR + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ .else - INT_VIRT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr + mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ .endif + + .if IBRANCH_TO_COMMON + GEN_BRANCH_TO_COMMON \name \virt + .endif + .if \ool .popsection .endif .endm /* - * On entry r13 points to the paca, r9-r13 are saved in the paca, - * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and - * SRR1, and relocation is on. + * __GEN_COMMON_ENTRY is required to receive the branch from interrupt + * entry, except in the case of the real-mode handlers which require + * __GEN_REALMODE_COMMON_ENTRY. * - * If stack=0, then the stack is already set in r1, and r1 is saved in r10. - * PPR save and CPU accounting is not done for the !stack case (XXX why not?) + * This switches to virtual mode and sets MSR[RI]. + */ +.macro __GEN_COMMON_ENTRY name +DEFINE_FIXED_SYMBOL(\name\()_common_real) +\name\()_common_real: + .if IKVM_REAL + KVMTEST \name + .endif + + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + /* MSR[RI] is clear iff using SRR regs */ + .if IHSRR == EXC_HV_OR_STD + BEGIN_FTR_SECTION + xori r10,r10,MSR_RI + END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) + .elseif ! IHSRR + xori r10,r10,MSR_RI + .endif + mtmsrd r10 + + .if IVIRT + .if IKVM_VIRT + b 1f /* skip the virt test coming from real */ + .endif + + .balign IFETCH_ALIGN_BYTES +DEFINE_FIXED_SYMBOL(\name\()_common_virt) +\name\()_common_virt: + .if IKVM_VIRT + KVMTEST \name +1: + .endif + .endif /* IVIRT */ +.endm + +/* + * Don't switch to virt mode. Used for early MCE and HMI handlers that + * want to run in real mode. */ -.macro INT_COMMON vec, area, stack, kuap, reconcile, dar, dsisr - .if \stack +.macro __GEN_REALMODE_COMMON_ENTRY name +DEFINE_FIXED_SYMBOL(\name\()_common_real) +\name\()_common_real: + .if IKVM_REAL + KVMTEST \name + .endif +.endm + +.macro __GEN_COMMON_BODY name + .if IMASK + lbz r10,PACAIRQSOFTMASK(r13) + andi. r10,r10,IMASK + /* Associate vector numbers with bits in paca->irq_happened */ + .if IVEC == 0x500 || IVEC == 0xea0 + li r10,PACA_IRQ_EE + .elseif IVEC == 0x900 + li r10,PACA_IRQ_DEC + .elseif IVEC == 0xa00 || IVEC == 0xe80 + li r10,PACA_IRQ_DBELL + .elseif IVEC == 0xe60 + li r10,PACA_IRQ_HMI + .elseif IVEC == 0xf00 + li r10,PACA_IRQ_PMI + .else + .abort "Bad maskable vector" + .endif + + .if IHSRR_IF_HVMODE + BEGIN_FTR_SECTION + bne masked_Hinterrupt + FTR_SECTION_ELSE + bne masked_interrupt + ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) + .elseif IHSRR + bne masked_Hinterrupt + .else + bne masked_interrupt + .endif + .endif + + .if ISTACK andi. r10,r12,MSR_PR /* See if coming from user */ mr r10,r1 /* Save r1 */ subi r1,r1,INT_FRAME_SIZE /* alloc frame on kernel stack */ @@ -532,54 +555,67 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) std r0,GPR0(r1) /* save r0 in stackframe */ std r10,GPR1(r1) /* save r1 in stackframe */ - .if \stack - .if \kuap + .if ISET_RI + li r10,MSR_RI + mtmsrd r10,1 /* Set MSR_RI */ + .endif + + .if ISTACK + .if IKUAP kuap_save_amr_and_lock r9, r10, cr1, cr0 .endif beq 101f /* if from kernel mode */ ACCOUNT_CPU_USER_ENTRY(r13, r9, r10) - SAVE_PPR(\area, r9) +BEGIN_FTR_SECTION + ld r9,IAREA+EX_PPR(r13) /* Read PPR from paca */ + std r9,_PPR(r1) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 101: .else - .if \kuap + .if IKUAP kuap_save_amr_and_lock r9, r10, cr1 .endif .endif /* Save original regs values from save area to stack frame. */ - ld r9,\area+EX_R9(r13) /* move r9, r10 to stackframe */ - ld r10,\area+EX_R10(r13) + ld r9,IAREA+EX_R9(r13) /* move r9, r10 to stackframe */ + ld r10,IAREA+EX_R10(r13) std r9,GPR9(r1) std r10,GPR10(r1) - ld r9,\area+EX_R11(r13) /* move r11 - r13 to stackframe */ - ld r10,\area+EX_R12(r13) - ld r11,\area+EX_R13(r13) + ld r9,IAREA+EX_R11(r13) /* move r11 - r13 to stackframe */ + ld r10,IAREA+EX_R12(r13) + ld r11,IAREA+EX_R13(r13) std r9,GPR11(r1) std r10,GPR12(r1) std r11,GPR13(r1) - .if \dar - .if \dar == 2 + + SAVE_NVGPRS(r1) + + .if IDAR + .if IISIDE ld r10,_NIP(r1) .else - ld r10,\area+EX_DAR(r13) + ld r10,IAREA+EX_DAR(r13) .endif std r10,_DAR(r1) .endif - .if \dsisr - .if \dsisr == 2 + + .if IDSISR + .if IISIDE ld r10,_MSR(r1) lis r11,DSISR_SRR1_MATCH_64S@h and r10,r10,r11 .else - lwz r10,\area+EX_DSISR(r13) + lwz r10,IAREA+EX_DSISR(r13) .endif std r10,_DSISR(r1) .endif -BEGIN_FTR_SECTION_NESTED(66) - ld r10,\area+EX_CFAR(r13) + +BEGIN_FTR_SECTION + ld r10,IAREA+EX_CFAR(r13) std r10,ORIG_GPR3(r1) -END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66) - GET_CTR(r10, \area) +END_FTR_SECTION_IFSET(CPU_FTR_CFAR) + ld r10,IAREA+EX_CTR(r13) std r10,_CTR(r1) std r2,GPR2(r1) /* save r2 in stackframe */ SAVE_4GPRS(3, r1) /* save r3 - r6 in stackframe */ @@ -591,32 +627,42 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66) mfspr r11,SPRN_XER /* save XER in stackframe */ std r10,SOFTE(r1) std r11,_XER(r1) - li r9,(\vec)+1 + li r9,IVEC std r9,_TRAP(r1) /* set trap number */ li r10,0 ld r11,exception_marker@toc(r2) std r10,RESULT(r1) /* clear regs->result */ std r11,STACK_FRAME_OVERHEAD-16(r1) /* mark the frame */ - .if \stack + .if ISTACK ACCOUNT_STOLEN_TIME .endif - .if \reconcile + .if IRECONCILE RECONCILE_IRQ_STATE(r10, r11) .endif .endm /* + * On entry r13 points to the paca, r9-r13 are saved in the paca, + * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and + * SRR1, and relocation is on. + * + * If stack=0, then the stack is already set in r1, and r1 is saved in r10. + * PPR save and CPU accounting is not done for the !stack case (XXX why not?) + */ +.macro GEN_COMMON name + __GEN_COMMON_ENTRY \name + __GEN_COMMON_BODY \name +.endm + +/* * Restore all registers including H/SRR0/1 saved in a stack frame of a * standard exception. */ -.macro EXCEPTION_RESTORE_REGS hsrr +.macro EXCEPTION_RESTORE_REGS hsrr=0 /* Move original SRR0 and SRR1 into the respective regs */ ld r9,_MSR(r1) - .if \hsrr == EXC_HV_OR_STD - .error "EXC_HV_OR_STD Not implemented for EXCEPTION_RESTORE_REGS" - .endif .if \hsrr mtspr SPRN_HSRR1,r9 .else @@ -670,28 +716,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define FINISH_NAP #endif -#define EXC_COMMON(name, realvec, hdlr) \ - EXC_COMMON_BEGIN(name); \ - INT_COMMON realvec, PACA_EXGEN, 1, 1, 1, 0, 0 ; \ - bl save_nvgprs; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except - -/* - * Like EXC_COMMON, but for exceptions that can occur in the idle task and - * therefore need the special idle handling (finish nap and runlatch) - */ -#define EXC_COMMON_ASYNC(name, realvec, hdlr) \ - EXC_COMMON_BEGIN(name); \ - INT_COMMON realvec, PACA_EXGEN, 1, 1, 1, 0, 0 ; \ - FINISH_NAP; \ - RUNLATCH_ON; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except_lite - - /* * There are a few constraints to be concerned with. * - Real mode exceptions code/data must be located at their physical location. @@ -778,6 +802,53 @@ __start_interrupts: EXC_VIRT_NONE(0x4000, 0x100) +/** + * Interrupt 0x100 - System Reset Interrupt (SRESET aka NMI). + * This is a non-maskable, asynchronous interrupt always taken in real-mode. + * It is caused by: + * - Wake from power-saving state, on powernv. + * - An NMI from another CPU, triggered by firmware or hypercall. + * - As crash/debug signal injected from BMC, firmware or hypervisor. + * + * Handling: + * Power-save wakeup is the only performance critical path, so this is + * determined quickly as possible first. In this case volatile registers + * can be discarded and SPRs like CFAR don't need to be read. + * + * If not a powersave wakeup, then it's run as a regular interrupt, however + * it uses its own stack and PACA save area to preserve the regular kernel + * environment for debugging. + * + * This interrupt is not maskable, so triggering it when MSR[RI] is clear, + * or SCRATCH0 is in use, etc. may cause a crash. It's also not entirely + * correct to switch to virtual mode to run the regular interrupt handler + * because it might be interrupted when the MMU is in a bad state (e.g., SLB + * is clear). + * + * FWNMI: + * PAPR specifies a "fwnmi" facility which sends the sreset to a different + * entry point with a different register set up. Some hypervisors will + * send the sreset to 0x100 in the guest if it is not fwnmi capable. + * + * KVM: + * Unlike most SRR interrupts, this may be taken by the host while executing + * in a guest, so a KVM test is required. KVM will pull the CPU out of guest + * mode and then raise the sreset. + */ +INT_DEFINE_BEGIN(system_reset) + IVEC=0x100 + IAREA=PACA_EXNMI + IVIRT=0 /* no virt entry point */ + /* + * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is + * being used, so a nested NMI exception would corrupt it. + */ + ISET_RI=0 + ISTACK=0 + IRECONCILE=0 + IKVM_REAL=1 +INT_DEFINE_END(system_reset) + EXC_REAL_BEGIN(system_reset, 0x100, 0x100) #ifdef CONFIG_PPC_P7_NAP /* @@ -815,11 +886,8 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) #endif - INT_HANDLER system_reset, 0x100, area=PACA_EXNMI, ri=0, kvm=1 + GEN_INT_ENTRY system_reset, virt=0 /* - * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is - * being used, so a nested NMI exception would corrupt it. - * * In theory, we should not enable relocation here if it was disabled * in SRR1, because the MMU may not be configured to support it (e.g., * SLB may have been cleared). In practice, there should only be a few @@ -828,7 +896,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) */ EXC_REAL_END(system_reset, 0x100, 0x100) EXC_VIRT_NONE(0x4100, 0x100) -INT_KVM_HANDLER system_reset 0x100, EXC_STD, PACA_EXNMI, 0 #ifdef CONFIG_PPC_P7_NAP TRAMP_REAL_BEGIN(system_reset_idle_wake) @@ -843,12 +910,14 @@ TRAMP_REAL_BEGIN(system_reset_idle_wake) * Vectors for the FWNMI option. Share common code. */ TRAMP_REAL_BEGIN(system_reset_fwnmi) - /* See comment at system_reset exception, don't turn on RI */ - INT_HANDLER system_reset, 0x100, area=PACA_EXNMI, ri=0 + /* XXX: fwnmi guest could run a nested/PR guest, so why no test? */ + __IKVM_REAL(system_reset)=0 + GEN_INT_ENTRY system_reset, virt=0 #endif /* CONFIG_PPC_PSERIES */ EXC_COMMON_BEGIN(system_reset_common) + __GEN_COMMON_ENTRY system_reset /* * Increment paca->in_nmi then enable MSR_RI. SLB or MCE will be able * to recover, but nested NMI will notice in_nmi and not recover @@ -864,21 +933,21 @@ EXC_COMMON_BEGIN(system_reset_common) mr r10,r1 ld r1,PACA_NMI_EMERG_SP(r13) subi r1,r1,INT_FRAME_SIZE - INT_COMMON 0x100, PACA_EXNMI, 0, 1, 0, 0, 0 - bl save_nvgprs + __GEN_COMMON_BODY system_reset /* - * Set IRQS_ALL_DISABLED unconditionally so arch_irqs_disabled does + * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does * the right thing. We do not want to reconcile because that goes * through irq tracing which we don't want in NMI. * - * Save PACAIRQHAPPENED because some code will do a hard disable - * (e.g., xmon). So we want to restore this back to where it was - * when we return. DAR is unused in the stack, so save it there. + * Save PACAIRQHAPPENED to _DAR (otherwise unused), and set HARD_DIS + * as we are running with MSR[EE]=0. */ li r10,IRQS_ALL_DISABLED stb r10,PACAIRQSOFTMASK(r13) lbz r10,PACAIRQHAPPENED(r13) std r10,_DAR(r1) + ori r10,r10,PACA_IRQ_HARD_DIS + stb r10,PACAIRQHAPPENED(r13) addi r3,r1,STACK_FRAME_OVERHEAD bl system_reset_exception @@ -902,28 +971,95 @@ EXC_COMMON_BEGIN(system_reset_common) ld r10,SOFTE(r1) stb r10,PACAIRQSOFTMASK(r13) - EXCEPTION_RESTORE_REGS EXC_STD + EXCEPTION_RESTORE_REGS RFI_TO_USER_OR_KERNEL + GEN_KVM system_reset -EXC_REAL_BEGIN(machine_check, 0x200, 0x100) - INT_HANDLER machine_check, 0x200, early=1, area=PACA_EXMC, dar=1, dsisr=1 + +/** + * Interrupt 0x200 - Machine Check Interrupt (MCE). + * This is a non-maskable interrupt always taken in real-mode. It can be + * synchronous or asynchronous, caused by hardware or software, and it may be + * taken in a power-saving state. + * + * Handling: + * Similarly to system reset, this uses its own stack and PACA save area, + * the difference is re-entrancy is allowed on the machine check stack. + * + * machine_check_early is run in real mode, and carefully decodes the + * machine check and tries to handle it (e.g., flush the SLB if there was an + * error detected there), determines if it was recoverable and logs the + * event. + * + * This early code does not "reconcile" irq soft-mask state like SRESET or + * regular interrupts do, so irqs_disabled() among other things may not work + * properly (irq disable/enable already doesn't work because irq tracing can + * not work in real mode). + * + * Then, depending on the execution context when the interrupt is taken, there + * are 3 main actions: + * - Executing in kernel mode. The event is queued with irq_work, which means + * it is handled when it is next safe to do so (i.e., the kernel has enabled + * interrupts), which could be immediately when the interrupt returns. This + * avoids nasty issues like switching to virtual mode when the MMU is in a + * bad state, or when executing OPAL code. (SRESET is exposed to such issues, + * but it has different priorities). Check to see if the CPU was in power + * save, and return via the wake up code if it was. + * + * - Executing in user mode. machine_check_exception is run like a normal + * interrupt handler, which processes the data generated by the early handler. + * + * - Executing in guest mode. The interrupt is run with its KVM test, and + * branches to KVM to deal with. KVM may queue the event for the host + * to report later. + * + * This interrupt is not maskable, so if it triggers when MSR[RI] is clear, + * or SCRATCH0 is in use, it may cause a crash. + * + * KVM: + * See SRESET. + */ +INT_DEFINE_BEGIN(machine_check_early) + IVEC=0x200 + IAREA=PACA_EXMC + IVIRT=0 /* no virt entry point */ + IREALMODE_COMMON=1 /* * MSR_RI is not enabled, because PACA_EXMC is being used, so a * nested machine check corrupts it. machine_check_common enables * MSR_RI. */ + ISET_RI=0 + ISTACK=0 + IDAR=1 + IDSISR=1 + IRECONCILE=0 + IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ +INT_DEFINE_END(machine_check_early) + +INT_DEFINE_BEGIN(machine_check) + IVEC=0x200 + IAREA=PACA_EXMC + IVIRT=0 /* no virt entry point */ + ISET_RI=0 + IDAR=1 + IDSISR=1 + IKVM_SKIP=1 + IKVM_REAL=1 +INT_DEFINE_END(machine_check) + +EXC_REAL_BEGIN(machine_check, 0x200, 0x100) + GEN_INT_ENTRY machine_check_early, virt=0 EXC_REAL_END(machine_check, 0x200, 0x100) EXC_VIRT_NONE(0x4200, 0x100) #ifdef CONFIG_PPC_PSERIES TRAMP_REAL_BEGIN(machine_check_fwnmi) /* See comment at machine_check exception, don't turn on RI */ - INT_HANDLER machine_check, 0x200, early=1, area=PACA_EXMC, dar=1, dsisr=1 + GEN_INT_ENTRY machine_check_early, virt=0 #endif -INT_KVM_HANDLER machine_check 0x200, EXC_STD, PACA_EXMC, 1 - #define MACHINE_CHECK_HANDLER_WINDUP \ /* Clear MSR_RI before setting SRR0 and SRR1. */\ li r9,0; \ @@ -932,12 +1068,10 @@ INT_KVM_HANDLER machine_check 0x200, EXC_STD, PACA_EXMC, 1 lhz r12,PACA_IN_MCE(r13); \ subi r12,r12,1; \ sth r12,PACA_IN_MCE(r13); \ - EXCEPTION_RESTORE_REGS EXC_STD + EXCEPTION_RESTORE_REGS EXC_COMMON_BEGIN(machine_check_early_common) - mtctr r10 /* Restore ctr */ - mfspr r11,SPRN_SRR0 - mfspr r12,SPRN_SRR1 + __GEN_REALMODE_COMMON_ENTRY machine_check_early /* * Switch to mc_emergency stack and handle re-entrancy (we limit @@ -974,8 +1108,7 @@ EXC_COMMON_BEGIN(machine_check_early_common) bgt cr1,unrecoverable_mce /* Check if we hit limit of 4 */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ - /* We don't touch AMR here, we never go to virtual mode */ - INT_COMMON 0x200, PACA_EXMC, 0, 0, 0, 1, 1 + __GEN_COMMON_BODY machine_check_early BEGIN_FTR_SECTION bl enable_machine_check @@ -983,7 +1116,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) li r10,MSR_RI mtmsrd r10,1 - bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl machine_check_early std r3,RESULT(r1) /* Save result */ @@ -1063,23 +1195,25 @@ BEGIN_FTR_SECTION mtspr SPRN_CFAR,r10 END_FTR_SECTION_IFSET(CPU_FTR_CFAR) MACHINE_CHECK_HANDLER_WINDUP - /* See comment at machine_check exception, don't turn on RI */ - INT_HANDLER machine_check, 0x200, area=PACA_EXMC, ri=0, dar=1, dsisr=1, kvm=1 + GEN_INT_ENTRY machine_check, virt=0 EXC_COMMON_BEGIN(machine_check_common) /* * Machine check is different because we use a different * save area: PACA_EXMC instead of PACA_EXGEN. */ - INT_COMMON 0x200, PACA_EXMC, 1, 1, 1, 1, 1 + GEN_COMMON machine_check + FINISH_NAP /* Enable MSR_RI when finished with PACA_EXMC */ li r10,MSR_RI mtmsrd r10,1 - bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl machine_check_exception - b ret_from_except + b interrupt_return + + GEN_KVM machine_check + #ifdef CONFIG_PPC_P7_NAP /* @@ -1144,21 +1278,48 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) b . +/** + * Interrupt 0x300 - Data Storage Interrupt (DSI). + * This is a synchronous interrupt generated due to a data access exception, + * e.g., a load orstore which does not have a valid page table entry with + * permissions. DAWR matches also fault here, as do RC updates, and minor misc + * errors e.g., copy/paste, AMO, certain invalid CI accesses, etc. + * + * Handling: + * - Hash MMU + * Go to do_hash_page first to see if the HPT can be filled from an entry in + * the Linux page table. Hash faults can hit in kernel mode in a fairly + * arbitrary state (e.g., interrupts disabled, locks held) when accessing + * "non-bolted" regions, e.g., vmalloc space. However these should always be + * backed by Linux page tables. + * + * If none is found, do a Linux page fault. Linux page faults can happen in + * kernel mode due to user copy operations of course. + * + * - Radix MMU + * The hardware loads from the Linux page table directly, so a fault goes + * immediately to Linux page fault. + * + * Conditions like DAWR match are handled on the way in to Linux page fault. + */ +INT_DEFINE_BEGIN(data_access) + IVEC=0x300 + IDAR=1 + IDSISR=1 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_SKIP=1 + IKVM_REAL=1 +#endif +INT_DEFINE_END(data_access) + EXC_REAL_BEGIN(data_access, 0x300, 0x80) - INT_HANDLER data_access, 0x300, ool=1, dar=1, dsisr=1, kvm=1 + GEN_INT_ENTRY data_access, virt=0 EXC_REAL_END(data_access, 0x300, 0x80) EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) - INT_HANDLER data_access, 0x300, virt=1, dar=1, dsisr=1 + GEN_INT_ENTRY data_access, virt=1 EXC_VIRT_END(data_access, 0x4300, 0x80) -INT_KVM_HANDLER data_access, 0x300, EXC_STD, PACA_EXGEN, 1 EXC_COMMON_BEGIN(data_access_common) - /* - * Here r13 points to the paca, r9 contains the saved CR, - * SRR0 and SRR1 are saved in r11 and r12, - * r9 - r13 are saved in paca->exgen. - * EX_DAR and EX_DSISR have saved DAR/DSISR - */ - INT_COMMON 0x300, PACA_EXGEN, 1, 1, 1, 1, 1 + GEN_COMMON data_access ld r4,_DAR(r1) ld r5,_DSISR(r1) BEGIN_MMU_FTR_SECTION @@ -1169,16 +1330,46 @@ MMU_FTR_SECTION_ELSE b handle_page_fault ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) + GEN_KVM data_access + + +/** + * Interrupt 0x380 - Data Segment Interrupt (DSLB). + * This is a synchronous interrupt in response to an MMU fault missing SLB + * entry for HPT, or an address outside RPT translation range. + * + * Handling: + * - HPT: + * This refills the SLB, or reports an access fault similarly to a bad page + * fault. When coming from user-mode, the SLB handler may access any kernel + * data, though it may itself take a DSLB. When coming from kernel mode, + * recursive faults must be avoided so access is restricted to the kernel + * image text/data, kernel stack, and any data allocated below + * ppc64_bolted_size (first segment). The kernel handler must avoid stomping + * on user-handler data structures. + * + * A dedicated save area EXSLB is used (XXX: but it actually need not be + * these days, we could use EXGEN). + */ +INT_DEFINE_BEGIN(data_access_slb) + IVEC=0x380 + IAREA=PACA_EXSLB + IRECONCILE=0 + IDAR=1 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_SKIP=1 + IKVM_REAL=1 +#endif +INT_DEFINE_END(data_access_slb) EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) - INT_HANDLER data_access_slb, 0x380, ool=1, area=PACA_EXSLB, dar=1, kvm=1 + GEN_INT_ENTRY data_access_slb, virt=0 EXC_REAL_END(data_access_slb, 0x380, 0x80) EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) - INT_HANDLER data_access_slb, 0x380, virt=1, area=PACA_EXSLB, dar=1 + GEN_INT_ENTRY data_access_slb, virt=1 EXC_VIRT_END(data_access_slb, 0x4380, 0x80) -INT_KVM_HANDLER data_access_slb, 0x380, EXC_STD, PACA_EXSLB, 1 EXC_COMMON_BEGIN(data_access_slb_common) - INT_COMMON 0x380, PACA_EXSLB, 1, 1, 0, 1, 0 + GEN_COMMON data_access_slb ld r4,_DAR(r1) addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION @@ -1186,31 +1377,50 @@ BEGIN_MMU_FTR_SECTION bl do_slb_fault cmpdi r3,0 bne- 1f - b fast_exception_return + b fast_interrupt_return 1: /* Error case */ MMU_FTR_SECTION_ELSE /* Radix case, access is outside page table range */ li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) ld r4,_DAR(r1) ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault - b ret_from_except + b interrupt_return + + GEN_KVM data_access_slb +/** + * Interrupt 0x400 - Instruction Storage Interrupt (ISI). + * This is a synchronous interrupt in response to an MMU fault due to an + * instruction fetch. + * + * Handling: + * Similar to DSI, though in response to fetch. The faulting address is found + * in SRR0 (rather than DAR), and status in SRR1 (rather than DSISR). + */ +INT_DEFINE_BEGIN(instruction_access) + IVEC=0x400 + IISIDE=1 + IDAR=1 + IDSISR=1 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(instruction_access) + EXC_REAL_BEGIN(instruction_access, 0x400, 0x80) - INT_HANDLER instruction_access, 0x400, kvm=1 + GEN_INT_ENTRY instruction_access, virt=0 EXC_REAL_END(instruction_access, 0x400, 0x80) EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80) - INT_HANDLER instruction_access, 0x400, virt=1 + GEN_INT_ENTRY instruction_access, virt=1 EXC_VIRT_END(instruction_access, 0x4400, 0x80) -INT_KVM_HANDLER instruction_access, 0x400, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(instruction_access_common) - INT_COMMON 0x400, PACA_EXGEN, 1, 1, 1, 2, 2 + GEN_COMMON instruction_access ld r4,_DAR(r1) ld r5,_DSISR(r1) BEGIN_MMU_FTR_SECTION @@ -1221,16 +1431,37 @@ MMU_FTR_SECTION_ELSE b handle_page_fault ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) + GEN_KVM instruction_access + + +/** + * Interrupt 0x480 - Instruction Segment Interrupt (ISLB). + * This is a synchronous interrupt in response to an MMU fault due to an + * instruction fetch. + * + * Handling: + * Similar to DSLB, though in response to fetch. The faulting address is found + * in SRR0 (rather than DAR). + */ +INT_DEFINE_BEGIN(instruction_access_slb) + IVEC=0x480 + IAREA=PACA_EXSLB + IRECONCILE=0 + IISIDE=1 + IDAR=1 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(instruction_access_slb) EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80) - INT_HANDLER instruction_access_slb, 0x480, area=PACA_EXSLB, kvm=1 + GEN_INT_ENTRY instruction_access_slb, virt=0 EXC_REAL_END(instruction_access_slb, 0x480, 0x80) EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) - INT_HANDLER instruction_access_slb, 0x480, virt=1, area=PACA_EXSLB + GEN_INT_ENTRY instruction_access_slb, virt=1 EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80) -INT_KVM_HANDLER instruction_access_slb, 0x480, EXC_STD, PACA_EXSLB, 0 EXC_COMMON_BEGIN(instruction_access_slb_common) - INT_COMMON 0x480, PACA_EXSLB, 1, 1, 0, 2, 0 + GEN_COMMON instruction_access_slb ld r4,_DAR(r1) addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION @@ -1238,54 +1469,125 @@ BEGIN_MMU_FTR_SECTION bl do_slb_fault cmpdi r3,0 bne- 1f - b fast_exception_return + b fast_interrupt_return 1: /* Error case */ MMU_FTR_SECTION_ELSE /* Radix case, access is outside page table range */ li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) ld r4,_DAR(r1) ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault - b ret_from_except + b interrupt_return + + GEN_KVM instruction_access_slb + + +/** + * Interrupt 0x500 - External Interrupt. + * This is an asynchronous maskable interrupt in response to an "external + * exception" from the interrupt controller or hypervisor (e.g., device + * interrupt). It is maskable in hardware by clearing MSR[EE], and + * soft-maskable with IRQS_DISABLED mask (i.e., local_irq_disable()). + * + * When running in HV mode, Linux sets up the LPCR[LPES] bit such that + * interrupts are delivered with HSRR registers, guests use SRRs, which + * reqiures IHSRR_IF_HVMODE. + * + * On bare metal POWER9 and later, Linux sets the LPCR[HVICE] bit such that + * external interrupts are delivered as Hypervisor Virtualization Interrupts + * rather than External Interrupts. + * + * Handling: + * This calls into Linux IRQ handler. NVGPRs are not saved to reduce overhead, + * because registers at the time of the interrupt are not so important as it is + * asynchronous. + * + * If soft masked, the masked handler will note the pending interrupt for + * replay, and clear MSR[EE] in the interrupted context. + */ +INT_DEFINE_BEGIN(hardware_interrupt) + IVEC=0x500 + IHSRR_IF_HVMODE=1 + IMASK=IRQS_DISABLED + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(hardware_interrupt) EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) - INT_HANDLER hardware_interrupt, 0x500, hsrr=EXC_HV_OR_STD, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY hardware_interrupt, virt=0 EXC_REAL_END(hardware_interrupt, 0x500, 0x100) EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) - INT_HANDLER hardware_interrupt, 0x500, virt=1, hsrr=EXC_HV_OR_STD, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY hardware_interrupt, virt=1 EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) -INT_KVM_HANDLER hardware_interrupt, 0x500, EXC_HV_OR_STD, PACA_EXGEN, 0 -EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) +EXC_COMMON_BEGIN(hardware_interrupt_common) + GEN_COMMON hardware_interrupt + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_IRQ + b interrupt_return + + GEN_KVM hardware_interrupt +/** + * Interrupt 0x600 - Alignment Interrupt + * This is a synchronous interrupt in response to data alignment fault. + */ +INT_DEFINE_BEGIN(alignment) + IVEC=0x600 + IDAR=1 + IDSISR=1 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(alignment) + EXC_REAL_BEGIN(alignment, 0x600, 0x100) - INT_HANDLER alignment, 0x600, dar=1, dsisr=1, kvm=1 + GEN_INT_ENTRY alignment, virt=0 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) - INT_HANDLER alignment, 0x600, virt=1, dar=1, dsisr=1 + GEN_INT_ENTRY alignment, virt=1 EXC_VIRT_END(alignment, 0x4600, 0x100) -INT_KVM_HANDLER alignment, 0x600, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(alignment_common) - INT_COMMON 0x600, PACA_EXGEN, 1, 1, 1, 1, 1 - bl save_nvgprs + GEN_COMMON alignment addi r3,r1,STACK_FRAME_OVERHEAD bl alignment_exception - b ret_from_except + REST_NVGPRS(r1) /* instruction emulation may change GPRs */ + b interrupt_return + + GEN_KVM alignment +/** + * Interrupt 0x700 - Program Interrupt (program check). + * This is a synchronous interrupt in response to various instruction faults: + * traps, privilege errors, TM errors, floating point exceptions. + * + * Handling: + * This interrupt may use the "emergency stack" in some cases when being taken + * from kernel context, which complicates handling. + */ +INT_DEFINE_BEGIN(program_check) + IVEC=0x700 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(program_check) + EXC_REAL_BEGIN(program_check, 0x700, 0x100) - INT_HANDLER program_check, 0x700, kvm=1 + GEN_INT_ENTRY program_check, virt=0 EXC_REAL_END(program_check, 0x700, 0x100) EXC_VIRT_BEGIN(program_check, 0x4700, 0x100) - INT_HANDLER program_check, 0x700, virt=1 + GEN_INT_ENTRY program_check, virt=1 EXC_VIRT_END(program_check, 0x4700, 0x100) -INT_KVM_HANDLER program_check, 0x700, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(program_check_common) + __GEN_COMMON_ENTRY program_check + /* * It's possible to receive a TM Bad Thing type program check with * userspace register values (in particular r1), but with SRR1 reporting @@ -1310,28 +1612,47 @@ EXC_COMMON_BEGIN(program_check_common) mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ - INT_COMMON 0x700, PACA_EXGEN, 0, 1, 1, 0, 0 + __ISTACK(program_check)=0 + __GEN_COMMON_BODY program_check b 3f 2: - INT_COMMON 0x700, PACA_EXGEN, 1, 1, 1, 0, 0 + __ISTACK(program_check)=1 + __GEN_COMMON_BODY program_check 3: - bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl program_check_exception - b ret_from_except + REST_NVGPRS(r1) /* instruction emulation may change GPRs */ + b interrupt_return + + GEN_KVM program_check +/* + * Interrupt 0x800 - Floating-Point Unavailable Interrupt. + * This is a synchronous interrupt in response to executing an fp instruction + * with MSR[FP]=0. + * + * Handling: + * This will load FP registers and enable the FP bit if coming from userspace, + * otherwise report a bad kernel use of FP. + */ +INT_DEFINE_BEGIN(fp_unavailable) + IVEC=0x800 + IRECONCILE=0 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(fp_unavailable) + EXC_REAL_BEGIN(fp_unavailable, 0x800, 0x100) - INT_HANDLER fp_unavailable, 0x800, kvm=1 + GEN_INT_ENTRY fp_unavailable, virt=0 EXC_REAL_END(fp_unavailable, 0x800, 0x100) EXC_VIRT_BEGIN(fp_unavailable, 0x4800, 0x100) - INT_HANDLER fp_unavailable, 0x800, virt=1 + GEN_INT_ENTRY fp_unavailable, virt=1 EXC_VIRT_END(fp_unavailable, 0x4800, 0x100) -INT_KVM_HANDLER fp_unavailable, 0x800, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(fp_unavailable_common) - INT_COMMON 0x800, PACA_EXGEN, 1, 1, 0, 0, 0 + GEN_COMMON fp_unavailable bne 1f /* if from user, just load it up */ - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl kernel_fp_unavailable_exception @@ -1348,64 +1669,168 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif bl load_up_fpu - b fast_exception_return + b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl fp_unavailable_tm - b ret_from_except + b interrupt_return #endif + GEN_KVM fp_unavailable + + +/** + * Interrupt 0x900 - Decrementer Interrupt. + * This is an asynchronous interrupt in response to a decrementer exception + * (e.g., DEC has wrapped below zero). It is maskable in hardware by clearing + * MSR[EE], and soft-maskable with IRQS_DISABLED mask (i.e., + * local_irq_disable()). + * + * Handling: + * This calls into Linux timer handler. NVGPRs are not saved (see 0x500). + * + * If soft masked, the masked handler will note the pending interrupt for + * replay, and bump the decrementer to a high value, leaving MSR[EE] enabled + * in the interrupted context. + * If PPC_WATCHDOG is configured, the soft masked handler will actually set + * things back up to run soft_nmi_interrupt as a regular interrupt handler + * on the emergency stack. + */ +INT_DEFINE_BEGIN(decrementer) + IVEC=0x900 + IMASK=IRQS_DISABLED +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(decrementer) EXC_REAL_BEGIN(decrementer, 0x900, 0x80) - INT_HANDLER decrementer, 0x900, ool=1, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY decrementer, virt=0 EXC_REAL_END(decrementer, 0x900, 0x80) EXC_VIRT_BEGIN(decrementer, 0x4900, 0x80) - INT_HANDLER decrementer, 0x900, virt=1, bitmask=IRQS_DISABLED + GEN_INT_ENTRY decrementer, virt=1 EXC_VIRT_END(decrementer, 0x4900, 0x80) -INT_KVM_HANDLER decrementer, 0x900, EXC_STD, PACA_EXGEN, 0 -EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt) +EXC_COMMON_BEGIN(decrementer_common) + GEN_COMMON decrementer + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD + bl timer_interrupt + b interrupt_return + GEN_KVM decrementer + + +/** + * Interrupt 0x980 - Hypervisor Decrementer Interrupt. + * This is an asynchronous interrupt, similar to 0x900 but for the HDEC + * register. + * + * Handling: + * Linux does not use this outside KVM where it's used to keep a host timer + * while the guest is given control of DEC. It should normally be caught by + * the KVM test and routed there. + */ +INT_DEFINE_BEGIN(hdecrementer) + IVEC=0x980 + IHSRR=1 + ISTACK=0 + IRECONCILE=0 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(hdecrementer) EXC_REAL_BEGIN(hdecrementer, 0x980, 0x80) - INT_HANDLER hdecrementer, 0x980, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY hdecrementer, virt=0 EXC_REAL_END(hdecrementer, 0x980, 0x80) EXC_VIRT_BEGIN(hdecrementer, 0x4980, 0x80) - INT_HANDLER hdecrementer, 0x980, virt=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY hdecrementer, virt=1 EXC_VIRT_END(hdecrementer, 0x4980, 0x80) -INT_KVM_HANDLER hdecrementer, 0x980, EXC_HV, PACA_EXGEN, 0 -EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt) +EXC_COMMON_BEGIN(hdecrementer_common) + __GEN_COMMON_ENTRY hdecrementer + /* + * Hypervisor decrementer interrupts not caught by the KVM test + * shouldn't occur but are sometimes left pending on exit from a KVM + * guest. We don't need to do anything to clear them, as they are + * edge-triggered. + * + * Be careful to avoid touching the kernel stack. + */ + ld r10,PACA_EXGEN+EX_CTR(r13) + mtctr r10 + mtcrf 0x80,r9 + ld r9,PACA_EXGEN+EX_R9(r13) + ld r10,PACA_EXGEN+EX_R10(r13) + ld r11,PACA_EXGEN+EX_R11(r13) + ld r12,PACA_EXGEN+EX_R12(r13) + ld r13,PACA_EXGEN+EX_R13(r13) + HRFI_TO_KERNEL + GEN_KVM hdecrementer + + +/** + * Interrupt 0xa00 - Directed Privileged Doorbell Interrupt. + * This is an asynchronous interrupt in response to a msgsndp doorbell. + * It is maskable in hardware by clearing MSR[EE], and soft-maskable with + * IRQS_DISABLED mask (i.e., local_irq_disable()). + * + * Handling: + * Guests may use this for IPIs between threads in a core if the + * hypervisor supports it. NVGPRS are not saved (see 0x500). + * + * If soft masked, the masked handler will note the pending interrupt for + * replay, leaving MSR[EE] enabled in the interrupted context because the + * doorbells are edge triggered. + */ +INT_DEFINE_BEGIN(doorbell_super) + IVEC=0xa00 + IMASK=IRQS_DISABLED +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(doorbell_super) EXC_REAL_BEGIN(doorbell_super, 0xa00, 0x100) - INT_HANDLER doorbell_super, 0xa00, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY doorbell_super, virt=0 EXC_REAL_END(doorbell_super, 0xa00, 0x100) EXC_VIRT_BEGIN(doorbell_super, 0x4a00, 0x100) - INT_HANDLER doorbell_super, 0xa00, virt=1, bitmask=IRQS_DISABLED + GEN_INT_ENTRY doorbell_super, virt=1 EXC_VIRT_END(doorbell_super, 0x4a00, 0x100) -INT_KVM_HANDLER doorbell_super, 0xa00, EXC_STD, PACA_EXGEN, 0 +EXC_COMMON_BEGIN(doorbell_super_common) + GEN_COMMON doorbell_super + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL -EXC_COMMON_ASYNC(doorbell_super_common, 0xa00, doorbell_exception) + bl doorbell_exception #else -EXC_COMMON_ASYNC(doorbell_super_common, 0xa00, unknown_exception) + bl unknown_exception #endif + b interrupt_return + + GEN_KVM doorbell_super EXC_REAL_NONE(0xb00, 0x100) EXC_VIRT_NONE(0x4b00, 0x100) -/* - * system call / hypercall (0xc00, 0x4c00) - * - * The system call exception is invoked with "sc 0" and does not alter HV bit. - * - * The hypercall is invoked with "sc 1" and sets HV=1. +/** + * Interrupt 0xc00 - System Call Interrupt (syscall, hcall). + * This is a synchronous interrupt invoked with the "sc" instruction. The + * system call is invoked with "sc 0" and does not alter the HV bit, so it + * is directed to the currently running OS. The hypercall is invoked with + * "sc 1" and it sets HV=1, so it elevates to hypervisor. * * In HPT, sc 1 always goes to 0xc00 real mode. In RADIX, sc 1 can go to * 0x4c00 virtual mode. * + * Handling: + * If the KVM test fires then it was due to a hypercall and is accordingly + * routed to KVM. Otherwise this executes a normal Linux system call. + * * Call convention: * * syscall and hypercalls register conventions are documented in @@ -1417,6 +1842,12 @@ EXC_VIRT_NONE(0x4b00, 0x100) * without saving, though xer is not a good idea to use, as hardware may * interpret some bits so it may be costly to change them. */ +INT_DEFINE_BEGIN(system_call) + IVEC=0xc00 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(system_call) + .macro SYSTEM_CALL virt #ifdef CONFIG_KVM_BOOK3S_64_HANDLER /* @@ -1431,7 +1862,7 @@ EXC_VIRT_NONE(0x4b00, 0x100) GET_PACA(r13) std r10,PACA_EXGEN+EX_R10(r13) INTERRUPT_TO_KERNEL - KVMTEST system_call EXC_STD 0xc00 /* uses r10, branch to system_call_kvm */ + KVMTEST system_call /* uses r10, branch to system_call_kvm */ mfctr r9 #else mr r9,r13 @@ -1490,6 +1921,7 @@ EXC_VIRT_BEGIN(system_call, 0x4c00, 0x100) EXC_VIRT_END(system_call, 0x4c00, 0x100) #ifdef CONFIG_KVM_BOOK3S_64_HANDLER +TRAMP_REAL_BEGIN(system_call_kvm) /* * This is a hcall, so register convention is as above, with these * differences: @@ -1497,43 +1929,95 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100) * ctr = orig r13 * orig r10 saved in PACA */ -TRAMP_KVM_BEGIN(system_call_kvm) /* * Save the PPR (on systems that support it) before changing to * HMT_MEDIUM. That allows the KVM code to save that value into the * guest state (it is the guest's PPR value). */ - OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR) +BEGIN_FTR_SECTION + mfspr r10,SPRN_PPR + std r10,HSTATE_PPR(r13) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) HMT_MEDIUM - OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR) mfctr r10 SET_SCRATCH0(r10) - std r9,PACA_EXGEN+EX_R9(r13) - mfcr r9 - KVM_HANDLER 0xc00, EXC_STD, PACA_EXGEN, 0 + mfcr r10 + std r12,HSTATE_SCRATCH0(r13) + sldi r12,r10,32 + ori r12,r12,0xc00 +#ifdef CONFIG_RELOCATABLE + /* + * Requires __LOAD_FAR_HANDLER beause kvmppc_interrupt lives + * outside the head section. + */ + __LOAD_FAR_HANDLER(r10, kvmppc_interrupt) + mtctr r10 + ld r10,PACA_EXGEN+EX_R10(r13) + bctr +#else + ld r10,PACA_EXGEN+EX_R10(r13) + b kvmppc_interrupt +#endif #endif +/** + * Interrupt 0xd00 - Trace Interrupt. + * This is a synchronous interrupt in response to instruction step or + * breakpoint faults. + */ +INT_DEFINE_BEGIN(single_step) + IVEC=0xd00 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(single_step) + EXC_REAL_BEGIN(single_step, 0xd00, 0x100) - INT_HANDLER single_step, 0xd00, kvm=1 + GEN_INT_ENTRY single_step, virt=0 EXC_REAL_END(single_step, 0xd00, 0x100) EXC_VIRT_BEGIN(single_step, 0x4d00, 0x100) - INT_HANDLER single_step, 0xd00, virt=1 + GEN_INT_ENTRY single_step, virt=1 EXC_VIRT_END(single_step, 0x4d00, 0x100) -INT_KVM_HANDLER single_step, 0xd00, EXC_STD, PACA_EXGEN, 0 -EXC_COMMON(single_step_common, 0xd00, single_step_exception) +EXC_COMMON_BEGIN(single_step_common) + GEN_COMMON single_step + addi r3,r1,STACK_FRAME_OVERHEAD + bl single_step_exception + b interrupt_return + GEN_KVM single_step + + +/** + * Interrupt 0xe00 - Hypervisor Data Storage Interrupt (HDSI). + * This is a synchronous interrupt in response to an MMU fault caused by a + * guest data access. + * + * Handling: + * This should always get routed to KVM. In radix MMU mode, this is caused + * by a guest nested radix access that can't be performed due to the + * partition scope page table. In hash mode, this can be caused by guests + * running with translation disabled (virtual real mode) or with VPM enabled. + * KVM will update the page table structures or disallow the access. + */ +INT_DEFINE_BEGIN(h_data_storage) + IVEC=0xe00 + IHSRR=1 + IDAR=1 + IDSISR=1 + IKVM_SKIP=1 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(h_data_storage) EXC_REAL_BEGIN(h_data_storage, 0xe00, 0x20) - INT_HANDLER h_data_storage, 0xe00, ool=1, hsrr=EXC_HV, dar=1, dsisr=1, kvm=1 + GEN_INT_ENTRY h_data_storage, virt=0, ool=1 EXC_REAL_END(h_data_storage, 0xe00, 0x20) EXC_VIRT_BEGIN(h_data_storage, 0x4e00, 0x20) - INT_HANDLER h_data_storage, 0xe00, ool=1, virt=1, hsrr=EXC_HV, dar=1, dsisr=1, kvm=1 + GEN_INT_ENTRY h_data_storage, virt=1, ool=1 EXC_VIRT_END(h_data_storage, 0x4e00, 0x20) -INT_KVM_HANDLER h_data_storage, 0xe00, EXC_HV, PACA_EXGEN, 1 EXC_COMMON_BEGIN(h_data_storage_common) - INT_COMMON 0xe00, PACA_EXGEN, 1, 1, 1, 1, 1 - bl save_nvgprs + GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION ld r4,_DAR(r1) @@ -1542,56 +2026,125 @@ BEGIN_MMU_FTR_SECTION MMU_FTR_SECTION_ELSE bl unknown_exception ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX) - b ret_from_except + b interrupt_return + GEN_KVM h_data_storage + + +/** + * Interrupt 0xe20 - Hypervisor Instruction Storage Interrupt (HISI). + * This is a synchronous interrupt in response to an MMU fault caused by a + * guest instruction fetch, similar to HDSI. + */ +INT_DEFINE_BEGIN(h_instr_storage) + IVEC=0xe20 + IHSRR=1 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(h_instr_storage) EXC_REAL_BEGIN(h_instr_storage, 0xe20, 0x20) - INT_HANDLER h_instr_storage, 0xe20, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY h_instr_storage, virt=0, ool=1 EXC_REAL_END(h_instr_storage, 0xe20, 0x20) EXC_VIRT_BEGIN(h_instr_storage, 0x4e20, 0x20) - INT_HANDLER h_instr_storage, 0xe20, ool=1, virt=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY h_instr_storage, virt=1, ool=1 EXC_VIRT_END(h_instr_storage, 0x4e20, 0x20) -INT_KVM_HANDLER h_instr_storage, 0xe20, EXC_HV, PACA_EXGEN, 0 -EXC_COMMON(h_instr_storage_common, 0xe20, unknown_exception) +EXC_COMMON_BEGIN(h_instr_storage_common) + GEN_COMMON h_instr_storage + addi r3,r1,STACK_FRAME_OVERHEAD + bl unknown_exception + b interrupt_return + GEN_KVM h_instr_storage + + +/** + * Interrupt 0xe40 - Hypervisor Emulation Assistance Interrupt. + */ +INT_DEFINE_BEGIN(emulation_assist) + IVEC=0xe40 + IHSRR=1 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(emulation_assist) EXC_REAL_BEGIN(emulation_assist, 0xe40, 0x20) - INT_HANDLER emulation_assist, 0xe40, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY emulation_assist, virt=0, ool=1 EXC_REAL_END(emulation_assist, 0xe40, 0x20) EXC_VIRT_BEGIN(emulation_assist, 0x4e40, 0x20) - INT_HANDLER emulation_assist, 0xe40, ool=1, virt=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY emulation_assist, virt=1, ool=1 EXC_VIRT_END(emulation_assist, 0x4e40, 0x20) -INT_KVM_HANDLER emulation_assist, 0xe40, EXC_HV, PACA_EXGEN, 0 -EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt) +EXC_COMMON_BEGIN(emulation_assist_common) + GEN_COMMON emulation_assist + addi r3,r1,STACK_FRAME_OVERHEAD + bl emulation_assist_interrupt + REST_NVGPRS(r1) /* instruction emulation may change GPRs */ + b interrupt_return + GEN_KVM emulation_assist -/* - * hmi_exception trampoline is a special case. It jumps to hmi_exception_early - * first, and then eventaully from there to the trampoline to get into virtual - * mode. + +/** + * Interrupt 0xe60 - Hypervisor Maintenance Interrupt (HMI). + * This is an asynchronous interrupt caused by a Hypervisor Maintenance + * Exception. It is always taken in real mode but uses HSRR registers + * unlike SRESET and MCE. + * + * It is maskable in hardware by clearing MSR[EE], and partially soft-maskable + * with IRQS_DISABLED mask (i.e., local_irq_disable()). + * + * Handling: + * This is a special case, this is handled similarly to machine checks, with an + * initial real mode handler that is not soft-masked, which attempts to fix the + * problem. Then a regular handler which is soft-maskable and reports the + * problem. + * + * The emergency stack is used for the early real mode handler. + * + * XXX: unclear why MCE and HMI schemes could not be made common, e.g., + * either use soft-masking for the MCE, or use irq_work for the HMI. + * + * KVM: + * Unlike MCE, this calls into KVM without calling the real mode handler + * first. */ +INT_DEFINE_BEGIN(hmi_exception_early) + IVEC=0xe60 + IHSRR=1 + IREALMODE_COMMON=1 + ISTACK=0 + IRECONCILE=0 + IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ + IKVM_REAL=1 +INT_DEFINE_END(hmi_exception_early) + +INT_DEFINE_BEGIN(hmi_exception) + IVEC=0xe60 + IHSRR=1 + IMASK=IRQS_DISABLED + IKVM_REAL=1 +INT_DEFINE_END(hmi_exception) + EXC_REAL_BEGIN(hmi_exception, 0xe60, 0x20) - INT_HANDLER hmi_exception, 0xe60, ool=1, early=1, hsrr=EXC_HV, ri=0, kvm=1 + GEN_INT_ENTRY hmi_exception_early, virt=0, ool=1 EXC_REAL_END(hmi_exception, 0xe60, 0x20) EXC_VIRT_NONE(0x4e60, 0x20) -INT_KVM_HANDLER hmi_exception, 0xe60, EXC_HV, PACA_EXGEN, 0 + EXC_COMMON_BEGIN(hmi_exception_early_common) - mtctr r10 /* Restore ctr */ - mfspr r11,SPRN_HSRR0 /* Save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* Save HSRR1 */ + __GEN_REALMODE_COMMON_ENTRY hmi_exception_early + mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ - /* We don't touch AMR here, we never go to virtual mode */ - INT_COMMON 0xe60, PACA_EXGEN, 0, 0, 0, 0, 0 + __GEN_COMMON_BODY hmi_exception_early addi r3,r1,STACK_FRAME_OVERHEAD bl hmi_exception_realmode cmpdi cr0,r3,0 bne 1f - EXCEPTION_RESTORE_REGS EXC_HV + EXCEPTION_RESTORE_REGS hsrr=1 HRFI_TO_USER_OR_KERNEL 1: @@ -1599,41 +2152,84 @@ EXC_COMMON_BEGIN(hmi_exception_early_common) * Go to virtual mode and pull the HMI event information from * firmware. */ - EXCEPTION_RESTORE_REGS EXC_HV - INT_HANDLER hmi_exception, 0xe60, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1 + EXCEPTION_RESTORE_REGS hsrr=1 + GEN_INT_ENTRY hmi_exception, virt=0 + + GEN_KVM hmi_exception_early EXC_COMMON_BEGIN(hmi_exception_common) - INT_COMMON 0xe60, PACA_EXGEN, 1, 1, 1, 0, 0 + GEN_COMMON hmi_exception FINISH_NAP RUNLATCH_ON - bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl handle_hmi_exception - b ret_from_except + b interrupt_return + + GEN_KVM hmi_exception +/** + * Interrupt 0xe80 - Directed Hypervisor Doorbell Interrupt. + * This is an asynchronous interrupt in response to a msgsnd doorbell. + * Similar to the 0xa00 doorbell but for host rather than guest. + */ +INT_DEFINE_BEGIN(h_doorbell) + IVEC=0xe80 + IHSRR=1 + IMASK=IRQS_DISABLED + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(h_doorbell) + EXC_REAL_BEGIN(h_doorbell, 0xe80, 0x20) - INT_HANDLER h_doorbell, 0xe80, ool=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY h_doorbell, virt=0, ool=1 EXC_REAL_END(h_doorbell, 0xe80, 0x20) EXC_VIRT_BEGIN(h_doorbell, 0x4e80, 0x20) - INT_HANDLER h_doorbell, 0xe80, ool=1, virt=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY h_doorbell, virt=1, ool=1 EXC_VIRT_END(h_doorbell, 0x4e80, 0x20) -INT_KVM_HANDLER h_doorbell, 0xe80, EXC_HV, PACA_EXGEN, 0 +EXC_COMMON_BEGIN(h_doorbell_common) + GEN_COMMON h_doorbell + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL -EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, doorbell_exception) + bl doorbell_exception #else -EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception) + bl unknown_exception #endif + b interrupt_return + + GEN_KVM h_doorbell +/** + * Interrupt 0xea0 - Hypervisor Virtualization Interrupt. + * This is an asynchronous interrupt in response to an "external exception". + * Similar to 0x500 but for host only. + */ +INT_DEFINE_BEGIN(h_virt_irq) + IVEC=0xea0 + IHSRR=1 + IMASK=IRQS_DISABLED + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(h_virt_irq) + EXC_REAL_BEGIN(h_virt_irq, 0xea0, 0x20) - INT_HANDLER h_virt_irq, 0xea0, ool=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY h_virt_irq, virt=0, ool=1 EXC_REAL_END(h_virt_irq, 0xea0, 0x20) EXC_VIRT_BEGIN(h_virt_irq, 0x4ea0, 0x20) - INT_HANDLER h_virt_irq, 0xea0, ool=1, virt=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1 + GEN_INT_ENTRY h_virt_irq, virt=1, ool=1 EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20) -INT_KVM_HANDLER h_virt_irq, 0xea0, EXC_HV, PACA_EXGEN, 0 -EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ) +EXC_COMMON_BEGIN(h_virt_irq_common) + GEN_COMMON h_virt_irq + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_IRQ + b interrupt_return + + GEN_KVM h_virt_irq EXC_REAL_NONE(0xec0, 0x20) @@ -1642,25 +2238,69 @@ EXC_REAL_NONE(0xee0, 0x20) EXC_VIRT_NONE(0x4ee0, 0x20) +/* + * Interrupt 0xf00 - Performance Monitor Interrupt (PMI, PMU). + * This is an asynchronous interrupt in response to a PMU exception. + * It is maskable in hardware by clearing MSR[EE], and soft-maskable with + * IRQS_PMI_DISABLED mask (NOTE: NOT local_irq_disable()). + * + * Handling: + * This calls into the perf subsystem. + * + * Like the watchdog soft-nmi, it appears an NMI interrupt to Linux, in that it + * runs under local_irq_disable. However it may be soft-masked in + * powerpc-specific code. + * + * If soft masked, the masked handler will note the pending interrupt for + * replay, and clear MSR[EE] in the interrupted context. + */ +INT_DEFINE_BEGIN(performance_monitor) + IVEC=0xf00 + IMASK=IRQS_PMI_DISABLED +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(performance_monitor) + EXC_REAL_BEGIN(performance_monitor, 0xf00, 0x20) - INT_HANDLER performance_monitor, 0xf00, ool=1, bitmask=IRQS_PMI_DISABLED, kvm=1 + GEN_INT_ENTRY performance_monitor, virt=0, ool=1 EXC_REAL_END(performance_monitor, 0xf00, 0x20) EXC_VIRT_BEGIN(performance_monitor, 0x4f00, 0x20) - INT_HANDLER performance_monitor, 0xf00, ool=1, virt=1, bitmask=IRQS_PMI_DISABLED + GEN_INT_ENTRY performance_monitor, virt=1, ool=1 EXC_VIRT_END(performance_monitor, 0x4f00, 0x20) -INT_KVM_HANDLER performance_monitor, 0xf00, EXC_STD, PACA_EXGEN, 0 -EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception) +EXC_COMMON_BEGIN(performance_monitor_common) + GEN_COMMON performance_monitor + FINISH_NAP + RUNLATCH_ON + addi r3,r1,STACK_FRAME_OVERHEAD + bl performance_monitor_exception + b interrupt_return + + GEN_KVM performance_monitor +/** + * Interrupt 0xf20 - Vector Unavailable Interrupt. + * This is a synchronous interrupt in response to + * executing a vector (or altivec) instruction with MSR[VEC]=0. + * Similar to FP unavailable. + */ +INT_DEFINE_BEGIN(altivec_unavailable) + IVEC=0xf20 + IRECONCILE=0 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(altivec_unavailable) + EXC_REAL_BEGIN(altivec_unavailable, 0xf20, 0x20) - INT_HANDLER altivec_unavailable, 0xf20, ool=1, kvm=1 + GEN_INT_ENTRY altivec_unavailable, virt=0, ool=1 EXC_REAL_END(altivec_unavailable, 0xf20, 0x20) EXC_VIRT_BEGIN(altivec_unavailable, 0x4f20, 0x20) - INT_HANDLER altivec_unavailable, 0xf20, ool=1, virt=1 + GEN_INT_ENTRY altivec_unavailable, virt=1, ool=1 EXC_VIRT_END(altivec_unavailable, 0x4f20, 0x20) -INT_KVM_HANDLER altivec_unavailable, 0xf20, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(altivec_unavailable_common) - INT_COMMON 0xf20, PACA_EXGEN, 1, 1, 0, 0, 0 + GEN_COMMON altivec_unavailable #ifdef CONFIG_ALTIVEC BEGIN_FTR_SECTION beq 1f @@ -1674,34 +2314,47 @@ BEGIN_FTR_SECTION END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) #endif bl load_up_altivec - b fast_exception_return + b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_tm - b ret_from_except + b interrupt_return #endif 1: END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_exception - b ret_from_except + b interrupt_return + GEN_KVM altivec_unavailable + + +/** + * Interrupt 0xf40 - VSX Unavailable Interrupt. + * This is a synchronous interrupt in response to + * executing a VSX instruction with MSR[VSX]=0. + * Similar to FP unavailable. + */ +INT_DEFINE_BEGIN(vsx_unavailable) + IVEC=0xf40 + IRECONCILE=0 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(vsx_unavailable) EXC_REAL_BEGIN(vsx_unavailable, 0xf40, 0x20) - INT_HANDLER vsx_unavailable, 0xf40, ool=1, kvm=1 + GEN_INT_ENTRY vsx_unavailable, virt=0, ool=1 EXC_REAL_END(vsx_unavailable, 0xf40, 0x20) EXC_VIRT_BEGIN(vsx_unavailable, 0x4f40, 0x20) - INT_HANDLER vsx_unavailable, 0xf40, ool=1, virt=1 + GEN_INT_ENTRY vsx_unavailable, virt=1, ool=1 EXC_VIRT_END(vsx_unavailable, 0x4f40, 0x20) -INT_KVM_HANDLER vsx_unavailable, 0xf40, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_BEGIN(vsx_unavailable_common) - INT_COMMON 0xf40, PACA_EXGEN, 1, 1, 0, 0, 0 + GEN_COMMON vsx_unavailable #ifdef CONFIG_VSX BEGIN_FTR_SECTION beq 1f @@ -1717,40 +2370,78 @@ BEGIN_FTR_SECTION b load_up_vsx #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_tm - b ret_from_except + b interrupt_return #endif 1: END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif - bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_exception - b ret_from_except + b interrupt_return + + GEN_KVM vsx_unavailable + +/** + * Interrupt 0xf60 - Facility Unavailable Interrupt. + * This is a synchronous interrupt in response to + * executing an instruction without access to the facility that can be + * resolved by the OS (e.g., FSCR, MSR). + * Similar to FP unavailable. + */ +INT_DEFINE_BEGIN(facility_unavailable) + IVEC=0xf60 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(facility_unavailable) EXC_REAL_BEGIN(facility_unavailable, 0xf60, 0x20) - INT_HANDLER facility_unavailable, 0xf60, ool=1, kvm=1 + GEN_INT_ENTRY facility_unavailable, virt=0, ool=1 EXC_REAL_END(facility_unavailable, 0xf60, 0x20) EXC_VIRT_BEGIN(facility_unavailable, 0x4f60, 0x20) - INT_HANDLER facility_unavailable, 0xf60, ool=1, virt=1 + GEN_INT_ENTRY facility_unavailable, virt=1, ool=1 EXC_VIRT_END(facility_unavailable, 0x4f60, 0x20) -INT_KVM_HANDLER facility_unavailable, 0xf60, EXC_STD, PACA_EXGEN, 0 -EXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception) +EXC_COMMON_BEGIN(facility_unavailable_common) + GEN_COMMON facility_unavailable + addi r3,r1,STACK_FRAME_OVERHEAD + bl facility_unavailable_exception + b interrupt_return + GEN_KVM facility_unavailable + + +/** + * Interrupt 0xf60 - Hypervisor Facility Unavailable Interrupt. + * This is a synchronous interrupt in response to + * executing an instruction without access to the facility that can only + * be resolved in HV mode (e.g., HFSCR). + * Similar to FP unavailable. + */ +INT_DEFINE_BEGIN(h_facility_unavailable) + IVEC=0xf80 + IHSRR=1 + IKVM_REAL=1 + IKVM_VIRT=1 +INT_DEFINE_END(h_facility_unavailable) EXC_REAL_BEGIN(h_facility_unavailable, 0xf80, 0x20) - INT_HANDLER h_facility_unavailable, 0xf80, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY h_facility_unavailable, virt=0, ool=1 EXC_REAL_END(h_facility_unavailable, 0xf80, 0x20) EXC_VIRT_BEGIN(h_facility_unavailable, 0x4f80, 0x20) - INT_HANDLER h_facility_unavailable, 0xf80, ool=1, virt=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY h_facility_unavailable, virt=1, ool=1 EXC_VIRT_END(h_facility_unavailable, 0x4f80, 0x20) -INT_KVM_HANDLER h_facility_unavailable, 0xf80, EXC_HV, PACA_EXGEN, 0 -EXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception) +EXC_COMMON_BEGIN(h_facility_unavailable_common) + GEN_COMMON h_facility_unavailable + addi r3,r1,STACK_FRAME_OVERHEAD + bl facility_unavailable_exception + b interrupt_return + + GEN_KVM h_facility_unavailable EXC_REAL_NONE(0xfa0, 0x20) @@ -1766,56 +2457,95 @@ EXC_REAL_NONE(0x1100, 0x100) EXC_VIRT_NONE(0x5100, 0x100) #ifdef CONFIG_CBE_RAS +INT_DEFINE_BEGIN(cbe_system_error) + IVEC=0x1200 + IHSRR=1 + IKVM_SKIP=1 + IKVM_REAL=1 +INT_DEFINE_END(cbe_system_error) + EXC_REAL_BEGIN(cbe_system_error, 0x1200, 0x100) - INT_HANDLER cbe_system_error, 0x1200, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY cbe_system_error, virt=0 EXC_REAL_END(cbe_system_error, 0x1200, 0x100) EXC_VIRT_NONE(0x5200, 0x100) -INT_KVM_HANDLER cbe_system_error, 0x1200, EXC_HV, PACA_EXGEN, 1 -EXC_COMMON(cbe_system_error_common, 0x1200, cbe_system_error_exception) +EXC_COMMON_BEGIN(cbe_system_error_common) + GEN_COMMON cbe_system_error + addi r3,r1,STACK_FRAME_OVERHEAD + bl cbe_system_error_exception + b interrupt_return + + GEN_KVM cbe_system_error + #else /* CONFIG_CBE_RAS */ EXC_REAL_NONE(0x1200, 0x100) EXC_VIRT_NONE(0x5200, 0x100) #endif +INT_DEFINE_BEGIN(instruction_breakpoint) + IVEC=0x1300 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_SKIP=1 + IKVM_REAL=1 +#endif +INT_DEFINE_END(instruction_breakpoint) + EXC_REAL_BEGIN(instruction_breakpoint, 0x1300, 0x100) - INT_HANDLER instruction_breakpoint, 0x1300, kvm=1 + GEN_INT_ENTRY instruction_breakpoint, virt=0 EXC_REAL_END(instruction_breakpoint, 0x1300, 0x100) EXC_VIRT_BEGIN(instruction_breakpoint, 0x5300, 0x100) - INT_HANDLER instruction_breakpoint, 0x1300, virt=1 + GEN_INT_ENTRY instruction_breakpoint, virt=1 EXC_VIRT_END(instruction_breakpoint, 0x5300, 0x100) -INT_KVM_HANDLER instruction_breakpoint, 0x1300, EXC_STD, PACA_EXGEN, 1 -EXC_COMMON(instruction_breakpoint_common, 0x1300, instruction_breakpoint_exception) +EXC_COMMON_BEGIN(instruction_breakpoint_common) + GEN_COMMON instruction_breakpoint + addi r3,r1,STACK_FRAME_OVERHEAD + bl instruction_breakpoint_exception + b interrupt_return + + GEN_KVM instruction_breakpoint EXC_REAL_NONE(0x1400, 0x100) EXC_VIRT_NONE(0x5400, 0x100) -EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) - INT_HANDLER denorm_exception_hv, 0x1500, early=2, hsrr=EXC_HV +/** + * Interrupt 0x1500 - Soft Patch Interrupt + * + * Handling: + * This is an implementation specific interrupt which can be used for a + * range of exceptions. + * + * This interrupt handler is unique in that it runs the denormal assist + * code even for guests (and even in guest context) without going to KVM, + * for speed. POWER9 does not raise denorm exceptions, so this special case + * could be phased out in future to reduce special cases. + */ +INT_DEFINE_BEGIN(denorm_exception) + IVEC=0x1500 + IHSRR=1 + IBRANCH_COMMON=0 + IKVM_REAL=1 +INT_DEFINE_END(denorm_exception) + +EXC_REAL_BEGIN(denorm_exception, 0x1500, 0x100) + GEN_INT_ENTRY denorm_exception, virt=0 #ifdef CONFIG_PPC_DENORMALISATION - mfspr r10,SPRN_HSRR1 - andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */ + andis. r10,r12,(HSRR1_DENORM)@h /* denorm? */ bne+ denorm_assist #endif - KVMTEST denorm_exception_hv, EXC_HV 0x1500 - INT_SAVE_SRR_AND_JUMP denorm_common, EXC_HV, 1 -EXC_REAL_END(denorm_exception_hv, 0x1500, 0x100) - + GEN_BRANCH_TO_COMMON denorm_exception, virt=0 +EXC_REAL_END(denorm_exception, 0x1500, 0x100) #ifdef CONFIG_PPC_DENORMALISATION EXC_VIRT_BEGIN(denorm_exception, 0x5500, 0x100) - INT_HANDLER denorm_exception, 0x1500, 0, 2, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 0 - mfspr r10,SPRN_HSRR1 - andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */ + GEN_INT_ENTRY denorm_exception, virt=1 + andis. r10,r12,(HSRR1_DENORM)@h /* denorm? */ bne+ denorm_assist - INT_VIRT_SAVE_SRR_AND_JUMP denorm_common, EXC_HV + GEN_BRANCH_TO_COMMON denorm_exception, virt=1 EXC_VIRT_END(denorm_exception, 0x5500, 0x100) #else EXC_VIRT_NONE(0x5500, 0x100) #endif -INT_KVM_HANDLER denorm_exception_hv, 0x1500, EXC_HV, PACA_EXGEN, 0 - #ifdef CONFIG_PPC_DENORMALISATION TRAMP_REAL_BEGIN(denorm_assist) BEGIN_FTR_SECTION @@ -1872,7 +2602,10 @@ denorm_done: mtspr SPRN_HSRR0,r11 mtcrf 0x80,r9 ld r9,PACA_EXGEN+EX_R9(r13) - RESTORE_PPR_PACA(PACA_EXGEN, r10) +BEGIN_FTR_SECTION + ld r10,PACA_EXGEN+EX_PPR(r13) + mtspr SPRN_PPR,r10 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) BEGIN_FTR_SECTION ld r10,PACA_EXGEN+EX_CFAR(r13) mtspr SPRN_CFAR,r10 @@ -1885,43 +2618,88 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) b . #endif -EXC_COMMON(denorm_common, 0x1500, unknown_exception) +EXC_COMMON_BEGIN(denorm_exception_common) + GEN_COMMON denorm_exception + addi r3,r1,STACK_FRAME_OVERHEAD + bl unknown_exception + b interrupt_return + + GEN_KVM denorm_exception #ifdef CONFIG_CBE_RAS +INT_DEFINE_BEGIN(cbe_maintenance) + IVEC=0x1600 + IHSRR=1 + IKVM_SKIP=1 + IKVM_REAL=1 +INT_DEFINE_END(cbe_maintenance) + EXC_REAL_BEGIN(cbe_maintenance, 0x1600, 0x100) - INT_HANDLER cbe_maintenance, 0x1600, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY cbe_maintenance, virt=0 EXC_REAL_END(cbe_maintenance, 0x1600, 0x100) EXC_VIRT_NONE(0x5600, 0x100) -INT_KVM_HANDLER cbe_maintenance, 0x1600, EXC_HV, PACA_EXGEN, 1 -EXC_COMMON(cbe_maintenance_common, 0x1600, cbe_maintenance_exception) +EXC_COMMON_BEGIN(cbe_maintenance_common) + GEN_COMMON cbe_maintenance + addi r3,r1,STACK_FRAME_OVERHEAD + bl cbe_maintenance_exception + b interrupt_return + + GEN_KVM cbe_maintenance + #else /* CONFIG_CBE_RAS */ EXC_REAL_NONE(0x1600, 0x100) EXC_VIRT_NONE(0x5600, 0x100) #endif +INT_DEFINE_BEGIN(altivec_assist) + IVEC=0x1700 +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + IKVM_REAL=1 +#endif +INT_DEFINE_END(altivec_assist) + EXC_REAL_BEGIN(altivec_assist, 0x1700, 0x100) - INT_HANDLER altivec_assist, 0x1700, kvm=1 + GEN_INT_ENTRY altivec_assist, virt=0 EXC_REAL_END(altivec_assist, 0x1700, 0x100) EXC_VIRT_BEGIN(altivec_assist, 0x5700, 0x100) - INT_HANDLER altivec_assist, 0x1700, virt=1 + GEN_INT_ENTRY altivec_assist, virt=1 EXC_VIRT_END(altivec_assist, 0x5700, 0x100) -INT_KVM_HANDLER altivec_assist, 0x1700, EXC_STD, PACA_EXGEN, 0 +EXC_COMMON_BEGIN(altivec_assist_common) + GEN_COMMON altivec_assist + addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_ALTIVEC -EXC_COMMON(altivec_assist_common, 0x1700, altivec_assist_exception) + bl altivec_assist_exception + REST_NVGPRS(r1) /* instruction emulation may change GPRs */ #else -EXC_COMMON(altivec_assist_common, 0x1700, unknown_exception) + bl unknown_exception #endif + b interrupt_return + + GEN_KVM altivec_assist #ifdef CONFIG_CBE_RAS +INT_DEFINE_BEGIN(cbe_thermal) + IVEC=0x1800 + IHSRR=1 + IKVM_SKIP=1 + IKVM_REAL=1 +INT_DEFINE_END(cbe_thermal) + EXC_REAL_BEGIN(cbe_thermal, 0x1800, 0x100) - INT_HANDLER cbe_thermal, 0x1800, ool=1, hsrr=EXC_HV, kvm=1 + GEN_INT_ENTRY cbe_thermal, virt=0 EXC_REAL_END(cbe_thermal, 0x1800, 0x100) EXC_VIRT_NONE(0x5800, 0x100) -INT_KVM_HANDLER cbe_thermal, 0x1800, EXC_HV, PACA_EXGEN, 1 -EXC_COMMON(cbe_thermal_common, 0x1800, cbe_thermal_exception) +EXC_COMMON_BEGIN(cbe_thermal_common) + GEN_COMMON cbe_thermal + addi r3,r1,STACK_FRAME_OVERHEAD + bl cbe_thermal_exception + b interrupt_return + + GEN_KVM cbe_thermal + #else /* CONFIG_CBE_RAS */ EXC_REAL_NONE(0x1800, 0x100) EXC_VIRT_NONE(0x5800, 0x100) @@ -1930,14 +2708,11 @@ EXC_VIRT_NONE(0x5800, 0x100) #ifdef CONFIG_PPC_WATCHDOG -#define MASKED_DEC_HANDLER_LABEL 3f - -#define MASKED_DEC_HANDLER(_H) \ -3: /* soft-nmi */ \ - std r12,PACA_EXGEN+EX_R12(r13); \ - GET_SCRATCH0(r10); \ - std r10,PACA_EXGEN+EX_R13(r13); \ - INT_SAVE_SRR_AND_JUMP soft_nmi_common, _H, 1 +INT_DEFINE_BEGIN(soft_nmi) + IVEC=0x900 + ISTACK=0 + IRECONCILE=0 /* Soft-NMI may fire under local_irq_disable */ +INT_DEFINE_END(soft_nmi) /* * Branch to soft_nmi_interrupt using the emergency stack. The emergency @@ -1949,18 +2724,42 @@ EXC_VIRT_NONE(0x5800, 0x100) * and run it entirely with interrupts hard disabled. */ EXC_COMMON_BEGIN(soft_nmi_common) + mfspr r11,SPRN_SRR0 mr r10,r1 ld r1,PACAEMERGSP(r13) subi r1,r1,INT_FRAME_SIZE - INT_COMMON 0x900, PACA_EXGEN, 0, 1, 1, 0, 0 - bl save_nvgprs + __GEN_COMMON_BODY soft_nmi + + /* + * Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see + * system_reset_common) + */ + li r10,IRQS_ALL_DISABLED + stb r10,PACAIRQSOFTMASK(r13) + lbz r10,PACAIRQHAPPENED(r13) + std r10,_DAR(r1) + ori r10,r10,PACA_IRQ_HARD_DIS + stb r10,PACAIRQHAPPENED(r13) + addi r3,r1,STACK_FRAME_OVERHEAD bl soft_nmi_interrupt - b ret_from_except -#else /* CONFIG_PPC_WATCHDOG */ -#define MASKED_DEC_HANDLER_LABEL 2f /* normal return */ -#define MASKED_DEC_HANDLER(_H) + /* Clear MSR_RI before setting SRR0 and SRR1. */ + li r9,0 + mtmsrd r9,1 + + /* + * Restore soft mask settings. + */ + ld r10,_DAR(r1) + stb r10,PACAIRQHAPPENED(r13) + ld r10,SOFTE(r1) + stb r10,PACAIRQSOFTMASK(r13) + + kuap_restore_amr r10 + EXCEPTION_RESTORE_REGS hsrr=0 + RFI_TO_KERNEL + #endif /* CONFIG_PPC_WATCHDOG */ /* @@ -1973,13 +2772,12 @@ EXC_COMMON_BEGIN(soft_nmi_common) * - Else it is one of PACA_IRQ_MUST_HARD_MASK, so hard disable and return. * This is called with r10 containing the value to OR to the paca field. */ -.macro MASKED_INTERRUPT hsrr +.macro MASKED_INTERRUPT hsrr=0 .if \hsrr masked_Hinterrupt: .else masked_interrupt: .endif - std r11,PACA_EXGEN+EX_R11(r13) lbz r11,PACAIRQHAPPENED(r13) or r11,r11,r10 stb r11,PACAIRQHAPPENED(r13) @@ -1988,26 +2786,30 @@ masked_interrupt: lis r10,0x7fff ori r10,r10,0xffff mtspr SPRN_DEC,r10 - b MASKED_DEC_HANDLER_LABEL +#ifdef CONFIG_PPC_WATCHDOG + b soft_nmi_common +#else + b 2f +#endif 1: andi. r10,r10,PACA_IRQ_MUST_HARD_MASK beq 2f + xori r12,r12,MSR_EE /* clear MSR_EE */ .if \hsrr - mfspr r10,SPRN_HSRR1 - xori r10,r10,MSR_EE /* clear MSR_EE */ - mtspr SPRN_HSRR1,r10 + mtspr SPRN_HSRR1,r12 .else - mfspr r10,SPRN_SRR1 - xori r10,r10,MSR_EE /* clear MSR_EE */ - mtspr SPRN_SRR1,r10 + mtspr SPRN_SRR1,r12 .endif ori r11,r11,PACA_IRQ_HARD_DIS stb r11,PACAIRQHAPPENED(r13) 2: /* done */ + ld r10,PACA_EXGEN+EX_CTR(r13) + mtctr r10 mtcrf 0x80,r9 std r1,PACAR1(r13) ld r9,PACA_EXGEN+EX_R9(r13) ld r10,PACA_EXGEN+EX_R10(r13) ld r11,PACA_EXGEN+EX_R11(r13) + ld r12,PACA_EXGEN+EX_R12(r13) /* returns to kernel where r13 must be set up, so don't restore it */ .if \hsrr HRFI_TO_KERNEL @@ -2015,7 +2817,6 @@ masked_interrupt: RFI_TO_KERNEL .endif b . - MASKED_DEC_HANDLER(\hsrr\()) .endm TRAMP_REAL_BEGIN(stf_barrier_fallback) @@ -2117,17 +2918,12 @@ TRAMP_REAL_BEGIN(hrfi_flush_fallback) GET_SCRATCH0(r13); hrfid -/* - * Real mode exceptions actually use this too, but alternate - * instruction code patches (which end up in the common .text area) - * cannot reach these if they are put there. - */ -USE_FIXED_SECTION(virt_trampolines) - MASKED_INTERRUPT EXC_STD - MASKED_INTERRUPT EXC_HV +USE_TEXT_SECTION() + MASKED_INTERRUPT + MASKED_INTERRUPT hsrr=1 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER -TRAMP_REAL_BEGIN(kvmppc_skip_interrupt) +kvmppc_skip_interrupt: /* * Here all GPRs are unchanged from when the interrupt happened * except for r13, which is saved in SPRG_SCRATCH0. @@ -2139,7 +2935,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt) RFI_TO_KERNEL b . -TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) +kvmppc_skip_Hinterrupt: /* * Here all GPRs are unchanged from when the interrupt happened * except for r13, which is saved in SPRG_SCRATCH0. @@ -2152,16 +2948,6 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) b . #endif -/* - * Ensure that any handlers that get invoked from the exception prologs - * above are below the first 64KB (0x10000) of the kernel image because - * the prologs assemble the addresses of these handlers using the - * LOAD_HANDLER macro, which uses an ori instruction. - */ - -/*** Common interrupt handlers ***/ - - /* * Relocation-on interrupts: A subset of the interrupts can be delivered * with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering @@ -2275,7 +3061,7 @@ do_hash_page: cmpdi r3,0 /* see if __hash_page succeeded */ /* Success */ - beq fast_exc_return_irq /* Return from exception on success */ + beq interrupt_return /* Return from exception on success */ /* Error */ blt- 13f @@ -2292,39 +3078,36 @@ handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD bl do_page_fault cmpdi r3,0 - beq+ ret_from_except_lite - bl save_nvgprs + beq+ interrupt_return mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD ld r4,_DAR(r1) bl bad_page_fault - b ret_from_except + b interrupt_return /* We have a data breakpoint exception - handle it */ handle_dabr_fault: - bl save_nvgprs ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_break /* * do_break() may have changed the NV GPRS while handling a breakpoint. - * If so, we need to restore them with their updated values. Don't use - * ret_from_except_lite here. + * If so, we need to restore them with their updated values. */ - b ret_from_except + REST_NVGPRS(r1) + b interrupt_return #ifdef CONFIG_PPC_BOOK3S_64 /* We have a page fault that hash_page could handle but HV refused * the PTE insertion */ -13: bl save_nvgprs - mr r5,r3 +13: mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD ld r4,_DAR(r1) bl low_hash_fault - b ret_from_except + b interrupt_return #endif /* @@ -2334,74 +3117,7 @@ handle_dabr_fault: * were soft-disabled. We want to invoke the exception handler for * the access, or panic if there isn't a handler. */ -77: bl save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD +77: addi r3,r1,STACK_FRAME_OVERHEAD li r5,SIGSEGV bl bad_page_fault - b ret_from_except - -/* - * When doorbell is triggered from system reset wakeup, the message is - * not cleared, so it would fire again when EE is enabled. - * - * When coming from local_irq_enable, there may be the same problem if - * we were hard disabled. - * - * Execute msgclr to clear pending exceptions before handling it. - */ -h_doorbell_common_msgclr: - LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36)) - PPC_MSGCLR(3) - b h_doorbell_common - -doorbell_super_common_msgclr: - LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36)) - PPC_MSGCLRP(3) - b doorbell_super_common - -/* - * Called from arch_local_irq_enable when an interrupt needs - * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate - * which kind of interrupt. MSR:EE is already off. We generate a - * stackframe like if a real interrupt had happened. - * - * Note: While MSR:EE is off, we need to make sure that _MSR - * in the generated frame has EE set to 1 or the exception - * handler will not properly re-enable them. - * - * Note that we don't specify LR as the NIP (return address) for - * the interrupt because that would unbalance the return branch - * predictor. - */ -_GLOBAL(__replay_interrupt) - /* We are going to jump to the exception common code which - * will retrieve various register values from the PACA which - * we don't give a damn about, so we don't bother storing them. - */ - mfmsr r12 - LOAD_REG_ADDR(r11, replay_interrupt_return) - mfcr r9 - ori r12,r12,MSR_EE - cmpwi r3,0x900 - beq decrementer_common - cmpwi r3,0x500 -BEGIN_FTR_SECTION - beq h_virt_irq_common -FTR_SECTION_ELSE - beq hardware_interrupt_common -ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300) - cmpwi r3,0xf00 - beq performance_monitor_common -BEGIN_FTR_SECTION - cmpwi r3,0xa00 - beq h_doorbell_common_msgclr - cmpwi r3,0xe60 - beq hmi_exception_common -FTR_SECTION_ELSE - cmpwi r3,0xa00 - beq doorbell_super_common_msgclr -ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) -replay_interrupt_return: - blr - -_ASM_NOKPROBE_SYMBOL(__replay_interrupt) + b interrupt_return diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index ff0114aeba9b..59e60a9a9f5c 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -36,6 +36,8 @@ static struct fw_dump fw_dump; static void __init fadump_reserve_crash_area(u64 base); +struct kobject *fadump_kobj; + #ifndef CONFIG_PRESERVE_FA_DUMP static DEFINE_MUTEX(fadump_mutex); struct fadump_mrange_info crash_mrange_info = { "crash", NULL, 0, 0, 0 }; @@ -1323,9 +1325,9 @@ static void fadump_invalidate_release_mem(void) fw_dump.ops->fadump_init_mem_struct(&fw_dump); } -static ssize_t fadump_release_memory_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t release_mem_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) { int input = -1; @@ -1350,23 +1352,40 @@ static ssize_t fadump_release_memory_store(struct kobject *kobj, return count; } -static ssize_t fadump_enabled_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) +/* Release the reserved memory and disable the FADump */ +static void unregister_fadump(void) +{ + fadump_cleanup(); + fadump_release_memory(fw_dump.reserve_dump_area_start, + fw_dump.reserve_dump_area_size); + fw_dump.fadump_enabled = 0; + kobject_put(fadump_kobj); +} + +static ssize_t enabled_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", fw_dump.fadump_enabled); } -static ssize_t fadump_register_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) +static ssize_t mem_reserved_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%ld\n", fw_dump.reserve_dump_area_size); +} + +static ssize_t registered_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", fw_dump.dump_registered); } -static ssize_t fadump_register_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t registered_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) { int ret = 0; int input = -1; @@ -1418,45 +1437,82 @@ static int fadump_region_show(struct seq_file *m, void *private) return 0; } -static struct kobj_attribute fadump_release_attr = __ATTR(fadump_release_mem, - 0200, NULL, - fadump_release_memory_store); -static struct kobj_attribute fadump_attr = __ATTR(fadump_enabled, - 0444, fadump_enabled_show, - NULL); -static struct kobj_attribute fadump_register_attr = __ATTR(fadump_registered, - 0644, fadump_register_show, - fadump_register_store); +static struct kobj_attribute release_attr = __ATTR_WO(release_mem); +static struct kobj_attribute enable_attr = __ATTR_RO(enabled); +static struct kobj_attribute register_attr = __ATTR_RW(registered); +static struct kobj_attribute mem_reserved_attr = __ATTR_RO(mem_reserved); + +static struct attribute *fadump_attrs[] = { + &enable_attr.attr, + ®ister_attr.attr, + &mem_reserved_attr.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(fadump); DEFINE_SHOW_ATTRIBUTE(fadump_region); static void fadump_init_files(void) { - struct dentry *debugfs_file; int rc = 0; - rc = sysfs_create_file(kernel_kobj, &fadump_attr.attr); - if (rc) - printk(KERN_ERR "fadump: unable to create sysfs file" - " fadump_enabled (%d)\n", rc); + fadump_kobj = kobject_create_and_add("fadump", kernel_kobj); + if (!fadump_kobj) { + pr_err("failed to create fadump kobject\n"); + return; + } - rc = sysfs_create_file(kernel_kobj, &fadump_register_attr.attr); - if (rc) - printk(KERN_ERR "fadump: unable to create sysfs file" - " fadump_registered (%d)\n", rc); + debugfs_create_file("fadump_region", 0444, powerpc_debugfs_root, NULL, + &fadump_region_fops); - debugfs_file = debugfs_create_file("fadump_region", 0444, - powerpc_debugfs_root, NULL, - &fadump_region_fops); - if (!debugfs_file) - printk(KERN_ERR "fadump: unable to create debugfs file" - " fadump_region\n"); + if (fw_dump.dump_active) { + rc = sysfs_create_file(fadump_kobj, &release_attr.attr); + if (rc) + pr_err("unable to create release_mem sysfs file (%d)\n", + rc); + } + + rc = sysfs_create_groups(fadump_kobj, fadump_groups); + if (rc) { + pr_err("sysfs group creation failed (%d), unregistering FADump", + rc); + unregister_fadump(); + return; + } + + /* + * The FADump sysfs are moved from kernel_kobj to fadump_kobj need to + * create symlink at old location to maintain backward compatibility. + * + * - fadump_enabled -> fadump/enabled + * - fadump_registered -> fadump/registered + * - fadump_release_mem -> fadump/release_mem + */ + rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, fadump_kobj, + "enabled", "fadump_enabled"); + if (rc) { + pr_err("unable to create fadump_enabled symlink (%d)", rc); + return; + } + + rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, fadump_kobj, + "registered", + "fadump_registered"); + if (rc) { + pr_err("unable to create fadump_registered symlink (%d)", rc); + sysfs_remove_link(kernel_kobj, "fadump_enabled"); + return; + } if (fw_dump.dump_active) { - rc = sysfs_create_file(kernel_kobj, &fadump_release_attr.attr); + rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, + fadump_kobj, + "release_mem", + "fadump_release_mem"); if (rc) - printk(KERN_ERR "fadump: unable to create sysfs file" - " fadump_release_mem (%d)\n", rc); + pr_err("unable to create fadump_release_mem symlink (%d)", + rc); } return; } diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 97c887950c3c..daaa153950c2 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -348,7 +348,7 @@ BEGIN_MMU_FTR_SECTION andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h #endif bne handle_page_fault_tramp_2 /* if not, try to put a PTE */ - rlwinm r3, r5, 32 - 15, 21, 21 /* DSISR_STORE -> _PAGE_RW */ + rlwinm r3, r5, 32 - 24, 30, 30 /* DSISR_STORE -> _PAGE_RW */ bl hash_page b handle_page_fault_tramp_1 FTR_SECTION_ELSE @@ -497,7 +497,6 @@ InstructionTLBMiss: andc. r1,r1,r0 /* check access & ~permission */ bne- InstructionAddressInvalid /* return if access not permitted */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ ori r1, r1, 0xe06 /* clear out reserved bits */ andc r1, r0, r1 /* PP = user? 1 : 0 */ BEGIN_FTR_SECTION @@ -565,9 +564,8 @@ DataLoadTLBMiss: * we would need to update the pte atomically with lwarx/stwcx. */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r1,r0,32-9,30,30 /* _PAGE_RW -> PP msb */ - rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ - rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */ + rlwinm r1,r0,0,30,30 /* _PAGE_RW -> PP msb */ + rlwimi r0,r0,1,30,30 /* _PAGE_USER -> PP msb */ ori r1,r1,0xe04 /* clear out reserved bits */ andc r1,r0,r1 /* PP = user? rw? 1: 3: 0 */ BEGIN_FTR_SECTION @@ -645,7 +643,6 @@ DataStoreTLBMiss: * we would need to update the pte atomically with lwarx/stwcx. */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ li r1,0xe06 /* clear out reserved bits & PP msb */ andc r1,r0,r1 /* PP = user? 1: 0 */ BEGIN_FTR_SECTION diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index 9db162f79fe6..9abec6cd099c 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -130,37 +130,36 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) .macro SYSCALL_ENTRY trapno mfspr r12,SPRN_SPRG_THREAD + mfspr r9, SPRN_SRR1 #ifdef CONFIG_VMAP_STACK - mfspr r9, SPRN_SRR0 - mfspr r11, SPRN_SRR1 - stw r9, SRR0(r12) - stw r11, SRR1(r12) + mfspr r11, SPRN_SRR0 + mtctr r11 #endif - mfcr r10 + andi. r11, r9, MSR_PR lwz r11,TASK_STACK-THREAD(r12) - rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ + beq- 99f addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE #ifdef CONFIG_VMAP_STACK - li r9, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ - mtmsr r9 + li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ + mtmsr r10 isync #endif tovirt_vmstack r12, r12 tophys_novmstack r11, r11 - mflr r9 - stw r10,_CCR(r11) /* save registers */ - stw r9, _LINK(r11) + mflr r10 + stw r10, _LINK(r11) #ifdef CONFIG_VMAP_STACK - lwz r10, SRR0(r12) - lwz r9, SRR1(r12) + mfctr r10 #else mfspr r10,SPRN_SRR0 - mfspr r9,SPRN_SRR1 #endif stw r1,GPR1(r11) stw r1,0(r11) tovirt_novmstack r1, r11 /* set new kernel sp */ stw r10,_NIP(r11) + mfcr r10 + rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ + stw r10,_CCR(r11) /* save registers */ #ifdef CONFIG_40x rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ #else @@ -228,6 +227,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) mtspr SPRN_SRR0,r11 SYNC RFI /* jump to handler, enable MMU */ +99: b ret_from_kernel_syscall .endm .macro save_dar_dsisr_on_stack reg1, reg2, sp diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index ad79fddb974d..ddfbd02140d9 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -537,6 +537,7 @@ __start_initialization_multiplatform: b __after_prom_start #endif /* CONFIG_PPC_BOOK3E */ +__REF __boot_from_prom: #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE /* Save parameters */ @@ -574,6 +575,7 @@ __boot_from_prom: /* We never return. We also hit that trap if trying to boot * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ trap + .previous __after_prom_start: #ifdef CONFIG_RELOCATABLE @@ -977,7 +979,6 @@ start_here_multiplatform: RFI b . /* prevent speculative execution */ - .previous /* This is where all platforms converge execution */ start_here_common: @@ -1001,6 +1002,7 @@ start_here_common: /* Not reached */ trap EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 + .previous /* * We put a few things here that have to be page-aligned. diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 37fc84ed90e3..bd2e5ed8dd50 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -104,16 +104,18 @@ FTR_SECTION_ELSE #ifdef CONFIG_KVM_BOOKE_HV ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #endif + mfspr r9, SPRN_SRR1 BOOKE_CLEAR_BTB(r11) + andi. r11, r9, MSR_PR lwz r11, TASK_STACK - THREAD(r10) rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */ + beq- 99f ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE) stw r12, _CCR(r11) /* save various registers */ mflr r12 stw r12,_LINK(r11) mfspr r12,SPRN_SRR0 stw r1, GPR1(r11) - mfspr r9,SPRN_SRR1 stw r1, 0(r11) mr r1, r11 stw r12,_NIP(r11) @@ -176,6 +178,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) mtspr SPRN_SRR0,r11 SYNC RFI /* jump to handler, enable MMU */ +99: b ret_from_kernel_syscall .endm /* To handle the additional exception priority levels on 40x and Book-E diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index d0854320bb50..72f461bd70fb 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -429,3 +429,19 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) { /* TODO */ } + +void ptrace_triggered(struct perf_event *bp, + struct perf_sample_data *data, struct pt_regs *regs) +{ + struct perf_event_attr attr; + + /* + * Disable the breakpoint request here since ptrace has defined a + * one-shot behaviour for breakpoint exceptions in PPC64. + * The SIGTRAP signal is generated automatically for us in do_dabr(). + * We don't have to do anything about that here + */ + attr = bp->attr; + attr.disabled = true; + modify_user_hw_breakpoint(bp, &attr); +} diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5c9b11878555..1f1169856dc8 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -70,6 +70,7 @@ #include <asm/paca.h> #include <asm/firmware.h> #include <asm/lv1call.h> +#include <asm/dbell.h> #endif #define CREATE_TRACE_POINTS #include <asm/trace.h> @@ -109,6 +110,8 @@ static inline notrace int decrementer_check_overflow(void) return now >= *next_tb; } +#ifdef CONFIG_PPC_BOOK3E + /* This is called whenever we are re-enabling interrupts * and returns either 0 (nothing to do) or 500/900/280/a00/e80 if * there's an EE, DEC or DBELL to generate. @@ -168,6 +171,67 @@ notrace unsigned int __check_irq_replay(void) } } + if (happened & PACA_IRQ_DEC) { + local_paca->irq_happened &= ~PACA_IRQ_DEC; + return 0x900; + } + + if (happened & PACA_IRQ_EE) { + local_paca->irq_happened &= ~PACA_IRQ_EE; + return 0x500; + } + + /* + * Check if an EPR external interrupt happened this bit is typically + * set if we need to handle another "edge" interrupt from within the + * MPIC "EPR" handler. + */ + if (happened & PACA_IRQ_EE_EDGE) { + local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; + return 0x500; + } + + if (happened & PACA_IRQ_DBELL) { + local_paca->irq_happened &= ~PACA_IRQ_DBELL; + return 0x280; + } + + /* There should be nothing left ! */ + BUG_ON(local_paca->irq_happened != 0); + + return 0; +} +#endif /* CONFIG_PPC_BOOK3E */ + +void replay_soft_interrupts(void) +{ + /* + * We use local_paca rather than get_paca() to avoid all + * the debug_smp_processor_id() business in this low level + * function + */ + unsigned char happened = local_paca->irq_happened; + struct pt_regs regs; + + ppc_save_regs(®s); + regs.softe = IRQS_ALL_DISABLED; + +again: + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) + WARN_ON_ONCE(mfmsr() & MSR_EE); + + if (happened & PACA_IRQ_HARD_DIS) { + /* + * We may have missed a decrementer interrupt if hard disabled. + * Check the decrementer register in case we had a rollover + * while hard disabled. + */ + if (!(happened & PACA_IRQ_DEC)) { + if (decrementer_check_overflow()) + happened |= PACA_IRQ_DEC; + } + } + /* * Force the delivery of pending soft-disabled interrupts on PS3. * Any HV call will have this side effect. @@ -182,58 +246,78 @@ notrace unsigned int __check_irq_replay(void) * This is a higher priority interrupt than the others, so * replay it first. */ - if (happened & PACA_IRQ_HMI) { + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_HMI)) { local_paca->irq_happened &= ~PACA_IRQ_HMI; - return 0xe60; + regs.trap = 0xe60; + handle_hmi_exception(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); } if (happened & PACA_IRQ_DEC) { local_paca->irq_happened &= ~PACA_IRQ_DEC; - return 0x900; - } - - if (happened & PACA_IRQ_PMI) { - local_paca->irq_happened &= ~PACA_IRQ_PMI; - return 0xf00; + regs.trap = 0x900; + timer_interrupt(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); } if (happened & PACA_IRQ_EE) { local_paca->irq_happened &= ~PACA_IRQ_EE; - return 0x500; + regs.trap = 0x500; + do_IRQ(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); } -#ifdef CONFIG_PPC_BOOK3E /* * Check if an EPR external interrupt happened this bit is typically * set if we need to handle another "edge" interrupt from within the * MPIC "EPR" handler. */ - if (happened & PACA_IRQ_EE_EDGE) { + if (IS_ENABLED(CONFIG_PPC_BOOK3E) && (happened & PACA_IRQ_EE_EDGE)) { local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; - return 0x500; + regs.trap = 0x500; + do_IRQ(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); } - if (happened & PACA_IRQ_DBELL) { + if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) { local_paca->irq_happened &= ~PACA_IRQ_DBELL; - return 0x280; + if (IS_ENABLED(CONFIG_PPC_BOOK3E)) + regs.trap = 0x280; + else + regs.trap = 0xa00; + doorbell_exception(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); } -#else - if (happened & PACA_IRQ_DBELL) { - local_paca->irq_happened &= ~PACA_IRQ_DBELL; - return 0xa00; - } -#endif /* CONFIG_PPC_BOOK3E */ - /* There should be nothing left ! */ - BUG_ON(local_paca->irq_happened != 0); + /* Book3E does not support soft-masking PMI interrupts */ + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_PMI)) { + local_paca->irq_happened &= ~PACA_IRQ_PMI; + regs.trap = 0xf00; + performance_monitor_exception(®s); + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) + hard_irq_disable(); + } - return 0; + happened = local_paca->irq_happened; + if (happened & ~PACA_IRQ_HARD_DIS) { + /* + * We are responding to the next interrupt, so interrupt-off + * latencies should be reset here. + */ + trace_hardirqs_on(); + trace_hardirqs_off(); + goto again; + } } notrace void arch_local_irq_restore(unsigned long mask) { unsigned char irq_happened; - unsigned int replay; /* Write the new soft-enabled value */ irq_soft_mask_set(mask); @@ -255,24 +339,16 @@ notrace void arch_local_irq_restore(unsigned long mask) */ irq_happened = get_irq_happened(); if (!irq_happened) { -#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON_ONCE(!(mfmsr() & MSR_EE)); -#endif + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); return; } - /* - * We need to hard disable to get a trusted value from - * __check_irq_replay(). We also need to soft-disable - * again to avoid warnings in there due to the use of - * per-cpu variables. - */ + /* We need to hard disable to replay. */ if (!(irq_happened & PACA_IRQ_HARD_DIS)) { -#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON_ONCE(!(mfmsr() & MSR_EE)); -#endif + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); __hard_irq_disable(); -#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG } else { /* * We should already be hard disabled here. We had bugs @@ -280,35 +356,26 @@ notrace void arch_local_irq_restore(unsigned long mask) * warn if we are wrong. Only do that when IRQ tracing * is enabled as mfmsr() can be costly. */ - if (WARN_ON_ONCE(mfmsr() & MSR_EE)) - __hard_irq_disable(); -#endif + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { + if (WARN_ON_ONCE(mfmsr() & MSR_EE)) + __hard_irq_disable(); + } + + if (irq_happened == PACA_IRQ_HARD_DIS) { + local_paca->irq_happened = 0; + __hard_irq_enable(); + return; + } } irq_soft_mask_set(IRQS_ALL_DISABLED); trace_hardirqs_off(); - /* - * Check if anything needs to be re-emitted. We haven't - * soft-enabled yet to avoid warnings in decrementer_check_overflow - * accessing per-cpu variables - */ - replay = __check_irq_replay(); + replay_soft_interrupts(); + local_paca->irq_happened = 0; - /* We can soft-enable now */ trace_hardirqs_on(); irq_soft_mask_set(IRQS_ENABLED); - - /* - * And replay if we have to. This will return with interrupts - * hard-enabled. - */ - if (replay) { - __replay_interrupt(replay); - return; - } - - /* Finally, let's ensure we are hard enabled */ __hard_irq_enable(); } EXPORT_SYMBOL(arch_local_irq_restore); @@ -460,6 +527,19 @@ void irq_set_pending_from_srr1(unsigned long srr1) return; } + if (reason == PACA_IRQ_DBELL) { + /* + * When doorbell triggers a system reset wakeup, the message + * is not cleared, so if the doorbell interrupt is replayed + * and the IPI handled, the doorbell interrupt would still + * fire when EE is enabled. + * + * To avoid taking the superfluous doorbell interrupt, + * execute a msgclr here before the interrupt is replayed. + */ + ppc_msgclr(PPC_DBELL_MSGTYPE); + } + /* * The 0 index (SRR1[42:45]=b0000) must always evaluate to 0, * so this can be called unconditionally with the SRR1 wake @@ -599,17 +679,18 @@ u64 arch_irq_stat_cpu(unsigned int cpu) static inline void check_stack_overflow(void) { -#ifdef CONFIG_DEBUG_STACKOVERFLOW long sp; - sp = current_stack_pointer() & (THREAD_SIZE-1); + if (!IS_ENABLED(CONFIG_DEBUG_STACKOVERFLOW)) + return; + + sp = current_stack_pointer & (THREAD_SIZE - 1); /* check for stack overflow: is there less than 2KB free? */ if (unlikely(sp < 2048)) { pr_err("do_IRQ: stack overflow: %ld\n", sp); dump_stack(); } -#endif } void __do_irq(struct pt_regs *regs) @@ -647,7 +728,7 @@ void do_IRQ(struct pt_regs *regs) void *cursp, *irqsp, *sirqsp; /* Switch to the irq stack to handle this */ - cursp = (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1)); + cursp = (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); irqsp = hardirq_ctx[raw_smp_processor_id()]; sirqsp = softirq_ctx[raw_smp_processor_id()]; diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 2d27ec4feee4..81efb605113e 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -264,6 +264,9 @@ int kprobe_handler(struct pt_regs *regs) if (user_mode(regs)) return 0; + if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR)) + return 0; + /* * We don't want to be preempted for the entire * duration of kprobe processing @@ -271,54 +274,6 @@ int kprobe_handler(struct pt_regs *regs) preempt_disable(); kcb = get_kprobe_ctlblk(); - /* Check we're not actually recursing */ - if (kprobe_running()) { - p = get_kprobe(addr); - if (p) { - kprobe_opcode_t insn = *p->ainsn.insn; - if (kcb->kprobe_status == KPROBE_HIT_SS && - is_trap(insn)) { - /* Turn off 'trace' bits */ - regs->msr &= ~MSR_SINGLESTEP; - regs->msr |= kcb->kprobe_saved_msr; - goto no_kprobe; - } - /* We have reentered the kprobe_handler(), since - * another probe was hit while within the handler. - * We here save the original kprobes variables and - * just single step on the instruction of the new probe - * without calling any user handlers. - */ - save_previous_kprobe(kcb); - set_current_kprobe(p, regs, kcb); - kprobes_inc_nmissed_count(p); - kcb->kprobe_status = KPROBE_REENTER; - if (p->ainsn.boostable >= 0) { - ret = try_to_emulate(p, regs); - - if (ret > 0) { - restore_previous_kprobe(kcb); - preempt_enable_no_resched(); - return 1; - } - } - prepare_singlestep(p, regs); - return 1; - } else if (*addr != BREAKPOINT_INSTRUCTION) { - /* If trap variant, then it belongs not to us */ - kprobe_opcode_t cur_insn = *addr; - - if (is_trap(cur_insn)) - goto no_kprobe; - /* The breakpoint instruction was removed by - * another cpu right after we hit, no further - * handling of this interrupt is appropriate - */ - ret = 1; - } - goto no_kprobe; - } - p = get_kprobe(addr); if (!p) { if (*addr != BREAKPOINT_INSTRUCTION) { @@ -343,6 +298,39 @@ int kprobe_handler(struct pt_regs *regs) goto no_kprobe; } + /* Check we're not actually recursing */ + if (kprobe_running()) { + kprobe_opcode_t insn = *p->ainsn.insn; + if (kcb->kprobe_status == KPROBE_HIT_SS && is_trap(insn)) { + /* Turn off 'trace' bits */ + regs->msr &= ~MSR_SINGLESTEP; + regs->msr |= kcb->kprobe_saved_msr; + goto no_kprobe; + } + + /* + * We have reentered the kprobe_handler(), since another probe + * was hit while within the handler. We here save the original + * kprobes variables and just single step on the instruction of + * the new probe without calling any user handlers. + */ + save_previous_kprobe(kcb); + set_current_kprobe(p, regs, kcb); + kprobes_inc_nmissed_count(p); + kcb->kprobe_status = KPROBE_REENTER; + if (p->ainsn.boostable >= 0) { + ret = try_to_emulate(p, regs); + + if (ret > 0) { + restore_previous_kprobe(kcb); + preempt_enable_no_resched(); + return 1; + } + } + prepare_singlestep(p, regs); + return 1; + } + kcb->kprobe_status = KPROBE_HIT_ACTIVE; set_current_kprobe(p, regs, kcb); if (p->pre_handler && p->pre_handler(p, regs)) { diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index 34c1001e9e8b..8077b5fb18a7 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -15,6 +15,7 @@ #include <linux/percpu.h> #include <linux/export.h> #include <linux/irq_work.h> +#include <linux/extable.h> #include <asm/machdep.h> #include <asm/mce.h> @@ -251,6 +252,19 @@ void machine_check_queue_event(void) /* Queue irq work to process this event later. */ irq_work_queue(&mce_event_process_work); } + +void mce_common_process_ue(struct pt_regs *regs, + struct mce_error_info *mce_err) +{ + const struct exception_table_entry *entry; + + entry = search_kernel_exception_table(regs->nip); + if (entry) { + mce_err->ignore_event = true; + regs->nip = extable_fixup(entry); + } +} + /* * process pending MCE event from the mce event queue. This function will be * called during syscall exit. diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 1cbf7f1a4e3d..067b094bfeff 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -579,14 +579,10 @@ static long mce_handle_ue_error(struct pt_regs *regs, struct mce_error_info *mce_err) { long handled = 0; - const struct exception_table_entry *entry; - entry = search_kernel_exception_table(regs->nip); - if (entry) { - mce_err->ignore_event = true; - regs->nip = extable_fixup(entry); + mce_common_process_ue(regs, mce_err); + if (mce_err->ignore_event) return 1; - } /* * On specific SCOM read via MMIO we may get a machine check diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index 974f65f79a8e..65f9f731c229 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S @@ -110,7 +110,7 @@ _GLOBAL(longjmp) li r3, 1 blr -_GLOBAL(current_stack_pointer) +_GLOBAL(current_stack_frame) PPC_LL r3,0(r1) blr -EXPORT_SYMBOL(current_stack_pointer) +EXPORT_SYMBOL(current_stack_frame) diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 427fc22f72b6..71a3f97dc988 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -62,13 +62,9 @@ static int of_pci_phb_probe(struct platform_device *dev) /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); - /* Create EEH devices for the PHB */ + /* Create EEH PEs for the PHB */ eeh_dev_phb_init_dynamic(phb); - /* Register devices with EEH */ - if (dev->dev.of_node->child) - eeh_add_device_tree_early(PCI_DN(dev->dev.of_node)); - /* Scan the bus */ pcibios_scan_phb(phb); if (phb->bus == NULL) @@ -80,15 +76,9 @@ static int of_pci_phb_probe(struct platform_device *dev) */ pcibios_claim_one_bus(phb->bus); - /* Finish EEH setup */ - eeh_add_device_tree_late(phb->bus); - /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); - /* sysfs files should only be added after devices are added */ - eeh_add_sysfs_files(phb->bus); - return 0; } diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 949eceb254d8..3f91ccaa9c74 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -176,7 +176,7 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit) struct paca_struct **paca_ptrs __read_mostly; EXPORT_SYMBOL(paca_ptrs); -void __init initialise_paca(struct paca_struct *new_paca, int cpu) +void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu) { #ifdef CONFIG_PPC_PSERIES new_paca->lppaca_ptr = NULL; @@ -205,7 +205,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) } /* Put the paca pointer into r13 and SPRG_PACA */ -void setup_paca(struct paca_struct *new_paca) +void __nostackprotector setup_paca(struct paca_struct *new_paca) { /* Setup r13 */ local_paca = new_paca; @@ -214,11 +214,15 @@ void setup_paca(struct paca_struct *new_paca) /* On Book3E, initialize the TLB miss exception frames */ mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); #else - /* In HV mode, we setup both HPACA and PACA to avoid problems + /* + * In HV mode, we setup both HPACA and PACA to avoid problems * if we do a GET_PACA() before the feature fixups have been - * applied + * applied. + * + * Normally you should test against CPU_FTR_HVMODE, but CPU features + * are not yet set up when we first reach here. */ - if (early_cpu_has_feature(CPU_FTR_HVMODE)) + if (mfmsr() & MSR_HV) mtspr(SPRN_SPRG_HPACA, local_paca); #endif mtspr(SPRN_SPRG_PACA, local_paca); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index c6c03416a151..be108616a721 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -728,7 +728,7 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", range.cpu_addr, range.cpu_addr + range.size - 1, range.pci_addr, - (range.pci_space & 0x40000000) ? + (range.flags & IORESOURCE_PREFETCH) ? "Prefetch" : ""); /* We support only 3 memory ranges */ @@ -1399,14 +1399,8 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) pci_assign_unassigned_bus_resources(bus); } - /* Fixup EEH */ - eeh_add_device_tree_late(bus); - /* Add new devices to global lists. Register in proc, sysfs. */ pci_bus_add_devices(bus); - - /* sysfs files should only be added after devices are added */ - eeh_add_sysfs_files(bus); } EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index d6a67f814983..bf83f76563a3 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -112,8 +112,6 @@ void pci_hp_add_devices(struct pci_bus *bus) struct pci_controller *phb; struct device_node *dn = pci_bus_to_OF_node(bus); - eeh_add_device_tree_early(PCI_DN(dn)); - phb = pci_bus_to_host(bus); mode = PCI_PROBE_NORMAL; diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index f3bd0bbf2ae8..2d4d21bb46a9 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -55,14 +55,17 @@ _GLOBAL(ppc_save_regs) PPC_STL r29,29*SZL(r3) PPC_STL r30,30*SZL(r3) PPC_STL r31,31*SZL(r3) + lbz r0,PACAIRQSOFTMASK(r13) + PPC_STL r0,SOFTE-STACK_FRAME_OVERHEAD(r3) #endif /* go up one stack frame for SP */ PPC_LL r4,0(r1) PPC_STL r4,1*SZL(r3) /* get caller's LR */ PPC_LL r0,LRSAVE(r4) - PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) + mflr r0 + PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) mfmsr r0 PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) mfctr r0 @@ -73,4 +76,5 @@ _GLOBAL(ppc_save_regs) PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) li r0,0 PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,ORIG_GPR3-STACK_FRAME_OVERHEAD(r3) blr diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index fad50db9dcf2..9c21288f8645 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -236,23 +236,9 @@ void enable_kernel_fp(void) } } EXPORT_SYMBOL(enable_kernel_fp); - -static int restore_fp(struct task_struct *tsk) -{ - if (tsk->thread.load_fp) { - load_fp_state(¤t->thread.fp_state); - current->thread.load_fp++; - return 1; - } - return 0; -} -#else -static int restore_fp(struct task_struct *tsk) { return 0; } #endif /* CONFIG_PPC_FPU */ #ifdef CONFIG_ALTIVEC -#define loadvec(thr) ((thr).load_vec) - static void __giveup_altivec(struct task_struct *tsk) { unsigned long msr; @@ -318,21 +304,6 @@ void flush_altivec_to_thread(struct task_struct *tsk) } } EXPORT_SYMBOL_GPL(flush_altivec_to_thread); - -static int restore_altivec(struct task_struct *tsk) -{ - if (cpu_has_feature(CPU_FTR_ALTIVEC) && (tsk->thread.load_vec)) { - load_vr_state(&tsk->thread.vr_state); - tsk->thread.used_vr = 1; - tsk->thread.load_vec++; - - return 1; - } - return 0; -} -#else -#define loadvec(thr) 0 -static inline int restore_altivec(struct task_struct *tsk) { return 0; } #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX @@ -400,18 +371,6 @@ void flush_vsx_to_thread(struct task_struct *tsk) } } EXPORT_SYMBOL_GPL(flush_vsx_to_thread); - -static int restore_vsx(struct task_struct *tsk) -{ - if (cpu_has_feature(CPU_FTR_VSX)) { - tsk->thread.used_vsr = 1; - return 1; - } - - return 0; -} -#else -static inline int restore_vsx(struct task_struct *tsk) { return 0; } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE @@ -511,6 +470,53 @@ void giveup_all(struct task_struct *tsk) } EXPORT_SYMBOL(giveup_all); +#ifdef CONFIG_PPC_BOOK3S_64 +#ifdef CONFIG_PPC_FPU +static int restore_fp(struct task_struct *tsk) +{ + if (tsk->thread.load_fp) { + load_fp_state(¤t->thread.fp_state); + current->thread.load_fp++; + return 1; + } + return 0; +} +#else +static int restore_fp(struct task_struct *tsk) { return 0; } +#endif /* CONFIG_PPC_FPU */ + +#ifdef CONFIG_ALTIVEC +#define loadvec(thr) ((thr).load_vec) +static int restore_altivec(struct task_struct *tsk) +{ + if (cpu_has_feature(CPU_FTR_ALTIVEC) && (tsk->thread.load_vec)) { + load_vr_state(&tsk->thread.vr_state); + tsk->thread.used_vr = 1; + tsk->thread.load_vec++; + + return 1; + } + return 0; +} +#else +#define loadvec(thr) 0 +static inline int restore_altivec(struct task_struct *tsk) { return 0; } +#endif /* CONFIG_ALTIVEC */ + +#ifdef CONFIG_VSX +static int restore_vsx(struct task_struct *tsk) +{ + if (cpu_has_feature(CPU_FTR_VSX)) { + tsk->thread.used_vsr = 1; + return 1; + } + + return 0; +} +#else +static inline int restore_vsx(struct task_struct *tsk) { return 0; } +#endif /* CONFIG_VSX */ + /* * The exception exit path calls restore_math() with interrupts hard disabled * but the soft irq state not "reconciled". ftrace code that calls @@ -551,6 +557,7 @@ void notrace restore_math(struct pt_regs *regs) regs->msr = msr; } +#endif static void save_all(struct task_struct *tsk) { @@ -1634,11 +1641,9 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp, p->thread.regs = childregs; childregs->gpr[3] = 0; /* Result from fork() */ if (clone_flags & CLONE_SETTLS) { -#ifdef CONFIG_PPC64 if (!is_32bit_task()) childregs->gpr[13] = tls; else -#endif childregs->gpr[2] = tls; } @@ -1976,6 +1981,32 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, return 0; } +static inline int valid_emergency_stack(unsigned long sp, struct task_struct *p, + unsigned long nbytes) +{ +#ifdef CONFIG_PPC64 + unsigned long stack_page; + unsigned long cpu = task_cpu(p); + + stack_page = (unsigned long)paca_ptrs[cpu]->emergency_sp - THREAD_SIZE; + if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; + +# ifdef CONFIG_PPC_BOOK3S_64 + stack_page = (unsigned long)paca_ptrs[cpu]->nmi_emergency_sp - THREAD_SIZE; + if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; + + stack_page = (unsigned long)paca_ptrs[cpu]->mc_emergency_sp - THREAD_SIZE; + if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; +# endif +#endif + + return 0; +} + + int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { @@ -1987,7 +2018,10 @@ int validate_sp(unsigned long sp, struct task_struct *p, if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) return 1; - return valid_irq_stack(sp, p, nbytes); + if (valid_irq_stack(sp, p, nbytes)) + return 1; + + return valid_emergency_stack(sp, p, nbytes); } EXPORT_SYMBOL(validate_sp); @@ -2053,7 +2087,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) sp = (unsigned long) stack; if (sp == 0) { if (tsk == current) - sp = current_stack_pointer(); + sp = current_stack_frame(); else sp = tsk->thread.ksp; } diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 577345382b23..806be751c336 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1773,6 +1773,9 @@ static void __init prom_rtas_os_term(char *str) if (token == 0) prom_panic("Could not get token for ibm,os-term\n"); os_term_args.token = cpu_to_be32(token); + os_term_args.nargs = cpu_to_be32(1); + os_term_args.nret = cpu_to_be32(1); + os_term_args.args[0] = cpu_to_be32(__pa(str)); prom_rtas_hcall((uint64_t)&os_term_args); } #endif /* CONFIG_PPC_SVM */ @@ -3474,7 +3477,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ hdr = dt_header_start; - /* Don't print anything after quiesce under OPAL, it crashes OFW */ prom_printf("Booting Linux via __start() @ 0x%lx ...\n", kbase); prom_debug("->dt_header_start=0x%lx\n", hdr); diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c deleted file mode 100644 index 25c0424e8868..000000000000 --- a/arch/powerpc/kernel/ptrace.c +++ /dev/null @@ -1,3468 +0,0 @@ -/* - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/m68k/kernel/ptrace.c" - * Copyright (C) 1994 by Hamish Macdonald - * Taken from linux/kernel/ptrace.c and modified for M680x0. - * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds - * - * Modified by Cort Dougan (cort@hq.fsmlabs.com) - * and Paul Mackerras (paulus@samba.org). - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file README.legal in the main directory of - * this archive for more details. - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/regset.h> -#include <linux/tracehook.h> -#include <linux/elf.h> -#include <linux/user.h> -#include <linux/security.h> -#include <linux/signal.h> -#include <linux/seccomp.h> -#include <linux/audit.h> -#include <trace/syscall.h> -#include <linux/hw_breakpoint.h> -#include <linux/perf_event.h> -#include <linux/context_tracking.h> -#include <linux/nospec.h> - -#include <linux/uaccess.h> -#include <linux/pkeys.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/switch_to.h> -#include <asm/tm.h> -#include <asm/asm-prototypes.h> -#include <asm/debug.h> -#include <asm/hw_breakpoint.h> - -#define CREATE_TRACE_POINTS -#include <trace/events/syscalls.h> - -/* - * The parameter save area on the stack is used to store arguments being passed - * to callee function and is located at fixed offset from stack pointer. - */ -#ifdef CONFIG_PPC32 -#define PARAMETER_SAVE_AREA_OFFSET 24 /* bytes */ -#else /* CONFIG_PPC32 */ -#define PARAMETER_SAVE_AREA_OFFSET 48 /* bytes */ -#endif - -struct pt_regs_offset { - const char *name; - int offset; -}; - -#define STR(s) #s /* convert to string */ -#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} -#define GPR_OFFSET_NAME(num) \ - {.name = STR(r##num), .offset = offsetof(struct pt_regs, gpr[num])}, \ - {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} -#define REG_OFFSET_END {.name = NULL, .offset = 0} - -#define TVSO(f) (offsetof(struct thread_vr_state, f)) -#define TFSO(f) (offsetof(struct thread_fp_state, f)) -#define TSO(f) (offsetof(struct thread_struct, f)) - -static const struct pt_regs_offset regoffset_table[] = { - GPR_OFFSET_NAME(0), - GPR_OFFSET_NAME(1), - GPR_OFFSET_NAME(2), - GPR_OFFSET_NAME(3), - GPR_OFFSET_NAME(4), - GPR_OFFSET_NAME(5), - GPR_OFFSET_NAME(6), - GPR_OFFSET_NAME(7), - GPR_OFFSET_NAME(8), - GPR_OFFSET_NAME(9), - GPR_OFFSET_NAME(10), - GPR_OFFSET_NAME(11), - GPR_OFFSET_NAME(12), - GPR_OFFSET_NAME(13), - GPR_OFFSET_NAME(14), - GPR_OFFSET_NAME(15), - GPR_OFFSET_NAME(16), - GPR_OFFSET_NAME(17), - GPR_OFFSET_NAME(18), - GPR_OFFSET_NAME(19), - GPR_OFFSET_NAME(20), - GPR_OFFSET_NAME(21), - GPR_OFFSET_NAME(22), - GPR_OFFSET_NAME(23), - GPR_OFFSET_NAME(24), - GPR_OFFSET_NAME(25), - GPR_OFFSET_NAME(26), - GPR_OFFSET_NAME(27), - GPR_OFFSET_NAME(28), - GPR_OFFSET_NAME(29), - GPR_OFFSET_NAME(30), - GPR_OFFSET_NAME(31), - REG_OFFSET_NAME(nip), - REG_OFFSET_NAME(msr), - REG_OFFSET_NAME(ctr), - REG_OFFSET_NAME(link), - REG_OFFSET_NAME(xer), - REG_OFFSET_NAME(ccr), -#ifdef CONFIG_PPC64 - REG_OFFSET_NAME(softe), -#else - REG_OFFSET_NAME(mq), -#endif - REG_OFFSET_NAME(trap), - REG_OFFSET_NAME(dar), - REG_OFFSET_NAME(dsisr), - REG_OFFSET_END, -}; - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -static void flush_tmregs_to_thread(struct task_struct *tsk) -{ - /* - * If task is not current, it will have been flushed already to - * it's thread_struct during __switch_to(). - * - * A reclaim flushes ALL the state or if not in TM save TM SPRs - * in the appropriate thread structures from live. - */ - - if ((!cpu_has_feature(CPU_FTR_TM)) || (tsk != current)) - return; - - if (MSR_TM_SUSPENDED(mfmsr())) { - tm_reclaim_current(TM_CAUSE_SIGNAL); - } else { - tm_enable(); - tm_save_sprs(&(tsk->thread)); - } -} -#else -static inline void flush_tmregs_to_thread(struct task_struct *tsk) { } -#endif - -/** - * regs_query_register_offset() - query register offset from its name - * @name: the name of a register - * - * regs_query_register_offset() returns the offset of a register in struct - * pt_regs from its name. If the name is invalid, this returns -EINVAL; - */ -int regs_query_register_offset(const char *name) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (!strcmp(roff->name, name)) - return roff->offset; - return -EINVAL; -} - -/** - * regs_query_register_name() - query register name from its offset - * @offset: the offset of a register in struct pt_regs. - * - * regs_query_register_name() returns the name of a register from its - * offset in struct pt_regs. If the @offset is invalid, this returns NULL; - */ -const char *regs_query_register_name(unsigned int offset) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (roff->offset == offset) - return roff->name; - return NULL; -} - -/* - * does not yet catch signals sent when the child dies. - * in exit.c or in signal.c. - */ - -/* - * Set of msr bits that gdb can change on behalf of a process. - */ -#ifdef CONFIG_PPC_ADV_DEBUG_REGS -#define MSR_DEBUGCHANGE 0 -#else -#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) -#endif - -/* - * Max register writeable via put_reg - */ -#ifdef CONFIG_PPC32 -#define PT_MAX_PUT_REG PT_MQ -#else -#define PT_MAX_PUT_REG PT_CCR -#endif - -static unsigned long get_user_msr(struct task_struct *task) -{ - return task->thread.regs->msr | task->thread.fpexc_mode; -} - -static int set_user_msr(struct task_struct *task, unsigned long msr) -{ - task->thread.regs->msr &= ~MSR_DEBUGCHANGE; - task->thread.regs->msr |= msr & MSR_DEBUGCHANGE; - return 0; -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -static unsigned long get_user_ckpt_msr(struct task_struct *task) -{ - return task->thread.ckpt_regs.msr | task->thread.fpexc_mode; -} - -static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr) -{ - task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE; - task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE; - return 0; -} - -static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap) -{ - task->thread.ckpt_regs.trap = trap & 0xfff0; - return 0; -} -#endif - -#ifdef CONFIG_PPC64 -static int get_user_dscr(struct task_struct *task, unsigned long *data) -{ - *data = task->thread.dscr; - return 0; -} - -static int set_user_dscr(struct task_struct *task, unsigned long dscr) -{ - task->thread.dscr = dscr; - task->thread.dscr_inherit = 1; - return 0; -} -#else -static int get_user_dscr(struct task_struct *task, unsigned long *data) -{ - return -EIO; -} - -static int set_user_dscr(struct task_struct *task, unsigned long dscr) -{ - return -EIO; -} -#endif - -/* - * We prevent mucking around with the reserved area of trap - * which are used internally by the kernel. - */ -static int set_user_trap(struct task_struct *task, unsigned long trap) -{ - task->thread.regs->trap = trap & 0xfff0; - return 0; -} - -/* - * Get contents of register REGNO in task TASK. - */ -int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data) -{ - unsigned int regs_max; - - if ((task->thread.regs == NULL) || !data) - return -EIO; - - if (regno == PT_MSR) { - *data = get_user_msr(task); - return 0; - } - - if (regno == PT_DSCR) - return get_user_dscr(task, data); - -#ifdef CONFIG_PPC64 - /* - * softe copies paca->irq_soft_mask variable state. Since irq_soft_mask is - * no more used as a flag, lets force usr to alway see the softe value as 1 - * which means interrupts are not soft disabled. - */ - if (regno == PT_SOFTE) { - *data = 1; - return 0; - } -#endif - - regs_max = sizeof(struct user_pt_regs) / sizeof(unsigned long); - if (regno < regs_max) { - regno = array_index_nospec(regno, regs_max); - *data = ((unsigned long *)task->thread.regs)[regno]; - return 0; - } - - return -EIO; -} - -/* - * Write contents of register REGNO in task TASK. - */ -int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data) -{ - if (task->thread.regs == NULL) - return -EIO; - - if (regno == PT_MSR) - return set_user_msr(task, data); - if (regno == PT_TRAP) - return set_user_trap(task, data); - if (regno == PT_DSCR) - return set_user_dscr(task, data); - - if (regno <= PT_MAX_PUT_REG) { - regno = array_index_nospec(regno, PT_MAX_PUT_REG + 1); - ((unsigned long *)task->thread.regs)[regno] = data; - return 0; - } - return -EIO; -} - -static int gpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int i, ret; - - if (target->thread.regs == NULL) - return -EIO; - - if (!FULL_REGS(target->thread.regs)) { - /* We have a partial register set. Fill 14-31 with bogus values */ - for (i = 14; i < 32; i++) - target->thread.regs->gpr[i] = NV_REG_POISON; - } - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - target->thread.regs, - 0, offsetof(struct pt_regs, msr)); - if (!ret) { - unsigned long msr = get_user_msr(target); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, - offsetof(struct pt_regs, msr), - offsetof(struct pt_regs, msr) + - sizeof(msr)); - } - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); - - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.regs->orig_gpr3, - offsetof(struct pt_regs, orig_gpr3), - sizeof(struct user_pt_regs)); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - sizeof(struct user_pt_regs), -1); - - return ret; -} - -static int gpr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - unsigned long reg; - int ret; - - if (target->thread.regs == NULL) - return -EIO; - - CHECK_FULL_REGS(target->thread.regs); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - target->thread.regs, - 0, PT_MSR * sizeof(reg)); - - if (!ret && count > 0) { - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, - PT_MSR * sizeof(reg), - (PT_MSR + 1) * sizeof(reg)); - if (!ret) - ret = set_user_msr(target, reg); - } - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.regs->orig_gpr3, - PT_ORIG_R3 * sizeof(reg), - (PT_MAX_PUT_REG + 1) * sizeof(reg)); - - if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret) - ret = user_regset_copyin_ignore( - &pos, &count, &kbuf, &ubuf, - (PT_MAX_PUT_REG + 1) * sizeof(reg), - PT_TRAP * sizeof(reg)); - - if (!ret && count > 0) { - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, - PT_TRAP * sizeof(reg), - (PT_TRAP + 1) * sizeof(reg)); - if (!ret) - ret = set_user_trap(target, reg); - } - - if (!ret) - ret = user_regset_copyin_ignore( - &pos, &count, &kbuf, &ubuf, - (PT_TRAP + 1) * sizeof(reg), -1); - - return ret; -} - -/* - * Regardless of transactions, 'fp_state' holds the current running - * value of all FPR registers and 'ckfp_state' holds the last checkpointed - * value of all FPR registers for the current transaction. - * - * Userspace interface buffer layout: - * - * struct data { - * u64 fpr[32]; - * u64 fpscr; - * }; - */ -static int fpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ -#ifdef CONFIG_VSX - u64 buf[33]; - int i; - - flush_fp_to_thread(target); - - /* copy to local buffer then write that out */ - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.TS_FPR(i); - buf[32] = target->thread.fp_state.fpscr; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); -#else - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != - offsetof(struct thread_fp_state, fpr[32])); - - flush_fp_to_thread(target); - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fp_state, 0, -1); -#endif -} - -/* - * Regardless of transactions, 'fp_state' holds the current running - * value of all FPR registers and 'ckfp_state' holds the last checkpointed - * value of all FPR registers for the current transaction. - * - * Userspace interface buffer layout: - * - * struct data { - * u64 fpr[32]; - * u64 fpscr; - * }; - * - */ -static int fpr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ -#ifdef CONFIG_VSX - u64 buf[33]; - int i; - - flush_fp_to_thread(target); - - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.TS_FPR(i); - buf[32] = target->thread.fp_state.fpscr; - - /* copy to local buffer then write that out */ - i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); - if (i) - return i; - - for (i = 0; i < 32 ; i++) - target->thread.TS_FPR(i) = buf[i]; - target->thread.fp_state.fpscr = buf[32]; - return 0; -#else - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != - offsetof(struct thread_fp_state, fpr[32])); - - flush_fp_to_thread(target); - - return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fp_state, 0, -1); -#endif -} - -#ifdef CONFIG_ALTIVEC -/* - * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go. - * The transfer totals 34 quadword. Quadwords 0-31 contain the - * corresponding vector registers. Quadword 32 contains the vscr as the - * last word (offset 12) within that quadword. Quadword 33 contains the - * vrsave as the first word (offset 0) within the quadword. - * - * This definition of the VMX state is compatible with the current PPC32 - * ptrace interface. This allows signal handling and ptrace to use the - * same structures. This also simplifies the implementation of a bi-arch - * (combined (32- and 64-bit) gdb. - */ - -static int vr_active(struct task_struct *target, - const struct user_regset *regset) -{ - flush_altivec_to_thread(target); - return target->thread.used_vr ? regset->n : 0; -} - -/* - * Regardless of transactions, 'vr_state' holds the current running - * value of all the VMX registers and 'ckvr_state' holds the last - * checkpointed value of all the VMX registers for the current - * transaction to fall back on in case it aborts. - * - * Userspace interface buffer layout: - * - * struct data { - * vector128 vr[32]; - * vector128 vscr; - * vector128 vrsave; - * }; - */ -static int vr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - flush_altivec_to_thread(target); - - BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != - offsetof(struct thread_vr_state, vr[32])); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.vr_state, 0, - 33 * sizeof(vector128)); - if (!ret) { - /* - * Copy out only the low-order word of vrsave. - */ - int start, end; - union { - elf_vrreg_t reg; - u32 word; - } vrsave; - memset(&vrsave, 0, sizeof(vrsave)); - - vrsave.word = target->thread.vrsave; - - start = 33 * sizeof(vector128); - end = start + sizeof(vrsave); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave, - start, end); - } - - return ret; -} - -/* - * Regardless of transactions, 'vr_state' holds the current running - * value of all the VMX registers and 'ckvr_state' holds the last - * checkpointed value of all the VMX registers for the current - * transaction to fall back on in case it aborts. - * - * Userspace interface buffer layout: - * - * struct data { - * vector128 vr[32]; - * vector128 vscr; - * vector128 vrsave; - * }; - */ -static int vr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - flush_altivec_to_thread(target); - - BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != - offsetof(struct thread_vr_state, vr[32])); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.vr_state, 0, - 33 * sizeof(vector128)); - if (!ret && count > 0) { - /* - * We use only the first word of vrsave. - */ - int start, end; - union { - elf_vrreg_t reg; - u32 word; - } vrsave; - memset(&vrsave, 0, sizeof(vrsave)); - - vrsave.word = target->thread.vrsave; - - start = 33 * sizeof(vector128); - end = start + sizeof(vrsave); - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave, - start, end); - if (!ret) - target->thread.vrsave = vrsave.word; - } - - return ret; -} -#endif /* CONFIG_ALTIVEC */ - -#ifdef CONFIG_VSX -/* - * Currently to set and and get all the vsx state, you need to call - * the fp and VMX calls as well. This only get/sets the lower 32 - * 128bit VSX registers. - */ - -static int vsr_active(struct task_struct *target, - const struct user_regset *regset) -{ - flush_vsx_to_thread(target); - return target->thread.used_vsr ? regset->n : 0; -} - -/* - * Regardless of transactions, 'fp_state' holds the current running - * value of all FPR registers and 'ckfp_state' holds the last - * checkpointed value of all FPR registers for the current - * transaction. - * - * Userspace interface buffer layout: - * - * struct data { - * u64 vsx[32]; - * }; - */ -static int vsr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - u64 buf[32]; - int ret, i; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - flush_vsx_to_thread(target); - - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - buf, 0, 32 * sizeof(double)); - - return ret; -} - -/* - * Regardless of transactions, 'fp_state' holds the current running - * value of all FPR registers and 'ckfp_state' holds the last - * checkpointed value of all FPR registers for the current - * transaction. - * - * Userspace interface buffer layout: - * - * struct data { - * u64 vsx[32]; - * }; - */ -static int vsr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - u64 buf[32]; - int ret,i; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - flush_vsx_to_thread(target); - - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - buf, 0, 32 * sizeof(double)); - if (!ret) - for (i = 0; i < 32 ; i++) - target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; - - return ret; -} -#endif /* CONFIG_VSX */ - -#ifdef CONFIG_SPE - -/* - * For get_evrregs/set_evrregs functions 'data' has the following layout: - * - * struct { - * u32 evr[32]; - * u64 acc; - * u32 spefscr; - * } - */ - -static int evr_active(struct task_struct *target, - const struct user_regset *regset) -{ - flush_spe_to_thread(target); - return target->thread.used_spe ? regset->n : 0; -} - -static int evr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - flush_spe_to_thread(target); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.evr, - 0, sizeof(target->thread.evr)); - - BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != - offsetof(struct thread_struct, spefscr)); - - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.acc, - sizeof(target->thread.evr), -1); - - return ret; -} - -static int evr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - flush_spe_to_thread(target); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.evr, - 0, sizeof(target->thread.evr)); - - BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != - offsetof(struct thread_struct, spefscr)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.acc, - sizeof(target->thread.evr), -1); - - return ret; -} -#endif /* CONFIG_SPE */ - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -/** - * tm_cgpr_active - get active number of registers in CGPR - * @target: The target task. - * @regset: The user regset structure. - * - * This function checks for the active number of available - * regisers in transaction checkpointed GPR category. - */ -static int tm_cgpr_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return 0; - - return regset->n; -} - -/** - * tm_cgpr_get - get CGPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. - * - * This function gets transaction checkpointed GPR registers. - * - * When the transaction is active, 'ckpt_regs' holds all the checkpointed - * GPR register values for the current transaction to fall back on if it - * aborts in between. This function gets those checkpointed GPR registers. - * The userspace interface buffer layout is as follows. - * - * struct data { - * struct pt_regs ckpt_regs; - * }; - */ -static int tm_cgpr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs, - 0, offsetof(struct pt_regs, msr)); - if (!ret) { - unsigned long msr = get_user_ckpt_msr(target); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, - offsetof(struct pt_regs, msr), - offsetof(struct pt_regs, msr) + - sizeof(msr)); - } - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); - - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs.orig_gpr3, - offsetof(struct pt_regs, orig_gpr3), - sizeof(struct user_pt_regs)); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - sizeof(struct user_pt_regs), -1); - - return ret; -} - -/* - * tm_cgpr_set - set the CGPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy into. - * @ubuf: User buffer to copy from. - * - * This function sets in transaction checkpointed GPR registers. - * - * When the transaction is active, 'ckpt_regs' holds the checkpointed - * GPR register values for the current transaction to fall back on if it - * aborts in between. This function sets those checkpointed GPR registers. - * The userspace interface buffer layout is as follows. - * - * struct data { - * struct pt_regs ckpt_regs; - * }; - */ -static int tm_cgpr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - unsigned long reg; - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs, - 0, PT_MSR * sizeof(reg)); - - if (!ret && count > 0) { - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, - PT_MSR * sizeof(reg), - (PT_MSR + 1) * sizeof(reg)); - if (!ret) - ret = set_user_ckpt_msr(target, reg); - } - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs.orig_gpr3, - PT_ORIG_R3 * sizeof(reg), - (PT_MAX_PUT_REG + 1) * sizeof(reg)); - - if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret) - ret = user_regset_copyin_ignore( - &pos, &count, &kbuf, &ubuf, - (PT_MAX_PUT_REG + 1) * sizeof(reg), - PT_TRAP * sizeof(reg)); - - if (!ret && count > 0) { - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, - PT_TRAP * sizeof(reg), - (PT_TRAP + 1) * sizeof(reg)); - if (!ret) - ret = set_user_ckpt_trap(target, reg); - } - - if (!ret) - ret = user_regset_copyin_ignore( - &pos, &count, &kbuf, &ubuf, - (PT_TRAP + 1) * sizeof(reg), -1); - - return ret; -} - -/** - * tm_cfpr_active - get active number of registers in CFPR - * @target: The target task. - * @regset: The user regset structure. - * - * This function checks for the active number of available - * regisers in transaction checkpointed FPR category. - */ -static int tm_cfpr_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return 0; - - return regset->n; -} - -/** - * tm_cfpr_get - get CFPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. - * - * This function gets in transaction checkpointed FPR registers. - * - * When the transaction is active 'ckfp_state' holds the checkpointed - * values for the current transaction to fall back on if it aborts - * in between. This function gets those checkpointed FPR registers. - * The userspace interface buffer layout is as follows. - * - * struct data { - * u64 fpr[32]; - * u64 fpscr; - *}; - */ -static int tm_cfpr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - u64 buf[33]; - int i; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - /* copy to local buffer then write that out */ - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.TS_CKFPR(i); - buf[32] = target->thread.ckfp_state.fpscr; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); -} - -/** - * tm_cfpr_set - set CFPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy into. - * @ubuf: User buffer to copy from. - * - * This function sets in transaction checkpointed FPR registers. - * - * When the transaction is active 'ckfp_state' holds the checkpointed - * FPR register values for the current transaction to fall back on - * if it aborts in between. This function sets these checkpointed - * FPR registers. The userspace interface buffer layout is as follows. - * - * struct data { - * u64 fpr[32]; - * u64 fpscr; - *}; - */ -static int tm_cfpr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - u64 buf[33]; - int i; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - for (i = 0; i < 32; i++) - buf[i] = target->thread.TS_CKFPR(i); - buf[32] = target->thread.ckfp_state.fpscr; - - /* copy to local buffer then write that out */ - i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); - if (i) - return i; - for (i = 0; i < 32 ; i++) - target->thread.TS_CKFPR(i) = buf[i]; - target->thread.ckfp_state.fpscr = buf[32]; - return 0; -} - -/** - * tm_cvmx_active - get active number of registers in CVMX - * @target: The target task. - * @regset: The user regset structure. - * - * This function checks for the active number of available - * regisers in checkpointed VMX category. - */ -static int tm_cvmx_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return 0; - - return regset->n; -} - -/** - * tm_cvmx_get - get CMVX registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. - * - * This function gets in transaction checkpointed VMX registers. - * - * When the transaction is active 'ckvr_state' and 'ckvrsave' hold - * the checkpointed values for the current transaction to fall - * back on if it aborts in between. The userspace interface buffer - * layout is as follows. - * - * struct data { - * vector128 vr[32]; - * vector128 vscr; - * vector128 vrsave; - *}; - */ -static int tm_cvmx_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - /* Flush the state */ - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ckvr_state, 0, - 33 * sizeof(vector128)); - if (!ret) { - /* - * Copy out only the low-order word of vrsave. - */ - union { - elf_vrreg_t reg; - u32 word; - } vrsave; - memset(&vrsave, 0, sizeof(vrsave)); - vrsave.word = target->thread.ckvrsave; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave, - 33 * sizeof(vector128), -1); - } - - return ret; -} - -/** - * tm_cvmx_set - set CMVX registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy into. - * @ubuf: User buffer to copy from. - * - * This function sets in transaction checkpointed VMX registers. - * - * When the transaction is active 'ckvr_state' and 'ckvrsave' hold - * the checkpointed values for the current transaction to fall - * back on if it aborts in between. The userspace interface buffer - * layout is as follows. - * - * struct data { - * vector128 vr[32]; - * vector128 vscr; - * vector128 vrsave; - *}; - */ -static int tm_cvmx_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ckvr_state, 0, - 33 * sizeof(vector128)); - if (!ret && count > 0) { - /* - * We use only the low-order word of vrsave. - */ - union { - elf_vrreg_t reg; - u32 word; - } vrsave; - memset(&vrsave, 0, sizeof(vrsave)); - vrsave.word = target->thread.ckvrsave; - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave, - 33 * sizeof(vector128), -1); - if (!ret) - target->thread.ckvrsave = vrsave.word; - } - - return ret; -} - -/** - * tm_cvsx_active - get active number of registers in CVSX - * @target: The target task. - * @regset: The user regset structure. - * - * This function checks for the active number of available - * regisers in transaction checkpointed VSX category. - */ -static int tm_cvsx_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return 0; - - flush_vsx_to_thread(target); - return target->thread.used_vsr ? regset->n : 0; -} - -/** - * tm_cvsx_get - get CVSX registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. - * - * This function gets in transaction checkpointed VSX registers. - * - * When the transaction is active 'ckfp_state' holds the checkpointed - * values for the current transaction to fall back on if it aborts - * in between. This function gets those checkpointed VSX registers. - * The userspace interface buffer layout is as follows. - * - * struct data { - * u64 vsx[32]; - *}; - */ -static int tm_cvsx_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - u64 buf[32]; - int ret, i; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - /* Flush the state */ - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - flush_vsx_to_thread(target); - - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - buf, 0, 32 * sizeof(double)); - - return ret; -} - -/** - * tm_cvsx_set - set CFPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy into. - * @ubuf: User buffer to copy from. - * - * This function sets in transaction checkpointed VSX registers. - * - * When the transaction is active 'ckfp_state' holds the checkpointed - * VSX register values for the current transaction to fall back on - * if it aborts in between. This function sets these checkpointed - * FPR registers. The userspace interface buffer layout is as follows. - * - * struct data { - * u64 vsx[32]; - *}; - */ -static int tm_cvsx_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - u64 buf[32]; - int ret, i; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - /* Flush the state */ - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - flush_vsx_to_thread(target); - - for (i = 0; i < 32 ; i++) - buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - buf, 0, 32 * sizeof(double)); - if (!ret) - for (i = 0; i < 32 ; i++) - target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; - - return ret; -} - -/** - * tm_spr_active - get active number of registers in TM SPR - * @target: The target task. - * @regset: The user regset structure. - * - * This function checks the active number of available - * regisers in the transactional memory SPR category. - */ -static int tm_spr_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - return regset->n; -} - -/** - * tm_spr_get - get the TM related SPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. - * - * This function gets transactional memory related SPR registers. - * The userspace interface buffer layout is as follows. - * - * struct { - * u64 tm_tfhar; - * u64 tm_texasr; - * u64 tm_tfiar; - * }; - */ -static int tm_spr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - /* Build tests */ - BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); - BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); - BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - /* Flush the states */ - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - /* TFHAR register */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfhar, 0, sizeof(u64)); - - /* TEXASR register */ - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_texasr, sizeof(u64), - 2 * sizeof(u64)); - - /* TFIAR register */ - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfiar, - 2 * sizeof(u64), 3 * sizeof(u64)); - return ret; -} - -/** - * tm_spr_set - set the TM related SPR registers - * @target: The target task. - * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy into. - * @ubuf: User buffer to copy from. - * - * This function sets transactional memory related SPR registers. - * The userspace interface buffer layout is as follows. - * - * struct { - * u64 tm_tfhar; - * u64 tm_texasr; - * u64 tm_tfiar; - * }; - */ -static int tm_spr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - /* Build tests */ - BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); - BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); - BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - /* Flush the states */ - flush_tmregs_to_thread(target); - flush_fp_to_thread(target); - flush_altivec_to_thread(target); - - /* TFHAR register */ - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfhar, 0, sizeof(u64)); - - /* TEXASR register */ - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_texasr, sizeof(u64), - 2 * sizeof(u64)); - - /* TFIAR register */ - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfiar, - 2 * sizeof(u64), 3 * sizeof(u64)); - return ret; -} - -static int tm_tar_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (MSR_TM_ACTIVE(target->thread.regs->msr)) - return regset->n; - - return 0; -} - -static int tm_tar_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tar, 0, sizeof(u64)); - return ret; -} - -static int tm_tar_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tar, 0, sizeof(u64)); - return ret; -} - -static int tm_ppr_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (MSR_TM_ACTIVE(target->thread.regs->msr)) - return regset->n; - - return 0; -} - - -static int tm_ppr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_ppr, 0, sizeof(u64)); - return ret; -} - -static int tm_ppr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_ppr, 0, sizeof(u64)); - return ret; -} - -static int tm_dscr_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (MSR_TM_ACTIVE(target->thread.regs->msr)) - return regset->n; - - return 0; -} - -static int tm_dscr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_dscr, 0, sizeof(u64)); - return ret; -} - -static int tm_dscr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_TM)) - return -ENODEV; - - if (!MSR_TM_ACTIVE(target->thread.regs->msr)) - return -ENODATA; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_dscr, 0, sizeof(u64)); - return ret; -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ - -#ifdef CONFIG_PPC64 -static int ppr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.regs->ppr, 0, sizeof(u64)); -} - -static int ppr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.regs->ppr, 0, sizeof(u64)); -} - -static int dscr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); -} -static int dscr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); -} -#endif -#ifdef CONFIG_PPC_BOOK3S_64 -static int tar_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); -} -static int tar_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); -} - -static int ebb_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - if (target->thread.used_ebb) - return regset->n; - - return 0; -} - -static int ebb_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - /* Build tests */ - BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr)); - BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr)); - - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - if (!target->thread.used_ebb) - return -ENODATA; - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ebbrr, 0, 3 * sizeof(unsigned long)); -} - -static int ebb_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret = 0; - - /* Build tests */ - BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr)); - BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr)); - - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - if (target->thread.used_ebb) - return -ENODATA; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ebbrr, 0, sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ebbhr, sizeof(unsigned long), - 2 * sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.bescr, - 2 * sizeof(unsigned long), 3 * sizeof(unsigned long)); - - return ret; -} -static int pmu_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - return regset->n; -} - -static int pmu_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - /* Build tests */ - BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar)); - BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier)); - BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2)); - BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0)); - - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.siar, 0, - 5 * sizeof(unsigned long)); -} - -static int pmu_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret = 0; - - /* Build tests */ - BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar)); - BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier)); - BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2)); - BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0)); - - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) - return -ENODEV; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.siar, 0, - sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.sdar, sizeof(unsigned long), - 2 * sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.sier, 2 * sizeof(unsigned long), - 3 * sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.mmcr2, 3 * sizeof(unsigned long), - 4 * sizeof(unsigned long)); - - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.mmcr0, 4 * sizeof(unsigned long), - 5 * sizeof(unsigned long)); - return ret; -} -#endif - -#ifdef CONFIG_PPC_MEM_KEYS -static int pkey_active(struct task_struct *target, - const struct user_regset *regset) -{ - if (!arch_pkeys_enabled()) - return -ENODEV; - - return regset->n; -} - -static int pkey_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr)); - BUILD_BUG_ON(TSO(iamr) + sizeof(unsigned long) != TSO(uamor)); - - if (!arch_pkeys_enabled()) - return -ENODEV; - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.amr, 0, - ELF_NPKEY * sizeof(unsigned long)); -} - -static int pkey_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - u64 new_amr; - int ret; - - if (!arch_pkeys_enabled()) - return -ENODEV; - - /* Only the AMR can be set from userspace */ - if (pos != 0 || count != sizeof(new_amr)) - return -EINVAL; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &new_amr, 0, sizeof(new_amr)); - if (ret) - return ret; - - /* UAMOR determines which bits of the AMR can be set from userspace. */ - target->thread.amr = (new_amr & target->thread.uamor) | - (target->thread.amr & ~target->thread.uamor); - - return 0; -} -#endif /* CONFIG_PPC_MEM_KEYS */ - -/* - * These are our native regset flavors. - */ -enum powerpc_regset { - REGSET_GPR, - REGSET_FPR, -#ifdef CONFIG_ALTIVEC - REGSET_VMX, -#endif -#ifdef CONFIG_VSX - REGSET_VSX, -#endif -#ifdef CONFIG_SPE - REGSET_SPE, -#endif -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - REGSET_TM_CGPR, /* TM checkpointed GPR registers */ - REGSET_TM_CFPR, /* TM checkpointed FPR registers */ - REGSET_TM_CVMX, /* TM checkpointed VMX registers */ - REGSET_TM_CVSX, /* TM checkpointed VSX registers */ - REGSET_TM_SPR, /* TM specific SPR registers */ - REGSET_TM_CTAR, /* TM checkpointed TAR register */ - REGSET_TM_CPPR, /* TM checkpointed PPR register */ - REGSET_TM_CDSCR, /* TM checkpointed DSCR register */ -#endif -#ifdef CONFIG_PPC64 - REGSET_PPR, /* PPR register */ - REGSET_DSCR, /* DSCR register */ -#endif -#ifdef CONFIG_PPC_BOOK3S_64 - REGSET_TAR, /* TAR register */ - REGSET_EBB, /* EBB registers */ - REGSET_PMR, /* Performance Monitor Registers */ -#endif -#ifdef CONFIG_PPC_MEM_KEYS - REGSET_PKEY, /* AMR register */ -#endif -}; - -static const struct user_regset native_regsets[] = { - [REGSET_GPR] = { - .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, - .size = sizeof(long), .align = sizeof(long), - .get = gpr_get, .set = gpr_set - }, - [REGSET_FPR] = { - .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, - .size = sizeof(double), .align = sizeof(double), - .get = fpr_get, .set = fpr_set - }, -#ifdef CONFIG_ALTIVEC - [REGSET_VMX] = { - .core_note_type = NT_PPC_VMX, .n = 34, - .size = sizeof(vector128), .align = sizeof(vector128), - .active = vr_active, .get = vr_get, .set = vr_set - }, -#endif -#ifdef CONFIG_VSX - [REGSET_VSX] = { - .core_note_type = NT_PPC_VSX, .n = 32, - .size = sizeof(double), .align = sizeof(double), - .active = vsr_active, .get = vsr_get, .set = vsr_set - }, -#endif -#ifdef CONFIG_SPE - [REGSET_SPE] = { - .core_note_type = NT_PPC_SPE, .n = 35, - .size = sizeof(u32), .align = sizeof(u32), - .active = evr_active, .get = evr_get, .set = evr_set - }, -#endif -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - [REGSET_TM_CGPR] = { - .core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG, - .size = sizeof(long), .align = sizeof(long), - .active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set - }, - [REGSET_TM_CFPR] = { - .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, - .size = sizeof(double), .align = sizeof(double), - .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set - }, - [REGSET_TM_CVMX] = { - .core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX, - .size = sizeof(vector128), .align = sizeof(vector128), - .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set - }, - [REGSET_TM_CVSX] = { - .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, - .size = sizeof(double), .align = sizeof(double), - .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set - }, - [REGSET_TM_SPR] = { - .core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set - }, - [REGSET_TM_CTAR] = { - .core_note_type = NT_PPC_TM_CTAR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_tar_active, .get = tm_tar_get, .set = tm_tar_set - }, - [REGSET_TM_CPPR] = { - .core_note_type = NT_PPC_TM_CPPR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_ppr_active, .get = tm_ppr_get, .set = tm_ppr_set - }, - [REGSET_TM_CDSCR] = { - .core_note_type = NT_PPC_TM_CDSCR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set - }, -#endif -#ifdef CONFIG_PPC64 - [REGSET_PPR] = { - .core_note_type = NT_PPC_PPR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = ppr_get, .set = ppr_set - }, - [REGSET_DSCR] = { - .core_note_type = NT_PPC_DSCR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = dscr_get, .set = dscr_set - }, -#endif -#ifdef CONFIG_PPC_BOOK3S_64 - [REGSET_TAR] = { - .core_note_type = NT_PPC_TAR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = tar_get, .set = tar_set - }, - [REGSET_EBB] = { - .core_note_type = NT_PPC_EBB, .n = ELF_NEBB, - .size = sizeof(u64), .align = sizeof(u64), - .active = ebb_active, .get = ebb_get, .set = ebb_set - }, - [REGSET_PMR] = { - .core_note_type = NT_PPC_PMU, .n = ELF_NPMU, - .size = sizeof(u64), .align = sizeof(u64), - .active = pmu_active, .get = pmu_get, .set = pmu_set - }, -#endif -#ifdef CONFIG_PPC_MEM_KEYS - [REGSET_PKEY] = { - .core_note_type = NT_PPC_PKEY, .n = ELF_NPKEY, - .size = sizeof(u64), .align = sizeof(u64), - .active = pkey_active, .get = pkey_get, .set = pkey_set - }, -#endif -}; - -static const struct user_regset_view user_ppc_native_view = { - .name = UTS_MACHINE, .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI, - .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets) -}; - -#ifdef CONFIG_PPC64 -#include <linux/compat.h> - -static int gpr32_get_common(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf, - unsigned long *regs) -{ - compat_ulong_t *k = kbuf; - compat_ulong_t __user *u = ubuf; - compat_ulong_t reg; - - pos /= sizeof(reg); - count /= sizeof(reg); - - if (kbuf) - for (; count > 0 && pos < PT_MSR; --count) - *k++ = regs[pos++]; - else - for (; count > 0 && pos < PT_MSR; --count) - if (__put_user((compat_ulong_t) regs[pos++], u++)) - return -EFAULT; - - if (count > 0 && pos == PT_MSR) { - reg = get_user_msr(target); - if (kbuf) - *k++ = reg; - else if (__put_user(reg, u++)) - return -EFAULT; - ++pos; - --count; - } - - if (kbuf) - for (; count > 0 && pos < PT_REGS_COUNT; --count) - *k++ = regs[pos++]; - else - for (; count > 0 && pos < PT_REGS_COUNT; --count) - if (__put_user((compat_ulong_t) regs[pos++], u++)) - return -EFAULT; - - kbuf = k; - ubuf = u; - pos *= sizeof(reg); - count *= sizeof(reg); - return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - PT_REGS_COUNT * sizeof(reg), -1); -} - -static int gpr32_set_common(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf, - unsigned long *regs) -{ - const compat_ulong_t *k = kbuf; - const compat_ulong_t __user *u = ubuf; - compat_ulong_t reg; - - pos /= sizeof(reg); - count /= sizeof(reg); - - if (kbuf) - for (; count > 0 && pos < PT_MSR; --count) - regs[pos++] = *k++; - else - for (; count > 0 && pos < PT_MSR; --count) { - if (__get_user(reg, u++)) - return -EFAULT; - regs[pos++] = reg; - } - - - if (count > 0 && pos == PT_MSR) { - if (kbuf) - reg = *k++; - else if (__get_user(reg, u++)) - return -EFAULT; - set_user_msr(target, reg); - ++pos; - --count; - } - - if (kbuf) { - for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) - regs[pos++] = *k++; - for (; count > 0 && pos < PT_TRAP; --count, ++pos) - ++k; - } else { - for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) { - if (__get_user(reg, u++)) - return -EFAULT; - regs[pos++] = reg; - } - for (; count > 0 && pos < PT_TRAP; --count, ++pos) - if (__get_user(reg, u++)) - return -EFAULT; - } - - if (count > 0 && pos == PT_TRAP) { - if (kbuf) - reg = *k++; - else if (__get_user(reg, u++)) - return -EFAULT; - set_user_trap(target, reg); - ++pos; - --count; - } - - kbuf = k; - ubuf = u; - pos *= sizeof(reg); - count *= sizeof(reg); - return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - (PT_TRAP + 1) * sizeof(reg), -1); -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -static int tm_cgpr32_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, - &target->thread.ckpt_regs.gpr[0]); -} - -static int tm_cgpr32_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, - &target->thread.ckpt_regs.gpr[0]); -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ - -static int gpr32_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - int i; - - if (target->thread.regs == NULL) - return -EIO; - - if (!FULL_REGS(target->thread.regs)) { - /* - * We have a partial register set. - * Fill 14-31 with bogus values. - */ - for (i = 14; i < 32; i++) - target->thread.regs->gpr[i] = NV_REG_POISON; - } - return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, - &target->thread.regs->gpr[0]); -} - -static int gpr32_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - if (target->thread.regs == NULL) - return -EIO; - - CHECK_FULL_REGS(target->thread.regs); - return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, - &target->thread.regs->gpr[0]); -} - -/* - * These are the regset flavors matching the CONFIG_PPC32 native set. - */ -static const struct user_regset compat_regsets[] = { - [REGSET_GPR] = { - .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, - .size = sizeof(compat_long_t), .align = sizeof(compat_long_t), - .get = gpr32_get, .set = gpr32_set - }, - [REGSET_FPR] = { - .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, - .size = sizeof(double), .align = sizeof(double), - .get = fpr_get, .set = fpr_set - }, -#ifdef CONFIG_ALTIVEC - [REGSET_VMX] = { - .core_note_type = NT_PPC_VMX, .n = 34, - .size = sizeof(vector128), .align = sizeof(vector128), - .active = vr_active, .get = vr_get, .set = vr_set - }, -#endif -#ifdef CONFIG_SPE - [REGSET_SPE] = { - .core_note_type = NT_PPC_SPE, .n = 35, - .size = sizeof(u32), .align = sizeof(u32), - .active = evr_active, .get = evr_get, .set = evr_set - }, -#endif -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - [REGSET_TM_CGPR] = { - .core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG, - .size = sizeof(long), .align = sizeof(long), - .active = tm_cgpr_active, - .get = tm_cgpr32_get, .set = tm_cgpr32_set - }, - [REGSET_TM_CFPR] = { - .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, - .size = sizeof(double), .align = sizeof(double), - .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set - }, - [REGSET_TM_CVMX] = { - .core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX, - .size = sizeof(vector128), .align = sizeof(vector128), - .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set - }, - [REGSET_TM_CVSX] = { - .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, - .size = sizeof(double), .align = sizeof(double), - .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set - }, - [REGSET_TM_SPR] = { - .core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set - }, - [REGSET_TM_CTAR] = { - .core_note_type = NT_PPC_TM_CTAR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_tar_active, .get = tm_tar_get, .set = tm_tar_set - }, - [REGSET_TM_CPPR] = { - .core_note_type = NT_PPC_TM_CPPR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_ppr_active, .get = tm_ppr_get, .set = tm_ppr_set - }, - [REGSET_TM_CDSCR] = { - .core_note_type = NT_PPC_TM_CDSCR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set - }, -#endif -#ifdef CONFIG_PPC64 - [REGSET_PPR] = { - .core_note_type = NT_PPC_PPR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = ppr_get, .set = ppr_set - }, - [REGSET_DSCR] = { - .core_note_type = NT_PPC_DSCR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = dscr_get, .set = dscr_set - }, -#endif -#ifdef CONFIG_PPC_BOOK3S_64 - [REGSET_TAR] = { - .core_note_type = NT_PPC_TAR, .n = 1, - .size = sizeof(u64), .align = sizeof(u64), - .get = tar_get, .set = tar_set - }, - [REGSET_EBB] = { - .core_note_type = NT_PPC_EBB, .n = ELF_NEBB, - .size = sizeof(u64), .align = sizeof(u64), - .active = ebb_active, .get = ebb_get, .set = ebb_set - }, -#endif -}; - -static const struct user_regset_view user_ppc_compat_view = { - .name = "ppc", .e_machine = EM_PPC, .ei_osabi = ELF_OSABI, - .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets) -}; -#endif /* CONFIG_PPC64 */ - -const struct user_regset_view *task_user_regset_view(struct task_struct *task) -{ -#ifdef CONFIG_PPC64 - if (test_tsk_thread_flag(task, TIF_32BIT)) - return &user_ppc_compat_view; -#endif - return &user_ppc_native_view; -} - - -void user_enable_single_step(struct task_struct *task) -{ - struct pt_regs *regs = task->thread.regs; - - if (regs != NULL) { -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - task->thread.debug.dbcr0 &= ~DBCR0_BT; - task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; - regs->msr |= MSR_DE; -#else - regs->msr &= ~MSR_BE; - regs->msr |= MSR_SE; -#endif - } - set_tsk_thread_flag(task, TIF_SINGLESTEP); -} - -void user_enable_block_step(struct task_struct *task) -{ - struct pt_regs *regs = task->thread.regs; - - if (regs != NULL) { -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - task->thread.debug.dbcr0 &= ~DBCR0_IC; - task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; - regs->msr |= MSR_DE; -#else - regs->msr &= ~MSR_SE; - regs->msr |= MSR_BE; -#endif - } - set_tsk_thread_flag(task, TIF_SINGLESTEP); -} - -void user_disable_single_step(struct task_struct *task) -{ - struct pt_regs *regs = task->thread.regs; - - if (regs != NULL) { -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - /* - * The logic to disable single stepping should be as - * simple as turning off the Instruction Complete flag. - * And, after doing so, if all debug flags are off, turn - * off DBCR0(IDM) and MSR(DE) .... Torez - */ - task->thread.debug.dbcr0 &= ~(DBCR0_IC|DBCR0_BT); - /* - * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. - */ - if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, - task->thread.debug.dbcr1)) { - /* - * All debug events were off..... - */ - task->thread.debug.dbcr0 &= ~DBCR0_IDM; - regs->msr &= ~MSR_DE; - } -#else - regs->msr &= ~(MSR_SE | MSR_BE); -#endif - } - clear_tsk_thread_flag(task, TIF_SINGLESTEP); -} - -#ifdef CONFIG_HAVE_HW_BREAKPOINT -void ptrace_triggered(struct perf_event *bp, - struct perf_sample_data *data, struct pt_regs *regs) -{ - struct perf_event_attr attr; - - /* - * Disable the breakpoint request here since ptrace has defined a - * one-shot behaviour for breakpoint exceptions in PPC64. - * The SIGTRAP signal is generated automatically for us in do_dabr(). - * We don't have to do anything about that here - */ - attr = bp->attr; - attr.disabled = true; - modify_user_hw_breakpoint(bp, &attr); -} -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - -static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, - unsigned long data) -{ -#ifdef CONFIG_HAVE_HW_BREAKPOINT - int ret; - struct thread_struct *thread = &(task->thread); - struct perf_event *bp; - struct perf_event_attr attr; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#ifndef CONFIG_PPC_ADV_DEBUG_REGS - bool set_bp = true; - struct arch_hw_breakpoint hw_brk; -#endif - - /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). - * For embedded processors we support one DAC and no IAC's at the - * moment. - */ - if (addr > 0) - return -EINVAL; - - /* The bottom 3 bits in dabr are flags */ - if ((data & ~0x7UL) >= TASK_SIZE) - return -EIO; - -#ifndef CONFIG_PPC_ADV_DEBUG_REGS - /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. - * It was assumed, on previous implementations, that 3 bits were - * passed together with the data address, fitting the design of the - * DABR register, as follows: - * - * bit 0: Read flag - * bit 1: Write flag - * bit 2: Breakpoint translation - * - * Thus, we use them here as so. - */ - - /* Ensure breakpoint translation bit is set */ - if (data && !(data & HW_BRK_TYPE_TRANSLATE)) - return -EIO; - hw_brk.address = data & (~HW_BRK_TYPE_DABR); - hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; - hw_brk.len = DABR_MAX_LEN; - hw_brk.hw_len = DABR_MAX_LEN; - set_bp = (data) && (hw_brk.type & HW_BRK_TYPE_RDWR); -#ifdef CONFIG_HAVE_HW_BREAKPOINT - bp = thread->ptrace_bps[0]; - if (!set_bp) { - if (bp) { - unregister_hw_breakpoint(bp); - thread->ptrace_bps[0] = NULL; - } - return 0; - } - if (bp) { - attr = bp->attr; - attr.bp_addr = hw_brk.address; - attr.bp_len = DABR_MAX_LEN; - arch_bp_generic_fields(hw_brk.type, &attr.bp_type); - - /* Enable breakpoint */ - attr.disabled = false; - - ret = modify_user_hw_breakpoint(bp, &attr); - if (ret) { - return ret; - } - thread->ptrace_bps[0] = bp; - thread->hw_brk = hw_brk; - return 0; - } - - /* Create a new breakpoint request if one doesn't exist already */ - hw_breakpoint_init(&attr); - attr.bp_addr = hw_brk.address; - attr.bp_len = DABR_MAX_LEN; - arch_bp_generic_fields(hw_brk.type, - &attr.bp_type); - - thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, - ptrace_triggered, NULL, task); - if (IS_ERR(bp)) { - thread->ptrace_bps[0] = NULL; - return PTR_ERR(bp); - } - -#else /* !CONFIG_HAVE_HW_BREAKPOINT */ - if (set_bp && (!ppc_breakpoint_available())) - return -ENODEV; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - task->thread.hw_brk = hw_brk; -#else /* CONFIG_PPC_ADV_DEBUG_REGS */ - /* As described above, it was assumed 3 bits were passed with the data - * address, but we will assume only the mode bits will be passed - * as to not cause alignment restrictions for DAC-based processors. - */ - - /* DAC's hold the whole address without any mode flags */ - task->thread.debug.dac1 = data & ~0x3UL; - - if (task->thread.debug.dac1 == 0) { - dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); - if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, - task->thread.debug.dbcr1)) { - task->thread.regs->msr &= ~MSR_DE; - task->thread.debug.dbcr0 &= ~DBCR0_IDM; - } - return 0; - } - - /* Read or Write bits must be set */ - - if (!(data & 0x3UL)) - return -EINVAL; - - /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 - register */ - task->thread.debug.dbcr0 |= DBCR0_IDM; - - /* Check for write and read flags and set DBCR0 - accordingly */ - dbcr_dac(task) &= ~(DBCR_DAC1R|DBCR_DAC1W); - if (data & 0x1UL) - dbcr_dac(task) |= DBCR_DAC1R; - if (data & 0x2UL) - dbcr_dac(task) |= DBCR_DAC1W; - task->thread.regs->msr |= MSR_DE; -#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ - return 0; -} - -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure single step bits etc are not set. - */ -void ptrace_disable(struct task_struct *child) -{ - /* make sure the single step bit is not set. */ - user_disable_single_step(child); -} - -#ifdef CONFIG_PPC_ADV_DEBUG_REGS -static long set_instruction_bp(struct task_struct *child, - struct ppc_hw_breakpoint *bp_info) -{ - int slot; - int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0); - int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0); - int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0); - int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0); - - if (dbcr_iac_range(child) & DBCR_IAC12MODE) - slot2_in_use = 1; - if (dbcr_iac_range(child) & DBCR_IAC34MODE) - slot4_in_use = 1; - - if (bp_info->addr >= TASK_SIZE) - return -EIO; - - if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) { - - /* Make sure range is valid. */ - if (bp_info->addr2 >= TASK_SIZE) - return -EIO; - - /* We need a pair of IAC regsisters */ - if ((!slot1_in_use) && (!slot2_in_use)) { - slot = 1; - child->thread.debug.iac1 = bp_info->addr; - child->thread.debug.iac2 = bp_info->addr2; - child->thread.debug.dbcr0 |= DBCR0_IAC1; - if (bp_info->addr_mode == - PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) - dbcr_iac_range(child) |= DBCR_IAC12X; - else - dbcr_iac_range(child) |= DBCR_IAC12I; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - } else if ((!slot3_in_use) && (!slot4_in_use)) { - slot = 3; - child->thread.debug.iac3 = bp_info->addr; - child->thread.debug.iac4 = bp_info->addr2; - child->thread.debug.dbcr0 |= DBCR0_IAC3; - if (bp_info->addr_mode == - PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) - dbcr_iac_range(child) |= DBCR_IAC34X; - else - dbcr_iac_range(child) |= DBCR_IAC34I; -#endif - } else - return -ENOSPC; - } else { - /* We only need one. If possible leave a pair free in - * case a range is needed later - */ - if (!slot1_in_use) { - /* - * Don't use iac1 if iac1-iac2 are free and either - * iac3 or iac4 (but not both) are free - */ - if (slot2_in_use || (slot3_in_use == slot4_in_use)) { - slot = 1; - child->thread.debug.iac1 = bp_info->addr; - child->thread.debug.dbcr0 |= DBCR0_IAC1; - goto out; - } - } - if (!slot2_in_use) { - slot = 2; - child->thread.debug.iac2 = bp_info->addr; - child->thread.debug.dbcr0 |= DBCR0_IAC2; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - } else if (!slot3_in_use) { - slot = 3; - child->thread.debug.iac3 = bp_info->addr; - child->thread.debug.dbcr0 |= DBCR0_IAC3; - } else if (!slot4_in_use) { - slot = 4; - child->thread.debug.iac4 = bp_info->addr; - child->thread.debug.dbcr0 |= DBCR0_IAC4; -#endif - } else - return -ENOSPC; - } -out: - child->thread.debug.dbcr0 |= DBCR0_IDM; - child->thread.regs->msr |= MSR_DE; - - return slot; -} - -static int del_instruction_bp(struct task_struct *child, int slot) -{ - switch (slot) { - case 1: - if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0) - return -ENOENT; - - if (dbcr_iac_range(child) & DBCR_IAC12MODE) { - /* address range - clear slots 1 & 2 */ - child->thread.debug.iac2 = 0; - dbcr_iac_range(child) &= ~DBCR_IAC12MODE; - } - child->thread.debug.iac1 = 0; - child->thread.debug.dbcr0 &= ~DBCR0_IAC1; - break; - case 2: - if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0) - return -ENOENT; - - if (dbcr_iac_range(child) & DBCR_IAC12MODE) - /* used in a range */ - return -EINVAL; - child->thread.debug.iac2 = 0; - child->thread.debug.dbcr0 &= ~DBCR0_IAC2; - break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case 3: - if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0) - return -ENOENT; - - if (dbcr_iac_range(child) & DBCR_IAC34MODE) { - /* address range - clear slots 3 & 4 */ - child->thread.debug.iac4 = 0; - dbcr_iac_range(child) &= ~DBCR_IAC34MODE; - } - child->thread.debug.iac3 = 0; - child->thread.debug.dbcr0 &= ~DBCR0_IAC3; - break; - case 4: - if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0) - return -ENOENT; - - if (dbcr_iac_range(child) & DBCR_IAC34MODE) - /* Used in a range */ - return -EINVAL; - child->thread.debug.iac4 = 0; - child->thread.debug.dbcr0 &= ~DBCR0_IAC4; - break; -#endif - default: - return -EINVAL; - } - return 0; -} - -static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) -{ - int byte_enable = - (bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT) - & 0xf; - int condition_mode = - bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE; - int slot; - - if (byte_enable && (condition_mode == 0)) - return -EINVAL; - - if (bp_info->addr >= TASK_SIZE) - return -EIO; - - if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) { - slot = 1; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) - dbcr_dac(child) |= DBCR_DAC1R; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) - dbcr_dac(child) |= DBCR_DAC1W; - child->thread.debug.dac1 = (unsigned long)bp_info->addr; -#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - if (byte_enable) { - child->thread.debug.dvc1 = - (unsigned long)bp_info->condition_value; - child->thread.debug.dbcr2 |= - ((byte_enable << DBCR2_DVC1BE_SHIFT) | - (condition_mode << DBCR2_DVC1M_SHIFT)); - } -#endif -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { - /* Both dac1 and dac2 are part of a range */ - return -ENOSPC; -#endif - } else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) { - slot = 2; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) - dbcr_dac(child) |= DBCR_DAC2R; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) - dbcr_dac(child) |= DBCR_DAC2W; - child->thread.debug.dac2 = (unsigned long)bp_info->addr; -#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - if (byte_enable) { - child->thread.debug.dvc2 = - (unsigned long)bp_info->condition_value; - child->thread.debug.dbcr2 |= - ((byte_enable << DBCR2_DVC2BE_SHIFT) | - (condition_mode << DBCR2_DVC2M_SHIFT)); - } -#endif - } else - return -ENOSPC; - child->thread.debug.dbcr0 |= DBCR0_IDM; - child->thread.regs->msr |= MSR_DE; - - return slot + 4; -} - -static int del_dac(struct task_struct *child, int slot) -{ - if (slot == 1) { - if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) - return -ENOENT; - - child->thread.debug.dac1 = 0; - dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { - child->thread.debug.dac2 = 0; - child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE; - } - child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); -#endif -#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - child->thread.debug.dvc1 = 0; -#endif - } else if (slot == 2) { - if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) - return -ENOENT; - -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) - /* Part of a range */ - return -EINVAL; - child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); -#endif -#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - child->thread.debug.dvc2 = 0; -#endif - child->thread.debug.dac2 = 0; - dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); - } else - return -EINVAL; - - return 0; -} -#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ - -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE -static int set_dac_range(struct task_struct *child, - struct ppc_hw_breakpoint *bp_info) -{ - int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK; - - /* We don't allow range watchpoints to be used with DVC */ - if (bp_info->condition_mode) - return -EINVAL; - - /* - * Best effort to verify the address range. The user/supervisor bits - * prevent trapping in kernel space, but let's fail on an obvious bad - * range. The simple test on the mask is not fool-proof, and any - * exclusive range will spill over into kernel space. - */ - if (bp_info->addr >= TASK_SIZE) - return -EIO; - if (mode == PPC_BREAKPOINT_MODE_MASK) { - /* - * dac2 is a bitmask. Don't allow a mask that makes a - * kernel space address from a valid dac1 value - */ - if (~((unsigned long)bp_info->addr2) >= TASK_SIZE) - return -EIO; - } else { - /* - * For range breakpoints, addr2 must also be a valid address - */ - if (bp_info->addr2 >= TASK_SIZE) - return -EIO; - } - - if (child->thread.debug.dbcr0 & - (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) - return -ENOSPC; - - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) - child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) - child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); - child->thread.debug.dac1 = bp_info->addr; - child->thread.debug.dac2 = bp_info->addr2; - if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) - child->thread.debug.dbcr2 |= DBCR2_DAC12M; - else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) - child->thread.debug.dbcr2 |= DBCR2_DAC12MX; - else /* PPC_BREAKPOINT_MODE_MASK */ - child->thread.debug.dbcr2 |= DBCR2_DAC12MM; - child->thread.regs->msr |= MSR_DE; - - return 5; -} -#endif /* CONFIG_PPC_ADV_DEBUG_DAC_RANGE */ - -static long ppc_set_hwdebug(struct task_struct *child, - struct ppc_hw_breakpoint *bp_info) -{ -#ifdef CONFIG_HAVE_HW_BREAKPOINT - int len = 0; - struct thread_struct *thread = &(child->thread); - struct perf_event *bp; - struct perf_event_attr attr; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#ifndef CONFIG_PPC_ADV_DEBUG_REGS - struct arch_hw_breakpoint brk; -#endif - - if (bp_info->version != 1) - return -ENOTSUPP; -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - /* - * Check for invalid flags and combinations - */ - if ((bp_info->trigger_type == 0) || - (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE | - PPC_BREAKPOINT_TRIGGER_RW)) || - (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) || - (bp_info->condition_mode & - ~(PPC_BREAKPOINT_CONDITION_MODE | - PPC_BREAKPOINT_CONDITION_BE_ALL))) - return -EINVAL; -#if CONFIG_PPC_ADV_DEBUG_DVCS == 0 - if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) - return -EINVAL; -#endif - - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) { - if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) || - (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)) - return -EINVAL; - return set_instruction_bp(child, bp_info); - } - if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) - return set_dac(child, bp_info); - -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - return set_dac_range(child, bp_info); -#else - return -EINVAL; -#endif -#else /* !CONFIG_PPC_ADV_DEBUG_DVCS */ - /* - * We only support one data breakpoint - */ - if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || - (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || - bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) - return -EINVAL; - - if ((unsigned long)bp_info->addr >= TASK_SIZE) - return -EIO; - - brk.address = bp_info->addr & ~HW_BREAKPOINT_ALIGN; - brk.type = HW_BRK_TYPE_TRANSLATE; - brk.len = DABR_MAX_LEN; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) - brk.type |= HW_BRK_TYPE_READ; - if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) - brk.type |= HW_BRK_TYPE_WRITE; -#ifdef CONFIG_HAVE_HW_BREAKPOINT - if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) - len = bp_info->addr2 - bp_info->addr; - else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) - len = 1; - else - return -EINVAL; - bp = thread->ptrace_bps[0]; - if (bp) - return -ENOSPC; - - /* Create a new breakpoint request if one doesn't exist already */ - hw_breakpoint_init(&attr); - attr.bp_addr = (unsigned long)bp_info->addr; - attr.bp_len = len; - arch_bp_generic_fields(brk.type, &attr.bp_type); - - thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, - ptrace_triggered, NULL, child); - if (IS_ERR(bp)) { - thread->ptrace_bps[0] = NULL; - return PTR_ERR(bp); - } - - return 1; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - - if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) - return -EINVAL; - - if (child->thread.hw_brk.address) - return -ENOSPC; - - if (!ppc_breakpoint_available()) - return -ENODEV; - - child->thread.hw_brk = brk; - - return 1; -#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ -} - -static long ppc_del_hwdebug(struct task_struct *child, long data) -{ -#ifdef CONFIG_HAVE_HW_BREAKPOINT - int ret = 0; - struct thread_struct *thread = &(child->thread); - struct perf_event *bp; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - int rc; - - if (data <= 4) - rc = del_instruction_bp(child, (int)data); - else - rc = del_dac(child, (int)data - 4); - - if (!rc) { - if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0, - child->thread.debug.dbcr1)) { - child->thread.debug.dbcr0 &= ~DBCR0_IDM; - child->thread.regs->msr &= ~MSR_DE; - } - } - return rc; -#else - if (data != 1) - return -EINVAL; - -#ifdef CONFIG_HAVE_HW_BREAKPOINT - bp = thread->ptrace_bps[0]; - if (bp) { - unregister_hw_breakpoint(bp); - thread->ptrace_bps[0] = NULL; - } else - ret = -ENOENT; - return ret; -#else /* CONFIG_HAVE_HW_BREAKPOINT */ - if (child->thread.hw_brk.address == 0) - return -ENOENT; - - child->thread.hw_brk.address = 0; - child->thread.hw_brk.type = 0; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - - return 0; -#endif -} - -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EPERM; - void __user *datavp = (void __user *) data; - unsigned long __user *datalp = datavp; - - switch (request) { - /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long index, tmp; - - ret = -EIO; - /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif - break; - - CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { - ret = ptrace_get_reg(child, (int) index, &tmp); - if (ret) - break; - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&tmp, &child->thread.TS_FPR(fpidx), - sizeof(long)); - else - tmp = child->thread.fp_state.fpscr; - } - ret = put_user(tmp, datalp); - break; - } - - /* write the word at location addr in the USER area */ - case PTRACE_POKEUSR: { - unsigned long index; - - ret = -EIO; - /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif - break; - - CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { - ret = ptrace_put_reg(child, index, data); - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, - sizeof(long)); - else - child->thread.fp_state.fpscr = data; - ret = 0; - } - break; - } - - case PPC_PTRACE_GETHWDBGINFO: { - struct ppc_debug_info dbginfo; - - dbginfo.version = 1; -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - dbginfo.num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS; - dbginfo.num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS; - dbginfo.num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS; - dbginfo.data_bp_alignment = 4; - dbginfo.sizeof_condition = 4; - dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE | - PPC_DEBUG_FEATURE_INSN_BP_MASK; -#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - dbginfo.features |= - PPC_DEBUG_FEATURE_DATA_BP_RANGE | - PPC_DEBUG_FEATURE_DATA_BP_MASK; -#endif -#else /* !CONFIG_PPC_ADV_DEBUG_REGS */ - dbginfo.num_instruction_bps = 0; - if (ppc_breakpoint_available()) - dbginfo.num_data_bps = 1; - else - dbginfo.num_data_bps = 0; - dbginfo.num_condition_regs = 0; -#ifdef CONFIG_PPC64 - dbginfo.data_bp_alignment = 8; -#else - dbginfo.data_bp_alignment = 4; -#endif - dbginfo.sizeof_condition = 0; -#ifdef CONFIG_HAVE_HW_BREAKPOINT - dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; - if (dawr_enabled()) - dbginfo.features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR; -#else - dbginfo.features = 0; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ - - if (copy_to_user(datavp, &dbginfo, - sizeof(struct ppc_debug_info))) - return -EFAULT; - return 0; - } - - case PPC_PTRACE_SETHWDEBUG: { - struct ppc_hw_breakpoint bp_info; - - if (copy_from_user(&bp_info, datavp, - sizeof(struct ppc_hw_breakpoint))) - return -EFAULT; - return ppc_set_hwdebug(child, &bp_info); - } - - case PPC_PTRACE_DELHWDEBUG: { - ret = ppc_del_hwdebug(child, data); - break; - } - - case PTRACE_GET_DEBUGREG: { -#ifndef CONFIG_PPC_ADV_DEBUG_REGS - unsigned long dabr_fake; -#endif - ret = -EINVAL; - /* We only support one DABR and no IABRS at the moment */ - if (addr > 0) - break; -#ifdef CONFIG_PPC_ADV_DEBUG_REGS - ret = put_user(child->thread.debug.dac1, datalp); -#else - dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | - (child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); - ret = put_user(dabr_fake, datalp); -#endif - break; - } - - case PTRACE_SET_DEBUGREG: - ret = ptrace_set_debugreg(child, addr, data); - break; - -#ifdef CONFIG_PPC64 - case PTRACE_GETREGS64: -#endif - case PTRACE_GETREGS: /* Get all pt_regs from the child. */ - return copy_regset_to_user(child, &user_ppc_native_view, - REGSET_GPR, - 0, sizeof(struct user_pt_regs), - datavp); - -#ifdef CONFIG_PPC64 - case PTRACE_SETREGS64: -#endif - case PTRACE_SETREGS: /* Set all gp regs in the child. */ - return copy_regset_from_user(child, &user_ppc_native_view, - REGSET_GPR, - 0, sizeof(struct user_pt_regs), - datavp); - - case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ - return copy_regset_to_user(child, &user_ppc_native_view, - REGSET_FPR, - 0, sizeof(elf_fpregset_t), - datavp); - - case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ - return copy_regset_from_user(child, &user_ppc_native_view, - REGSET_FPR, - 0, sizeof(elf_fpregset_t), - datavp); - -#ifdef CONFIG_ALTIVEC - case PTRACE_GETVRREGS: - return copy_regset_to_user(child, &user_ppc_native_view, - REGSET_VMX, - 0, (33 * sizeof(vector128) + - sizeof(u32)), - datavp); - - case PTRACE_SETVRREGS: - return copy_regset_from_user(child, &user_ppc_native_view, - REGSET_VMX, - 0, (33 * sizeof(vector128) + - sizeof(u32)), - datavp); -#endif -#ifdef CONFIG_VSX - case PTRACE_GETVSRREGS: - return copy_regset_to_user(child, &user_ppc_native_view, - REGSET_VSX, - 0, 32 * sizeof(double), - datavp); - - case PTRACE_SETVSRREGS: - return copy_regset_from_user(child, &user_ppc_native_view, - REGSET_VSX, - 0, 32 * sizeof(double), - datavp); -#endif -#ifdef CONFIG_SPE - case PTRACE_GETEVRREGS: - /* Get the child spe register state. */ - return copy_regset_to_user(child, &user_ppc_native_view, - REGSET_SPE, 0, 35 * sizeof(u32), - datavp); - - case PTRACE_SETEVRREGS: - /* Set the child spe register state. */ - return copy_regset_from_user(child, &user_ppc_native_view, - REGSET_SPE, 0, 35 * sizeof(u32), - datavp); -#endif - - default: - ret = ptrace_request(child, request, addr, data); - break; - } - return ret; -} - -#ifdef CONFIG_SECCOMP -static int do_seccomp(struct pt_regs *regs) -{ - if (!test_thread_flag(TIF_SECCOMP)) - return 0; - - /* - * The ABI we present to seccomp tracers is that r3 contains - * the syscall return value and orig_gpr3 contains the first - * syscall parameter. This is different to the ptrace ABI where - * both r3 and orig_gpr3 contain the first syscall parameter. - */ - regs->gpr[3] = -ENOSYS; - - /* - * We use the __ version here because we have already checked - * TIF_SECCOMP. If this fails, there is nothing left to do, we - * have already loaded -ENOSYS into r3, or seccomp has put - * something else in r3 (via SECCOMP_RET_ERRNO/TRACE). - */ - if (__secure_computing(NULL)) - return -1; - - /* - * The syscall was allowed by seccomp, restore the register - * state to what audit expects. - * Note that we use orig_gpr3, which means a seccomp tracer can - * modify the first syscall parameter (in orig_gpr3) and also - * allow the syscall to proceed. - */ - regs->gpr[3] = regs->orig_gpr3; - - return 0; -} -#else -static inline int do_seccomp(struct pt_regs *regs) { return 0; } -#endif /* CONFIG_SECCOMP */ - -/** - * do_syscall_trace_enter() - Do syscall tracing on kernel entry. - * @regs: the pt_regs of the task to trace (current) - * - * Performs various types of tracing on syscall entry. This includes seccomp, - * ptrace, syscall tracepoints and audit. - * - * The pt_regs are potentially visible to userspace via ptrace, so their - * contents is ABI. - * - * One or more of the tracers may modify the contents of pt_regs, in particular - * to modify arguments or even the syscall number itself. - * - * It's also possible that a tracer can choose to reject the system call. In - * that case this function will return an illegal syscall number, and will put - * an appropriate return value in regs->r3. - * - * Return: the (possibly changed) syscall number. - */ -long do_syscall_trace_enter(struct pt_regs *regs) -{ - u32 flags; - - user_exit(); - - flags = READ_ONCE(current_thread_info()->flags) & - (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); - - if (flags) { - int rc = tracehook_report_syscall_entry(regs); - - if (unlikely(flags & _TIF_SYSCALL_EMU)) { - /* - * A nonzero return code from - * tracehook_report_syscall_entry() tells us to prevent - * the syscall execution, but we are not going to - * execute it anyway. - * - * Returning -1 will skip the syscall execution. We want - * to avoid clobbering any registers, so we don't goto - * the skip label below. - */ - return -1; - } - - if (rc) { - /* - * The tracer decided to abort the syscall. Note that - * the tracer may also just change regs->gpr[0] to an - * invalid syscall number, that is handled below on the - * exit path. - */ - goto skip; - } - } - - /* Run seccomp after ptrace; allow it to set gpr[3]. */ - if (do_seccomp(regs)) - return -1; - - /* Avoid trace and audit when syscall is invalid. */ - if (regs->gpr[0] >= NR_syscalls) - goto skip; - - if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_enter(regs, regs->gpr[0]); - -#ifdef CONFIG_PPC64 - if (!is_32bit_task()) - audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4], - regs->gpr[5], regs->gpr[6]); - else -#endif - audit_syscall_entry(regs->gpr[0], - regs->gpr[3] & 0xffffffff, - regs->gpr[4] & 0xffffffff, - regs->gpr[5] & 0xffffffff, - regs->gpr[6] & 0xffffffff); - - /* Return the possibly modified but valid syscall number */ - return regs->gpr[0]; - -skip: - /* - * If we are aborting explicitly, or if the syscall number is - * now invalid, set the return value to -ENOSYS. - */ - regs->gpr[3] = -ENOSYS; - return -1; -} - -void do_syscall_trace_leave(struct pt_regs *regs) -{ - int step; - - audit_syscall_exit(regs); - - if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_exit(regs, regs->result); - - step = test_thread_flag(TIF_SINGLESTEP); - if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, step); - - user_enter(); -} - -void __init pt_regs_check(void); - -/* - * Dummy function, its purpose is to break the build if struct pt_regs and - * struct user_pt_regs don't match. - */ -void __init pt_regs_check(void) -{ - BUILD_BUG_ON(offsetof(struct pt_regs, gpr) != - offsetof(struct user_pt_regs, gpr)); - BUILD_BUG_ON(offsetof(struct pt_regs, nip) != - offsetof(struct user_pt_regs, nip)); - BUILD_BUG_ON(offsetof(struct pt_regs, msr) != - offsetof(struct user_pt_regs, msr)); - BUILD_BUG_ON(offsetof(struct pt_regs, msr) != - offsetof(struct user_pt_regs, msr)); - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct user_pt_regs, orig_gpr3)); - BUILD_BUG_ON(offsetof(struct pt_regs, ctr) != - offsetof(struct user_pt_regs, ctr)); - BUILD_BUG_ON(offsetof(struct pt_regs, link) != - offsetof(struct user_pt_regs, link)); - BUILD_BUG_ON(offsetof(struct pt_regs, xer) != - offsetof(struct user_pt_regs, xer)); - BUILD_BUG_ON(offsetof(struct pt_regs, ccr) != - offsetof(struct user_pt_regs, ccr)); -#ifdef __powerpc64__ - BUILD_BUG_ON(offsetof(struct pt_regs, softe) != - offsetof(struct user_pt_regs, softe)); -#else - BUILD_BUG_ON(offsetof(struct pt_regs, mq) != - offsetof(struct user_pt_regs, mq)); -#endif - BUILD_BUG_ON(offsetof(struct pt_regs, trap) != - offsetof(struct user_pt_regs, trap)); - BUILD_BUG_ON(offsetof(struct pt_regs, dar) != - offsetof(struct user_pt_regs, dar)); - BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) != - offsetof(struct user_pt_regs, dsisr)); - BUILD_BUG_ON(offsetof(struct pt_regs, result) != - offsetof(struct user_pt_regs, result)); - - BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs)); - - // Now check that the pt_regs offsets match the uapi #defines - #define CHECK_REG(_pt, _reg) \ - BUILD_BUG_ON(_pt != (offsetof(struct user_pt_regs, _reg) / \ - sizeof(unsigned long))); - - CHECK_REG(PT_R0, gpr[0]); - CHECK_REG(PT_R1, gpr[1]); - CHECK_REG(PT_R2, gpr[2]); - CHECK_REG(PT_R3, gpr[3]); - CHECK_REG(PT_R4, gpr[4]); - CHECK_REG(PT_R5, gpr[5]); - CHECK_REG(PT_R6, gpr[6]); - CHECK_REG(PT_R7, gpr[7]); - CHECK_REG(PT_R8, gpr[8]); - CHECK_REG(PT_R9, gpr[9]); - CHECK_REG(PT_R10, gpr[10]); - CHECK_REG(PT_R11, gpr[11]); - CHECK_REG(PT_R12, gpr[12]); - CHECK_REG(PT_R13, gpr[13]); - CHECK_REG(PT_R14, gpr[14]); - CHECK_REG(PT_R15, gpr[15]); - CHECK_REG(PT_R16, gpr[16]); - CHECK_REG(PT_R17, gpr[17]); - CHECK_REG(PT_R18, gpr[18]); - CHECK_REG(PT_R19, gpr[19]); - CHECK_REG(PT_R20, gpr[20]); - CHECK_REG(PT_R21, gpr[21]); - CHECK_REG(PT_R22, gpr[22]); - CHECK_REG(PT_R23, gpr[23]); - CHECK_REG(PT_R24, gpr[24]); - CHECK_REG(PT_R25, gpr[25]); - CHECK_REG(PT_R26, gpr[26]); - CHECK_REG(PT_R27, gpr[27]); - CHECK_REG(PT_R28, gpr[28]); - CHECK_REG(PT_R29, gpr[29]); - CHECK_REG(PT_R30, gpr[30]); - CHECK_REG(PT_R31, gpr[31]); - CHECK_REG(PT_NIP, nip); - CHECK_REG(PT_MSR, msr); - CHECK_REG(PT_ORIG_R3, orig_gpr3); - CHECK_REG(PT_CTR, ctr); - CHECK_REG(PT_LNK, link); - CHECK_REG(PT_XER, xer); - CHECK_REG(PT_CCR, ccr); -#ifdef CONFIG_PPC64 - CHECK_REG(PT_SOFTE, softe); -#else - CHECK_REG(PT_MQ, mq); -#endif - CHECK_REG(PT_TRAP, trap); - CHECK_REG(PT_DAR, dar); - CHECK_REG(PT_DSISR, dsisr); - CHECK_REG(PT_RESULT, result); - #undef CHECK_REG - - BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long)); - - /* - * PT_DSCR isn't a real reg, but it's important that it doesn't overlap the - * real registers. - */ - BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long)); -} diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile new file mode 100644 index 000000000000..c2f2402ebc8c --- /dev/null +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the linux kernel. +# + +CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' + +obj-y += ptrace.o ptrace-view.o +obj-$(CONFIG_COMPAT) += ptrace32.o +obj-$(CONFIG_VSX) += ptrace-vsx.o +ifneq ($(CONFIG_VSX),y) +obj-y += ptrace-novsx.o +endif +obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o +obj-$(CONFIG_SPE) += ptrace-spe.o +obj-$(CONFIG_PPC_TRANSACTIONAL_MEM) += ptrace-tm.o +obj-$(CONFIG_PPC_ADV_DEBUG_REGS) += ptrace-adv.o +ifneq ($(CONFIG_PPC_ADV_DEBUG_REGS),y) +obj-y += ptrace-noadv.o +endif diff --git a/arch/powerpc/kernel/ptrace/ptrace-adv.c b/arch/powerpc/kernel/ptrace/ptrace-adv.c new file mode 100644 index 000000000000..3990c01ef8cf --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-adv.c @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> +#include <linux/hw_breakpoint.h> + +#include "ptrace-decl.h" + +void user_enable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + task->thread.debug.dbcr0 &= ~DBCR0_BT; + task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; + regs->msr |= MSR_DE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_enable_block_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + task->thread.debug.dbcr0 &= ~DBCR0_IC; + task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; + regs->msr |= MSR_DE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + /* + * The logic to disable single stepping should be as + * simple as turning off the Instruction Complete flag. + * And, after doing so, if all debug flags are off, turn + * off DBCR0(IDM) and MSR(DE) .... Torez + */ + task->thread.debug.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); + /* + * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. + */ + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { + /* + * All debug events were off..... + */ + task->thread.debug.dbcr0 &= ~DBCR0_IDM; + regs->msr &= ~MSR_DE; + } + } + clear_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void ppc_gethwdinfo(struct ppc_debug_info *dbginfo) +{ + dbginfo->version = 1; + dbginfo->num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS; + dbginfo->num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS; + dbginfo->num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS; + dbginfo->data_bp_alignment = 4; + dbginfo->sizeof_condition = 4; + dbginfo->features = PPC_DEBUG_FEATURE_INSN_BP_RANGE | + PPC_DEBUG_FEATURE_INSN_BP_MASK; + if (IS_ENABLED(CONFIG_PPC_ADV_DEBUG_DAC_RANGE)) + dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_RANGE | + PPC_DEBUG_FEATURE_DATA_BP_MASK; +} + +int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, + unsigned long __user *datalp) +{ + /* We only support one DABR and no IABRS at the moment */ + if (addr > 0) + return -EINVAL; + return put_user(child->thread.debug.dac1, datalp); +} + +int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data) +{ +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int ret; + struct thread_struct *thread = &task->thread; + struct perf_event *bp; + struct perf_event_attr attr; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). + * For embedded processors we support one DAC and no IAC's at the + * moment. + */ + if (addr > 0) + return -EINVAL; + + /* The bottom 3 bits in dabr are flags */ + if ((data & ~0x7UL) >= TASK_SIZE) + return -EIO; + + /* As described above, it was assumed 3 bits were passed with the data + * address, but we will assume only the mode bits will be passed + * as to not cause alignment restrictions for DAC-based processors. + */ + + /* DAC's hold the whole address without any mode flags */ + task->thread.debug.dac1 = data & ~0x3UL; + + if (task->thread.debug.dac1 == 0) { + dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { + task->thread.regs->msr &= ~MSR_DE; + task->thread.debug.dbcr0 &= ~DBCR0_IDM; + } + return 0; + } + + /* Read or Write bits must be set */ + + if (!(data & 0x3UL)) + return -EINVAL; + + /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 register */ + task->thread.debug.dbcr0 |= DBCR0_IDM; + + /* Check for write and read flags and set DBCR0 accordingly */ + dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); + if (data & 0x1UL) + dbcr_dac(task) |= DBCR_DAC1R; + if (data & 0x2UL) + dbcr_dac(task) |= DBCR_DAC1W; + task->thread.regs->msr |= MSR_DE; + return 0; +} + +static long set_instruction_bp(struct task_struct *child, + struct ppc_hw_breakpoint *bp_info) +{ + int slot; + int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0); + int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0); + int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0); + int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0); + + if (dbcr_iac_range(child) & DBCR_IAC12MODE) + slot2_in_use = 1; + if (dbcr_iac_range(child) & DBCR_IAC34MODE) + slot4_in_use = 1; + + if (bp_info->addr >= TASK_SIZE) + return -EIO; + + if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) { + /* Make sure range is valid. */ + if (bp_info->addr2 >= TASK_SIZE) + return -EIO; + + /* We need a pair of IAC regsisters */ + if (!slot1_in_use && !slot2_in_use) { + slot = 1; + child->thread.debug.iac1 = bp_info->addr; + child->thread.debug.iac2 = bp_info->addr2; + child->thread.debug.dbcr0 |= DBCR0_IAC1; + if (bp_info->addr_mode == + PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) + dbcr_iac_range(child) |= DBCR_IAC12X; + else + dbcr_iac_range(child) |= DBCR_IAC12I; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 + } else if ((!slot3_in_use) && (!slot4_in_use)) { + slot = 3; + child->thread.debug.iac3 = bp_info->addr; + child->thread.debug.iac4 = bp_info->addr2; + child->thread.debug.dbcr0 |= DBCR0_IAC3; + if (bp_info->addr_mode == + PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) + dbcr_iac_range(child) |= DBCR_IAC34X; + else + dbcr_iac_range(child) |= DBCR_IAC34I; +#endif + } else { + return -ENOSPC; + } + } else { + /* We only need one. If possible leave a pair free in + * case a range is needed later + */ + if (!slot1_in_use) { + /* + * Don't use iac1 if iac1-iac2 are free and either + * iac3 or iac4 (but not both) are free + */ + if (slot2_in_use || slot3_in_use == slot4_in_use) { + slot = 1; + child->thread.debug.iac1 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC1; + goto out; + } + } + if (!slot2_in_use) { + slot = 2; + child->thread.debug.iac2 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC2; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 + } else if (!slot3_in_use) { + slot = 3; + child->thread.debug.iac3 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC3; + } else if (!slot4_in_use) { + slot = 4; + child->thread.debug.iac4 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC4; +#endif + } else { + return -ENOSPC; + } + } +out: + child->thread.debug.dbcr0 |= DBCR0_IDM; + child->thread.regs->msr |= MSR_DE; + + return slot; +} + +static int del_instruction_bp(struct task_struct *child, int slot) +{ + switch (slot) { + case 1: + if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0) + return -ENOENT; + + if (dbcr_iac_range(child) & DBCR_IAC12MODE) { + /* address range - clear slots 1 & 2 */ + child->thread.debug.iac2 = 0; + dbcr_iac_range(child) &= ~DBCR_IAC12MODE; + } + child->thread.debug.iac1 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC1; + break; + case 2: + if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0) + return -ENOENT; + + if (dbcr_iac_range(child) & DBCR_IAC12MODE) + /* used in a range */ + return -EINVAL; + child->thread.debug.iac2 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC2; + break; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 + case 3: + if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0) + return -ENOENT; + + if (dbcr_iac_range(child) & DBCR_IAC34MODE) { + /* address range - clear slots 3 & 4 */ + child->thread.debug.iac4 = 0; + dbcr_iac_range(child) &= ~DBCR_IAC34MODE; + } + child->thread.debug.iac3 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC3; + break; + case 4: + if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0) + return -ENOENT; + + if (dbcr_iac_range(child) & DBCR_IAC34MODE) + /* Used in a range */ + return -EINVAL; + child->thread.debug.iac4 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC4; + break; +#endif + default: + return -EINVAL; + } + return 0; +} + +static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) +{ + int byte_enable = + (bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT) + & 0xf; + int condition_mode = + bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE; + int slot; + + if (byte_enable && condition_mode == 0) + return -EINVAL; + + if (bp_info->addr >= TASK_SIZE) + return -EIO; + + if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) { + slot = 1; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) + dbcr_dac(child) |= DBCR_DAC1R; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) + dbcr_dac(child) |= DBCR_DAC1W; + child->thread.debug.dac1 = (unsigned long)bp_info->addr; +#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 + if (byte_enable) { + child->thread.debug.dvc1 = + (unsigned long)bp_info->condition_value; + child->thread.debug.dbcr2 |= + ((byte_enable << DBCR2_DVC1BE_SHIFT) | + (condition_mode << DBCR2_DVC1M_SHIFT)); + } +#endif +#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE + } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { + /* Both dac1 and dac2 are part of a range */ + return -ENOSPC; +#endif + } else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) { + slot = 2; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) + dbcr_dac(child) |= DBCR_DAC2R; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) + dbcr_dac(child) |= DBCR_DAC2W; + child->thread.debug.dac2 = (unsigned long)bp_info->addr; +#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 + if (byte_enable) { + child->thread.debug.dvc2 = + (unsigned long)bp_info->condition_value; + child->thread.debug.dbcr2 |= + ((byte_enable << DBCR2_DVC2BE_SHIFT) | + (condition_mode << DBCR2_DVC2M_SHIFT)); + } +#endif + } else { + return -ENOSPC; + } + child->thread.debug.dbcr0 |= DBCR0_IDM; + child->thread.regs->msr |= MSR_DE; + + return slot + 4; +} + +static int del_dac(struct task_struct *child, int slot) +{ + if (slot == 1) { + if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) + return -ENOENT; + + child->thread.debug.dac1 = 0; + dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); +#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE + if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { + child->thread.debug.dac2 = 0; + child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE; + } + child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); +#endif +#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 + child->thread.debug.dvc1 = 0; +#endif + } else if (slot == 2) { + if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) + return -ENOENT; + +#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE + if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) + /* Part of a range */ + return -EINVAL; + child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); +#endif +#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 + child->thread.debug.dvc2 = 0; +#endif + child->thread.debug.dac2 = 0; + dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); + } else { + return -EINVAL; + } + + return 0; +} + +#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE +static int set_dac_range(struct task_struct *child, + struct ppc_hw_breakpoint *bp_info) +{ + int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK; + + /* We don't allow range watchpoints to be used with DVC */ + if (bp_info->condition_mode) + return -EINVAL; + + /* + * Best effort to verify the address range. The user/supervisor bits + * prevent trapping in kernel space, but let's fail on an obvious bad + * range. The simple test on the mask is not fool-proof, and any + * exclusive range will spill over into kernel space. + */ + if (bp_info->addr >= TASK_SIZE) + return -EIO; + if (mode == PPC_BREAKPOINT_MODE_MASK) { + /* + * dac2 is a bitmask. Don't allow a mask that makes a + * kernel space address from a valid dac1 value + */ + if (~((unsigned long)bp_info->addr2) >= TASK_SIZE) + return -EIO; + } else { + /* + * For range breakpoints, addr2 must also be a valid address + */ + if (bp_info->addr2 >= TASK_SIZE) + return -EIO; + } + + if (child->thread.debug.dbcr0 & + (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) + return -ENOSPC; + + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) + child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) + child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); + child->thread.debug.dac1 = bp_info->addr; + child->thread.debug.dac2 = bp_info->addr2; + if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) + child->thread.debug.dbcr2 |= DBCR2_DAC12M; + else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) + child->thread.debug.dbcr2 |= DBCR2_DAC12MX; + else /* PPC_BREAKPOINT_MODE_MASK */ + child->thread.debug.dbcr2 |= DBCR2_DAC12MM; + child->thread.regs->msr |= MSR_DE; + + return 5; +} +#endif /* CONFIG_PPC_ADV_DEBUG_DAC_RANGE */ + +long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) +{ + if (bp_info->version != 1) + return -ENOTSUPP; + /* + * Check for invalid flags and combinations + */ + if (bp_info->trigger_type == 0 || + (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE | + PPC_BREAKPOINT_TRIGGER_RW)) || + (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) || + (bp_info->condition_mode & + ~(PPC_BREAKPOINT_CONDITION_MODE | + PPC_BREAKPOINT_CONDITION_BE_ALL))) + return -EINVAL; +#if CONFIG_PPC_ADV_DEBUG_DVCS == 0 + if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) + return -EINVAL; +#endif + + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) { + if (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE || + bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) + return -EINVAL; + return set_instruction_bp(child, bp_info); + } + if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) + return set_dac(child, bp_info); + +#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE + return set_dac_range(child, bp_info); +#else + return -EINVAL; +#endif +} + +long ppc_del_hwdebug(struct task_struct *child, long data) +{ + int rc; + + if (data <= 4) + rc = del_instruction_bp(child, (int)data); + else + rc = del_dac(child, (int)data - 4); + + if (!rc) { + if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0, + child->thread.debug.dbcr1)) { + child->thread.debug.dbcr0 &= ~DBCR0_IDM; + child->thread.regs->msr &= ~MSR_DE; + } + } + return rc; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-altivec.c b/arch/powerpc/kernel/ptrace/ptrace-altivec.c new file mode 100644 index 000000000000..dd8b75dfbd06 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-altivec.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> +#include <linux/elf.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +/* + * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go. + * The transfer totals 34 quadword. Quadwords 0-31 contain the + * corresponding vector registers. Quadword 32 contains the vscr as the + * last word (offset 12) within that quadword. Quadword 33 contains the + * vrsave as the first word (offset 0) within the quadword. + * + * This definition of the VMX state is compatible with the current PPC32 + * ptrace interface. This allows signal handling and ptrace to use the + * same structures. This also simplifies the implementation of a bi-arch + * (combined (32- and 64-bit) gdb. + */ + +int vr_active(struct task_struct *target, const struct user_regset *regset) +{ + flush_altivec_to_thread(target); + return target->thread.used_vr ? regset->n : 0; +} + +/* + * Regardless of transactions, 'vr_state' holds the current running + * value of all the VMX registers and 'ckvr_state' holds the last + * checkpointed value of all the VMX registers for the current + * transaction to fall back on in case it aborts. + * + * Userspace interface buffer layout: + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + * }; + */ +int vr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + flush_altivec_to_thread(target); + + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != + offsetof(struct thread_vr_state, vr[32])); + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.vr_state, 0, + 33 * sizeof(vector128)); + if (!ret) { + /* + * Copy out only the low-order word of vrsave. + */ + int start, end; + union { + elf_vrreg_t reg; + u32 word; + } vrsave; + memset(&vrsave, 0, sizeof(vrsave)); + + vrsave.word = target->thread.vrsave; + + start = 33 * sizeof(vector128); + end = start + sizeof(vrsave); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave, + start, end); + } + + return ret; +} + +/* + * Regardless of transactions, 'vr_state' holds the current running + * value of all the VMX registers and 'ckvr_state' holds the last + * checkpointed value of all the VMX registers for the current + * transaction to fall back on in case it aborts. + * + * Userspace interface buffer layout: + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + * }; + */ +int vr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + flush_altivec_to_thread(target); + + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != + offsetof(struct thread_vr_state, vr[32])); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.vr_state, 0, + 33 * sizeof(vector128)); + if (!ret && count > 0) { + /* + * We use only the first word of vrsave. + */ + int start, end; + union { + elf_vrreg_t reg; + u32 word; + } vrsave; + memset(&vrsave, 0, sizeof(vrsave)); + + vrsave.word = target->thread.vrsave; + + start = 33 * sizeof(vector128); + end = start + sizeof(vrsave); + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave, + start, end); + if (!ret) + target->thread.vrsave = vrsave.word; + } + + return ret; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h new file mode 100644 index 000000000000..3c8a81999292 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Set of msr bits that gdb can change on behalf of a process. + */ +#ifdef CONFIG_PPC_ADV_DEBUG_REGS +#define MSR_DEBUGCHANGE 0 +#else +#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) +#endif + +/* + * Max register writeable via put_reg + */ +#ifdef CONFIG_PPC32 +#define PT_MAX_PUT_REG PT_MQ +#else +#define PT_MAX_PUT_REG PT_CCR +#endif + +#define TVSO(f) (offsetof(struct thread_vr_state, f)) +#define TFSO(f) (offsetof(struct thread_fp_state, f)) +#define TSO(f) (offsetof(struct thread_struct, f)) + +/* + * These are our native regset flavors. + */ +enum powerpc_regset { + REGSET_GPR, + REGSET_FPR, +#ifdef CONFIG_ALTIVEC + REGSET_VMX, +#endif +#ifdef CONFIG_VSX + REGSET_VSX, +#endif +#ifdef CONFIG_SPE + REGSET_SPE, +#endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + REGSET_TM_CGPR, /* TM checkpointed GPR registers */ + REGSET_TM_CFPR, /* TM checkpointed FPR registers */ + REGSET_TM_CVMX, /* TM checkpointed VMX registers */ + REGSET_TM_CVSX, /* TM checkpointed VSX registers */ + REGSET_TM_SPR, /* TM specific SPR registers */ + REGSET_TM_CTAR, /* TM checkpointed TAR register */ + REGSET_TM_CPPR, /* TM checkpointed PPR register */ + REGSET_TM_CDSCR, /* TM checkpointed DSCR register */ +#endif +#ifdef CONFIG_PPC64 + REGSET_PPR, /* PPR register */ + REGSET_DSCR, /* DSCR register */ +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + REGSET_TAR, /* TAR register */ + REGSET_EBB, /* EBB registers */ + REGSET_PMR, /* Performance Monitor Registers */ +#endif +#ifdef CONFIG_PPC_MEM_KEYS + REGSET_PKEY, /* AMR register */ +#endif +}; + +/* ptrace-(no)vsx */ + +int fpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int fpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); + +/* ptrace-vsx */ + +int vsr_active(struct task_struct *target, const struct user_regset *regset); +int vsr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int vsr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); + +/* ptrace-altivec */ + +int vr_active(struct task_struct *target, const struct user_regset *regset); +int vr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int vr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); + +/* ptrace-spe */ + +int evr_active(struct task_struct *target, const struct user_regset *regset); +int evr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int evr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); + +/* ptrace */ + +int gpr32_get_common(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf, + unsigned long *regs); +int gpr32_set_common(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf, + unsigned long *regs); + +/* ptrace-tm */ + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +void flush_tmregs_to_thread(struct task_struct *tsk); +#else +static inline void flush_tmregs_to_thread(struct task_struct *tsk) { } +#endif + +int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset); +int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset); +int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset); +int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset); +int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_spr_active(struct task_struct *target, const struct user_regset *regset); +int tm_spr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_spr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_tar_active(struct task_struct *target, const struct user_regset *regset); +int tm_tar_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_tar_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_ppr_active(struct task_struct *target, const struct user_regset *regset); +int tm_ppr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_ppr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_dscr_active(struct task_struct *target, const struct user_regset *regset); +int tm_dscr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_dscr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); +int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf); +int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf); + +/* ptrace-view */ + +extern const struct user_regset_view user_ppc_native_view; + +/* ptrace-(no)adv */ +void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); +int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, + unsigned long __user *datalp); +int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data); +long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info); +long ppc_del_hwdebug(struct task_struct *child, long data); diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c new file mode 100644 index 000000000000..f87e7c5c3bf3 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> +#include <linux/hw_breakpoint.h> + +#include <asm/debug.h> + +#include "ptrace-decl.h" + +void user_enable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + regs->msr &= ~MSR_BE; + regs->msr |= MSR_SE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_enable_block_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + regs->msr &= ~MSR_SE; + regs->msr |= MSR_BE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) + regs->msr &= ~(MSR_SE | MSR_BE); + + clear_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void ppc_gethwdinfo(struct ppc_debug_info *dbginfo) +{ + dbginfo->version = 1; + dbginfo->num_instruction_bps = 0; + if (ppc_breakpoint_available()) + dbginfo->num_data_bps = 1; + else + dbginfo->num_data_bps = 0; + dbginfo->num_condition_regs = 0; + dbginfo->data_bp_alignment = sizeof(long); + dbginfo->sizeof_condition = 0; + if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT)) { + dbginfo->features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; + if (dawr_enabled()) + dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR; + } else { + dbginfo->features = 0; + } +} + +int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, + unsigned long __user *datalp) +{ + unsigned long dabr_fake; + + /* We only support one DABR and no IABRS at the moment */ + if (addr > 0) + return -EINVAL; + dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | + (child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); + return put_user(dabr_fake, datalp); +} + +int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data) +{ +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int ret; + struct thread_struct *thread = &task->thread; + struct perf_event *bp; + struct perf_event_attr attr; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + bool set_bp = true; + struct arch_hw_breakpoint hw_brk; + + /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). + * For embedded processors we support one DAC and no IAC's at the + * moment. + */ + if (addr > 0) + return -EINVAL; + + /* The bottom 3 bits in dabr are flags */ + if ((data & ~0x7UL) >= TASK_SIZE) + return -EIO; + + /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. + * It was assumed, on previous implementations, that 3 bits were + * passed together with the data address, fitting the design of the + * DABR register, as follows: + * + * bit 0: Read flag + * bit 1: Write flag + * bit 2: Breakpoint translation + * + * Thus, we use them here as so. + */ + + /* Ensure breakpoint translation bit is set */ + if (data && !(data & HW_BRK_TYPE_TRANSLATE)) + return -EIO; + hw_brk.address = data & (~HW_BRK_TYPE_DABR); + hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; + hw_brk.len = DABR_MAX_LEN; + hw_brk.hw_len = DABR_MAX_LEN; + set_bp = (data) && (hw_brk.type & HW_BRK_TYPE_RDWR); +#ifdef CONFIG_HAVE_HW_BREAKPOINT + bp = thread->ptrace_bps[0]; + if (!set_bp) { + if (bp) { + unregister_hw_breakpoint(bp); + thread->ptrace_bps[0] = NULL; + } + return 0; + } + if (bp) { + attr = bp->attr; + attr.bp_addr = hw_brk.address; + attr.bp_len = DABR_MAX_LEN; + arch_bp_generic_fields(hw_brk.type, &attr.bp_type); + + /* Enable breakpoint */ + attr.disabled = false; + + ret = modify_user_hw_breakpoint(bp, &attr); + if (ret) + return ret; + + thread->ptrace_bps[0] = bp; + thread->hw_brk = hw_brk; + return 0; + } + + /* Create a new breakpoint request if one doesn't exist already */ + hw_breakpoint_init(&attr); + attr.bp_addr = hw_brk.address; + attr.bp_len = DABR_MAX_LEN; + arch_bp_generic_fields(hw_brk.type, + &attr.bp_type); + + thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, + ptrace_triggered, NULL, task); + if (IS_ERR(bp)) { + thread->ptrace_bps[0] = NULL; + return PTR_ERR(bp); + } + +#else /* !CONFIG_HAVE_HW_BREAKPOINT */ + if (set_bp && (!ppc_breakpoint_available())) + return -ENODEV; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + task->thread.hw_brk = hw_brk; + return 0; +} + +long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) +{ +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int len = 0; + struct thread_struct *thread = &child->thread; + struct perf_event *bp; + struct perf_event_attr attr; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + struct arch_hw_breakpoint brk; + + if (bp_info->version != 1) + return -ENOTSUPP; + /* + * We only support one data breakpoint + */ + if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || + (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || + bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) + return -EINVAL; + + if ((unsigned long)bp_info->addr >= TASK_SIZE) + return -EIO; + + brk.address = bp_info->addr & ~HW_BREAKPOINT_ALIGN; + brk.type = HW_BRK_TYPE_TRANSLATE; + brk.len = DABR_MAX_LEN; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) + brk.type |= HW_BRK_TYPE_READ; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) + brk.type |= HW_BRK_TYPE_WRITE; +#ifdef CONFIG_HAVE_HW_BREAKPOINT + if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) + len = bp_info->addr2 - bp_info->addr; + else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) + len = 1; + else + return -EINVAL; + bp = thread->ptrace_bps[0]; + if (bp) + return -ENOSPC; + + /* Create a new breakpoint request if one doesn't exist already */ + hw_breakpoint_init(&attr); + attr.bp_addr = (unsigned long)bp_info->addr; + attr.bp_len = len; + arch_bp_generic_fields(brk.type, &attr.bp_type); + + bp = register_user_hw_breakpoint(&attr, ptrace_triggered, NULL, child); + thread->ptrace_bps[0] = bp; + if (IS_ERR(bp)) { + thread->ptrace_bps[0] = NULL; + return PTR_ERR(bp); + } + + return 1; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) + return -EINVAL; + + if (child->thread.hw_brk.address) + return -ENOSPC; + + if (!ppc_breakpoint_available()) + return -ENODEV; + + child->thread.hw_brk = brk; + + return 1; +} + +long ppc_del_hwdebug(struct task_struct *child, long data) +{ +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int ret = 0; + struct thread_struct *thread = &child->thread; + struct perf_event *bp; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + if (data != 1) + return -EINVAL; + +#ifdef CONFIG_HAVE_HW_BREAKPOINT + bp = thread->ptrace_bps[0]; + if (bp) { + unregister_hw_breakpoint(bp); + thread->ptrace_bps[0] = NULL; + } else { + ret = -ENOENT; + } + return ret; +#else /* CONFIG_HAVE_HW_BREAKPOINT */ + if (child->thread.hw_brk.address == 0) + return -ENOENT; + + child->thread.hw_brk.address = 0; + child->thread.hw_brk.type = 0; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + return 0; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-novsx.c b/arch/powerpc/kernel/ptrace/ptrace-novsx.c new file mode 100644 index 000000000000..b2dc4e92d11a --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-novsx.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + */ +int fpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != + offsetof(struct thread_fp_state, fpr[32])); + + flush_fp_to_thread(target); + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.fp_state, 0, -1); +} + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + * + */ +int fpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != + offsetof(struct thread_fp_state, fpr[32])); + + flush_fp_to_thread(target); + + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.fp_state, 0, -1); +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-spe.c b/arch/powerpc/kernel/ptrace/ptrace-spe.c new file mode 100644 index 000000000000..68b86b4a4be4 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-spe.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +/* + * For get_evrregs/set_evrregs functions 'data' has the following layout: + * + * struct { + * u32 evr[32]; + * u64 acc; + * u32 spefscr; + * } + */ + +int evr_active(struct task_struct *target, const struct user_regset *regset) +{ + flush_spe_to_thread(target); + return target->thread.used_spe ? regset->n : 0; +} + +int evr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + flush_spe_to_thread(target); + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.evr, + 0, sizeof(target->thread.evr)); + + BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != + offsetof(struct thread_struct, spefscr)); + + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.acc, + sizeof(target->thread.evr), -1); + + return ret; +} + +int evr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + flush_spe_to_thread(target); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.evr, + 0, sizeof(target->thread.evr)); + + BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != + offsetof(struct thread_struct, spefscr)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.acc, + sizeof(target->thread.evr), -1); + + return ret; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c new file mode 100644 index 000000000000..d75aff31f637 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c @@ -0,0 +1,851 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> +#include <asm/tm.h> +#include <asm/asm-prototypes.h> + +#include "ptrace-decl.h" + +void flush_tmregs_to_thread(struct task_struct *tsk) +{ + /* + * If task is not current, it will have been flushed already to + * it's thread_struct during __switch_to(). + * + * A reclaim flushes ALL the state or if not in TM save TM SPRs + * in the appropriate thread structures from live. + */ + + if (!cpu_has_feature(CPU_FTR_TM) || tsk != current) + return; + + if (MSR_TM_SUSPENDED(mfmsr())) { + tm_reclaim_current(TM_CAUSE_SIGNAL); + } else { + tm_enable(); + tm_save_sprs(&tsk->thread); + } +} + +static unsigned long get_user_ckpt_msr(struct task_struct *task) +{ + return task->thread.ckpt_regs.msr | task->thread.fpexc_mode; +} + +static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr) +{ + task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE; + task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE; + return 0; +} + +static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap) +{ + task->thread.ckpt_regs.trap = trap & 0xfff0; + return 0; +} + +/** + * tm_cgpr_active - get active number of registers in CGPR + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in transaction checkpointed GPR category. + */ +int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return 0; + + return regset->n; +} + +/** + * tm_cgpr_get - get CGPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy from. + * @ubuf: User buffer to copy into. + * + * This function gets transaction checkpointed GPR registers. + * + * When the transaction is active, 'ckpt_regs' holds all the checkpointed + * GPR register values for the current transaction to fall back on if it + * aborts in between. This function gets those checkpointed GPR registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * struct pt_regs ckpt_regs; + * }; + */ +int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.ckpt_regs, + 0, offsetof(struct pt_regs, msr)); + if (!ret) { + unsigned long msr = get_user_ckpt_msr(target); + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, + offsetof(struct pt_regs, msr), + offsetof(struct pt_regs, msr) + + sizeof(msr)); + } + + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != + offsetof(struct pt_regs, msr) + sizeof(long)); + + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.ckpt_regs.orig_gpr3, + offsetof(struct pt_regs, orig_gpr3), + sizeof(struct user_pt_regs)); + if (!ret) + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + sizeof(struct user_pt_regs), -1); + + return ret; +} + +/* + * tm_cgpr_set - set the CGPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy into. + * @ubuf: User buffer to copy from. + * + * This function sets in transaction checkpointed GPR registers. + * + * When the transaction is active, 'ckpt_regs' holds the checkpointed + * GPR register values for the current transaction to fall back on if it + * aborts in between. This function sets those checkpointed GPR registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * struct pt_regs ckpt_regs; + * }; + */ +int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + unsigned long reg; + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.ckpt_regs, + 0, PT_MSR * sizeof(reg)); + + if (!ret && count > 0) { + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, + PT_MSR * sizeof(reg), + (PT_MSR + 1) * sizeof(reg)); + if (!ret) + ret = set_user_ckpt_msr(target, reg); + } + + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != + offsetof(struct pt_regs, msr) + sizeof(long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.ckpt_regs.orig_gpr3, + PT_ORIG_R3 * sizeof(reg), + (PT_MAX_PUT_REG + 1) * sizeof(reg)); + + if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret) + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + (PT_MAX_PUT_REG + 1) * sizeof(reg), + PT_TRAP * sizeof(reg)); + + if (!ret && count > 0) { + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, + PT_TRAP * sizeof(reg), + (PT_TRAP + 1) * sizeof(reg)); + if (!ret) + ret = set_user_ckpt_trap(target, reg); + } + + if (!ret) + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + (PT_TRAP + 1) * sizeof(reg), -1); + + return ret; +} + +/** + * tm_cfpr_active - get active number of registers in CFPR + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in transaction checkpointed FPR category. + */ +int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return 0; + + return regset->n; +} + +/** + * tm_cfpr_get - get CFPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy from. + * @ubuf: User buffer to copy into. + * + * This function gets in transaction checkpointed FPR registers. + * + * When the transaction is active 'ckfp_state' holds the checkpointed + * values for the current transaction to fall back on if it aborts + * in between. This function gets those checkpointed FPR registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + *}; + */ +int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + u64 buf[33]; + int i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + /* copy to local buffer then write that out */ + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.TS_CKFPR(i); + buf[32] = target->thread.ckfp_state.fpscr; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); +} + +/** + * tm_cfpr_set - set CFPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy into. + * @ubuf: User buffer to copy from. + * + * This function sets in transaction checkpointed FPR registers. + * + * When the transaction is active 'ckfp_state' holds the checkpointed + * FPR register values for the current transaction to fall back on + * if it aborts in between. This function sets these checkpointed + * FPR registers. The userspace interface buffer layout is as follows. + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + *}; + */ +int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 buf[33]; + int i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + for (i = 0; i < 32; i++) + buf[i] = target->thread.TS_CKFPR(i); + buf[32] = target->thread.ckfp_state.fpscr; + + /* copy to local buffer then write that out */ + i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); + if (i) + return i; + for (i = 0; i < 32 ; i++) + target->thread.TS_CKFPR(i) = buf[i]; + target->thread.ckfp_state.fpscr = buf[32]; + return 0; +} + +/** + * tm_cvmx_active - get active number of registers in CVMX + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in checkpointed VMX category. + */ +int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return 0; + + return regset->n; +} + +/** + * tm_cvmx_get - get CMVX registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy from. + * @ubuf: User buffer to copy into. + * + * This function gets in transaction checkpointed VMX registers. + * + * When the transaction is active 'ckvr_state' and 'ckvrsave' hold + * the checkpointed values for the current transaction to fall + * back on if it aborts in between. The userspace interface buffer + * layout is as follows. + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + *}; + */ +int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + /* Flush the state */ + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state, + 0, 33 * sizeof(vector128)); + if (!ret) { + /* + * Copy out only the low-order word of vrsave. + */ + union { + elf_vrreg_t reg; + u32 word; + } vrsave; + memset(&vrsave, 0, sizeof(vrsave)); + vrsave.word = target->thread.ckvrsave; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave, + 33 * sizeof(vector128), -1); + } + + return ret; +} + +/** + * tm_cvmx_set - set CMVX registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy into. + * @ubuf: User buffer to copy from. + * + * This function sets in transaction checkpointed VMX registers. + * + * When the transaction is active 'ckvr_state' and 'ckvrsave' hold + * the checkpointed values for the current transaction to fall + * back on if it aborts in between. The userspace interface buffer + * layout is as follows. + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + *}; + */ +int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state, + 0, 33 * sizeof(vector128)); + if (!ret && count > 0) { + /* + * We use only the low-order word of vrsave. + */ + union { + elf_vrreg_t reg; + u32 word; + } vrsave; + memset(&vrsave, 0, sizeof(vrsave)); + vrsave.word = target->thread.ckvrsave; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave, + 33 * sizeof(vector128), -1); + if (!ret) + target->thread.ckvrsave = vrsave.word; + } + + return ret; +} + +/** + * tm_cvsx_active - get active number of registers in CVSX + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in transaction checkpointed VSX category. + */ +int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return 0; + + flush_vsx_to_thread(target); + return target->thread.used_vsr ? regset->n : 0; +} + +/** + * tm_cvsx_get - get CVSX registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy from. + * @ubuf: User buffer to copy into. + * + * This function gets in transaction checkpointed VSX registers. + * + * When the transaction is active 'ckfp_state' holds the checkpointed + * values for the current transaction to fall back on if it aborts + * in between. This function gets those checkpointed VSX registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * u64 vsx[32]; + *}; + */ +int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + u64 buf[32]; + int ret, i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + /* Flush the state */ + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_vsx_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + + return ret; +} + +/** + * tm_cvsx_set - set CFPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy into. + * @ubuf: User buffer to copy from. + * + * This function sets in transaction checkpointed VSX registers. + * + * When the transaction is active 'ckfp_state' holds the checkpointed + * VSX register values for the current transaction to fall back on + * if it aborts in between. This function sets these checkpointed + * FPR registers. The userspace interface buffer layout is as follows. + * + * struct data { + * u64 vsx[32]; + *}; + */ +int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 buf[32]; + int ret, i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + /* Flush the state */ + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_vsx_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + if (!ret) + for (i = 0; i < 32 ; i++) + target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + + return ret; +} + +/** + * tm_spr_active - get active number of registers in TM SPR + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks the active number of available + * regisers in the transactional memory SPR category. + */ +int tm_spr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + return regset->n; +} + +/** + * tm_spr_get - get the TM related SPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy from. + * @ubuf: User buffer to copy into. + * + * This function gets transactional memory related SPR registers. + * The userspace interface buffer layout is as follows. + * + * struct { + * u64 tm_tfhar; + * u64 tm_texasr; + * u64 tm_tfiar; + * }; + */ +int tm_spr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + /* Build tests */ + BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); + BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); + BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + /* Flush the states */ + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + /* TFHAR register */ + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tfhar, 0, sizeof(u64)); + + /* TEXASR register */ + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_texasr, sizeof(u64), + 2 * sizeof(u64)); + + /* TFIAR register */ + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tfiar, + 2 * sizeof(u64), 3 * sizeof(u64)); + return ret; +} + +/** + * tm_spr_set - set the TM related SPR registers + * @target: The target task. + * @regset: The user regset structure. + * @pos: The buffer position. + * @count: Number of bytes to copy. + * @kbuf: Kernel buffer to copy into. + * @ubuf: User buffer to copy from. + * + * This function sets transactional memory related SPR registers. + * The userspace interface buffer layout is as follows. + * + * struct { + * u64 tm_tfhar; + * u64 tm_texasr; + * u64 tm_tfiar; + * }; + */ +int tm_spr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + /* Build tests */ + BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); + BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); + BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + /* Flush the states */ + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + + /* TFHAR register */ + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tfhar, 0, sizeof(u64)); + + /* TEXASR register */ + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_texasr, sizeof(u64), + 2 * sizeof(u64)); + + /* TFIAR register */ + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tfiar, + 2 * sizeof(u64), 3 * sizeof(u64)); + return ret; +} + +int tm_tar_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (MSR_TM_ACTIVE(target->thread.regs->msr)) + return regset->n; + + return 0; +} + +int tm_tar_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tar, 0, sizeof(u64)); + return ret; +} + +int tm_tar_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_tar, 0, sizeof(u64)); + return ret; +} + +int tm_ppr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (MSR_TM_ACTIVE(target->thread.regs->msr)) + return regset->n; + + return 0; +} + + +int tm_ppr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_ppr, 0, sizeof(u64)); + return ret; +} + +int tm_ppr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_ppr, 0, sizeof(u64)); + return ret; +} + +int tm_dscr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (MSR_TM_ACTIVE(target->thread.regs->msr)) + return regset->n; + + return 0; +} + +int tm_dscr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_dscr, 0, sizeof(u64)); + return ret; +} + +int tm_dscr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tm_dscr, 0, sizeof(u64)); + return ret; +} + +int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, + &target->thread.ckpt_regs.gpr[0]); +} + +int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, + &target->thread.ckpt_regs.gpr[0]); +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c new file mode 100644 index 000000000000..15e3b79b6395 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-view.c @@ -0,0 +1,904 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> +#include <linux/elf.h> +#include <linux/nospec.h> +#include <linux/pkeys.h> + +#include "ptrace-decl.h" + +struct pt_regs_offset { + const char *name; + int offset; +}; + +#define STR(s) #s /* convert to string */ +#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} +#define GPR_OFFSET_NAME(num) \ + {.name = STR(r##num), .offset = offsetof(struct pt_regs, gpr[num])}, \ + {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +static const struct pt_regs_offset regoffset_table[] = { + GPR_OFFSET_NAME(0), + GPR_OFFSET_NAME(1), + GPR_OFFSET_NAME(2), + GPR_OFFSET_NAME(3), + GPR_OFFSET_NAME(4), + GPR_OFFSET_NAME(5), + GPR_OFFSET_NAME(6), + GPR_OFFSET_NAME(7), + GPR_OFFSET_NAME(8), + GPR_OFFSET_NAME(9), + GPR_OFFSET_NAME(10), + GPR_OFFSET_NAME(11), + GPR_OFFSET_NAME(12), + GPR_OFFSET_NAME(13), + GPR_OFFSET_NAME(14), + GPR_OFFSET_NAME(15), + GPR_OFFSET_NAME(16), + GPR_OFFSET_NAME(17), + GPR_OFFSET_NAME(18), + GPR_OFFSET_NAME(19), + GPR_OFFSET_NAME(20), + GPR_OFFSET_NAME(21), + GPR_OFFSET_NAME(22), + GPR_OFFSET_NAME(23), + GPR_OFFSET_NAME(24), + GPR_OFFSET_NAME(25), + GPR_OFFSET_NAME(26), + GPR_OFFSET_NAME(27), + GPR_OFFSET_NAME(28), + GPR_OFFSET_NAME(29), + GPR_OFFSET_NAME(30), + GPR_OFFSET_NAME(31), + REG_OFFSET_NAME(nip), + REG_OFFSET_NAME(msr), + REG_OFFSET_NAME(ctr), + REG_OFFSET_NAME(link), + REG_OFFSET_NAME(xer), + REG_OFFSET_NAME(ccr), +#ifdef CONFIG_PPC64 + REG_OFFSET_NAME(softe), +#else + REG_OFFSET_NAME(mq), +#endif + REG_OFFSET_NAME(trap), + REG_OFFSET_NAME(dar), + REG_OFFSET_NAME(dsisr), + REG_OFFSET_END, +}; + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_query_register_name() - query register name from its offset + * @offset: the offset of a register in struct pt_regs. + * + * regs_query_register_name() returns the name of a register from its + * offset in struct pt_regs. If the @offset is invalid, this returns NULL; + */ +const char *regs_query_register_name(unsigned int offset) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (roff->offset == offset) + return roff->name; + return NULL; +} + +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +static unsigned long get_user_msr(struct task_struct *task) +{ + return task->thread.regs->msr | task->thread.fpexc_mode; +} + +static int set_user_msr(struct task_struct *task, unsigned long msr) +{ + task->thread.regs->msr &= ~MSR_DEBUGCHANGE; + task->thread.regs->msr |= msr & MSR_DEBUGCHANGE; + return 0; +} + +#ifdef CONFIG_PPC64 +static int get_user_dscr(struct task_struct *task, unsigned long *data) +{ + *data = task->thread.dscr; + return 0; +} + +static int set_user_dscr(struct task_struct *task, unsigned long dscr) +{ + task->thread.dscr = dscr; + task->thread.dscr_inherit = 1; + return 0; +} +#else +static int get_user_dscr(struct task_struct *task, unsigned long *data) +{ + return -EIO; +} + +static int set_user_dscr(struct task_struct *task, unsigned long dscr) +{ + return -EIO; +} +#endif + +/* + * We prevent mucking around with the reserved area of trap + * which are used internally by the kernel. + */ +static int set_user_trap(struct task_struct *task, unsigned long trap) +{ + task->thread.regs->trap = trap & 0xfff0; + return 0; +} + +/* + * Get contents of register REGNO in task TASK. + */ +int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data) +{ + unsigned int regs_max; + + if (task->thread.regs == NULL || !data) + return -EIO; + + if (regno == PT_MSR) { + *data = get_user_msr(task); + return 0; + } + + if (regno == PT_DSCR) + return get_user_dscr(task, data); + + /* + * softe copies paca->irq_soft_mask variable state. Since irq_soft_mask is + * no more used as a flag, lets force usr to alway see the softe value as 1 + * which means interrupts are not soft disabled. + */ + if (IS_ENABLED(CONFIG_PPC64) && regno == PT_SOFTE) { + *data = 1; + return 0; + } + + regs_max = sizeof(struct user_pt_regs) / sizeof(unsigned long); + if (regno < regs_max) { + regno = array_index_nospec(regno, regs_max); + *data = ((unsigned long *)task->thread.regs)[regno]; + return 0; + } + + return -EIO; +} + +/* + * Write contents of register REGNO in task TASK. + */ +int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data) +{ + if (task->thread.regs == NULL) + return -EIO; + + if (regno == PT_MSR) + return set_user_msr(task, data); + if (regno == PT_TRAP) + return set_user_trap(task, data); + if (regno == PT_DSCR) + return set_user_dscr(task, data); + + if (regno <= PT_MAX_PUT_REG) { + regno = array_index_nospec(regno, PT_MAX_PUT_REG + 1); + ((unsigned long *)task->thread.regs)[regno] = data; + return 0; + } + return -EIO; +} + +static int gpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + int i, ret; + + if (target->thread.regs == NULL) + return -EIO; + + if (!FULL_REGS(target->thread.regs)) { + /* We have a partial register set. Fill 14-31 with bogus values */ + for (i = 14; i < 32; i++) + target->thread.regs->gpr[i] = NV_REG_POISON; + } + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + target->thread.regs, + 0, offsetof(struct pt_regs, msr)); + if (!ret) { + unsigned long msr = get_user_msr(target); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, + offsetof(struct pt_regs, msr), + offsetof(struct pt_regs, msr) + + sizeof(msr)); + } + + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != + offsetof(struct pt_regs, msr) + sizeof(long)); + + if (!ret) + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.regs->orig_gpr3, + offsetof(struct pt_regs, orig_gpr3), + sizeof(struct user_pt_regs)); + if (!ret) + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + sizeof(struct user_pt_regs), -1); + + return ret; +} + +static int gpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + unsigned long reg; + int ret; + + if (target->thread.regs == NULL) + return -EIO; + + CHECK_FULL_REGS(target->thread.regs); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + target->thread.regs, + 0, PT_MSR * sizeof(reg)); + + if (!ret && count > 0) { + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, + PT_MSR * sizeof(reg), + (PT_MSR + 1) * sizeof(reg)); + if (!ret) + ret = set_user_msr(target, reg); + } + + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != + offsetof(struct pt_regs, msr) + sizeof(long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.regs->orig_gpr3, + PT_ORIG_R3 * sizeof(reg), + (PT_MAX_PUT_REG + 1) * sizeof(reg)); + + if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret) + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + (PT_MAX_PUT_REG + 1) * sizeof(reg), + PT_TRAP * sizeof(reg)); + + if (!ret && count > 0) { + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, + PT_TRAP * sizeof(reg), + (PT_TRAP + 1) * sizeof(reg)); + if (!ret) + ret = set_user_trap(target, reg); + } + + if (!ret) + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + (PT_TRAP + 1) * sizeof(reg), -1); + + return ret; +} + +#ifdef CONFIG_PPC64 +static int ppr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.regs->ppr, 0, sizeof(u64)); +} + +static int ppr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.regs->ppr, 0, sizeof(u64)); +} + +static int dscr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); +} +static int dscr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); +} +#endif +#ifdef CONFIG_PPC_BOOK3S_64 +static int tar_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); +} +static int tar_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); +} + +static int ebb_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + if (target->thread.used_ebb) + return regset->n; + + return 0; +} + +static int ebb_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + /* Build tests */ + BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr)); + BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr)); + + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + if (!target->thread.used_ebb) + return -ENODATA; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.ebbrr, + 0, 3 * sizeof(unsigned long)); +} + +static int ebb_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + int ret = 0; + + /* Build tests */ + BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr)); + BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr)); + + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + if (target->thread.used_ebb) + return -ENODATA; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ebbrr, + 0, sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.ebbhr, sizeof(unsigned long), + 2 * sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.bescr, 2 * sizeof(unsigned long), + 3 * sizeof(unsigned long)); + + return ret; +} +static int pmu_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + return regset->n; +} + +static int pmu_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + /* Build tests */ + BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar)); + BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier)); + BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2)); + BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0)); + + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.siar, + 0, 5 * sizeof(unsigned long)); +} + +static int pmu_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + int ret = 0; + + /* Build tests */ + BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar)); + BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier)); + BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2)); + BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0)); + + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + return -ENODEV; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.siar, + 0, sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.sdar, sizeof(unsigned long), + 2 * sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.sier, 2 * sizeof(unsigned long), + 3 * sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.mmcr2, 3 * sizeof(unsigned long), + 4 * sizeof(unsigned long)); + + if (!ret) + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.mmcr0, 4 * sizeof(unsigned long), + 5 * sizeof(unsigned long)); + return ret; +} +#endif + +#ifdef CONFIG_PPC_MEM_KEYS +static int pkey_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!arch_pkeys_enabled()) + return -ENODEV; + + return regset->n; +} + +static int pkey_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr)); + BUILD_BUG_ON(TSO(iamr) + sizeof(unsigned long) != TSO(uamor)); + + if (!arch_pkeys_enabled()) + return -ENODEV; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.amr, + 0, ELF_NPKEY * sizeof(unsigned long)); +} + +static int pkey_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + u64 new_amr; + int ret; + + if (!arch_pkeys_enabled()) + return -ENODEV; + + /* Only the AMR can be set from userspace */ + if (pos != 0 || count != sizeof(new_amr)) + return -EINVAL; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &new_amr, 0, sizeof(new_amr)); + if (ret) + return ret; + + /* UAMOR determines which bits of the AMR can be set from userspace. */ + target->thread.amr = (new_amr & target->thread.uamor) | + (target->thread.amr & ~target->thread.uamor); + + return 0; +} +#endif /* CONFIG_PPC_MEM_KEYS */ + +static const struct user_regset native_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, + .size = sizeof(long), .align = sizeof(long), + .get = gpr_get, .set = gpr_set + }, + [REGSET_FPR] = { + .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .get = fpr_get, .set = fpr_set + }, +#ifdef CONFIG_ALTIVEC + [REGSET_VMX] = { + .core_note_type = NT_PPC_VMX, .n = 34, + .size = sizeof(vector128), .align = sizeof(vector128), + .active = vr_active, .get = vr_get, .set = vr_set + }, +#endif +#ifdef CONFIG_VSX + [REGSET_VSX] = { + .core_note_type = NT_PPC_VSX, .n = 32, + .size = sizeof(double), .align = sizeof(double), + .active = vsr_active, .get = vsr_get, .set = vsr_set + }, +#endif +#ifdef CONFIG_SPE + [REGSET_SPE] = { + .core_note_type = NT_PPC_SPE, .n = 35, + .size = sizeof(u32), .align = sizeof(u32), + .active = evr_active, .get = evr_get, .set = evr_set + }, +#endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + [REGSET_TM_CGPR] = { + .core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG, + .size = sizeof(long), .align = sizeof(long), + .active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set + }, + [REGSET_TM_CFPR] = { + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set + }, + [REGSET_TM_CVMX] = { + .core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX, + .size = sizeof(vector128), .align = sizeof(vector128), + .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set + }, + [REGSET_TM_CVSX] = { + .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set + }, + [REGSET_TM_SPR] = { + .core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set + }, + [REGSET_TM_CTAR] = { + .core_note_type = NT_PPC_TM_CTAR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_tar_active, .get = tm_tar_get, .set = tm_tar_set + }, + [REGSET_TM_CPPR] = { + .core_note_type = NT_PPC_TM_CPPR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_ppr_active, .get = tm_ppr_get, .set = tm_ppr_set + }, + [REGSET_TM_CDSCR] = { + .core_note_type = NT_PPC_TM_CDSCR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set + }, +#endif +#ifdef CONFIG_PPC64 + [REGSET_PPR] = { + .core_note_type = NT_PPC_PPR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = ppr_get, .set = ppr_set + }, + [REGSET_DSCR] = { + .core_note_type = NT_PPC_DSCR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = dscr_get, .set = dscr_set + }, +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + [REGSET_TAR] = { + .core_note_type = NT_PPC_TAR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = tar_get, .set = tar_set + }, + [REGSET_EBB] = { + .core_note_type = NT_PPC_EBB, .n = ELF_NEBB, + .size = sizeof(u64), .align = sizeof(u64), + .active = ebb_active, .get = ebb_get, .set = ebb_set + }, + [REGSET_PMR] = { + .core_note_type = NT_PPC_PMU, .n = ELF_NPMU, + .size = sizeof(u64), .align = sizeof(u64), + .active = pmu_active, .get = pmu_get, .set = pmu_set + }, +#endif +#ifdef CONFIG_PPC_MEM_KEYS + [REGSET_PKEY] = { + .core_note_type = NT_PPC_PKEY, .n = ELF_NPKEY, + .size = sizeof(u64), .align = sizeof(u64), + .active = pkey_active, .get = pkey_get, .set = pkey_set + }, +#endif +}; + +const struct user_regset_view user_ppc_native_view = { + .name = UTS_MACHINE, .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI, + .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets) +}; + +#include <linux/compat.h> + +int gpr32_get_common(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf, + unsigned long *regs) +{ + compat_ulong_t *k = kbuf; + compat_ulong_t __user *u = ubuf; + compat_ulong_t reg; + + pos /= sizeof(reg); + count /= sizeof(reg); + + if (kbuf) + for (; count > 0 && pos < PT_MSR; --count) + *k++ = regs[pos++]; + else + for (; count > 0 && pos < PT_MSR; --count) + if (__put_user((compat_ulong_t)regs[pos++], u++)) + return -EFAULT; + + if (count > 0 && pos == PT_MSR) { + reg = get_user_msr(target); + if (kbuf) + *k++ = reg; + else if (__put_user(reg, u++)) + return -EFAULT; + ++pos; + --count; + } + + if (kbuf) + for (; count > 0 && pos < PT_REGS_COUNT; --count) + *k++ = regs[pos++]; + else + for (; count > 0 && pos < PT_REGS_COUNT; --count) + if (__put_user((compat_ulong_t)regs[pos++], u++)) + return -EFAULT; + + kbuf = k; + ubuf = u; + pos *= sizeof(reg); + count *= sizeof(reg); + return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + PT_REGS_COUNT * sizeof(reg), -1); +} + +int gpr32_set_common(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf, + unsigned long *regs) +{ + const compat_ulong_t *k = kbuf; + const compat_ulong_t __user *u = ubuf; + compat_ulong_t reg; + + pos /= sizeof(reg); + count /= sizeof(reg); + + if (kbuf) + for (; count > 0 && pos < PT_MSR; --count) + regs[pos++] = *k++; + else + for (; count > 0 && pos < PT_MSR; --count) { + if (__get_user(reg, u++)) + return -EFAULT; + regs[pos++] = reg; + } + + + if (count > 0 && pos == PT_MSR) { + if (kbuf) + reg = *k++; + else if (__get_user(reg, u++)) + return -EFAULT; + set_user_msr(target, reg); + ++pos; + --count; + } + + if (kbuf) { + for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) + regs[pos++] = *k++; + for (; count > 0 && pos < PT_TRAP; --count, ++pos) + ++k; + } else { + for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) { + if (__get_user(reg, u++)) + return -EFAULT; + regs[pos++] = reg; + } + for (; count > 0 && pos < PT_TRAP; --count, ++pos) + if (__get_user(reg, u++)) + return -EFAULT; + } + + if (count > 0 && pos == PT_TRAP) { + if (kbuf) + reg = *k++; + else if (__get_user(reg, u++)) + return -EFAULT; + set_user_trap(target, reg); + ++pos; + --count; + } + + kbuf = k; + ubuf = u; + pos *= sizeof(reg); + count *= sizeof(reg); + return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + (PT_TRAP + 1) * sizeof(reg), -1); +} + +static int gpr32_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + int i; + + if (target->thread.regs == NULL) + return -EIO; + + if (!FULL_REGS(target->thread.regs)) { + /* + * We have a partial register set. + * Fill 14-31 with bogus values. + */ + for (i = 14; i < 32; i++) + target->thread.regs->gpr[i] = NV_REG_POISON; + } + return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, + &target->thread.regs->gpr[0]); +} + +static int gpr32_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + if (target->thread.regs == NULL) + return -EIO; + + CHECK_FULL_REGS(target->thread.regs); + return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, + &target->thread.regs->gpr[0]); +} + +/* + * These are the regset flavors matching the CONFIG_PPC32 native set. + */ +static const struct user_regset compat_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, + .size = sizeof(compat_long_t), .align = sizeof(compat_long_t), + .get = gpr32_get, .set = gpr32_set + }, + [REGSET_FPR] = { + .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .get = fpr_get, .set = fpr_set + }, +#ifdef CONFIG_ALTIVEC + [REGSET_VMX] = { + .core_note_type = NT_PPC_VMX, .n = 34, + .size = sizeof(vector128), .align = sizeof(vector128), + .active = vr_active, .get = vr_get, .set = vr_set + }, +#endif +#ifdef CONFIG_SPE + [REGSET_SPE] = { + .core_note_type = NT_PPC_SPE, .n = 35, + .size = sizeof(u32), .align = sizeof(u32), + .active = evr_active, .get = evr_get, .set = evr_set + }, +#endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + [REGSET_TM_CGPR] = { + .core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG, + .size = sizeof(long), .align = sizeof(long), + .active = tm_cgpr_active, + .get = tm_cgpr32_get, .set = tm_cgpr32_set + }, + [REGSET_TM_CFPR] = { + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set + }, + [REGSET_TM_CVMX] = { + .core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX, + .size = sizeof(vector128), .align = sizeof(vector128), + .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set + }, + [REGSET_TM_CVSX] = { + .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set + }, + [REGSET_TM_SPR] = { + .core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set + }, + [REGSET_TM_CTAR] = { + .core_note_type = NT_PPC_TM_CTAR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_tar_active, .get = tm_tar_get, .set = tm_tar_set + }, + [REGSET_TM_CPPR] = { + .core_note_type = NT_PPC_TM_CPPR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_ppr_active, .get = tm_ppr_get, .set = tm_ppr_set + }, + [REGSET_TM_CDSCR] = { + .core_note_type = NT_PPC_TM_CDSCR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set + }, +#endif +#ifdef CONFIG_PPC64 + [REGSET_PPR] = { + .core_note_type = NT_PPC_PPR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = ppr_get, .set = ppr_set + }, + [REGSET_DSCR] = { + .core_note_type = NT_PPC_DSCR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = dscr_get, .set = dscr_set + }, +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + [REGSET_TAR] = { + .core_note_type = NT_PPC_TAR, .n = 1, + .size = sizeof(u64), .align = sizeof(u64), + .get = tar_get, .set = tar_set + }, + [REGSET_EBB] = { + .core_note_type = NT_PPC_EBB, .n = ELF_NEBB, + .size = sizeof(u64), .align = sizeof(u64), + .active = ebb_active, .get = ebb_get, .set = ebb_set + }, +#endif +}; + +static const struct user_regset_view user_ppc_compat_view = { + .name = "ppc", .e_machine = EM_PPC, .ei_osabi = ELF_OSABI, + .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets) +}; + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ + if (IS_ENABLED(CONFIG_PPC64) && test_tsk_thread_flag(task, TIF_32BIT)) + return &user_ppc_compat_view; + return &user_ppc_native_view; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace-vsx.c b/arch/powerpc/kernel/ptrace/ptrace-vsx.c new file mode 100644 index 000000000000..d53466d49cc0 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-vsx.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + */ +int fpr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + u64 buf[33]; + int i; + + flush_fp_to_thread(target); + + /* copy to local buffer then write that out */ + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.TS_FPR(i); + buf[32] = target->thread.fp_state.fpscr; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); +} + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + * + */ +int fpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 buf[33]; + int i; + + flush_fp_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.TS_FPR(i); + buf[32] = target->thread.fp_state.fpscr; + + /* copy to local buffer then write that out */ + i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); + if (i) + return i; + + for (i = 0; i < 32 ; i++) + target->thread.TS_FPR(i) = buf[i]; + target->thread.fp_state.fpscr = buf[32]; + return 0; +} + +/* + * Currently to set and and get all the vsx state, you need to call + * the fp and VMX calls as well. This only get/sets the lower 32 + * 128bit VSX registers. + */ + +int vsr_active(struct task_struct *target, const struct user_regset *regset) +{ + flush_vsx_to_thread(target); + return target->thread.used_vsr ? regset->n : 0; +} + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last + * checkpointed value of all FPR registers for the current + * transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 vsx[32]; + * }; + */ +int vsr_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) +{ + u64 buf[32]; + int ret, i; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_vsx_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + + return ret; +} + +/* + * Regardless of transactions, 'fp_state' holds the current running + * value of all FPR registers and 'ckfp_state' holds the last + * checkpointed value of all FPR registers for the current + * transaction. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 vsx[32]; + * }; + */ +int vsr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 buf[32]; + int ret, i; + + flush_tmregs_to_thread(target); + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_vsx_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + if (!ret) + for (i = 0; i < 32 ; i++) + target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + + return ret; +} diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c new file mode 100644 index 000000000000..f6e51be47c6e --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -0,0 +1,481 @@ +/* + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Derived from "arch/m68k/kernel/ptrace.c" + * Copyright (C) 1994 by Hamish Macdonald + * Taken from linux/kernel/ptrace.c and modified for M680x0. + * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds + * + * Modified by Cort Dougan (cort@hq.fsmlabs.com) + * and Paul Mackerras (paulus@samba.org). + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file README.legal in the main directory of + * this archive for more details. + */ + +#include <linux/regset.h> +#include <linux/tracehook.h> +#include <linux/audit.h> +#include <linux/context_tracking.h> +#include <linux/syscalls.h> + +#include <asm/switch_to.h> +#include <asm/asm-prototypes.h> +#include <asm/debug.h> + +#define CREATE_TRACE_POINTS +#include <trace/events/syscalls.h> + +#include "ptrace-decl.h" + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure single step bits etc are not set. + */ +void ptrace_disable(struct task_struct *child) +{ + /* make sure the single step bit is not set. */ + user_disable_single_step(child); +} + +long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) +{ + int ret = -EPERM; + void __user *datavp = (void __user *) data; + unsigned long __user *datalp = datavp; + + switch (request) { + /* read the word at location addr in the USER area. */ + case PTRACE_PEEKUSR: { + unsigned long index, tmp; + + ret = -EIO; + /* convert to index and check */ +#ifdef CONFIG_PPC32 + index = addr >> 2; + if ((addr & 3) || (index > PT_FPSCR) + || (child->thread.regs == NULL)) +#else + index = addr >> 3; + if ((addr & 7) || (index > PT_FPSCR)) +#endif + break; + + CHECK_FULL_REGS(child->thread.regs); + if (index < PT_FPR0) { + ret = ptrace_get_reg(child, (int) index, &tmp); + if (ret) + break; + } else { + unsigned int fpidx = index - PT_FPR0; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(&tmp, &child->thread.TS_FPR(fpidx), + sizeof(long)); + else + tmp = child->thread.fp_state.fpscr; + } + ret = put_user(tmp, datalp); + break; + } + + /* write the word at location addr in the USER area */ + case PTRACE_POKEUSR: { + unsigned long index; + + ret = -EIO; + /* convert to index and check */ +#ifdef CONFIG_PPC32 + index = addr >> 2; + if ((addr & 3) || (index > PT_FPSCR) + || (child->thread.regs == NULL)) +#else + index = addr >> 3; + if ((addr & 7) || (index > PT_FPSCR)) +#endif + break; + + CHECK_FULL_REGS(child->thread.regs); + if (index < PT_FPR0) { + ret = ptrace_put_reg(child, index, data); + } else { + unsigned int fpidx = index - PT_FPR0; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(&child->thread.TS_FPR(fpidx), &data, + sizeof(long)); + else + child->thread.fp_state.fpscr = data; + ret = 0; + } + break; + } + + case PPC_PTRACE_GETHWDBGINFO: { + struct ppc_debug_info dbginfo; + + ppc_gethwdinfo(&dbginfo); + + if (copy_to_user(datavp, &dbginfo, + sizeof(struct ppc_debug_info))) + return -EFAULT; + return 0; + } + + case PPC_PTRACE_SETHWDEBUG: { + struct ppc_hw_breakpoint bp_info; + + if (copy_from_user(&bp_info, datavp, + sizeof(struct ppc_hw_breakpoint))) + return -EFAULT; + return ppc_set_hwdebug(child, &bp_info); + } + + case PPC_PTRACE_DELHWDEBUG: { + ret = ppc_del_hwdebug(child, data); + break; + } + + case PTRACE_GET_DEBUGREG: + ret = ptrace_get_debugreg(child, addr, datalp); + break; + + case PTRACE_SET_DEBUGREG: + ret = ptrace_set_debugreg(child, addr, data); + break; + +#ifdef CONFIG_PPC64 + case PTRACE_GETREGS64: +#endif + case PTRACE_GETREGS: /* Get all pt_regs from the child. */ + return copy_regset_to_user(child, &user_ppc_native_view, + REGSET_GPR, + 0, sizeof(struct user_pt_regs), + datavp); + +#ifdef CONFIG_PPC64 + case PTRACE_SETREGS64: +#endif + case PTRACE_SETREGS: /* Set all gp regs in the child. */ + return copy_regset_from_user(child, &user_ppc_native_view, + REGSET_GPR, + 0, sizeof(struct user_pt_regs), + datavp); + + case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ + return copy_regset_to_user(child, &user_ppc_native_view, + REGSET_FPR, + 0, sizeof(elf_fpregset_t), + datavp); + + case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ + return copy_regset_from_user(child, &user_ppc_native_view, + REGSET_FPR, + 0, sizeof(elf_fpregset_t), + datavp); + +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + return copy_regset_to_user(child, &user_ppc_native_view, + REGSET_VMX, + 0, (33 * sizeof(vector128) + + sizeof(u32)), + datavp); + + case PTRACE_SETVRREGS: + return copy_regset_from_user(child, &user_ppc_native_view, + REGSET_VMX, + 0, (33 * sizeof(vector128) + + sizeof(u32)), + datavp); +#endif +#ifdef CONFIG_VSX + case PTRACE_GETVSRREGS: + return copy_regset_to_user(child, &user_ppc_native_view, + REGSET_VSX, + 0, 32 * sizeof(double), + datavp); + + case PTRACE_SETVSRREGS: + return copy_regset_from_user(child, &user_ppc_native_view, + REGSET_VSX, + 0, 32 * sizeof(double), + datavp); +#endif +#ifdef CONFIG_SPE + case PTRACE_GETEVRREGS: + /* Get the child spe register state. */ + return copy_regset_to_user(child, &user_ppc_native_view, + REGSET_SPE, 0, 35 * sizeof(u32), + datavp); + + case PTRACE_SETEVRREGS: + /* Set the child spe register state. */ + return copy_regset_from_user(child, &user_ppc_native_view, + REGSET_SPE, 0, 35 * sizeof(u32), + datavp); +#endif + + default: + ret = ptrace_request(child, request, addr, data); + break; + } + return ret; +} + +#ifdef CONFIG_SECCOMP +static int do_seccomp(struct pt_regs *regs) +{ + if (!test_thread_flag(TIF_SECCOMP)) + return 0; + + /* + * The ABI we present to seccomp tracers is that r3 contains + * the syscall return value and orig_gpr3 contains the first + * syscall parameter. This is different to the ptrace ABI where + * both r3 and orig_gpr3 contain the first syscall parameter. + */ + regs->gpr[3] = -ENOSYS; + + /* + * We use the __ version here because we have already checked + * TIF_SECCOMP. If this fails, there is nothing left to do, we + * have already loaded -ENOSYS into r3, or seccomp has put + * something else in r3 (via SECCOMP_RET_ERRNO/TRACE). + */ + if (__secure_computing(NULL)) + return -1; + + /* + * The syscall was allowed by seccomp, restore the register + * state to what audit expects. + * Note that we use orig_gpr3, which means a seccomp tracer can + * modify the first syscall parameter (in orig_gpr3) and also + * allow the syscall to proceed. + */ + regs->gpr[3] = regs->orig_gpr3; + + return 0; +} +#else +static inline int do_seccomp(struct pt_regs *regs) { return 0; } +#endif /* CONFIG_SECCOMP */ + +/** + * do_syscall_trace_enter() - Do syscall tracing on kernel entry. + * @regs: the pt_regs of the task to trace (current) + * + * Performs various types of tracing on syscall entry. This includes seccomp, + * ptrace, syscall tracepoints and audit. + * + * The pt_regs are potentially visible to userspace via ptrace, so their + * contents is ABI. + * + * One or more of the tracers may modify the contents of pt_regs, in particular + * to modify arguments or even the syscall number itself. + * + * It's also possible that a tracer can choose to reject the system call. In + * that case this function will return an illegal syscall number, and will put + * an appropriate return value in regs->r3. + * + * Return: the (possibly changed) syscall number. + */ +long do_syscall_trace_enter(struct pt_regs *regs) +{ + u32 flags; + + user_exit(); + + flags = READ_ONCE(current_thread_info()->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); + + if (flags) { + int rc = tracehook_report_syscall_entry(regs); + + if (unlikely(flags & _TIF_SYSCALL_EMU)) { + /* + * A nonzero return code from + * tracehook_report_syscall_entry() tells us to prevent + * the syscall execution, but we are not going to + * execute it anyway. + * + * Returning -1 will skip the syscall execution. We want + * to avoid clobbering any registers, so we don't goto + * the skip label below. + */ + return -1; + } + + if (rc) { + /* + * The tracer decided to abort the syscall. Note that + * the tracer may also just change regs->gpr[0] to an + * invalid syscall number, that is handled below on the + * exit path. + */ + goto skip; + } + } + + /* Run seccomp after ptrace; allow it to set gpr[3]. */ + if (do_seccomp(regs)) + return -1; + + /* Avoid trace and audit when syscall is invalid. */ + if (regs->gpr[0] >= NR_syscalls) + goto skip; + + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_enter(regs, regs->gpr[0]); + + if (!is_32bit_task()) + audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4], + regs->gpr[5], regs->gpr[6]); + else + audit_syscall_entry(regs->gpr[0], + regs->gpr[3] & 0xffffffff, + regs->gpr[4] & 0xffffffff, + regs->gpr[5] & 0xffffffff, + regs->gpr[6] & 0xffffffff); + + /* Return the possibly modified but valid syscall number */ + return regs->gpr[0]; + +skip: + /* + * If we are aborting explicitly, or if the syscall number is + * now invalid, set the return value to -ENOSYS. + */ + regs->gpr[3] = -ENOSYS; + return -1; +} + +void do_syscall_trace_leave(struct pt_regs *regs) +{ + int step; + + audit_syscall_exit(regs); + + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_exit(regs, regs->result); + + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); + + user_enter(); +} + +void __init pt_regs_check(void); + +/* + * Dummy function, its purpose is to break the build if struct pt_regs and + * struct user_pt_regs don't match. + */ +void __init pt_regs_check(void) +{ + BUILD_BUG_ON(offsetof(struct pt_regs, gpr) != + offsetof(struct user_pt_regs, gpr)); + BUILD_BUG_ON(offsetof(struct pt_regs, nip) != + offsetof(struct user_pt_regs, nip)); + BUILD_BUG_ON(offsetof(struct pt_regs, msr) != + offsetof(struct user_pt_regs, msr)); + BUILD_BUG_ON(offsetof(struct pt_regs, msr) != + offsetof(struct user_pt_regs, msr)); + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != + offsetof(struct user_pt_regs, orig_gpr3)); + BUILD_BUG_ON(offsetof(struct pt_regs, ctr) != + offsetof(struct user_pt_regs, ctr)); + BUILD_BUG_ON(offsetof(struct pt_regs, link) != + offsetof(struct user_pt_regs, link)); + BUILD_BUG_ON(offsetof(struct pt_regs, xer) != + offsetof(struct user_pt_regs, xer)); + BUILD_BUG_ON(offsetof(struct pt_regs, ccr) != + offsetof(struct user_pt_regs, ccr)); +#ifdef __powerpc64__ + BUILD_BUG_ON(offsetof(struct pt_regs, softe) != + offsetof(struct user_pt_regs, softe)); +#else + BUILD_BUG_ON(offsetof(struct pt_regs, mq) != + offsetof(struct user_pt_regs, mq)); +#endif + BUILD_BUG_ON(offsetof(struct pt_regs, trap) != + offsetof(struct user_pt_regs, trap)); + BUILD_BUG_ON(offsetof(struct pt_regs, dar) != + offsetof(struct user_pt_regs, dar)); + BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) != + offsetof(struct user_pt_regs, dsisr)); + BUILD_BUG_ON(offsetof(struct pt_regs, result) != + offsetof(struct user_pt_regs, result)); + + BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs)); + + // Now check that the pt_regs offsets match the uapi #defines + #define CHECK_REG(_pt, _reg) \ + BUILD_BUG_ON(_pt != (offsetof(struct user_pt_regs, _reg) / \ + sizeof(unsigned long))); + + CHECK_REG(PT_R0, gpr[0]); + CHECK_REG(PT_R1, gpr[1]); + CHECK_REG(PT_R2, gpr[2]); + CHECK_REG(PT_R3, gpr[3]); + CHECK_REG(PT_R4, gpr[4]); + CHECK_REG(PT_R5, gpr[5]); + CHECK_REG(PT_R6, gpr[6]); + CHECK_REG(PT_R7, gpr[7]); + CHECK_REG(PT_R8, gpr[8]); + CHECK_REG(PT_R9, gpr[9]); + CHECK_REG(PT_R10, gpr[10]); + CHECK_REG(PT_R11, gpr[11]); + CHECK_REG(PT_R12, gpr[12]); + CHECK_REG(PT_R13, gpr[13]); + CHECK_REG(PT_R14, gpr[14]); + CHECK_REG(PT_R15, gpr[15]); + CHECK_REG(PT_R16, gpr[16]); + CHECK_REG(PT_R17, gpr[17]); + CHECK_REG(PT_R18, gpr[18]); + CHECK_REG(PT_R19, gpr[19]); + CHECK_REG(PT_R20, gpr[20]); + CHECK_REG(PT_R21, gpr[21]); + CHECK_REG(PT_R22, gpr[22]); + CHECK_REG(PT_R23, gpr[23]); + CHECK_REG(PT_R24, gpr[24]); + CHECK_REG(PT_R25, gpr[25]); + CHECK_REG(PT_R26, gpr[26]); + CHECK_REG(PT_R27, gpr[27]); + CHECK_REG(PT_R28, gpr[28]); + CHECK_REG(PT_R29, gpr[29]); + CHECK_REG(PT_R30, gpr[30]); + CHECK_REG(PT_R31, gpr[31]); + CHECK_REG(PT_NIP, nip); + CHECK_REG(PT_MSR, msr); + CHECK_REG(PT_ORIG_R3, orig_gpr3); + CHECK_REG(PT_CTR, ctr); + CHECK_REG(PT_LNK, link); + CHECK_REG(PT_XER, xer); + CHECK_REG(PT_CCR, ccr); +#ifdef CONFIG_PPC64 + CHECK_REG(PT_SOFTE, softe); +#else + CHECK_REG(PT_MQ, mq); +#endif + CHECK_REG(PT_TRAP, trap); + CHECK_REG(PT_DAR, dar); + CHECK_REG(PT_DSISR, dsisr); + CHECK_REG(PT_RESULT, result); + #undef CHECK_REG + + BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long)); + + /* + * PT_DSCR isn't a real reg, but it's important that it doesn't overlap the + * real registers. + */ + BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long)); +} diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace/ptrace32.c index f37eb53de1a1..7976ddf29c0e 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace/ptrace32.c @@ -17,21 +17,10 @@ * this archive for more details. */ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/errno.h> #include <linux/ptrace.h> #include <linux/regset.h> -#include <linux/user.h> -#include <linux/security.h> -#include <linux/signal.h> #include <linux/compat.h> -#include <linux/uaccess.h> -#include <asm/page.h> -#include <asm/pgtable.h> #include <asm/switch_to.h> /* diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 7f8c890360fe..f9c0d888ce8a 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -787,8 +787,7 @@ EXPORT_SYMBOL(powerpc_debugfs_root); static int powerpc_debugfs_init(void) { powerpc_debugfs_root = debugfs_create_dir("powerpc", NULL); - - return powerpc_debugfs_root == NULL; + return 0; } arch_initcall(powerpc_debugfs_init); #endif diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h index 2dd0d9cb5a20..2ec835574cc9 100644 --- a/arch/powerpc/kernel/setup.h +++ b/arch/powerpc/kernel/setup.h @@ -8,6 +8,12 @@ #ifndef __ARCH_POWERPC_KERNEL_SETUP_H #define __ARCH_POWERPC_KERNEL_SETUP_H +#ifdef CONFIG_CC_IS_CLANG +#define __nostackprotector +#else +#define __nostackprotector __attribute__((__optimize__("no-stack-protector"))) +#endif + void initialize_cache_info(void); void irqstack_early_init(void); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 5b49b26eb154..305ca89d856f 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -58,7 +58,6 @@ EXPORT_SYMBOL_GPL(boot_cpuid_phys); int smp_hw_index[NR_CPUS]; EXPORT_SYMBOL(smp_hw_index); -unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index e05e6dd67ae6..438a9befce41 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -279,24 +279,42 @@ void __init record_spr_defaults(void) * device-tree is not accessible via normal means at this point. */ -void __init early_setup(unsigned long dt_ptr) +void __init __nostackprotector early_setup(unsigned long dt_ptr) { static __initdata struct paca_struct boot_paca; /* -------- printk is _NOT_ safe to use here ! ------- */ - /* Try new device tree based feature discovery ... */ - if (!dt_cpu_ftrs_init(__va(dt_ptr))) - /* Otherwise use the old style CPU table */ - identify_cpu(0, mfspr(SPRN_PVR)); - - /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ + /* + * Assume we're on cpu 0 for now. + * + * We need to load a PACA very early for a few reasons. + * + * The stack protector canary is stored in the paca, so as soon as we + * call any stack protected code we need r13 pointing somewhere valid. + * + * If we are using kcov it will call in_task() in its instrumentation, + * which relies on the current task from the PACA. + * + * dt_cpu_ftrs_init() calls into generic OF/fdt code, as well as + * printk(), which can trigger both stack protector and kcov. + * + * percpu variables and spin locks also use the paca. + * + * So set up a temporary paca. It will be replaced below once we know + * what CPU we are on. + */ initialise_paca(&boot_paca, 0); setup_paca(&boot_paca); fixup_boot_paca(); /* -------- printk is now safe to use ------- */ + /* Try new device tree based feature discovery ... */ + if (!dt_cpu_ftrs_init(__va(dt_ptr))) + /* Otherwise use the old style CPU table */ + identify_cpu(0, mfspr(SPRN_PVR)); + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index d215f9554553..a264989626fd 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -18,12 +18,153 @@ #include <linux/syscalls.h> #include <asm/hw_breakpoint.h> #include <linux/uaccess.h> +#include <asm/switch_to.h> #include <asm/unistd.h> #include <asm/debug.h> #include <asm/tm.h> #include "signal.h" +#ifdef CONFIG_VSX +unsigned long copy_fpr_to_user(void __user *to, + struct task_struct *task) +{ + u64 buf[ELF_NFPREG]; + int i; + + /* save FPR copy to local buffer then write to the thread_struct */ + for (i = 0; i < (ELF_NFPREG - 1) ; i++) + buf[i] = task->thread.TS_FPR(i); + buf[i] = task->thread.fp_state.fpscr; + return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); +} + +unsigned long copy_fpr_from_user(struct task_struct *task, + void __user *from) +{ + u64 buf[ELF_NFPREG]; + int i; + + if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) + return 1; + for (i = 0; i < (ELF_NFPREG - 1) ; i++) + task->thread.TS_FPR(i) = buf[i]; + task->thread.fp_state.fpscr = buf[i]; + + return 0; +} + +unsigned long copy_vsx_to_user(void __user *to, + struct task_struct *task) +{ + u64 buf[ELF_NVSRHALFREG]; + int i; + + /* save FPR copy to local buffer then write to the thread_struct */ + for (i = 0; i < ELF_NVSRHALFREG; i++) + buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; + return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); +} + +unsigned long copy_vsx_from_user(struct task_struct *task, + void __user *from) +{ + u64 buf[ELF_NVSRHALFREG]; + int i; + + if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) + return 1; + for (i = 0; i < ELF_NVSRHALFREG ; i++) + task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + return 0; +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +unsigned long copy_ckfpr_to_user(void __user *to, + struct task_struct *task) +{ + u64 buf[ELF_NFPREG]; + int i; + + /* save FPR copy to local buffer then write to the thread_struct */ + for (i = 0; i < (ELF_NFPREG - 1) ; i++) + buf[i] = task->thread.TS_CKFPR(i); + buf[i] = task->thread.ckfp_state.fpscr; + return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); +} + +unsigned long copy_ckfpr_from_user(struct task_struct *task, + void __user *from) +{ + u64 buf[ELF_NFPREG]; + int i; + + if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) + return 1; + for (i = 0; i < (ELF_NFPREG - 1) ; i++) + task->thread.TS_CKFPR(i) = buf[i]; + task->thread.ckfp_state.fpscr = buf[i]; + + return 0; +} + +unsigned long copy_ckvsx_to_user(void __user *to, + struct task_struct *task) +{ + u64 buf[ELF_NVSRHALFREG]; + int i; + + /* save FPR copy to local buffer then write to the thread_struct */ + for (i = 0; i < ELF_NVSRHALFREG; i++) + buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; + return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); +} + +unsigned long copy_ckvsx_from_user(struct task_struct *task, + void __user *from) +{ + u64 buf[ELF_NVSRHALFREG]; + int i; + + if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) + return 1; + for (i = 0; i < ELF_NVSRHALFREG ; i++) + task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + return 0; +} +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#else +inline unsigned long copy_fpr_to_user(void __user *to, + struct task_struct *task) +{ + return __copy_to_user(to, task->thread.fp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +inline unsigned long copy_fpr_from_user(struct task_struct *task, + void __user *from) +{ + return __copy_from_user(task->thread.fp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +inline unsigned long copy_ckfpr_to_user(void __user *to, + struct task_struct *task) +{ + return __copy_to_user(to, task->thread.ckfp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +inline unsigned long copy_ckfpr_from_user(struct task_struct *task, + void __user *from) +{ + return __copy_from_user(task->thread.ckfp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#endif + /* Log an error when sending an unhandled signal to a process. Controlled * through debug.exception-trace sysctl. */ @@ -106,7 +247,6 @@ static void do_signal(struct task_struct *tsk) sigset_t *oldset = sigmask_to_save(); struct ksignal ksig = { .sig = 0 }; int ret; - int is32 = is_32bit_task(); BUG_ON(tsk != current); @@ -136,7 +276,7 @@ static void do_signal(struct task_struct *tsk) rseq_signal_deliver(&ksig, tsk->thread.regs); - if (is32) { + if (is_32bit_task()) { if (ksig.ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(&ksig, oldset, tsk); else diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 800433685888..d396efca4068 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -10,8 +10,6 @@ #ifndef _POWERPC_ARCH_SIGNAL_H #define _POWERPC_ARCH_SIGNAL_H -extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); - extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size, int is_32); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 1b090a76b444..4f96d29a22bf 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -235,146 +235,6 @@ struct rt_sigframe { int abigap[56]; }; -#ifdef CONFIG_VSX -unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task) -{ - u64 buf[ELF_NFPREG]; - int i; - - /* save FPR copy to local buffer then write to the thread_struct */ - for (i = 0; i < (ELF_NFPREG - 1) ; i++) - buf[i] = task->thread.TS_FPR(i); - buf[i] = task->thread.fp_state.fpscr; - return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); -} - -unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from) -{ - u64 buf[ELF_NFPREG]; - int i; - - if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) - return 1; - for (i = 0; i < (ELF_NFPREG - 1) ; i++) - task->thread.TS_FPR(i) = buf[i]; - task->thread.fp_state.fpscr = buf[i]; - - return 0; -} - -unsigned long copy_vsx_to_user(void __user *to, - struct task_struct *task) -{ - u64 buf[ELF_NVSRHALFREG]; - int i; - - /* save FPR copy to local buffer then write to the thread_struct */ - for (i = 0; i < ELF_NVSRHALFREG; i++) - buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; - return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); -} - -unsigned long copy_vsx_from_user(struct task_struct *task, - void __user *from) -{ - u64 buf[ELF_NVSRHALFREG]; - int i; - - if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) - return 1; - for (i = 0; i < ELF_NVSRHALFREG ; i++) - task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; - return 0; -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task) -{ - u64 buf[ELF_NFPREG]; - int i; - - /* save FPR copy to local buffer then write to the thread_struct */ - for (i = 0; i < (ELF_NFPREG - 1) ; i++) - buf[i] = task->thread.TS_CKFPR(i); - buf[i] = task->thread.ckfp_state.fpscr; - return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); -} - -unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from) -{ - u64 buf[ELF_NFPREG]; - int i; - - if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) - return 1; - for (i = 0; i < (ELF_NFPREG - 1) ; i++) - task->thread.TS_CKFPR(i) = buf[i]; - task->thread.ckfp_state.fpscr = buf[i]; - - return 0; -} - -unsigned long copy_ckvsx_to_user(void __user *to, - struct task_struct *task) -{ - u64 buf[ELF_NVSRHALFREG]; - int i; - - /* save FPR copy to local buffer then write to the thread_struct */ - for (i = 0; i < ELF_NVSRHALFREG; i++) - buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; - return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); -} - -unsigned long copy_ckvsx_from_user(struct task_struct *task, - void __user *from) -{ - u64 buf[ELF_NVSRHALFREG]; - int i; - - if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) - return 1; - for (i = 0; i < ELF_NVSRHALFREG ; i++) - task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; - return 0; -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#else -inline unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.fp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.fp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -inline unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.ckfp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.ckfp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#endif - /* * Save the current user registers on the user stack. * We only save the altivec/spe registers if the process has used diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 84ed2e77ef9c..adfde59cf4ba 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -473,8 +473,10 @@ static long restore_tm_sigcontexts(struct task_struct *tsk, err |= __get_user(tsk->thread.ckpt_regs.ccr, &sc->gp_regs[PT_CCR]); + /* Don't allow userspace to set the trap value */ + regs->trap = 0; + /* These regs are not checkpointed; they can go in 'regs'. */ - err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ea6adbf6a221..6d2a3a3666f0 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1185,10 +1185,30 @@ static inline void add_cpu_to_smallcore_masks(int cpu) } } +int get_physical_package_id(int cpu) +{ + int pkg_id = cpu_to_chip_id(cpu); + + /* + * If the platform is PowerNV or Guest on KVM, ibm,chip-id is + * defined. Hence we would return the chip-id as the result of + * get_physical_package_id. + */ + if (pkg_id == -1 && firmware_has_feature(FW_FEATURE_LPAR) && + IS_ENABLED(CONFIG_PPC_SPLPAR)) { + struct device_node *np = of_get_cpu_node(cpu, NULL); + pkg_id = of_node_to_nid(np); + of_node_put(np); + } + + return pkg_id; +} +EXPORT_SYMBOL_GPL(get_physical_package_id); + static void add_cpu_to_masks(int cpu) { int first_thread = cpu_first_thread_sibling(cpu); - int chipid = cpu_to_chip_id(cpu); + int pkg_id = get_physical_package_id(cpu); int i; /* @@ -1217,11 +1237,11 @@ static void add_cpu_to_masks(int cpu) for_each_cpu(i, cpu_l2_cache_mask(cpu)) set_cpus_related(cpu, i, cpu_core_mask); - if (chipid == -1) + if (pkg_id == -1) return; for_each_cpu(i, cpu_online_mask) - if (cpu_to_chip_id(i) == chipid) + if (get_physical_package_id(i) == pkg_id) set_cpus_related(cpu, i, cpu_core_mask); } @@ -1359,11 +1379,6 @@ void __init smp_cpus_done(unsigned int max_cpus) if (smp_ops && smp_ops->bringup_done) smp_ops->bringup_done(); - /* - * On a shared LPAR, associativity needs to be requested. - * Hence, get numa topology before dumping cpu topology - */ - shared_proc_topology_init(); dump_numa_cpu_topology(); #ifdef CONFIG_SCHED_SMT diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index e2a46cfed5fd..c477b8585a29 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -57,7 +57,7 @@ void save_stack_trace(struct stack_trace *trace) { unsigned long sp; - sp = current_stack_pointer(); + sp = current_stack_frame(); save_context_stack(trace, sp, current, 1); } @@ -71,7 +71,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) return; if (tsk == current) - sp = current_stack_pointer(); + sp = current_stack_frame(); else sp = tsk->thread.ksp; @@ -131,7 +131,7 @@ static int __save_stack_trace_tsk_reliable(struct task_struct *tsk, } if (tsk == current) - sp = current_stack_pointer(); + sp = current_stack_frame(); else sp = tsk->thread.ksp; diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c new file mode 100644 index 000000000000..c74295a7765b --- /dev/null +++ b/arch/powerpc/kernel/syscall_64.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/err.h> +#include <asm/asm-prototypes.h> +#include <asm/book3s/64/kup-radix.h> +#include <asm/cputime.h> +#include <asm/hw_irq.h> +#include <asm/kprobes.h> +#include <asm/paca.h> +#include <asm/ptrace.h> +#include <asm/reg.h> +#include <asm/signal.h> +#include <asm/switch_to.h> +#include <asm/syscall.h> +#include <asm/time.h> +#include <asm/unistd.h> + +typedef long (*syscall_fn)(long, long, long, long, long, long); + +/* Has to run notrace because it is entered not completely "reconciled" */ +notrace long system_call_exception(long r3, long r4, long r5, + long r6, long r7, long r8, + unsigned long r0, struct pt_regs *regs) +{ + syscall_fn f; + + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) + BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); + + trace_hardirqs_off(); /* finish reconciling */ + + if (IS_ENABLED(CONFIG_PPC_BOOK3S)) + BUG_ON(!(regs->msr & MSR_RI)); + BUG_ON(!(regs->msr & MSR_PR)); + BUG_ON(!FULL_REGS(regs)); + BUG_ON(regs->softe != IRQS_ENABLED); + + account_cpu_user_entry(); + +#ifdef CONFIG_PPC_SPLPAR + if (IS_ENABLED(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && + firmware_has_feature(FW_FEATURE_SPLPAR)) { + struct lppaca *lp = local_paca->lppaca_ptr; + + if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx))) + accumulate_stolen_time(); + } +#endif + + kuap_check_amr(); + + /* + * This is not required for the syscall exit path, but makes the + * stack frame look nicer. If this was initialised in the first stack + * frame, or if the unwinder was taught the first stack frame always + * returns to user with IRQS_ENABLED, this store could be avoided! + */ + regs->softe = IRQS_ENABLED; + + local_irq_enable(); + + if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) { + /* + * We use the return value of do_syscall_trace_enter() as the + * syscall number. If the syscall was rejected for any reason + * do_syscall_trace_enter() returns an invalid syscall number + * and the test against NR_syscalls will fail and the return + * value to be used is in regs->gpr[3]. + */ + r0 = do_syscall_trace_enter(regs); + if (unlikely(r0 >= NR_syscalls)) + return regs->gpr[3]; + r3 = regs->gpr[3]; + r4 = regs->gpr[4]; + r5 = regs->gpr[5]; + r6 = regs->gpr[6]; + r7 = regs->gpr[7]; + r8 = regs->gpr[8]; + + } else if (unlikely(r0 >= NR_syscalls)) { + return -ENOSYS; + } + + /* May be faster to do array_index_nospec? */ + barrier_nospec(); + + if (unlikely(is_32bit_task())) { + f = (void *)compat_sys_call_table[r0]; + + r3 &= 0x00000000ffffffffULL; + r4 &= 0x00000000ffffffffULL; + r5 &= 0x00000000ffffffffULL; + r6 &= 0x00000000ffffffffULL; + r7 &= 0x00000000ffffffffULL; + r8 &= 0x00000000ffffffffULL; + + } else { + f = (void *)sys_call_table[r0]; + } + + return f(r3, r4, r5, r6, r7, r8); +} + +/* + * This should be called after a syscall returns, with r3 the return value + * from the syscall. If this function returns non-zero, the system call + * exit assembly should additionally load all GPR registers and CTR and XER + * from the interrupt frame. + * + * The function graph tracer can not trace the return side of this function, + * because RI=0 and soft mask state is "unreconciled", so it is marked notrace. + */ +notrace unsigned long syscall_exit_prepare(unsigned long r3, + struct pt_regs *regs) +{ + unsigned long *ti_flagsp = ¤t_thread_info()->flags; + unsigned long ti_flags; + unsigned long ret = 0; + + regs->result = r3; + + /* Check whether the syscall is issued inside a restartable sequence */ + rseq_syscall(regs); + + ti_flags = *ti_flagsp; + + if (unlikely(r3 >= (unsigned long)-MAX_ERRNO)) { + if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) { + r3 = -r3; + regs->ccr |= 0x10000000; /* Set SO bit in CR */ + } + } + + if (unlikely(ti_flags & _TIF_PERSYSCALL_MASK)) { + if (ti_flags & _TIF_RESTOREALL) + ret = _TIF_RESTOREALL; + else + regs->gpr[3] = r3; + clear_bits(_TIF_PERSYSCALL_MASK, ti_flagsp); + } else { + regs->gpr[3] = r3; + } + + if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) { + do_syscall_trace_leave(regs); + ret |= _TIF_RESTOREALL; + } + +again: + local_irq_disable(); + ti_flags = READ_ONCE(*ti_flagsp); + while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) { + local_irq_enable(); + if (ti_flags & _TIF_NEED_RESCHED) { + schedule(); + } else { + /* + * SIGPENDING must restore signal handler function + * argument GPRs, and some non-volatiles (e.g., r1). + * Restore all for now. This could be made lighter. + */ + if (ti_flags & _TIF_SIGPENDING) + ret |= _TIF_RESTOREALL; + do_notify_resume(regs, ti_flags); + } + local_irq_disable(); + ti_flags = READ_ONCE(*ti_flagsp); + } + + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) { + if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && + unlikely((ti_flags & _TIF_RESTORE_TM))) { + restore_tm_state(regs); + } else { + unsigned long mathflags = MSR_FP; + + if (cpu_has_feature(CPU_FTR_VSX)) + mathflags |= MSR_VEC | MSR_VSX; + else if (cpu_has_feature(CPU_FTR_ALTIVEC)) + mathflags |= MSR_VEC; + + if ((regs->msr & mathflags) != mathflags) + restore_math(regs); + } + } + + /* This must be done with RI=1 because tracing may touch vmaps */ + trace_hardirqs_on(); + + /* This pattern matches prep_irq_for_idle */ + __hard_EE_RI_disable(); + if (unlikely(lazy_irq_pending())) { + __hard_RI_enable(); + trace_hardirqs_off(); + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + local_irq_enable(); + /* Took an interrupt, may have more exit work to do. */ + goto again; + } + local_paca->irq_happened = 0; + irq_soft_mask_set(IRQS_ENABLED); + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + local_paca->tm_scratch = regs->msr; +#endif + + kuap_check_amr(); + + account_cpu_user_exit(); + + return ret; +} + +#ifdef CONFIG_PPC_BOOK3S /* BOOK3E not yet using this */ +notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned long msr) +{ +#ifdef CONFIG_PPC_BOOK3E + struct thread_struct *ts = ¤t->thread; +#endif + unsigned long *ti_flagsp = ¤t_thread_info()->flags; + unsigned long ti_flags; + unsigned long flags; + unsigned long ret = 0; + + if (IS_ENABLED(CONFIG_PPC_BOOK3S)) + BUG_ON(!(regs->msr & MSR_RI)); + BUG_ON(!(regs->msr & MSR_PR)); + BUG_ON(!FULL_REGS(regs)); + BUG_ON(regs->softe != IRQS_ENABLED); + + local_irq_save(flags); + +again: + ti_flags = READ_ONCE(*ti_flagsp); + while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) { + local_irq_enable(); /* returning to user: may enable */ + if (ti_flags & _TIF_NEED_RESCHED) { + schedule(); + } else { + if (ti_flags & _TIF_SIGPENDING) + ret |= _TIF_RESTOREALL; + do_notify_resume(regs, ti_flags); + } + local_irq_disable(); + ti_flags = READ_ONCE(*ti_flagsp); + } + + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) { + if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && + unlikely((ti_flags & _TIF_RESTORE_TM))) { + restore_tm_state(regs); + } else { + unsigned long mathflags = MSR_FP; + + if (cpu_has_feature(CPU_FTR_VSX)) + mathflags |= MSR_VEC | MSR_VSX; + else if (cpu_has_feature(CPU_FTR_ALTIVEC)) + mathflags |= MSR_VEC; + + if ((regs->msr & mathflags) != mathflags) + restore_math(regs); + } + } + + trace_hardirqs_on(); + __hard_EE_RI_disable(); + if (unlikely(lazy_irq_pending())) { + __hard_RI_enable(); + trace_hardirqs_off(); + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + local_irq_enable(); + local_irq_disable(); + /* Took an interrupt, may have more exit work to do. */ + goto again; + } + local_paca->irq_happened = 0; + irq_soft_mask_set(IRQS_ENABLED); + +#ifdef CONFIG_PPC_BOOK3E + if (unlikely(ts->debug.dbcr0 & DBCR0_IDM)) { + /* + * Check to see if the dbcr0 register is set up to debug. + * Use the internal debug mode bit to do this. + */ + mtmsr(mfmsr() & ~MSR_DE); + mtspr(SPRN_DBCR0, ts->debug.dbcr0); + mtspr(SPRN_DBSR, -1); + } +#endif + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + local_paca->tm_scratch = regs->msr; +#endif + + kuap_check_amr(); + + account_cpu_user_exit(); + + return ret; +} + +void unrecoverable_exception(struct pt_regs *regs); +void preempt_schedule_irq(void); + +notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr) +{ + unsigned long *ti_flagsp = ¤t_thread_info()->flags; + unsigned long flags; + unsigned long ret = 0; + + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && unlikely(!(regs->msr & MSR_RI))) + unrecoverable_exception(regs); + BUG_ON(regs->msr & MSR_PR); + BUG_ON(!FULL_REGS(regs)); + + if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { + clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); + ret = 1; + } + + local_irq_save(flags); + + if (regs->softe == IRQS_ENABLED) { + /* Returning to a kernel context with local irqs enabled. */ + WARN_ON_ONCE(!(regs->msr & MSR_EE)); +again: + if (IS_ENABLED(CONFIG_PREEMPT)) { + /* Return to preemptible kernel context */ + if (unlikely(*ti_flagsp & _TIF_NEED_RESCHED)) { + if (preempt_count() == 0) + preempt_schedule_irq(); + } + } + + trace_hardirqs_on(); + __hard_EE_RI_disable(); + if (unlikely(lazy_irq_pending())) { + __hard_RI_enable(); + irq_soft_mask_set(IRQS_ALL_DISABLED); + trace_hardirqs_off(); + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + /* + * Can't local_irq_restore to replay if we were in + * interrupt context. Must replay directly. + */ + if (irqs_disabled_flags(flags)) { + replay_soft_interrupts(); + } else { + local_irq_restore(flags); + local_irq_save(flags); + } + /* Took an interrupt, may have more exit work to do. */ + goto again; + } + local_paca->irq_happened = 0; + irq_soft_mask_set(IRQS_ENABLED); + } else { + /* Returning to a kernel context with local irqs disabled. */ + __hard_EE_RI_disable(); + if (regs->msr & MSR_EE) + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; + } + + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + local_paca->tm_scratch = regs->msr; +#endif + + /* + * We don't need to restore AMR on the way back to userspace for KUAP. + * The value of AMR only matters while we're in the kernel. + */ + kuap_restore_amr(regs); + + return ret; +} +#endif diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 35b61bfc1b1a..220ae11555f2 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -9,7 +9,9 @@ # 0 nospu restart_syscall sys_restart_syscall 1 nospu exit sys_exit -2 nospu fork ppc_fork +2 32 fork ppc_fork sys_fork +2 64 fork sys_fork +2 spu fork sys_ni_syscall 3 common read sys_read 4 common write sys_write 5 common open sys_open compat_sys_open @@ -158,7 +160,9 @@ 119 32 sigreturn sys_sigreturn compat_sys_sigreturn 119 64 sigreturn sys_ni_syscall 119 spu sigreturn sys_ni_syscall -120 nospu clone ppc_clone +120 32 clone ppc_clone sys_clone +120 64 clone sys_clone +120 spu clone sys_ni_syscall 121 common setdomainname sys_setdomainname 122 common uname sys_newuname 123 common modify_ldt sys_ni_syscall @@ -240,7 +244,9 @@ 186 spu sendfile sys_sendfile64 187 common getpmsg sys_ni_syscall 188 common putpmsg sys_ni_syscall -189 nospu vfork ppc_vfork +189 32 vfork ppc_vfork sys_vfork +189 64 vfork sys_vfork +189 spu vfork sys_ni_syscall 190 common ugetrlimit sys_getrlimit compat_sys_getrlimit 191 common readahead sys_readahead compat_sys_readahead 192 32 mmap2 sys_mmap2 compat_sys_mmap2 @@ -316,8 +322,8 @@ 248 32 clock_nanosleep sys_clock_nanosleep_time32 248 64 clock_nanosleep sys_clock_nanosleep 248 spu clock_nanosleep sys_clock_nanosleep -249 32 swapcontext ppc_swapcontext ppc32_swapcontext -249 64 swapcontext ppc64_swapcontext +249 32 swapcontext ppc_swapcontext compat_sys_swapcontext +249 64 swapcontext sys_swapcontext 249 spu swapcontext sys_ni_syscall 250 common tgkill sys_tgkill 251 32 utimes sys_utimes_time32 @@ -456,7 +462,7 @@ 361 common bpf sys_bpf 362 nospu execveat sys_execveat compat_sys_execveat 363 32 switch_endian sys_ni_syscall -363 64 switch_endian ppc_switch_endian +363 64 switch_endian sys_switch_endian 363 spu switch_endian sys_ni_syscall 364 common userfaultfd sys_userfaultfd 365 common membarrier sys_membarrier @@ -516,6 +522,8 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open -435 nospu clone3 ppc_clone3 +435 32 clone3 ppc_clone3 sys_clone3 +435 64 clone3 sys_clone3 +435 spu clone3 sys_ni_syscall 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd diff --git a/arch/powerpc/kernel/syscalls/syscallhdr.sh b/arch/powerpc/kernel/syscalls/syscallhdr.sh index c0a9a32937f1..02d6751f3be3 100644 --- a/arch/powerpc/kernel/syscalls/syscallhdr.sh +++ b/arch/powerpc/kernel/syscalls/syscallhdr.sh @@ -32,6 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" - printf "\n" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 80a676da11cb..479c70680b76 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -87,6 +87,155 @@ __setup("smt-snooze-delay=", setup_smt_snooze_delay); #endif /* CONFIG_PPC64 */ +#define __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, EXTRA) \ +static void read_##NAME(void *val) \ +{ \ + *(unsigned long *)val = mfspr(ADDRESS); \ +} \ +static void write_##NAME(void *val) \ +{ \ + EXTRA; \ + mtspr(ADDRESS, *(unsigned long *)val); \ +} + +#define __SYSFS_SPRSETUP_SHOW_STORE(NAME) \ +static ssize_t show_##NAME(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct cpu *cpu = container_of(dev, struct cpu, dev); \ + unsigned long val; \ + smp_call_function_single(cpu->dev.id, read_##NAME, &val, 1); \ + return sprintf(buf, "%lx\n", val); \ +} \ +static ssize_t __used \ + store_##NAME(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct cpu *cpu = container_of(dev, struct cpu, dev); \ + unsigned long val; \ + int ret = sscanf(buf, "%lx", &val); \ + if (ret != 1) \ + return -EINVAL; \ + smp_call_function_single(cpu->dev.id, write_##NAME, &val, 1); \ + return count; \ +} + +#define SYSFS_PMCSETUP(NAME, ADDRESS) \ + __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ppc_enable_pmcs()) \ + __SYSFS_SPRSETUP_SHOW_STORE(NAME) +#define SYSFS_SPRSETUP(NAME, ADDRESS) \ + __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ) \ + __SYSFS_SPRSETUP_SHOW_STORE(NAME) + +#define SYSFS_SPRSETUP_SHOW_STORE(NAME) \ + __SYSFS_SPRSETUP_SHOW_STORE(NAME) + +#ifdef CONFIG_PPC64 + +/* + * This is the system wide DSCR register default value. Any + * change to this default value through the sysfs interface + * will update all per cpu DSCR default values across the + * system stored in their respective PACA structures. + */ +static unsigned long dscr_default; + +/** + * read_dscr() - Fetch the cpu specific DSCR default + * @val: Returned cpu specific DSCR default value + * + * This function returns the per cpu DSCR default value + * for any cpu which is contained in it's PACA structure. + */ +static void read_dscr(void *val) +{ + *(unsigned long *)val = get_paca()->dscr_default; +} + + +/** + * write_dscr() - Update the cpu specific DSCR default + * @val: New cpu specific DSCR default value to update + * + * This function updates the per cpu DSCR default value + * for any cpu which is contained in it's PACA structure. + */ +static void write_dscr(void *val) +{ + get_paca()->dscr_default = *(unsigned long *)val; + if (!current->thread.dscr_inherit) { + current->thread.dscr = *(unsigned long *)val; + mtspr(SPRN_DSCR, *(unsigned long *)val); + } +} + +SYSFS_SPRSETUP_SHOW_STORE(dscr); +static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); + +static void add_write_permission_dev_attr(struct device_attribute *attr) +{ + attr->attr.mode |= 0200; +} + +/** + * show_dscr_default() - Fetch the system wide DSCR default + * @dev: Device structure + * @attr: Device attribute structure + * @buf: Interface buffer + * + * This function returns the system wide DSCR default value. + */ +static ssize_t show_dscr_default(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%lx\n", dscr_default); +} + +/** + * store_dscr_default() - Update the system wide DSCR default + * @dev: Device structure + * @attr: Device attribute structure + * @buf: Interface buffer + * @count: Size of the update + * + * This function updates the system wide DSCR default value. + */ +static ssize_t __used store_dscr_default(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + unsigned long val; + int ret = 0; + + ret = sscanf(buf, "%lx", &val); + if (ret != 1) + return -EINVAL; + dscr_default = val; + + on_each_cpu(write_dscr, &val, 1); + + return count; +} + +static DEVICE_ATTR(dscr_default, 0600, + show_dscr_default, store_dscr_default); + +static void sysfs_create_dscr_default(void) +{ + if (cpu_has_feature(CPU_FTR_DSCR)) { + int err = 0; + int cpu; + + dscr_default = spr_default_dscr; + for_each_possible_cpu(cpu) + paca_ptrs[cpu]->dscr_default = dscr_default; + + err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default); + } +} +#endif /* CONFIG_PPC64 */ + #ifdef CONFIG_PPC_FSL_BOOK3E #define MAX_BIT 63 @@ -407,84 +556,35 @@ void ppc_enable_pmcs(void) } EXPORT_SYMBOL(ppc_enable_pmcs); -#define __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, EXTRA) \ -static void read_##NAME(void *val) \ -{ \ - *(unsigned long *)val = mfspr(ADDRESS); \ -} \ -static void write_##NAME(void *val) \ -{ \ - EXTRA; \ - mtspr(ADDRESS, *(unsigned long *)val); \ -} -#define __SYSFS_SPRSETUP_SHOW_STORE(NAME) \ -static ssize_t show_##NAME(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct cpu *cpu = container_of(dev, struct cpu, dev); \ - unsigned long val; \ - smp_call_function_single(cpu->dev.id, read_##NAME, &val, 1); \ - return sprintf(buf, "%lx\n", val); \ -} \ -static ssize_t __used \ - store_##NAME(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct cpu *cpu = container_of(dev, struct cpu, dev); \ - unsigned long val; \ - int ret = sscanf(buf, "%lx", &val); \ - if (ret != 1) \ - return -EINVAL; \ - smp_call_function_single(cpu->dev.id, write_##NAME, &val, 1); \ - return count; \ -} - -#define SYSFS_PMCSETUP(NAME, ADDRESS) \ - __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ppc_enable_pmcs()) \ - __SYSFS_SPRSETUP_SHOW_STORE(NAME) -#define SYSFS_SPRSETUP(NAME, ADDRESS) \ - __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ) \ - __SYSFS_SPRSETUP_SHOW_STORE(NAME) - -#define SYSFS_SPRSETUP_SHOW_STORE(NAME) \ - __SYSFS_SPRSETUP_SHOW_STORE(NAME) /* Let's define all possible registers, we'll only hook up the ones * that are implemented on the current processor */ -#if defined(CONFIG_PPC64) +#ifdef CONFIG_PMU_SYSFS +#if defined(CONFIG_PPC64) || defined(CONFIG_PPC_BOOK3S_32) #define HAS_PPC_PMC_CLASSIC 1 #define HAS_PPC_PMC_IBM 1 -#define HAS_PPC_PMC_PA6T 1 -#elif defined(CONFIG_PPC_BOOK3S_32) -#define HAS_PPC_PMC_CLASSIC 1 -#define HAS_PPC_PMC_IBM 1 -#define HAS_PPC_PMC_G4 1 #endif +#ifdef CONFIG_PPC64 +#define HAS_PPC_PMC_PA6T 1 +#define HAS_PPC_PMC56 1 +#endif -#ifdef HAS_PPC_PMC_CLASSIC -SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); -SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); -SYSFS_PMCSETUP(pmc1, SPRN_PMC1); -SYSFS_PMCSETUP(pmc2, SPRN_PMC2); -SYSFS_PMCSETUP(pmc3, SPRN_PMC3); -SYSFS_PMCSETUP(pmc4, SPRN_PMC4); -SYSFS_PMCSETUP(pmc5, SPRN_PMC5); -SYSFS_PMCSETUP(pmc6, SPRN_PMC6); - -#ifdef HAS_PPC_PMC_G4 -SYSFS_PMCSETUP(mmcr2, SPRN_MMCR2); +#ifdef CONFIG_PPC_BOOK3S_32 +#define HAS_PPC_PMC_G4 1 #endif +#endif /* CONFIG_PMU_SYSFS */ +#if defined(CONFIG_PPC64) && defined(CONFIG_DEBUG_MISC) +#define HAS_PPC_PA6T +#endif +/* + * SPRs which are not related to PMU. + */ #ifdef CONFIG_PPC64 -SYSFS_PMCSETUP(pmc7, SPRN_PMC7); -SYSFS_PMCSETUP(pmc8, SPRN_PMC8); - -SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); SYSFS_SPRSETUP(purr, SPRN_PURR); SYSFS_SPRSETUP(spurr, SPRN_SPURR); SYSFS_SPRSETUP(pir, SPRN_PIR); @@ -495,115 +595,38 @@ SYSFS_SPRSETUP(tscr, SPRN_TSCR); enable write when needed with a separate function. Lets be conservative and default to pseries. */ -static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); static DEVICE_ATTR(purr, 0400, show_purr, store_purr); static DEVICE_ATTR(pir, 0400, show_pir, NULL); static DEVICE_ATTR(tscr, 0600, show_tscr, store_tscr); +#endif /* CONFIG_PPC64 */ -/* - * This is the system wide DSCR register default value. Any - * change to this default value through the sysfs interface - * will update all per cpu DSCR default values across the - * system stored in their respective PACA structures. - */ -static unsigned long dscr_default; - -/** - * read_dscr() - Fetch the cpu specific DSCR default - * @val: Returned cpu specific DSCR default value - * - * This function returns the per cpu DSCR default value - * for any cpu which is contained in it's PACA structure. - */ -static void read_dscr(void *val) -{ - *(unsigned long *)val = get_paca()->dscr_default; -} - - -/** - * write_dscr() - Update the cpu specific DSCR default - * @val: New cpu specific DSCR default value to update - * - * This function updates the per cpu DSCR default value - * for any cpu which is contained in it's PACA structure. - */ -static void write_dscr(void *val) -{ - get_paca()->dscr_default = *(unsigned long *)val; - if (!current->thread.dscr_inherit) { - current->thread.dscr = *(unsigned long *)val; - mtspr(SPRN_DSCR, *(unsigned long *)val); - } -} - -SYSFS_SPRSETUP_SHOW_STORE(dscr); -static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); - -static void add_write_permission_dev_attr(struct device_attribute *attr) -{ - attr->attr.mode |= 0200; -} - -/** - * show_dscr_default() - Fetch the system wide DSCR default - * @dev: Device structure - * @attr: Device attribute structure - * @buf: Interface buffer - * - * This function returns the system wide DSCR default value. - */ -static ssize_t show_dscr_default(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%lx\n", dscr_default); -} - -/** - * store_dscr_default() - Update the system wide DSCR default - * @dev: Device structure - * @attr: Device attribute structure - * @buf: Interface buffer - * @count: Size of the update - * - * This function updates the system wide DSCR default value. - */ -static ssize_t __used store_dscr_default(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret = 0; - - ret = sscanf(buf, "%lx", &val); - if (ret != 1) - return -EINVAL; - dscr_default = val; +#ifdef HAS_PPC_PMC_CLASSIC +SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); +SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); +SYSFS_PMCSETUP(pmc1, SPRN_PMC1); +SYSFS_PMCSETUP(pmc2, SPRN_PMC2); +SYSFS_PMCSETUP(pmc3, SPRN_PMC3); +SYSFS_PMCSETUP(pmc4, SPRN_PMC4); +SYSFS_PMCSETUP(pmc5, SPRN_PMC5); +SYSFS_PMCSETUP(pmc6, SPRN_PMC6); +#endif - on_each_cpu(write_dscr, &val, 1); +#ifdef HAS_PPC_PMC_G4 +SYSFS_PMCSETUP(mmcr2, SPRN_MMCR2); +#endif - return count; -} +#ifdef HAS_PPC_PMC56 +SYSFS_PMCSETUP(pmc7, SPRN_PMC7); +SYSFS_PMCSETUP(pmc8, SPRN_PMC8); -static DEVICE_ATTR(dscr_default, 0600, - show_dscr_default, store_dscr_default); +SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); -static void sysfs_create_dscr_default(void) -{ - if (cpu_has_feature(CPU_FTR_DSCR)) { - int err = 0; - int cpu; +static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); +#endif /* HAS_PPC_PMC56 */ - dscr_default = spr_default_dscr; - for_each_possible_cpu(cpu) - paca_ptrs[cpu]->dscr_default = dscr_default; - err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default); - } -} -#endif /* CONFIG_PPC64 */ #ifdef HAS_PPC_PMC_PA6T SYSFS_PMCSETUP(pa6t_pmc0, SPRN_PA6T_PMC0); @@ -612,7 +635,9 @@ SYSFS_PMCSETUP(pa6t_pmc2, SPRN_PA6T_PMC2); SYSFS_PMCSETUP(pa6t_pmc3, SPRN_PA6T_PMC3); SYSFS_PMCSETUP(pa6t_pmc4, SPRN_PA6T_PMC4); SYSFS_PMCSETUP(pa6t_pmc5, SPRN_PA6T_PMC5); -#ifdef CONFIG_DEBUG_MISC +#endif + +#ifdef HAS_PPC_PA6T SYSFS_SPRSETUP(hid0, SPRN_HID0); SYSFS_SPRSETUP(hid1, SPRN_HID1); SYSFS_SPRSETUP(hid4, SPRN_HID4); @@ -641,15 +666,14 @@ SYSFS_SPRSETUP(tsr0, SPRN_PA6T_TSR0); SYSFS_SPRSETUP(tsr1, SPRN_PA6T_TSR1); SYSFS_SPRSETUP(tsr2, SPRN_PA6T_TSR2); SYSFS_SPRSETUP(tsr3, SPRN_PA6T_TSR3); -#endif /* CONFIG_DEBUG_MISC */ -#endif /* HAS_PPC_PMC_PA6T */ +#endif /* HAS_PPC_PA6T */ #ifdef HAS_PPC_PMC_IBM static struct device_attribute ibm_common_attrs[] = { __ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), __ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), }; -#endif /* HAS_PPC_PMC_G4 */ +#endif /* HAS_PPC_PMC_IBM */ #ifdef HAS_PPC_PMC_G4 static struct device_attribute g4_common_attrs[] = { @@ -659,6 +683,7 @@ static struct device_attribute g4_common_attrs[] = { }; #endif /* HAS_PPC_PMC_G4 */ +#ifdef HAS_PPC_PMC_CLASSIC static struct device_attribute classic_pmc_attrs[] = { __ATTR(pmc1, 0600, show_pmc1, store_pmc1), __ATTR(pmc2, 0600, show_pmc2, store_pmc2), @@ -666,14 +691,16 @@ static struct device_attribute classic_pmc_attrs[] = { __ATTR(pmc4, 0600, show_pmc4, store_pmc4), __ATTR(pmc5, 0600, show_pmc5, store_pmc5), __ATTR(pmc6, 0600, show_pmc6, store_pmc6), -#ifdef CONFIG_PPC64 +#ifdef HAS_PPC_PMC56 __ATTR(pmc7, 0600, show_pmc7, store_pmc7), __ATTR(pmc8, 0600, show_pmc8, store_pmc8), #endif }; +#endif -#ifdef HAS_PPC_PMC_PA6T +#if defined(HAS_PPC_PMC_PA6T) || defined(HAS_PPC_PA6T) static struct device_attribute pa6t_attrs[] = { +#ifdef HAS_PPC_PMC_PA6T __ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), __ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), __ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0), @@ -682,7 +709,8 @@ static struct device_attribute pa6t_attrs[] = { __ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3), __ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4), __ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5), -#ifdef CONFIG_DEBUG_MISC +#endif +#ifdef HAS_PPC_PA6T __ATTR(hid0, 0600, show_hid0, store_hid0), __ATTR(hid1, 0600, show_hid1, store_hid1), __ATTR(hid4, 0600, show_hid4, store_hid4), @@ -711,10 +739,9 @@ static struct device_attribute pa6t_attrs[] = { __ATTR(tsr1, 0600, show_tsr1, store_tsr1), __ATTR(tsr2, 0600, show_tsr2, store_tsr2), __ATTR(tsr3, 0600, show_tsr3, store_tsr3), -#endif /* CONFIG_DEBUG_MISC */ +#endif /* HAS_PPC_PA6T */ }; -#endif /* HAS_PPC_PMC_PA6T */ -#endif /* HAS_PPC_PMC_CLASSIC */ +#endif #ifdef CONFIG_PPC_SVM static ssize_t show_svm(struct device *dev, struct device_attribute *attr, char *buf) @@ -765,14 +792,14 @@ static int register_cpu_online(unsigned int cpu) pmc_attrs = classic_pmc_attrs; break; #endif /* HAS_PPC_PMC_G4 */ -#ifdef HAS_PPC_PMC_PA6T +#if defined(HAS_PPC_PMC_PA6T) || defined(HAS_PPC_PA6T) case PPC_PMC_PA6T: /* PA Semi starts counting at PMC0 */ attrs = pa6t_attrs; nattrs = sizeof(pa6t_attrs) / sizeof(struct device_attribute); pmc_attrs = NULL; break; -#endif /* HAS_PPC_PMC_PA6T */ +#endif default: attrs = NULL; nattrs = 0; @@ -787,8 +814,10 @@ static int register_cpu_online(unsigned int cpu) device_create_file(s, &pmc_attrs[i]); #ifdef CONFIG_PPC64 +#ifdef CONFIG_PMU_SYSFS if (cpu_has_feature(CPU_FTR_MMCRA)) device_create_file(s, &dev_attr_mmcra); +#endif /* CONFIG_PMU_SYSFS */ if (cpu_has_feature(CPU_FTR_PURR)) { if (!firmware_has_feature(FW_FEATURE_LPAR)) @@ -854,14 +883,14 @@ static int unregister_cpu_online(unsigned int cpu) pmc_attrs = classic_pmc_attrs; break; #endif /* HAS_PPC_PMC_G4 */ -#ifdef HAS_PPC_PMC_PA6T +#if defined(HAS_PPC_PMC_PA6T) || defined(HAS_PPC_PA6T) case PPC_PMC_PA6T: /* PA Semi starts counting at PMC0 */ attrs = pa6t_attrs; nattrs = sizeof(pa6t_attrs) / sizeof(struct device_attribute); pmc_attrs = NULL; break; -#endif /* HAS_PPC_PMC_PA6T */ +#endif default: attrs = NULL; nattrs = 0; @@ -876,8 +905,10 @@ static int unregister_cpu_online(unsigned int cpu) device_remove_file(s, &pmc_attrs[i]); #ifdef CONFIG_PPC64 +#ifdef CONFIG_PMU_SYSFS if (cpu_has_feature(CPU_FTR_MMCRA)) device_remove_file(s, &dev_attr_mmcra); +#endif /* CONFIG_PMU_SYSFS */ if (cpu_has_feature(CPU_FTR_PURR)) device_remove_file(s, &dev_attr_purr); diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 5b905a2f4e4d..d34276f3c495 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -16,25 +16,22 @@ #ifdef CONFIG_PPC64 .p2align 3 +#define __SYSCALL(nr, entry) .8byte entry +#else +#define __SYSCALL(nr, entry) .long entry #endif .globl sys_call_table sys_call_table: #ifdef CONFIG_PPC64 -#define __SYSCALL(nr, entry) .8byte DOTSYM(entry) #include <asm/syscall_table_64.h> -#undef __SYSCALL #else -#define __SYSCALL(nr, entry) .long entry #include <asm/syscall_table_32.h> -#undef __SYSCALL #endif #ifdef CONFIG_COMPAT .globl compat_sys_call_table compat_sys_call_table: #define compat_sys_sigsuspend sys_sigsuspend -#define __SYSCALL(nr, entry) .8byte DOTSYM(entry) #include <asm/syscall_table_c32.h> -#undef __SYSCALL #endif diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 1168e8b37e30..6fcae436ae51 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -50,7 +50,7 @@ #include <linux/irq.h> #include <linux/delay.h> #include <linux/irq_work.h> -#include <linux/clk-provider.h> +#include <linux/of_clk.h> #include <linux/suspend.h> #include <linux/sched/cputime.h> #include <linux/processor.h> @@ -522,35 +522,6 @@ static inline void clear_irq_work_pending(void) "i" (offsetof(struct paca_struct, irq_work_pending))); } -void arch_irq_work_raise(void) -{ - preempt_disable(); - set_irq_work_pending_flag(); - /* - * Non-nmi code running with interrupts disabled will replay - * irq_happened before it re-enables interrupts, so setthe - * decrementer there instead of causing a hardware exception - * which would immediately hit the masked interrupt handler - * and have the net effect of setting the decrementer in - * irq_happened. - * - * NMI interrupts can not check this when they return, so the - * decrementer hardware exception is raised, which will fire - * when interrupts are next enabled. - * - * BookE does not support this yet, it must audit all NMI - * interrupt handlers to ensure they call nmi_enter() so this - * check would be correct. - */ - if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) { - set_dec(1); - } else { - hard_irq_disable(); - local_paca->irq_happened |= PACA_IRQ_DEC; - } - preempt_enable(); -} - #else /* 32-bit */ DEFINE_PER_CPU(u8, irq_work_pending); @@ -559,16 +530,27 @@ DEFINE_PER_CPU(u8, irq_work_pending); #define test_irq_work_pending() __this_cpu_read(irq_work_pending) #define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0) +#endif /* 32 vs 64 bit */ + void arch_irq_work_raise(void) { + /* + * 64-bit code that uses irq soft-mask can just cause an immediate + * interrupt here that gets soft masked, if this is called under + * local_irq_disable(). It might be possible to prevent that happening + * by noticing interrupts are disabled and setting decrementer pending + * to be replayed when irqs are enabled. The problem there is that + * tracing can call irq_work_raise, including in code that does low + * level manipulations of irq soft-mask state (e.g., trace_hardirqs_on) + * which could get tangled up if we're messing with the same state + * here. + */ preempt_disable(); set_irq_work_pending_flag(); set_dec(1); preempt_enable(); } -#endif /* 32 vs 64 bit */ - #else /* CONFIG_IRQ_WORK */ #define test_irq_work_pending() 0 @@ -663,15 +645,6 @@ void timer_broadcast_interrupt(void) } #endif -/* - * Hypervisor decrementer interrupts shouldn't occur but are sometimes - * left pending on exit from a KVM guest. We don't need to do anything - * to clear them, as they are edge-triggered. - */ -void hdec_interrupt(struct pt_regs *regs) -{ -} - #ifdef CONFIG_SUSPEND static void generic_suspend_disable_irqs(void) { @@ -1158,9 +1131,7 @@ void __init time_init(void) init_decrementer_clockevent(); tick_setup_hrtimer_broadcast(); -#ifdef CONFIG_COMMON_CLK of_clk_init(NULL); -#endif } /* diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 82a3438300fd..3fca22276bb1 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -2278,35 +2278,20 @@ void ppc_warn_emulated_print(const char *type) static int __init ppc_warn_emulated_init(void) { - struct dentry *dir, *d; + struct dentry *dir; unsigned int i; struct ppc_emulated_entry *entries = (void *)&ppc_emulated; - if (!powerpc_debugfs_root) - return -ENODEV; - dir = debugfs_create_dir("emulated_instructions", powerpc_debugfs_root); - if (!dir) - return -ENOMEM; - d = debugfs_create_u32("do_warn", 0644, dir, - &ppc_warn_emulated); - if (!d) - goto fail; + debugfs_create_u32("do_warn", 0644, dir, &ppc_warn_emulated); - for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) { - d = debugfs_create_u32(entries[i].name, 0644, dir, - (u32 *)&entries[i].val.counter); - if (!d) - goto fail; - } + for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) + debugfs_create_u32(entries[i].name, 0644, dir, + (u32 *)&entries[i].val.counter); return 0; - -fail: - debugfs_remove_recursive(dir); - return -ENOMEM; } device_initcall(ppc_warn_emulated_init); diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index b9a108411c0d..f38f26e844b6 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -391,12 +391,7 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib, symname); return 0; } -#ifdef VDS64_HAS_DESCRIPTORS - return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) - - VDSO64_LBASE; -#else return sym->st_value - VDSO64_LBASE; -#endif } static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32, @@ -656,7 +651,8 @@ static void __init vdso_setup_syscall_map(void) if (sys_call_table[i] != sys_ni_syscall) vdso_data->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f); - if (compat_sys_call_table[i] != sys_ni_syscall) + if (IS_ENABLED(CONFIG_COMPAT) && + compat_sys_call_table[i] != sys_ni_syscall) vdso_data->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f); #else /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/vdso32/.gitignore b/arch/powerpc/kernel/vdso32/.gitignore index fea5809857a5..824b863ec6bd 100644 --- a/arch/powerpc/kernel/vdso32/.gitignore +++ b/arch/powerpc/kernel/vdso32/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso32.lds vdso32.so.dbg diff --git a/arch/powerpc/kernel/vdso64/.gitignore b/arch/powerpc/kernel/vdso64/.gitignore index 77a0b423642c..84151a7ba31d 100644 --- a/arch/powerpc/kernel/vdso64/.gitignore +++ b/arch/powerpc/kernel/vdso64/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso64.lds vdso64.so.dbg diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 25c14a0981bf..d20c5e79e03c 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -134,7 +134,7 @@ _GLOBAL(load_up_vsx) /* enable use of VSX after return */ oris r12,r12,MSR_VSX@h std r12,_MSR(r1) - b fast_exception_return + b fast_interrupt_return #endif /* CONFIG_VSX */ diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index b4c89a1acebb..31a0f201fb6f 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -256,6 +256,7 @@ SECTIONS *(.dynamic) } .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) } + .gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) } .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) } .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET) { diff --git a/arch/powerpc/kexec/Makefile b/arch/powerpc/kexec/Makefile index 378f6108a414..86380c69f5ce 100644 --- a/arch/powerpc/kexec/Makefile +++ b/arch/powerpc/kexec/Makefile @@ -3,9 +3,6 @@ # Makefile for the linux kernel. # -# Avoid clang warnings around longjmp/setjmp declarations -CFLAGS_crash.o += -ffreestanding - obj-y += core.o crash.o core_$(BITS).o obj-$(CONFIG_PPC32) += relocate_32.o diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 711fca9bc6f0..12885eda324e 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -204,6 +204,4 @@ config KVM_XIVE default y depends on KVM_XICS && PPC_XIVE_NATIVE && KVM_BOOK3S_HV_POSSIBLE -source "drivers/vhost/Kconfig" - endif # VIRTUALIZATION diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 3aecec890d6f..2b35f9bcf892 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -604,18 +604,19 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, */ local_irq_disable(); ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift); + pte = __pte(0); + if (ptep) + pte = *ptep; + local_irq_enable(); /* * If the PTE disappeared temporarily due to a THP * collapse, just return and let the guest try again. */ - if (!ptep) { - local_irq_enable(); + if (!pte_present(pte)) { if (page) put_page(page); return RESUME_GUEST; } - pte = *ptep; - local_irq_enable(); hpa = pte_pfn(pte) << PAGE_SHIFT; pte_size = PAGE_SIZE; if (shift) @@ -2133,9 +2134,8 @@ static const struct file_operations debugfs_htab_fops = { void kvmppc_mmu_debugfs_init(struct kvm *kvm) { - kvm->arch.htab_dentry = debugfs_create_file("htab", 0400, - kvm->arch.debugfs_dir, kvm, - &debugfs_htab_fops); + debugfs_create_file("htab", 0400, kvm->arch.debugfs_dir, kvm, + &debugfs_htab_fops); } void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu) diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 134fbc1f029f..aa12cd4078b3 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -815,18 +815,19 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu, */ local_irq_disable(); ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift); + pte = __pte(0); + if (ptep) + pte = *ptep; + local_irq_enable(); /* * If the PTE disappeared temporarily due to a THP * collapse, just return and let the guest try again. */ - if (!ptep) { - local_irq_enable(); + if (!pte_present(pte)) { if (page) put_page(page); return RESUME_GUEST; } - pte = *ptep; - local_irq_enable(); /* If we're logging dirty pages, always map single pages */ large_enable = !(memslot->flags & KVM_MEM_LOG_DIRTY_PAGES); @@ -1376,9 +1377,8 @@ static const struct file_operations debugfs_radix_fops = { void kvmhv_radix_debugfs_init(struct kvm *kvm) { - kvm->arch.radix_dentry = debugfs_create_file("radix", 0400, - kvm->arch.debugfs_dir, kvm, - &debugfs_radix_fops); + debugfs_create_file("radix", 0400, kvm->arch.debugfs_dir, kvm, + &debugfs_radix_fops); } int kvmppc_radix_init(void) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index fa6e4fc7d0e4..93493f0cbfe8 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2267,14 +2267,9 @@ static void debugfs_vcpu_init(struct kvm_vcpu *vcpu, unsigned int id) struct kvm *kvm = vcpu->kvm; snprintf(buf, sizeof(buf), "vcpu%u", id); - if (IS_ERR_OR_NULL(kvm->arch.debugfs_dir)) - return; vcpu->arch.debugfs_dir = debugfs_create_dir(buf, kvm->arch.debugfs_dir); - if (IS_ERR_OR_NULL(vcpu->arch.debugfs_dir)) - return; - vcpu->arch.debugfs_timings = - debugfs_create_file("timings", 0444, vcpu->arch.debugfs_dir, - vcpu, &debugfs_timings_ops); + debugfs_create_file("timings", 0444, vcpu->arch.debugfs_dir, vcpu, + &debugfs_timings_ops); } #else /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */ diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index dbc2fecc37f0..780a499c7114 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1266,7 +1266,6 @@ kvmppc_interrupt_hv: * R12 = (guest CR << 32) | interrupt vector * R13 = PACA * guest R12 saved in shadow VCPU SCRATCH0 - * guest CTR saved in shadow VCPU SCRATCH1 if RELOCATABLE * guest R13 saved in SPRN_SCRATCH0 */ std r9, HSTATE_SCRATCH2(r13) @@ -1367,12 +1366,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 11: stw r3,VCPU_HEIR(r9) /* these are volatile across C function calls */ -#ifdef CONFIG_RELOCATABLE - ld r3, HSTATE_SCRATCH1(r13) - mtctr r3 -#else mfctr r3 -#endif mfxer r4 std r3, VCPU_CTR(r9) std r4, VCPU_XER(r9) @@ -3258,7 +3252,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST) * r12 is (CR << 32) | vector * r13 points to our PACA * r12 is saved in HSTATE_SCRATCH0(r13) - * ctr is saved in HSTATE_SCRATCH1(r13) if RELOCATABLE * r9 is saved in HSTATE_SCRATCH2(r13) * r13 is saved in HSPRG1 * cfar is saved in HSTATE_CFAR(r13) @@ -3307,11 +3300,7 @@ kvmppc_bad_host_intr: ld r5, HSTATE_CFAR(r13) std r5, ORIG_GPR3(r1) mflr r3 -#ifdef CONFIG_RELOCATABLE - ld r4, HSTATE_SCRATCH1(r13) -#else mfctr r4 -#endif mfxer r5 lbz r6, PACAIRQSOFTMASK(r13) std r3, _LINK(r1) diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 0169bab544dd..1f492aa4c8d6 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S @@ -167,16 +167,9 @@ kvmppc_interrupt_pr: * R12 = (guest CR << 32) | exit handler id * R13 = PACA * HSTATE.SCRATCH0 = guest R12 - * HSTATE.SCRATCH1 = guest CTR if RELOCATABLE */ #ifdef CONFIG_PPC64 /* Match 32-bit entry */ -#ifdef CONFIG_RELOCATABLE - std r9, HSTATE_SCRATCH2(r13) - ld r9, HSTATE_SCRATCH1(r13) - mtctr r9 - ld r9, HSTATE_SCRATCH2(r13) -#endif rotldi r12, r12, 32 /* Flip R12 halves for stw */ stw r12, HSTATE_SCRATCH1(r13) /* CR is now in the low half */ srdi r12, r12, 32 /* shift trap into low half */ diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 425d13806645..df9989cf7ba3 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -422,7 +422,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, break; } } else if (vma && hva >= vma->vm_start && - (vma->vm_flags & VM_HUGETLB)) { + is_vm_hugetlb_page(vma)) { unsigned long psize = vma_kernel_pagesize(vma); tsize = (gtlbe->mas1 & MAS1_TSIZE_MASK) >> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 7e24691e138a..052614e9d468 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -521,6 +521,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_IOEVENTFD: case KVM_CAP_DEVICE_CTRL: case KVM_CAP_IMMEDIATE_EXIT: + case KVM_CAP_SET_GUEST_DEBUG: r = 1; break; case KVM_CAP_PPC_GUEST_DEBUG_SSTEP: diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index bfe4f106cffc..ba56a5cbba97 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c @@ -211,23 +211,14 @@ void kvmppc_create_vcpu_debugfs(struct kvm_vcpu *vcpu, unsigned int id) snprintf(dbg_fname, sizeof(dbg_fname), "vm%u_vcpu%u_timing", current->pid, id); - debugfs_file = debugfs_create_file(dbg_fname, 0666, - kvm_debugfs_dir, vcpu, - &kvmppc_exit_timing_fops); - - if (!debugfs_file) { - printk(KERN_ERR"%s: error creating debugfs file %s\n", - __func__, dbg_fname); - return; - } + debugfs_file = debugfs_create_file(dbg_fname, 0666, kvm_debugfs_dir, + vcpu, &kvmppc_exit_timing_fops); vcpu->arch.debugfs_exit_timing = debugfs_file; } void kvmppc_remove_vcpu_debugfs(struct kvm_vcpu *vcpu) { - if (vcpu->arch.debugfs_exit_timing) { - debugfs_remove(vcpu->arch.debugfs_exit_timing); - vcpu->arch.debugfs_exit_timing = NULL; - } + debugfs_remove(vcpu->arch.debugfs_exit_timing); + vcpu->arch.debugfs_exit_timing = NULL; } diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index c077acb983a1..5f3a7bd9d90d 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -3179,8 +3179,9 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) * entry code works. If that is changed, this will * need to be changed also. */ - if (regs->gpr[0] == 0x1ebe && - cpu_has_feature(CPU_FTR_REAL_LE)) { + if (IS_ENABLED(CONFIG_PPC_FAST_ENDIAN_SWITCH) && + cpu_has_feature(CPU_FTR_REAL_LE) && + regs->gpr[0] == 0x1ebe) { regs->msr ^= MSR_LE; goto instr_done; } diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 42347067739c..53df4146dd32 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -13,19 +13,20 @@ #include <asm/code-patching.h> #define IMM_L(i) ((uintptr_t)(i) & 0xffff) +#define IMM_DS(i) ((uintptr_t)(i) & 0xfffc) /* * Defined with TEST_ prefix so it does not conflict with other * definitions. */ #define TEST_LD(r, base, i) (PPC_INST_LD | ___PPC_RT(r) | \ - ___PPC_RA(base) | IMM_L(i)) + ___PPC_RA(base) | IMM_DS(i)) #define TEST_LWZ(r, base, i) (PPC_INST_LWZ | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) #define TEST_LWZX(t, a, b) (PPC_INST_LWZX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) #define TEST_STD(r, base, i) (PPC_INST_STD | ___PPC_RS(r) | \ - ___PPC_RA(base) | ((i) & 0xfffc)) + ___PPC_RA(base) | IMM_DS(i)) #define TEST_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b) | \ __PPC_EH(eh)) @@ -160,7 +161,7 @@ static void __init test_std(void) /* std r5, 0(r3) */ stepped = emulate_step(®s, TEST_STD(5, 3, 0)); - if (stepped == 1 || regs.gpr[5] == a) + if (stepped == 1 && regs.gpr[5] == a) show_result("std", "PASS"); else show_result("std", "FAIL"); diff --git a/arch/powerpc/mm/book3s32/hash_low.S b/arch/powerpc/mm/book3s32/hash_low.S index 2015c4f96238..6d236080cb1a 100644 --- a/arch/powerpc/mm/book3s32/hash_low.S +++ b/arch/powerpc/mm/book3s32/hash_low.S @@ -35,7 +35,7 @@ mmu_hash_lock: /* * Load a PTE into the hash table, if possible. * The address is in r4, and r3 contains an access flag: - * _PAGE_RW (0x400) if a write. + * _PAGE_RW (0x002) if a write. * r9 contains the SRR1 value, from which we use the MSR_PR bit. * SPRG_THREAD contains the physical address of the current task's thread. * @@ -69,7 +69,7 @@ _GLOBAL(hash_page) blt+ 112f /* assume user more likely */ lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ - rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ + rlwimi r3,r9,32-14,31,31 /* MSR_PR -> _PAGE_USER */ 112: #ifndef CONFIG_PTE_64BIT rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ @@ -94,7 +94,7 @@ _GLOBAL(hash_page) #else rlwimi r8,r4,23,20,28 /* compute pte address */ #endif - rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + rlwinm r0,r3,6,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE /* @@ -310,11 +310,9 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) _GLOBAL(create_hpte) /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */ - rlwinm r8,r5,32-9,30,30 /* _PAGE_RW -> PP msb */ rlwinm r0,r5,32-6,30,30 /* _PAGE_DIRTY -> PP msb */ - and r8,r8,r0 /* writable if _RW & _DIRTY */ - rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ - rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ + and r8,r5,r0 /* writable if _RW & _DIRTY */ + rlwimi r5,r5,1,30,30 /* _PAGE_USER -> PP msb */ ori r8,r8,0xe04 /* clear out reserved bits */ andc r8,r5,r8 /* PP = user? (rw&dirty? 1: 3): 0 */ BEGIN_FTR_SECTION @@ -566,7 +564,7 @@ _GLOBAL(flush_hash_pages) 33: lwarx r8,0,r5 /* fetch the pte flags word */ andi. r0,r8,_PAGE_HASHPTE beq 8f /* done if HASHPTE is already clear */ - rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ + rlwinm r8,r8,0,~_PAGE_HASHPTE /* clear HASHPTE bit */ stwcx. r8,0,r5 /* update the pte */ bne- 33b @@ -690,18 +688,21 @@ _GLOBAL(_tlbia) bne- 10b stwcx. r8,0,r9 bne- 10b +#endif /* CONFIG_SMP */ + li r5, 32 + lis r4, KERNELBASE@h + mtctr r5 sync - tlbia +0: tlbie r4 + addi r4, r4, 0x1000 + bdnz 0b sync +#ifdef CONFIG_SMP TLBSYNC li r0,0 stw r0,0(r9) /* clear mmu_hash_lock */ mtmsr r10 SYNC_601 isync -#else /* CONFIG_SMP */ - sync - tlbia - sync #endif /* CONFIG_SMP */ blr diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c index f888cbb109b9..39ba53ca5bb5 100644 --- a/arch/powerpc/mm/book3s32/mmu.c +++ b/arch/powerpc/mm/book3s32/mmu.c @@ -312,7 +312,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea) if (!Hash) return; - pmd = pmd_offset(pud_offset(pgd_offset(mm, ea), ea), ea); + pmd = pmd_ptr(mm, ea); if (!pmd_none(*pmd)) add_hash_page(mm->context.id, ea, pmd_val(*pmd)); } diff --git a/arch/powerpc/mm/book3s32/tlb.c b/arch/powerpc/mm/book3s32/tlb.c index 2fcd321040ff..dc9039a170aa 100644 --- a/arch/powerpc/mm/book3s32/tlb.c +++ b/arch/powerpc/mm/book3s32/tlb.c @@ -79,15 +79,18 @@ static void flush_range(struct mm_struct *mm, unsigned long start, int count; unsigned int ctx = mm->context.id; + start &= PAGE_MASK; if (!Hash) { - _tlbia(); + if (end - start <= PAGE_SIZE) + _tlbie(start); + else + _tlbia(); return; } - start &= PAGE_MASK; if (start >= end) return; end = (end - 1) | ~PAGE_MASK; - pmd = pmd_offset(pud_offset(pgd_offset(mm, start), start), start); + pmd = pmd_ptr(mm, start); for (;;) { pmd_end = ((start + PGDIR_SIZE) & PGDIR_MASK) - 1; if (pmd_end > end) @@ -145,7 +148,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) return; } mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; - pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr); + pmd = pmd_ptr(mm, vmaddr); if (!pmd_none(*pmd)) flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); } diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 523d4d39d11e..8ed2411c3f39 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -809,7 +809,8 @@ int resize_hpt_for_hotplug(unsigned long new_mem_size) return 0; } -int hash__create_section_mapping(unsigned long start, unsigned long end, int nid) +int hash__create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot) { int rc; @@ -819,7 +820,7 @@ int hash__create_section_mapping(unsigned long start, unsigned long end, int nid } rc = htab_bolt_mapping(start, end, __pa(start), - pgprot_val(PAGE_KERNEL), mmu_linear_psize, + pgprot_val(prot), mmu_linear_psize, mmu_kernel_ssize); if (rc < 0) { @@ -2018,11 +2019,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n") static int __init hash64_debugfs(void) { - if (!debugfs_create_file_unsafe("hpt_order", 0600, powerpc_debugfs_root, - NULL, &fops_hpt_order)) { - pr_err("lpar: unable to create hpt_order debugsfs file\n"); - } - + debugfs_create_file("hpt_order", 0600, powerpc_debugfs_root, NULL, + &fops_hpt_order); return 0; } machine_device_initcall(pseries, hash64_debugfs); diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c index eba73ebd8ae5..fa05bbd1f682 100644 --- a/arch/powerpc/mm/book3s64/iommu_api.c +++ b/arch/powerpc/mm/book3s64/iommu_api.c @@ -121,24 +121,6 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, goto free_exit; } - pageshift = PAGE_SHIFT; - for (i = 0; i < entries; ++i) { - struct page *page = mem->hpages[i]; - - /* - * Allow to use larger than 64k IOMMU pages. Only do that - * if we are backed by hugetlb. - */ - if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) - pageshift = page_shift(compound_head(page)); - mem->pageshift = min(mem->pageshift, pageshift); - /* - * We don't need struct page reference any more, switch - * to physical address. - */ - mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT; - } - good_exit: atomic64_set(&mem->mapped, 1); mem->used = 1; @@ -158,6 +140,27 @@ good_exit: } } + if (mem->dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) { + /* + * Allow to use larger than 64k IOMMU pages. Only do that + * if we are backed by hugetlb. Skip device memory as it is not + * backed with page structs. + */ + pageshift = PAGE_SHIFT; + for (i = 0; i < entries; ++i) { + struct page *page = mem->hpages[i]; + + if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) + pageshift = page_shift(compound_head(page)); + mem->pageshift = min(mem->pageshift, pageshift); + /* + * We don't need struct page reference any more, switch + * to physical address. + */ + mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT; + } + } + list_add_rcu(&mem->next, &mm->context.iommu_group_mem_list); mutex_unlock(&mem_list_mutex); diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index 2bf7e1b4fd82..e0bb69c616e4 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -171,12 +171,13 @@ void mmu_cleanup_all(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int __meminit create_section_mapping(unsigned long start, unsigned long end, int nid) +int __meminit create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot) { if (radix_enabled()) - return radix__create_section_mapping(start, end, nid); + return radix__create_section_mapping(start, end, nid, prot); - return hash__create_section_mapping(start, end, nid); + return hash__create_section_mapping(start, end, nid, prot); } int __meminit remove_section_mapping(unsigned long start, unsigned long end) diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index 07527f1ed108..1199fc2bfaec 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -315,7 +315,7 @@ int __execute_only_pkey(struct mm_struct *mm) static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma) { /* Do this check first since the vm_flags should be hot */ - if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC) + if ((vma->vm_flags & VM_ACCESS_FLAGS) != VM_EXEC) return false; return (vma_pkey(vma) == vma->vm_mm->context.execute_only_pkey); diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index dd1bea45325c..8f9edf07063a 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -26,6 +26,7 @@ #include <asm/firmware.h> #include <asm/powernv.h> #include <asm/sections.h> +#include <asm/smp.h> #include <asm/trace.h> #include <asm/uaccess.h> #include <asm/ultravisor.h> @@ -253,7 +254,7 @@ static unsigned long next_boundary(unsigned long addr, unsigned long end) static int __meminit create_physical_mapping(unsigned long start, unsigned long end, - int nid) + int nid, pgprot_t _prot) { unsigned long vaddr, addr, mapping_size = 0; bool prev_exec, exec = false; @@ -289,7 +290,7 @@ static int __meminit create_physical_mapping(unsigned long start, prot = PAGE_KERNEL_X; exec = true; } else { - prot = PAGE_KERNEL; + prot = _prot; exec = false; } @@ -333,7 +334,7 @@ static void __init radix_init_pgtable(void) WARN_ON(create_physical_mapping(reg->base, reg->base + reg->size, - -1)); + -1, PAGE_KERNEL)); } /* Find out how many PID bits are supported */ @@ -712,8 +713,10 @@ static int __meminit stop_machine_change_mapping(void *data) spin_unlock(&init_mm.page_table_lock); pte_clear(&init_mm, params->aligned_start, params->pte); - create_physical_mapping(__pa(params->aligned_start), __pa(params->start), -1); - create_physical_mapping(__pa(params->end), __pa(params->aligned_end), -1); + create_physical_mapping(__pa(params->aligned_start), + __pa(params->start), -1, PAGE_KERNEL); + create_physical_mapping(__pa(params->end), __pa(params->aligned_end), + -1, PAGE_KERNEL); spin_lock(&init_mm.page_table_lock); return 0; } @@ -870,14 +873,16 @@ static void __meminit remove_pagetable(unsigned long start, unsigned long end) radix__flush_tlb_kernel_range(start, end); } -int __meminit radix__create_section_mapping(unsigned long start, unsigned long end, int nid) +int __meminit radix__create_section_mapping(unsigned long start, + unsigned long end, int nid, + pgprot_t prot) { if (end >= RADIX_VMALLOC_START) { pr_warn("Outside the supported range\n"); return -1; } - return create_physical_mapping(__pa(start), __pa(end), nid); + return create_physical_mapping(__pa(start), __pa(end), nid, prot); } int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end) diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 03f43c924e00..758ade2c2b6e 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -587,6 +587,11 @@ void radix__local_flush_all_mm(struct mm_struct *mm) preempt_enable(); } EXPORT_SYMBOL(radix__local_flush_all_mm); + +static void __flush_all_mm(struct mm_struct *mm, bool fullmm) +{ + radix__local_flush_all_mm(mm); +} #endif /* CONFIG_SMP */ void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, @@ -777,7 +782,7 @@ void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) EXPORT_SYMBOL(radix__flush_tlb_page); #else /* CONFIG_SMP */ -#define radix__flush_all_mm radix__local_flush_all_mm +static inline void exit_flush_lazy_tlbs(struct mm_struct *mm) { } #endif /* CONFIG_SMP */ static void do_tlbiel_kernel(void *info) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index d15f0f0ee806..84af6c8eecf7 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -314,7 +314,7 @@ static bool access_error(bool is_write, bool is_exec, return false; } - if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + if (unlikely(!vma_is_accessible(vma))) return true; /* * We should ideally do the vma pkey access check here. But in the diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c index fc669643ce6a..b1a0aebe8c48 100644 --- a/arch/powerpc/mm/ioremap.c +++ b/arch/powerpc/mm/ioremap.c @@ -2,6 +2,7 @@ #include <linux/io.h> #include <linux/slab.h> +#include <linux/mmzone.h> #include <linux/vmalloc.h> #include <asm/io-workarounds.h> @@ -97,3 +98,23 @@ void __iomem *do_ioremap(phys_addr_t pa, phys_addr_t offset, unsigned long size, return NULL; } + +#ifdef CONFIG_ZONE_DEVICE +/* + * Override the generic version in mm/memremap.c. + * + * With hash translation, the direct-map range is mapped with just one + * page size selected by htab_init_page_sizes(). Consult + * mmu_psize_defs[] to determine the minimum page size alignment. +*/ +unsigned long memremap_compat_align(void) +{ + unsigned int shift = mmu_psize_defs[mmu_linear_psize].shift; + + if (radix_enabled()) + return SUBSECTION_SIZE; + return max(SUBSECTION_SIZE, 1UL << shift); + +} +EXPORT_SYMBOL_GPL(memremap_compat_align); +#endif diff --git a/arch/powerpc/mm/kasan/kasan_init_32.c b/arch/powerpc/mm/kasan/kasan_init_32.c index d2bed3fcb719..cbcad369fcb2 100644 --- a/arch/powerpc/mm/kasan/kasan_init_32.c +++ b/arch/powerpc/mm/kasan/kasan_init_32.c @@ -36,7 +36,7 @@ static int __init kasan_init_shadow_page_tables(unsigned long k_start, unsigned unsigned long k_cur, k_next; pte_t *new = NULL; - pmd = pmd_offset(pud_offset(pgd_offset_k(k_start), k_start), k_start); + pmd = pmd_ptr_k(k_start); for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd++) { k_next = pgd_addr_end(k_cur, k_end); @@ -78,7 +78,7 @@ static int __init kasan_init_region(void *start, size_t size) block = memblock_alloc(k_end - k_start, PAGE_SIZE); for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { - pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); + pmd_t *pmd = pmd_ptr_k(k_cur); void *va = block + k_cur - k_start; pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL); @@ -101,8 +101,8 @@ static void __init kasan_remap_early_shadow_ro(void) kasan_populate_pte(kasan_early_shadow_pte, prot); - for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { - pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); + for (k_cur = k_start & PAGE_MASK; k_cur != k_end; k_cur += PAGE_SIZE) { + pmd_t *pmd = pmd_ptr_k(k_cur); pte_t *ptep = pte_offset_kernel(pmd, k_cur); if ((pte_val(*ptep) & PTE_RPN_MASK) != pa) @@ -196,7 +196,7 @@ void __init kasan_early_init(void) unsigned long addr = KASAN_SHADOW_START; unsigned long end = KASAN_SHADOW_END; unsigned long next; - pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(addr), addr), addr); + pmd_t *pmd = pmd_ptr_k(addr); BUILD_BUG_ON(KASAN_SHADOW_START & ~PGDIR_MASK); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 1c07d5a3f543..041ed7cfd341 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -66,12 +66,6 @@ pte_t *kmap_pte; EXPORT_SYMBOL(kmap_pte); pgprot_t kmap_prot; EXPORT_SYMBOL(kmap_prot); - -static inline pte_t *virt_to_kpte(unsigned long vaddr) -{ - return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), - vaddr), vaddr), vaddr); -} #endif pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, @@ -96,7 +90,8 @@ int memory_add_physaddr_to_nid(u64 start) } #endif -int __weak create_section_mapping(unsigned long start, unsigned long end, int nid) +int __weak create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot) { return -ENODEV; } @@ -128,7 +123,7 @@ static void flush_dcache_range_chunked(unsigned long start, unsigned long stop, } int __ref arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -137,14 +132,15 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, resize_hpt_for_hotplug(memblock_phys_mem_size()); start = (unsigned long)__va(start); - rc = create_section_mapping(start, start + size, nid); + rc = create_section_mapping(start, start + size, nid, + params->pgprot); if (rc) { pr_warn("Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n", start, start + size, rc); return -EFAULT; } - return __add_pages(nid, start_pfn, nr_pages, restrictions); + return __add_pages(nid, start_pfn, nr_pages, params); } void __ref arch_remove_memory(int nid, u64 start, u64 size, diff --git a/arch/powerpc/mm/nohash/40x.c b/arch/powerpc/mm/nohash/40x.c index f348104eb461..82862723ab42 100644 --- a/arch/powerpc/mm/nohash/40x.c +++ b/arch/powerpc/mm/nohash/40x.c @@ -104,7 +104,7 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top) pmd_t *pmdp; unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE; - pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); + pmdp = pmd_ptr_k(v); *pmdp++ = __pmd(val); *pmdp++ = __pmd(val); *pmdp++ = __pmd(val); @@ -119,7 +119,7 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top) pmd_t *pmdp; unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE; - pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); + pmdp = pmd_ptr_k(v); *pmdp = __pmd(val); v += LARGE_PAGE_SIZE_4M; diff --git a/arch/powerpc/mm/nohash/tlb_low.S b/arch/powerpc/mm/nohash/tlb_low.S index 2ca407cedbe7..eaeee402f96e 100644 --- a/arch/powerpc/mm/nohash/tlb_low.S +++ b/arch/powerpc/mm/nohash/tlb_low.S @@ -397,7 +397,7 @@ _GLOBAL(set_context) * extern void loadcam_entry(unsigned int index) * * Load TLBCAM[index] entry in to the L2 CAM MMU - * Must preserve r7, r8, r9, and r10 + * Must preserve r7, r8, r9, r10 and r11 */ _GLOBAL(loadcam_entry) mflr r5 @@ -433,6 +433,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) */ _GLOBAL(loadcam_multi) mflr r8 + /* Don't switch to AS=1 if already there */ + mfmsr r11 + andi. r11,r11,MSR_IS + bne 10f /* * Set up temporary TLB entry that is the same as what we're @@ -458,6 +462,7 @@ _GLOBAL(loadcam_multi) mtmsr r6 isync +10: mr r9,r3 add r10,r3,r4 2: bl loadcam_entry @@ -466,6 +471,10 @@ _GLOBAL(loadcam_multi) mr r3,r9 blt 2b + /* Don't return to AS=0 if we were in AS=1 at function start */ + andi. r11,r11,MSR_IS + bne 3f + /* Return to AS=0 and clear the temporary entry */ mfmsr r6 rlwinm. r6,r6,0,~(MSR_IS|MSR_DS) @@ -481,6 +490,7 @@ _GLOBAL(loadcam_multi) tlbwe isync +3: mtlr r8 blr #endif diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 3c7dec70cda0..9fcf2d195830 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -461,25 +461,69 @@ static int of_drconf_to_nid_single(struct drmem_lmb *lmb) return nid; } +#ifdef CONFIG_PPC_SPLPAR +static int vphn_get_nid(long lcpu) +{ + __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0}; + long rc, hwid; + + /* + * On a shared lpar, device tree will not have node associativity. + * At this time lppaca, or its __old_status field may not be + * updated. Hence kernel cannot detect if its on a shared lpar. So + * request an explicit associativity irrespective of whether the + * lpar is shared or dedicated. Use the device tree property as a + * fallback. cpu_to_phys_id is only valid between + * smp_setup_cpu_maps() and smp_setup_pacas(). + */ + if (firmware_has_feature(FW_FEATURE_VPHN)) { + if (cpu_to_phys_id) + hwid = cpu_to_phys_id[lcpu]; + else + hwid = get_hard_smp_processor_id(lcpu); + + rc = hcall_vphn(hwid, VPHN_FLAG_VCPU, associativity); + if (rc == H_SUCCESS) + return associativity_to_nid(associativity); + } + + return NUMA_NO_NODE; +} +#else +static int vphn_get_nid(long unused) +{ + return NUMA_NO_NODE; +} +#endif /* CONFIG_PPC_SPLPAR */ + /* * Figure out to which domain a cpu belongs and stick it there. * Return the id of the domain used. */ static int numa_setup_cpu(unsigned long lcpu) { - int nid = NUMA_NO_NODE; struct device_node *cpu; + int fcpu = cpu_first_thread_sibling(lcpu); + int nid = NUMA_NO_NODE; /* * If a valid cpu-to-node mapping is already available, use it * directly instead of querying the firmware, since it represents * the most recent mapping notified to us by the platform (eg: VPHN). + * Since cpu_to_node binding remains the same for all threads in the + * core. If a valid cpu-to-node mapping is already available, for + * the first thread in the core, use it. */ - if ((nid = numa_cpu_lookup_table[lcpu]) >= 0) { + nid = numa_cpu_lookup_table[fcpu]; + if (nid >= 0) { map_cpu_to_node(lcpu, nid); return nid; } + nid = vphn_get_nid(lcpu); + if (nid != NUMA_NO_NODE) + goto out_present; + cpu = of_get_cpu_node(lcpu, NULL); if (!cpu) { @@ -491,13 +535,26 @@ static int numa_setup_cpu(unsigned long lcpu) } nid = of_node_to_nid_single(cpu); + of_node_put(cpu); out_present: if (nid < 0 || !node_possible(nid)) nid = first_online_node; + /* + * Update for the first thread of the core. All threads of a core + * have to be part of the same node. This not only avoids querying + * for every other thread in the core, but always avoids a case + * where virtual node associativity change causes subsequent threads + * of a core to be associated with different nid. However if first + * thread is already online, expect it to have a valid mapping. + */ + if (fcpu != lcpu) { + WARN_ON(cpu_online(fcpu)); + map_cpu_to_node(fcpu, nid); + } + map_cpu_to_node(lcpu, nid); - of_node_put(cpu); out: return nid; } @@ -1191,23 +1248,30 @@ static long vphn_get_associativity(unsigned long cpu, VPHN_FLAG_VCPU, associativity); switch (rc) { + case H_SUCCESS: + dbg("VPHN hcall succeeded. Reset polling...\n"); + timed_topology_update(0); + goto out; + case H_FUNCTION: - printk_once(KERN_INFO - "VPHN is not supported. Disabling polling...\n"); - stop_topology_update(); + pr_err_ratelimited("VPHN unsupported. Disabling polling...\n"); break; case H_HARDWARE: - printk(KERN_ERR - "hcall_vphn() experienced a hardware fault " + pr_err_ratelimited("hcall_vphn() experienced a hardware fault " "preventing VPHN. Disabling polling...\n"); - stop_topology_update(); break; - case H_SUCCESS: - dbg("VPHN hcall succeeded. Reset polling...\n"); - timed_topology_update(0); + case H_PARAMETER: + pr_err_ratelimited("hcall_vphn() was passed an invalid parameter. " + "Disabling polling...\n"); + break; + default: + pr_err_ratelimited("hcall_vphn() returned %ld. Disabling polling...\n" + , rc); break; } + stop_topology_update(); +out: return rc; } @@ -1568,15 +1632,6 @@ int prrn_is_enabled(void) return prrn_enabled; } -void __init shared_proc_topology_init(void) -{ - if (lppaca_shared_proc(get_lppaca())) { - bitmap_fill(cpumask_bits(&cpu_associativity_changes_mask), - nr_cpumask_bits); - numa_update_cpu_topology(false); - } -} - static int topology_read(struct seq_file *file, void *v) { if (vphn_enabled || prrn_enabled) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 5fb90edd865e..f62de06e3d07 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -63,7 +63,7 @@ int __ref map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot) int err = -ENOMEM; /* Use upper 10 bits of VA to index the first level map */ - pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va); + pd = pmd_ptr_k(va); /* Use middle 10 bits of VA to index the second-level map */ if (likely(slab_is_available())) pg = pte_alloc_kernel(pd, va); @@ -121,44 +121,9 @@ void __init mapin_ram(void) } } -/* Scan the real Linux page tables and return a PTE pointer for - * a virtual address in a context. - * Returns true (1) if PTE was found, zero otherwise. The pointer to - * the PTE pointer is unmodified if PTE is not found. - */ -static int -get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - int retval = 0; - - pgd = pgd_offset(mm, addr & PAGE_MASK); - if (pgd) { - pud = pud_offset(pgd, addr & PAGE_MASK); - if (pud && pud_present(*pud)) { - pmd = pmd_offset(pud, addr & PAGE_MASK); - if (pmd_present(*pmd)) { - pte = pte_offset_map(pmd, addr & PAGE_MASK); - if (pte) { - retval = 1; - *ptep = pte; - if (pmdp) - *pmdp = pmd; - /* XXX caller needs to do pte_unmap, yuck */ - } - } - } - } - return(retval); -} - static int __change_page_attr_noflush(struct page *page, pgprot_t prot) { pte_t *kpte; - pmd_t *kpmd; unsigned long address; BUG_ON(PageHighMem(page)); @@ -166,10 +131,10 @@ static int __change_page_attr_noflush(struct page *page, pgprot_t prot) if (v_block_mapped(address)) return 0; - if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) + kpte = virt_to_kpte(address); + if (!kpte) return -EINVAL; __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); - pte_unmap(kpte); return 0; } diff --git a/arch/powerpc/mm/ptdump/bats.c b/arch/powerpc/mm/ptdump/bats.c index 4154feac1da3..d3a5d6b318d1 100644 --- a/arch/powerpc/mm/ptdump/bats.c +++ b/arch/powerpc/mm/ptdump/bats.c @@ -164,10 +164,8 @@ static const struct file_operations bats_fops = { static int __init bats_init(void) { - struct dentry *debugfs_file; - - debugfs_file = debugfs_create_file("block_address_translation", 0400, - powerpc_debugfs_root, NULL, &bats_fops); - return debugfs_file ? 0 : -ENOMEM; + debugfs_create_file("block_address_translation", 0400, + powerpc_debugfs_root, NULL, &bats_fops); + return 0; } device_initcall(bats_init); diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c index a07278027c6f..b6ed9578382f 100644 --- a/arch/powerpc/mm/ptdump/hashpagetable.c +++ b/arch/powerpc/mm/ptdump/hashpagetable.c @@ -527,13 +527,10 @@ static const struct file_operations ptdump_fops = { static int ptdump_init(void) { - struct dentry *debugfs_file; - if (!radix_enabled()) { populate_markers(); - debugfs_file = debugfs_create_file("kernel_hash_pagetable", - 0400, NULL, NULL, &ptdump_fops); - return debugfs_file ? 0 : -ENOMEM; + debugfs_create_file("kernel_hash_pagetable", 0400, NULL, NULL, + &ptdump_fops); } return 0; } diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c index 206156255247..d92bb8ea229c 100644 --- a/arch/powerpc/mm/ptdump/ptdump.c +++ b/arch/powerpc/mm/ptdump/ptdump.c @@ -417,12 +417,10 @@ void ptdump_check_wx(void) static int ptdump_init(void) { - struct dentry *debugfs_file; - populate_markers(); build_pgtable_complete_mask(); - debugfs_file = debugfs_create_file("kernel_page_tables", 0400, NULL, - NULL, &ptdump_fops); - return debugfs_file ? 0 : -ENOMEM; + debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, + &ptdump_fops); + return 0; } device_initcall(ptdump_init); diff --git a/arch/powerpc/mm/ptdump/segment_regs.c b/arch/powerpc/mm/ptdump/segment_regs.c index 501843664bb9..dde2fe8de4b2 100644 --- a/arch/powerpc/mm/ptdump/segment_regs.c +++ b/arch/powerpc/mm/ptdump/segment_regs.c @@ -55,10 +55,8 @@ static const struct file_operations sr_fops = { static int __init sr_init(void) { - struct dentry *debugfs_file; - - debugfs_file = debugfs_create_file("segment_registers", 0400, - powerpc_debugfs_root, NULL, &sr_fops); - return debugfs_file ? 0 : -ENOMEM; + debugfs_create_file("segment_registers", 0400, powerpc_debugfs_root, + NULL, &sr_fops); + return 0; } device_initcall(sr_init); diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index c155dcbb8691..53d614e98537 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o +obj-$(CONFIG_PERF_EVENTS) += callchain.o callchain_$(BITS).o perf_regs.o +ifdef CONFIG_COMPAT +obj-$(CONFIG_PERF_EVENTS) += callchain_32.o +endif obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o obj64-$(CONFIG_PPC_PERF_CTRS) += ppc970-pmu.o power5-pmu.o \ diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c index cbc251981209..dd5051015008 100644 --- a/arch/powerpc/perf/callchain.c +++ b/arch/powerpc/perf/callchain.c @@ -15,11 +15,9 @@ #include <asm/sigcontext.h> #include <asm/ucontext.h> #include <asm/vdso.h> -#ifdef CONFIG_PPC64 -#include "../kernel/ppc32.h" -#endif #include <asm/pte-walk.h> +#include "callchain.h" /* * Is sp valid as the address of the next kernel stack frame after prev_sp? @@ -102,358 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re } } -#ifdef CONFIG_PPC64 -/* - * On 64-bit we don't want to invoke hash_page on user addresses from - * interrupt context, so if the access faults, we read the page tables - * to find which page (if any) is mapped and access it directly. - */ -static int read_user_stack_slow(void __user *ptr, void *buf, int nb) -{ - int ret = -EFAULT; - pgd_t *pgdir; - pte_t *ptep, pte; - unsigned shift; - unsigned long addr = (unsigned long) ptr; - unsigned long offset; - unsigned long pfn, flags; - void *kaddr; - - pgdir = current->mm->pgd; - if (!pgdir) - return -EFAULT; - - local_irq_save(flags); - ptep = find_current_mm_pte(pgdir, addr, NULL, &shift); - if (!ptep) - goto err_out; - if (!shift) - shift = PAGE_SHIFT; - - /* align address to page boundary */ - offset = addr & ((1UL << shift) - 1); - - pte = READ_ONCE(*ptep); - if (!pte_present(pte) || !pte_user(pte)) - goto err_out; - pfn = pte_pfn(pte); - if (!page_is_ram(pfn)) - goto err_out; - - /* no highmem to worry about here */ - kaddr = pfn_to_kaddr(pfn); - memcpy(buf, kaddr + offset, nb); - ret = 0; -err_out: - local_irq_restore(flags); - return ret; -} - -static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) -{ - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) || - ((unsigned long)ptr & 7)) - return -EFAULT; - - if (!probe_user_read(ret, ptr, sizeof(*ret))) - return 0; - - return read_user_stack_slow(ptr, ret, 8); -} - -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) -{ - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || - ((unsigned long)ptr & 3)) - return -EFAULT; - - if (!probe_user_read(ret, ptr, sizeof(*ret))) - return 0; - - return read_user_stack_slow(ptr, ret, 4); -} - -static inline int valid_user_sp(unsigned long sp, int is_64) -{ - if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32) - return 0; - return 1; -} - -/* - * 64-bit user processes use the same stack frame for RT and non-RT signals. - */ -struct signal_frame_64 { - char dummy[__SIGNAL_FRAMESIZE]; - struct ucontext uc; - unsigned long unused[2]; - unsigned int tramp[6]; - struct siginfo *pinfo; - void *puc; - struct siginfo info; - char abigap[288]; -}; - -static int is_sigreturn_64_address(unsigned long nip, unsigned long fp) -{ - if (nip == fp + offsetof(struct signal_frame_64, tramp)) - return 1; - if (vdso64_rt_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso64_rt_sigtramp) - return 1; - return 0; -} - -/* - * Do some sanity checking on the signal frame pointed to by sp. - * We check the pinfo and puc pointers in the frame. - */ -static int sane_signal_64_frame(unsigned long sp) -{ - struct signal_frame_64 __user *sf; - unsigned long pinfo, puc; - - sf = (struct signal_frame_64 __user *) sp; - if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) || - read_user_stack_64((unsigned long __user *) &sf->puc, &puc)) - return 0; - return pinfo == (unsigned long) &sf->info && - puc == (unsigned long) &sf->uc; -} - -static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) -{ - unsigned long sp, next_sp; - unsigned long next_ip; - unsigned long lr; - long level = 0; - struct signal_frame_64 __user *sigframe; - unsigned long __user *fp, *uregs; - - next_ip = perf_instruction_pointer(regs); - lr = regs->link; - sp = regs->gpr[1]; - perf_callchain_store(entry, next_ip); - - while (entry->nr < entry->max_stack) { - fp = (unsigned long __user *) sp; - if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp)) - return; - if (level > 0 && read_user_stack_64(&fp[2], &next_ip)) - return; - - /* - * Note: the next_sp - sp >= signal frame size check - * is true when next_sp < sp, which can happen when - * transitioning from an alternate signal stack to the - * normal stack. - */ - if (next_sp - sp >= sizeof(struct signal_frame_64) && - (is_sigreturn_64_address(next_ip, sp) || - (level <= 1 && is_sigreturn_64_address(lr, sp))) && - sane_signal_64_frame(sp)) { - /* - * This looks like an signal frame - */ - sigframe = (struct signal_frame_64 __user *) sp; - uregs = sigframe->uc.uc_mcontext.gp_regs; - if (read_user_stack_64(&uregs[PT_NIP], &next_ip) || - read_user_stack_64(&uregs[PT_LNK], &lr) || - read_user_stack_64(&uregs[PT_R1], &sp)) - return; - level = 0; - perf_callchain_store_context(entry, PERF_CONTEXT_USER); - perf_callchain_store(entry, next_ip); - continue; - } - - if (level == 0) - next_ip = lr; - perf_callchain_store(entry, next_ip); - ++level; - sp = next_sp; - } -} - -#else /* CONFIG_PPC64 */ -/* - * On 32-bit we just access the address and let hash_page create a - * HPTE if necessary, so there is no need to fall back to reading - * the page tables. Since this is called at interrupt level, - * do_page_fault() won't treat a DSI as a page fault. - */ -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) -{ - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || - ((unsigned long)ptr & 3)) - return -EFAULT; - - return probe_user_read(ret, ptr, sizeof(*ret)); -} - -static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) -{ -} - -static inline int valid_user_sp(unsigned long sp, int is_64) -{ - if (!sp || (sp & 7) || sp > TASK_SIZE - 32) - return 0; - return 1; -} - -#define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE -#define sigcontext32 sigcontext -#define mcontext32 mcontext -#define ucontext32 ucontext -#define compat_siginfo_t struct siginfo - -#endif /* CONFIG_PPC64 */ - -/* - * Layout for non-RT signal frames - */ -struct signal_frame_32 { - char dummy[__SIGNAL_FRAMESIZE32]; - struct sigcontext32 sctx; - struct mcontext32 mctx; - int abigap[56]; -}; - -/* - * Layout for RT signal frames - */ -struct rt_signal_frame_32 { - char dummy[__SIGNAL_FRAMESIZE32 + 16]; - compat_siginfo_t info; - struct ucontext32 uc; - int abigap[56]; -}; - -static int is_sigreturn_32_address(unsigned int nip, unsigned int fp) -{ - if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad)) - return 1; - if (vdso32_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso32_sigtramp) - return 1; - return 0; -} - -static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp) -{ - if (nip == fp + offsetof(struct rt_signal_frame_32, - uc.uc_mcontext.mc_pad)) - return 1; - if (vdso32_rt_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso32_rt_sigtramp) - return 1; - return 0; -} - -static int sane_signal_32_frame(unsigned int sp) -{ - struct signal_frame_32 __user *sf; - unsigned int regs; - - sf = (struct signal_frame_32 __user *) (unsigned long) sp; - if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, ®s)) - return 0; - return regs == (unsigned long) &sf->mctx; -} - -static int sane_rt_signal_32_frame(unsigned int sp) -{ - struct rt_signal_frame_32 __user *sf; - unsigned int regs; - - sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; - if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, ®s)) - return 0; - return regs == (unsigned long) &sf->uc.uc_mcontext; -} - -static unsigned int __user *signal_frame_32_regs(unsigned int sp, - unsigned int next_sp, unsigned int next_ip) -{ - struct mcontext32 __user *mctx = NULL; - struct signal_frame_32 __user *sf; - struct rt_signal_frame_32 __user *rt_sf; - - /* - * Note: the next_sp - sp >= signal frame size check - * is true when next_sp < sp, for example, when - * transitioning from an alternate signal stack to the - * normal stack. - */ - if (next_sp - sp >= sizeof(struct signal_frame_32) && - is_sigreturn_32_address(next_ip, sp) && - sane_signal_32_frame(sp)) { - sf = (struct signal_frame_32 __user *) (unsigned long) sp; - mctx = &sf->mctx; - } - - if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) && - is_rt_sigreturn_32_address(next_ip, sp) && - sane_rt_signal_32_frame(sp)) { - rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; - mctx = &rt_sf->uc.uc_mcontext; - } - - if (!mctx) - return NULL; - return mctx->mc_gregs; -} - -static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) -{ - unsigned int sp, next_sp; - unsigned int next_ip; - unsigned int lr; - long level = 0; - unsigned int __user *fp, *uregs; - - next_ip = perf_instruction_pointer(regs); - lr = regs->link; - sp = regs->gpr[1]; - perf_callchain_store(entry, next_ip); - - while (entry->nr < entry->max_stack) { - fp = (unsigned int __user *) (unsigned long) sp; - if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp)) - return; - if (level > 0 && read_user_stack_32(&fp[1], &next_ip)) - return; - - uregs = signal_frame_32_regs(sp, next_sp, next_ip); - if (!uregs && level <= 1) - uregs = signal_frame_32_regs(sp, next_sp, lr); - if (uregs) { - /* - * This looks like an signal frame, so restart - * the stack trace with the values in it. - */ - if (read_user_stack_32(&uregs[PT_NIP], &next_ip) || - read_user_stack_32(&uregs[PT_LNK], &lr) || - read_user_stack_32(&uregs[PT_R1], &sp)) - return; - level = 0; - perf_callchain_store_context(entry, PERF_CONTEXT_USER); - perf_callchain_store(entry, next_ip); - continue; - } - - if (level == 0) - next_ip = lr; - perf_callchain_store(entry, next_ip); - ++level; - sp = next_sp; - } -} - void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { diff --git a/arch/powerpc/perf/callchain.h b/arch/powerpc/perf/callchain.h new file mode 100644 index 000000000000..7a2cb9e1181a --- /dev/null +++ b/arch/powerpc/perf/callchain.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _POWERPC_PERF_CALLCHAIN_H +#define _POWERPC_PERF_CALLCHAIN_H + +int read_user_stack_slow(void __user *ptr, void *buf, int nb); +void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs); +void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs); + +static inline bool invalid_user_sp(unsigned long sp) +{ + unsigned long mask = is_32bit_task() ? 3 : 7; + unsigned long top = STACK_TOP - (is_32bit_task() ? 16 : 32); + + return (!sp || (sp & mask) || (sp > top)); +} + +#endif /* _POWERPC_PERF_CALLCHAIN_H */ diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c new file mode 100644 index 000000000000..8aa951003141 --- /dev/null +++ b/arch/powerpc/perf/callchain_32.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Performance counter callchain support - powerpc architecture code + * + * Copyright © 2009 Paul Mackerras, IBM Corporation. + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/perf_event.h> +#include <linux/percpu.h> +#include <linux/uaccess.h> +#include <linux/mm.h> +#include <asm/ptrace.h> +#include <asm/pgtable.h> +#include <asm/sigcontext.h> +#include <asm/ucontext.h> +#include <asm/vdso.h> +#include <asm/pte-walk.h> + +#include "callchain.h" + +#ifdef CONFIG_PPC64 +#include "../kernel/ppc32.h" +#else /* CONFIG_PPC64 */ + +#define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE +#define sigcontext32 sigcontext +#define mcontext32 mcontext +#define ucontext32 ucontext +#define compat_siginfo_t struct siginfo + +#endif /* CONFIG_PPC64 */ + +/* + * On 32-bit we just access the address and let hash_page create a + * HPTE if necessary, so there is no need to fall back to reading + * the page tables. Since this is called at interrupt level, + * do_page_fault() won't treat a DSI as a page fault. + */ +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) +{ + int rc; + + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || + ((unsigned long)ptr & 3)) + return -EFAULT; + + rc = probe_user_read(ret, ptr, sizeof(*ret)); + + if (IS_ENABLED(CONFIG_PPC64) && rc) + return read_user_stack_slow(ptr, ret, 4); + + return rc; +} + +/* + * Layout for non-RT signal frames + */ +struct signal_frame_32 { + char dummy[__SIGNAL_FRAMESIZE32]; + struct sigcontext32 sctx; + struct mcontext32 mctx; + int abigap[56]; +}; + +/* + * Layout for RT signal frames + */ +struct rt_signal_frame_32 { + char dummy[__SIGNAL_FRAMESIZE32 + 16]; + compat_siginfo_t info; + struct ucontext32 uc; + int abigap[56]; +}; + +static int is_sigreturn_32_address(unsigned int nip, unsigned int fp) +{ + if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad)) + return 1; + if (vdso32_sigtramp && current->mm->context.vdso_base && + nip == current->mm->context.vdso_base + vdso32_sigtramp) + return 1; + return 0; +} + +static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp) +{ + if (nip == fp + offsetof(struct rt_signal_frame_32, + uc.uc_mcontext.mc_pad)) + return 1; + if (vdso32_rt_sigtramp && current->mm->context.vdso_base && + nip == current->mm->context.vdso_base + vdso32_rt_sigtramp) + return 1; + return 0; +} + +static int sane_signal_32_frame(unsigned int sp) +{ + struct signal_frame_32 __user *sf; + unsigned int regs; + + sf = (struct signal_frame_32 __user *) (unsigned long) sp; + if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, ®s)) + return 0; + return regs == (unsigned long) &sf->mctx; +} + +static int sane_rt_signal_32_frame(unsigned int sp) +{ + struct rt_signal_frame_32 __user *sf; + unsigned int regs; + + sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; + if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, ®s)) + return 0; + return regs == (unsigned long) &sf->uc.uc_mcontext; +} + +static unsigned int __user *signal_frame_32_regs(unsigned int sp, + unsigned int next_sp, unsigned int next_ip) +{ + struct mcontext32 __user *mctx = NULL; + struct signal_frame_32 __user *sf; + struct rt_signal_frame_32 __user *rt_sf; + + /* + * Note: the next_sp - sp >= signal frame size check + * is true when next_sp < sp, for example, when + * transitioning from an alternate signal stack to the + * normal stack. + */ + if (next_sp - sp >= sizeof(struct signal_frame_32) && + is_sigreturn_32_address(next_ip, sp) && + sane_signal_32_frame(sp)) { + sf = (struct signal_frame_32 __user *) (unsigned long) sp; + mctx = &sf->mctx; + } + + if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) && + is_rt_sigreturn_32_address(next_ip, sp) && + sane_rt_signal_32_frame(sp)) { + rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; + mctx = &rt_sf->uc.uc_mcontext; + } + + if (!mctx) + return NULL; + return mctx->mc_gregs; +} + +void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) +{ + unsigned int sp, next_sp; + unsigned int next_ip; + unsigned int lr; + long level = 0; + unsigned int __user *fp, *uregs; + + next_ip = perf_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; + perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned int __user *) (unsigned long) sp; + if (invalid_user_sp(sp) || read_user_stack_32(fp, &next_sp)) + return; + if (level > 0 && read_user_stack_32(&fp[1], &next_ip)) + return; + + uregs = signal_frame_32_regs(sp, next_sp, next_ip); + if (!uregs && level <= 1) + uregs = signal_frame_32_regs(sp, next_sp, lr); + if (uregs) { + /* + * This looks like an signal frame, so restart + * the stack trace with the values in it. + */ + if (read_user_stack_32(&uregs[PT_NIP], &next_ip) || + read_user_stack_32(&uregs[PT_LNK], &lr) || + read_user_stack_32(&uregs[PT_R1], &sp)) + return; + level = 0; + perf_callchain_store_context(entry, PERF_CONTEXT_USER); + perf_callchain_store(entry, next_ip); + continue; + } + + if (level == 0) + next_ip = lr; + perf_callchain_store(entry, next_ip); + ++level; + sp = next_sp; + } +} diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c new file mode 100644 index 000000000000..df1ffd8b20f2 --- /dev/null +++ b/arch/powerpc/perf/callchain_64.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Performance counter callchain support - powerpc architecture code + * + * Copyright © 2009 Paul Mackerras, IBM Corporation. + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/perf_event.h> +#include <linux/percpu.h> +#include <linux/uaccess.h> +#include <linux/mm.h> +#include <asm/ptrace.h> +#include <asm/pgtable.h> +#include <asm/sigcontext.h> +#include <asm/ucontext.h> +#include <asm/vdso.h> +#include <asm/pte-walk.h> + +#include "callchain.h" + +/* + * On 64-bit we don't want to invoke hash_page on user addresses from + * interrupt context, so if the access faults, we read the page tables + * to find which page (if any) is mapped and access it directly. + */ +int read_user_stack_slow(void __user *ptr, void *buf, int nb) +{ + int ret = -EFAULT; + pgd_t *pgdir; + pte_t *ptep, pte; + unsigned int shift; + unsigned long addr = (unsigned long) ptr; + unsigned long offset; + unsigned long pfn, flags; + void *kaddr; + + pgdir = current->mm->pgd; + if (!pgdir) + return -EFAULT; + + local_irq_save(flags); + ptep = find_current_mm_pte(pgdir, addr, NULL, &shift); + if (!ptep) + goto err_out; + if (!shift) + shift = PAGE_SHIFT; + + /* align address to page boundary */ + offset = addr & ((1UL << shift) - 1); + + pte = READ_ONCE(*ptep); + if (!pte_present(pte) || !pte_user(pte)) + goto err_out; + pfn = pte_pfn(pte); + if (!page_is_ram(pfn)) + goto err_out; + + /* no highmem to worry about here */ + kaddr = pfn_to_kaddr(pfn); + memcpy(buf, kaddr + offset, nb); + ret = 0; +err_out: + local_irq_restore(flags); + return ret; +} + +static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) +{ + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) || + ((unsigned long)ptr & 7)) + return -EFAULT; + + if (!probe_user_read(ret, ptr, sizeof(*ret))) + return 0; + + return read_user_stack_slow(ptr, ret, 8); +} + +/* + * 64-bit user processes use the same stack frame for RT and non-RT signals. + */ +struct signal_frame_64 { + char dummy[__SIGNAL_FRAMESIZE]; + struct ucontext uc; + unsigned long unused[2]; + unsigned int tramp[6]; + struct siginfo *pinfo; + void *puc; + struct siginfo info; + char abigap[288]; +}; + +static int is_sigreturn_64_address(unsigned long nip, unsigned long fp) +{ + if (nip == fp + offsetof(struct signal_frame_64, tramp)) + return 1; + if (vdso64_rt_sigtramp && current->mm->context.vdso_base && + nip == current->mm->context.vdso_base + vdso64_rt_sigtramp) + return 1; + return 0; +} + +/* + * Do some sanity checking on the signal frame pointed to by sp. + * We check the pinfo and puc pointers in the frame. + */ +static int sane_signal_64_frame(unsigned long sp) +{ + struct signal_frame_64 __user *sf; + unsigned long pinfo, puc; + + sf = (struct signal_frame_64 __user *) sp; + if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) || + read_user_stack_64((unsigned long __user *) &sf->puc, &puc)) + return 0; + return pinfo == (unsigned long) &sf->info && + puc == (unsigned long) &sf->uc; +} + +void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) +{ + unsigned long sp, next_sp; + unsigned long next_ip; + unsigned long lr; + long level = 0; + struct signal_frame_64 __user *sigframe; + unsigned long __user *fp, *uregs; + + next_ip = perf_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; + perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned long __user *) sp; + if (invalid_user_sp(sp) || read_user_stack_64(fp, &next_sp)) + return; + if (level > 0 && read_user_stack_64(&fp[2], &next_ip)) + return; + + /* + * Note: the next_sp - sp >= signal frame size check + * is true when next_sp < sp, which can happen when + * transitioning from an alternate signal stack to the + * normal stack. + */ + if (next_sp - sp >= sizeof(struct signal_frame_64) && + (is_sigreturn_64_address(next_ip, sp) || + (level <= 1 && is_sigreturn_64_address(lr, sp))) && + sane_signal_64_frame(sp)) { + /* + * This looks like an signal frame + */ + sigframe = (struct signal_frame_64 __user *) sp; + uregs = sigframe->uc.uc_mcontext.gp_regs; + if (read_user_stack_64(&uregs[PT_NIP], &next_ip) || + read_user_stack_64(&uregs[PT_LNK], &lr) || + read_user_stack_64(&uregs[PT_R1], &sp)) + return; + level = 0; + perf_callchain_store_context(entry, PERF_CONTEXT_USER); + perf_callchain_store(entry, next_ip); + continue; + } + + if (level == 0) + next_ip = lr; + perf_callchain_store(entry, next_ip); + ++level; + sp = next_sp; + } +} diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index cb50a9e1fd2d..eb82dda884e5 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -44,6 +44,16 @@ static DEFINE_PER_CPU(u64 *, trace_imc_mem); static struct imc_pmu_ref *trace_imc_refc; static int trace_imc_mem_size; +/* + * Global data structure used to avoid races between thread, + * core and trace-imc + */ +static struct imc_pmu_ref imc_global_refc = { + .lock = __MUTEX_INITIALIZER(imc_global_refc.lock), + .id = 0, + .refc = 0, +}; + static struct imc_pmu *imc_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct imc_pmu, pmu); @@ -698,6 +708,16 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu) return -EINVAL; ref->refc = 0; + /* + * Reduce the global reference count, if this is the + * last cpu in this core and core-imc event running + * in this cpu. + */ + mutex_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_CORE) + imc_global_refc.refc--; + + mutex_unlock(&imc_global_refc.lock); } return 0; } @@ -710,6 +730,23 @@ static int core_imc_pmu_cpumask_init(void) ppc_core_imc_cpu_offline); } +static void reset_global_refc(struct perf_event *event) +{ + mutex_lock(&imc_global_refc.lock); + imc_global_refc.refc--; + + /* + * If no other thread is running any + * event for this domain(thread/core/trace), + * set the global id to zero. + */ + if (imc_global_refc.refc <= 0) { + imc_global_refc.refc = 0; + imc_global_refc.id = 0; + } + mutex_unlock(&imc_global_refc.lock); +} + static void core_imc_counters_release(struct perf_event *event) { int rc, core_id; @@ -759,6 +796,8 @@ static void core_imc_counters_release(struct perf_event *event) ref->refc = 0; } mutex_unlock(&ref->lock); + + reset_global_refc(event); } static int core_imc_event_init(struct perf_event *event) @@ -819,6 +858,29 @@ static int core_imc_event_init(struct perf_event *event) ++ref->refc; mutex_unlock(&ref->lock); + /* + * Since the system can run either in accumulation or trace-mode + * of IMC at a time, core-imc events are allowed only if no other + * trace/thread imc events are enabled/monitored. + * + * Take the global lock, and check the refc.id + * to know whether any other trace/thread imc + * events are running. + */ + mutex_lock(&imc_global_refc.lock); + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_CORE) { + /* + * No other trace/thread imc events are running in + * the system, so set the refc.id to core-imc. + */ + imc_global_refc.id = IMC_DOMAIN_CORE; + imc_global_refc.refc++; + } else { + mutex_unlock(&imc_global_refc.lock); + return -EBUSY; + } + mutex_unlock(&imc_global_refc.lock); + event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK); event->destroy = core_imc_counters_release; return 0; @@ -877,7 +939,23 @@ static int ppc_thread_imc_cpu_online(unsigned int cpu) static int ppc_thread_imc_cpu_offline(unsigned int cpu) { - mtspr(SPRN_LDBAR, 0); + /* + * Set the bit 0 of LDBAR to zero. + * + * If bit 0 of LDBAR is unset, it will stop posting + * the counter data to memory. + * For thread-imc, bit 0 of LDBAR will be set to 1 in the + * event_add function. So reset this bit here, to stop the updates + * to memory in the cpu_offline path. + */ + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); + + /* Reduce the refc if thread-imc event running on this cpu */ + mutex_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_THREAD) + imc_global_refc.refc--; + mutex_unlock(&imc_global_refc.lock); + return 0; } @@ -916,7 +994,22 @@ static int thread_imc_event_init(struct perf_event *event) if (!target) return -EINVAL; + mutex_lock(&imc_global_refc.lock); + /* + * Check if any other trace/core imc events are running in the + * system, if not set the global id to thread-imc. + */ + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_THREAD) { + imc_global_refc.id = IMC_DOMAIN_THREAD; + imc_global_refc.refc++; + } else { + mutex_unlock(&imc_global_refc.lock); + return -EBUSY; + } + mutex_unlock(&imc_global_refc.lock); + event->pmu->task_ctx_nr = perf_sw_context; + event->destroy = reset_global_refc; return 0; } @@ -1063,10 +1156,12 @@ static void thread_imc_event_del(struct perf_event *event, int flags) int core_id; struct imc_pmu_ref *ref; - mtspr(SPRN_LDBAR, 0); - core_id = smp_processor_id() / threads_per_core; ref = &core_imc_refc[core_id]; + if (!ref) { + pr_debug("imc: Failed to get event reference count\n"); + return; + } mutex_lock(&ref->lock); ref->refc--; @@ -1082,6 +1177,10 @@ static void thread_imc_event_del(struct perf_event *event, int flags) ref->refc = 0; } mutex_unlock(&ref->lock); + + /* Set bit 0 of LDBAR to zero, to stop posting updates to memory */ + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); + /* * Take a snapshot and calculate the delta and update * the event counter values. @@ -1133,7 +1232,18 @@ static int ppc_trace_imc_cpu_online(unsigned int cpu) static int ppc_trace_imc_cpu_offline(unsigned int cpu) { - mtspr(SPRN_LDBAR, 0); + /* + * No need to set bit 0 of LDBAR to zero, as + * it is set to zero for imc trace-mode + * + * Reduce the refc if any trace-imc event running + * on this cpu. + */ + mutex_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_TRACE) + imc_global_refc.refc--; + mutex_unlock(&imc_global_refc.lock); + return 0; } @@ -1226,15 +1336,14 @@ static int trace_imc_event_add(struct perf_event *event, int flags) local_mem = get_trace_imc_event_base_addr(); ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | TRACE_IMC_ENABLE; - if (core_imc_refc) - ref = &core_imc_refc[core_id]; + /* trace-imc reference count */ + if (trace_imc_refc) + ref = &trace_imc_refc[core_id]; if (!ref) { - /* If core-imc is not enabled, use trace-imc reference count */ - if (trace_imc_refc) - ref = &trace_imc_refc[core_id]; - if (!ref) - return -EINVAL; + pr_debug("imc: Failed to get the event reference count\n"); + return -EINVAL; } + mtspr(SPRN_LDBAR, ldbar_value); mutex_lock(&ref->lock); if (ref->refc == 0) { @@ -1242,13 +1351,11 @@ static int trace_imc_event_add(struct perf_event *event, int flags) get_hard_smp_processor_id(smp_processor_id()))) { mutex_unlock(&ref->lock); pr_err("trace-imc: Unable to start the counters for core %d\n", core_id); - mtspr(SPRN_LDBAR, 0); return -EINVAL; } } ++ref->refc; mutex_unlock(&ref->lock); - return 0; } @@ -1274,16 +1381,13 @@ static void trace_imc_event_del(struct perf_event *event, int flags) int core_id = smp_processor_id() / threads_per_core; struct imc_pmu_ref *ref = NULL; - if (core_imc_refc) - ref = &core_imc_refc[core_id]; + if (trace_imc_refc) + ref = &trace_imc_refc[core_id]; if (!ref) { - /* If core-imc is not enabled, use trace-imc reference count */ - if (trace_imc_refc) - ref = &trace_imc_refc[core_id]; - if (!ref) - return; + pr_debug("imc: Failed to get event reference count\n"); + return; } - mtspr(SPRN_LDBAR, 0); + mutex_lock(&ref->lock); ref->refc--; if (ref->refc == 0) { @@ -1297,6 +1401,7 @@ static void trace_imc_event_del(struct perf_event *event, int flags) ref->refc = 0; } mutex_unlock(&ref->lock); + trace_imc_event_stop(event, flags); } @@ -1314,10 +1419,30 @@ static int trace_imc_event_init(struct perf_event *event) if (event->attr.sample_period == 0) return -ENOENT; + /* + * Take the global lock, and make sure + * no other thread is running any core/thread imc + * events + */ + mutex_lock(&imc_global_refc.lock); + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_TRACE) { + /* + * No core/thread imc events are running in the + * system, so set the refc.id to trace-imc. + */ + imc_global_refc.id = IMC_DOMAIN_TRACE; + imc_global_refc.refc++; + } else { + mutex_unlock(&imc_global_refc.lock); + return -EBUSY; + } + mutex_unlock(&imc_global_refc.lock); + event->hw.idx = -1; target = event->hw.target; event->pmu->task_ctx_nr = perf_hw_context; + event->destroy = reset_global_refc; return 0; } @@ -1429,10 +1554,10 @@ static void cleanup_all_core_imc_memory(void) static void thread_imc_ldbar_disable(void *dummy) { /* - * By Zeroing LDBAR, we disable thread-imc - * updates. + * By setting 0th bit of LDBAR to zero, we disable thread-imc + * updates to memory. */ - mtspr(SPRN_LDBAR, 0); + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); } void thread_imc_disable(void) diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index 6620b64e4963..665f18e37efb 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c @@ -43,9 +43,6 @@ static int __init warp_probe(void) if (!of_machine_is_compatible("pika,warp")) return 0; - /* For arch_dma_alloc */ - ISA_DMA_THRESHOLD = ~0L; - return 1; } diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 61538869e88a..4514a6f7458a 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -205,7 +205,6 @@ static int __init efika_probe(void) if (strcmp(model, "EFIKA5K2")) return 0; - ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index ada42f03915a..bcdc2c203ec9 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -53,17 +53,19 @@ static void quirk_mpc8360e_qe_enet10(void) np_par = of_find_node_by_name(NULL, "par_io"); if (np_par == NULL) { - pr_warn("%s couldn;t find par_io node\n", __func__); + pr_warn("%s couldn't find par_io node\n", __func__); return; } /* Map Parallel I/O ports registers */ ret = of_address_to_resource(np_par, 0, &res); if (ret) { - pr_warn("%s couldn;t map par_io registers\n", __func__); - return; + pr_warn("%s couldn't map par_io registers\n", __func__); + goto out; } base = ioremap(res.start, resource_size(&res)); + if (!base) + goto out; /* * set output delay adjustments to default values according @@ -111,6 +113,7 @@ static void quirk_mpc8360e_qe_enet10(void) setbits32((base + 0xac), 0x0000c000); } iounmap(base); +out: of_node_put(np_par); } diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 6b1436abe9b1..915ab6710b93 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -218,12 +218,6 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) { return IRQ_HANDLED; } - -static struct irqaction mpc85xxcds_8259_irqaction = { - .handler = mpc85xx_8259_cascade_action, - .flags = IRQF_SHARED | IRQF_NO_THREAD, - .name = "8259 cascade", -}; #endif /* PPC_I8259 */ #endif /* CONFIG_PCI */ @@ -271,7 +265,10 @@ static int mpc85xx_cds_8259_attach(void) * disabled when the last user of the shared IRQ line frees their * interrupt. */ - if ((ret = setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction))) { + ret = request_irq(cascade_irq, mpc85xx_8259_cascade_action, + IRQF_SHARED | IRQF_NO_THREAD, "8259 cascade", + cascade_node); + if (ret) { printk(KERN_ERR "Failed to setup cascade interrupt\n"); return ret; } diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c index a43ee7d1ff85..4db4ca2e1222 100644 --- a/arch/powerpc/platforms/8xx/cpm1.c +++ b/arch/powerpc/platforms/8xx/cpm1.c @@ -120,12 +120,6 @@ static irqreturn_t cpm_error_interrupt(int irq, void *dev) return IRQ_HANDLED; } -static struct irqaction cpm_error_irqaction = { - .handler = cpm_error_interrupt, - .flags = IRQF_NO_THREAD, - .name = "error", -}; - static const struct irq_domain_ops cpm_pic_host_ops = { .map = cpm_pic_host_map, }; @@ -187,7 +181,8 @@ unsigned int __init cpm_pic_init(void) if (!eirq) goto end; - if (setup_irq(eirq, &cpm_error_irqaction)) + if (request_irq(eirq, cpm_error_interrupt, IRQF_NO_THREAD, "error", + NULL)) printk(KERN_ERR "Could not allocate CPM error IRQ!"); setbits32(&cpic_reg->cpic_cicr, CICR_IEN); diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index f1c805c8adbc..df4d57d07f9a 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -39,12 +39,6 @@ static irqreturn_t timebase_interrupt(int irq, void *dev) return IRQ_HANDLED; } -static struct irqaction tbint_irqaction = { - .handler = timebase_interrupt, - .flags = IRQF_NO_THREAD, - .name = "tbint", -}; - /* per-board overridable init_internal_rtc() function. */ void __init __attribute__ ((weak)) init_internal_rtc(void) @@ -157,7 +151,8 @@ void __init mpc8xx_calibrate_decr(void) (TBSCR_TBF | TBSCR_TBE)); immr_unmap(sys_tmr2); - if (setup_irq(virq, &tbint_irqaction)) + if (request_irq(virq, timebase_interrupt, IRQF_NO_THREAD, "tbint", + NULL)) panic("Could not allocate timer IRQ!"); } diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 6caedc88474f..0c3c1902135c 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -397,7 +397,7 @@ config PPC_KUAP config PPC_KUAP_DEBUG bool "Extra debugging for Kernel Userspace Access Protection" - depends on PPC_HAVE_KUAP && (PPC_RADIX_MMU || PPC_32) + depends on PPC_KUAP && (PPC_RADIX_MMU || PPC_32) help Add extra debugging for Kernel Userspace Access Protection (KUAP) If you're unsure, say N. @@ -425,6 +425,12 @@ config PPC_MM_SLICES config PPC_HAVE_PMU_SUPPORT bool +config PMU_SYSFS + bool "Create PMU SPRs sysfs file" + default n + help + This option enables sysfs file creation for PMU SPRs like MMCR* and PMC*. + config PPC_PERF_CTRS def_bool y depends on PERF_EVENTS && PPC_HAVE_PMU_SUPPORT diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index ea5e45e32683..f5d0bf999759 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -146,7 +146,6 @@ static int __init amigaone_probe(void) */ cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT; - ISA_DMA_THRESHOLD = 0x00ffffff; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 57c4e0e86c88..ca2555b8a0c2 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -480,10 +480,6 @@ void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic) snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn)); - if (!debugfs_create_file(name, 0600, powerpc_debugfs_root, - msic, &fops_msic)) { - pr_devel("axon_msi: debugfs_create_file failed!\n"); - return; - } + debugfs_create_file(name, 0600, powerpc_debugfs_root, msic, &fops_msic); } #endif /* DEBUG */ diff --git a/arch/powerpc/platforms/cell/spufs/.gitignore b/arch/powerpc/platforms/cell/spufs/.gitignore index a09ee8d84d6c..5f3eb224f653 100644 --- a/arch/powerpc/platforms/cell/spufs/.gitignore +++ b/arch/powerpc/platforms/cell/spufs/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only spu_save_dump.h spu_restore_dump.h diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 5c3f5d088c3b..d56b4e3241cd 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -177,7 +177,7 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); - /* fall through */ + fallthrough; case MFC_CNTL_SUSPEND_COMPLETE: if (csa) csa->priv2.mfc_control_RW = diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index fcf6f2342ef4..65a7e01a8f7d 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -451,13 +451,6 @@ static void __init chrp_find_openpic(void) of_node_put(np); } -#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON) -static struct irqaction xmon_irqaction = { - .handler = xmon_irq, - .name = "XMON break", -}; -#endif - static void __init chrp_find_8259(void) { struct device_node *np, *pic = NULL; @@ -541,8 +534,11 @@ static void __init chrp_init_IRQ(void) if (of_node_is_type(kbd->parent, "adb")) break; of_node_put(kbd); - if (kbd) - setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction); + if (kbd) { + if (request_irq(HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", + NULL)) + pr_err("Failed to register XMON break interrupt\n"); + } #endif } @@ -573,7 +569,6 @@ static int __init chrp_probe(void) if (strcmp(dtype, "chrp")) return 0; - ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 6f019df37916..15b2c6eb506d 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -291,23 +291,6 @@ static int __init maple_probe(void) return 1; } -define_machine(maple) { - .name = "Maple", - .probe = maple_probe, - .setup_arch = maple_setup_arch, - .init_IRQ = maple_init_IRQ, - .pci_irq_fixup = maple_pci_irq_fixup, - .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, - .restart = maple_restart, - .halt = maple_halt, - .get_boot_time = maple_get_boot_time, - .set_rtc_time = maple_set_rtc_time, - .get_rtc_time = maple_get_rtc_time, - .calibrate_decr = generic_calibrate_decr, - .progress = maple_progress, - .power_save = power4_idle, -}; - #ifdef CONFIG_EDAC /* * Register a platform device for CPC925 memory controller on @@ -364,3 +347,20 @@ static int __init maple_cpc925_edac_setup(void) } machine_device_initcall(maple, maple_cpc925_edac_setup); #endif + +define_machine(maple) { + .name = "Maple", + .probe = maple_probe, + .setup_arch = maple_setup_arch, + .init_IRQ = maple_init_IRQ, + .pci_irq_fixup = maple_pci_irq_fixup, + .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, + .restart = maple_restart, + .halt = maple_halt, + .get_boot_time = maple_get_boot_time, + .set_rtc_time = maple_set_rtc_time, + .get_rtc_time = maple_get_rtc_time, + .calibrate_decr = generic_calibrate_decr, + .progress = maple_progress, + .power_save = power4_idle, +}; diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 2e969073473d..4921bccf0376 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -250,20 +250,6 @@ static unsigned int pmac_pic_get_irq(void) return irq_linear_revmap(pmac_pic_host, irq); } -#ifdef CONFIG_XMON -static struct irqaction xmon_action = { - .handler = xmon_irq, - .flags = IRQF_NO_THREAD, - .name = "NMI - XMON" -}; -#endif - -static struct irqaction gatwick_cascade_action = { - .handler = gatwick_action, - .flags = IRQF_NO_THREAD, - .name = "cascade", -}; - static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node, enum irq_domain_bus_token bus_token) { @@ -384,12 +370,17 @@ static void __init pmac_pic_probe_oldstyle(void) out_le32(&pmac_irq_hw[i]->enable, 0); /* Hookup cascade irq */ - if (slave && pmac_irq_cascade) - setup_irq(pmac_irq_cascade, &gatwick_cascade_action); + if (slave && pmac_irq_cascade) { + if (request_irq(pmac_irq_cascade, gatwick_action, + IRQF_NO_THREAD, "cascade", NULL)) + pr_err("Failed to register cascade interrupt\n"); + } printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); #ifdef CONFIG_XMON - setup_irq(irq_create_mapping(NULL, 20), &xmon_action); + i = irq_create_mapping(NULL, 20); + if (request_irq(i, xmon_irq, IRQF_NO_THREAD, "NMI - XMON", NULL)) + pr_err("Failed to register NMI-XMON interrupt\n"); #endif } @@ -441,7 +432,9 @@ static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) nmi_irq = irq_of_parse_and_map(pswitch, 0); if (nmi_irq) { mpic_irq_set_priority(nmi_irq, 9); - setup_irq(nmi_irq, &xmon_action); + if (request_irq(nmi_irq, xmon_irq, IRQF_NO_THREAD, + "NMI - XMON", NULL)) + pr_err("Failed to register NMI-XMON interrupt\n"); } of_node_put(pswitch); } diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index c6d5333729ed..95fb4feb6ccc 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -586,7 +586,6 @@ static int __init pmac_probe(void) #ifdef CONFIG_PPC32 /* isa_io_base gets set in pmac_pci_init */ - ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 1; DMA_MODE_WRITE = 2; #endif /* CONFIG_PPC32 */ diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index f95fbdee6efe..be2ab5b11e57 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -399,21 +399,19 @@ static int __init smp_psurge_kick_cpu(int nr) return 0; } -static struct irqaction psurge_irqaction = { - .handler = psurge_ipi_intr, - .flags = IRQF_PERCPU | IRQF_NO_THREAD, - .name = "primary IPI", -}; - static void __init smp_psurge_setup_cpu(int cpu_nr) { + unsigned long flags = IRQF_PERCPU | IRQF_NO_THREAD; + int irq; + if (cpu_nr != 0 || !psurge_start) return; /* reset the entry point so if we get another intr we won't * try to startup again */ out_be32(psurge_start, 0x100); - if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction)) + irq = irq_create_mapping(NULL, 30); + if (request_irq(irq, psurge_ipi_intr, flags, "primary IPI", NULL)) printk(KERN_ERR "Couldn't get primary IPI interrupt"); } @@ -660,13 +658,13 @@ static void smp_core99_gpio_tb_freeze(int freeze) #endif /* !CONFIG_PPC64 */ -/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ -volatile static long int core99_l2_cache; -volatile static long int core99_l3_cache; - static void core99_init_caches(int cpu) { #ifndef CONFIG_PPC64 + /* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ + static long int core99_l2_cache; + static long int core99_l3_cache; + if (!cpu_has_feature(CPU_FTR_L2CR)) return; diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 6f300ab7f0e9..79409e005fcd 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -40,15 +40,8 @@ static int eeh_event_irq = -EINVAL; void pnv_pcibios_bus_add_device(struct pci_dev *pdev) { - struct pci_dn *pdn = pci_get_pdn(pdev); - - if (!pdn || eeh_has_flag(EEH_FORCE_DISABLED)) - return; - dev_dbg(&pdev->dev, "EEH: Setting up device\n"); - eeh_add_device_early(pdn); - eeh_add_device_late(pdev); - eeh_sysfs_add_device(pdev); + eeh_probe_device(pdev); } static int pnv_eeh_init(void) @@ -347,23 +340,13 @@ static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap) /** * pnv_eeh_probe - Do probe on PCI device - * @pdn: PCI device node - * @data: unused + * @pdev: pci_dev to probe * - * When EEH module is installed during system boot, all PCI devices - * are checked one by one to see if it supports EEH. The function - * is introduced for the purpose. By default, EEH has been enabled - * on all PCI devices. That's to say, we only need do necessary - * initialization on the corresponding eeh device and create PE - * accordingly. - * - * It's notable that's unsafe to retrieve the EEH device through - * the corresponding PCI device. During the PCI device hotplug, which - * was possiblly triggered by EEH core, the binding between EEH device - * and the PCI device isn't built yet. + * Create, or find the existing, eeh_dev for this pci_dev. */ -static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) +static struct eeh_dev *pnv_eeh_probe(struct pci_dev *pdev) { + struct pci_dn *pdn = pci_get_pdn(pdev); struct pci_controller *hose = pdn->phb; struct pnv_phb *phb = hose->private_data; struct eeh_dev *edev = pdn_to_eeh_dev(pdn); @@ -380,6 +363,14 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) if (!edev || edev->pe) return NULL; + /* already configured? */ + if (edev->pdev) { + pr_debug("%s: found existing edev for %04x:%02x:%02x.%01x\n", + __func__, hose->global_number, config_addr >> 8, + PCI_SLOT(config_addr), PCI_FUNC(config_addr)); + return edev; + } + /* Skip for PCI-ISA bridge */ if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA) return NULL; @@ -471,7 +462,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) eeh_edev_dbg(edev, "EEH enabled on device\n"); - return NULL; + return edev; } /** diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index eb2e75dac369..13b369d2cc45 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -187,11 +187,6 @@ static int memtrace_init_debugfs(void) snprintf(ent->name, 16, "%08x", ent->nid); dir = debugfs_create_dir(ent->name, memtrace_debugfs_dir); - if (!dir) { - pr_err("Failed to create debugfs directory for node %d\n", - ent->nid); - return -1; - } ent->dir = dir; debugfs_create_file("trace", 0400, dir, ent, &memtrace_fops); @@ -236,16 +231,10 @@ static int memtrace_online(void) continue; } - /* - * If kernel isn't compiled with the auto online option - * we need to online the memory ourselves. - */ - if (!memhp_auto_online) { - lock_device_hotplug(); - walk_memory_blocks(ent->start, ent->size, NULL, - online_mem_block); - unlock_device_hotplug(); - } + lock_device_hotplug(); + walk_memory_blocks(ent->start, ent->size, NULL, + online_mem_block); + unlock_device_hotplug(); /* * Memory was added successfully so clean up references to it @@ -314,8 +303,6 @@ static int memtrace_init(void) { memtrace_debugfs_dir = debugfs_create_dir("memtrace", powerpc_debugfs_root); - if (!memtrace_debugfs_dir) - return -1; debugfs_create_file("enable", 0600, memtrace_debugfs_dir, NULL, &memtrace_init_fops); diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c index ed895d82c048..6dba3b62269f 100644 --- a/arch/powerpc/platforms/powernv/opal-core.c +++ b/arch/powerpc/platforms/powernv/opal-core.c @@ -71,6 +71,7 @@ static LIST_HEAD(opalcore_list); static struct opalcore_config *oc_conf; static const struct opal_mpipl_fadump *opalc_metadata; static const struct opal_mpipl_fadump *opalc_cpu_metadata; +struct kobject *mpipl_kobj; /* * Set crashing CPU's signal to SIGUSR1. if the kernel is triggered @@ -428,7 +429,7 @@ static void opalcore_cleanup(void) return; /* Remove OPAL core sysfs file */ - sysfs_remove_bin_file(opal_kobj, &opal_core_attr); + sysfs_remove_bin_file(mpipl_kobj, &opal_core_attr); oc_conf->ptload_phdr = NULL; oc_conf->ptload_cnt = 0; @@ -563,9 +564,9 @@ error_out: of_node_put(np); } -static ssize_t fadump_release_opalcore_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t release_core_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) { int input = -1; @@ -589,9 +590,23 @@ static ssize_t fadump_release_opalcore_store(struct kobject *kobj, return count; } -static struct kobj_attribute opalcore_rel_attr = __ATTR(fadump_release_opalcore, - 0200, NULL, - fadump_release_opalcore_store); +static struct kobj_attribute opalcore_rel_attr = __ATTR_WO(release_core); + +static struct attribute *mpipl_attr[] = { + &opalcore_rel_attr.attr, + NULL, +}; + +static struct bin_attribute *mpipl_bin_attr[] = { + &opal_core_attr, + NULL, + +}; + +static struct attribute_group mpipl_group = { + .attrs = mpipl_attr, + .bin_attrs = mpipl_bin_attr, +}; static int __init opalcore_init(void) { @@ -609,7 +624,7 @@ static int __init opalcore_init(void) * then capture the dump. */ if (!(is_opalcore_usable())) { - pr_err("Failed to export /sys/firmware/opal/core\n"); + pr_err("Failed to export /sys/firmware/opal/mpipl/core\n"); opalcore_cleanup(); return rc; } @@ -617,18 +632,28 @@ static int __init opalcore_init(void) /* Set OPAL core file size */ opal_core_attr.size = oc_conf->opalcore_size; + mpipl_kobj = kobject_create_and_add("mpipl", opal_kobj); + if (!mpipl_kobj) { + pr_err("unable to create mpipl kobject\n"); + return -ENOMEM; + } + /* Export OPAL core sysfs file */ - rc = sysfs_create_bin_file(opal_kobj, &opal_core_attr); - if (rc != 0) { - pr_err("Failed to export /sys/firmware/opal/core\n"); + rc = sysfs_create_group(mpipl_kobj, &mpipl_group); + if (rc) { + pr_err("mpipl sysfs group creation failed (%d)", rc); opalcore_cleanup(); return rc; } - - rc = sysfs_create_file(kernel_kobj, &opalcore_rel_attr.attr); + /* The /sys/firmware/opal/core is moved to /sys/firmware/opal/mpipl/ + * directory, need to create symlink at old location to maintain + * backward compatibility. + */ + rc = compat_only_sysfs_link_entry_to_kobj(opal_kobj, mpipl_kobj, + "core", NULL); if (rc) { - pr_warn("unable to create sysfs file fadump_release_opalcore (%d)\n", - rc); + pr_err("unable to create core symlink (%d)\n", rc); + return rc; } return 0; diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index 000b350d4060..7824cc364bc4 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -35,11 +35,10 @@ static int imc_mem_set(void *data, u64 val) } DEFINE_DEBUGFS_ATTRIBUTE(fops_imc_x64, imc_mem_get, imc_mem_set, "0x%016llx\n"); -static struct dentry *imc_debugfs_create_x64(const char *name, umode_t mode, - struct dentry *parent, u64 *value) +static void imc_debugfs_create_x64(const char *name, umode_t mode, + struct dentry *parent, u64 *value) { - return debugfs_create_file_unsafe(name, mode, parent, - value, &fops_imc_x64); + debugfs_create_file_unsafe(name, mode, parent, value, &fops_imc_x64); } /* @@ -59,9 +58,6 @@ static void export_imc_mode_and_cmd(struct device_node *node, imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root); - if (!imc_debugfs_parent) - return; - if (of_property_read_u32(node, "cb_offset", &cb_offset)) cb_offset = IMC_CNTL_BLK_OFFSET; @@ -69,21 +65,15 @@ static void export_imc_mode_and_cmd(struct device_node *node, loc = (u64)(ptr->vbase) + cb_offset; imc_mode_addr = (u64 *)(loc + IMC_CNTL_BLK_MODE_OFFSET); sprintf(mode, "imc_mode_%d", (u32)(ptr->id)); - if (!imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent, - imc_mode_addr)) - goto err; + imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent, + imc_mode_addr); imc_cmd_addr = (u64 *)(loc + IMC_CNTL_BLK_CMD_OFFSET); sprintf(cmd, "imc_cmd_%d", (u32)(ptr->id)); - if (!imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent, - imc_cmd_addr)) - goto err; + imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent, + imc_cmd_addr); ptr++; } - return; - -err: - debugfs_remove_recursive(imc_debugfs_parent); } /* @@ -278,14 +268,7 @@ static int opal_imc_counters_probe(struct platform_device *pdev) domain = IMC_DOMAIN_THREAD; break; case IMC_TYPE_TRACE: - /* - * FIXME. Using trace_imc events to monitor application - * or KVM thread performance can cause a checkstop - * (system crash). - * Disable it for now. - */ - pr_info_once("IMC: disabling trace_imc PMU\n"); - domain = -1; + domain = IMC_DOMAIN_TRACE; break; default: pr_warn("IMC Unknown Device type \n"); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 22c22cd7bd82..57d3a6af1d52 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -3174,11 +3174,6 @@ static void pnv_pci_ioda_create_dbgfs(void) sprintf(name, "PCI%04x", hose->global_number); phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root); - if (!phb->dbgfs) { - pr_warn("%s: Error on creating debugfs on PHB#%x\n", - __func__, hose->global_number); - continue; - } debugfs_create_file_unsafe("dump_diag_regs", 0200, phb->dbgfs, phb, &pnv_pci_diag_data_fops); diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 11fdae81b5dd..3bc188da82ba 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -229,7 +229,7 @@ static void __noreturn pnv_restart(char *cmd) pnv_prepare_going_down(); do { - if (!cmd) + if (!cmd || !strlen(cmd)) rc = opal_cec_reboot(); else if (strcmp(cmd, "full") == 0) rc = opal_cec_reboot2(OPAL_REBOOT_FULL_IPL, NULL); @@ -237,6 +237,8 @@ static void __noreturn pnv_restart(char *cmd) rc = opal_cec_reboot2(OPAL_REBOOT_MPIPL, NULL); else if (strcmp(cmd, "error") == 0) rc = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, NULL); + else if (strcmp(cmd, "fast") == 0) + rc = opal_cec_reboot2(OPAL_REBOOT_FAST, NULL); else rc = OPAL_UNSUPPORTED; diff --git a/arch/powerpc/platforms/powernv/vas-debug.c b/arch/powerpc/platforms/powernv/vas-debug.c index 09e63df53c30..44035a3d6414 100644 --- a/arch/powerpc/platforms/powernv/vas-debug.c +++ b/arch/powerpc/platforms/powernv/vas-debug.c @@ -115,7 +115,7 @@ void vas_window_free_dbgdir(struct vas_window *window) void vas_window_init_dbgdir(struct vas_window *window) { - struct dentry *f, *d; + struct dentry *d; if (!window->vinst->dbgdir) return; @@ -127,28 +127,10 @@ void vas_window_init_dbgdir(struct vas_window *window) snprintf(window->dbgname, 16, "w%d", window->winid); d = debugfs_create_dir(window->dbgname, window->vinst->dbgdir); - if (IS_ERR(d)) - goto free_name; - window->dbgdir = d; - f = debugfs_create_file("info", 0444, d, window, &info_fops); - if (IS_ERR(f)) - goto remove_dir; - - f = debugfs_create_file("hvwc", 0444, d, window, &hvwc_fops); - if (IS_ERR(f)) - goto remove_dir; - - return; - -remove_dir: - debugfs_remove_recursive(window->dbgdir); - window->dbgdir = NULL; - -free_name: - kfree(window->dbgname); - window->dbgname = NULL; + debugfs_create_file("info", 0444, d, window, &info_fops); + debugfs_create_file("hvwc", 0444, d, window, &hvwc_fops); } void vas_instance_init_dbgdir(struct vas_instance *vinst) @@ -156,8 +138,6 @@ void vas_instance_init_dbgdir(struct vas_instance *vinst) struct dentry *d; vas_init_dbgdir(); - if (!vas_debugfs) - return; vinst->dbgname = kzalloc(16, GFP_KERNEL); if (!vinst->dbgname) @@ -166,16 +146,7 @@ void vas_instance_init_dbgdir(struct vas_instance *vinst) snprintf(vinst->dbgname, 16, "v%d", vinst->vas_id); d = debugfs_create_dir(vinst->dbgname, vas_debugfs); - if (IS_ERR(d)) - goto free_name; - vinst->dbgdir = d; - return; - -free_name: - kfree(vinst->dbgname); - vinst->dbgname = NULL; - vinst->dbgdir = NULL; } /* @@ -191,6 +162,4 @@ void vas_init_dbgdir(void) first_time = false; vas_debugfs = debugfs_create_dir("vas", NULL); - if (IS_ERR(vas_debugfs)) - vas_debugfs = NULL; } diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index cbddd63caf2d..e8530371aed6 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -613,10 +613,8 @@ static int update_flash_db(void) /* Read in header and db from flash. */ header = kmalloc(buf_len, GFP_KERNEL); - if (!header) { - pr_debug("%s: kmalloc failed\n", __func__); + if (!header) return -ENOMEM; - } count = os_area_flash_read(header, buf_len, 0); if (count < 0) { diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index a3c74a5cf20d..c8a2b0b05ac0 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -29,6 +29,4 @@ obj-$(CONFIG_PPC_SPLPAR) += vphn.o obj-$(CONFIG_PPC_SVM) += svm.o obj-$(CONFIG_FA_DUMP) += rtas-fadump.o -ifdef CONFIG_PPC_PSERIES obj-$(CONFIG_SUSPEND) += suspend.o -endif diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 893ba3f562c4..845342814edc 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -67,8 +67,7 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev) pdn->pe_number = physfn_pdn->pe_num_map[pdn->vf_index]; } #endif - eeh_add_device_early(pdn); - eeh_add_device_late(pdev); + pseries_eeh_init_edev(pdn); #ifdef CONFIG_PCI_IOV if (pdev->is_virtfn) { struct eeh_dev *edev = pdn_to_eeh_dev(pdn); @@ -78,7 +77,7 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev) eeh_add_to_parent_pe(edev); /* Add as VF PE type */ } #endif - eeh_sysfs_add_device(pdev); + eeh_probe_device(pdev); } /* @@ -222,15 +221,16 @@ static int pseries_eeh_find_ecap(struct pci_dn *pdn, int cap) } /** - * pseries_eeh_probe - EEH probe on the given device + * pseries_eeh_init_edev - initialise the eeh_dev and eeh_pe for a pci_dn + * * @pdn: PCI device node - * @data: Unused * - * When EEH module is installed during system boot, all PCI devices - * are checked one by one to see if it supports EEH. The function - * is introduced for the purpose. + * When we discover a new PCI device via the device-tree we create a + * corresponding pci_dn and we allocate, but don't initialise, an eeh_dev. + * This function takes care of the initialisation and inserts the eeh_dev + * into the correct eeh_pe. If no eeh_pe exists we'll allocate one. */ -static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) +void pseries_eeh_init_edev(struct pci_dn *pdn) { struct eeh_dev *edev; struct eeh_pe pe; @@ -238,18 +238,35 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) int enable = 0; int ret; - /* Retrieve OF node and eeh device */ + if (WARN_ON_ONCE(!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))) + return; + + /* + * Find the eeh_dev for this pdn. The storage for the eeh_dev was + * allocated at the same time as the pci_dn. + * + * XXX: We should probably re-visit that. + */ edev = pdn_to_eeh_dev(pdn); - if (!edev || edev->pe) - return NULL; + if (!edev) + return; + + /* + * If ->pe is set then we've already probed this device. We hit + * this path when a pci_dev is removed and rescanned while recovering + * a PE (i.e. for devices where the driver doesn't support error + * recovery). + */ + if (edev->pe) + return; /* Check class/vendor/device IDs */ if (!pdn->vendor_id || !pdn->device_id || !pdn->class_code) - return NULL; + return; /* Skip for PCI-ISA bridge */ if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA) - return NULL; + return; eeh_edev_dbg(edev, "Probing device\n"); @@ -316,9 +333,49 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) /* Save memory bars */ eeh_save_bars(edev); +} + +static struct eeh_dev *pseries_eeh_probe(struct pci_dev *pdev) +{ + struct eeh_dev *edev; + struct pci_dn *pdn; + + pdn = pci_get_pdn_by_devfn(pdev->bus, pdev->devfn); + if (!pdn) + return NULL; + + /* + * If the system supports EEH on this device then the eeh_dev was + * configured and inserted into a PE in pseries_eeh_init_edev() + */ + edev = pdn_to_eeh_dev(pdn); + if (!edev || !edev->pe) + return NULL; + + return edev; +} + +/** + * pseries_eeh_init_edev_recursive - Enable EEH for the indicated device + * @pdn: PCI device node + * + * This routine must be used to perform EEH initialization for the + * indicated PCI device that was added after system boot (e.g. + * hotplug, dlpar). + */ +void pseries_eeh_init_edev_recursive(struct pci_dn *pdn) +{ + struct pci_dn *n; + + if (!pdn) + return; + + list_for_each_entry(n, &pdn->child_list, list) + pseries_eeh_init_edev_recursive(n); - return NULL; + pseries_eeh_init_edev(pdn); } +EXPORT_SYMBOL_GPL(pseries_eeh_init_edev_recursive); /** * pseries_eeh_set_option - Initialize EEH or MMIO/DMA reenable diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index f3ed1baa6289..b2cde1732301 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -223,7 +223,7 @@ static int get_lmb_range(u32 drc_index, int n_lmbs, struct drmem_lmb **end_lmb) { struct drmem_lmb *lmb, *start, *end; - struct drmem_lmb *last_lmb; + struct drmem_lmb *limit; start = NULL; for_each_drmem_lmb(lmb) { @@ -236,10 +236,10 @@ static int get_lmb_range(u32 drc_index, int n_lmbs, if (!start) return -EINVAL; - end = &start[n_lmbs - 1]; + end = &start[n_lmbs]; - last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1]; - if (end > last_lmb) + limit = &drmem_info->lmbs[drmem_info->n_lmbs]; + if (end > limit) return -EINVAL; *start_lmb = start; diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 2e0a8eab5588..6d47b4a3ce39 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -945,6 +945,15 @@ static phys_addr_t ddw_memory_hotplug_max(void) phys_addr_t max_addr = memory_hotplug_max(); struct device_node *memory; + /* + * The "ibm,pmemory" can appear anywhere in the address space. + * Assuming it is still backed by page structs, set the upper limit + * for the huge DMA window as MAX_PHYSMEM_BITS. + */ + if (of_find_node_by_type(NULL, "ibm,pmemory")) + return (sizeof(phys_addr_t) * 8 <= MAX_PHYSMEM_BITS) ? + (phys_addr_t) -1 : (1ULL << MAX_PHYSMEM_BITS); + for_each_node_by_type(memory, "memory") { unsigned long start, size; int n_mem_addr_cells, n_mem_size_cells, len; diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 3c3da25b445c..e4ed5317f117 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -636,8 +636,16 @@ static const struct proc_ops vcpudispatch_stats_freq_proc_ops = { static int __init vcpudispatch_stats_procfs_init(void) { - if (!lppaca_shared_proc(get_lppaca())) + /* + * Avoid smp_processor_id while preemptible. All CPUs should have + * the same value for lppaca_shared_proc. + */ + preempt_disable(); + if (!lppaca_shared_proc(get_lppaca())) { + preempt_enable(); return 0; + } + preempt_enable(); if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL, &vcpudispatch_stats_proc_ops)) diff --git a/arch/powerpc/platforms/pseries/of_helpers.c b/arch/powerpc/platforms/pseries/of_helpers.c index 66dfd8256712..23241c71ef37 100644 --- a/arch/powerpc/platforms/pseries/of_helpers.c +++ b/arch/powerpc/platforms/pseries/of_helpers.c @@ -88,7 +88,7 @@ int of_read_drc_info_cell(struct property **prop, const __be32 **curval, return -EINVAL; /* Should now know end of current entry */ - (*curval) = (void *)p2; + (*curval) = (void *)(++p2); data->last_drc_index = data->drc_index_start + ((data->num_sequential_elems - 1) * data->sequential_inc); diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 0b4467e378e5..f35592423380 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -246,8 +246,9 @@ static int papr_scm_meta_set(struct papr_scm_priv *p, return 0; } -int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, - unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc) +static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, + struct nvdimm *nvdimm, unsigned int cmd, void *buf, + unsigned int buf_len, int *cmd_rc) { struct nd_cmd_get_config_size *get_size_hdr; struct papr_scm_priv *p; @@ -285,25 +286,6 @@ int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, return 0; } -static inline int papr_scm_node(int node) -{ - int min_dist = INT_MAX, dist; - int nid, min_node; - - if ((node == NUMA_NO_NODE) || node_online(node)) - return node; - - min_node = first_online_node; - for_each_online_node(nid) { - dist = node_distance(node, nid); - if (dist < min_dist) { - min_dist = dist; - min_node = nid; - } - } - return min_node; -} - static int papr_scm_nvdimm_init(struct papr_scm_priv *p) { struct device *dev = &p->pdev->dev; @@ -328,7 +310,7 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) } dimm_flags = 0; - set_bit(NDD_ALIASING, &dimm_flags); + set_bit(NDD_LABELING, &dimm_flags); p->nvdimm = nvdimm_create(p->bus, p, NULL, dimm_flags, PAPR_SCM_DIMM_CMD_MASK, 0, NULL); @@ -349,7 +331,7 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) memset(&ndr_desc, 0, sizeof(ndr_desc)); target_nid = dev_to_node(&p->pdev->dev); - online_nid = papr_scm_node(target_nid); + online_nid = numa_map_to_online_node(target_nid); ndr_desc.numa_node = online_nid; ndr_desc.target_node = target_nid; ndr_desc.res = &p->res; @@ -361,8 +343,10 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) if (p->is_volatile) p->region = nvdimm_volatile_region_create(p->bus, &ndr_desc); - else + else { + set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc.flags); p->region = nvdimm_pmem_region_create(p->bus, &ndr_desc); + } if (!p->region) { dev_err(dev, "Error registering region %pR from %pOF\n", ndr_desc.res, p->dn); diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 361986e4354e..b3a38f5a6b68 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -37,7 +37,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) eeh_dev_phb_init_dynamic(phb); if (dn->child) - eeh_add_device_tree_early(PCI_DN(dn)); + pseries_eeh_init_edev_recursive(PCI_DN(dn)); pcibios_scan_phb(phb); pcibios_finish_adding_to_bus(phb->bus); diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 1d7f973c647b..1d1da639b8b7 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -558,6 +558,9 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) switch (mce_log->error_type) { case MC_ERROR_TYPE_UE: mce_err.error_type = MCE_ERROR_TYPE_UE; + mce_common_process_ue(regs, &mce_err); + if (mce_err.ignore_event) + disposition = RTAS_DISP_FULLY_RECOVERED; switch (err_sub_type) { case MC_ERROR_UE_IFETCH: mce_err.u.ue_error_type = MCE_UE_ERROR_IFETCH; @@ -683,6 +686,17 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) #endif out: + /* + * Enable translation as we will be accessing per-cpu variables + * in save_mce_event() which may fall outside RMO region, also + * leave it enabled because subsequently we will be queuing work + * to workqueues where again per-cpu variables accessed, besides + * fwnmi_release_errinfo() crashes when called in realmode on + * pseries. + * Note: All the realmode handling like flushing SLB entries for + * SLB multihit is done by now. + */ + mtmsr(mfmsr() | MSR_IR | MSR_DR); save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED, &mce_err, regs->nip, eaddr, paddr); diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index f682b7babc09..37f1f25ba804 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1628,7 +1628,6 @@ const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) } EXPORT_SYMBOL(vio_get_attribute); -#ifdef CONFIG_PPC_PSERIES /* vio_find_name() - internal because only vio.c knows how we formatted the * kobject name */ @@ -1698,7 +1697,6 @@ int vio_disable_interrupts(struct vio_dev *dev) return rc; } EXPORT_SYMBOL(vio_disable_interrupts); -#endif /* CONFIG_PPC_PSERIES */ static int __init vio_init(void) { diff --git a/arch/powerpc/platforms/pseries/vphn.c b/arch/powerpc/platforms/pseries/vphn.c index 3f07bf6c670e..cca474a2c396 100644 --- a/arch/powerpc/platforms/pseries/vphn.c +++ b/arch/powerpc/platforms/pseries/vphn.c @@ -82,7 +82,8 @@ long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity) long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu); - vphn_unpack_associativity(retbuf, associativity); + if (rc == H_SUCCESS) + vphn_unpack_associativity(retbuf, associativity); return rc; } diff --git a/arch/powerpc/purgatory/.gitignore b/arch/powerpc/purgatory/.gitignore index e9e66f178a6d..b8dc6ff34254 100644 --- a/arch/powerpc/purgatory/.gitignore +++ b/arch/powerpc/purgatory/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only kexec-purgatory.c purgatory.ro diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 9651ca061828..b294f70f1a67 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -20,6 +20,7 @@ #include <linux/spinlock.h> #include <linux/msi.h> +#include <asm/debugfs.h> #include <asm/prom.h> #include <asm/io.h> #include <asm/smp.h> @@ -68,13 +69,6 @@ static u32 xive_ipi_irq; /* Xive state for each CPU */ static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu); -/* - * A "disabled" interrupt should never fire, to catch problems - * we set its logical number to this - */ -#define XIVE_BAD_IRQ 0x7fffffff -#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) - /* An invalid CPU target */ #define XIVE_INVALID_TARGET (-1) @@ -265,11 +259,15 @@ notrace void xmon_xive_do_dump(int cpu) int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) { + struct irq_chip *chip = irq_data_get_irq_chip(d); int rc; u32 target; u8 prio; u32 lirq; + if (!is_xive_irq(chip)) + return -EINVAL; + rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq); if (rc) { xmon_printf("IRQ 0x%08x : no config rc=%d\n", hw_irq, rc); @@ -283,7 +281,10 @@ int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); u64 val = xive_esb_read(xd, XIVE_ESB_GET); - xmon_printf("PQ=%c%c", + xmon_printf("flags=%c%c%c PQ=%c%c", + xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', + xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', + xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', val & XIVE_ESB_VAL_P ? 'P' : '-', val & XIVE_ESB_VAL_Q ? 'Q' : '-'); } @@ -1150,7 +1151,7 @@ static int xive_setup_cpu_ipi(unsigned int cpu) xc = per_cpu(xive_cpu, cpu); /* Check if we are already setup */ - if (xc->hw_ipi != 0) + if (xc->hw_ipi != XIVE_BAD_IRQ) return 0; /* Grab an IPI from the backend, this will populate xc->hw_ipi */ @@ -1187,7 +1188,7 @@ static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc) /* Disable the IPI and free the IRQ data */ /* Already cleaned up ? */ - if (xc->hw_ipi == 0) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; /* Mask the IPI */ @@ -1343,6 +1344,7 @@ static int xive_prepare_cpu(unsigned int cpu) if (np) xc->chip_id = of_get_ibm_chip_id(np); of_node_put(np); + xc->hw_ipi = XIVE_BAD_IRQ; per_cpu(xive_cpu, cpu) = xc; } @@ -1554,3 +1556,107 @@ static int __init xive_off(char *arg) return 0; } __setup("xive=off", xive_off); + +void xive_debug_show_cpu(struct seq_file *m, int cpu) +{ + struct xive_cpu *xc = per_cpu(xive_cpu, cpu); + + seq_printf(m, "CPU %d:", cpu); + if (xc) { + seq_printf(m, "pp=%02x CPPR=%02x ", xc->pending_prio, xc->cppr); + +#ifdef CONFIG_SMP + { + u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET); + + seq_printf(m, "IPI=0x%08x PQ=%c%c ", xc->hw_ipi, + val & XIVE_ESB_VAL_P ? 'P' : '-', + val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + } +#endif + { + struct xive_q *q = &xc->queue[xive_irq_priority]; + u32 i0, i1, idx; + + if (q->qpage) { + idx = q->idx; + i0 = be32_to_cpup(q->qpage + idx); + idx = (idx + 1) & q->msk; + i1 = be32_to_cpup(q->qpage + idx); + seq_printf(m, "EQ idx=%d T=%d %08x %08x ...", + q->idx, q->toggle, i0, i1); + } + } + } + seq_puts(m, "\n"); +} + +void xive_debug_show_irq(struct seq_file *m, u32 hw_irq, struct irq_data *d) +{ + struct irq_chip *chip = irq_data_get_irq_chip(d); + int rc; + u32 target; + u8 prio; + u32 lirq; + + if (!is_xive_irq(chip)) + return; + + rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq); + if (rc) { + seq_printf(m, "IRQ 0x%08x : no config rc=%d\n", hw_irq, rc); + return; + } + + seq_printf(m, "IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ", + hw_irq, target, prio, lirq); + + if (d) { + struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); + u64 val = xive_esb_read(xd, XIVE_ESB_GET); + + seq_printf(m, "flags=%c%c%c PQ=%c%c", + xd->flags & XIVE_IRQ_FLAG_STORE_EOI ? 'S' : ' ', + xd->flags & XIVE_IRQ_FLAG_LSI ? 'L' : ' ', + xd->flags & XIVE_IRQ_FLAG_H_INT_ESB ? 'H' : ' ', + val & XIVE_ESB_VAL_P ? 'P' : '-', + val & XIVE_ESB_VAL_Q ? 'Q' : '-'); + } + seq_puts(m, "\n"); +} + +static int xive_core_debug_show(struct seq_file *m, void *private) +{ + unsigned int i; + struct irq_desc *desc; + int cpu; + + if (xive_ops->debug_show) + xive_ops->debug_show(m, private); + + for_each_possible_cpu(cpu) + xive_debug_show_cpu(m, cpu); + + for_each_irq_desc(i, desc) { + struct irq_data *d = irq_desc_get_irq_data(desc); + unsigned int hw_irq; + + if (!d) + continue; + + hw_irq = (unsigned int)irqd_to_hwirq(d); + + /* IPIs are special (HW number 0) */ + if (hw_irq) + xive_debug_show_irq(m, hw_irq, d); + } + return 0; +} +DEFINE_SHOW_ATTRIBUTE(xive_core_debug); + +int xive_core_debug_init(void) +{ + debugfs_create_file("xive", 0400, powerpc_debugfs_root, + NULL, &xive_core_debug_fops); + return 0; +} diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 0ff6b739052c..5218fdc4b29a 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -19,6 +19,7 @@ #include <linux/cpumask.h> #include <linux/mm.h> +#include <asm/machdep.h> #include <asm/prom.h> #include <asm/io.h> #include <asm/smp.h> @@ -312,7 +313,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc) s64 rc; /* Free the IPI */ - if (!xc->hw_ipi) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; for (;;) { rc = opal_xive_free_irq(xc->hw_ipi); @@ -320,7 +321,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc) msleep(OPAL_BUSY_DELAY_MS); continue; } - xc->hw_ipi = 0; + xc->hw_ipi = XIVE_BAD_IRQ; break; } } @@ -850,3 +851,5 @@ int xive_native_get_vp_state(u32 vp_id, u64 *out_state) return 0; } EXPORT_SYMBOL_GPL(xive_native_get_vp_state); + +machine_arch_initcall(powernv, xive_core_debug_init); diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 55dc61cb4867..7ab5c6780997 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/libfdt.h> +#include <asm/machdep.h> #include <asm/prom.h> #include <asm/io.h> #include <asm/smp.h> @@ -560,11 +561,11 @@ static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc) static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc) { - if (!xc->hw_ipi) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; xive_irq_bitmap_free(xc->hw_ipi); - xc->hw_ipi = 0; + xc->hw_ipi = XIVE_BAD_IRQ; } #endif /* CONFIG_SMP */ @@ -645,6 +646,21 @@ static void xive_spapr_sync_source(u32 hw_irq) plpar_int_sync(0, hw_irq); } +static int xive_spapr_debug_show(struct seq_file *m, void *private) +{ + struct xive_irq_bitmap *xibm; + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + + list_for_each_entry(xibm, &xive_irq_bitmaps, list) { + memset(buf, 0, PAGE_SIZE); + bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count); + seq_printf(m, "bitmap #%d: %s", xibm->count, buf); + } + kfree(buf); + + return 0; +} + static const struct xive_ops xive_spapr_ops = { .populate_irq_data = xive_spapr_populate_irq_data, .configure_irq = xive_spapr_configure_irq, @@ -662,6 +678,7 @@ static const struct xive_ops xive_spapr_ops = { #ifdef CONFIG_SMP .get_ipi = xive_spapr_get_ipi, .put_ipi = xive_spapr_put_ipi, + .debug_show = xive_spapr_debug_show, #endif /* CONFIG_SMP */ .name = "spapr", }; @@ -839,3 +856,5 @@ bool __init xive_spapr_init(void) pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); return true; } + +machine_arch_initcall(pseries, xive_core_debug_init); diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index 59cd366e7933..b7b901da2168 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -5,6 +5,13 @@ #ifndef __XIVE_INTERNAL_H #define __XIVE_INTERNAL_H +/* + * A "disabled" interrupt should never fire, to catch problems + * we set its logical number to this + */ +#define XIVE_BAD_IRQ 0x7fffffff +#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) + /* Each CPU carry one of these with various per-CPU state */ struct xive_cpu { #ifdef CONFIG_SMP @@ -50,12 +57,14 @@ struct xive_ops { int (*get_ipi)(unsigned int cpu, struct xive_cpu *xc); void (*put_ipi)(unsigned int cpu, struct xive_cpu *xc); #endif + int (*debug_show)(struct seq_file *m, void *private); const char *name; }; bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, u8 max_prio); __be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift); +int xive_core_debug_init(void); static inline u32 xive_alloc_order(u32 queue_shift) { diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index c3842dbeb1b7..6f9cccea54f3 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -1,9 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for xmon -# Avoid clang warnings around longjmp/setjmp declarations -subdir-ccflags-y := -ffreestanding - GCOV_PROFILE := n KCOV_INSTRUMENT := n UBSAN_SANITIZE := n diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 0ec9640335bb..7af840c0fc93 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -81,8 +81,9 @@ static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE); static unsigned long adrs; static int size = 1; -#define MAX_DUMP (128 * 1024) +#define MAX_DUMP (64 * 1024) static unsigned long ndump = 64; +#define MAX_IDUMP (MAX_DUMP >> 2) static unsigned long nidump = 16; static unsigned long ncsum = 4096; static int termch; @@ -2712,7 +2713,12 @@ static void dump_by_size(unsigned long addr, long count, int size) printf("%0*llx", size * 2, val); } - printf("\n"); + printf(" |"); + for (j = 0; j < 16; ++j) { + val = temp[j]; + putchar(' ' <= val && val <= '~' ? val : '.'); + } + printf("|\n"); } } @@ -2756,8 +2762,8 @@ dump(void) scanhex(&nidump); if (nidump == 0) nidump = 16; - else if (nidump > MAX_DUMP) - nidump = MAX_DUMP; + else if (nidump > MAX_IDUMP) + nidump = MAX_IDUMP; adrs += ppc_inst_dump(adrs, nidump, 1); last_cmd = "di\n"; } else if (c == 'l') { diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 8672e77a5b7a..62f7bfeb709e 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -20,7 +20,6 @@ config RISCV select CLONE_BACKWARDS select COMMON_CLK select GENERIC_CLOCKEVENTS - select GENERIC_CPU_DEVICES select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP select GENERIC_SCHED_CLOCK @@ -29,6 +28,7 @@ config RISCV select GENERIC_SMP_IDLE_THREAD select GENERIC_ATOMIC64 if !64BIT select GENERIC_IOREMAP + select GENERIC_PTDUMP if MMU select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_SECCOMP_FILTER select HAVE_ASM_MODVERSIONS @@ -55,9 +55,12 @@ config RISCV select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MMIOWB select ARCH_HAS_DEBUG_VIRTUAL - select HAVE_EBPF_JIT + select HAVE_EBPF_JIT if MMU select EDAC_SUPPORT select ARCH_HAS_GIGANTIC_PAGE + select ARCH_HAS_SET_DIRECT_MAP + select ARCH_HAS_SET_MEMORY + select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_WANT_HUGE_PMD_SHARE if 64BIT select SPARSEMEM_STATIC if 32BIT select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU @@ -129,6 +132,9 @@ config ARCH_SELECT_MEMORY_MODEL config ARCH_WANT_GENERAL_HUGETLB def_bool y +config ARCH_SUPPORTS_DEBUG_PAGEALLOC + def_bool y + config SYS_SUPPORTS_HUGETLBFS def_bool y @@ -247,6 +253,17 @@ config NR_CPUS depends on SMP default "8" +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP + select GENERIC_IRQ_MIGRATION + help + + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + + Say N if you want to disable CPU hotplug. + choice prompt "CPU Tuning" default TUNE_GENERIC @@ -307,6 +324,13 @@ config SECCOMP and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. +config RISCV_SBI_V01 + bool "SBI v0.1 support" + default y + depends on RISCV_SBI + help + This config allows kernel to use SBI v0.1 APIs. This will be + deprecated in future once legacy M-mode software are no longer in use. endmenu menu "Boot options" diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index a131174a0a77..216286db81c9 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -20,4 +20,14 @@ config SOC_VIRT help This enables support for QEMU Virt Machine. +config SOC_KENDRYTE + bool "Kendryte K210 SoC" + depends on !MMU + select BUILTIN_DTB + select SERIAL_SIFIVE if TTY + select SERIAL_SIFIVE_CONSOLE if TTY + select SIFIVE_PLIC + help + This enables support for Kendryte K210 SoC platform hardware. + endmenu diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 259cb53d7f20..fb6e37db836d 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -85,12 +85,12 @@ PHONY += vdso_install vdso_install: $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ -ifeq ($(CONFIG_RISCV_M_MODE),y) -KBUILD_IMAGE := $(boot)/loader +ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_KENDRYTE),yy) +KBUILD_IMAGE := $(boot)/loader.bin else KBUILD_IMAGE := $(boot)/Image.gz endif -BOOT_TARGETS := Image Image.gz loader +BOOT_TARGETS := Image Image.gz loader loader.bin all: $(notdir $(KBUILD_IMAGE)) diff --git a/arch/riscv/boot/.gitignore b/arch/riscv/boot/.gitignore index 8a45a37d2af4..574c10f8ff68 100644 --- a/arch/riscv/boot/.gitignore +++ b/arch/riscv/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only Image Image.gz loader diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index 36db8145f9f4..3530c59b3ea7 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -41,6 +41,9 @@ $(obj)/Image.lzma: $(obj)/Image FORCE $(obj)/Image.lzo: $(obj)/Image FORCE $(call if_changed,lzo) +$(obj)/loader.bin: $(obj)/loader FORCE + $(call if_changed,objcopy) + install: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile index dcc3ada78455..557f0b519c8e 100644 --- a/arch/riscv/boot/dts/Makefile +++ b/arch/riscv/boot/dts/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 subdir-y += sifive +subdir-y += kendryte diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile new file mode 100644 index 000000000000..815444e69e89 --- /dev/null +++ b/arch/riscv/boot/dts/kendryte/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts new file mode 100644 index 000000000000..0d1f28fce6b2 --- /dev/null +++ b/arch/riscv/boot/dts/kendryte/k210.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ + +/dts-v1/; + +#include "k210.dtsi" + +/ { + model = "Kendryte K210 generic"; + compatible = "kendryte,k210"; + + chosen { + bootargs = "earlycon console=ttySIF0"; + stdout-path = "serial0"; + }; +}; + +&uarths0 { + status = "okay"; +}; + diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi new file mode 100644 index 000000000000..c1df56ccb8d5 --- /dev/null +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com> + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#include <dt-bindings/clock/k210-clk.h> + +/ { + /* + * Although the K210 is a 64-bit CPU, the address bus is only 32-bits + * wide, and the upper half of all addresses is ignored. + */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "kendryte,k210"; + + aliases { + serial0 = &uarths0; + }; + + /* + * The K210 has an sv39 MMU following the priviledge specification v1.9. + * Since this is a non-ratified draft specification, the kernel does not + * support it and the K210 support enabled only for the !MMU case. + * Be consistent with this by setting the CPUs MMU type to "none". + */ + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <7800000>; + cpu0: cpu@0 { + device_type = "cpu"; + reg = <0>; + compatible = "kendryte,k210", "sifive,rocket0", "riscv"; + riscv,isa = "rv64imafdc"; + mmu-type = "none"; + i-cache-size = <0x8000>; + i-cache-block-size = <64>; + d-cache-size = <0x8000>; + d-cache-block-size = <64>; + clocks = <&sysctl K210_CLK_CPU>; + clock-frequency = <390000000>; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + cpu1: cpu@1 { + device_type = "cpu"; + reg = <1>; + compatible = "kendryte,k210", "sifive,rocket0", "riscv"; + riscv,isa = "rv64imafdc"; + mmu-type = "none"; + i-cache-size = <0x8000>; + i-cache-block-size = <64>; + d-cache-size = <0x8000>; + d-cache-block-size = <64>; + clocks = <&sysctl K210_CLK_CPU>; + clock-frequency = <390000000>; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + }; + + sram: memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x400000>, + <0x80400000 0x200000>, + <0x80600000 0x200000>; + reg-names = "sram0", "sram1", "aisram"; + }; + + clocks { + in0: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "kendryte,k210-soc", "simple-bus"; + ranges; + interrupt-parent = <&plic0>; + + sysctl: sysctl@50440000 { + compatible = "kendryte,k210-sysctl", "simple-mfd"; + reg = <0x50440000 0x1000>; + #clock-cells = <1>; + }; + + clint0: interrupt-controller@2000000 { + compatible = "riscv,clint0"; + reg = <0x2000000 0xC000>; + interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>; + clocks = <&sysctl K210_CLK_ACLK>; + }; + + plic0: interrupt-controller@c000000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "kendryte,k210-plic0", "riscv,plic0"; + reg = <0xC000000 0x4000000>; + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>, + <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>; + riscv,ndev = <65>; + riscv,max-priority = <7>; + }; + + uarths0: serial@38000000 { + compatible = "kendryte,k210-uarths", "sifive,uart0"; + reg = <0x38000000 0x1000>; + interrupts = <33>; + clocks = <&sysctl K210_CLK_CPU>; + }; + }; +}; diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index 2557c5372a25..4da4886246a4 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -128,3 +128,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y # CONFIG_FTRACE is not set # CONFIG_RUNTIME_TESTING_MENU is not set CONFIG_MEMTEST=y +# CONFIG_SYSFS_SYSCALL is not set diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig new file mode 100644 index 000000000000..632aa2f95e57 --- /dev/null +++ b/arch/riscv/configs/nommu_k210_defconfig @@ -0,0 +1,68 @@ +# CONFIG_CPU_ISOLATION is not set +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INITRAMFS_FORCE=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_BOOT_CONFIG is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_SYSFS_SYSCALL is not set +# CONFIG_FHANDLE is not set +# CONFIG_BASE_FULL is not set +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set +# CONFIG_IO_URING is not set +# CONFIG_ADVISE_SYSCALLS is not set +# CONFIG_MEMBARRIER is not set +# CONFIG_KALLSYMS is not set +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLOB=y +# CONFIG_SLAB_MERGE_DEFAULT is not set +# CONFIG_MMU is not set +CONFIG_SOC_KENDRYTE=y +CONFIG_MAXPHYSMEM_2GB=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +CONFIG_CMDLINE="earlycon console=ttySIF0" +CONFIG_CMDLINE_FORCE=y +CONFIG_USE_BUILTIN_DTB=y +CONFIG_BUILTIN_DTB_SOURCE="kendryte/k210" +# CONFIG_BLOCK is not set +CONFIG_BINFMT_FLAT=y +# CONFIG_COREDUMP is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_FW_LOADER is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_LDISC_AUTOLOAD is not set +# CONFIG_DEVMEM is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_VIRTIO_MENU is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_LSM="[]" +CONFIG_PRINTK_TIME=y +# CONFIG_DEBUG_MISC is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_FTRACE is not set +# CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig index 0292879a9690..05bbf5240569 100644 --- a/arch/riscv/configs/rv32_defconfig +++ b/arch/riscv/configs/rv32_defconfig @@ -124,3 +124,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y # CONFIG_FTRACE is not set # CONFIG_RUNTIME_TESTING_MENU is not set CONFIG_MEMTEST=y +# CONFIG_SYSFS_SYSCALL is not set diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h index 75604fec1b1b..d6f1ec08d97b 100644 --- a/arch/riscv/include/asm/bug.h +++ b/arch/riscv/include/asm/bug.h @@ -19,6 +19,14 @@ #define __BUG_INSN_32 _UL(0x00100073) /* ebreak */ #define __BUG_INSN_16 _UL(0x9002) /* c.ebreak */ +#define GET_INSN_LENGTH(insn) \ +({ \ + unsigned long __len; \ + __len = ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? \ + 4UL : 2UL; \ + __len; \ +}) + typedef u32 bug_insn_t; #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h index 555b20b11dc3..c8677c75f82c 100644 --- a/arch/riscv/include/asm/cacheflush.h +++ b/arch/riscv/include/asm/cacheflush.h @@ -85,7 +85,7 @@ static inline void flush_dcache_page(struct page *page) * so instead we just flush the whole thing. */ #define flush_icache_range(start, end) flush_icache_all() -#define flush_icache_user_range(vma, pg, addr, len) flush_icache_all() +#define flush_icache_user_range(vma, pg, addr, len) flush_icache_mm(vma->vm_mm, 0) #ifndef CONFIG_SMP diff --git a/arch/riscv/include/asm/cpu_ops.h b/arch/riscv/include/asm/cpu_ops.h new file mode 100644 index 000000000000..a8ec3c5c1bd2 --- /dev/null +++ b/arch/riscv/include/asm/cpu_ops.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * Based on arch/arm64/include/asm/cpu_ops.h + */ +#ifndef __ASM_CPU_OPS_H +#define __ASM_CPU_OPS_H + +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/threads.h> + +/** + * struct cpu_operations - Callback operations for hotplugging CPUs. + * + * @name: Name of the boot protocol. + * @cpu_prepare: Early one-time preparation step for a cpu. If there + * is a mechanism for doing so, tests whether it is + * possible to boot the given HART. + * @cpu_start: Boots a cpu into the kernel. + * @cpu_disable: Prepares a cpu to die. May fail for some + * mechanism-specific reason, which will cause the hot + * unplug to be aborted. Called from the cpu to be killed. + * @cpu_stop: Makes a cpu leave the kernel. Must not fail. Called from + * the cpu being stopped. + * @cpu_is_stopped: Ensures a cpu has left the kernel. Called from another + * cpu. + */ +struct cpu_operations { + const char *name; + int (*cpu_prepare)(unsigned int cpu); + int (*cpu_start)(unsigned int cpu, + struct task_struct *tidle); +#ifdef CONFIG_HOTPLUG_CPU + int (*cpu_disable)(unsigned int cpu); + void (*cpu_stop)(void); + int (*cpu_is_stopped)(unsigned int cpu); +#endif +}; + +extern const struct cpu_operations *cpu_ops[NR_CPUS]; +void __init cpu_set_ops(int cpu); +void cpu_update_secondary_bootdata(unsigned int cpuid, + struct task_struct *tidle); + +#endif /* ifndef __ASM_CPU_OPS_H */ diff --git a/arch/riscv/include/asm/current.h b/arch/riscv/include/asm/current.h index dd973efe5d7c..1de233d8e8de 100644 --- a/arch/riscv/include/asm/current.h +++ b/arch/riscv/include/asm/current.h @@ -17,6 +17,8 @@ struct task_struct; +register struct task_struct *riscv_current_is_tp __asm__("tp"); + /* * This only works because "struct thread_info" is at offset 0 from "struct * task_struct". This constraint seems to be necessary on other architectures @@ -26,8 +28,7 @@ struct task_struct; */ static __always_inline struct task_struct *get_current(void) { - register struct task_struct *tp __asm__("tp"); - return tp; + return riscv_current_is_tp; } #define current get_current() diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h index 42d2c42f3cc9..2368d49eb4ef 100644 --- a/arch/riscv/include/asm/fixmap.h +++ b/arch/riscv/include/asm/fixmap.h @@ -27,6 +27,8 @@ enum fixed_addresses { FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1, FIX_PTE, FIX_PMD, + FIX_TEXT_POKE1, + FIX_TEXT_POKE0, FIX_EARLYCON_MEM_BASE, __end_of_fixed_addresses }; diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h index eee6e6588b12..b47045cb85ce 100644 --- a/arch/riscv/include/asm/kasan.h +++ b/arch/riscv/include/asm/kasan.h @@ -13,7 +13,7 @@ #define KASAN_SHADOW_SCALE_SHIFT 3 #define KASAN_SHADOW_SIZE (UL(1) << (38 - KASAN_SHADOW_SCALE_SHIFT)) -#define KASAN_SHADOW_START 0xffffffc000000000 /* 2^64 - 2^38 */ +#define KASAN_SHADOW_START KERN_VIRT_START /* 2^64 - 2^38 */ #define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) #define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << \ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index 8ca1930caa44..2d50f76efe48 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -137,8 +137,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h new file mode 100644 index 000000000000..b5918a6e0615 --- /dev/null +++ b/arch/riscv/include/asm/patch.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 SiFive + */ + +#ifndef _ASM_RISCV_PATCH_H +#define _ASM_RISCV_PATCH_H + +int riscv_patch_text_nosync(void *addr, const void *insns, size_t len); +int riscv_patch_text(void *addr, u32 insn); + +#endif /* _ASM_RISCV_PATCH_H */ diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 393f2014dfee..9c188ad2e52d 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -449,6 +449,16 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* + * In the RV64 Linux scheme, we give the user half of the virtual-address space + * and give the kernel the other (upper) half. + */ +#ifdef CONFIG_64BIT +#define KERN_VIRT_START (-(BIT(CONFIG_VA_BITS)) + TASK_SIZE) +#else +#define KERN_VIRT_START FIXADDR_START +#endif + +/* * Task size is 0x4000000000 for RV64 or 0x9fc00000 for RV32. * Note that PGDIR_SIZE must evenly divide TASK_SIZE. */ diff --git a/arch/riscv/include/asm/ptdump.h b/arch/riscv/include/asm/ptdump.h new file mode 100644 index 000000000000..e29af7191909 --- /dev/null +++ b/arch/riscv/include/asm/ptdump.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 SiFive + */ + +#ifndef _ASM_RISCV_PTDUMP_H +#define _ASM_RISCV_PTDUMP_H + +void ptdump_check_wx(void); + +#endif /* _ASM_RISCV_PTDUMP_H */ diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2570c1e683d3..653edb25d495 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2015 Regents of the University of California + * Copyright (c) 2020 Western Digital Corporation or its affiliates. */ #ifndef _ASM_RISCV_SBI_H @@ -9,96 +10,148 @@ #include <linux/types.h> #ifdef CONFIG_RISCV_SBI -#define SBI_SET_TIMER 0 -#define SBI_CONSOLE_PUTCHAR 1 -#define SBI_CONSOLE_GETCHAR 2 -#define SBI_CLEAR_IPI 3 -#define SBI_SEND_IPI 4 -#define SBI_REMOTE_FENCE_I 5 -#define SBI_REMOTE_SFENCE_VMA 6 -#define SBI_REMOTE_SFENCE_VMA_ASID 7 -#define SBI_SHUTDOWN 8 - -#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ - register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ - asm volatile ("ecall" \ - : "+r" (a0) \ - : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ - : "memory"); \ - a0; \ -}) - -/* Lazy implementations until SBI is finalized */ -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) -#define SBI_CALL_3(which, arg0, arg1, arg2) \ - SBI_CALL(which, arg0, arg1, arg2, 0) -#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ - SBI_CALL(which, arg0, arg1, arg2, arg3) - -static inline void sbi_console_putchar(int ch) -{ - SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); -} +enum sbi_ext_id { +#ifdef CONFIG_RISCV_SBI_V01 + SBI_EXT_0_1_SET_TIMER = 0x0, + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, + SBI_EXT_0_1_CLEAR_IPI = 0x3, + SBI_EXT_0_1_SEND_IPI = 0x4, + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, + SBI_EXT_0_1_SHUTDOWN = 0x8, +#endif + SBI_EXT_BASE = 0x10, + SBI_EXT_TIME = 0x54494D45, + SBI_EXT_IPI = 0x735049, + SBI_EXT_RFENCE = 0x52464E43, + SBI_EXT_HSM = 0x48534D, +}; -static inline int sbi_console_getchar(void) -{ - return SBI_CALL_0(SBI_CONSOLE_GETCHAR); -} +enum sbi_ext_base_fid { + SBI_EXT_BASE_GET_SPEC_VERSION = 0, + SBI_EXT_BASE_GET_IMP_ID, + SBI_EXT_BASE_GET_IMP_VERSION, + SBI_EXT_BASE_PROBE_EXT, + SBI_EXT_BASE_GET_MVENDORID, + SBI_EXT_BASE_GET_MARCHID, + SBI_EXT_BASE_GET_MIMPID, +}; -static inline void sbi_set_timer(uint64_t stime_value) -{ -#if __riscv_xlen == 32 - SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); -#else - SBI_CALL_1(SBI_SET_TIMER, stime_value); -#endif -} +enum sbi_ext_time_fid { + SBI_EXT_TIME_SET_TIMER = 0, +}; -static inline void sbi_shutdown(void) -{ - SBI_CALL_0(SBI_SHUTDOWN); -} +enum sbi_ext_ipi_fid { + SBI_EXT_IPI_SEND_IPI = 0, +}; -static inline void sbi_clear_ipi(void) -{ - SBI_CALL_0(SBI_CLEAR_IPI); -} +enum sbi_ext_rfence_fid { + SBI_EXT_RFENCE_REMOTE_FENCE_I = 0, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, +}; -static inline void sbi_send_ipi(const unsigned long *hart_mask) -{ - SBI_CALL_1(SBI_SEND_IPI, hart_mask); -} +enum sbi_ext_hsm_fid { + SBI_EXT_HSM_HART_START = 0, + SBI_EXT_HSM_HART_STOP, + SBI_EXT_HSM_HART_STATUS, +}; + +enum sbi_hsm_hart_status { + SBI_HSM_HART_STATUS_STARTED = 0, + SBI_HSM_HART_STATUS_STOPPED, + SBI_HSM_HART_STATUS_START_PENDING, + SBI_HSM_HART_STATUS_STOP_PENDING, +}; + +#define SBI_SPEC_VERSION_DEFAULT 0x1 +#define SBI_SPEC_VERSION_MAJOR_SHIFT 24 +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff + +/* SBI return error codes */ +#define SBI_SUCCESS 0 +#define SBI_ERR_FAILURE -1 +#define SBI_ERR_NOT_SUPPORTED -2 +#define SBI_ERR_INVALID_PARAM -3 +#define SBI_ERR_DENIED -4 +#define SBI_ERR_INVALID_ADDRESS -5 -static inline void sbi_remote_fence_i(const unsigned long *hart_mask) +extern unsigned long sbi_spec_version; +struct sbiret { + long error; + long value; +}; + +int sbi_init(void); +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5); + +void sbi_console_putchar(int ch); +int sbi_console_getchar(void); +void sbi_set_timer(uint64_t stime_value); +void sbi_shutdown(void); +void sbi_clear_ipi(void); +void sbi_send_ipi(const unsigned long *hart_mask); +void sbi_remote_fence_i(const unsigned long *hart_mask); +void sbi_remote_sfence_vma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); + +void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid); +int sbi_remote_hfence_gvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); +int sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long vmid); +int sbi_remote_hfence_vvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); +int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid); +int sbi_probe_extension(int ext); + +/* Check if current SBI specification version is 0.1 or not */ +static inline int sbi_spec_is_0_1(void) { - SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); + return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT) ? 1 : 0; } -static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, - unsigned long start, - unsigned long size) +/* Get the major version of SBI */ +static inline unsigned long sbi_major_version(void) { - SBI_CALL_3(SBI_REMOTE_SFENCE_VMA, hart_mask, start, size); + return (sbi_spec_version >> SBI_SPEC_VERSION_MAJOR_SHIFT) & + SBI_SPEC_VERSION_MAJOR_MASK; } -static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, - unsigned long start, - unsigned long size, - unsigned long asid) +/* Get the minor version of SBI */ +static inline unsigned long sbi_minor_version(void) { - SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid); + return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK; } + +int sbi_err_map_linux_errno(int err); #else /* CONFIG_RISCV_SBI */ /* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */ void sbi_set_timer(uint64_t stime_value); void sbi_clear_ipi(void); void sbi_send_ipi(const unsigned long *hart_mask); void sbi_remote_fence_i(const unsigned long *hart_mask); +void sbi_init(void); #endif /* CONFIG_RISCV_SBI */ #endif /* _ASM_RISCV_SBI_H */ diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h new file mode 100644 index 000000000000..c38df4771c09 --- /dev/null +++ b/arch/riscv/include/asm/set_memory.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2019 SiFive + */ + +#ifndef _ASM_RISCV_SET_MEMORY_H +#define _ASM_RISCV_SET_MEMORY_H + +#ifndef __ASSEMBLY__ +/* + * Functions to change memory attributes. + */ +#ifdef CONFIG_MMU +int set_memory_ro(unsigned long addr, int numpages); +int set_memory_rw(unsigned long addr, int numpages); +int set_memory_x(unsigned long addr, int numpages); +int set_memory_nx(unsigned long addr, int numpages); +#else +static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; } +static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; } +static inline int set_memory_x(unsigned long addr, int numpages) { return 0; } +static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } +#endif + +#ifdef CONFIG_STRICT_KERNEL_RWX +void set_kernel_text_ro(void); +void set_kernel_text_rw(void); +#else +static inline void set_kernel_text_ro(void) { } +static inline void set_kernel_text_rw(void) { } +#endif + +int set_direct_map_invalid_noflush(struct page *page); +int set_direct_map_default_noflush(struct page *page); + +#endif /* __ASSEMBLY__ */ + +#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX +#ifdef CONFIG_64BIT +#define SECTION_ALIGN (1 << 21) +#else +#define SECTION_ALIGN (1 << 22) +#endif +#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ +#define SECTION_ALIGN L1_CACHE_BYTES +#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ + +#endif /* _ASM_RISCV_SET_MEMORY_H */ diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h index a83451d73a4e..f4c7cfda6b7f 100644 --- a/arch/riscv/include/asm/smp.h +++ b/arch/riscv/include/asm/smp.h @@ -43,6 +43,13 @@ void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); */ #define raw_smp_processor_id() (current_thread_info()->cpu) +#if defined CONFIG_HOTPLUG_CPU +int __cpu_disable(void); +void __cpu_die(unsigned int cpu); +void cpu_stop(void); +#else +#endif /* CONFIG_HOTPLUG_CPU */ + #else static inline void show_ipi_stats(struct seq_file *p, int prec) @@ -61,5 +68,22 @@ static inline unsigned long cpuid_to_hartid_map(int cpu) return boot_cpu_hartid; } +static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, + struct cpumask *out) +{ + cpumask_clear(out); + cpumask_set_cpu(boot_cpu_hartid, out); +} + #endif /* CONFIG_SMP */ + +#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP) +bool cpu_has_hotplug(unsigned int cpu); +#else +static inline bool cpu_has_hotplug(unsigned int cpu) +{ + return false; +} +#endif + #endif /* _ASM_RISCV_SMP_H */ diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h new file mode 100644 index 000000000000..7cec1968c8b4 --- /dev/null +++ b/arch/riscv/include/asm/soc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ + +#ifndef _ASM_RISCV_SOC_H +#define _ASM_RISCV_SOC_H + +#include <linux/of.h> +#include <linux/linkage.h> +#include <linux/types.h> + +#define SOC_EARLY_INIT_DECLARE(name, compat, fn) \ + static const struct of_device_id __soc_early_init__##name \ + __used __section(__soc_early_init_table) \ + = { .compatible = compat, .data = fn } + +void soc_early_init(void); + +extern unsigned long __soc_early_init_table_start; +extern unsigned long __soc_early_init_table_end; + +#endif diff --git a/arch/riscv/kernel/.gitignore b/arch/riscv/kernel/.gitignore index b51634f6a7cd..e052ed331cc1 100644 --- a/arch/riscv/kernel/.gitignore +++ b/arch/riscv/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only /vmlinux.lds diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index f40205cb9a22..86c83081044f 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -4,12 +4,14 @@ # ifdef CONFIG_FTRACE -CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_patch.o = -pg endif extra-y += head.o extra-y += vmlinux.lds +obj-y += soc.o obj-y += cpu.o obj-y += cpufeature.o obj-y += entry.o @@ -26,12 +28,15 @@ obj-y += traps.o obj-y += riscv_ksyms.o obj-y += stacktrace.o obj-y += cacheinfo.o +obj-y += patch.o obj-$(CONFIG_MMU) += vdso.o vdso/ -obj-$(CONFIG_RISCV_M_MODE) += clint.o +obj-$(CONFIG_RISCV_M_MODE) += clint.o traps_misaligned.o obj-$(CONFIG_FPU) += fpu.o obj-$(CONFIG_SMP) += smpboot.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SMP) += cpu_ops.o +obj-$(CONFIG_SMP) += cpu_ops_spinwait.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o @@ -42,5 +47,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o obj-$(CONFIG_RISCV_SBI) += sbi.o +ifeq ($(CONFIG_RISCV_SBI), y) +obj-$(CONFIG_SMP) += cpu_ops_sbi.o +endif +obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o clean: diff --git a/arch/riscv/kernel/cpu-hotplug.c b/arch/riscv/kernel/cpu-hotplug.c new file mode 100644 index 000000000000..df84e0c13db1 --- /dev/null +++ b/arch/riscv/kernel/cpu-hotplug.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ + +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/err.h> +#include <linux/irq.h> +#include <linux/cpu.h> +#include <linux/sched/hotplug.h> +#include <asm/irq.h> +#include <asm/cpu_ops.h> +#include <asm/sbi.h> + +void cpu_stop(void); +void arch_cpu_idle_dead(void) +{ + cpu_stop(); +} + +bool cpu_has_hotplug(unsigned int cpu) +{ + if (cpu_ops[cpu]->cpu_stop) + return true; + + return false; +} + +/* + * __cpu_disable runs on the processor to be shutdown. + */ +int __cpu_disable(void) +{ + int ret = 0; + unsigned int cpu = smp_processor_id(); + + if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_stop) + return -EOPNOTSUPP; + + if (cpu_ops[cpu]->cpu_disable) + ret = cpu_ops[cpu]->cpu_disable(cpu); + + if (ret) + return ret; + + remove_cpu_topology(cpu); + set_cpu_online(cpu, false); + irq_migrate_all_off_this_cpu(); + + return ret; +} + +/* + * Called on the thread which is asking for a CPU to be shutdown. + */ +void __cpu_die(unsigned int cpu) +{ + int ret = 0; + + if (!cpu_wait_death(cpu, 5)) { + pr_err("CPU %u: didn't die\n", cpu); + return; + } + pr_notice("CPU%u: off\n", cpu); + + /* Verify from the firmware if the cpu is really stopped*/ + if (cpu_ops[cpu]->cpu_is_stopped) + ret = cpu_ops[cpu]->cpu_is_stopped(cpu); + if (ret) + pr_warn("CPU%d may not have stopped: %d\n", cpu, ret); +} + +/* + * Called from the idle thread for the CPU which has been shutdown. + */ +void cpu_stop(void) +{ + idle_task_exit(); + + (void)cpu_report_death(); + + cpu_ops[smp_processor_id()]->cpu_stop(); + /* It should never reach here */ + BUG(); +} diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c new file mode 100644 index 000000000000..c4c33bf02369 --- /dev/null +++ b/arch/riscv/kernel/cpu_ops.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ + +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/of.h> +#include <linux/string.h> +#include <linux/sched.h> +#include <linux/sched/task_stack.h> +#include <asm/cpu_ops.h> +#include <asm/sbi.h> +#include <asm/smp.h> + +const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init; + +void *__cpu_up_stack_pointer[NR_CPUS]; +void *__cpu_up_task_pointer[NR_CPUS]; + +extern const struct cpu_operations cpu_ops_sbi; +extern const struct cpu_operations cpu_ops_spinwait; + +void cpu_update_secondary_bootdata(unsigned int cpuid, + struct task_struct *tidle) +{ + int hartid = cpuid_to_hartid_map(cpuid); + + /* Make sure tidle is updated */ + smp_mb(); + WRITE_ONCE(__cpu_up_stack_pointer[hartid], + task_stack_page(tidle) + THREAD_SIZE); + WRITE_ONCE(__cpu_up_task_pointer[hartid], tidle); +} + +void __init cpu_set_ops(int cpuid) +{ +#if IS_ENABLED(CONFIG_RISCV_SBI) + if (sbi_probe_extension(SBI_EXT_HSM) > 0) { + if (!cpuid) + pr_info("SBI v0.2 HSM extension detected\n"); + cpu_ops[cpuid] = &cpu_ops_sbi; + } else +#endif + cpu_ops[cpuid] = &cpu_ops_spinwait; +} diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c new file mode 100644 index 000000000000..685fae72b7f5 --- /dev/null +++ b/arch/riscv/kernel/cpu_ops_sbi.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * HSM extension and cpu_ops implementation. + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ + +#include <linux/init.h> +#include <linux/mm.h> +#include <asm/cpu_ops.h> +#include <asm/sbi.h> +#include <asm/smp.h> + +extern char secondary_start_sbi[]; +const struct cpu_operations cpu_ops_sbi; + +static int sbi_hsm_hart_start(unsigned long hartid, unsigned long saddr, + unsigned long priv) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, + hartid, saddr, priv, 0, 0, 0); + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return 0; +} + +#ifdef CONFIG_HOTPLUG_CPU +static int sbi_hsm_hart_stop(void) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP, 0, 0, 0, 0, 0, 0); + + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return 0; +} + +static int sbi_hsm_hart_get_status(unsigned long hartid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_STATUS, + hartid, 0, 0, 0, 0, 0); + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return ret.value; +} +#endif + +static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle) +{ + int rc; + unsigned long boot_addr = __pa_symbol(secondary_start_sbi); + int hartid = cpuid_to_hartid_map(cpuid); + + cpu_update_secondary_bootdata(cpuid, tidle); + rc = sbi_hsm_hart_start(hartid, boot_addr, 0); + + return rc; +} + +static int sbi_cpu_prepare(unsigned int cpuid) +{ + if (!cpu_ops_sbi.cpu_start) { + pr_err("cpu start method not defined for CPU [%d]\n", cpuid); + return -ENODEV; + } + return 0; +} + +#ifdef CONFIG_HOTPLUG_CPU +static int sbi_cpu_disable(unsigned int cpuid) +{ + if (!cpu_ops_sbi.cpu_stop) + return -EOPNOTSUPP; + return 0; +} + +static void sbi_cpu_stop(void) +{ + int ret; + + ret = sbi_hsm_hart_stop(); + pr_crit("Unable to stop the cpu %u (%d)\n", smp_processor_id(), ret); +} + +static int sbi_cpu_is_stopped(unsigned int cpuid) +{ + int rc; + int hartid = cpuid_to_hartid_map(cpuid); + + rc = sbi_hsm_hart_get_status(hartid); + + if (rc == SBI_HSM_HART_STATUS_STOPPED) + return 0; + return rc; +} +#endif + +const struct cpu_operations cpu_ops_sbi = { + .name = "sbi", + .cpu_prepare = sbi_cpu_prepare, + .cpu_start = sbi_cpu_start, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = sbi_cpu_disable, + .cpu_stop = sbi_cpu_stop, + .cpu_is_stopped = sbi_cpu_is_stopped, +#endif +}; diff --git a/arch/riscv/kernel/cpu_ops_spinwait.c b/arch/riscv/kernel/cpu_ops_spinwait.c new file mode 100644 index 000000000000..b2c957bb68c1 --- /dev/null +++ b/arch/riscv/kernel/cpu_ops_spinwait.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ + +#include <linux/errno.h> +#include <linux/of.h> +#include <linux/string.h> +#include <asm/cpu_ops.h> +#include <asm/sbi.h> +#include <asm/smp.h> + +const struct cpu_operations cpu_ops_spinwait; + +static int spinwait_cpu_prepare(unsigned int cpuid) +{ + if (!cpu_ops_spinwait.cpu_start) { + pr_err("cpu start method not defined for CPU [%d]\n", cpuid); + return -ENODEV; + } + return 0; +} + +static int spinwait_cpu_start(unsigned int cpuid, struct task_struct *tidle) +{ + /* + * In this protocol, all cpus boot on their own accord. _start + * selects the first cpu to boot the kernel and causes the remainder + * of the cpus to spin in a loop waiting for their stack pointer to be + * setup by that main cpu. Writing to bootdata + * (i.e __cpu_up_stack_pointer) signals to the spinning cpus that they + * can continue the boot process. + */ + cpu_update_secondary_bootdata(cpuid, tidle); + + return 0; +} + +const struct cpu_operations cpu_ops_spinwait = { + .name = "spinwait", + .cpu_prepare = spinwait_cpu_prepare, + .cpu_start = spinwait_cpu_start, +}; diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 208702d8c18e..56d071b2c0a1 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -13,17 +13,11 @@ #include <asm/thread_info.h> #include <asm/asm-offsets.h> - .text - .altmacro - -/* - * Prepares to enter a system call or exception by saving all registers to the - * stack. - */ - .macro SAVE_ALL - LOCAL _restore_kernel_tpsp - LOCAL _save_context +#if !IS_ENABLED(CONFIG_PREEMPTION) +.set resume_kernel, restore_all +#endif +ENTRY(handle_exception) /* * If coming from userspace, preserve the user thread pointer and load * the kernel thread pointer. If we came from the kernel, the scratch @@ -90,77 +84,6 @@ _save_context: REG_S s3, PT_BADADDR(sp) REG_S s4, PT_CAUSE(sp) REG_S s5, PT_TP(sp) - .endm - -/* - * Prepares to return from a system call or exception by restoring all - * registers from the stack. - */ - .macro RESTORE_ALL - REG_L a0, PT_STATUS(sp) - /* - * The current load reservation is effectively part of the processor's - * state, in the sense that load reservations cannot be shared between - * different hart contexts. We can't actually save and restore a load - * reservation, so instead here we clear any existing reservation -- - * it's always legal for implementations to clear load reservations at - * any point (as long as the forward progress guarantee is kept, but - * we'll ignore that here). - * - * Dangling load reservations can be the result of taking a trap in the - * middle of an LR/SC sequence, but can also be the result of a taken - * forward branch around an SC -- which is how we implement CAS. As a - * result we need to clear reservations between the last CAS and the - * jump back to the new context. While it is unlikely the store - * completes, implementations are allowed to expand reservations to be - * arbitrarily large. - */ - REG_L a2, PT_EPC(sp) - REG_SC x0, a2, PT_EPC(sp) - - csrw CSR_STATUS, a0 - csrw CSR_EPC, a2 - - REG_L x1, PT_RA(sp) - REG_L x3, PT_GP(sp) - REG_L x4, PT_TP(sp) - REG_L x5, PT_T0(sp) - REG_L x6, PT_T1(sp) - REG_L x7, PT_T2(sp) - REG_L x8, PT_S0(sp) - REG_L x9, PT_S1(sp) - REG_L x10, PT_A0(sp) - REG_L x11, PT_A1(sp) - REG_L x12, PT_A2(sp) - REG_L x13, PT_A3(sp) - REG_L x14, PT_A4(sp) - REG_L x15, PT_A5(sp) - REG_L x16, PT_A6(sp) - REG_L x17, PT_A7(sp) - REG_L x18, PT_S2(sp) - REG_L x19, PT_S3(sp) - REG_L x20, PT_S4(sp) - REG_L x21, PT_S5(sp) - REG_L x22, PT_S6(sp) - REG_L x23, PT_S7(sp) - REG_L x24, PT_S8(sp) - REG_L x25, PT_S9(sp) - REG_L x26, PT_S10(sp) - REG_L x27, PT_S11(sp) - REG_L x28, PT_T3(sp) - REG_L x29, PT_T4(sp) - REG_L x30, PT_T5(sp) - REG_L x31, PT_T6(sp) - - REG_L x2, PT_SP(sp) - .endm - -#if !IS_ENABLED(CONFIG_PREEMPTION) -.set resume_kernel, restore_all -#endif - -ENTRY(handle_exception) - SAVE_ALL /* * Set the scratch register to 0, so that if a recursive exception @@ -291,7 +214,63 @@ resume_userspace: csrw CSR_SCRATCH, tp restore_all: - RESTORE_ALL + REG_L a0, PT_STATUS(sp) + /* + * The current load reservation is effectively part of the processor's + * state, in the sense that load reservations cannot be shared between + * different hart contexts. We can't actually save and restore a load + * reservation, so instead here we clear any existing reservation -- + * it's always legal for implementations to clear load reservations at + * any point (as long as the forward progress guarantee is kept, but + * we'll ignore that here). + * + * Dangling load reservations can be the result of taking a trap in the + * middle of an LR/SC sequence, but can also be the result of a taken + * forward branch around an SC -- which is how we implement CAS. As a + * result we need to clear reservations between the last CAS and the + * jump back to the new context. While it is unlikely the store + * completes, implementations are allowed to expand reservations to be + * arbitrarily large. + */ + REG_L a2, PT_EPC(sp) + REG_SC x0, a2, PT_EPC(sp) + + csrw CSR_STATUS, a0 + csrw CSR_EPC, a2 + + REG_L x1, PT_RA(sp) + REG_L x3, PT_GP(sp) + REG_L x4, PT_TP(sp) + REG_L x5, PT_T0(sp) + REG_L x6, PT_T1(sp) + REG_L x7, PT_T2(sp) + REG_L x8, PT_S0(sp) + REG_L x9, PT_S1(sp) + REG_L x10, PT_A0(sp) + REG_L x11, PT_A1(sp) + REG_L x12, PT_A2(sp) + REG_L x13, PT_A3(sp) + REG_L x14, PT_A4(sp) + REG_L x15, PT_A5(sp) + REG_L x16, PT_A6(sp) + REG_L x17, PT_A7(sp) + REG_L x18, PT_S2(sp) + REG_L x19, PT_S3(sp) + REG_L x20, PT_S4(sp) + REG_L x21, PT_S5(sp) + REG_L x22, PT_S6(sp) + REG_L x23, PT_S7(sp) + REG_L x24, PT_S8(sp) + REG_L x25, PT_S9(sp) + REG_L x26, PT_S10(sp) + REG_L x27, PT_S11(sp) + REG_L x28, PT_T3(sp) + REG_L x29, PT_T4(sp) + REG_L x30, PT_T5(sp) + REG_L x31, PT_T6(sp) + + REG_L x2, PT_SP(sp) + #ifdef CONFIG_RISCV_M_MODE mret #else diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index c40fdcdeb950..ce69b34ff55d 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -8,6 +8,7 @@ #include <linux/ftrace.h> #include <linux/uaccess.h> #include <asm/cacheflush.h> +#include <asm/patch.h> #ifdef CONFIG_DYNAMIC_FTRACE static int ftrace_check_current_call(unsigned long hook_pos, @@ -46,20 +47,14 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, { unsigned int call[2]; unsigned int nops[2] = {NOP4, NOP4}; - int ret = 0; make_call(hook_pos, target, call); - /* replace the auipc-jalr pair at once */ - ret = probe_kernel_write((void *)hook_pos, enable ? call : nops, - MCOUNT_INSN_SIZE); - /* return must be -EPERM on write error */ - if (ret) + /* Replace the auipc-jalr pair at once. Return -EPERM on write error. */ + if (riscv_patch_text_nosync + ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE)) return -EPERM; - smp_mb(); - flush_icache_range((void *)hook_pos, (void *)hook_pos + MCOUNT_INSN_SIZE); - return 0; } diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 85f2073e7fe4..98a406474e7d 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -14,7 +14,7 @@ #include <asm/hwcap.h> #include <asm/image.h> -__INIT +__HEAD ENTRY(_start) /* * Image header expected by Linux boot-loaders. The image header data @@ -45,8 +45,111 @@ ENTRY(_start) .ascii RISCV_IMAGE_MAGIC2 .word 0 -.global _start_kernel -_start_kernel: +.align 2 +#ifdef CONFIG_MMU +relocate: + /* Relocate return address */ + li a1, PAGE_OFFSET + la a2, _start + sub a1, a1, a2 + add ra, ra, a1 + + /* Point stvec to virtual address of intruction after satp write */ + la a2, 1f + add a2, a2, a1 + csrw CSR_TVEC, a2 + + /* Compute satp for kernel page tables, but don't load it yet */ + srl a2, a0, PAGE_SHIFT + li a1, SATP_MODE + or a2, a2, a1 + + /* + * Load trampoline page directory, which will cause us to trap to + * stvec if VA != PA, or simply fall through if VA == PA. We need a + * full fence here because setup_vm() just wrote these PTEs and we need + * to ensure the new translations are in use. + */ + la a0, trampoline_pg_dir + srl a0, a0, PAGE_SHIFT + or a0, a0, a1 + sfence.vma + csrw CSR_SATP, a0 +.align 2 +1: + /* Set trap vector to spin forever to help debug */ + la a0, .Lsecondary_park + csrw CSR_TVEC, a0 + + /* Reload the global pointer */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* + * Switch to kernel page tables. A full fence is necessary in order to + * avoid using the trampoline translations, which are only correct for + * the first superpage. Fetching the fence is guarnteed to work + * because that first superpage is translated the same way. + */ + csrw CSR_SATP, a2 + sfence.vma + + ret +#endif /* CONFIG_MMU */ +#ifdef CONFIG_SMP + .global secondary_start_sbi +secondary_start_sbi: + /* Mask all interrupts */ + csrw CSR_IE, zero + csrw CSR_IP, zero + + /* Load the global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + /* + * Disable FPU to detect illegal usage of + * floating point in kernel space + */ + li t0, SR_FS + csrc CSR_STATUS, t0 + + /* Set trap vector to spin forever to help debug */ + la a3, .Lsecondary_park + csrw CSR_TVEC, a3 + + slli a3, a0, LGREG + la a4, __cpu_up_stack_pointer + la a5, __cpu_up_task_pointer + add a4, a3, a4 + add a5, a3, a5 + REG_L sp, (a4) + REG_L tp, (a5) + + .global secondary_start_common +secondary_start_common: + +#ifdef CONFIG_MMU + /* Enable virtual memory and relocate to virtual address */ + la a0, swapper_pg_dir + call relocate +#endif + tail smp_callin +#endif /* CONFIG_SMP */ + +.Lsecondary_park: + /* We lack SMP support or have too many harts, so park this hart */ + wfi + j .Lsecondary_park + +END(_start) + + __INIT +ENTRY(_start_kernel) /* Mask all interrupts */ csrw CSR_IE, zero csrw CSR_IP, zero @@ -131,62 +234,10 @@ clear_bss_done: call kasan_early_init #endif /* Start the kernel */ + call soc_early_init call parse_dtb tail start_kernel -#ifdef CONFIG_MMU -relocate: - /* Relocate return address */ - li a1, PAGE_OFFSET - la a2, _start - sub a1, a1, a2 - add ra, ra, a1 - - /* Point stvec to virtual address of intruction after satp write */ - la a2, 1f - add a2, a2, a1 - csrw CSR_TVEC, a2 - - /* Compute satp for kernel page tables, but don't load it yet */ - srl a2, a0, PAGE_SHIFT - li a1, SATP_MODE - or a2, a2, a1 - - /* - * Load trampoline page directory, which will cause us to trap to - * stvec if VA != PA, or simply fall through if VA == PA. We need a - * full fence here because setup_vm() just wrote these PTEs and we need - * to ensure the new translations are in use. - */ - la a0, trampoline_pg_dir - srl a0, a0, PAGE_SHIFT - or a0, a0, a1 - sfence.vma - csrw CSR_SATP, a0 -.align 2 -1: - /* Set trap vector to spin forever to help debug */ - la a0, .Lsecondary_park - csrw CSR_TVEC, a0 - - /* Reload the global pointer */ -.option push -.option norelax - la gp, __global_pointer$ -.option pop - - /* - * Switch to kernel page tables. A full fence is necessary in order to - * avoid using the trampoline translations, which are only correct for - * the first superpage. Fetching the fence is guarnteed to work - * because that first superpage is translated the same way. - */ - csrw CSR_SATP, a2 - sfence.vma - - ret -#endif /* CONFIG_MMU */ - .Lsecondary_start: #ifdef CONFIG_SMP /* Set trap vector to spin forever to help debug */ @@ -211,16 +262,10 @@ relocate: beqz tp, .Lwait_for_cpu_up fence -#ifdef CONFIG_MMU - /* Enable virtual memory and relocate to virtual address */ - la a0, swapper_pg_dir - call relocate + tail secondary_start_common #endif - tail smp_callin -#endif - -END(_start) +END(_start_kernel) #ifdef CONFIG_RISCV_M_MODE ENTRY(reset_regs) @@ -301,13 +346,6 @@ ENTRY(reset_regs) END(reset_regs) #endif /* CONFIG_RISCV_M_MODE */ -.section ".text", "ax",@progbits -.align 2 -.Lsecondary_park: - /* We lack SMP support or have too many harts, so park this hart */ - wfi - j .Lsecondary_park - __PAGE_ALIGNED_BSS /* Empty zero page */ .balign PAGE_SIZE diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c new file mode 100644 index 000000000000..8a4fc65ee022 --- /dev/null +++ b/arch/riscv/kernel/patch.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 SiFive + */ + +#include <linux/spinlock.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/stop_machine.h> +#include <asm/kprobes.h> +#include <asm/cacheflush.h> +#include <asm/fixmap.h> + +struct riscv_insn_patch { + void *addr; + u32 insn; + atomic_t cpu_count; +}; + +#ifdef CONFIG_MMU +static DEFINE_RAW_SPINLOCK(patch_lock); + +static void __kprobes *patch_map(void *addr, int fixmap) +{ + uintptr_t uintaddr = (uintptr_t) addr; + struct page *page; + + if (core_kernel_text(uintaddr)) + page = phys_to_page(__pa_symbol(addr)); + else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + page = vmalloc_to_page(addr); + else + return addr; + + BUG_ON(!page); + + return (void *)set_fixmap_offset(fixmap, page_to_phys(page) + + (uintaddr & ~PAGE_MASK)); +} + +static void __kprobes patch_unmap(int fixmap) +{ + clear_fixmap(fixmap); +} + +static int __kprobes riscv_insn_write(void *addr, const void *insn, size_t len) +{ + void *waddr = addr; + bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE; + unsigned long flags = 0; + int ret; + + raw_spin_lock_irqsave(&patch_lock, flags); + + if (across_pages) + patch_map(addr + len, FIX_TEXT_POKE1); + + waddr = patch_map(addr, FIX_TEXT_POKE0); + + ret = probe_kernel_write(waddr, insn, len); + + patch_unmap(FIX_TEXT_POKE0); + + if (across_pages) + patch_unmap(FIX_TEXT_POKE1); + + raw_spin_unlock_irqrestore(&patch_lock, flags); + + return ret; +} +#else +static int __kprobes riscv_insn_write(void *addr, const void *insn, size_t len) +{ + return probe_kernel_write(addr, insn, len); +} +#endif /* CONFIG_MMU */ + +int __kprobes riscv_patch_text_nosync(void *addr, const void *insns, size_t len) +{ + u32 *tp = addr; + int ret; + + ret = riscv_insn_write(tp, insns, len); + + if (!ret) + flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len); + + return ret; +} + +static int __kprobes riscv_patch_text_cb(void *data) +{ + struct riscv_insn_patch *patch = data; + int ret = 0; + + if (atomic_inc_return(&patch->cpu_count) == 1) { + ret = + riscv_patch_text_nosync(patch->addr, &patch->insn, + GET_INSN_LENGTH(patch->insn)); + atomic_inc(&patch->cpu_count); + } else { + while (atomic_read(&patch->cpu_count) <= num_online_cpus()) + cpu_relax(); + smp_mb(); + } + + return ret; +} + +int __kprobes riscv_patch_text(void *addr, u32 insn) +{ + struct riscv_insn_patch patch = { + .addr = addr, + .insn = insn, + .cpu_count = ATOMIC_INIT(0), + }; + + return stop_machine_cpuslocked(riscv_patch_text_cb, + &patch, cpu_online_mask); +} diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 817cf7b0974c..610c11e91606 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -22,6 +22,8 @@ #include <asm/switch_to.h> #include <asm/thread_info.h> +unsigned long gp_in_global __asm__("gp"); + extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_kernel_thread(void); @@ -107,9 +109,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp, /* p->thread holds context to be restored by __switch_to() */ if (unlikely(p->flags & PF_KTHREAD)) { /* Kernel thread */ - const register unsigned long gp __asm__ ("gp"); memset(childregs, 0, sizeof(struct pt_regs)); - childregs->gp = gp; + childregs->gp = gp_in_global; /* Supervisor/Machine, irqs on: */ childregs->status = SR_PP | SR_PIE; diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index f6c7c3e82d28..7c24da59bccf 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -1,17 +1,588 @@ // SPDX-License-Identifier: GPL-2.0-only +/* + * SBI initialilization and all extension implementation. + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ #include <linux/init.h> #include <linux/pm.h> #include <asm/sbi.h> +#include <asm/smp.h> + +/* default SBI version is 0.1 */ +unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT; +EXPORT_SYMBOL(sbi_spec_version); + +static void (*__sbi_set_timer)(uint64_t stime); +static int (*__sbi_send_ipi)(const unsigned long *hart_mask); +static int (*__sbi_rfence)(int fid, const unsigned long *hart_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5); + +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5) +{ + struct sbiret ret; + + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); + register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); + register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); + register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); + register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); + asm volatile ("ecall" + : "+r" (a0), "+r" (a1) + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) + : "memory"); + ret.error = a0; + ret.value = a1; + + return ret; +} +EXPORT_SYMBOL(sbi_ecall); + +int sbi_err_map_linux_errno(int err) +{ + switch (err) { + case SBI_SUCCESS: + return 0; + case SBI_ERR_DENIED: + return -EPERM; + case SBI_ERR_INVALID_PARAM: + return -EINVAL; + case SBI_ERR_INVALID_ADDRESS: + return -EFAULT; + case SBI_ERR_NOT_SUPPORTED: + case SBI_ERR_FAILURE: + default: + return -ENOTSUPP; + }; +} +EXPORT_SYMBOL(sbi_err_map_linux_errno); + +#ifdef CONFIG_RISCV_SBI_V01 +/** + * sbi_console_putchar() - Writes given character to the console device. + * @ch: The data to be written to the console. + * + * Return: None + */ +void sbi_console_putchar(int ch) +{ + sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch, 0, 0, 0, 0, 0); +} +EXPORT_SYMBOL(sbi_console_putchar); + +/** + * sbi_console_getchar() - Reads a byte from console device. + * + * Returns the value read from console. + */ +int sbi_console_getchar(void) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_0_1_CONSOLE_GETCHAR, 0, 0, 0, 0, 0, 0, 0); + + return ret.error; +} +EXPORT_SYMBOL(sbi_console_getchar); + +/** + * sbi_shutdown() - Remove all the harts from executing supervisor code. + * + * Return: None + */ +void sbi_shutdown(void) +{ + sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); +} +EXPORT_SYMBOL(sbi_set_timer); + +/** + * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. + * + * Return: None + */ +void sbi_clear_ipi(void) +{ + sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0); +} +EXPORT_SYMBOL(sbi_shutdown); + +/** + * sbi_set_timer_v01() - Program the timer for next timer event. + * @stime_value: The value after which next timer event should fire. + * + * Return: None + */ +static void __sbi_set_timer_v01(uint64_t stime_value) +{ +#if __riscv_xlen == 32 + sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, + stime_value >> 32, 0, 0, 0, 0); +#else + sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, 0, 0, 0, 0, 0); +#endif +} + +static int __sbi_send_ipi_v01(const unsigned long *hart_mask) +{ + sbi_ecall(SBI_EXT_0_1_SEND_IPI, 0, (unsigned long)hart_mask, + 0, 0, 0, 0, 0); + return 0; +} + +static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5) +{ + int result = 0; + + /* v0.2 function IDs are equivalent to v0.1 extension IDs */ + switch (fid) { + case SBI_EXT_RFENCE_REMOTE_FENCE_I: + sbi_ecall(SBI_EXT_0_1_REMOTE_FENCE_I, 0, + (unsigned long)hart_mask, 0, 0, 0, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: + sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA, 0, + (unsigned long)hart_mask, start, size, + 0, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: + sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, 0, + (unsigned long)hart_mask, start, size, + arg4, 0, 0); + break; + default: + pr_err("SBI call [%d]not supported in SBI v0.1\n", fid); + result = -EINVAL; + } + + return result; +} +#else +static void __sbi_set_timer_v01(uint64_t stime_value) +{ + pr_warn("Timer extension is not available in SBI v%lu.%lu\n", + sbi_major_version(), sbi_minor_version()); +} + +static int __sbi_send_ipi_v01(const unsigned long *hart_mask) +{ + pr_warn("IPI extension is not available in SBI v%lu.%lu\n", + sbi_major_version(), sbi_minor_version()); + + return 0; +} + +static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5) +{ + pr_warn("remote fence extension is not available in SBI v%lu.%lu\n", + sbi_major_version(), sbi_minor_version()); + + return 0; +} +#endif /* CONFIG_RISCV_SBI_V01 */ + +static void __sbi_set_timer_v02(uint64_t stime_value) +{ +#if __riscv_xlen == 32 + sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, + stime_value >> 32, 0, 0, 0, 0); +#else + sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, + 0, 0, 0, 0); +#endif +} + +static int __sbi_send_ipi_v02(const unsigned long *hart_mask) +{ + unsigned long hartid, hmask_val, hbase; + struct cpumask tmask; + struct sbiret ret = {0}; + int result; + + if (!hart_mask || !(*hart_mask)) { + riscv_cpuid_to_hartid_mask(cpu_online_mask, &tmask); + hart_mask = cpumask_bits(&tmask); + } + + hmask_val = 0; + hbase = 0; + for_each_set_bit(hartid, hart_mask, NR_CPUS) { + if (hmask_val && ((hbase + BITS_PER_LONG) <= hartid)) { + ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, + hmask_val, hbase, 0, 0, 0, 0); + if (ret.error) + goto ecall_failed; + hmask_val = 0; + hbase = 0; + } + if (!hmask_val) + hbase = hartid; + hmask_val |= 1UL << (hartid - hbase); + } + + if (hmask_val) { + ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, + hmask_val, hbase, 0, 0, 0, 0); + if (ret.error) + goto ecall_failed; + } + + return 0; + +ecall_failed: + result = sbi_err_map_linux_errno(ret.error); + pr_err("%s: hbase = [%lu] hmask = [0x%lx] failed (error [%d])\n", + __func__, hbase, hmask_val, result); + return result; +} + +static int __sbi_rfence_v02_call(unsigned long fid, unsigned long hmask_val, + unsigned long hbase, unsigned long start, + unsigned long size, unsigned long arg4, + unsigned long arg5) +{ + struct sbiret ret = {0}; + int ext = SBI_EXT_RFENCE; + int result = 0; + + switch (fid) { + case SBI_EXT_RFENCE_REMOTE_FENCE_I: + ret = sbi_ecall(ext, fid, hmask_val, hbase, 0, 0, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, arg4, 0); + break; + + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, arg4, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: + ret = sbi_ecall(ext, fid, hmask_val, hbase, start, + size, arg4, 0); + break; + default: + pr_err("unknown function ID [%lu] for SBI extension [%d]\n", + fid, ext); + result = -EINVAL; + } + + if (ret.error) { + result = sbi_err_map_linux_errno(ret.error); + pr_err("%s: hbase = [%lu] hmask = [0x%lx] failed (error [%d])\n", + __func__, hbase, hmask_val, result); + } + + return result; +} + +static int __sbi_rfence_v02(int fid, const unsigned long *hart_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5) +{ + unsigned long hmask_val, hartid, hbase; + struct cpumask tmask; + int result; + + if (!hart_mask || !(*hart_mask)) { + riscv_cpuid_to_hartid_mask(cpu_online_mask, &tmask); + hart_mask = cpumask_bits(&tmask); + } + + hmask_val = 0; + hbase = 0; + for_each_set_bit(hartid, hart_mask, NR_CPUS) { + if (hmask_val && ((hbase + BITS_PER_LONG) <= hartid)) { + result = __sbi_rfence_v02_call(fid, hmask_val, hbase, + start, size, arg4, arg5); + if (result) + return result; + hmask_val = 0; + hbase = 0; + } + if (!hmask_val) + hbase = hartid; + hmask_val |= 1UL << (hartid - hbase); + } + + if (hmask_val) { + result = __sbi_rfence_v02_call(fid, hmask_val, hbase, + start, size, arg4, arg5); + if (result) + return result; + } + + return 0; +} + +/** + * sbi_set_timer() - Program the timer for next timer event. + * @stime_value: The value after which next timer event should fire. + * + * Return: None + */ +void sbi_set_timer(uint64_t stime_value) +{ + __sbi_set_timer(stime_value); +} + +/** + * sbi_send_ipi() - Send an IPI to any hart. + * @hart_mask: A cpu mask containing all the target harts. + * + * Return: None + */ +void sbi_send_ipi(const unsigned long *hart_mask) +{ + __sbi_send_ipi(hart_mask); +} +EXPORT_SYMBOL(sbi_send_ipi); + +/** + * sbi_remote_fence_i() - Execute FENCE.I instruction on given remote harts. + * @hart_mask: A cpu mask containing all the target harts. + * + * Return: None + */ +void sbi_remote_fence_i(const unsigned long *hart_mask) +{ + __sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I, + hart_mask, 0, 0, 0, 0); +} +EXPORT_SYMBOL(sbi_remote_fence_i); + +/** + * sbi_remote_sfence_vma() - Execute SFENCE.VMA instructions on given remote + * harts for the specified virtual address range. + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the virtual address + * @size: Total size of the virtual address range. + * + * Return: None + */ +void sbi_remote_sfence_vma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size) +{ + __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + hart_mask, start, size, 0, 0); +} +EXPORT_SYMBOL(sbi_remote_sfence_vma); + +/** + * sbi_remote_sfence_vma_asid() - Execute SFENCE.VMA instructions on given + * remote harts for a virtual address range belonging to a specific ASID. + * + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the virtual address + * @size: Total size of the virtual address range. + * @asid: The value of address space identifier (ASID). + * + * Return: None + */ +void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid) +{ + __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, + hart_mask, start, size, asid, 0); +} +EXPORT_SYMBOL(sbi_remote_sfence_vma_asid); + +/** + * sbi_remote_hfence_gvma() - Execute HFENCE.GVMA instructions on given remote + * harts for the specified guest physical address range. + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the guest physical address + * @size: Total size of the guest physical address range. + * + * Return: None + */ +int sbi_remote_hfence_gvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + hart_mask, start, size, 0, 0); +} +EXPORT_SYMBOL_GPL(sbi_remote_hfence_gvma); + +/** + * sbi_remote_hfence_gvma_vmid() - Execute HFENCE.GVMA instructions on given + * remote harts for a guest physical address range belonging to a specific VMID. + * + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the guest physical address + * @size: Total size of the guest physical address range. + * @vmid: The value of guest ID (VMID). + * + * Return: 0 if success, Error otherwise. + */ +int sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long vmid) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, + hart_mask, start, size, vmid, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_gvma_vmid); + +/** + * sbi_remote_hfence_vvma() - Execute HFENCE.VVMA instructions on given remote + * harts for the current guest virtual address range. + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the current guest virtual address + * @size: Total size of the current guest virtual address range. + * + * Return: None + */ +int sbi_remote_hfence_vvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, + hart_mask, start, size, 0, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_vvma); + +/** + * sbi_remote_hfence_vvma_asid() - Execute HFENCE.VVMA instructions on given + * remote harts for current guest virtual address range belonging to a specific + * ASID. + * + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the current guest virtual address + * @size: Total size of the current guest virtual address range. + * @asid: The value of address space identifier (ASID). + * + * Return: None + */ +int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, + hart_mask, start, size, asid, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_vvma_asid); + +/** + * sbi_probe_extension() - Check if an SBI extension ID is supported or not. + * @extid: The extension ID to be probed. + * + * Return: Extension specific nonzero value f yes, -ENOTSUPP otherwise. + */ +int sbi_probe_extension(int extid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid, + 0, 0, 0, 0, 0); + if (!ret.error) + if (ret.value) + return ret.value; + + return -ENOTSUPP; +} +EXPORT_SYMBOL(sbi_probe_extension); + +static long __sbi_base_ecall(int fid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); + if (!ret.error) + return ret.value; + else + return sbi_err_map_linux_errno(ret.error); +} + +static inline long sbi_get_spec_version(void) +{ + return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION); +} + +static inline long sbi_get_firmware_id(void) +{ + return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); +} + +static inline long sbi_get_firmware_version(void) +{ + return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); +} static void sbi_power_off(void) { sbi_shutdown(); } -static int __init sbi_init(void) +int __init sbi_init(void) { + int ret; + pm_power_off = sbi_power_off; + ret = sbi_get_spec_version(); + if (ret > 0) + sbi_spec_version = ret; + + pr_info("SBI specification v%lu.%lu detected\n", + sbi_major_version(), sbi_minor_version()); + + if (!sbi_spec_is_0_1()) { + pr_info("SBI implementation ID=0x%lx Version=0x%lx\n", + sbi_get_firmware_id(), sbi_get_firmware_version()); + if (sbi_probe_extension(SBI_EXT_TIME) > 0) { + __sbi_set_timer = __sbi_set_timer_v02; + pr_info("SBI v0.2 TIME extension detected\n"); + } else { + __sbi_set_timer = __sbi_set_timer_v01; + } + if (sbi_probe_extension(SBI_EXT_IPI) > 0) { + __sbi_send_ipi = __sbi_send_ipi_v02; + pr_info("SBI v0.2 IPI extension detected\n"); + } else { + __sbi_send_ipi = __sbi_send_ipi_v01; + } + if (sbi_probe_extension(SBI_EXT_RFENCE) > 0) { + __sbi_rfence = __sbi_rfence_v02; + pr_info("SBI v0.2 RFENCE extension detected\n"); + } else { + __sbi_rfence = __sbi_rfence_v01; + } + } else { + __sbi_set_timer = __sbi_set_timer_v01; + __sbi_send_ipi = __sbi_send_ipi_v01; + __sbi_rfence = __sbi_rfence_v01; + } + return 0; } -early_initcall(sbi_init); diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 0a6d415b0a5a..145128a7e560 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -16,12 +16,14 @@ #include <linux/of_platform.h> #include <linux/sched/task.h> #include <linux/swiotlb.h> +#include <linux/smp.h> #include <asm/clint.h> +#include <asm/cpu_ops.h> #include <asm/setup.h> #include <asm/sections.h> #include <asm/pgtable.h> -#include <asm/smp.h> +#include <asm/sbi.h> #include <asm/tlbflush.h> #include <asm/thread_info.h> #include <asm/kasan.h> @@ -39,9 +41,14 @@ struct screen_info screen_info = { }; #endif -/* The lucky hart to first increment this variable will boot the other cores */ -atomic_t hart_lottery; +/* + * The lucky hart to first increment this variable will boot the other cores. + * This is used before the kernel initializes the BSS so it can't be in the + * BSS. + */ +atomic_t hart_lottery __section(.sdata); unsigned long boot_cpu_hartid; +static DEFINE_PER_CPU(struct cpu, cpu_devices); void __init parse_dtb(void) { @@ -79,9 +86,28 @@ void __init setup_arch(char **cmdline_p) kasan_init(); #endif +#if IS_ENABLED(CONFIG_RISCV_SBI) + sbi_init(); +#endif + #ifdef CONFIG_SMP setup_smp(); #endif riscv_fill_hwcap(); } + +static int __init topology_init(void) +{ + int i; + + for_each_possible_cpu(i) { + struct cpu *cpu = &per_cpu(cpu_devices, i); + + cpu->hotpluggable = cpu_has_hotplug(i); + register_cpu(cpu, i); + } + + return 0; +} +subsys_initcall(topology_init); diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 8bc01f0ca73b..4e9922790f6e 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -25,6 +25,7 @@ #include <linux/sched/task_stack.h> #include <linux/sched/mm.h> #include <asm/clint.h> +#include <asm/cpu_ops.h> #include <asm/irq.h> #include <asm/mmu_context.h> #include <asm/tlbflush.h> @@ -34,8 +35,6 @@ #include "head.h" -void *__cpu_up_stack_pointer[NR_CPUS]; -void *__cpu_up_task_pointer[NR_CPUS]; static DECLARE_COMPLETION(cpu_running); void __init smp_prepare_boot_cpu(void) @@ -46,6 +45,7 @@ void __init smp_prepare_boot_cpu(void) void __init smp_prepare_cpus(unsigned int max_cpus) { int cpuid; + int ret; /* This covers non-smp usecase mandated by "nosmp" option */ if (max_cpus == 0) @@ -54,6 +54,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) for_each_possible_cpu(cpuid) { if (cpuid == smp_processor_id()) continue; + if (cpu_ops[cpuid]->cpu_prepare) { + ret = cpu_ops[cpuid]->cpu_prepare(cpuid); + if (ret) + continue; + } set_cpu_present(cpuid, true); } } @@ -65,6 +70,8 @@ void __init setup_smp(void) bool found_boot_cpu = false; int cpuid = 1; + cpu_set_ops(0); + for_each_of_cpu_node(dn) { hart = riscv_of_processor_hartid(dn); if (hart < 0) @@ -92,36 +99,38 @@ void __init setup_smp(void) cpuid, nr_cpu_ids); for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { - if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) { + cpu_set_ops(cpuid); set_cpu_possible(cpuid, true); + } } } +int start_secondary_cpu(int cpu, struct task_struct *tidle) +{ + if (cpu_ops[cpu]->cpu_start) + return cpu_ops[cpu]->cpu_start(cpu, tidle); + + return -EOPNOTSUPP; +} + int __cpu_up(unsigned int cpu, struct task_struct *tidle) { int ret = 0; - int hartid = cpuid_to_hartid_map(cpu); tidle->thread_info.cpu = cpu; - /* - * On RISC-V systems, all harts boot on their own accord. Our _start - * selects the first hart to boot the kernel and causes the remainder - * of the harts to spin in a loop waiting for their stack pointer to be - * setup by that main hart. Writing __cpu_up_stack_pointer signals to - * the spinning harts that they can continue the boot process. - */ - smp_mb(); - WRITE_ONCE(__cpu_up_stack_pointer[hartid], - task_stack_page(tidle) + THREAD_SIZE); - WRITE_ONCE(__cpu_up_task_pointer[hartid], tidle); - - lockdep_assert_held(&cpu_running); - wait_for_completion_timeout(&cpu_running, + ret = start_secondary_cpu(cpu, tidle); + if (!ret) { + lockdep_assert_held(&cpu_running); + wait_for_completion_timeout(&cpu_running, msecs_to_jiffies(1000)); - if (!cpu_online(cpu)) { - pr_crit("CPU%u: failed to come online\n", cpu); - ret = -EIO; + if (!cpu_online(cpu)) { + pr_crit("CPU%u: failed to come online\n", cpu); + ret = -EIO; + } + } else { + pr_crit("CPU%u: failed to start\n", cpu); } return ret; @@ -134,7 +143,7 @@ void __init smp_cpus_done(unsigned int max_cpus) /* * C entry point for a secondary processor. */ -asmlinkage __visible void __init smp_callin(void) +asmlinkage __visible void smp_callin(void) { struct mm_struct *mm = &init_mm; diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c new file mode 100644 index 000000000000..0b3b3dc9ad0f --- /dev/null +++ b/arch/riscv/kernel/soc.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#include <linux/init.h> +#include <linux/libfdt.h> +#include <asm/pgtable.h> +#include <asm/soc.h> + +/* + * This is called extremly early, before parse_dtb(), to allow initializing + * SoC hardware before memory or any device driver initialization. + */ +void __init soc_early_init(void) +{ + void (*early_fn)(const void *fdt); + const struct of_device_id *s; + const void *fdt = dtb_early_va; + + for (s = (void *)&__soc_early_init_table_start; + (void *)s < (void *)&__soc_early_init_table_end; s++) { + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) { + early_fn = s->data; + early_fn(fdt); + return; + } + } +} diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 0940681d2f68..02087fe539c6 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -19,6 +19,8 @@ struct stackframe { unsigned long ra; }; +register unsigned long sp_in_global __asm__("sp"); + void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) { @@ -29,7 +31,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, sp = user_stack_pointer(regs); pc = instruction_pointer(regs); } else if (task == NULL || task == current) { - const register unsigned long current_sp __asm__ ("sp"); + const register unsigned long current_sp = sp_in_global; fp = (unsigned long)__builtin_frame_address(0); sp = current_sp; pc = (unsigned long)walk_stackframe; @@ -73,8 +75,7 @@ static void notrace walk_stackframe(struct task_struct *task, sp = user_stack_pointer(regs); pc = instruction_pointer(regs); } else if (task == NULL || task == current) { - const register unsigned long current_sp __asm__ ("sp"); - sp = current_sp; + sp = sp_in_global; pc = (unsigned long)walk_stackframe; } else { /* task blocked in __switch_to */ diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 55ea614d89bf..7f58fa53033f 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -97,12 +97,33 @@ DO_ERROR_INFO(do_trap_insn_fault, SIGSEGV, SEGV_ACCERR, "instruction access fault"); DO_ERROR_INFO(do_trap_insn_illegal, SIGILL, ILL_ILLOPC, "illegal instruction"); -DO_ERROR_INFO(do_trap_load_misaligned, - SIGBUS, BUS_ADRALN, "load address misaligned"); DO_ERROR_INFO(do_trap_load_fault, SIGSEGV, SEGV_ACCERR, "load access fault"); +#ifndef CONFIG_RISCV_M_MODE +DO_ERROR_INFO(do_trap_load_misaligned, + SIGBUS, BUS_ADRALN, "Oops - load address misaligned"); DO_ERROR_INFO(do_trap_store_misaligned, - SIGBUS, BUS_ADRALN, "store (or AMO) address misaligned"); + SIGBUS, BUS_ADRALN, "Oops - store (or AMO) address misaligned"); +#else +int handle_misaligned_load(struct pt_regs *regs); +int handle_misaligned_store(struct pt_regs *regs); + +asmlinkage void do_trap_load_misaligned(struct pt_regs *regs) +{ + if (!handle_misaligned_load(regs)) + return; + do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, + "Oops - load address misaligned"); +} + +asmlinkage void do_trap_store_misaligned(struct pt_regs *regs) +{ + if (!handle_misaligned_store(regs)) + return; + do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, + "Oops - store (or AMO) address misaligned"); +} +#endif DO_ERROR_INFO(do_trap_store_fault, SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); DO_ERROR_INFO(do_trap_ecall_u, @@ -118,7 +139,8 @@ static inline unsigned long get_break_insn_length(unsigned long pc) if (probe_kernel_address((bug_insn_t *)pc, insn)) return 0; - return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL); + + return GET_INSN_LENGTH(insn); } asmlinkage __visible void do_trap_break(struct pt_regs *regs) @@ -147,7 +169,7 @@ int is_valid_bugaddr(unsigned long pc) } #endif /* CONFIG_GENERIC_BUG */ -void __init trap_init(void) +void trap_init(void) { /* * Set sup0 scratch register to 0, indicating to exception vector diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c new file mode 100644 index 000000000000..46c4dafe3ba0 --- /dev/null +++ b/arch/riscv/kernel/traps_misaligned.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/irq.h> + +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/csr.h> + +#define INSN_MATCH_LB 0x3 +#define INSN_MASK_LB 0x707f +#define INSN_MATCH_LH 0x1003 +#define INSN_MASK_LH 0x707f +#define INSN_MATCH_LW 0x2003 +#define INSN_MASK_LW 0x707f +#define INSN_MATCH_LD 0x3003 +#define INSN_MASK_LD 0x707f +#define INSN_MATCH_LBU 0x4003 +#define INSN_MASK_LBU 0x707f +#define INSN_MATCH_LHU 0x5003 +#define INSN_MASK_LHU 0x707f +#define INSN_MATCH_LWU 0x6003 +#define INSN_MASK_LWU 0x707f +#define INSN_MATCH_SB 0x23 +#define INSN_MASK_SB 0x707f +#define INSN_MATCH_SH 0x1023 +#define INSN_MASK_SH 0x707f +#define INSN_MATCH_SW 0x2023 +#define INSN_MASK_SW 0x707f +#define INSN_MATCH_SD 0x3023 +#define INSN_MASK_SD 0x707f + +#define INSN_MATCH_FLW 0x2007 +#define INSN_MASK_FLW 0x707f +#define INSN_MATCH_FLD 0x3007 +#define INSN_MASK_FLD 0x707f +#define INSN_MATCH_FLQ 0x4007 +#define INSN_MASK_FLQ 0x707f +#define INSN_MATCH_FSW 0x2027 +#define INSN_MASK_FSW 0x707f +#define INSN_MATCH_FSD 0x3027 +#define INSN_MASK_FSD 0x707f +#define INSN_MATCH_FSQ 0x4027 +#define INSN_MASK_FSQ 0x707f + +#define INSN_MATCH_C_LD 0x6000 +#define INSN_MASK_C_LD 0xe003 +#define INSN_MATCH_C_SD 0xe000 +#define INSN_MASK_C_SD 0xe003 +#define INSN_MATCH_C_LW 0x4000 +#define INSN_MASK_C_LW 0xe003 +#define INSN_MATCH_C_SW 0xc000 +#define INSN_MASK_C_SW 0xe003 +#define INSN_MATCH_C_LDSP 0x6002 +#define INSN_MASK_C_LDSP 0xe003 +#define INSN_MATCH_C_SDSP 0xe002 +#define INSN_MASK_C_SDSP 0xe003 +#define INSN_MATCH_C_LWSP 0x4002 +#define INSN_MASK_C_LWSP 0xe003 +#define INSN_MATCH_C_SWSP 0xc002 +#define INSN_MASK_C_SWSP 0xe003 + +#define INSN_MATCH_C_FLD 0x2000 +#define INSN_MASK_C_FLD 0xe003 +#define INSN_MATCH_C_FLW 0x6000 +#define INSN_MASK_C_FLW 0xe003 +#define INSN_MATCH_C_FSD 0xa000 +#define INSN_MASK_C_FSD 0xe003 +#define INSN_MATCH_C_FSW 0xe000 +#define INSN_MASK_C_FSW 0xe003 +#define INSN_MATCH_C_FLDSP 0x2002 +#define INSN_MASK_C_FLDSP 0xe003 +#define INSN_MATCH_C_FSDSP 0xa002 +#define INSN_MASK_C_FSDSP 0xe003 +#define INSN_MATCH_C_FLWSP 0x6002 +#define INSN_MASK_C_FLWSP 0xe003 +#define INSN_MATCH_C_FSWSP 0xe002 +#define INSN_MASK_C_FSWSP 0xe003 + +#define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4) + +#if defined(CONFIG_64BIT) +#define LOG_REGBYTES 3 +#define XLEN 64 +#else +#define LOG_REGBYTES 2 +#define XLEN 32 +#endif +#define REGBYTES (1 << LOG_REGBYTES) +#define XLEN_MINUS_16 ((XLEN) - 16) + +#define SH_RD 7 +#define SH_RS1 15 +#define SH_RS2 20 +#define SH_RS2C 2 + +#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1)) +#define RVC_LW_IMM(x) ((RV_X(x, 6, 1) << 2) | \ + (RV_X(x, 10, 3) << 3) | \ + (RV_X(x, 5, 1) << 6)) +#define RVC_LD_IMM(x) ((RV_X(x, 10, 3) << 3) | \ + (RV_X(x, 5, 2) << 6)) +#define RVC_LWSP_IMM(x) ((RV_X(x, 4, 3) << 2) | \ + (RV_X(x, 12, 1) << 5) | \ + (RV_X(x, 2, 2) << 6)) +#define RVC_LDSP_IMM(x) ((RV_X(x, 5, 2) << 3) | \ + (RV_X(x, 12, 1) << 5) | \ + (RV_X(x, 2, 3) << 6)) +#define RVC_SWSP_IMM(x) ((RV_X(x, 9, 4) << 2) | \ + (RV_X(x, 7, 2) << 6)) +#define RVC_SDSP_IMM(x) ((RV_X(x, 10, 3) << 3) | \ + (RV_X(x, 7, 3) << 6)) +#define RVC_RS1S(insn) (8 + RV_X(insn, SH_RD, 3)) +#define RVC_RS2S(insn) (8 + RV_X(insn, SH_RS2C, 3)) +#define RVC_RS2(insn) RV_X(insn, SH_RS2C, 5) + +#define SHIFT_RIGHT(x, y) \ + ((y) < 0 ? ((x) << -(y)) : ((x) >> (y))) + +#define REG_MASK \ + ((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES)) + +#define REG_OFFSET(insn, pos) \ + (SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK) + +#define REG_PTR(insn, pos, regs) \ + (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos)) + +#define GET_RM(insn) (((insn) >> 12) & 7) + +#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs)) +#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs)) +#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs)) +#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs)) +#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs)) +#define GET_SP(regs) (*REG_PTR(2, 0, regs)) +#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val)) +#define IMM_I(insn) ((s32)(insn) >> 20) +#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \ + (s32)(((insn) >> 7) & 0x1f)) +#define MASK_FUNCT3 0x7000 + +#define GET_PRECISION(insn) (((insn) >> 25) & 3) +#define GET_RM(insn) (((insn) >> 12) & 7) +#define PRECISION_S 0 +#define PRECISION_D 1 + +#define STR(x) XSTR(x) +#define XSTR(x) #x + +#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \ +static inline type load_##type(const type *addr) \ +{ \ + type val; \ + asm (#insn " %0, %1" \ + : "=&r" (val) : "m" (*addr)); \ + return val; \ +} + +#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \ +static inline void store_##type(type *addr, type val) \ +{ \ + asm volatile (#insn " %0, %1\n" \ + : : "r" (val), "m" (*addr)); \ +} + +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8, lbu) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16, lhu) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s8, lb) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s16, lh) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s32, lw) +DECLARE_UNPRIVILEGED_STORE_FUNCTION(u8, sb) +DECLARE_UNPRIVILEGED_STORE_FUNCTION(u16, sh) +DECLARE_UNPRIVILEGED_STORE_FUNCTION(u32, sw) +#if defined(CONFIG_64BIT) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lwu) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u64, ld) +DECLARE_UNPRIVILEGED_STORE_FUNCTION(u64, sd) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, ld) +#else +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lw) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, lw) + +static inline u64 load_u64(const u64 *addr) +{ + return load_u32((u32 *)addr) + + ((u64)load_u32((u32 *)addr + 1) << 32); +} + +static inline void store_u64(u64 *addr, u64 val) +{ + store_u32((u32 *)addr, val); + store_u32((u32 *)addr + 1, val >> 32); +} +#endif + +static inline ulong get_insn(ulong mepc) +{ + register ulong __mepc asm ("a2") = mepc; + ulong val, rvc_mask = 3, tmp; + + asm ("and %[tmp], %[addr], 2\n" + "bnez %[tmp], 1f\n" +#if defined(CONFIG_64BIT) + STR(LWU) " %[insn], (%[addr])\n" +#else + STR(LW) " %[insn], (%[addr])\n" +#endif + "and %[tmp], %[insn], %[rvc_mask]\n" + "beq %[tmp], %[rvc_mask], 2f\n" + "sll %[insn], %[insn], %[xlen_minus_16]\n" + "srl %[insn], %[insn], %[xlen_minus_16]\n" + "j 2f\n" + "1:\n" + "lhu %[insn], (%[addr])\n" + "and %[tmp], %[insn], %[rvc_mask]\n" + "bne %[tmp], %[rvc_mask], 2f\n" + "lhu %[tmp], 2(%[addr])\n" + "sll %[tmp], %[tmp], 16\n" + "add %[insn], %[insn], %[tmp]\n" + "2:" + : [insn] "=&r" (val), [tmp] "=&r" (tmp) + : [addr] "r" (__mepc), [rvc_mask] "r" (rvc_mask), + [xlen_minus_16] "i" (XLEN_MINUS_16)); + + return val; +} + +union reg_data { + u8 data_bytes[8]; + ulong data_ulong; + u64 data_u64; +}; + +int handle_misaligned_load(struct pt_regs *regs) +{ + union reg_data val; + unsigned long epc = regs->epc; + unsigned long insn = get_insn(epc); + unsigned long addr = csr_read(mtval); + int i, fp = 0, shift = 0, len = 0; + + regs->epc = 0; + + if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) { + len = 4; + shift = 8 * (sizeof(unsigned long) - len); +#if defined(CONFIG_64BIT) + } else if ((insn & INSN_MASK_LD) == INSN_MATCH_LD) { + len = 8; + shift = 8 * (sizeof(unsigned long) - len); + } else if ((insn & INSN_MASK_LWU) == INSN_MATCH_LWU) { + len = 4; +#endif + } else if ((insn & INSN_MASK_FLD) == INSN_MATCH_FLD) { + fp = 1; + len = 8; + } else if ((insn & INSN_MASK_FLW) == INSN_MATCH_FLW) { + fp = 1; + len = 4; + } else if ((insn & INSN_MASK_LH) == INSN_MATCH_LH) { + len = 2; + shift = 8 * (sizeof(unsigned long) - len); + } else if ((insn & INSN_MASK_LHU) == INSN_MATCH_LHU) { + len = 2; +#if defined(CONFIG_64BIT) + } else if ((insn & INSN_MASK_C_LD) == INSN_MATCH_C_LD) { + len = 8; + shift = 8 * (sizeof(unsigned long) - len); + insn = RVC_RS2S(insn) << SH_RD; + } else if ((insn & INSN_MASK_C_LDSP) == INSN_MATCH_C_LDSP && + ((insn >> SH_RD) & 0x1f)) { + len = 8; + shift = 8 * (sizeof(unsigned long) - len); +#endif + } else if ((insn & INSN_MASK_C_LW) == INSN_MATCH_C_LW) { + len = 4; + shift = 8 * (sizeof(unsigned long) - len); + insn = RVC_RS2S(insn) << SH_RD; + } else if ((insn & INSN_MASK_C_LWSP) == INSN_MATCH_C_LWSP && + ((insn >> SH_RD) & 0x1f)) { + len = 4; + shift = 8 * (sizeof(unsigned long) - len); + } else if ((insn & INSN_MASK_C_FLD) == INSN_MATCH_C_FLD) { + fp = 1; + len = 8; + insn = RVC_RS2S(insn) << SH_RD; + } else if ((insn & INSN_MASK_C_FLDSP) == INSN_MATCH_C_FLDSP) { + fp = 1; + len = 8; +#if defined(CONFIG_32BIT) + } else if ((insn & INSN_MASK_C_FLW) == INSN_MATCH_C_FLW) { + fp = 1; + len = 4; + insn = RVC_RS2S(insn) << SH_RD; + } else if ((insn & INSN_MASK_C_FLWSP) == INSN_MATCH_C_FLWSP) { + fp = 1; + len = 4; +#endif + } else { + regs->epc = epc; + return -1; + } + + val.data_u64 = 0; + for (i = 0; i < len; i++) + val.data_bytes[i] = load_u8((void *)(addr + i)); + + if (fp) + return -1; + SET_RD(insn, regs, val.data_ulong << shift >> shift); + + regs->epc = epc + INSN_LEN(insn); + + return 0; +} + +int handle_misaligned_store(struct pt_regs *regs) +{ + union reg_data val; + unsigned long epc = regs->epc; + unsigned long insn = get_insn(epc); + unsigned long addr = csr_read(mtval); + int i, len = 0; + + regs->epc = 0; + + val.data_ulong = GET_RS2(insn, regs); + + if ((insn & INSN_MASK_SW) == INSN_MATCH_SW) { + len = 4; +#if defined(CONFIG_64BIT) + } else if ((insn & INSN_MASK_SD) == INSN_MATCH_SD) { + len = 8; +#endif + } else if ((insn & INSN_MASK_SH) == INSN_MATCH_SH) { + len = 2; +#if defined(CONFIG_64BIT) + } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { + len = 8; + val.data_ulong = GET_RS2S(insn, regs); + } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && + ((insn >> SH_RD) & 0x1f)) { + len = 8; + val.data_ulong = GET_RS2C(insn, regs); +#endif + } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { + len = 4; + val.data_ulong = GET_RS2S(insn, regs); + } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && + ((insn >> SH_RD) & 0x1f)) { + len = 4; + val.data_ulong = GET_RS2C(insn, regs); + } else { + regs->epc = epc; + return -1; + } + + for (i = 0; i < len; i++) + store_u8((void *)(addr + i), val.data_bytes[i]); + + regs->epc = epc + INSN_LEN(insn); + + return 0; +} diff --git a/arch/riscv/kernel/vdso/.gitignore b/arch/riscv/kernel/vdso/.gitignore index 97c2d69d0289..11ebee9e4c1d 100644 --- a/arch/riscv/kernel/vdso/.gitignore +++ b/arch/riscv/kernel/vdso/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds *.tmp diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 1e0193ded420..0339b6bbe11a 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -9,7 +9,9 @@ #include <asm/page.h> #include <asm/cache.h> #include <asm/thread_info.h> +#include <asm/set_memory.h> +#include <linux/sizes.h> OUTPUT_ARCH(riscv) ENTRY(_start) @@ -20,10 +22,18 @@ SECTIONS /* Beginning of code and text segment */ . = LOAD_OFFSET; _start = .; - __init_begin = .; HEAD_TEXT_SECTION + . = ALIGN(PAGE_SIZE); + + __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) INIT_DATA_SECTION(16) + . = ALIGN(8); + __soc_early_init_table : { + __soc_early_init_table_start = .; + KEEP(*(__soc_early_init_table)) + __soc_early_init_table_end = .; + } /* we have to discard exit text and such at runtime, not link time */ .exit.text : { @@ -36,6 +46,7 @@ SECTIONS PERCPU_SECTION(L1_CACHE_BYTES) __init_end = .; + . = ALIGN(SECTION_ALIGN); .text : { _text = .; _stext = .; @@ -53,24 +64,26 @@ SECTIONS /* Start of data section */ _sdata = .; - RO_DATA(L1_CACHE_BYTES) + RO_DATA(SECTION_ALIGN) .srodata : { *(.srodata*) } + EXCEPTION_TABLE(0x10) + + . = ALIGN(SECTION_ALIGN); + _data = .; + RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) .sdata : { __global_pointer$ = . + 0x800; *(.sdata*) /* End of data section */ _edata = .; - *(.sbss*) } BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) - EXCEPTION_TABLE(0x10) - .rel.dyn : { *(.rel.dyn*) } diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S index f29d2ba2c0a6..fceaeb18cc64 100644 --- a/arch/riscv/lib/uaccess.S +++ b/arch/riscv/lib/uaccess.S @@ -3,14 +3,12 @@ #include <asm/asm.h> #include <asm/csr.h> - .altmacro .macro fixup op reg addr lbl - LOCAL _epc -_epc: +100: \op \reg, \addr .section __ex_table,"a" .balign RISCV_SZPTR - RISCV_PTR _epc, \lbl + RISCV_PTR 100b, \lbl .previous .endm diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile index 50b7af58c566..363ef01c30b1 100644 --- a/arch/riscv/mm/Makefile +++ b/arch/riscv/mm/Makefile @@ -7,7 +7,7 @@ endif obj-y += init.o obj-y += extable.o -obj-$(CONFIG_MMU) += fault.o +obj-$(CONFIG_MMU) += fault.o pageattr.o obj-y += cacheflush.o obj-y += context.o @@ -15,6 +15,7 @@ ifeq ($(CONFIG_MMU),y) obj-$(CONFIG_SMP) += tlbflush.o endif obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_PTDUMP_CORE) += ptdump.o obj-$(CONFIG_KASAN) += kasan_init.o ifdef CONFIG_KASAN diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 0d4747e9d5b5..a6189ed36c5f 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -4,14 +4,12 @@ int pud_huge(pud_t pud) { - return pud_present(pud) && - (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)); + return pud_leaf(pud); } int pmd_huge(pmd_t pmd) { - return pmd_present(pmd) && - (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)); + return pmd_leaf(pmd); } static __init int setup_hugepagesz(char *opt) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index fab855963c73..b55be44ff9bd 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -12,6 +12,7 @@ #include <linux/sizes.h> #include <linux/of_fdt.h> #include <linux/libfdt.h> +#include <linux/set_memory.h> #include <asm/fixmap.h> #include <asm/tlbflush.h> @@ -477,6 +478,17 @@ static void __init setup_vm_final(void) csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE); local_flush_tlb_all(); } + +void free_initmem(void) +{ + unsigned long init_begin = (unsigned long)__init_begin; + unsigned long init_end = (unsigned long)__init_end; + + /* Make the region as non-execuatble. */ + set_memory_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); + free_initmem_default(POISON_FREE_INITMEM); +} + #else asmlinkage void __init setup_vm(uintptr_t dtb_pa) { @@ -488,6 +500,38 @@ static inline void setup_vm_final(void) } #endif /* CONFIG_MMU */ +#ifdef CONFIG_STRICT_KERNEL_RWX +void set_kernel_text_rw(void) +{ + unsigned long text_start = (unsigned long)_text; + unsigned long text_end = (unsigned long)_etext; + + set_memory_rw(text_start, (text_end - text_start) >> PAGE_SHIFT); +} + +void set_kernel_text_ro(void) +{ + unsigned long text_start = (unsigned long)_text; + unsigned long text_end = (unsigned long)_etext; + + set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT); +} + +void mark_rodata_ro(void) +{ + unsigned long text_start = (unsigned long)_text; + unsigned long text_end = (unsigned long)_etext; + unsigned long rodata_start = (unsigned long)__start_rodata; + unsigned long data_start = (unsigned long)_data; + unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn))); + + set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT); + set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT); + set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT); + set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT); +} +#endif + void __init paging_init(void) { setup_vm_final(); diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c new file mode 100644 index 000000000000..728759eb530a --- /dev/null +++ b/arch/riscv/mm/pageattr.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 SiFive + */ + +#include <linux/pagewalk.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> +#include <asm/bitops.h> + +struct pageattr_masks { + pgprot_t set_mask; + pgprot_t clear_mask; +}; + +static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk) +{ + struct pageattr_masks *masks = walk->private; + unsigned long new_val = val; + + new_val &= ~(pgprot_val(masks->clear_mask)); + new_val |= (pgprot_val(masks->set_mask)); + + return new_val; +} + +static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pgd_t val = READ_ONCE(*pgd); + + if (pgd_leaf(val)) { + val = __pgd(set_pageattr_masks(pgd_val(val), walk)); + set_pgd(pgd, val); + } + + return 0; +} + +static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + p4d_t val = READ_ONCE(*p4d); + + if (p4d_leaf(val)) { + val = __p4d(set_pageattr_masks(p4d_val(val), walk)); + set_p4d(p4d, val); + } + + return 0; +} + +static int pageattr_pud_entry(pud_t *pud, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pud_t val = READ_ONCE(*pud); + + if (pud_leaf(val)) { + val = __pud(set_pageattr_masks(pud_val(val), walk)); + set_pud(pud, val); + } + + return 0; +} + +static int pageattr_pmd_entry(pmd_t *pmd, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pmd_t val = READ_ONCE(*pmd); + + if (pmd_leaf(val)) { + val = __pmd(set_pageattr_masks(pmd_val(val), walk)); + set_pmd(pmd, val); + } + + return 0; +} + +static int pageattr_pte_entry(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pte_t val = READ_ONCE(*pte); + + val = __pte(set_pageattr_masks(pte_val(val), walk)); + set_pte(pte, val); + + return 0; +} + +static int pageattr_pte_hole(unsigned long addr, unsigned long next, + int depth, struct mm_walk *walk) +{ + /* Nothing to do here */ + return 0; +} + +const static struct mm_walk_ops pageattr_ops = { + .pgd_entry = pageattr_pgd_entry, + .p4d_entry = pageattr_p4d_entry, + .pud_entry = pageattr_pud_entry, + .pmd_entry = pageattr_pmd_entry, + .pte_entry = pageattr_pte_entry, + .pte_hole = pageattr_pte_hole, +}; + +static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, + pgprot_t clear_mask) +{ + int ret; + unsigned long start = addr; + unsigned long end = start + PAGE_SIZE * numpages; + struct pageattr_masks masks = { + .set_mask = set_mask, + .clear_mask = clear_mask + }; + + if (!numpages) + return 0; + + down_read(&init_mm.mmap_sem); + ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, + &masks); + up_read(&init_mm.mmap_sem); + + flush_tlb_kernel_range(start, end); + + return ret; +} + +int set_memory_ro(unsigned long addr, int numpages) +{ + return __set_memory(addr, numpages, __pgprot(_PAGE_READ), + __pgprot(_PAGE_WRITE)); +} + +int set_memory_rw(unsigned long addr, int numpages) +{ + return __set_memory(addr, numpages, __pgprot(_PAGE_READ | _PAGE_WRITE), + __pgprot(0)); +} + +int set_memory_x(unsigned long addr, int numpages) +{ + return __set_memory(addr, numpages, __pgprot(_PAGE_EXEC), __pgprot(0)); +} + +int set_memory_nx(unsigned long addr, int numpages) +{ + return __set_memory(addr, numpages, __pgprot(0), __pgprot(_PAGE_EXEC)); +} + +int set_direct_map_invalid_noflush(struct page *page) +{ + unsigned long start = (unsigned long)page_address(page); + unsigned long end = start + PAGE_SIZE; + struct pageattr_masks masks = { + .set_mask = __pgprot(0), + .clear_mask = __pgprot(_PAGE_PRESENT) + }; + + return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +} + +int set_direct_map_default_noflush(struct page *page) +{ + unsigned long start = (unsigned long)page_address(page); + unsigned long end = start + PAGE_SIZE; + struct pageattr_masks masks = { + .set_mask = PAGE_KERNEL, + .clear_mask = __pgprot(0) + }; + + return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +} + +void __kernel_map_pages(struct page *page, int numpages, int enable) +{ + if (!debug_pagealloc_enabled()) + return; + + if (enable) + __set_memory((unsigned long)page_address(page), numpages, + __pgprot(_PAGE_PRESENT), __pgprot(0)); + else + __set_memory((unsigned long)page_address(page), numpages, + __pgprot(0), __pgprot(_PAGE_PRESENT)); +} diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c new file mode 100644 index 000000000000..7eab76a93106 --- /dev/null +++ b/arch/riscv/mm/ptdump.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 SiFive + */ + +#include <linux/init.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/ptdump.h> + +#include <asm/ptdump.h> +#include <asm/pgtable.h> +#include <asm/kasan.h> + +#define pt_dump_seq_printf(m, fmt, args...) \ +({ \ + if (m) \ + seq_printf(m, fmt, ##args); \ +}) + +#define pt_dump_seq_puts(m, fmt) \ +({ \ + if (m) \ + seq_printf(m, fmt); \ +}) + +/* + * The page dumper groups page table entries of the same type into a single + * description. It uses pg_state to track the range information while + * iterating over the pte entries. When the continuity is broken it then + * dumps out a description of the range. + */ +struct pg_state { + struct ptdump_state ptdump; + struct seq_file *seq; + const struct addr_marker *marker; + unsigned long start_address; + unsigned long start_pa; + unsigned long last_pa; + int level; + u64 current_prot; + bool check_wx; + unsigned long wx_pages; +}; + +/* Address marker */ +struct addr_marker { + unsigned long start_address; + const char *name; +}; + +static struct addr_marker address_markers[] = { +#ifdef CONFIG_KASAN + {KASAN_SHADOW_START, "Kasan shadow start"}, + {KASAN_SHADOW_END, "Kasan shadow end"}, +#endif + {FIXADDR_START, "Fixmap start"}, + {FIXADDR_TOP, "Fixmap end"}, + {PCI_IO_START, "PCI I/O start"}, + {PCI_IO_END, "PCI I/O end"}, +#ifdef CONFIG_SPARSEMEM_VMEMMAP + {VMEMMAP_START, "vmemmap start"}, + {VMEMMAP_END, "vmemmap end"}, +#endif + {VMALLOC_START, "vmalloc() area"}, + {VMALLOC_END, "vmalloc() end"}, + {PAGE_OFFSET, "Linear mapping"}, + {-1, NULL}, +}; + +/* Page Table Entry */ +struct prot_bits { + u64 mask; + u64 val; + const char *set; + const char *clear; +}; + +static const struct prot_bits pte_bits[] = { + { + .mask = _PAGE_SOFT, + .val = _PAGE_SOFT, + .set = "RSW", + .clear = " ", + }, { + .mask = _PAGE_DIRTY, + .val = _PAGE_DIRTY, + .set = "D", + .clear = ".", + }, { + .mask = _PAGE_ACCESSED, + .val = _PAGE_ACCESSED, + .set = "A", + .clear = ".", + }, { + .mask = _PAGE_GLOBAL, + .val = _PAGE_GLOBAL, + .set = "G", + .clear = ".", + }, { + .mask = _PAGE_USER, + .val = _PAGE_USER, + .set = "U", + .clear = ".", + }, { + .mask = _PAGE_EXEC, + .val = _PAGE_EXEC, + .set = "X", + .clear = ".", + }, { + .mask = _PAGE_WRITE, + .val = _PAGE_WRITE, + .set = "W", + .clear = ".", + }, { + .mask = _PAGE_READ, + .val = _PAGE_READ, + .set = "R", + .clear = ".", + }, { + .mask = _PAGE_PRESENT, + .val = _PAGE_PRESENT, + .set = "V", + .clear = ".", + } +}; + +/* Page Level */ +struct pg_level { + const char *name; + u64 mask; +}; + +static struct pg_level pg_level[] = { + { /* pgd */ + .name = "PGD", + }, { /* p4d */ + .name = (CONFIG_PGTABLE_LEVELS > 4) ? "P4D" : "PGD", + }, { /* pud */ + .name = (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD", + }, { /* pmd */ + .name = (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD", + }, { /* pte */ + .name = "PTE", + }, +}; + +static void dump_prot(struct pg_state *st) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pte_bits); i++) { + const char *s; + + if ((st->current_prot & pte_bits[i].mask) == pte_bits[i].val) + s = pte_bits[i].set; + else + s = pte_bits[i].clear; + + if (s) + pt_dump_seq_printf(st->seq, " %s", s); + } +} + +#ifdef CONFIG_64BIT +#define ADDR_FORMAT "0x%016lx" +#else +#define ADDR_FORMAT "0x%08lx" +#endif +static void dump_addr(struct pg_state *st, unsigned long addr) +{ + static const char units[] = "KMGTPE"; + const char *unit = units; + unsigned long delta; + + pt_dump_seq_printf(st->seq, ADDR_FORMAT "-" ADDR_FORMAT " ", + st->start_address, addr); + + pt_dump_seq_printf(st->seq, " " ADDR_FORMAT " ", st->start_pa); + delta = (addr - st->start_address) >> 10; + + while (!(delta & 1023) && unit[1]) { + delta >>= 10; + unit++; + } + + pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit, + pg_level[st->level].name); +} + +static void note_prot_wx(struct pg_state *st, unsigned long addr) +{ + if (!st->check_wx) + return; + + if ((st->current_prot & (_PAGE_WRITE | _PAGE_EXEC)) != + (_PAGE_WRITE | _PAGE_EXEC)) + return; + + WARN_ONCE(1, "riscv/mm: Found insecure W+X mapping at address %p/%pS\n", + (void *)st->start_address, (void *)st->start_address); + + st->wx_pages += (addr - st->start_address) / PAGE_SIZE; +} + +static void note_page(struct ptdump_state *pt_st, unsigned long addr, + int level, unsigned long val) +{ + struct pg_state *st = container_of(pt_st, struct pg_state, ptdump); + u64 pa = PFN_PHYS(pte_pfn(__pte(val))); + u64 prot = 0; + + if (level >= 0) + prot = val & pg_level[level].mask; + + if (st->level == -1) { + st->level = level; + st->current_prot = prot; + st->start_address = addr; + st->start_pa = pa; + st->last_pa = pa; + pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name); + } else if (prot != st->current_prot || + level != st->level || addr >= st->marker[1].start_address) { + if (st->current_prot) { + note_prot_wx(st, addr); + dump_addr(st, addr); + dump_prot(st); + pt_dump_seq_puts(st->seq, "\n"); + } + + while (addr >= st->marker[1].start_address) { + st->marker++; + pt_dump_seq_printf(st->seq, "---[ %s ]---\n", + st->marker->name); + } + + st->start_address = addr; + st->start_pa = pa; + st->last_pa = pa; + st->current_prot = prot; + st->level = level; + } else { + st->last_pa = pa; + } +} + +static void ptdump_walk(struct seq_file *s) +{ + struct pg_state st = { + .seq = s, + .marker = address_markers, + .level = -1, + .ptdump = { + .note_page = note_page, + .range = (struct ptdump_range[]) { + {KERN_VIRT_START, ULONG_MAX}, + {0, 0} + } + } + }; + + ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); +} + +void ptdump_check_wx(void) +{ + struct pg_state st = { + .seq = NULL, + .marker = (struct addr_marker[]) { + {0, NULL}, + {-1, NULL}, + }, + .level = -1, + .check_wx = true, + .ptdump = { + .note_page = note_page, + .range = (struct ptdump_range[]) { + {KERN_VIRT_START, ULONG_MAX}, + {0, 0} + } + } + }; + + ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); + + if (st.wx_pages) + pr_warn("Checked W+X mappings: failed, %lu W+X pages found\n", + st.wx_pages); + else + pr_info("Checked W+X mappings: passed, no W+X pages found\n"); +} + +static int ptdump_show(struct seq_file *m, void *v) +{ + ptdump_walk(m); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(ptdump); + +static int ptdump_init(void) +{ + unsigned int i, j; + + for (i = 0; i < ARRAY_SIZE(pg_level); i++) + for (j = 0; j < ARRAY_SIZE(pte_bits); j++) + pg_level[i].mask |= pte_bits[j].mask; + + debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, + &ptdump_fops); + + return 0; +} + +device_initcall(ptdump_init); diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index cc1985d8750a..d208a9fd6c52 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -110,6 +110,16 @@ static bool is_32b_int(s64 val) return -(1L << 31) <= val && val < (1L << 31); } +static bool in_auipc_jalr_range(s64 val) +{ + /* + * auipc+jalr can reach any signed PC-relative offset in the range + * [-2^31 - 2^11, 2^31 - 2^11). + */ + return (-(1L << 31) - (1L << 11)) <= val && + val < ((1L << 31) - (1L << 11)); +} + static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx) { /* Note that the immediate from the add is sign-extended, @@ -380,20 +390,24 @@ static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx) *rd = RV_REG_T2; } -static void emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr, - struct rv_jit_context *ctx) +static int emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr, + struct rv_jit_context *ctx) { s64 upper, lower; if (rvoff && is_21b_int(rvoff) && !force_jalr) { emit(rv_jal(rd, rvoff >> 1), ctx); - return; + return 0; + } else if (in_auipc_jalr_range(rvoff)) { + upper = (rvoff + (1 << 11)) >> 12; + lower = rvoff & 0xfff; + emit(rv_auipc(RV_REG_T1, upper), ctx); + emit(rv_jalr(rd, RV_REG_T1, lower), ctx); + return 0; } - upper = (rvoff + (1 << 11)) >> 12; - lower = rvoff & 0xfff; - emit(rv_auipc(RV_REG_T1, upper), ctx); - emit(rv_jalr(rd, RV_REG_T1, lower), ctx); + pr_err("bpf-jit: target offset 0x%llx is out of range\n", rvoff); + return -ERANGE; } static bool is_signed_bpf_cond(u8 cond) @@ -407,18 +421,16 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx) s64 off = 0; u64 ip; u8 rd; + int ret; if (addr && ctx->insns) { ip = (u64)(long)(ctx->insns + ctx->ninsns); off = addr - ip; - if (!is_32b_int(off)) { - pr_err("bpf-jit: target call addr %pK is out of range\n", - (void *)addr); - return -ERANGE; - } } - emit_jump_and_link(RV_REG_RA, off, !fixed, ctx); + ret = emit_jump_and_link(RV_REG_RA, off, !fixed, ctx); + if (ret) + return ret; rd = bpf_to_rv_reg(BPF_REG_0, ctx); emit(rv_addi(rd, RV_REG_A0, 0), ctx); return 0; @@ -429,7 +441,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, { bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 || BPF_CLASS(insn->code) == BPF_JMP; - int s, e, rvoff, i = insn - ctx->prog->insnsi; + int s, e, rvoff, ret, i = insn - ctx->prog->insnsi; struct bpf_prog_aux *aux = ctx->prog->aux; u8 rd = -1, rs = -1, code = insn->code; s16 off = insn->off; @@ -699,7 +711,9 @@ out_be: /* JUMP off */ case BPF_JMP | BPF_JA: rvoff = rv_offset(i, off, ctx); - emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); + ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); + if (ret) + return ret; break; /* IF (dst COND src) JUMP off */ @@ -801,7 +815,6 @@ out_be: case BPF_JMP | BPF_CALL: { bool fixed; - int ret; u64 addr; mark_call(ctx); @@ -826,7 +839,9 @@ out_be: break; rvoff = epilogue_offset(ctx); - emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); + ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); + if (ret) + return ret; break; /* dst = imm64 */ diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 59c216af6264..2167bce993ff 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -102,13 +102,13 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE select ARCH_KEEP_MEMBLOCK - select ARCH_SAVE_PAGE_KEYS if HIBERNATION select ARCH_STACKWALK select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_NUMA_BALANCING select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_WANTS_DYNAMIC_TASK_STRUCT + select ARCH_WANT_DEFAULT_BPF_JIT select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_TABLE_SORT select CLONE_BACKWARDS2 @@ -451,14 +451,6 @@ config NR_CPUS config HOTPLUG_CPU def_bool y -# Some NUMA nodes have memory ranges that span -# other nodes. Even though a pfn is valid and -# between a node's start and end pfns, it may not -# reside on that node. See memmap_init_zone() -# for details. <- They meant memory holes! -config NODES_SPAN_OTHER_NODES - def_bool NUMA - config NUMA bool "NUMA support" depends on SCHED_TOPOLOGY @@ -468,58 +460,9 @@ config NUMA This option adds NUMA support to the kernel. - An operation mode can be selected by appending - numa=<method> to the kernel command line. - - The default behaviour is identical to appending numa=plain to - the command line. This will create just one node with all - available memory and all CPUs in it. - config NODES_SHIFT - int "Maximum NUMA nodes (as a power of 2)" - range 1 10 - depends on NUMA - default "4" - help - Specify the maximum number of NUMA nodes available on the target - system. Increases memory reserved to accommodate various tables. - -menu "Select NUMA modes" - depends on NUMA - -config NUMA_EMU - bool "NUMA emulation" - default y - help - Numa emulation mode will split the available system memory into - equal chunks which then are distributed over the configured number - of nodes in a round-robin manner. - - The number of fake nodes is limited by the number of available memory - chunks (i.e. memory size / fake size) and the number of supported - nodes in the kernel. - - The CPUs are assigned to the nodes in a way that partially respects - the original machine topology (if supported by the machine). - Fair distribution of the CPUs is not guaranteed. - -config EMU_SIZE - hex "NUMA emulation memory chunk size" - default 0x10000000 - range 0x400000 0x100000000 - depends on NUMA_EMU - help - Select the default size by which the memory is chopped and then - assigned to emulated NUMA nodes. - - This can be overridden by specifying - - emu_size=<n> - - on the kernel command line where also suffixes K, M, G, and T are - supported. - -endmenu + int + default "1" config SCHED_SMT def_bool n @@ -867,15 +810,6 @@ config SECCOMP If unsure, say Y. -menu "Power Management" - -config ARCH_HIBERNATION_POSSIBLE - def_bool y - -source "kernel/power/Kconfig" - -endmenu - config CCW def_bool y @@ -1010,7 +944,6 @@ config S390_GUEST select TTY select VIRTUALIZATION select VIRTIO - select VIRTIO_CONSOLE help Enabling this option adds support for virtio based paravirtual device drivers on s390. diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 54f375627532..8bf46d705957 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -75,7 +75,7 @@ struct appldata_os_data { (waiting for I/O) */ /* per cpu data */ - struct appldata_os_per_cpu os_cpu[0]; + struct appldata_os_per_cpu os_cpu[]; } __attribute__((packed)); static struct appldata_os_data *appldata_os_data; diff --git a/arch/s390/boot/.gitignore b/arch/s390/boot/.gitignore index 16ff906e4610..b265bfede188 100644 --- a/arch/s390/boot/.gitignore +++ b/arch/s390/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only image bzImage section_cmp.* diff --git a/arch/s390/boot/compressed/.gitignore b/arch/s390/boot/compressed/.gitignore index e72fcd7ecebb..765a08f1bd77 100644 --- a/arch/s390/boot/compressed/.gitignore +++ b/arch/s390/boot/compressed/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux vmlinux.lds diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh index bed227f267ae..515b27a996b3 100644 --- a/arch/s390/boot/install.sh +++ b/arch/s390/boot/install.sh @@ -21,15 +21,10 @@ if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi -# Default install - same as make zlilo +echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ + "bootloader config required" >&2 +if [ -f $4/vmlinuz-$1 ]; then mv $4/vmlinuz-$1 $4/vmlinuz-$1.old; fi +if [ -f $4/System.map-$1 ]; then mv $4/System.map-$1 $4/System.map-$1.old; fi -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map +cat $2 > $4/vmlinuz-$1 +cp $3 $4/System.map-$1 diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 0c86ba19fa2b..46038bc58c9e 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -532,6 +532,7 @@ CONFIG_INPUT_EVDEV=y # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=0 CONFIG_NULL_TTY=m +CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m CONFIG_RAW_DRIVER=m CONFIG_HANGCHECK_TIMER=m diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 6b27d861a9a3..7cd0648c1f4e 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -528,6 +528,7 @@ CONFIG_INPUT_EVDEV=y # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=0 CONFIG_NULL_TTY=m +CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m CONFIG_RAW_DRIVER=m CONFIG_HANGCHECK_TIMER=m diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 1c23d84a9097..73044634d342 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -342,6 +342,7 @@ static int cbc_aes_crypt(struct skcipher_request *req, unsigned long modifier) memcpy(walk.iv, param.iv, AES_BLOCK_SIZE); ret = skcipher_walk_done(&walk, nbytes - n); } + memzero_explicit(¶m, sizeof(param)); return ret; } @@ -470,6 +471,8 @@ static int xts_aes_crypt(struct skcipher_request *req, unsigned long modifier) walk.dst.virt.addr, walk.src.virt.addr, n); ret = skcipher_walk_done(&walk, nbytes - n); } + memzero_explicit(&pcc_param, sizeof(pcc_param)); + memzero_explicit(&xts_param, sizeof(xts_param)); return ret; } diff --git a/arch/s390/include/asm/hw_irq.h b/arch/s390/include/asm/hw_irq.h index adae176757ae..9078b5b6b837 100644 --- a/arch/s390/include/asm/hw_irq.h +++ b/arch/s390/include/asm/hw_irq.h @@ -7,6 +7,5 @@ void __init init_airq_interrupts(void); void __init init_cio_interrupts(void); -void __init init_ext_interrupts(void); #endif diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 084e71b7272a..b63bd66404b8 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -119,6 +119,7 @@ enum diag308_subcode { DIAG308_LOAD_NORMAL_DUMP = 4, DIAG308_SET = 5, DIAG308_STORE = 6, + DIAG308_LOAD_NORMAL = 7, }; enum diag308_rc { diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 237ee0c4169f..612ed3c6d581 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -141,7 +141,9 @@ struct lowcore { /* br %r1 trampoline */ __u16 br_r1_trampoline; /* 0x0400 */ - __u8 pad_0x0402[0x0e00-0x0402]; /* 0x0402 */ + __u32 return_lpswe; /* 0x0402 */ + __u32 return_mcck_lpswe; /* 0x0406 */ + __u8 pad_0x040a[0x0e00-0x040a]; /* 0x040a */ /* * 0xe00 contains the address of the IPL Parameter Information diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index e21b618ad432..e12ff0f29d1a 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -34,8 +34,6 @@ typedef struct { unsigned int uses_cmm:1; /* The gmaps associated with this context are allowed to use huge pages. */ unsigned int allow_gmap_hpage_1m:1; - /* The mmu context is for compat task */ - unsigned int compat_mm:1; } mm_context_t; #define INIT_MM_CONTEXT(name) \ diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index afa836014076..c9f3d8a52756 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -18,6 +18,8 @@ static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { + unsigned long asce_type, init_entry; + spin_lock_init(&mm->context.lock); INIT_LIST_HEAD(&mm->context.pgtable_list); INIT_LIST_HEAD(&mm->context.gmap_list); @@ -26,7 +28,6 @@ static inline int init_new_context(struct task_struct *tsk, atomic_set(&mm->context.is_protected, 0); mm->context.gmap_asce = 0; mm->context.flush_mm = 0; - mm->context.compat_mm = test_thread_flag(TIF_31BIT); #ifdef CONFIG_PGSTE mm->context.alloc_pgste = page_table_allocate_pgste || test_thread_flag(TIF_PGSTE) || @@ -37,33 +38,34 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.allow_gmap_hpage_1m = 0; #endif switch (mm->context.asce_limit) { - case _REGION2_SIZE: + default: /* - * forked 3-level task, fall through to set new asce with new - * mm->pgd + * context created by exec, the value of asce_limit can + * only be zero in this case */ - case 0: - /* context created by exec, set asce limit to 4TB */ - mm->context.asce_limit = STACK_TOP_MAX; - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION3; + VM_BUG_ON(mm->context.asce_limit); + /* continue as 3-level task */ + mm->context.asce_limit = _REGION2_SIZE; + fallthrough; + case _REGION2_SIZE: + /* forked 3-level task */ + init_entry = _REGION3_ENTRY_EMPTY; + asce_type = _ASCE_TYPE_REGION3; break; - case -PAGE_SIZE: - /* forked 5-level task, set new asce with new_mm->pgd */ - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION1; + case TASK_SIZE_MAX: + /* forked 5-level task */ + init_entry = _REGION1_ENTRY_EMPTY; + asce_type = _ASCE_TYPE_REGION1; break; case _REGION1_SIZE: - /* forked 4-level task, set new asce with new mm->pgd */ - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + /* forked 4-level task */ + init_entry = _REGION2_ENTRY_EMPTY; + asce_type = _ASCE_TYPE_REGION2; break; - case _REGION3_SIZE: - /* forked 2-level compat task, set new asce with new mm->pgd */ - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; } - crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | asce_type; + crst_table_init((unsigned long *) mm->pgd, init_entry); return 0; } diff --git a/arch/s390/include/asm/numa.h b/arch/s390/include/asm/numa.h index 35f8cbe7e5bb..23cd5d1b734b 100644 --- a/arch/s390/include/asm/numa.h +++ b/arch/s390/include/asm/numa.h @@ -13,24 +13,13 @@ #ifdef CONFIG_NUMA #include <linux/numa.h> -#include <linux/cpumask.h> void numa_setup(void); -int numa_pfn_to_nid(unsigned long pfn); -int __node_distance(int a, int b); -void numa_update_cpu_topology(void); - -extern cpumask_t node_to_cpumask_map[MAX_NUMNODES]; -extern int numa_debug_enabled; #else static inline void numa_setup(void) { } -static inline void numa_update_cpu_topology(void) { } -static inline int numa_pfn_to_nid(unsigned long pfn) -{ - return 0; -} #endif /* CONFIG_NUMA */ + #endif /* _ASM_S390_NUMA_H */ diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 62440a82731a..cc98f9b78fd4 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -166,23 +166,22 @@ int arch_make_page_accessible(struct page *page); #define __pa(x) ((unsigned long)(x)) #define __va(x) ((void *)(unsigned long)(x)) -#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +#define phys_to_pfn(phys) ((phys) >> PAGE_SHIFT) +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) + +#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys)) +#define page_to_phys(page) pfn_to_phys(page_to_pfn(page)) + +#define pfn_to_virt(pfn) __va(pfn_to_phys(pfn)) +#define virt_to_pfn(kaddr) (phys_to_pfn(__pa(kaddr))) #define pfn_to_kaddr(pfn) pfn_to_virt(pfn) #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) #define page_to_virt(page) pfn_to_virt(page_to_pfn(page)) -#define phys_to_pfn(kaddr) ((kaddr) >> PAGE_SHIFT) -#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) - -#define phys_to_page(kaddr) pfn_to_page(phys_to_pfn(kaddr)) -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) - -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index b05187ce5dbd..7485ee561fec 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -5,6 +5,7 @@ #include <linux/pci.h> #include <linux/mutex.h> #include <linux/iommu.h> +#include <linux/pci_hotplug.h> #include <asm-generic/pci.h> #include <asm/pci_clp.h> #include <asm/pci_debug.h> @@ -25,6 +26,7 @@ int pci_proc_domain(struct pci_bus *); #define ZPCI_NR_DMA_SPACES 1 #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS +#define ZPCI_DOMAIN_BITMAP_SIZE (1 << 16) /* PCI Function Controls */ #define ZPCI_FC_FN_ENABLED 0x80 @@ -96,6 +98,7 @@ struct s390_domain; struct zpci_dev { struct pci_bus *bus; struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */ + struct hotplug_slot hotplug_slot; enum zpci_state state; u32 fid; /* function ID, used by sclp */ @@ -186,6 +189,9 @@ int clp_enable_fh(struct zpci_dev *, u8); int clp_disable_fh(struct zpci_dev *); int clp_get_state(u32 fid, enum zpci_state *state); +/* UID */ +void update_uid_checking(bool new); + /* IOMMU Interface */ int zpci_init_iommu(struct zpci_dev *zdev); void zpci_destroy_iommu(struct zpci_dev *zdev); diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 77606c4acd58..74a352f8c0d1 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -34,19 +34,21 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry) memset64((u64 *)crst, entry, _CRST_ENTRIES); } -static inline unsigned long pgd_entry_type(struct mm_struct *mm) +int crst_table_upgrade(struct mm_struct *mm, unsigned long limit); + +static inline unsigned long check_asce_limit(struct mm_struct *mm, unsigned long addr, + unsigned long len) { - if (mm_pmd_folded(mm)) - return _SEGMENT_ENTRY_EMPTY; - if (mm_pud_folded(mm)) - return _REGION3_ENTRY_EMPTY; - if (mm_p4d_folded(mm)) - return _REGION2_ENTRY_EMPTY; - return _REGION1_ENTRY_EMPTY; -} + int rc; -int crst_table_upgrade(struct mm_struct *mm, unsigned long limit); -void crst_table_downgrade(struct mm_struct *); + if (addr + len > mm->context.asce_limit && + addr + len <= TASK_SIZE) { + rc = crst_table_upgrade(mm, addr + len); + if (rc) + return (unsigned long) rc; + } + return addr; +} static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address) { @@ -116,24 +118,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - unsigned long *table = crst_table_alloc(mm); - - if (!table) - return NULL; - if (mm->context.asce_limit == _REGION3_SIZE) { - /* Forking a compat process with 2 page table levels */ - if (!pgtable_pmd_page_ctor(virt_to_page(table))) { - crst_table_free(mm, table); - return NULL; - } - } - return (pgd_t *) table; + return (pgd_t *) crst_table_alloc(mm); } static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { - if (mm->context.asce_limit == _REGION3_SIZE) - pgtable_pmd_page_dtor(virt_to_page(pgd)); crst_table_free(mm, (unsigned long *) pgd); } diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index aadb3d0e2adc..555d148ccf32 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -92,15 +92,15 @@ extern void __bpon(void); */ #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? \ - (1UL << 31) : -PAGE_SIZE) + _REGION3_SIZE : TASK_SIZE_MAX) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ - (1UL << 30) : (1UL << 41)) + (_REGION3_SIZE >> 1) : (_REGION2_SIZE >> 1)) #define TASK_SIZE TASK_SIZE_OF(current) #define TASK_SIZE_MAX (-PAGE_SIZE) #define STACK_TOP (test_thread_flag(TIF_31BIT) ? \ - (1UL << 31) : (1UL << 42)) -#define STACK_TOP_MAX (1UL << 42) + _REGION3_SIZE : _REGION2_SIZE) +#define STACK_TOP_MAX _REGION2_SIZE #define HAVE_ARCH_PICK_MMAP_LAYOUT @@ -161,6 +161,7 @@ typedef struct thread_struct thread_struct; #define INIT_THREAD { \ .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ .fpu.regs = (void *) init_task.thread.fpu.fprs, \ + .last_break = 1, \ } /* @@ -177,7 +178,6 @@ typedef struct thread_struct thread_struct; regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ - crst_table_downgrade(current->mm); \ execve_tail(); \ } while (0) diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index e577f8533009..86a3796e9be8 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -325,7 +325,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, /** * struct qdio_initialize - qdio initialization data - * @cdev: associated ccw device * @q_format: queue format * @qdr_ac: feature flags to set * @adapter_name: name for the adapter @@ -341,12 +340,11 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, * @irq_poll: Data IRQ polling handler (NULL when not supported) * @scan_threshold: # of in-use buffers that triggers scan on output queue * @int_parm: interruption parameter - * @input_sbal_addr_array: address of no_input_qs * 128 pointers - * @output_sbal_addr_array: address of no_output_qs * 128 pointers + * @input_sbal_addr_array: per-queue array, each element points to 128 SBALs + * @output_sbal_addr_array: per-queue array, each element points to 128 SBALs * @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL) */ struct qdio_initialize { - struct ccw_device *cdev; unsigned char q_format; unsigned char qdr_ac; unsigned char adapter_name[8]; @@ -362,8 +360,8 @@ struct qdio_initialize { void (*irq_poll)(struct ccw_device *cdev, unsigned long data); unsigned int scan_threshold; unsigned long int_parm; - struct qdio_buffer **input_sbal_addr_array; - struct qdio_buffer **output_sbal_addr_array; + struct qdio_buffer ***input_sbal_addr_array; + struct qdio_buffer ***output_sbal_addr_array; struct qdio_outbuf_state *output_sbal_state_array; }; @@ -408,8 +406,10 @@ int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count); void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count); void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count); -extern int qdio_allocate(struct qdio_initialize *); -extern int qdio_establish(struct qdio_initialize *); +extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs, + unsigned int no_output_qs); +extern int qdio_establish(struct ccw_device *cdev, + struct qdio_initialize *init_data); extern int qdio_activate(struct ccw_device *); extern void qdio_release_aob(struct qaob *); extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int, diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index b241ddb67caf..534f212753d6 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -8,6 +8,7 @@ #include <linux/bits.h> #include <uapi/asm/setup.h> +#include <linux/build_bug.h> #define EP_OFFSET 0x10008 #define EP_STRING "S390EP" @@ -162,6 +163,12 @@ static inline unsigned long kaslr_offset(void) return __kaslr_offset; } +static inline u32 gen_lpswe(unsigned long addr) +{ + BUILD_BUG_ON(addr > 0xfff); + return 0xb2b20000 | addr; +} + #else /* __ASSEMBLY__ */ #define IPL_DEVICE (IPL_DEVICE_OFFSET) diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index b157a81fb977..231a51e870fe 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -34,6 +34,7 @@ extern int smp_vcpu_scheduled(int cpu); extern void smp_yield_cpu(int cpu); extern void smp_cpu_set_polarization(int cpu, int val); extern int smp_cpu_get_polarization(int cpu); +extern int smp_cpu_get_cpu_address(int cpu); extern void smp_fill_possible_mask(void); extern void smp_detect_cpus(void); diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index cca406fdbe51..fbb507504a3b 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -16,8 +16,8 @@ struct cpu_topology_s390 { unsigned short socket_id; unsigned short book_id; unsigned short drawer_id; - unsigned short node_id; unsigned short dedicated : 1; + int booted_cores; cpumask_t thread_mask; cpumask_t core_mask; cpumask_t book_mask; @@ -25,7 +25,6 @@ struct cpu_topology_s390 { }; extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; -extern cpumask_t cpus_with_topology; #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) #define topology_thread_id(cpu) (cpu_topology[cpu].thread_id) @@ -37,6 +36,7 @@ extern cpumask_t cpus_with_topology; #define topology_drawer_id(cpu) (cpu_topology[cpu].drawer_id) #define topology_drawer_cpumask(cpu) (&cpu_topology[cpu].drawer_mask) #define topology_cpu_dedicated(cpu) (cpu_topology[cpu].dedicated) +#define topology_booted_cores(cpu) (cpu_topology[cpu].booted_cores) #define mc_capable() 1 @@ -45,6 +45,7 @@ int topology_cpu_init(struct cpu *); int topology_set_cpu_management(int fc); void topology_schedule_update(void); void store_topology(struct sysinfo_15_1_x *info); +void update_cpu_masks(void); void topology_expect_change(void); const struct cpumask *cpu_coregroup_mask(int cpu); @@ -54,6 +55,8 @@ static inline void topology_init_early(void) { } static inline void topology_schedule_update(void) { } static inline int topology_cpu_init(struct cpu *cpu) { return 0; } static inline int topology_cpu_dedicated(int cpu_nr) { return 0; } +static inline int topology_booted_cores(int cpu_nr) { return 1; } +static inline void update_cpu_masks(void) { } static inline void topology_expect_change(void) { } #endif /* CONFIG_SCHED_TOPOLOGY */ @@ -71,19 +74,23 @@ static inline void topology_expect_change(void) { } #define cpu_to_node cpu_to_node static inline int cpu_to_node(int cpu) { - return cpu_topology[cpu].node_id; + return 0; } /* Returns a pointer to the cpumask of CPUs on node 'node'. */ #define cpumask_of_node cpumask_of_node static inline const struct cpumask *cpumask_of_node(int node) { - return &node_to_cpumask_map[node]; + return cpu_possible_mask; } #define pcibus_to_node(bus) __pcibus_to_node(bus) #define node_distance(a, b) __node_distance(a, b) +static inline int __node_distance(int a, int b) +{ + return 0; +} #else /* !CONFIG_NUMA */ diff --git a/arch/s390/kernel/.gitignore b/arch/s390/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/s390/kernel/.gitignore +++ b/arch/s390/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 33d4de233c5b..75f26d775027 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -54,7 +54,6 @@ CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o -obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o obj-$(CONFIG_AUDIT) += audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index ce33406cfe83..e80f0e6f5972 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -124,6 +124,8 @@ int main(void) OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code); OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address); OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr); + OFFSET(__LC_RETURN_LPSWE, lowcore, return_lpswe); + OFFSET(__LC_RETURN_MCCK_LPSWE, lowcore, return_mcck_lpswe); OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw); OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw); OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw); diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c index e9dac9a24d3f..61f2b0412345 100644 --- a/arch/s390/kernel/diag.c +++ b/arch/s390/kernel/diag.c @@ -84,7 +84,7 @@ static int show_diag_stat(struct seq_file *m, void *v) static void *show_diag_stat_start(struct seq_file *m, loff_t *pos) { - return *pos <= nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; + return *pos <= NR_DIAG_STAT ? (void *)((unsigned long) *pos + 1) : NULL; } static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 9205add8481d..3ae64914bd14 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -115,26 +115,29 @@ _LPP_OFFSET = __LC_LPP .macro SWITCH_ASYNC savearea,timer tmhh %r8,0x0001 # interrupting from user ? - jnz 1f + jnz 2f lgr %r14,%r9 + cghi %r14,__LC_RETURN_LPSWE + je 0f slg %r14,BASED(.Lcritical_start) clg %r14,BASED(.Lcritical_length) - jhe 0f + jhe 1f +0: lghi %r11,\savearea # inside critical section, do cleanup brasl %r14,cleanup_critical tmhh %r8,0x0001 # retest problem state after cleanup - jnz 1f -0: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? + jnz 2f +1: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? slgr %r14,%r15 srag %r14,%r14,STACK_SHIFT - jnz 2f + jnz 3f CHECK_STACK \savearea aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) - j 3f -1: UPDATE_VTIME %r14,%r15,\timer + j 4f +2: UPDATE_VTIME %r14,%r15,\timer BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP -2: lg %r15,__LC_ASYNC_STACK # load async stack -3: la %r11,STACK_FRAME_OVERHEAD(%r15) +3: lg %r15,__LC_ASYNC_STACK # load async stack +4: la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro UPDATE_VTIME w1,w2,enter_timer @@ -401,7 +404,7 @@ ENTRY(system_call) stpt __LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_PSW + b __LC_RETURN_LPSWE(%r0) .Lsysc_done: # @@ -608,43 +611,50 @@ ENTRY(pgm_check_handler) BPOFF stmg %r8,%r15,__LC_SAVE_AREA_SYNC lg %r10,__LC_LAST_BREAK - lg %r12,__LC_CURRENT + srag %r11,%r10,12 + jnz 0f + /* if __LC_LAST_BREAK is < 4096, it contains one of + * the lpswe addresses in lowcore. Set it to 1 (initial state) + * to prevent leaking that address to userspace. + */ + lghi %r10,1 +0: lg %r12,__LC_CURRENT lghi %r11,0 larl %r13,cleanup_critical lmg %r8,%r9,__LC_PGM_OLD_PSW tmhh %r8,0x0001 # test problem state bit - jnz 2f # -> fault in user space + jnz 3f # -> fault in user space #if IS_ENABLED(CONFIG_KVM) # cleanup critical section for program checks in sie64a lgr %r14,%r9 slg %r14,BASED(.Lsie_critical_start) clg %r14,BASED(.Lsie_critical_length) - jhe 0f + jhe 1f lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE lctlg %c1,%c1,__LC_USER_ASCE # load primary asce larl %r9,sie_exit # skip forward to sie_exit lghi %r11,_PIF_GUEST_FAULT #endif -0: tmhh %r8,0x4000 # PER bit set in old PSW ? - jnz 1f # -> enabled, can't be a double fault +1: tmhh %r8,0x4000 # PER bit set in old PSW ? + jnz 2f # -> enabled, can't be a double fault tm __LC_PGM_ILC+3,0x80 # check for per exception jnz .Lpgm_svcper # -> single stepped svc -1: CHECK_STACK __LC_SAVE_AREA_SYNC +2: CHECK_STACK __LC_SAVE_AREA_SYNC aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) - # CHECK_VMAP_STACK branches to stack_overflow or 4f - CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f -2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER + # CHECK_VMAP_STACK branches to stack_overflow or 5f + CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f +3: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP lg %r15,__LC_KERNEL_STACK lgr %r14,%r12 aghi %r14,__TASK_thread # pointer to thread_struct lghi %r13,__LC_PGM_TDB tm __LC_PGM_ILC+2,0x02 # check for transaction abort - jz 3f + jz 4f mvc __THREAD_trap_tdb(256,%r14),0(%r13) -3: stg %r10,__THREAD_last_break(%r14) -4: lgr %r13,%r11 +4: stg %r10,__THREAD_last_break(%r14) +5: lgr %r13,%r11 la %r11,STACK_FRAME_OVERHEAD(%r15) stmg %r0,%r7,__PT_R0(%r11) # clear user controlled registers to prevent speculative use @@ -663,14 +673,14 @@ ENTRY(pgm_check_handler) stg %r13,__PT_FLAGS(%r11) stg %r10,__PT_ARGS(%r11) tm __LC_PGM_ILC+3,0x80 # check for per exception - jz 5f + jz 6f tmhh %r8,0x0001 # kernel per event ? jz .Lpgm_kprobe oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID -5: REENABLE_IRQS +6: REENABLE_IRQS xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) larl %r1,pgm_check_table llgh %r10,__PT_INT_CODE+2(%r11) @@ -775,7 +785,7 @@ ENTRY(io_int_handler) mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER .Lio_exit_kernel: lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_PSW + b __LC_RETURN_LPSWE(%r0) .Lio_done: # @@ -1214,7 +1224,7 @@ ENTRY(mcck_int_handler) stpt __LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 0: lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_MCCK_PSW + b __LC_RETURN_MCCK_LPSWE .Lmcck_panic: lg %r15,__LC_NODAT_STACK @@ -1271,6 +1281,8 @@ ENDPROC(stack_overflow) #endif ENTRY(cleanup_critical) + cghi %r9,__LC_RETURN_LPSWE + je .Lcleanup_lpswe #if IS_ENABLED(CONFIG_KVM) clg %r9,BASED(.Lcleanup_table_sie) # .Lsie_gmap jl 0f @@ -1424,6 +1436,7 @@ ENDPROC(cleanup_critical) mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) mvc 0(64,%r11),__PT_R8(%r9) lmg %r0,%r7,__PT_R0(%r9) +.Lcleanup_lpswe: 1: lmg %r8,%r9,__LC_RETURN_PSW BR_EX %r14,%r11 .Lcleanup_sysc_restore_insn: diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 6837affc19e8..4a71061974fd 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -144,6 +144,9 @@ static struct ipl_parameter_block *dump_block_ccw; static struct sclp_ipl_info sclp_ipl_info; +static bool reipl_fcp_clear; +static bool reipl_ccw_clear; + static inline int __diag308(unsigned long subcode, void *addr) { register unsigned long _addr asm("0") = (unsigned long) addr; @@ -691,6 +694,21 @@ static struct kobj_attribute sys_reipl_fcp_loadparm_attr = __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show, reipl_fcp_loadparm_store); +static ssize_t reipl_fcp_clear_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return sprintf(page, "%u\n", reipl_fcp_clear); +} + +static ssize_t reipl_fcp_clear_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + if (strtobool(buf, &reipl_fcp_clear) < 0) + return -EINVAL; + return len; +} + static struct attribute *reipl_fcp_attrs[] = { &sys_reipl_fcp_device_attr.attr, &sys_reipl_fcp_wwpn_attr.attr, @@ -706,6 +724,9 @@ static struct attribute_group reipl_fcp_attr_group = { .bin_attrs = reipl_fcp_bin_attrs, }; +static struct kobj_attribute sys_reipl_fcp_clear_attr = + __ATTR(clear, 0644, reipl_fcp_clear_show, reipl_fcp_clear_store); + /* CCW reipl device attributes */ DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ccw); @@ -741,16 +762,36 @@ static struct kobj_attribute sys_reipl_ccw_loadparm_attr = __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show, reipl_ccw_loadparm_store); +static ssize_t reipl_ccw_clear_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return sprintf(page, "%u\n", reipl_ccw_clear); +} + +static ssize_t reipl_ccw_clear_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + if (strtobool(buf, &reipl_ccw_clear) < 0) + return -EINVAL; + return len; +} + +static struct kobj_attribute sys_reipl_ccw_clear_attr = + __ATTR(clear, 0644, reipl_ccw_clear_show, reipl_ccw_clear_store); + static struct attribute *reipl_ccw_attrs_vm[] = { &sys_reipl_ccw_device_attr.attr, &sys_reipl_ccw_loadparm_attr.attr, &sys_reipl_ccw_vmparm_attr.attr, + &sys_reipl_ccw_clear_attr.attr, NULL, }; static struct attribute *reipl_ccw_attrs_lpar[] = { &sys_reipl_ccw_device_attr.attr, &sys_reipl_ccw_loadparm_attr.attr, + &sys_reipl_ccw_clear_attr.attr, NULL, }; @@ -892,11 +933,17 @@ static void __reipl_run(void *unused) switch (reipl_type) { case IPL_TYPE_CCW: diag308(DIAG308_SET, reipl_block_ccw); - diag308(DIAG308_LOAD_CLEAR, NULL); + if (reipl_ccw_clear) + diag308(DIAG308_LOAD_CLEAR, NULL); + else + diag308(DIAG308_LOAD_NORMAL_DUMP, NULL); break; case IPL_TYPE_FCP: diag308(DIAG308_SET, reipl_block_fcp); - diag308(DIAG308_LOAD_CLEAR, NULL); + if (reipl_fcp_clear) + diag308(DIAG308_LOAD_CLEAR, NULL); + else + diag308(DIAG308_LOAD_NORMAL, NULL); break; case IPL_TYPE_NSS: diag308(DIAG308_SET, reipl_block_nss); @@ -1008,11 +1055,16 @@ static int __init reipl_fcp_init(void) } rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); - if (rc) { - kset_unregister(reipl_fcp_kset); - free_page((unsigned long) reipl_block_fcp); - return rc; - } + if (rc) + goto out1; + + if (test_facility(141)) { + rc = sysfs_create_file(&reipl_fcp_kset->kobj, + &sys_reipl_fcp_clear_attr.attr); + if (rc) + goto out2; + } else + reipl_fcp_clear = true; if (ipl_info.type == IPL_TYPE_FCP) { memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block)); @@ -1032,6 +1084,13 @@ static int __init reipl_fcp_init(void) } reipl_capabilities |= IPL_TYPE_FCP; return 0; + +out2: + sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); +out1: + kset_unregister(reipl_fcp_kset); + free_page((unsigned long) reipl_block_fcp); + return rc; } static int __init reipl_type_init(void) diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 8371855042dc..3514420f0259 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -95,14 +95,6 @@ static const struct irq_class irqclass_sub_desc[] = { {.irq = CPU_RST, .name = "RST", .desc = "[CPU] CPU Restart"}, }; -void __init init_IRQ(void) -{ - BUILD_BUG_ON(ARRAY_SIZE(irqclass_sub_desc) != NR_ARCH_IRQS); - init_cio_interrupts(); - init_airq_interrupts(); - init_ext_interrupts(); -} - void do_IRQ(struct pt_regs *regs, int irq) { struct pt_regs *old_regs; @@ -294,12 +286,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy) return IRQ_HANDLED; } -static struct irqaction external_interrupt = { - .name = "EXT", - .handler = do_ext_interrupt, -}; - -void __init init_ext_interrupts(void) +static void __init init_ext_interrupts(void) { int idx; @@ -308,7 +295,16 @@ void __init init_ext_interrupts(void) irq_set_chip_and_handler(EXT_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); - setup_irq(EXT_INTERRUPT, &external_interrupt); + if (request_irq(EXT_INTERRUPT, do_ext_interrupt, 0, "EXT", NULL)) + panic("Failed to register EXT interrupt\n"); +} + +void __init init_IRQ(void) +{ + BUILD_BUG_ON(ARRAY_SIZE(irqclass_sub_desc) != NR_ARCH_IRQS); + init_cio_interrupts(); + init_airq_interrupts(); + init_ext_interrupts(); } static DEFINE_SPINLOCK(irq_subclass_lock); diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index cb8b1cc285c9..3a854cb5a4c6 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -14,7 +14,6 @@ #include <linux/reboot.h> #include <linux/ftrace.h> #include <linux/debug_locks.h> -#include <linux/suspend.h> #include <asm/cio.h> #include <asm/setup.h> #include <asm/pgtable.h> @@ -39,36 +38,6 @@ extern const unsigned long long relocate_kernel_len; #ifdef CONFIG_CRASH_DUMP /* - * PM notifier callback for kdump - */ -static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - if (kexec_crash_image) - arch_kexec_unprotect_crashkres(); - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - if (kexec_crash_image) - arch_kexec_protect_crashkres(); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init machine_kdump_pm_init(void) -{ - pm_notifier(machine_kdump_pm_cb, 0); - return 0; -} -arch_initcall(machine_kdump_pm_init); - -/* * Reset the system, copy boot CPU registers to absolute zero, * and jump to the kdump image */ diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c index 8b33e03e47b8..1e3df52b2b65 100644 --- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c @@ -238,6 +238,64 @@ CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_SPECIAL, 0x00f5); CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); +CPUMF_EVENT_ATTR(cf_z15, L1D_RO_EXCL_WRITES, 0x0080); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_WRITES, 0x0081); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_MISSES, 0x0082); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_HPAGE_WRITES, 0x0083); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_GPAGE_WRITES, 0x0084); +CPUMF_EVENT_ATTR(cf_z15, L1D_L2D_SOURCED_WRITES, 0x0085); +CPUMF_EVENT_ATTR(cf_z15, ITLB2_WRITES, 0x0086); +CPUMF_EVENT_ATTR(cf_z15, ITLB2_MISSES, 0x0087); +CPUMF_EVENT_ATTR(cf_z15, L1I_L2I_SOURCED_WRITES, 0x0088); +CPUMF_EVENT_ATTR(cf_z15, TLB2_PTE_WRITES, 0x0089); +CPUMF_EVENT_ATTR(cf_z15, TLB2_CRSTE_WRITES, 0x008a); +CPUMF_EVENT_ATTR(cf_z15, TLB2_ENGINES_BUSY, 0x008b); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TEND, 0x008c); +CPUMF_EVENT_ATTR(cf_z15, TX_NC_TEND, 0x008d); +CPUMF_EVENT_ATTR(cf_z15, L1C_TLB2_MISSES, 0x008f); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0090); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_MEMORY_SOURCED_WRITES, 0x0091); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_IV, 0x0092); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES, 0x0093); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_MEMORY_SOURCED_WRITES, 0x0094); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES_IV, 0x0095); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES, 0x0096); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES, 0x0097); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV, 0x0098); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES, 0x0099); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_MEMORY_SOURCED_WRITES, 0x009a); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES_IV, 0x009b); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONDRAWER_L4_SOURCED_WRITES, 0x009c); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L4_SOURCED_WRITES, 0x009d); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_RO, 0x009e); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES, 0x00a2); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_MEMORY_SOURCED_WRITES, 0x00a3); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES_IV, 0x00a4); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES, 0x00a5); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_MEMORY_SOURCED_WRITES, 0x00a6); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES_IV, 0x00a7); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES, 0x00a8); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES, 0x00a9); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV, 0x00aa); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES, 0x00ab); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_MEMORY_SOURCED_WRITES, 0x00ac); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES_IV, 0x00ad); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONDRAWER_L4_SOURCED_WRITES, 0x00ae); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L4_SOURCED_WRITES, 0x00af); +CPUMF_EVENT_ATTR(cf_z15, BCD_DFP_EXECUTION_SLOTS, 0x00e0); +CPUMF_EVENT_ATTR(cf_z15, VX_BCD_EXECUTION_SLOTS, 0x00e1); +CPUMF_EVENT_ATTR(cf_z15, DECIMAL_INSTRUCTIONS, 0x00e2); +CPUMF_EVENT_ATTR(cf_z15, LAST_HOST_TRANSLATIONS, 0x00e8); +CPUMF_EVENT_ATTR(cf_z15, TX_NC_TABORT, 0x00f3); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TABORT_NO_SPECIAL, 0x00f4); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TABORT_SPECIAL, 0x00f5); +CPUMF_EVENT_ATTR(cf_z15, DFLT_ACCESS, 0x00f7); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CYCLES, 0x00fc); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CC, 0x00108); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CCERROR, 0x00109); +CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); +CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); + static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = { CPUMF_EVENT_PTR(cf_fvn1, CPU_CYCLES), CPUMF_EVENT_PTR(cf_fvn1, INSTRUCTIONS), @@ -516,6 +574,67 @@ static struct attribute *cpumcf_z14_pmu_event_attr[] __initdata = { NULL, }; +static struct attribute *cpumcf_z15_pmu_event_attr[] __initdata = { + CPUMF_EVENT_PTR(cf_z15, L1D_RO_EXCL_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_HPAGE_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_GPAGE_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_L2D_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, ITLB2_WRITES), + CPUMF_EVENT_PTR(cf_z15, ITLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, L1I_L2I_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_PTE_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_CRSTE_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_ENGINES_BUSY), + CPUMF_EVENT_PTR(cf_z15, TX_C_TEND), + CPUMF_EVENT_PTR(cf_z15, TX_NC_TEND), + CPUMF_EVENT_PTR(cf_z15, L1C_TLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_ONDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_RO), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_ONDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, BCD_DFP_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z15, VX_BCD_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z15, DECIMAL_INSTRUCTIONS), + CPUMF_EVENT_PTR(cf_z15, LAST_HOST_TRANSLATIONS), + CPUMF_EVENT_PTR(cf_z15, TX_NC_TABORT), + CPUMF_EVENT_PTR(cf_z15, TX_C_TABORT_NO_SPECIAL), + CPUMF_EVENT_PTR(cf_z15, TX_C_TABORT_SPECIAL), + CPUMF_EVENT_PTR(cf_z15, DFLT_ACCESS), + CPUMF_EVENT_PTR(cf_z15, DFLT_CYCLES), + CPUMF_EVENT_PTR(cf_z15, DFLT_CC), + CPUMF_EVENT_PTR(cf_z15, DFLT_CCERROR), + CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE), + CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE), + NULL, +}; + /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ static struct attribute_group cpumcf_pmu_events_group = { @@ -624,9 +743,11 @@ __init const struct attribute_group **cpumf_cf_event_group(void) break; case 0x3906: case 0x3907: + model = cpumcf_z14_pmu_event_attr; + break; case 0x8561: case 0x8562: - model = cpumcf_z14_pmu_event_attr; + model = cpumcf_z15_pmu_event_attr; break; default: model = none; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index b095b1c78987..85a711d783eb 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -372,28 +372,33 @@ static void deallocate_buffers(struct cpu_hw_sf *cpuhw) static int allocate_buffers(struct cpu_hw_sf *cpuhw, struct hw_perf_event *hwc) { - unsigned long n_sdb, freq, factor; + unsigned long n_sdb, freq; size_t sample_size; /* Calculate sampling buffers using 4K pages * - * 1. Determine the sample data size which depends on the used - * sampling functions, for example, basic-sampling or - * basic-sampling with diagnostic-sampling. + * 1. The sampling size is 32 bytes for basic sampling. This size + * is the same for all machine types. Diagnostic + * sampling uses auxlilary data buffer setup which provides the + * memory for SDBs using linux common code auxiliary trace + * setup. * - * 2. Use the sampling frequency as input. The sampling buffer is - * designed for almost one second. This can be adjusted through - * the "factor" variable. - * In any case, alloc_sampling_buffer() sets the Alert Request + * 2. Function alloc_sampling_buffer() sets the Alert Request * Control indicator to trigger a measurement-alert to harvest - * sample-data-blocks (sdb). + * sample-data-blocks (SDB). This is done per SDB. This + * measurement alert interrupt fires quick enough to handle + * one SDB, on very high frequency and work loads there might + * be 2 to 3 SBDs available for sample processing. + * Currently there is no need for setup alert request on every + * n-th page. This is counterproductive as one IRQ triggers + * a very high number of samples to be processed at one IRQ. * - * 3. Compute the number of sample-data-blocks and ensure a minimum - * of CPUM_SF_MIN_SDB. Also ensure the upper limit does not - * exceed a "calculated" maximum. The symbolic maximum is - * designed for basic-sampling only and needs to be increased if - * diagnostic-sampling is active. - * See also the remarks for these symbolic constants. + * 3. Use the sampling frequency as input. + * Compute the number of SDBs and ensure a minimum + * of CPUM_SF_MIN_SDB. Depending on frequency add some more + * SDBs to handle a higher sampling rate. + * Use a minimum of CPUM_SF_MIN_SDB and allow for 100 samples + * (one SDB) for every 10000 HZ frequency increment. * * 4. Compute the number of sample-data-block-tables (SDBT) and * ensure a minimum of CPUM_SF_MIN_SDBT (one table can manage up @@ -401,10 +406,7 @@ static int allocate_buffers(struct cpu_hw_sf *cpuhw, struct hw_perf_event *hwc) */ sample_size = sizeof(struct hws_basic_entry); freq = sample_rate_to_freq(&cpuhw->qsi, SAMPL_RATE(hwc)); - factor = 1; - n_sdb = DIV_ROUND_UP(freq, factor * ((PAGE_SIZE-64) / sample_size)); - if (n_sdb < CPUM_SF_MIN_SDB) - n_sdb = CPUM_SF_MIN_SDB; + n_sdb = CPUM_SF_MIN_SDB + DIV_ROUND_UP(freq, 10000); /* If there is already a sampling buffer allocated, it is very likely * that the sampling facility is enabled too. If the event to be @@ -1576,6 +1578,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw) unsigned long range = 0, size; unsigned long long overflow = 0; struct perf_output_handle *handle = &cpuhw->handle; + unsigned long num_sdb; aux = perf_get_aux(handle); if (WARN_ON_ONCE(!aux)) @@ -1587,13 +1590,14 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw) size >> PAGE_SHIFT); perf_aux_output_end(handle, size); + num_sdb = aux->sfb.num_sdb; while (!done) { /* Get an output handle */ aux = perf_aux_output_begin(handle, cpuhw->event); if (handle->size == 0) { pr_err("The AUX buffer with %lu pages for the " "diagnostic-sampling mode is full\n", - aux->sfb.num_sdb); + num_sdb); debug_sprintf_event(sfdbg, 1, "%s: AUX buffer used up\n", __func__); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 6ccef5f29761..eb6e23ad15a2 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -106,6 +106,7 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp, p->thread.system_timer = 0; p->thread.hardirq_timer = 0; p->thread.softirq_timer = 0; + p->thread.last_break = 1; frame->sf.back_chain = 0; /* new return point is ret_from_fork */ diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 6ebc2117c66c..c92d04f876cb 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -151,10 +151,35 @@ static void show_cpu_summary(struct seq_file *m, void *v) } } +static void show_cpu_topology(struct seq_file *m, unsigned long n) +{ +#ifdef CONFIG_SCHED_TOPOLOGY + seq_printf(m, "physical id : %d\n", topology_physical_package_id(n)); + seq_printf(m, "core id : %d\n", topology_core_id(n)); + seq_printf(m, "book id : %d\n", topology_book_id(n)); + seq_printf(m, "drawer id : %d\n", topology_drawer_id(n)); + seq_printf(m, "dedicated : %d\n", topology_cpu_dedicated(n)); + seq_printf(m, "address : %d\n", smp_cpu_get_cpu_address(n)); + seq_printf(m, "siblings : %d\n", cpumask_weight(topology_core_cpumask(n))); + seq_printf(m, "cpu cores : %d\n", topology_booted_cores(n)); +#endif /* CONFIG_SCHED_TOPOLOGY */ +} + +static void show_cpu_ids(struct seq_file *m, unsigned long n) +{ + struct cpuid *id = &per_cpu(cpu_info.cpu_id, n); + + seq_printf(m, "version : %02X\n", id->version); + seq_printf(m, "identification : %06X\n", id->ident); + seq_printf(m, "machine : %04X\n", id->machine); +} + static void show_cpu_mhz(struct seq_file *m, unsigned long n) { struct cpu_info *c = per_cpu_ptr(&cpu_info, n); + if (!machine_has_cpu_mhz) + return; seq_printf(m, "cpu MHz dynamic : %d\n", c->cpu_mhz_dynamic); seq_printf(m, "cpu MHz static : %d\n", c->cpu_mhz_static); } @@ -165,12 +190,13 @@ static void show_cpu_mhz(struct seq_file *m, unsigned long n) static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long n = (unsigned long) v - 1; + unsigned long first = cpumask_first(cpu_online_mask); - if (!n) + if (n == first) show_cpu_summary(m, v); - if (!machine_has_cpu_mhz) - return 0; seq_printf(m, "\ncpu number : %ld\n", n); + show_cpu_topology(m, n); + show_cpu_ids(m, n); show_cpu_mhz(m, n); return 0; } @@ -179,6 +205,8 @@ static inline void *c_update(loff_t *pos) { if (*pos) *pos = cpumask_next(*pos - 1, cpu_online_mask); + else + *pos = cpumask_first(cpu_online_mask); return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1423090a2259..36445dd40fdb 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -73,6 +73,7 @@ #include <asm/nospec-branch.h> #include <asm/mem_detect.h> #include <asm/uv.h> +#include <asm/asm-offsets.h> #include "entry.h" /* @@ -446,6 +447,8 @@ static void __init setup_lowcore_dat_off(void) lc->spinlock_index = 0; arch_spin_lock_setup(0); lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; @@ -789,6 +792,7 @@ static void __init memblock_add_mem_detect_info(void) memblock_physmem_add(start, end - start); } memblock_set_bottom_up(false); + memblock_set_node(0, ULONG_MAX, &memblock.memory, 0); memblock_dump_all(); } diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index e6fca5498e1f..b295090e2ce6 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -487,7 +487,7 @@ void do_signal(struct pt_regs *regs) regs->gprs[2] = -EINTR; break; } - /* fallthrough */ + fallthrough; case -ERESTARTNOINTR: regs->gprs[2] = regs->orig_gpr2; regs->psw.addr = @@ -514,7 +514,7 @@ void do_signal(struct pt_regs *regs) case -ERESTART_RESTARTBLOCK: /* Restart with sys_restart_syscall */ regs->int_code = __NR_restart_syscall; - /* fallthrough */ + fallthrough; case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a08bd2522dd9..7eaabbab2213 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -212,6 +212,8 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) lc->spinlock_lockval = arch_spin_lockval(cpu); lc->spinlock_index = 0; lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); if (nmi_alloc_per_cpu(lc)) goto out_async; if (vdso_alloc_per_cpu(lc)) @@ -701,6 +703,11 @@ int smp_cpu_get_polarization(int cpu) return pcpu_devices[cpu].polarization; } +int smp_cpu_get_cpu_address(int cpu) +{ + return pcpu_devices[cpu].address; +} + static void __ref smp_get_core_info(struct sclp_core_info *info, int early) { static int use_sigp_detection; @@ -851,12 +858,13 @@ static void smp_init_secondary(void) init_cpu_timer(); vtime_init(); pfault_init(); - notify_cpu_starting(smp_processor_id()); + notify_cpu_starting(cpu); if (topology_cpu_dedicated(cpu)) set_cpu_flag(CIF_DEDICATED_CPU); else clear_cpu_flag(CIF_DEDICATED_CPU); - set_cpu_online(smp_processor_id(), true); + set_cpu_online(cpu, true); + update_cpu_masks(); inc_irq_stat(CPU_RST); local_irq_enable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); @@ -928,6 +936,7 @@ int __cpu_disable(void) /* Handle possible pending IPIs */ smp_handle_ext_call(); set_cpu_online(smp_processor_id(), false); + update_cpu_masks(); /* Disable pseudo page faults on this cpu. */ pfault_fini(); /* Disable interrupt sources via control register. */ diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c deleted file mode 100644 index 75b7b307946e..000000000000 --- a/arch/s390/kernel/suspend.c +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Suspend support specific for s390. - * - * Copyright IBM Corp. 2009 - * - * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> - */ - -#include <linux/pfn.h> -#include <linux/suspend.h> -#include <linux/mm.h> -#include <linux/pci.h> -#include <asm/ctl_reg.h> -#include <asm/ipl.h> -#include <asm/cio.h> -#include <asm/sections.h> -#include "entry.h" - -/* - * The restore of the saved pages in an hibernation image will set - * the change and referenced bits in the storage key for each page. - * Overindication of the referenced bits after an hibernation cycle - * does not cause any harm but the overindication of the change bits - * would cause trouble. - * Use the ARCH_SAVE_PAGE_KEYS hooks to save the storage key of each - * page to the most significant byte of the associated page frame - * number in the hibernation image. - */ - -/* - * Key storage is allocated as a linked list of pages. - * The size of the keys array is (PAGE_SIZE - sizeof(long)) - */ -struct page_key_data { - struct page_key_data *next; - unsigned char data[]; -}; - -#define PAGE_KEY_DATA_SIZE (PAGE_SIZE - sizeof(struct page_key_data *)) - -static struct page_key_data *page_key_data; -static struct page_key_data *page_key_rp, *page_key_wp; -static unsigned long page_key_rx, page_key_wx; -unsigned long suspend_zero_pages; - -/* - * For each page in the hibernation image one additional byte is - * stored in the most significant byte of the page frame number. - * On suspend no additional memory is required but on resume the - * keys need to be memorized until the page data has been restored. - * Only then can the storage keys be set to their old state. - */ -unsigned long page_key_additional_pages(unsigned long pages) -{ - return DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE); -} - -/* - * Free page_key_data list of arrays. - */ -void page_key_free(void) -{ - struct page_key_data *pkd; - - while (page_key_data) { - pkd = page_key_data; - page_key_data = pkd->next; - free_page((unsigned long) pkd); - } -} - -/* - * Allocate page_key_data list of arrays with enough room to store - * one byte for each page in the hibernation image. - */ -int page_key_alloc(unsigned long pages) -{ - struct page_key_data *pk; - unsigned long size; - - size = DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE); - while (size--) { - pk = (struct page_key_data *) get_zeroed_page(GFP_KERNEL); - if (!pk) { - page_key_free(); - return -ENOMEM; - } - pk->next = page_key_data; - page_key_data = pk; - } - page_key_rp = page_key_wp = page_key_data; - page_key_rx = page_key_wx = 0; - return 0; -} - -/* - * Save the storage key into the upper 8 bits of the page frame number. - */ -void page_key_read(unsigned long *pfn) -{ - struct page *page; - unsigned long addr; - unsigned char key; - - page = pfn_to_page(*pfn); - addr = (unsigned long) page_address(page); - key = (unsigned char) page_get_storage_key(addr) & 0x7f; - if (arch_test_page_nodat(page)) - key |= 0x80; - *(unsigned char *) pfn = key; -} - -/* - * Extract the storage key from the upper 8 bits of the page frame number - * and store it in the page_key_data list of arrays. - */ -void page_key_memorize(unsigned long *pfn) -{ - page_key_wp->data[page_key_wx] = *(unsigned char *) pfn; - *(unsigned char *) pfn = 0; - if (++page_key_wx < PAGE_KEY_DATA_SIZE) - return; - page_key_wp = page_key_wp->next; - page_key_wx = 0; -} - -/* - * Get the next key from the page_key_data list of arrays and set the - * storage key of the page referred by @address. If @address refers to - * a "safe" page the swsusp_arch_resume code will transfer the storage - * key from the buffer page to the original page. - */ -void page_key_write(void *address) -{ - struct page *page; - unsigned char key; - - key = page_key_rp->data[page_key_rx]; - page_set_storage_key((unsigned long) address, key & 0x7f, 0); - page = virt_to_page(address); - if (key & 0x80) - arch_set_page_nodat(page, 0); - else - arch_set_page_dat(page, 0); - if (++page_key_rx >= PAGE_KEY_DATA_SIZE) - return; - page_key_rp = page_key_rp->next; - page_key_rx = 0; -} - -int pfn_is_nosave(unsigned long pfn) -{ - unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); - unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end)); - unsigned long end_rodata_pfn = PFN_DOWN(__pa(__end_rodata)) - 1; - unsigned long stext_pfn = PFN_DOWN(__pa(_stext)); - - /* Always save lowcore pages (LC protection might be enabled). */ - if (pfn <= LC_PAGES) - return 0; - if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) - return 1; - /* Skip memory holes and read-only pages (DCSS, ...). */ - if (pfn >= stext_pfn && pfn <= end_rodata_pfn) - return 0; - if (tprot(PFN_PHYS(pfn))) - return 1; - return 0; -} - -/* - * PM notifier callback for suspend - */ -static int suspend_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER); - if (!suspend_zero_pages) - return NOTIFY_BAD; - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - free_pages(suspend_zero_pages, LC_ORDER); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init suspend_pm_init(void) -{ - pm_notifier(suspend_pm_cb, 0); - return 0; -} -arch_initcall(suspend_pm_init); - -void save_processor_state(void) -{ - /* swsusp_arch_suspend() actually saves all cpu register contents. - * Machine checks must be disabled since swsusp_arch_suspend() stores - * register contents to their lowcore save areas. That's the same - * place where register contents on machine checks would be saved. - * To avoid register corruption disable machine checks. - * We must also disable machine checks in the new psw mask for - * program checks, since swsusp_arch_suspend() may generate program - * checks. Disabling machine checks for all other new psw masks is - * just paranoia. - */ - local_mcck_disable(); - /* Disable lowcore protection */ - __ctl_clear_bit(0,28); - S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK; - S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK; - S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK; - S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK; -} - -void restore_processor_state(void) -{ - S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK; - S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK; - S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK; - S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK; - /* Enable lowcore protection */ - __ctl_set_bit(0,28); - local_mcck_enable(); -} - -/* Called at the end of swsusp_arch_resume */ -void s390_early_resume(void) -{ - lgr_info_log(); - channel_subsystem_reinit(); - zpci_rescan(); -} diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S deleted file mode 100644 index a7baf0b5f818..000000000000 --- a/arch/s390/kernel/swsusp.S +++ /dev/null @@ -1,276 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * S390 64-bit swsusp implementation - * - * Copyright IBM Corp. 2009 - * - * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> - * Michael Holzheu <holzheu@linux.vnet.ibm.com> - */ - -#include <linux/linkage.h> -#include <asm/page.h> -#include <asm/ptrace.h> -#include <asm/thread_info.h> -#include <asm/asm-offsets.h> -#include <asm/nospec-insn.h> -#include <asm/sigp.h> - -/* - * Save register context in absolute 0 lowcore and call swsusp_save() to - * create in-memory kernel image. The context is saved in the designated - * "store status" memory locations (see POP). - * We return from this function twice. The first time during the suspend to - * disk process. The second time via the swsusp_arch_resume() function - * (see below) in the resume process. - * This function runs with disabled interrupts. - */ - GEN_BR_THUNK %r14 - - .section .text -ENTRY(swsusp_arch_suspend) - lg %r1,__LC_NODAT_STACK - stmg %r6,%r15,__SF_GPRS(%r1) - aghi %r1,-STACK_FRAME_OVERHEAD - stg %r15,__SF_BACKCHAIN(%r1) - lgr %r15,%r1 - - /* Store FPU registers */ - brasl %r14,save_fpu_regs - - /* Deactivate DAT */ - stnsm __SF_EMPTY(%r15),0xfb - - /* Store prefix register on stack */ - stpx __SF_EMPTY(%r15) - - /* Save prefix register contents for lowcore copy */ - llgf %r10,__SF_EMPTY(%r15) - - /* Get pointer to save area */ - lghi %r1,0x1000 - - /* Save CPU address */ - stap __LC_EXT_CPU_ADDR(%r0) - - /* Store registers */ - mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ - stam %a0,%a15,0x340(%r1) /* store access registers */ - stctg %c0,%c15,0x380(%r1) /* store control registers */ - stmg %r0,%r15,0x280(%r1) /* store general registers */ - - stpt 0x328(%r1) /* store timer */ - stck __SF_EMPTY(%r15) /* store clock */ - stckc 0x330(%r1) /* store clock comparator */ - - /* Update cputime accounting before going to sleep */ - lg %r0,__LC_LAST_UPDATE_TIMER - slg %r0,0x328(%r1) - alg %r0,__LC_SYSTEM_TIMER - stg %r0,__LC_SYSTEM_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),0x328(%r1) - lg %r0,__LC_LAST_UPDATE_CLOCK - slg %r0,__SF_EMPTY(%r15) - alg %r0,__LC_STEAL_TIMER - stg %r0,__LC_STEAL_TIMER - mvc __LC_LAST_UPDATE_CLOCK(8),__SF_EMPTY(%r15) - - /* Activate DAT */ - stosm __SF_EMPTY(%r15),0x04 - - /* Set prefix page to zero */ - xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) - spx __SF_EMPTY(%r15) - - /* Save absolute zero pages */ - larl %r2,suspend_zero_pages - lg %r2,0(%r2) - lghi %r4,0 - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - - /* Copy lowcore to absolute zero lowcore */ - lghi %r2,0 - lgr %r4,%r10 - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - - /* Save image */ - brasl %r14,swsusp_save - - /* Restore prefix register and return */ - lghi %r1,0x1000 - spx 0x318(%r1) - lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) - lghi %r2,0 - BR_EX %r14 -ENDPROC(swsusp_arch_suspend) - -/* - * Restore saved memory image to correct place and restore register context. - * Then we return to the function that called swsusp_arch_suspend(). - * swsusp_arch_resume() runs with disabled interrupts. - */ -ENTRY(swsusp_arch_resume) - stmg %r6,%r15,__SF_GPRS(%r15) - lgr %r1,%r15 - aghi %r15,-STACK_FRAME_OVERHEAD - stg %r1,__SF_BACKCHAIN(%r15) - - /* Make all free pages stable */ - lghi %r2,1 - brasl %r14,arch_set_page_states - - /* Set prefix page to zero */ - xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) - spx __SF_EMPTY(%r15) - - /* Deactivate DAT */ - stnsm __SF_EMPTY(%r15),0xfb - - /* Restore saved image */ - larl %r1,restore_pblist - lg %r1,0(%r1) - ltgr %r1,%r1 - jz 2f -0: - lg %r2,8(%r1) - lg %r4,0(%r1) - iske %r0,%r4 - lghi %r3,PAGE_SIZE - lghi %r5,PAGE_SIZE -1: - mvcle %r2,%r4,0 - jo 1b - lg %r2,8(%r1) - sske %r0,%r2 - lg %r1,16(%r1) - ltgr %r1,%r1 - jnz 0b -2: - ptlb /* flush tlb */ - - /* Reset System */ - larl %r1,.Lnew_pgm_check_psw - epsw %r2,%r3 - stm %r2,%r3,0(%r1) - mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1) - larl %r1,__swsusp_reset_dma - lg %r1,0(%r1) - BASR_EX %r14,%r1 - larl %r1,smp_cpu_mt_shift - icm %r1,15,0(%r1) - jz smt_done - llgfr %r1,%r1 -smt_loop: - sigp %r1,%r0,SIGP_SET_MULTI_THREADING - brc 8,smt_done /* accepted */ - brc 2,smt_loop /* busy, try again */ -smt_done: - larl %r1,.Lnew_pgm_check_psw - lpswe 0(%r1) -pgm_check_entry: - - /* Switch to original suspend CPU */ - larl %r1,.Lresume_cpu /* Resume CPU address: r2 */ - stap 0(%r1) - llgh %r2,0(%r1) - llgh %r1,__LC_EXT_CPU_ADDR(%r0) /* Suspend CPU address: r1 */ - cgr %r1,%r2 - je restore_registers /* r1 = r2 -> nothing to do */ - larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ - mvc __LC_RST_NEW_PSW(16,%r0),0(%r4) -3: - sigp %r9,%r1,SIGP_INITIAL_CPU_RESET /* sigp initial cpu reset */ - brc 8,4f /* accepted */ - brc 2,3b /* busy, try again */ - - /* Suspend CPU not available -> panic */ - larl %r15,init_thread_union+THREAD_SIZE-STACK_FRAME_OVERHEAD - larl %r2,.Lpanic_string - brasl %r14,sclp_early_printk_force - larl %r3,.Ldisabled_wait_31 - lpsw 0(%r3) -4: - /* Switch to suspend CPU */ - sigp %r9,%r1,SIGP_RESTART /* sigp restart to suspend CPU */ - brc 2,4b /* busy, try again */ -5: - sigp %r9,%r2,SIGP_STOP /* sigp stop to current resume CPU */ - brc 2,5b /* busy, try again */ -6: j 6b - -restart_suspend: - larl %r1,.Lresume_cpu - llgh %r2,0(%r1) -7: - sigp %r9,%r2,SIGP_SENSE /* sigp sense, wait for resume CPU */ - brc 8,7b /* accepted, status 0, still running */ - brc 2,7b /* busy, try again */ - tmll %r9,0x40 /* Test if resume CPU is stopped */ - jz 7b - -restore_registers: - /* Restore registers */ - lghi %r13,0x1000 /* %r1 = pointer to save area */ - - /* Ignore time spent in suspended state. */ - llgf %r1,0x318(%r13) - stck __LC_LAST_UPDATE_CLOCK(%r1) - spt 0x328(%r13) /* reprogram timer */ - //sckc 0x330(%r13) /* set clock comparator */ - - lctlg %c0,%c15,0x380(%r13) /* load control registers */ - lam %a0,%a15,0x340(%r13) /* load access registers */ - - /* Load old stack */ - lg %r15,0x2f8(%r13) - - /* Save prefix register */ - mvc __SF_EMPTY(4,%r15),0x318(%r13) - - /* Restore absolute zero pages */ - lghi %r2,0 - larl %r4,suspend_zero_pages - lg %r4,0(%r4) - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - - /* Restore prefix register */ - spx __SF_EMPTY(%r15) - - /* Activate DAT */ - stosm __SF_EMPTY(%r15),0x04 - - /* Make all free pages unstable */ - lghi %r2,0 - brasl %r14,arch_set_page_states - - /* Call arch specific early resume code */ - brasl %r14,s390_early_resume - - /* Return 0 */ - lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) - lghi %r2,0 - BR_EX %r14 -ENDPROC(swsusp_arch_resume) - - .section .data..nosave,"aw",@progbits - .align 8 -.Ldisabled_wait_31: - .long 0x000a0000,0x00000000 -.Lpanic_string: - .asciz "Resume not possible because suspend CPU is no longer available\n" - .align 8 -.Lrestart_suspend_psw: - .quad 0x0000000180000000,restart_suspend -.Lnew_pgm_check_psw: - .quad 0,pgm_check_entry -.Lresume_cpu: - .byte 0,0 diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 3627953007ed..5f70cefc13e4 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -26,7 +26,6 @@ #include <linux/nodemask.h> #include <linux/node.h> #include <asm/sysinfo.h> -#include <asm/numa.h> #define PTF_HORIZONTAL (0UL) #define PTF_VERTICAL (1UL) @@ -63,8 +62,6 @@ static struct mask_info drawer_info; struct cpu_topology_s390 cpu_topology[NR_CPUS]; EXPORT_SYMBOL_GPL(cpu_topology); -cpumask_t cpus_with_topology; - static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) { cpumask_t mask; @@ -86,11 +83,12 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) cpumask_copy(&mask, cpu_present_mask); break; default: - /* fallthrough */ + fallthrough; case TOPOLOGY_MODE_SINGLE: cpumask_copy(&mask, cpumask_of(cpu)); break; } + cpumask_and(&mask, &mask, cpu_online_mask); return mask; } @@ -106,6 +104,7 @@ static cpumask_t cpu_thread_map(unsigned int cpu) for (i = 0; i <= smp_cpu_mtid; i++) if (cpu_present(cpu + i)) cpumask_set_cpu(cpu + i, &mask); + cpumask_and(&mask, &mask, cpu_online_mask); return mask; } @@ -138,7 +137,6 @@ static void add_cpus_to_mask(struct topology_core *tl_core, cpumask_set_cpu(lcpu + i, &drawer->mask); cpumask_set_cpu(lcpu + i, &book->mask); cpumask_set_cpu(lcpu + i, &socket->mask); - cpumask_set_cpu(lcpu + i, &cpus_with_topology); smp_cpu_set_polarization(lcpu + i, tl_core->pp); } } @@ -245,10 +243,10 @@ int topology_set_cpu_management(int fc) return rc; } -static void update_cpu_masks(void) +void update_cpu_masks(void) { - struct cpu_topology_s390 *topo; - int cpu, id; + struct cpu_topology_s390 *topo, *topo_package, *topo_sibling; + int cpu, sibling, pkg_first, smt_first, id; for_each_possible_cpu(cpu) { topo = &cpu_topology[cpu]; @@ -256,6 +254,7 @@ static void update_cpu_masks(void) topo->core_mask = cpu_group_map(&socket_info, cpu); topo->book_mask = cpu_group_map(&book_info, cpu); topo->drawer_mask = cpu_group_map(&drawer_info, cpu); + topo->booted_cores = 0; if (topology_mode != TOPOLOGY_MODE_HW) { id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; topo->thread_id = cpu; @@ -263,11 +262,23 @@ static void update_cpu_masks(void) topo->socket_id = id; topo->book_id = id; topo->drawer_id = id; - if (cpu_present(cpu)) - cpumask_set_cpu(cpu, &cpus_with_topology); } } - numa_update_cpu_topology(); + for_each_online_cpu(cpu) { + topo = &cpu_topology[cpu]; + pkg_first = cpumask_first(&topo->core_mask); + topo_package = &cpu_topology[pkg_first]; + if (cpu == pkg_first) { + for_each_cpu(sibling, &topo->core_mask) { + topo_sibling = &cpu_topology[sibling]; + smt_first = cpumask_first(&topo_sibling->thread_mask); + if (sibling == smt_first) + topo_package->booted_cores++; + } + } else { + topo->booted_cores = topo_package->booted_cores; + } + } } void store_topology(struct sysinfo_15_1_x *info) @@ -289,7 +300,6 @@ static int __arch_update_cpu_topology(void) int rc = 0; mutex_lock(&smp_cpu_state_mutex); - cpumask_clear(&cpus_with_topology); if (MACHINE_HAS_TOPOLOGY) { rc = 1; store_topology(info); diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index dc75588d7894..ff9cc4c3290e 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -271,7 +271,7 @@ void kernel_stack_overflow(struct pt_regs *regs) } NOKPROBE_SYMBOL(kernel_stack_overflow); -static void test_monitor_call(void) +static void __init test_monitor_call(void) { int val = 1; diff --git a/arch/s390/kernel/vdso64/.gitignore b/arch/s390/kernel/vdso64/.gitignore index 3fd18cf9fec2..4ec80685fecc 100644 --- a/arch/s390/kernel/vdso64/.gitignore +++ b/arch/s390/kernel/vdso64/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso64.lds diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index d3db3d7ed077..def3b60f1fe8 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -55,8 +55,4 @@ config KVM_S390_UCONTROL If unsure, say N. -# OK, it's a little counter-intuitive to do this, but it puts it neatly under -# the virtualization menu. -source "drivers/vhost/Kconfig" - endif # VIRTUALIZATION diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 8191106bf7b9..bfb481134994 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -393,7 +393,7 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu) if (psw_mchk_disabled(vcpu)) active_mask &= ~IRQ_PEND_MCHK_MASK; /* PV guest cpus can have a single interruption injected at a time. */ - if (kvm_s390_pv_cpu_is_protected(vcpu) && + if (kvm_s390_pv_cpu_get_handle(vcpu) && vcpu->arch.sie_block->iictl != IICTL_CODE_NONE) active_mask &= ~(IRQ_PEND_EXT_II_MASK | IRQ_PEND_IO_MASK | diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 75471b646fd7..389ff1b7cd43 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -542,6 +542,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_S390_AIS: case KVM_CAP_S390_AIS_MIGRATION: case KVM_CAP_S390_VCPU_RESETS: + case KVM_CAP_SET_GUEST_DEBUG: r = 1; break; case KVM_CAP_S390_HPAGE_1M: diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index a51c892f14f3..ae989b740376 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -19,7 +19,6 @@ #include <linux/swap.h> #include <linux/kthread.h> #include <linux/oom.h> -#include <linux/suspend.h> #include <linux/uaccess.h> #include <asm/pgalloc.h> @@ -49,7 +48,6 @@ static volatile long cmm_pages_target; static volatile long cmm_timed_pages_target; static long cmm_timeout_pages; static long cmm_timeout_seconds; -static int cmm_suspended; static struct cmm_page_array *cmm_page_list; static struct cmm_page_array *cmm_timed_page_list; @@ -151,9 +149,9 @@ static int cmm_thread(void *dummy) while (1) { rc = wait_event_interruptible(cmm_thread_wait, - (!cmm_suspended && (cmm_pages != cmm_pages_target || - cmm_timed_pages != cmm_timed_pages_target)) || - kthread_should_stop()); + cmm_pages != cmm_pages_target || + cmm_timed_pages != cmm_timed_pages_target || + kthread_should_stop()); if (kthread_should_stop() || rc == -ERESTARTSYS) { cmm_pages_target = cmm_pages; cmm_timed_pages_target = cmm_timed_pages; @@ -390,38 +388,6 @@ static void cmm_smsg_target(const char *from, char *msg) static struct ctl_table_header *cmm_sysctl_header; -static int cmm_suspend(void) -{ - cmm_suspended = 1; - cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); - cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); - return 0; -} - -static int cmm_resume(void) -{ - cmm_suspended = 0; - cmm_kick_thread(); - return 0; -} - -static int cmm_power_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - switch (event) { - case PM_POST_HIBERNATION: - return cmm_resume(); - case PM_HIBERNATION_PREPARE: - return cmm_suspend(); - default: - return NOTIFY_DONE; - } -} - -static struct notifier_block cmm_power_notifier = { - .notifier_call = cmm_power_event, -}; - static int __init cmm_init(void) { int rc = -ENOMEM; @@ -446,16 +412,11 @@ static int __init cmm_init(void) rc = register_oom_notifier(&cmm_oom_nb); if (rc < 0) goto out_oom_notify; - rc = register_pm_notifier(&cmm_power_notifier); - if (rc) - goto out_pm; cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); if (!IS_ERR(cmm_thread_ptr)) return 0; rc = PTR_ERR(cmm_thread_ptr); - unregister_pm_notifier(&cmm_power_notifier); -out_pm: unregister_oom_notifier(&cmm_oom_nb); out_oom_notify: #ifdef CONFIG_CMM_IUCV @@ -475,7 +436,6 @@ static void __exit cmm_exit(void) #ifdef CONFIG_CMM_IUCV smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); #endif - unregister_pm_notifier(&cmm_power_notifier); unregister_oom_notifier(&cmm_oom_nb); kthread_stop(cmm_thread_ptr); del_timer_sync(&cmm_timer); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 09bf7f2121ac..dedc28be27ab 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -45,11 +45,11 @@ #define __SUBCODE_MASK 0x0600 #define __PF_RES_FIELD 0x8000000000000000ULL -#define VM_FAULT_BADCONTEXT 0x010000 -#define VM_FAULT_BADMAP 0x020000 -#define VM_FAULT_BADACCESS 0x040000 -#define VM_FAULT_SIGNAL 0x080000 -#define VM_FAULT_PFAULT 0x100000 +#define VM_FAULT_BADCONTEXT ((__force vm_fault_t) 0x010000) +#define VM_FAULT_BADMAP ((__force vm_fault_t) 0x020000) +#define VM_FAULT_BADACCESS ((__force vm_fault_t) 0x040000) +#define VM_FAULT_SIGNAL ((__force vm_fault_t) 0x080000) +#define VM_FAULT_PFAULT ((__force vm_fault_t) 0x100000) enum fault_type { KERNEL_FAULT, @@ -123,7 +123,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) if (*table & _REGION_ENTRY_INVALID) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - /* fallthrough */ + fallthrough; case _ASCE_TYPE_REGION2: table += (address & _REGION2_INDEX) >> _REGION2_SHIFT; if (bad_address(table)) @@ -132,7 +132,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) if (*table & _REGION_ENTRY_INVALID) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - /* fallthrough */ + fallthrough; case _ASCE_TYPE_REGION3: table += (address & _REGION3_INDEX) >> _REGION3_SHIFT; if (bad_address(table)) @@ -141,7 +141,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE)) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - /* fallthrough */ + fallthrough; case _ASCE_TYPE_SEGMENT: table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (bad_address(table)) @@ -328,7 +328,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int access, case VM_FAULT_BADACCESS: if (access == VM_EXEC && signal_return(regs) == 0) break; - /* fallthrough */ + fallthrough; case VM_FAULT_BADMAP: /* Bad memory access. Check if it is kernel or user space. */ if (user_mode(regs)) { @@ -338,9 +338,8 @@ static noinline void do_fault_error(struct pt_regs *regs, int access, do_sigsegv(regs, si_code); break; } - /* fallthrough */ + fallthrough; case VM_FAULT_BADCONTEXT: - /* fallthrough */ case VM_FAULT_PFAULT: do_no_context(regs); break; @@ -581,7 +580,7 @@ void do_dat_exception(struct pt_regs *regs) int access; vm_fault_t fault; - access = VM_READ | VM_EXEC | VM_WRITE; + access = VM_ACCESS_FLAGS; fault = do_exception(regs, access); if (unlikely(fault)) do_fault_error(regs, access, fault); @@ -853,9 +852,7 @@ void do_secure_storage_access(struct pt_regs *regs) BUG(); break; case VDSO_FAULT: - /* fallthrough */ case GMAP_FAULT: - /* fallthrough */ default: do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); WARN_ON_ONCE(1); diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 5674710a4841..f01daddcbc5e 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -326,7 +326,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, struct hstate *h = hstate_file(file); struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - int rc; if (len & ~huge_page_mask(h)) return -EINVAL; @@ -353,15 +352,9 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, else addr = hugetlb_get_unmapped_area_topdown(file, addr, len, pgoff, flags); - if (addr & ~PAGE_MASK) + if (offset_in_page(addr)) return addr; check_asce_limit: - if (addr + len > current->mm->context.asce_limit && - addr + len <= TASK_SIZE) { - rc = crst_table_upgrade(mm, addr + len); - if (rc) - return (unsigned long) rc; - } - return addr; + return check_asce_limit(mm, addr, len); } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index ac44bd76db4b..87b2d024e75a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -268,20 +268,23 @@ device_initcall(s390_cma_mem_init); #endif /* CONFIG_CMA */ int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = PFN_DOWN(start); unsigned long size_pages = PFN_DOWN(size); int rc; - if (WARN_ON_ONCE(restrictions->altmap)) + if (WARN_ON_ONCE(params->altmap)) + return -EINVAL; + + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) return -EINVAL; rc = vmem_add_mapping(start, size); if (rc) return rc; - rc = __add_pages(nid, start_pfn, size_pages, restrictions); + rc = __add_pages(nid, start_pfn, size_pages, params); if (rc) vmem_remove_mapping(start, size); return rc; diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index cbc718ba6d78..1b78f630a9ca 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -72,14 +72,13 @@ static inline unsigned long mmap_base(unsigned long rnd, return PAGE_ALIGN(STACK_TOP - gap - rnd); } -unsigned long -arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; struct vm_unmapped_area_info info; - int rc; if (len > TASK_SIZE - mmap_min_addr) return -ENOMEM; @@ -105,30 +104,20 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, info.align_mask = 0; info.align_offset = pgoff << PAGE_SHIFT; addr = vm_unmapped_area(&info); - if (addr & ~PAGE_MASK) + if (offset_in_page(addr)) return addr; check_asce_limit: - if (addr + len > current->mm->context.asce_limit && - addr + len <= TASK_SIZE) { - rc = crst_table_upgrade(mm, addr + len); - if (rc) - return (unsigned long) rc; - } - - return addr; + return check_asce_limit(mm, addr, len); } -unsigned long -arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - const unsigned long len, const unsigned long pgoff, - const unsigned long flags) +unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; - unsigned long addr = addr0; struct vm_unmapped_area_info info; - int rc; /* requested length too big for entire address space */ if (len > TASK_SIZE - mmap_min_addr) @@ -163,25 +152,18 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, * can happen with large stack limits and large mmap() * allocations. */ - if (addr & ~PAGE_MASK) { + if (offset_in_page(addr)) { VM_BUG_ON(addr != -ENOMEM); info.flags = 0; info.low_limit = TASK_UNMAPPED_BASE; info.high_limit = TASK_SIZE; addr = vm_unmapped_area(&info); - if (addr & ~PAGE_MASK) + if (offset_in_page(addr)) return addr; } check_asce_limit: - if (addr + len > current->mm->context.asce_limit && - addr + len <= TASK_SIZE) { - rc = crst_table_upgrade(mm, addr + len); - if (rc) - return (unsigned long) rc; - } - - return addr; + return check_asce_limit(mm, addr, len); } /* diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index f8c6faab41f4..e22c06d5f206 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -367,20 +367,4 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) } } -#ifdef CONFIG_HIBERNATION -bool kernel_page_present(struct page *page) -{ - unsigned long addr; - int cc; - - addr = page_to_phys(page); - asm volatile( - " lra %1,0(%1)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (cc), "+a" (addr) : : "cc"); - return cc == 0; -} -#endif /* CONFIG_HIBERNATION */ - #endif /* CONFIG_DEBUG_PAGEALLOC */ diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index 3dd253f81a77..498c98a312f4 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -77,67 +77,65 @@ static void __crst_table_upgrade(void *arg) int crst_table_upgrade(struct mm_struct *mm, unsigned long end) { - unsigned long *table, *pgd; - int rc, notify; + unsigned long *pgd = NULL, *p4d = NULL, *__pgd; + unsigned long asce_limit = mm->context.asce_limit; /* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */ - VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE); - rc = 0; - notify = 0; - while (mm->context.asce_limit < end) { - table = crst_table_alloc(mm); - if (!table) { - rc = -ENOMEM; - break; - } - spin_lock_bh(&mm->page_table_lock); - pgd = (unsigned long *) mm->pgd; - if (mm->context.asce_limit == _REGION2_SIZE) { - crst_table_init(table, _REGION2_ENTRY_EMPTY); - p4d_populate(mm, (p4d_t *) table, (pud_t *) pgd); - mm->pgd = (pgd_t *) table; - mm->context.asce_limit = _REGION1_SIZE; - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION2; - mm_inc_nr_puds(mm); - } else { - crst_table_init(table, _REGION1_ENTRY_EMPTY); - pgd_populate(mm, (pgd_t *) table, (p4d_t *) pgd); - mm->pgd = (pgd_t *) table; - mm->context.asce_limit = -PAGE_SIZE; - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION1; - } - notify = 1; - spin_unlock_bh(&mm->page_table_lock); - } - if (notify) - on_each_cpu(__crst_table_upgrade, mm, 0); - return rc; -} + VM_BUG_ON(asce_limit < _REGION2_SIZE); -void crst_table_downgrade(struct mm_struct *mm) -{ - pgd_t *pgd; + if (end <= asce_limit) + return 0; - /* downgrade should only happen from 3 to 2 levels (compat only) */ - VM_BUG_ON(mm->context.asce_limit != _REGION2_SIZE); + if (asce_limit == _REGION2_SIZE) { + p4d = crst_table_alloc(mm); + if (unlikely(!p4d)) + goto err_p4d; + crst_table_init(p4d, _REGION2_ENTRY_EMPTY); + } + if (end > _REGION1_SIZE) { + pgd = crst_table_alloc(mm); + if (unlikely(!pgd)) + goto err_pgd; + crst_table_init(pgd, _REGION1_ENTRY_EMPTY); + } - if (current->active_mm == mm) { - clear_user_asce(); - __tlb_flush_mm(mm); + spin_lock_bh(&mm->page_table_lock); + + /* + * This routine gets called with mmap_sem lock held and there is + * no reason to optimize for the case of otherwise. However, if + * that would ever change, the below check will let us know. + */ + VM_BUG_ON(asce_limit != mm->context.asce_limit); + + if (p4d) { + __pgd = (unsigned long *) mm->pgd; + p4d_populate(mm, (p4d_t *) p4d, (pud_t *) __pgd); + mm->pgd = (pgd_t *) p4d; + mm->context.asce_limit = _REGION1_SIZE; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + mm_inc_nr_puds(mm); + } + if (pgd) { + __pgd = (unsigned long *) mm->pgd; + pgd_populate(mm, (pgd_t *) pgd, (p4d_t *) __pgd); + mm->pgd = (pgd_t *) pgd; + mm->context.asce_limit = TASK_SIZE_MAX; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION1; } - pgd = mm->pgd; - mm_dec_nr_pmds(mm); - mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); - mm->context.asce_limit = _REGION3_SIZE; - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; - crst_table_free(mm, (unsigned long *) pgd); + spin_unlock_bh(&mm->page_table_lock); - if (current->active_mm == mm) - set_user_asce(mm); + on_each_cpu(__crst_table_upgrade, mm, 0); + + return 0; + +err_pgd: + crst_table_free(mm, p4d); +err_p4d: + return -ENOMEM; } static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits) @@ -304,7 +302,7 @@ void __tlb_remove_table(void *_table) mask >>= 24; if (mask != 0) break; - /* fallthrough */ + fallthrough; case 3: /* 4K page table with pgstes */ if (mask & 3) atomic_xor_bits(&page->_refcount, 3 << 24); @@ -529,7 +527,7 @@ void base_asce_free(unsigned long asce) base_region2_walk(table, 0, _REGION1_SIZE, 0); break; case _ASCE_TYPE_REGION1: - base_region1_walk(table, 0, -_PAGE_SIZE, 0); + base_region1_walk(table, 0, TASK_SIZE_MAX, 0); break; } base_crst_free(table); diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index b403fa14847d..f810930aff42 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -415,6 +415,10 @@ void __init vmem_map_init(void) SET_MEMORY_RO | SET_MEMORY_X); __set_memory(__stext_dma, (__etext_dma - __stext_dma) >> PAGE_SHIFT, SET_MEMORY_RO | SET_MEMORY_X); + + /* we need lowcore executable for our LPSWE instructions */ + set_memory_x(0, 1); + pr_info("Write protected kernel read-only data: %luk\n", (unsigned long)(__end_rodata - _stext) >> 10); } diff --git a/arch/s390/numa/Makefile b/arch/s390/numa/Makefile index 66c2dff74895..c89d26f4f77d 100644 --- a/arch/s390/numa/Makefile +++ b/arch/s390/numa/Makefile @@ -1,4 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += numa.o -obj-y += toptree.o -obj-$(CONFIG_NUMA_EMU) += mode_emu.o diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c deleted file mode 100644 index 72d742bb2d17..000000000000 --- a/arch/s390/numa/mode_emu.c +++ /dev/null @@ -1,577 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * NUMA support for s390 - * - * NUMA emulation (aka fake NUMA) distributes the available memory to nodes - * without using real topology information about the physical memory of the - * machine. - * - * It distributes the available CPUs to nodes while respecting the original - * machine topology information. This is done by trying to avoid to separate - * CPUs which reside on the same book or even on the same MC. - * - * Because the current Linux scheduler code requires a stable cpu to node - * mapping, cores are pinned to nodes when the first CPU thread is set online. - * - * Copyright IBM Corp. 2015 - */ - -#define KMSG_COMPONENT "numa_emu" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - -#include <linux/kernel.h> -#include <linux/cpumask.h> -#include <linux/memblock.h> -#include <linux/node.h> -#include <linux/memory.h> -#include <linux/slab.h> -#include <asm/smp.h> -#include <asm/topology.h> -#include "numa_mode.h" -#include "toptree.h" - -/* Distances between the different system components */ -#define DIST_EMPTY 0 -#define DIST_CORE 1 -#define DIST_MC 2 -#define DIST_BOOK 3 -#define DIST_DRAWER 4 -#define DIST_MAX 5 - -/* Node distance reported to common code */ -#define EMU_NODE_DIST 10 - -/* Node ID for free (not yet pinned) cores */ -#define NODE_ID_FREE -1 - -/* Different levels of toptree */ -enum toptree_level {CORE, MC, BOOK, DRAWER, NODE, TOPOLOGY}; - -/* The two toptree IDs */ -enum {TOPTREE_ID_PHYS, TOPTREE_ID_NUMA}; - -/* Number of NUMA nodes */ -static int emu_nodes = 1; -/* NUMA stripe size */ -static unsigned long emu_size; - -/* - * Node to core pinning information updates are protected by - * "sched_domains_mutex". - */ -static struct { - s32 to_node_id[CONFIG_NR_CPUS]; /* Pinned core to node mapping */ - int total; /* Total number of pinned cores */ - int per_node_target; /* Cores per node without extra cores */ - int per_node[MAX_NUMNODES]; /* Number of cores pinned to node */ -} *emu_cores; - -/* - * Pin a core to a node - */ -static void pin_core_to_node(int core_id, int node_id) -{ - if (emu_cores->to_node_id[core_id] == NODE_ID_FREE) { - emu_cores->per_node[node_id]++; - emu_cores->to_node_id[core_id] = node_id; - emu_cores->total++; - } else { - WARN_ON(emu_cores->to_node_id[core_id] != node_id); - } -} - -/* - * Number of pinned cores of a node - */ -static int cores_pinned(struct toptree *node) -{ - return emu_cores->per_node[node->id]; -} - -/* - * ID of the node where the core is pinned (or NODE_ID_FREE) - */ -static int core_pinned_to_node_id(struct toptree *core) -{ - return emu_cores->to_node_id[core->id]; -} - -/* - * Number of cores in the tree that are not yet pinned - */ -static int cores_free(struct toptree *tree) -{ - struct toptree *core; - int count = 0; - - toptree_for_each(core, tree, CORE) { - if (core_pinned_to_node_id(core) == NODE_ID_FREE) - count++; - } - return count; -} - -/* - * Return node of core - */ -static struct toptree *core_node(struct toptree *core) -{ - return core->parent->parent->parent->parent; -} - -/* - * Return drawer of core - */ -static struct toptree *core_drawer(struct toptree *core) -{ - return core->parent->parent->parent; -} - -/* - * Return book of core - */ -static struct toptree *core_book(struct toptree *core) -{ - return core->parent->parent; -} - -/* - * Return mc of core - */ -static struct toptree *core_mc(struct toptree *core) -{ - return core->parent; -} - -/* - * Distance between two cores - */ -static int dist_core_to_core(struct toptree *core1, struct toptree *core2) -{ - if (core_drawer(core1)->id != core_drawer(core2)->id) - return DIST_DRAWER; - if (core_book(core1)->id != core_book(core2)->id) - return DIST_BOOK; - if (core_mc(core1)->id != core_mc(core2)->id) - return DIST_MC; - /* Same core or sibling on same MC */ - return DIST_CORE; -} - -/* - * Distance of a node to a core - */ -static int dist_node_to_core(struct toptree *node, struct toptree *core) -{ - struct toptree *core_node; - int dist_min = DIST_MAX; - - toptree_for_each(core_node, node, CORE) - dist_min = min(dist_min, dist_core_to_core(core_node, core)); - return dist_min == DIST_MAX ? DIST_EMPTY : dist_min; -} - -/* - * Unify will delete empty nodes, therefore recreate nodes. - */ -static void toptree_unify_tree(struct toptree *tree) -{ - int nid; - - toptree_unify(tree); - for (nid = 0; nid < emu_nodes; nid++) - toptree_get_child(tree, nid); -} - -/* - * Find the best/nearest node for a given core and ensure that no node - * gets more than "emu_cores->per_node_target + extra" cores. - */ -static struct toptree *node_for_core(struct toptree *numa, struct toptree *core, - int extra) -{ - struct toptree *node, *node_best = NULL; - int dist_cur, dist_best, cores_target; - - cores_target = emu_cores->per_node_target + extra; - dist_best = DIST_MAX; - node_best = NULL; - toptree_for_each(node, numa, NODE) { - /* Already pinned cores must use their nodes */ - if (core_pinned_to_node_id(core) == node->id) { - node_best = node; - break; - } - /* Skip nodes that already have enough cores */ - if (cores_pinned(node) >= cores_target) - continue; - dist_cur = dist_node_to_core(node, core); - if (dist_cur < dist_best) { - dist_best = dist_cur; - node_best = node; - } - } - return node_best; -} - -/* - * Find the best node for each core with respect to "extra" core count - */ -static void toptree_to_numa_single(struct toptree *numa, struct toptree *phys, - int extra) -{ - struct toptree *node, *core, *tmp; - - toptree_for_each_safe(core, tmp, phys, CORE) { - node = node_for_core(numa, core, extra); - if (!node) - return; - toptree_move(core, node); - pin_core_to_node(core->id, node->id); - } -} - -/* - * Move structures of given level to specified NUMA node - */ -static void move_level_to_numa_node(struct toptree *node, struct toptree *phys, - enum toptree_level level, bool perfect) -{ - int cores_free, cores_target = emu_cores->per_node_target; - struct toptree *cur, *tmp; - - toptree_for_each_safe(cur, tmp, phys, level) { - cores_free = cores_target - toptree_count(node, CORE); - if (perfect) { - if (cores_free == toptree_count(cur, CORE)) - toptree_move(cur, node); - } else { - if (cores_free >= toptree_count(cur, CORE)) - toptree_move(cur, node); - } - } -} - -/* - * Move structures of a given level to NUMA nodes. If "perfect" is specified - * move only perfectly fitting structures. Otherwise move also smaller - * than needed structures. - */ -static void move_level_to_numa(struct toptree *numa, struct toptree *phys, - enum toptree_level level, bool perfect) -{ - struct toptree *node; - - toptree_for_each(node, numa, NODE) - move_level_to_numa_node(node, phys, level, perfect); -} - -/* - * For the first run try to move the big structures - */ -static void toptree_to_numa_first(struct toptree *numa, struct toptree *phys) -{ - struct toptree *core; - - /* Always try to move perfectly fitting structures first */ - move_level_to_numa(numa, phys, DRAWER, true); - move_level_to_numa(numa, phys, DRAWER, false); - move_level_to_numa(numa, phys, BOOK, true); - move_level_to_numa(numa, phys, BOOK, false); - move_level_to_numa(numa, phys, MC, true); - move_level_to_numa(numa, phys, MC, false); - /* Now pin all the moved cores */ - toptree_for_each(core, numa, CORE) - pin_core_to_node(core->id, core_node(core)->id); -} - -/* - * Allocate new topology and create required nodes - */ -static struct toptree *toptree_new(int id, int nodes) -{ - struct toptree *tree; - int nid; - - tree = toptree_alloc(TOPOLOGY, id); - if (!tree) - goto fail; - for (nid = 0; nid < nodes; nid++) { - if (!toptree_get_child(tree, nid)) - goto fail; - } - return tree; -fail: - panic("NUMA emulation could not allocate topology"); -} - -/* - * Allocate and initialize core to node mapping - */ -static void __ref create_core_to_node_map(void) -{ - int i; - - emu_cores = memblock_alloc(sizeof(*emu_cores), 8); - if (!emu_cores) - panic("%s: Failed to allocate %zu bytes align=0x%x\n", - __func__, sizeof(*emu_cores), 8); - for (i = 0; i < ARRAY_SIZE(emu_cores->to_node_id); i++) - emu_cores->to_node_id[i] = NODE_ID_FREE; -} - -/* - * Move cores from physical topology into NUMA target topology - * and try to keep as much of the physical topology as possible. - */ -static struct toptree *toptree_to_numa(struct toptree *phys) -{ - static int first = 1; - struct toptree *numa; - int cores_total; - - cores_total = emu_cores->total + cores_free(phys); - emu_cores->per_node_target = cores_total / emu_nodes; - numa = toptree_new(TOPTREE_ID_NUMA, emu_nodes); - if (first) { - toptree_to_numa_first(numa, phys); - first = 0; - } - toptree_to_numa_single(numa, phys, 0); - toptree_to_numa_single(numa, phys, 1); - toptree_unify_tree(numa); - - WARN_ON(cpumask_weight(&phys->mask)); - return numa; -} - -/* - * Create a toptree out of the physical topology that we got from the hypervisor - */ -static struct toptree *toptree_from_topology(void) -{ - struct toptree *phys, *node, *drawer, *book, *mc, *core; - struct cpu_topology_s390 *top; - int cpu; - - phys = toptree_new(TOPTREE_ID_PHYS, 1); - - for_each_cpu(cpu, &cpus_with_topology) { - top = &cpu_topology[cpu]; - node = toptree_get_child(phys, 0); - drawer = toptree_get_child(node, top->drawer_id); - book = toptree_get_child(drawer, top->book_id); - mc = toptree_get_child(book, top->socket_id); - core = toptree_get_child(mc, smp_get_base_cpu(cpu)); - if (!drawer || !book || !mc || !core) - panic("NUMA emulation could not allocate memory"); - cpumask_set_cpu(cpu, &core->mask); - toptree_update_mask(mc); - } - return phys; -} - -/* - * Add toptree core to topology and create correct CPU masks - */ -static void topology_add_core(struct toptree *core) -{ - struct cpu_topology_s390 *top; - int cpu; - - for_each_cpu(cpu, &core->mask) { - top = &cpu_topology[cpu]; - cpumask_copy(&top->thread_mask, &core->mask); - cpumask_copy(&top->core_mask, &core_mc(core)->mask); - cpumask_copy(&top->book_mask, &core_book(core)->mask); - cpumask_copy(&top->drawer_mask, &core_drawer(core)->mask); - cpumask_set_cpu(cpu, &node_to_cpumask_map[core_node(core)->id]); - top->node_id = core_node(core)->id; - } -} - -/* - * Apply toptree to topology and create CPU masks - */ -static void toptree_to_topology(struct toptree *numa) -{ - struct toptree *core; - int i; - - /* Clear all node masks */ - for (i = 0; i < MAX_NUMNODES; i++) - cpumask_clear(&node_to_cpumask_map[i]); - - /* Rebuild all masks */ - toptree_for_each(core, numa, CORE) - topology_add_core(core); -} - -/* - * Show the node to core mapping - */ -static void print_node_to_core_map(void) -{ - int nid, cid; - - if (!numa_debug_enabled) - return; - printk(KERN_DEBUG "NUMA node to core mapping\n"); - for (nid = 0; nid < emu_nodes; nid++) { - printk(KERN_DEBUG " node %3d: ", nid); - for (cid = 0; cid < ARRAY_SIZE(emu_cores->to_node_id); cid++) { - if (emu_cores->to_node_id[cid] == nid) - printk(KERN_CONT "%d ", cid); - } - printk(KERN_CONT "\n"); - } -} - -static void pin_all_possible_cpus(void) -{ - int core_id, node_id, cpu; - static int initialized; - - if (initialized) - return; - print_node_to_core_map(); - node_id = 0; - for_each_possible_cpu(cpu) { - core_id = smp_get_base_cpu(cpu); - if (emu_cores->to_node_id[core_id] != NODE_ID_FREE) - continue; - pin_core_to_node(core_id, node_id); - cpu_topology[cpu].node_id = node_id; - node_id = (node_id + 1) % emu_nodes; - } - print_node_to_core_map(); - initialized = 1; -} - -/* - * Transfer physical topology into a NUMA topology and modify CPU masks - * according to the NUMA topology. - * - * Must be called with "sched_domains_mutex" lock held. - */ -static void emu_update_cpu_topology(void) -{ - struct toptree *phys, *numa; - - if (emu_cores == NULL) - create_core_to_node_map(); - phys = toptree_from_topology(); - numa = toptree_to_numa(phys); - toptree_free(phys); - toptree_to_topology(numa); - toptree_free(numa); - pin_all_possible_cpus(); -} - -/* - * If emu_size is not set, use CONFIG_EMU_SIZE. Then round to minimum - * alignment (needed for memory hotplug). - */ -static unsigned long emu_setup_size_adjust(unsigned long size) -{ - unsigned long size_new; - - size = size ? : CONFIG_EMU_SIZE; - size_new = roundup(size, memory_block_size_bytes()); - if (size_new == size) - return size; - pr_warn("Increasing memory stripe size from %ld MB to %ld MB\n", - size >> 20, size_new >> 20); - return size_new; -} - -/* - * If we have not enough memory for the specified nodes, reduce the node count. - */ -static int emu_setup_nodes_adjust(int nodes) -{ - int nodes_max; - - nodes_max = memblock.memory.total_size / emu_size; - nodes_max = max(nodes_max, 1); - if (nodes_max >= nodes) - return nodes; - pr_warn("Not enough memory for %d nodes, reducing node count\n", nodes); - return nodes_max; -} - -/* - * Early emu setup - */ -static void emu_setup(void) -{ - int nid; - - emu_size = emu_setup_size_adjust(emu_size); - emu_nodes = emu_setup_nodes_adjust(emu_nodes); - for (nid = 0; nid < emu_nodes; nid++) - node_set(nid, node_possible_map); - pr_info("Creating %d nodes with memory stripe size %ld MB\n", - emu_nodes, emu_size >> 20); -} - -/* - * Return node id for given page number - */ -static int emu_pfn_to_nid(unsigned long pfn) -{ - return (pfn / (emu_size >> PAGE_SHIFT)) % emu_nodes; -} - -/* - * Return stripe size - */ -static unsigned long emu_align(void) -{ - return emu_size; -} - -/* - * Return distance between two nodes - */ -static int emu_distance(int node1, int node2) -{ - return (node1 != node2) * EMU_NODE_DIST; -} - -/* - * Define callbacks for generic s390 NUMA infrastructure - */ -const struct numa_mode numa_mode_emu = { - .name = "emu", - .setup = emu_setup, - .update_cpu_topology = emu_update_cpu_topology, - .__pfn_to_nid = emu_pfn_to_nid, - .align = emu_align, - .distance = emu_distance, -}; - -/* - * Kernel parameter: emu_nodes=<n> - */ -static int __init early_parse_emu_nodes(char *p) -{ - int count; - - if (!p || kstrtoint(p, 0, &count) != 0 || count <= 0) - return 0; - emu_nodes = min(count, MAX_NUMNODES); - return 0; -} -early_param("emu_nodes", early_parse_emu_nodes); - -/* - * Kernel parameter: emu_size=[<n>[k|M|G|T]] - */ -static int __init early_parse_emu_size(char *p) -{ - if (p) - emu_size = memparse(p, NULL); - return 0; -} -early_param("emu_size", early_parse_emu_size); diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c index d2910fa834c8..51c5a9f6e525 100644 --- a/arch/s390/numa/numa.c +++ b/arch/s390/numa/numa.c @@ -7,165 +7,36 @@ * Copyright IBM Corp. 2015 */ -#define KMSG_COMPONENT "numa" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - #include <linux/kernel.h> #include <linux/mmzone.h> #include <linux/cpumask.h> #include <linux/memblock.h> -#include <linux/slab.h> #include <linux/node.h> - #include <asm/numa.h> -#include "numa_mode.h" -pg_data_t *node_data[MAX_NUMNODES]; +struct pglist_data *node_data[MAX_NUMNODES]; EXPORT_SYMBOL(node_data); -cpumask_t node_to_cpumask_map[MAX_NUMNODES]; -EXPORT_SYMBOL(node_to_cpumask_map); - -static void plain_setup(void) -{ - node_set(0, node_possible_map); -} - -const struct numa_mode numa_mode_plain = { - .name = "plain", - .setup = plain_setup, -}; - -static const struct numa_mode *mode = &numa_mode_plain; - -int numa_pfn_to_nid(unsigned long pfn) -{ - return mode->__pfn_to_nid ? mode->__pfn_to_nid(pfn) : 0; -} - -void numa_update_cpu_topology(void) -{ - if (mode->update_cpu_topology) - mode->update_cpu_topology(); -} - -int __node_distance(int a, int b) -{ - return mode->distance ? mode->distance(a, b) : 0; -} -EXPORT_SYMBOL(__node_distance); - -int numa_debug_enabled; - -/* - * numa_setup_memory() - Assign bootmem to nodes - * - * The memory is first added to memblock without any respect to nodes. - * This is fixed before remaining memblock memory is handed over to the - * buddy allocator. - * An important side effect is that large bootmem allocations might easily - * cross node boundaries, which can be needed for large allocations with - * smaller memory stripes in each node (i.e. when using NUMA emulation). - * - * Memory defines nodes: - * Therefore this routine also sets the nodes online with memory. - */ -static void __init numa_setup_memory(void) +void __init numa_setup(void) { - unsigned long cur_base, align, end_of_dram; - int nid = 0; - - end_of_dram = memblock_end_of_DRAM(); - align = mode->align ? mode->align() : ULONG_MAX; - - /* - * Step through all available memory and assign it to the nodes - * indicated by the mode implementation. - * All nodes which are seen here will be set online. - */ - cur_base = 0; - do { - nid = numa_pfn_to_nid(PFN_DOWN(cur_base)); - node_set_online(nid); - memblock_set_node(cur_base, align, &memblock.memory, nid); - cur_base += align; - } while (cur_base < end_of_dram); + int nid; - /* Allocate and fill out node_data */ + nodes_clear(node_possible_map); + node_set(0, node_possible_map); + node_set_online(0); for (nid = 0; nid < MAX_NUMNODES; nid++) { NODE_DATA(nid) = memblock_alloc(sizeof(pg_data_t), 8); if (!NODE_DATA(nid)) panic("%s: Failed to allocate %zu bytes align=0x%x\n", __func__, sizeof(pg_data_t), 8); } - - for_each_online_node(nid) { - unsigned long start_pfn, end_pfn; - unsigned long t_start, t_end; - int i; - - start_pfn = ULONG_MAX; - end_pfn = 0; - for_each_mem_pfn_range(i, nid, &t_start, &t_end, NULL) { - if (t_start < start_pfn) - start_pfn = t_start; - if (t_end > end_pfn) - end_pfn = t_end; - } - NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; - NODE_DATA(nid)->node_id = nid; - } -} - -/* - * numa_setup() - Earliest initialization - * - * Assign the mode and call the mode's setup routine. - */ -void __init numa_setup(void) -{ - pr_info("NUMA mode: %s\n", mode->name); - nodes_clear(node_possible_map); - /* Initially attach all possible CPUs to node 0. */ - cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask); - if (mode->setup) - mode->setup(); - numa_setup_memory(); - memblock_dump_all(); + NODE_DATA(0)->node_spanned_pages = memblock_end_of_DRAM() >> PAGE_SHIFT; + NODE_DATA(0)->node_id = 0; } -/* - * numa_init_late() - Initialization initcall - * - * Register NUMA nodes. - */ static int __init numa_init_late(void) { - int nid; - - for_each_online_node(nid) - register_one_node(nid); + register_one_node(0); return 0; } arch_initcall(numa_init_late); - -static int __init parse_debug(char *parm) -{ - numa_debug_enabled = 1; - return 0; -} -early_param("numa_debug", parse_debug); - -static int __init parse_numa(char *parm) -{ - if (!parm) - return 1; - if (strcmp(parm, numa_mode_plain.name) == 0) - mode = &numa_mode_plain; -#ifdef CONFIG_NUMA_EMU - if (strcmp(parm, numa_mode_emu.name) == 0) - mode = &numa_mode_emu; -#endif - return 0; -} -early_param("numa", parse_numa); diff --git a/arch/s390/numa/numa_mode.h b/arch/s390/numa/numa_mode.h deleted file mode 100644 index dfd3e2784081..000000000000 --- a/arch/s390/numa/numa_mode.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * NUMA support for s390 - * - * Define declarations used for communication between NUMA mode - * implementations and NUMA core functionality. - * - * Copyright IBM Corp. 2015 - */ -#ifndef __S390_NUMA_MODE_H -#define __S390_NUMA_MODE_H - -struct numa_mode { - char *name; /* Name of mode */ - void (*setup)(void); /* Initizalize mode */ - void (*update_cpu_topology)(void); /* Called by topology code */ - int (*__pfn_to_nid)(unsigned long pfn); /* PFN to node ID */ - unsigned long (*align)(void); /* Minimum node alignment */ - int (*distance)(int a, int b); /* Distance between two nodes */ -}; - -extern const struct numa_mode numa_mode_plain; -extern const struct numa_mode numa_mode_emu; - -#endif /* __S390_NUMA_MODE_H */ diff --git a/arch/s390/numa/toptree.c b/arch/s390/numa/toptree.c deleted file mode 100644 index 71a608cd4f61..000000000000 --- a/arch/s390/numa/toptree.c +++ /dev/null @@ -1,351 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * NUMA support for s390 - * - * A tree structure used for machine topology mangling - * - * Copyright IBM Corp. 2015 - */ - -#include <linux/kernel.h> -#include <linux/memblock.h> -#include <linux/cpumask.h> -#include <linux/list.h> -#include <linux/list_sort.h> -#include <linux/slab.h> -#include <asm/numa.h> - -#include "toptree.h" - -/** - * toptree_alloc - Allocate and initialize a new tree node. - * @level: The node's vertical level; level 0 contains the leaves. - * @id: ID number, explicitly not unique beyond scope of node's siblings - * - * Allocate a new tree node and initialize it. - * - * RETURNS: - * Pointer to the new tree node or NULL on error - */ -struct toptree __ref *toptree_alloc(int level, int id) -{ - struct toptree *res; - - if (slab_is_available()) - res = kzalloc(sizeof(*res), GFP_KERNEL); - else - res = memblock_alloc(sizeof(*res), 8); - if (!res) - return res; - - INIT_LIST_HEAD(&res->children); - INIT_LIST_HEAD(&res->sibling); - cpumask_clear(&res->mask); - res->level = level; - res->id = id; - return res; -} - -/** - * toptree_remove - Remove a tree node from a tree - * @cand: Pointer to the node to remove - * - * The node is detached from its parent node. The parent node's - * masks will be updated to reflect the loss of the child. - */ -static void toptree_remove(struct toptree *cand) -{ - struct toptree *oldparent; - - list_del_init(&cand->sibling); - oldparent = cand->parent; - cand->parent = NULL; - toptree_update_mask(oldparent); -} - -/** - * toptree_free - discard a tree node - * @cand: Pointer to the tree node to discard - * - * Checks if @cand is attached to a parent node. Detaches it - * cleanly using toptree_remove. Possible children are freed - * recursively. In the end @cand itself is freed. - */ -void __ref toptree_free(struct toptree *cand) -{ - struct toptree *child, *tmp; - - if (cand->parent) - toptree_remove(cand); - toptree_for_each_child_safe(child, tmp, cand) - toptree_free(child); - if (slab_is_available()) - kfree(cand); - else - memblock_free_early((unsigned long)cand, sizeof(*cand)); -} - -/** - * toptree_update_mask - Update node bitmasks - * @cand: Pointer to a tree node - * - * The node's cpumask will be updated by combining all children's - * masks. Then toptree_update_mask is called recursively for the - * parent if applicable. - * - * NOTE: - * This must not be called on leaves. If called on a leaf, its - * CPU mask is cleared and lost. - */ -void toptree_update_mask(struct toptree *cand) -{ - struct toptree *child; - - cpumask_clear(&cand->mask); - list_for_each_entry(child, &cand->children, sibling) - cpumask_or(&cand->mask, &cand->mask, &child->mask); - if (cand->parent) - toptree_update_mask(cand->parent); -} - -/** - * toptree_insert - Insert a tree node into tree - * @cand: Pointer to the node to insert - * @target: Pointer to the node to which @cand will added as a child - * - * Insert a tree node into a tree. Masks will be updated automatically. - * - * RETURNS: - * 0 on success, -1 if NULL is passed as argument or the node levels - * don't fit. - */ -static int toptree_insert(struct toptree *cand, struct toptree *target) -{ - if (!cand || !target) - return -1; - if (target->level != (cand->level + 1)) - return -1; - list_add_tail(&cand->sibling, &target->children); - cand->parent = target; - toptree_update_mask(target); - return 0; -} - -/** - * toptree_move_children - Move all child nodes of a node to a new place - * @cand: Pointer to the node whose children are to be moved - * @target: Pointer to the node to which @cand's children will be attached - * - * Take all child nodes of @cand and move them using toptree_move. - */ -static void toptree_move_children(struct toptree *cand, struct toptree *target) -{ - struct toptree *child, *tmp; - - toptree_for_each_child_safe(child, tmp, cand) - toptree_move(child, target); -} - -/** - * toptree_unify - Merge children with same ID - * @cand: Pointer to node whose direct children should be made unique - * - * When mangling the tree it is possible that a node has two or more children - * which have the same ID. This routine merges these children into one and - * moves all children of the merged nodes into the unified node. - */ -void toptree_unify(struct toptree *cand) -{ - struct toptree *child, *tmp, *cand_copy; - - /* Threads cannot be split, cores are not split */ - if (cand->level < 2) - return; - - cand_copy = toptree_alloc(cand->level, 0); - toptree_for_each_child_safe(child, tmp, cand) { - struct toptree *tmpchild; - - if (!cpumask_empty(&child->mask)) { - tmpchild = toptree_get_child(cand_copy, child->id); - toptree_move_children(child, tmpchild); - } - toptree_free(child); - } - toptree_move_children(cand_copy, cand); - toptree_free(cand_copy); - - toptree_for_each_child(child, cand) - toptree_unify(child); -} - -/** - * toptree_move - Move a node to another context - * @cand: Pointer to the node to move - * @target: Pointer to the node where @cand should go - * - * In the easiest case @cand is exactly on the level below @target - * and will be immediately moved to the target. - * - * If @target's level is not the direct parent level of @cand, - * nodes for the missing levels are created and put between - * @cand and @target. The "stacking" nodes' IDs are taken from - * @cand's parents. - * - * After this it is likely to have redundant nodes in the tree - * which are addressed by means of toptree_unify. - */ -void toptree_move(struct toptree *cand, struct toptree *target) -{ - struct toptree *stack_target, *real_insert_point, *ptr, *tmp; - - if (cand->level + 1 == target->level) { - toptree_remove(cand); - toptree_insert(cand, target); - return; - } - - real_insert_point = NULL; - ptr = cand; - stack_target = NULL; - - do { - tmp = stack_target; - stack_target = toptree_alloc(ptr->level + 1, - ptr->parent->id); - toptree_insert(tmp, stack_target); - if (!real_insert_point) - real_insert_point = stack_target; - ptr = ptr->parent; - } while (stack_target->level < (target->level - 1)); - - toptree_remove(cand); - toptree_insert(cand, real_insert_point); - toptree_insert(stack_target, target); -} - -/** - * toptree_get_child - Access a tree node's child by its ID - * @cand: Pointer to tree node whose child is to access - * @id: The desired child's ID - * - * @cand's children are searched for a child with matching ID. - * If no match can be found, a new child with the desired ID - * is created and returned. - */ -struct toptree *toptree_get_child(struct toptree *cand, int id) -{ - struct toptree *child; - - toptree_for_each_child(child, cand) - if (child->id == id) - return child; - child = toptree_alloc(cand->level-1, id); - toptree_insert(child, cand); - return child; -} - -/** - * toptree_first - Find the first descendant on specified level - * @context: Pointer to tree node whose descendants are to be used - * @level: The level of interest - * - * RETURNS: - * @context's first descendant on the specified level, or NULL - * if there is no matching descendant - */ -struct toptree *toptree_first(struct toptree *context, int level) -{ - struct toptree *child, *tmp; - - if (context->level == level) - return context; - - if (!list_empty(&context->children)) { - list_for_each_entry(child, &context->children, sibling) { - tmp = toptree_first(child, level); - if (tmp) - return tmp; - } - } - return NULL; -} - -/** - * toptree_next_sibling - Return next sibling - * @cur: Pointer to a tree node - * - * RETURNS: - * If @cur has a parent and is not the last in the parent's children list, - * the next sibling is returned. Or NULL when there are no siblings left. - */ -static struct toptree *toptree_next_sibling(struct toptree *cur) -{ - if (cur->parent == NULL) - return NULL; - - if (cur == list_last_entry(&cur->parent->children, - struct toptree, sibling)) - return NULL; - return (struct toptree *) list_next_entry(cur, sibling); -} - -/** - * toptree_next - Tree traversal function - * @cur: Pointer to current element - * @context: Pointer to the root node of the tree or subtree to - * be traversed. - * @level: The level of interest. - * - * RETURNS: - * Pointer to the next node on level @level - * or NULL when there is no next node. - */ -struct toptree *toptree_next(struct toptree *cur, struct toptree *context, - int level) -{ - struct toptree *cur_context, *tmp; - - if (!cur) - return NULL; - - if (context->level == level) - return NULL; - - tmp = toptree_next_sibling(cur); - if (tmp != NULL) - return tmp; - - cur_context = cur; - while (cur_context->level < context->level - 1) { - /* Step up */ - cur_context = cur_context->parent; - /* Step aside */ - tmp = toptree_next_sibling(cur_context); - if (tmp != NULL) { - /* Step down */ - tmp = toptree_first(tmp, level); - if (tmp != NULL) - return tmp; - } - } - return NULL; -} - -/** - * toptree_count - Count descendants on specified level - * @context: Pointer to node whose descendants are to be considered - * @level: Only descendants on the specified level will be counted - * - * RETURNS: - * Number of descendants on the specified level - */ -int toptree_count(struct toptree *context, int level) -{ - struct toptree *cur; - int cnt = 0; - - toptree_for_each(cur, context, level) - cnt++; - return cnt; -} diff --git a/arch/s390/numa/toptree.h b/arch/s390/numa/toptree.h deleted file mode 100644 index 5246371ec713..000000000000 --- a/arch/s390/numa/toptree.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * NUMA support for s390 - * - * A tree structure used for machine topology mangling - * - * Copyright IBM Corp. 2015 - */ -#ifndef S390_TOPTREE_H -#define S390_TOPTREE_H - -#include <linux/cpumask.h> -#include <linux/list.h> - -struct toptree { - int level; - int id; - cpumask_t mask; - struct toptree *parent; - struct list_head sibling; - struct list_head children; -}; - -struct toptree *toptree_alloc(int level, int id); -void toptree_free(struct toptree *cand); -void toptree_update_mask(struct toptree *cand); -void toptree_unify(struct toptree *cand); -struct toptree *toptree_get_child(struct toptree *cand, int id); -void toptree_move(struct toptree *cand, struct toptree *target); -int toptree_count(struct toptree *context, int level); - -struct toptree *toptree_first(struct toptree *context, int level); -struct toptree *toptree_next(struct toptree *cur, struct toptree *context, - int level); - -#define toptree_for_each_child(child, ptree) \ - list_for_each_entry(child, &ptree->children, sibling) - -#define toptree_for_each_child_safe(child, ptmp, ptree) \ - list_for_each_entry_safe(child, ptmp, &ptree->children, sibling) - -#define toptree_is_last(ptree) \ - ((ptree->parent == NULL) || \ - (ptree->parent->children.prev == &ptree->sibling)) - -#define toptree_for_each(ptree, cont, ttype) \ - for (ptree = toptree_first(cont, ttype); \ - ptree != NULL; \ - ptree = toptree_next(ptree, cont, ttype)) - -#define toptree_for_each_safe(ptree, tmp, cont, ttype) \ - for (ptree = toptree_first(cont, ttype), \ - tmp = toptree_next(ptree, cont, ttype); \ - ptree != NULL; \ - ptree = tmp, \ - tmp = toptree_next(ptree, cont, ttype)) - -#define toptree_for_each_sibling(ptree, start) \ - toptree_for_each(ptree, start->parent, start->level) - -#endif /* S390_TOPTREE_H */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 60716d18ce5a..94ca121933de 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -40,8 +40,9 @@ static LIST_HEAD(zpci_list); static DEFINE_SPINLOCK(zpci_list_lock); -static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); +static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE); static DEFINE_SPINLOCK(zpci_domain_lock); +static unsigned int zpci_num_domains_allocated; #define ZPCI_IOMAP_ENTRIES \ min(((unsigned long) ZPCI_NR_DEVICES * PCI_STD_NUM_BARS / 2), \ @@ -607,57 +608,25 @@ void pcibios_disable_device(struct pci_dev *pdev) zpci_debug_exit_device(zdev); } -#ifdef CONFIG_HIBERNATE_CALLBACKS -static int zpci_restore(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct zpci_dev *zdev = to_zpci(pdev); - int ret = 0; - - if (zdev->state != ZPCI_FN_STATE_ONLINE) - goto out; - - ret = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES); - if (ret) - goto out; - - zpci_map_resources(pdev); - zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, - (u64) zdev->dma_table); - -out: - return ret; -} - -static int zpci_freeze(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct zpci_dev *zdev = to_zpci(pdev); - - if (zdev->state != ZPCI_FN_STATE_ONLINE) - return 0; - - zpci_unregister_ioat(zdev, 0); - zpci_unmap_resources(pdev); - return clp_disable_fh(zdev); -} - -struct dev_pm_ops pcibios_pm_ops = { - .thaw_noirq = zpci_restore, - .freeze_noirq = zpci_freeze, - .restore_noirq = zpci_restore, - .poweroff_noirq = zpci_freeze, -}; -#endif /* CONFIG_HIBERNATE_CALLBACKS */ - static int zpci_alloc_domain(struct zpci_dev *zdev) { + spin_lock(&zpci_domain_lock); + if (zpci_num_domains_allocated > (ZPCI_NR_DEVICES - 1)) { + spin_unlock(&zpci_domain_lock); + pr_err("Adding PCI function %08x failed because the configured limit of %d is reached\n", + zdev->fid, ZPCI_NR_DEVICES); + return -ENOSPC; + } + if (zpci_unique_uid) { zdev->domain = (u16) zdev->uid; - if (zdev->domain >= ZPCI_NR_DEVICES) - return 0; + if (zdev->domain == 0) { + pr_warn("UID checking is active but no UID is set for PCI function %08x, so automatic domain allocation is used instead\n", + zdev->fid); + update_uid_checking(false); + goto auto_allocate; + } - spin_lock(&zpci_domain_lock); if (test_bit(zdev->domain, zpci_domain)) { spin_unlock(&zpci_domain_lock); pr_err("Adding PCI function %08x failed because domain %04x is already assigned\n", @@ -665,30 +634,28 @@ static int zpci_alloc_domain(struct zpci_dev *zdev) return -EEXIST; } set_bit(zdev->domain, zpci_domain); + zpci_num_domains_allocated++; spin_unlock(&zpci_domain_lock); return 0; } - - spin_lock(&zpci_domain_lock); +auto_allocate: + /* + * We can always auto allocate domains below ZPCI_NR_DEVICES. + * There is either a free domain or we have reached the maximum in + * which case we would have bailed earlier. + */ zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); - if (zdev->domain == ZPCI_NR_DEVICES) { - spin_unlock(&zpci_domain_lock); - pr_err("Adding PCI function %08x failed because the configured limit of %d is reached\n", - zdev->fid, ZPCI_NR_DEVICES); - return -ENOSPC; - } set_bit(zdev->domain, zpci_domain); + zpci_num_domains_allocated++; spin_unlock(&zpci_domain_lock); return 0; } static void zpci_free_domain(struct zpci_dev *zdev) { - if (zdev->domain >= ZPCI_NR_DEVICES) - return; - spin_lock(&zpci_domain_lock); clear_bit(zdev->domain, zpci_domain); + zpci_num_domains_allocated--; spin_unlock(&zpci_domain_lock); } diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 0d3d8f170ea4..ea794ae755ae 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -24,7 +24,7 @@ bool zpci_unique_uid; -static void update_uid_checking(bool new) +void update_uid_checking(bool new) { if (zpci_unique_uid != new) zpci_dbg(1, "uid checking:%d\n", new); diff --git a/arch/s390/purgatory/.gitignore b/arch/s390/purgatory/.gitignore index c82157f46b18..97ca52779457 100644 --- a/arch/s390/purgatory/.gitignore +++ b/arch/s390/purgatory/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only purgatory purgatory.chk purgatory.lds diff --git a/arch/s390/tools/.gitignore b/arch/s390/tools/.gitignore index 71bd6f8eebaf..ea62f37b79ef 100644 --- a/arch/s390/tools/.gitignore +++ b/arch/s390/tools/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only gen_facilities gen_opcode_table diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore index f50fdd9975c5..6603bbbc917d 100644 --- a/arch/sh/boot/.gitignore +++ b/arch/sh/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only zImage vmlinux* uImage* diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore index edff113f1b85..37aa53057369 100644 --- a/arch/sh/boot/compressed/.gitignore +++ b/arch/sh/boot/compressed/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only ashiftrt.S ashldi3.c ashlsi3.S diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index e5beb625ab88..87db9a84b5ec 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -46,7 +46,6 @@ CONFIG_BLK_DEV_IDETAPE=m CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y diff --git a/arch/sh/include/asm/bitops-op32.h b/arch/sh/include/asm/bitops-op32.h index 466880362ad1..cfe5465acce7 100644 --- a/arch/sh/include/asm/bitops-op32.h +++ b/arch/sh/include/asm/bitops-op32.h @@ -16,11 +16,9 @@ #define BYTE_OFFSET(nr) ((nr) % BITS_PER_BYTE) #endif -#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) - static inline void __set_bit(int nr, volatile unsigned long *addr) { - if (IS_IMMEDIATE(nr)) { + if (__builtin_constant_p(nr)) { __asm__ __volatile__ ( "bset.b %1, @(%O2,%0) ! __set_bit\n\t" : "+r" (addr) @@ -37,7 +35,7 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) static inline void __clear_bit(int nr, volatile unsigned long *addr) { - if (IS_IMMEDIATE(nr)) { + if (__builtin_constant_p(nr)) { __asm__ __volatile__ ( "bclr.b %1, @(%O2,%0) ! __clear_bit\n\t" : "+r" (addr) @@ -64,7 +62,7 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr) */ static inline void __change_bit(int nr, volatile unsigned long *addr) { - if (IS_IMMEDIATE(nr)) { + if (__builtin_constant_p(nr)) { __asm__ __volatile__ ( "bxor.b %1, @(%O2,%0) ! __change_bit\n\t" : "+r" (addr) diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 5eef8be3e59f..ea8d68f58e39 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -182,9 +182,6 @@ typedef struct page *pgtable_t; #endif #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/sh/include/uapi/asm/setup.h b/arch/sh/include/uapi/asm/setup.h deleted file mode 100644 index 4bd19f80f9b0..000000000000 --- a/arch/sh/include/uapi/asm/setup.h +++ /dev/null @@ -1,2 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#include <asm-generic/setup.h> diff --git a/arch/sh/include/uapi/asm/types.h b/arch/sh/include/uapi/asm/types.h deleted file mode 100644 index 68100e108ea6..000000000000 --- a/arch/sh/include/uapi/asm/types.h +++ /dev/null @@ -1,2 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#include <asm-generic/types.h> diff --git a/arch/sh/kernel/.gitignore b/arch/sh/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/sh/kernel/.gitignore +++ b/arch/sh/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/sh/kernel/syscalls/syscallhdr.sh b/arch/sh/kernel/syscalls/syscallhdr.sh index 1de0334e577f..4c0519861e97 100644 --- a/arch/sh/kernel/syscalls/syscallhdr.sh +++ b/arch/sh/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore index 40836ad9079c..530a3031a88d 100644 --- a/arch/sh/kernel/vsyscall/.gitignore +++ b/arch/sh/kernel/vsyscall/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vsyscall.lds diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 13ee4d20e622..5f23d7907597 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -355,7 +355,7 @@ static inline int access_error(int error_code, struct vm_area_struct *vma) return 1; /* read, not present: */ - if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + if (unlikely(!vma_is_accessible(vma))) return 1; return 0; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index d1b1ff2be17a..b9de2d4fa57e 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -406,14 +406,17 @@ void __init mem_init(void) #ifdef CONFIG_MEMORY_HOTPLUG int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = PFN_DOWN(start); unsigned long nr_pages = size >> PAGE_SHIFT; int ret; + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot) + return -EINVAL; + /* We only have ZONE_NORMAL, so this is easy.. */ - ret = __add_pages(nid, start_pfn, nr_pages, restrictions); + ret = __add_pages(nid, start_pfn, nr_pages, params); if (unlikely(ret)) printk("%s: Failed, __add_pages() == %d\n", __func__, ret); diff --git a/arch/sparc/boot/.gitignore b/arch/sparc/boot/.gitignore index fc6f3986c76c..f3d8569a21d1 100644 --- a/arch/sparc/boot/.gitignore +++ b/arch/sparc/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only btfix.S btfixupprep image diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 6c325d53a20a..bde4d21a8ac8 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -73,7 +73,6 @@ CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index ed32845bd2d2..2f051343612e 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -2,23 +2,12 @@ #ifndef ___ASM_SPARC_DMA_MAPPING_H #define ___ASM_SPARC_DMA_MAPPING_H -#include <asm/cpu_type.h> - extern const struct dma_map_ops *dma_ops; -extern struct bus_type pci_bus_type; - static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) { -#ifdef CONFIG_SPARC_LEON - if (sparc_cpu_model == sparc_leon) - return NULL; -#endif -#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI) - if (bus == &pci_bus_type) - return NULL; -#endif - return dma_ops; + /* sparc32 uses per-device dma_ops */ + return IS_ENABLED(CONFIG_SPARC64) ? dma_ops : NULL; } #endif diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index b76d59edec8c..478260002836 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -133,9 +133,6 @@ extern unsigned long pfn_base; #define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr)) #define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index e80f2d5bf62f..254dffd85fb1 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -158,9 +158,6 @@ extern unsigned long PAGE_OFFSET; #endif /* !(__ASSEMBLY__) */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/getorder.h> #endif /* _SPARC64_PAGE_H */ diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index 6d6f44c0cad9..0de659ae0ba4 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -223,11 +223,6 @@ static inline int pte_young(pte_t pte) return pte_val(pte) & SRMMU_REF; } -static inline int pte_special(pte_t pte) -{ - return 0; -} - static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~SRMMU_WRITE); @@ -258,8 +253,6 @@ static inline pte_t pte_mkyoung(pte_t pte) return __pte(pte_val(pte) | SRMMU_REF); } -#define pte_mkspecial(pte) (pte) - #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot) static inline unsigned long pte_pfn(pte_t pte) diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 65494c3a420e..da527b27cf7d 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -907,11 +907,11 @@ static inline unsigned long pud_pfn(pud_t pud) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))) /* Find an entry in the third-level page table.. */ -#define pte_index(dir, address) \ - ((pte_t *) __pmd_page(*(dir)) + \ - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) -#define pte_offset_kernel pte_index -#define pte_offset_map pte_index +#define pte_index(address) \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) __pmd_page(*(dir)) + pte_index(address)) +#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) #define pte_unmap(pte) do { } while (0) /* We cannot include <linux/mm_types.h> at this point yet: */ diff --git a/arch/sparc/kernel/.gitignore b/arch/sparc/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/sparc/kernel/.gitignore +++ b/arch/sparc/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index e59461d03b9a..d6874c9b639f 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -373,9 +373,6 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, dma_make_coherent(paddr, PAGE_ALIGN(size)); } -const struct dma_map_ops *dma_ops; -EXPORT_SYMBOL(dma_ops); - #ifdef CONFIG_PROC_FS static int sparc_io_proc_show(struct seq_file *m, void *v) diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index b32cc5610712..e717a56efc5d 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -67,6 +67,7 @@ void of_propagate_archdata(struct platform_device *bus) op->dev.archdata.stc = bus_sd->stc; op->dev.archdata.host_controller = bus_sd->host_controller; op->dev.archdata.numa_node = bus_sd->numa_node; + op->dev.dma_ops = bus->dev.dma_ops; if (dp->child) of_propagate_archdata(op); diff --git a/arch/sparc/kernel/syscalls/syscallhdr.sh b/arch/sparc/kernel/syscalls/syscallhdr.sh index 626b5740a9f1..cf50a75cc0bb 100644 --- a/arch/sparc/kernel/syscalls/syscallhdr.sh +++ b/arch/sparc/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 33a0facd9eb5..289276b99b01 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -38,6 +38,8 @@ #define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) +static const struct dma_map_ops iounit_dma_ops; + static void __init iounit_iommu_init(struct platform_device *op) { struct iounit_struct *iounit; @@ -70,6 +72,8 @@ static void __init iounit_iommu_init(struct platform_device *op) xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); for (; xpt < xptend; xpt++) sbus_writel(0, xpt); + + op->dev.dma_ops = &iounit_dma_ops; } static int __init iounit_init(void) @@ -288,8 +292,3 @@ static const struct dma_map_ops iounit_dma_ops = { .map_sg = iounit_map_sg, .unmap_sg = iounit_unmap_sg, }; - -void __init ld_mmu_iounit(void) -{ - dma_ops = &iounit_dma_ops; -} diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 4d3c6991f0ae..b00dde13681b 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -54,6 +54,9 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */ #define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) #define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) +static const struct dma_map_ops sbus_iommu_dma_gflush_ops; +static const struct dma_map_ops sbus_iommu_dma_pflush_ops; + static void __init sbus_iommu_init(struct platform_device *op) { struct iommu_struct *iommu; @@ -129,6 +132,11 @@ static void __init sbus_iommu_init(struct platform_device *op) (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); op->dev.archdata.iommu = iommu; + + if (flush_page_for_dma_global) + op->dev.dma_ops = &sbus_iommu_dma_gflush_ops; + else + op->dev.dma_ops = &sbus_iommu_dma_pflush_ops; } static int __init iommu_init(void) @@ -445,13 +453,6 @@ static const struct dma_map_ops sbus_iommu_dma_pflush_ops = { void __init ld_mmu_iommu(void) { - if (flush_page_for_dma_global) { - /* flush_page_for_dma flushes everything, no matter of what page is it */ - dma_ops = &sbus_iommu_dma_gflush_ops; - } else { - dma_ops = &sbus_iommu_dma_pflush_ops; - } - if (viking_mxcc_present || srmmu_modtype == HyperSparc) { dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV); ioperm_noc = IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID; diff --git a/arch/sparc/mm/mm_32.h b/arch/sparc/mm/mm_32.h index 0d0b06e952a5..ce750a99eea9 100644 --- a/arch/sparc/mm/mm_32.h +++ b/arch/sparc/mm/mm_32.h @@ -20,6 +20,3 @@ void __init srmmu_paging_init(void); /* iommu.c */ void ld_mmu_iommu(void); - -/* io-unit.c */ -void ld_mmu_iounit(void); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index f56c3c9a9793..b7c94de70cca 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1865,9 +1865,7 @@ void __init load_mmu(void) &smp_cachetlb_ops; #endif - if (sparc_cpu_model == sun4d) - ld_mmu_iounit(); - else + if (sparc_cpu_model != sun4d) ld_mmu_iommu(); #ifdef CONFIG_SMP if (sparc_cpu_model == sun4d) diff --git a/arch/sparc/vdso/.gitignore b/arch/sparc/vdso/.gitignore index ef925b998222..8d4ebc990bf3 100644 --- a/arch/sparc/vdso/.gitignore +++ b/arch/sparc/vdso/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds vdso-image-*.c vdso2c diff --git a/arch/sparc/vdso/vdso32/.gitignore b/arch/sparc/vdso/vdso32/.gitignore index e45fba9d0ced..5167384843b9 100644 --- a/arch/sparc/vdso/vdso32/.gitignore +++ b/arch/sparc/vdso/vdso32/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso32.lds diff --git a/arch/sparc/vdso/vdso32/vclock_gettime.c b/arch/sparc/vdso/vdso32/vclock_gettime.c index 026abb3b826c..d7f99e6745ea 100644 --- a/arch/sparc/vdso/vdso32/vclock_gettime.c +++ b/arch/sparc/vdso/vdso32/vclock_gettime.c @@ -4,10 +4,6 @@ #define BUILD_VDSO32 -#ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE -#undef CONFIG_OPTIMIZE_INLINING -#endif - #ifdef CONFIG_SPARC64 /* diff --git a/arch/um/.gitignore b/arch/um/.gitignore index a73d3a1cc746..6323e5571887 100644 --- a/arch/um/.gitignore +++ b/arch/um/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only kernel/config.c kernel/config.tmp kernel/vmlinux.lds diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 0917f8443c28..96ab7026b037 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -62,9 +62,12 @@ config NR_CPUS source "arch/$(HEADER_ARCH)/um/Kconfig" +config FORBID_STATIC_LINK + bool + config STATIC_LINK bool "Force a static link" - default n + depends on !FORBID_STATIC_LINK help This option gives you the ability to force a static link of UML. Normally, UML is linked as a shared binary. This is inconvenient for @@ -73,6 +76,9 @@ config STATIC_LINK Additionally, this option enables using higher memory spaces (up to 2.75G) for UML. + NOTE: This option is incompatible with some networking features which + depend on features that require being dynamically loaded (like NSS). + config LD_SCRIPT_STATIC bool default y @@ -191,6 +197,7 @@ config UML_TIME_TRAVEL_SUPPORT prompt "Support time-travel mode (e.g. for test execution)" # inf-cpu mode is incompatible with the benchmarking depends on !RAID6_PQ_BENCHMARK + depends on !SMP help Enable this option to support time travel inside the UML instance. diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index 73e98bb57bf5..fb51bd206dbe 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig @@ -26,7 +26,7 @@ CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set -CONFIG_IOSCHED_CFQ=m +CONFIG_IOSCHED_BFQ=m CONFIG_SSL=y CONFIG_NULL_CHAN=y CONFIG_PORT_CHAN=y diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index 3281d7600225..477b87317424 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig @@ -24,7 +24,7 @@ CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set -CONFIG_IOSCHED_CFQ=m +CONFIG_IOSCHED_BFQ=m CONFIG_SSL=y CONFIG_NULL_CHAN=y CONFIG_PORT_CHAN=y diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index 72d417055782..9160ead56e33 100644 --- a/arch/um/drivers/Kconfig +++ b/arch/um/drivers/Kconfig @@ -234,6 +234,7 @@ config UML_NET_DAEMON config UML_NET_VECTOR bool "Vector I/O high performance network devices" depends on UML_NET + select FORBID_STATIC_LINK help This User-Mode Linux network driver uses multi-message send and receive functions. The host running the UML guest must have @@ -245,6 +246,7 @@ config UML_NET_VECTOR config UML_NET_VDE bool "VDE transport (obsolete)" depends on UML_NET + select FORBID_STATIC_LINK help This User-Mode Linux network transport allows one or more running UMLs on a single host to communicate with each other and also @@ -292,6 +294,7 @@ config UML_NET_MCAST config UML_NET_PCAP bool "pcap transport (obsolete)" depends on UML_NET + select FORBID_STATIC_LINK help The pcap transport makes a pcap packet stream on the host look like an ethernet device inside UML. This is useful for making diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 35ebeebfc1a8..1802cf4ef5a5 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -266,7 +266,6 @@ static void uml_net_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strlcpy(info->version, "42", sizeof(info->version)); } static const struct ethtool_ops uml_net_ethtool_ops = { @@ -275,17 +274,6 @@ static const struct ethtool_ops uml_net_ethtool_ops = { .get_ts_info = ethtool_op_get_ts_info, }; -static void uml_net_user_timer_expire(struct timer_list *t) -{ -#ifdef undef - struct uml_net_private *lp = from_timer(lp, t, tl); - struct connection *conn = &lp->user; - - dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn); - do_connect(conn); -#endif -} - void uml_net_setup_etheraddr(struct net_device *dev, char *str) { unsigned char *addr = dev->dev_addr; @@ -456,7 +444,6 @@ static void eth_configure(int n, void *init, char *mac, .add_address = transport->user->add_address, .delete_address = transport->user->delete_address }); - timer_setup(&lp->tl, uml_net_user_timer_expire, 0); spin_lock_init(&lp->lock); memcpy(lp->mac, dev->dev_addr, sizeof(lp->mac)); diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 1d5d3057e6f1..ce115fce52f0 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -23,8 +23,6 @@ #define RNG_VERSION "1.0.0" #define RNG_MODULE_NAME "hw_random" -#define RNG_MISCDEV_MINOR 183 /* official */ - /* Changed at init time, in the non-modular case, and at module load * time, in the module case. Presumably, the module subsystem * protects against a module being loaded twice at the same time. @@ -104,7 +102,7 @@ static const struct file_operations rng_chrdev_ops = { /* rng_init shouldn't be called more than once at boot time */ static struct miscdevice rng_miscdev = { - RNG_MISCDEV_MINOR, + HWRNG_MINOR, RNG_MODULE_NAME, &rng_chrdev_ops, }; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 247f95da057b..eae8c83364f7 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1592,11 +1592,11 @@ int io_thread(void *arg) &io_remainder_size, UBD_REQ_BUFFER_SIZE ); - if (n < 0) { - if (n == -EAGAIN) { + if (n <= 0) { + if (n == -EAGAIN) ubd_read_poll(-1); - continue; - } + + continue; } for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { @@ -1607,7 +1607,9 @@ int io_thread(void *arg) written = 0; do { - res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + res = os_write_file(kernel_fd, + ((char *) io_req_buffer) + written, + n - written); if (res >= 0) { written += res; } diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index e98304d0219e..8735c468230a 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -46,7 +46,6 @@ #define DRIVER_NAME "uml-vector" -#define DRIVER_VERSION "01" struct vector_cmd_line_arg { struct list_head list; int unit; @@ -198,6 +197,9 @@ static int get_transport_options(struct arglist *def) long parsed; int result = 0; + if (transport == NULL) + return -EINVAL; + if (vector != NULL) { if (kstrtoul(vector, 10, &parsed) == 0) { if (parsed == 0) { @@ -1378,7 +1380,6 @@ static void vector_net_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); } static int vector_net_load_bpf_flash(struct net_device *dev, diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c index ddcd917be0af..aa28e9eecb7b 100644 --- a/arch/um/drivers/vector_user.c +++ b/arch/um/drivers/vector_user.c @@ -221,8 +221,7 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); - if (result != NULL) - kfree(result); + kfree(result); return NULL; } @@ -266,8 +265,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) return result; hybrid_cleanup: printk(UM_KERN_ERR "user_init_hybrid: init failed"); - if (result != NULL) - kfree(result); + kfree(result); return NULL; } @@ -344,10 +342,8 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id) unix_cleanup: if (fd >= 0) os_close_file(fd); - if (remote_addr != NULL) - kfree(remote_addr); - if (result != NULL) - kfree(result); + kfree(remote_addr); + kfree(result); return NULL; } @@ -382,8 +378,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) return result; raw_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); - if (result != NULL) - kfree(result); + kfree(result); return NULL; } diff --git a/arch/um/drivers/vhost_user.h b/arch/um/drivers/vhost_user.h index 45ff5ea22fea..6c71b6005177 100644 --- a/arch/um/drivers/vhost_user.h +++ b/arch/um/drivers/vhost_user.h @@ -10,9 +10,10 @@ /* Feature bits */ #define VHOST_USER_F_PROTOCOL_FEATURES 30 /* Protocol feature bits */ -#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3 -#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5 -#define VHOST_USER_PROTOCOL_F_CONFIG 9 +#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3 +#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5 +#define VHOST_USER_PROTOCOL_F_CONFIG 9 +#define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14 /* Vring state index masks */ #define VHOST_USER_VRING_INDEX_MASK 0xff #define VHOST_USER_VRING_POLL_MASK BIT(8) @@ -24,7 +25,8 @@ /* Supported protocol features */ #define VHOST_USER_SUPPORTED_PROTOCOL_F (BIT_ULL(VHOST_USER_PROTOCOL_F_REPLY_ACK) | \ BIT_ULL(VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \ - BIT_ULL(VHOST_USER_PROTOCOL_F_CONFIG)) + BIT_ULL(VHOST_USER_PROTOCOL_F_CONFIG) | \ + BIT_ULL(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS)) enum vhost_user_request { VHOST_USER_GET_FEATURES = 1, @@ -52,12 +54,14 @@ enum vhost_user_request { VHOST_USER_SET_VRING_ENDIAN = 23, VHOST_USER_GET_CONFIG = 24, VHOST_USER_SET_CONFIG = 25, + VHOST_USER_VRING_KICK = 35, }; enum vhost_user_slave_request { VHOST_USER_SLAVE_IOTLB_MSG = 1, VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2, VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3, + VHOST_USER_SLAVE_VRING_CALL = 4, }; struct vhost_user_header { diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 023ced2250ea..be54d368e73d 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -26,6 +26,7 @@ #include <linux/virtio.h> #include <linux/virtio_config.h> #include <linux/virtio_ring.h> +#include <linux/time-internal.h> #include <shared/as-layout.h> #include <irq_kern.h> #include <init.h> @@ -53,6 +54,7 @@ struct virtio_uml_device { struct virtio_device vdev; struct platform_device *pdev; + spinlock_t sock_lock; int sock, req_fd; u64 features; u64 protocol_features; @@ -63,6 +65,11 @@ struct virtio_uml_device { struct virtio_uml_vq_info { int kick_fd, call_fd; char name[32]; +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT + struct virtqueue *vq; + vq_callback_t *callback; + struct time_travel_event defer; +#endif }; extern unsigned long long physmem_size, highmem; @@ -117,10 +124,27 @@ static int vhost_user_recv_header(int fd, struct vhost_user_msg *msg) static int vhost_user_recv(struct virtio_uml_device *vu_dev, int fd, struct vhost_user_msg *msg, - size_t max_payload_size) + size_t max_payload_size, bool wait) { size_t size; - int rc = vhost_user_recv_header(fd, msg); + int rc; + + /* + * In virtio time-travel mode, we're handling all the vhost-user + * FDs by polling them whenever appropriate. However, we may get + * into a situation where we're sending out an interrupt message + * to a device (e.g. a net device) and need to handle a simulation + * time message while doing so, e.g. one that tells us to update + * our idea of how long we can run without scheduling. + * + * Thus, we need to not just read() from the given fd, but need + * to also handle messages for the simulation time - this function + * does that for us while waiting for the given fd to be readable. + */ + if (wait) + time_travel_wait_readable(fd); + + rc = vhost_user_recv_header(fd, msg); if (rc == -ECONNRESET && vu_dev->registered) { struct virtio_uml_platform_data *pdata; @@ -142,7 +166,8 @@ static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, struct vhost_user_msg *msg, size_t max_payload_size) { - int rc = vhost_user_recv(vu_dev, vu_dev->sock, msg, max_payload_size); + int rc = vhost_user_recv(vu_dev, vu_dev->sock, msg, + max_payload_size, true); if (rc) return rc; @@ -172,7 +197,8 @@ static int vhost_user_recv_req(struct virtio_uml_device *vu_dev, struct vhost_user_msg *msg, size_t max_payload_size) { - int rc = vhost_user_recv(vu_dev, vu_dev->req_fd, msg, max_payload_size); + int rc = vhost_user_recv(vu_dev, vu_dev->req_fd, msg, + max_payload_size, false); if (rc) return rc; @@ -189,6 +215,7 @@ static int vhost_user_send(struct virtio_uml_device *vu_dev, int *fds, size_t num_fds) { size_t size = sizeof(msg->header) + msg->header.size; + unsigned long flags; bool request_ack; int rc; @@ -207,24 +234,28 @@ static int vhost_user_send(struct virtio_uml_device *vu_dev, if (request_ack) msg->header.flags |= VHOST_USER_FLAG_NEED_REPLY; + spin_lock_irqsave(&vu_dev->sock_lock, flags); rc = full_sendmsg_fds(vu_dev->sock, msg, size, fds, num_fds); if (rc < 0) - return rc; + goto out; if (request_ack) { uint64_t status; rc = vhost_user_recv_u64(vu_dev, &status); if (rc) - return rc; + goto out; if (status) { vu_err(vu_dev, "slave reports error: %llu\n", status); - return -EIO; + rc = -EIO; + goto out; } } - return 0; +out: + spin_unlock_irqrestore(&vu_dev->sock_lock, flags); + return rc; } static int vhost_user_send_no_payload(struct virtio_uml_device *vu_dev, @@ -324,6 +355,7 @@ static void vhost_user_reply(struct virtio_uml_device *vu_dev, static irqreturn_t vu_req_interrupt(int irq, void *data) { struct virtio_uml_device *vu_dev = data; + struct virtqueue *vq; int response = 1; struct { struct vhost_user_msg msg; @@ -343,6 +375,15 @@ static irqreturn_t vu_req_interrupt(int irq, void *data) virtio_config_changed(&vu_dev->vdev); response = 0; break; + case VHOST_USER_SLAVE_VRING_CALL: + virtio_device_for_each_vq((&vu_dev->vdev), vq) { + if (vq->index == msg.msg.payload.vring_state.index) { + response = 0; + vring_interrupt(0 /* ignored */, vq); + break; + } + } + break; case VHOST_USER_SLAVE_IOTLB_MSG: /* not supported - VIRTIO_F_IOMMU_PLATFORM */ case VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG: @@ -684,6 +725,17 @@ static bool vu_notify(struct virtqueue *vq) const uint64_t n = 1; int rc; + time_travel_propagate_time(); + + if (info->kick_fd < 0) { + struct virtio_uml_device *vu_dev; + + vu_dev = to_virtio_uml_device(vq->vdev); + + return vhost_user_set_vring_state(vu_dev, VHOST_USER_VRING_KICK, + vq->index, 0) == 0; + } + do { rc = os_write_file(info->kick_fd, &n, sizeof(n)); } while (rc == -EINTR); @@ -749,10 +801,13 @@ static void vu_del_vq(struct virtqueue *vq) { struct virtio_uml_vq_info *info = vq->priv; - um_free_irq(VIRTIO_IRQ, vq); + if (info->call_fd >= 0) { + um_free_irq(VIRTIO_IRQ, vq); + os_close_file(info->call_fd); + } - os_close_file(info->call_fd); - os_close_file(info->kick_fd); + if (info->kick_fd >= 0) + os_close_file(info->kick_fd); vring_del_virtqueue(vq); kfree(info); @@ -782,6 +837,15 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, int call_fds[2]; int rc; + /* no call FD needed/desired in this case */ + if (vu_dev->protocol_features & + BIT_ULL(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS) && + vu_dev->protocol_features & + BIT_ULL(VHOST_USER_PROTOCOL_F_SLAVE_REQ)) { + info->call_fd = -1; + return 0; + } + /* Use a pipe for call fd, since SIGIO is not supported for eventfd */ rc = os_pipe(call_fds, true, true); if (rc < 0) @@ -810,6 +874,23 @@ out: return rc; } +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT +static void vu_defer_irq_handle(struct time_travel_event *d) +{ + struct virtio_uml_vq_info *info; + + info = container_of(d, struct virtio_uml_vq_info, defer); + info->callback(info->vq); +} + +static void vu_defer_irq_callback(struct virtqueue *vq) +{ + struct virtio_uml_vq_info *info = vq->priv; + + time_travel_add_irq_event(&info->defer); +} +#endif + static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, unsigned index, vq_callback_t *callback, const char *name, bool ctx) @@ -829,6 +910,19 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, snprintf(info->name, sizeof(info->name), "%s.%d-%s", pdev->name, pdev->id, name); +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT + /* + * When we get an interrupt, we must bounce it through the simulation + * calendar (the simtime device), except for the simtime device itself + * since that's part of the simulation control. + */ + if (time_travel_mode == TT_MODE_EXTERNAL && callback) { + info->callback = callback; + callback = vu_defer_irq_callback; + time_travel_set_event_fn(&info->defer, vu_defer_irq_handle); + } +#endif + vq = vring_create_virtqueue(index, num, PAGE_SIZE, vdev, true, true, ctx, vu_notify, callback, info->name); if (!vq) { @@ -837,11 +931,19 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, } vq->priv = info; num = virtqueue_get_vring_size(vq); +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT + info->vq = vq; +#endif - rc = os_eventfd(0, 0); - if (rc < 0) - goto error_kick; - info->kick_fd = rc; + if (vu_dev->protocol_features & + BIT_ULL(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS)) { + info->kick_fd = -1; + } else { + rc = os_eventfd(0, 0); + if (rc < 0) + goto error_kick; + info->kick_fd = rc; + } rc = vu_setup_vq_call_fd(vu_dev, vq); if (rc) @@ -866,10 +968,13 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, return vq; error_setup: - um_free_irq(VIRTIO_IRQ, vq); - os_close_file(info->call_fd); + if (info->call_fd >= 0) { + um_free_irq(VIRTIO_IRQ, vq); + os_close_file(info->call_fd); + } error_call: - os_close_file(info->kick_fd); + if (info->kick_fd >= 0) + os_close_file(info->kick_fd); error_kick: vring_del_virtqueue(vq); error_create: @@ -908,10 +1013,12 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs, list_for_each_entry(vq, &vdev->vqs, list) { struct virtio_uml_vq_info *info = vq->priv; - rc = vhost_user_set_vring_kick(vu_dev, vq->index, - info->kick_fd); - if (rc) - goto error_setup; + if (info->kick_fd >= 0) { + rc = vhost_user_set_vring_kick(vu_dev, vq->index, + info->kick_fd); + if (rc) + goto error_setup; + } rc = vhost_user_set_vring_enable(vu_dev, vq->index, true); if (rc) @@ -1008,6 +1115,8 @@ static int virtio_uml_probe(struct platform_device *pdev) return rc; vu_dev->sock = rc; + spin_lock_init(&vu_dev->sock_lock); + rc = vhost_user_init(vu_dev); if (rc) goto error_init; diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index db7d9d4e30d8..8d435f8a6dec 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -3,7 +3,6 @@ generic-y += bpf_perf_event.h generic-y += bug.h generic-y += compat.h generic-y += current.h -generic-y += delay.h generic-y += device.h generic-y += emergency-restart.h generic-y += exec.h diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h new file mode 100644 index 000000000000..56fc2b8f2dd0 --- /dev/null +++ b/arch/um/include/asm/delay.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_DELAY_H +#define __UM_DELAY_H +#include <asm-generic/delay.h> +#include <linux/time-internal.h> + +static inline void um_ndelay(unsigned long nsecs) +{ + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) { + time_travel_ndelay(nsecs); + return; + } + ndelay(nsecs); +} +#undef ndelay +#define ndelay um_ndelay + +static inline void um_udelay(unsigned long usecs) +{ + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) { + time_travel_ndelay(1000 * usecs); + return; + } + udelay(usecs); +} +#undef udelay +#define udelay um_udelay +#endif /* __UM_DELAY_H */ diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 2daa58df2190..b5ddf5d98bd5 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -167,11 +167,6 @@ static inline int pte_newprot(pte_t pte) return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT))); } -static inline int pte_special(pte_t pte) -{ - return 0; -} - /* * ================================= * Flags setting section. @@ -247,11 +242,6 @@ static inline pte_t pte_mknewpage(pte_t pte) return(pte); } -static inline pte_t pte_mkspecial(pte_t pte) -{ - return(pte); -} - static inline void set_pte(pte_t *pteptr, pte_t pteval) { pte_copy(*pteptr, pteval); diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h new file mode 100644 index 000000000000..f3b03d39a854 --- /dev/null +++ b/arch/um/include/linux/time-internal.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2012 - 2014 Cisco Systems + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#ifndef __TIMER_INTERNAL_H__ +#define __TIMER_INTERNAL_H__ +#include <linux/list.h> + +#define TIMER_MULTIPLIER 256 +#define TIMER_MIN_DELTA 500 + +enum time_travel_mode { + TT_MODE_OFF, + TT_MODE_BASIC, + TT_MODE_INFCPU, + TT_MODE_EXTERNAL, +}; + +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT +struct time_travel_event { + unsigned long long time; + void (*fn)(struct time_travel_event *d); + struct list_head list; + bool pending, onstack; +}; + +extern enum time_travel_mode time_travel_mode; + +void time_travel_sleep(unsigned long long duration); + +static inline void +time_travel_set_event_fn(struct time_travel_event *e, + void (*fn)(struct time_travel_event *d)) +{ + e->fn = fn; +} + +void __time_travel_propagate_time(void); + +static inline void time_travel_propagate_time(void) +{ + if (time_travel_mode == TT_MODE_EXTERNAL) + __time_travel_propagate_time(); +} + +void __time_travel_wait_readable(int fd); + +static inline void time_travel_wait_readable(int fd) +{ + if (time_travel_mode == TT_MODE_EXTERNAL) + __time_travel_wait_readable(fd); +} + +void time_travel_add_irq_event(struct time_travel_event *e); +#else +struct time_travel_event { +}; + +#define time_travel_mode TT_MODE_OFF + +static inline void time_travel_sleep(unsigned long long duration) +{ +} + +/* this is a macro so the event/function need not exist */ +#define time_travel_set_event_fn(e, fn) do {} while (0) + +static inline void time_travel_propagate_time(void) +{ +} + +static inline void time_travel_wait_readable(int fd) +{ +} +#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ + +/* + * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used, + * which is intentional since we really shouldn't link it in that case. + */ +void time_travel_ndelay(unsigned long nsec); +#endif /* __TIMER_INTERNAL_H__ */ diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 0f30204b6afa..f467d28fc0b4 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -181,6 +181,7 @@ extern int os_falloc_punch(int fd, unsigned long long offset, int count); extern int os_eventfd(unsigned int initval, int flags); extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds, unsigned int fds_num); +int os_poll(unsigned int n, const int *fds); /* start_up.c */ extern void os_early_checks(void); diff --git a/arch/um/include/shared/timer-internal.h b/arch/um/include/shared/timer-internal.h deleted file mode 100644 index 2d2d13c9b46f..000000000000 --- a/arch/um/include/shared/timer-internal.h +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2012 - 2014 Cisco Systems - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - */ - -#ifndef __TIMER_INTERNAL_H__ -#define __TIMER_INTERNAL_H__ - -#define TIMER_MULTIPLIER 256 -#define TIMER_MIN_DELTA 500 - -enum time_travel_mode { - TT_MODE_OFF, - TT_MODE_BASIC, - TT_MODE_INFCPU, -}; - -enum time_travel_timer_mode { - TT_TMR_DISABLED, - TT_TMR_ONESHOT, - TT_TMR_PERIODIC, -}; - -#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT -extern enum time_travel_mode time_travel_mode; -extern unsigned long long time_travel_time; -extern enum time_travel_timer_mode time_travel_timer_mode; -extern unsigned long long time_travel_timer_expiry; -extern unsigned long long time_travel_timer_interval; - -static inline void time_travel_set_time(unsigned long long ns) -{ - time_travel_time = ns; -} - -static inline void time_travel_set_timer_mode(enum time_travel_timer_mode mode) -{ - time_travel_timer_mode = mode; -} - -static inline void time_travel_set_timer_expiry(unsigned long long expiry) -{ - time_travel_timer_expiry = expiry; -} - -static inline void time_travel_set_timer_interval(unsigned long long interval) -{ - time_travel_timer_interval = interval; -} -#else -#define time_travel_mode TT_MODE_OFF -#define time_travel_time 0 -#define time_travel_timer_expiry 0 -#define time_travel_timer_interval 0 - -static inline void time_travel_set_time(unsigned long long ns) -{ -} - -static inline void time_travel_set_timer_mode(enum time_travel_timer_mode mode) -{ -} - -static inline void time_travel_set_timer_expiry(unsigned long long expiry) -{ -} - -static inline void time_travel_set_timer_interval(unsigned long long interval) -{ -} - -#define time_travel_timer_mode TT_TMR_DISABLED -#endif - -#endif diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c index 98bdf69e4c2e..e4abac6c9727 100644 --- a/arch/um/kernel/kmsg_dump.c +++ b/arch/um/kernel/kmsg_dump.c @@ -9,20 +9,19 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason) { static char line[1024]; - + struct console *con; size_t len = 0; - bool con_available = false; /* only dump kmsg when no console is available */ if (!console_trylock()) return; - if (console_drivers != NULL) - con_available = true; + for_each_console(con) + break; console_unlock(); - if (con_available == true) + if (con) return; printf("kmsg_dump:\n"); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 56a094182bf5..cbe33af2a880 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,7 +32,7 @@ #include <kern_util.h> #include <os.h> #include <skas.h> -#include <timer-internal.h> +#include <linux/time-internal.h> /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -203,43 +203,6 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } -static void time_travel_sleep(unsigned long long duration) -{ - unsigned long long next = time_travel_time + duration; - - if (time_travel_mode != TT_MODE_INFCPU) - os_timer_disable(); - - while (time_travel_timer_mode == TT_TMR_PERIODIC && - time_travel_timer_expiry < time_travel_time) - time_travel_set_timer_expiry(time_travel_timer_expiry + - time_travel_timer_interval); - - if (time_travel_timer_mode != TT_TMR_DISABLED && - time_travel_timer_expiry < next) { - if (time_travel_timer_mode == TT_TMR_ONESHOT) - time_travel_set_timer_mode(TT_TMR_DISABLED); - /* - * In basic mode, time_travel_time will be adjusted in - * the timer IRQ handler so it works even when the signal - * comes from the OS timer, see there. - */ - if (time_travel_mode != TT_MODE_BASIC) - time_travel_set_time(time_travel_timer_expiry); - - deliver_alarm(); - } else { - time_travel_set_time(next); - } - - if (time_travel_mode != TT_MODE_INFCPU) { - if (time_travel_timer_mode == TT_TMR_PERIODIC) - os_timer_set_interval(time_travel_timer_interval); - else if (time_travel_timer_mode == TT_TMR_ONESHOT) - os_timer_one_shot(time_travel_timer_expiry - next); - } -} - static void um_idle_sleep(void) { unsigned long long duration = UM_NSEC_PER_SEC; diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 40d90dddf3f1..0a12d5a09217 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -10,7 +10,7 @@ #include <sysdep/ptrace.h> #include <sysdep/ptrace_user.h> #include <sysdep/syscalls.h> -#include <shared/timer-internal.h> +#include <linux/time-internal.h> void handle_syscall(struct uml_pt_regs *r) { @@ -24,7 +24,8 @@ void handle_syscall(struct uml_pt_regs *r) * went to sleep, even if said userspace interacts with the kernel in * various ways. */ - if (time_travel_mode == TT_MODE_INFCPU) + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) schedule(); /* Initialize the syscall number and default return value. */ diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 94ea87bd231c..25eaa6a0c658 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -4,6 +4,7 @@ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de) * Copyright (C) 2012-2014 Cisco Systems * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright (C) 2019 Intel Corporation */ #include <linux/clockchips.h> @@ -18,21 +19,484 @@ #include <asm/param.h> #include <kern_util.h> #include <os.h> -#include <timer-internal.h> +#include <linux/time-internal.h> +#include <linux/um_timetravel.h> #include <shared/init.h> #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT enum time_travel_mode time_travel_mode; -unsigned long long time_travel_time; -enum time_travel_timer_mode time_travel_timer_mode; -unsigned long long time_travel_timer_expiry; -unsigned long long time_travel_timer_interval; +EXPORT_SYMBOL_GPL(time_travel_mode); static bool time_travel_start_set; static unsigned long long time_travel_start; -#else +static unsigned long long time_travel_time; +static LIST_HEAD(time_travel_events); +static unsigned long long time_travel_timer_interval; +static unsigned long long time_travel_next_event; +static struct time_travel_event time_travel_timer_event; +static int time_travel_ext_fd = -1; +static unsigned int time_travel_ext_waiting; +static bool time_travel_ext_prev_request_valid; +static unsigned long long time_travel_ext_prev_request; +static bool time_travel_ext_free_until_valid; +static unsigned long long time_travel_ext_free_until; + +static void time_travel_set_time(unsigned long long ns) +{ + if (unlikely(ns < time_travel_time)) + panic("time-travel: time goes backwards %lld -> %lld\n", + time_travel_time, ns); + time_travel_time = ns; +} + +enum time_travel_message_handling { + TTMH_IDLE, + TTMH_POLL, + TTMH_READ, +}; + +static void time_travel_handle_message(struct um_timetravel_msg *msg, + enum time_travel_message_handling mode) +{ + struct um_timetravel_msg resp = { + .op = UM_TIMETRAVEL_ACK, + }; + int ret; + + /* + * Poll outside the locked section (if we're not called to only read + * the response) so we can get interrupts for e.g. virtio while we're + * here, but then we need to lock to not get interrupted between the + * read of the message and write of the ACK. + */ + if (mode != TTMH_READ) { + while (os_poll(1, &time_travel_ext_fd) != 0) { + if (mode == TTMH_IDLE) { + BUG_ON(!irqs_disabled()); + local_irq_enable(); + local_irq_disable(); + } + } + } + + ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); + + if (ret == 0) + panic("time-travel external link is broken\n"); + if (ret != sizeof(*msg)) + panic("invalid time-travel message - %d bytes\n", ret); + + switch (msg->op) { + default: + WARN_ONCE(1, "time-travel: unexpected message %lld\n", + (unsigned long long)msg->op); + break; + case UM_TIMETRAVEL_ACK: + return; + case UM_TIMETRAVEL_RUN: + time_travel_set_time(msg->time); + break; + case UM_TIMETRAVEL_FREE_UNTIL: + time_travel_ext_free_until_valid = true; + time_travel_ext_free_until = msg->time; + break; + } + + os_write_file(time_travel_ext_fd, &resp, sizeof(resp)); +} + +static u64 time_travel_ext_req(u32 op, u64 time) +{ + static int seq; + int mseq = ++seq; + struct um_timetravel_msg msg = { + .op = op, + .time = time, + .seq = mseq, + }; + unsigned long flags; + + /* + * We need to save interrupts here and only restore when we + * got the ACK - otherwise we can get interrupted and send + * another request while we're still waiting for an ACK, but + * the peer doesn't know we got interrupted and will send + * the ACKs in the same order as the message, but we'd need + * to see them in the opposite order ... + * + * This wouldn't matter *too* much, but some ACKs carry the + * current time (for UM_TIMETRAVEL_GET) and getting another + * ACK without a time would confuse us a lot! + * + * The sequence number assignment that happens here lets us + * debug such message handling issues more easily. + */ + local_irq_save(flags); + os_write_file(time_travel_ext_fd, &msg, sizeof(msg)); + + while (msg.op != UM_TIMETRAVEL_ACK) + time_travel_handle_message(&msg, TTMH_READ); + + if (msg.seq != mseq) + panic("time-travel: ACK message has different seqno! op=%d, seq=%d != %d time=%lld\n", + msg.op, msg.seq, mseq, msg.time); + + if (op == UM_TIMETRAVEL_GET) + time_travel_set_time(msg.time); + local_irq_restore(flags); + + return msg.time; +} + +void __time_travel_wait_readable(int fd) +{ + int fds[2] = { fd, time_travel_ext_fd }; + int ret; + + if (time_travel_mode != TT_MODE_EXTERNAL) + return; + + while ((ret = os_poll(2, fds))) { + struct um_timetravel_msg msg; + + if (ret == 1) + time_travel_handle_message(&msg, TTMH_READ); + } +} +EXPORT_SYMBOL_GPL(__time_travel_wait_readable); + +static void time_travel_ext_update_request(unsigned long long time) +{ + if (time_travel_mode != TT_MODE_EXTERNAL) + return; + + /* asked for exactly this time previously */ + if (time_travel_ext_prev_request_valid && + time == time_travel_ext_prev_request) + return; + + time_travel_ext_prev_request = time; + time_travel_ext_prev_request_valid = true; + time_travel_ext_req(UM_TIMETRAVEL_REQUEST, time); +} + +void __time_travel_propagate_time(void) +{ + time_travel_ext_req(UM_TIMETRAVEL_UPDATE, time_travel_time); +} +EXPORT_SYMBOL_GPL(__time_travel_propagate_time); + +/* returns true if we must do a wait to the simtime device */ +static bool time_travel_ext_request(unsigned long long time) +{ + /* + * If we received an external sync point ("free until") then we + * don't have to request/wait for anything until then, unless + * we're already waiting. + */ + if (!time_travel_ext_waiting && time_travel_ext_free_until_valid && + time < time_travel_ext_free_until) + return false; + + time_travel_ext_update_request(time); + return true; +} + +static void time_travel_ext_wait(bool idle) +{ + struct um_timetravel_msg msg = { + .op = UM_TIMETRAVEL_ACK, + }; + + time_travel_ext_prev_request_valid = false; + time_travel_ext_waiting++; + + time_travel_ext_req(UM_TIMETRAVEL_WAIT, -1); + + /* + * Here we are deep in the idle loop, so we have to break out of the + * kernel abstraction in a sense and implement this in terms of the + * UML system waiting on the VQ interrupt while sleeping, when we get + * the signal it'll call time_travel_ext_vq_notify_done() completing the + * call. + */ + while (msg.op != UM_TIMETRAVEL_RUN) + time_travel_handle_message(&msg, idle ? TTMH_IDLE : TTMH_POLL); + + time_travel_ext_waiting--; + + /* we might request more stuff while polling - reset when we run */ + time_travel_ext_prev_request_valid = false; +} + +static void time_travel_ext_get_time(void) +{ + time_travel_ext_req(UM_TIMETRAVEL_GET, -1); +} + +static void __time_travel_update_time(unsigned long long ns, bool idle) +{ + if (time_travel_mode == TT_MODE_EXTERNAL && time_travel_ext_request(ns)) + time_travel_ext_wait(idle); + else + time_travel_set_time(ns); +} + +static struct time_travel_event *time_travel_first_event(void) +{ + return list_first_entry_or_null(&time_travel_events, + struct time_travel_event, + list); +} + +static void __time_travel_add_event(struct time_travel_event *e, + unsigned long long time) +{ + struct time_travel_event *tmp; + bool inserted = false; + + if (WARN(time_travel_mode == TT_MODE_BASIC && + e != &time_travel_timer_event, + "only timer events can be handled in basic mode")) + return; + + if (e->pending) + return; + + e->pending = true; + e->time = time; + + list_for_each_entry(tmp, &time_travel_events, list) { + /* + * Add the new entry before one with higher time, + * or if they're equal and both on stack, because + * in that case we need to unwind the stack in the + * right order, and the later event (timer sleep + * or such) must be dequeued first. + */ + if ((tmp->time > e->time) || + (tmp->time == e->time && tmp->onstack && e->onstack)) { + list_add_tail(&e->list, &tmp->list); + inserted = true; + break; + } + } + + if (!inserted) + list_add_tail(&e->list, &time_travel_events); + + tmp = time_travel_first_event(); + time_travel_ext_update_request(tmp->time); + time_travel_next_event = tmp->time; +} + +static void time_travel_add_event(struct time_travel_event *e, + unsigned long long time) +{ + if (WARN_ON(!e->fn)) + return; + + __time_travel_add_event(e, time); +} + +void time_travel_periodic_timer(struct time_travel_event *e) +{ + time_travel_add_event(&time_travel_timer_event, + time_travel_time + time_travel_timer_interval); + deliver_alarm(); +} + +static void time_travel_deliver_event(struct time_travel_event *e) +{ + if (e == &time_travel_timer_event) { + /* + * deliver_alarm() does the irq_enter/irq_exit + * by itself, so must handle it specially here + */ + e->fn(e); + } else { + unsigned long flags; + + local_irq_save(flags); + irq_enter(); + e->fn(e); + irq_exit(); + local_irq_restore(flags); + } +} + +static bool time_travel_del_event(struct time_travel_event *e) +{ + if (!e->pending) + return false; + list_del(&e->list); + e->pending = false; + return true; +} + +static void time_travel_update_time(unsigned long long next, bool idle) +{ + struct time_travel_event ne = { + .onstack = true, + }; + struct time_travel_event *e; + bool finished = idle; + + /* add it without a handler - we deal with that specifically below */ + __time_travel_add_event(&ne, next); + + do { + e = time_travel_first_event(); + + BUG_ON(!e); + __time_travel_update_time(e->time, idle); + + /* new events may have been inserted while we were waiting */ + if (e == time_travel_first_event()) { + BUG_ON(!time_travel_del_event(e)); + BUG_ON(time_travel_time != e->time); + + if (e == &ne) { + finished = true; + } else { + if (e->onstack) + panic("On-stack event dequeued outside of the stack! time=%lld, event time=%lld, event=%pS\n", + time_travel_time, e->time, e); + time_travel_deliver_event(e); + } + } + + e = time_travel_first_event(); + if (e) + time_travel_ext_update_request(e->time); + } while (ne.pending && !finished); + + time_travel_del_event(&ne); +} + +void time_travel_ndelay(unsigned long nsec) +{ + time_travel_update_time(time_travel_time + nsec, false); +} +EXPORT_SYMBOL(time_travel_ndelay); + +void time_travel_add_irq_event(struct time_travel_event *e) +{ + BUG_ON(time_travel_mode != TT_MODE_EXTERNAL); + + time_travel_ext_get_time(); + /* + * We could model interrupt latency here, for now just + * don't have any latency at all and request the exact + * same time (again) to run the interrupt... + */ + time_travel_add_event(e, time_travel_time); +} +EXPORT_SYMBOL_GPL(time_travel_add_irq_event); + +static void time_travel_oneshot_timer(struct time_travel_event *e) +{ + deliver_alarm(); +} + +void time_travel_sleep(unsigned long long duration) +{ + unsigned long long next = time_travel_time + duration; + + if (time_travel_mode == TT_MODE_BASIC) + os_timer_disable(); + + time_travel_update_time(next, true); + + if (time_travel_mode == TT_MODE_BASIC && + time_travel_timer_event.pending) { + if (time_travel_timer_event.fn == time_travel_periodic_timer) { + /* + * This is somewhat wrong - we should get the first + * one sooner like the os_timer_one_shot() below... + */ + os_timer_set_interval(time_travel_timer_interval); + } else { + os_timer_one_shot(time_travel_timer_event.time - next); + } + } +} + +static void time_travel_handle_real_alarm(void) +{ + time_travel_set_time(time_travel_next_event); + + time_travel_del_event(&time_travel_timer_event); + + if (time_travel_timer_event.fn == time_travel_periodic_timer) + time_travel_add_event(&time_travel_timer_event, + time_travel_time + + time_travel_timer_interval); +} + +static void time_travel_set_interval(unsigned long long interval) +{ + time_travel_timer_interval = interval; +} + +static int time_travel_connect_external(const char *socket) +{ + const char *sep; + unsigned long long id = (unsigned long long)-1; + int rc; + + if ((sep = strchr(socket, ':'))) { + char buf[25] = {}; + if (sep - socket > sizeof(buf) - 1) + goto invalid_number; + + memcpy(buf, socket, sep - socket); + if (kstrtoull(buf, 0, &id)) { +invalid_number: + panic("time-travel: invalid external ID in string '%s'\n", + socket); + return -EINVAL; + } + + socket = sep + 1; + } + + rc = os_connect_socket(socket); + if (rc < 0) { + panic("time-travel: failed to connect to external socket %s\n", + socket); + return rc; + } + + time_travel_ext_fd = rc; + + time_travel_ext_req(UM_TIMETRAVEL_START, id); + + return 1; +} +#else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ #define time_travel_start_set 0 #define time_travel_start 0 +#define time_travel_time 0 + +static inline void time_travel_update_time(unsigned long long ns, bool retearly) +{ +} + +static inline void time_travel_handle_real_alarm(void) +{ +} + +static void time_travel_set_interval(unsigned long long interval) +{ +} + +/* fail link if this actually gets used */ +extern u64 time_travel_ext_req(u32 op, u64 time); + +/* these are empty macros so the struct/fn need not exist */ +#define time_travel_add_event(e, time) do { } while (0) +#define time_travel_del_event(e) do { } while (0) #endif void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) @@ -48,7 +512,7 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) * never get any real signals from the OS. */ if (time_travel_mode == TT_MODE_BASIC) - time_travel_set_time(time_travel_timer_expiry); + time_travel_handle_real_alarm(); local_irq_save(flags); do_IRQ(TIMER_IRQ, regs); @@ -58,9 +522,10 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) static int itimer_shutdown(struct clock_event_device *evt) { if (time_travel_mode != TT_MODE_OFF) - time_travel_set_timer_mode(TT_TMR_DISABLED); + time_travel_del_event(&time_travel_timer_event); - if (time_travel_mode != TT_MODE_INFCPU) + if (time_travel_mode != TT_MODE_INFCPU && + time_travel_mode != TT_MODE_EXTERNAL) os_timer_disable(); return 0; @@ -71,12 +536,16 @@ static int itimer_set_periodic(struct clock_event_device *evt) unsigned long long interval = NSEC_PER_SEC / HZ; if (time_travel_mode != TT_MODE_OFF) { - time_travel_set_timer_mode(TT_TMR_PERIODIC); - time_travel_set_timer_expiry(time_travel_time + interval); - time_travel_set_timer_interval(interval); + time_travel_del_event(&time_travel_timer_event); + time_travel_set_event_fn(&time_travel_timer_event, + time_travel_periodic_timer); + time_travel_set_interval(interval); + time_travel_add_event(&time_travel_timer_event, + time_travel_time + interval); } - if (time_travel_mode != TT_MODE_INFCPU) + if (time_travel_mode != TT_MODE_INFCPU && + time_travel_mode != TT_MODE_EXTERNAL) os_timer_set_interval(interval); return 0; @@ -88,11 +557,15 @@ static int itimer_next_event(unsigned long delta, delta += 1; if (time_travel_mode != TT_MODE_OFF) { - time_travel_set_timer_mode(TT_TMR_ONESHOT); - time_travel_set_timer_expiry(time_travel_time + delta); + time_travel_del_event(&time_travel_timer_event); + time_travel_set_event_fn(&time_travel_timer_event, + time_travel_oneshot_timer); + time_travel_add_event(&time_travel_timer_event, + time_travel_time + delta); } - if (time_travel_mode != TT_MODE_INFCPU) + if (time_travel_mode != TT_MODE_INFCPU && + time_travel_mode != TT_MODE_EXTERNAL) return os_timer_one_shot(delta); return 0; @@ -143,8 +616,17 @@ static u64 timer_read(struct clocksource *cs) * stuck in loops that expect time to move more than the * exact requested sleep amount, e.g. python's socket server, * see https://bugs.python.org/issue37026. + * + * However, don't do that when we're in interrupt or such as + * then we might recurse into our own processing, and get to + * even more waiting, and that's not good - it messes up the + * "what do I do next" and onstack event we use to know when + * to return from time_travel_update_time(). */ - time_travel_set_time(time_travel_time + TIMER_MULTIPLIER); + if (!irqs_disabled() && !in_interrupt() && !in_softirq()) + time_travel_update_time(time_travel_time + + TIMER_MULTIPLIER, + false); return time_travel_time / TIMER_MULTIPLIER; } @@ -188,6 +670,8 @@ void read_persistent_clock64(struct timespec64 *ts) if (time_travel_start_set) nsecs = time_travel_start + time_travel_time; + else if (time_travel_mode == TT_MODE_EXTERNAL) + nsecs = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); else nsecs = os_persistent_clock_emulation(); @@ -204,7 +688,8 @@ void __init time_init(void) #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT unsigned long calibrate_delay_is_known(void) { - if (time_travel_mode == TT_MODE_INFCPU) + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) return 1; return 0; } @@ -218,6 +703,13 @@ int setup_time_travel(char *str) return 1; } + if (strncmp(str, "=ext:", 5) == 0) { + time_travel_mode = TT_MODE_EXTERNAL; + timer_clockevent.name = "time-travel-timer-external"; + timer_clocksource.name = "time-travel-clock-external"; + return time_travel_connect_external(str + 5); + } + if (!*str) { time_travel_mode = TT_MODE_BASIC; timer_clockevent.name = "time-travel-timer"; @@ -242,7 +734,15 @@ __uml_help(setup_time_travel, "are no wall clock timers, and any CPU processing happens - as seen from the\n" "guest - instantly. This can be useful for accurate simulation regardless of\n" "debug overhead, physical CPU speed, etc. but is somewhat dangerous as it can\n" -"easily lead to getting stuck (e.g. if anything in the system busy loops).\n"); +"easily lead to getting stuck (e.g. if anything in the system busy loops).\n" +"\n" +"time-travel=ext:[ID:]/path/to/socket\n" +"This enables time travel mode similar to =inf-cpu, except the system will\n" +"use the given socket to coordinate with a central scheduler, in order to\n" +"have more than one system simultaneously be on simulated time. The virtio\n" +"driver code in UML knows about this so you can also simulate networks and\n" +"devices using it, assuming the device has the right capabilities.\n" +"The optional ID is a 64-bit integer that's sent to the central scheduler.\n"); int setup_time_travel_start(char *str) { diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 9f21443be2c9..3b6dab3d4501 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -19,10 +19,10 @@ SECTIONS __binary_start = START; . = START + SIZEOF_HEADERS; + . = ALIGN(PAGE_SIZE); _text = .; INIT_TEXT_SECTION(0) - . = ALIGN(PAGE_SIZE); .text : { diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index fbda10535dab..26ecbd64c409 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -5,9 +5,11 @@ #include <stdio.h> #include <unistd.h> +#include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <signal.h> +#include <linux/falloc.h> #include <sys/ioctl.h> #include <sys/mount.h> #include <sys/socket.h> @@ -16,6 +18,7 @@ #include <sys/un.h> #include <sys/types.h> #include <sys/eventfd.h> +#include <poll.h> #include <os.h> static void copy_stat(struct uml_stat *dst, const struct stat64 *src) @@ -664,3 +667,31 @@ int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds, return -errno; return err; } + +int os_poll(unsigned int n, const int *fds) +{ + /* currently need 2 FDs at most so avoid dynamic allocation */ + struct pollfd pollfds[2] = {}; + unsigned int i; + int ret; + + if (n > ARRAY_SIZE(pollfds)) + return -EINVAL; + + for (i = 0; i < n; i++) { + pollfds[i].fd = fds[i]; + pollfds[i].events = POLLIN; + } + + ret = poll(pollfds, n, -1); + if (ret < 0) + return -errno; + + /* Return the index of the available FD */ + for (i = 0; i < n; i++) { + if (pollfds[i].revents) + return i; + } + + return -EIO; +} diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 432f8e1f55c2..90f6de224c70 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -14,7 +14,6 @@ #include <kern_util.h> #include <os.h> #include <string.h> -#include <timer-internal.h> static timer_t event_high_res_timer = 0; diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 44def53a11cd..9e16078a4bf8 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -220,11 +220,12 @@ static void __init create_pid_file(void) char pid[sizeof("nnnnn\0")], *file; int fd, n; - file = malloc(strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")); + n = strlen(uml_dir) + UMID_LEN + sizeof("/pid\0"); + file = malloc(n); if (!file) return; - if (umid_file_name("pid", file, sizeof(file))) + if (umid_file_name("pid", file, n)) goto out; fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); diff --git a/arch/unicore32/.gitignore b/arch/unicore32/.gitignore index 947e99c2a957..e82f3fb57ba0 100644 --- a/arch/unicore32/.gitignore +++ b/arch/unicore32/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Generated include files # diff --git a/arch/unicore32/include/asm/page.h b/arch/unicore32/include/asm/page.h index 8a89335673f9..96d6bdf180bd 100644 --- a/arch/unicore32/include/asm/page.h +++ b/arch/unicore32/include/asm/page.h @@ -69,9 +69,6 @@ extern int pfn_valid(unsigned long); #endif /* !__ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/getorder.h> #endif diff --git a/arch/unicore32/include/asm/pgtable.h b/arch/unicore32/include/asm/pgtable.h index c8f7ba12f309..3b8731b3a937 100644 --- a/arch/unicore32/include/asm/pgtable.h +++ b/arch/unicore32/include/asm/pgtable.h @@ -177,7 +177,6 @@ extern struct page *empty_zero_page; #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) #define pte_young(pte) (pte_val(pte) & PTE_YOUNG) #define pte_exec(pte) (pte_val(pte) & PTE_EXEC) -#define pte_special(pte) (0) #define PTE_BIT_FUNC(fn, op) \ static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } @@ -189,8 +188,6 @@ PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY); PTE_BIT_FUNC(mkold, &= ~PTE_YOUNG); PTE_BIT_FUNC(mkyoung, |= PTE_YOUNG); -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - /* * Mark the prot value as uncacheable. */ diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c index a3bf2ffc54dd..e251f5028396 100644 --- a/arch/unicore32/kernel/puv3-nb0916.c +++ b/arch/unicore32/kernel/puv3-nb0916.c @@ -55,7 +55,6 @@ static struct pwm_lookup nb0916_pwm_lookup[] = { static struct platform_pwm_backlight_data nb0916_backlight_data = { .max_brightness = 100, .dft_brightness = 100, - .enable_gpio = -1, }; static struct gpio_keys_button nb0916_gpio_keys[] = { diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index a9bd08fbe588..3022104aa613 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -149,7 +149,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) */ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) { - unsigned int mask = VM_READ | VM_WRITE | VM_EXEC; + unsigned int mask = VM_ACCESS_FLAGS; if (!(fsr ^ 0x12)) /* write? */ mask = VM_WRITE; diff --git a/arch/x86/.gitignore b/arch/x86/.gitignore index 5a82bac5e0bc..677111acbaa3 100644 --- a/arch/x86/.gitignore +++ b/arch/x86/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only boot/compressed/vmlinux tools/test_get_len tools/insn_sanity diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1edf788d301c..1d6104ea8af0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -149,6 +149,7 @@ config X86 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64 + select HAVE_ARCH_USERFAULTFD_WP if USERFAULTFD select HAVE_ARCH_VMAP_STACK if X86_64 select HAVE_ARCH_WITHIN_STACK_FRAMES select HAVE_ASM_MODVERSIONS @@ -1660,6 +1661,7 @@ config X86_PMEM_LEGACY depends on PHYS_ADDR_T_64BIT depends on BLK_DEV select X86_PMEM_LEGACY_DEVICE + select NUMA_KEEP_MEMINFO if NUMA select LIBNVDIMM help Treat memory marked using the non-standard e820 type of 12 as used @@ -2930,3 +2932,5 @@ config HAVE_ATOMIC_IOMAP source "drivers/firmware/Kconfig" source "arch/x86/kvm/Kconfig" + +source "arch/x86/Kconfig.assembler" diff --git a/arch/x86/Kconfig.assembler b/arch/x86/Kconfig.assembler new file mode 100644 index 000000000000..13de0db38d4e --- /dev/null +++ b/arch/x86/Kconfig.assembler @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + +config AS_AVX512 + def_bool $(as-instr,vpmovm2b %k1$(comma)%zmm5) + help + Supported by binutils >= 2.25 and LLVM integrated assembler + +config AS_SHA1_NI + def_bool $(as-instr,sha1msg1 %xmm0$(comma)%xmm1) + help + Supported by binutils >= 2.24 and LLVM integrated assembler + +config AS_SHA256_NI + def_bool $(as-instr,sha256msg1 %xmm0$(comma)%xmm1) + help + Supported by binutils >= 2.24 and LLVM integrated assembler diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 513a55562d75..b65ec63c7db7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -177,28 +177,6 @@ ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1) KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,) endif -# Stackpointer is addressed different for 32 bit and 64 bit x86 -sp-$(CONFIG_X86_32) := esp -sp-$(CONFIG_X86_64) := rsp - -# do binutils support CFI? -cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1) -# is .cfi_signal_frame supported too? -cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1) -cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1) - -# does binutils support specific instructions? -asinstr += $(call as-instr,pshufb %xmm0$(comma)%xmm0,-DCONFIG_AS_SSSE3=1) -avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1) -avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) -avx512_instr :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,-DCONFIG_AS_AVX512=1) -sha1_ni_instr :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA1_NI=1) -sha256_ni_instr :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA256_NI=1) -adx_instr := $(call as-instr,adox %r10$(comma)%r10,-DCONFIG_AS_ADX=1) - -KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr) -KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr) - KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE) # diff --git a/arch/x86/boot/.gitignore b/arch/x86/boot/.gitignore index 09d25dd09307..9cc7f1357b9b 100644 --- a/arch/x86/boot/.gitignore +++ b/arch/x86/boot/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only bootsect bzImage cpustr.h diff --git a/arch/x86/boot/compressed/.gitignore b/arch/x86/boot/compressed/.gitignore index 4a46fab7162e..25805199a506 100644 --- a/arch/x86/boot/compressed/.gitignore +++ b/arch/x86/boot/compressed/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only relocs vmlinux.bin.all vmlinux.relocs diff --git a/arch/x86/boot/tools/.gitignore b/arch/x86/boot/tools/.gitignore index 378eac25d311..ae91f4d0d78b 100644 --- a/arch/x86/boot/tools/.gitignore +++ b/arch/x86/boot/tools/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only build diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 5b602beb0b72..550904591e94 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -136,7 +136,6 @@ CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y @@ -286,7 +285,6 @@ CONFIG_EARLY_PRINTK_DBGP=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_DEBUG_BOOT_PARAMS=y -CONFIG_OPTIMIZE_INLINING=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index f3d1f36103b1..614961009075 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -134,7 +134,6 @@ CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y @@ -283,7 +282,6 @@ CONFIG_EARLY_PRINTK_DBGP=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_DEBUG_BOOT_PARAMS=y -CONFIG_OPTIMIZE_INLINING=y CONFIG_UNWINDER_ORC=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y diff --git a/arch/x86/crypto/.gitignore b/arch/x86/crypto/.gitignore index 30be0400a439..580c839bb177 100644 --- a/arch/x86/crypto/.gitignore +++ b/arch/x86/crypto/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only poly1305-x86_64-cryptogams.S diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 8c2e9eadee8a..a31de0c6ccde 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -1,131 +1,97 @@ # SPDX-License-Identifier: GPL-2.0 # -# Arch-specific CryptoAPI modules. -# +# x86 crypto algorithms OBJECT_FILES_NON_STANDARD := y -avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no) -avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ - $(comma)4)$(comma)%ymm2,yes,no) -avx512_supported :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,yes,no) -sha1_ni_supported :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,yes,no) -sha256_ni_supported :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,yes,no) -adx_supported := $(call as-instr,adox %r10$(comma)%r10,yes,no) - obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o +twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o +obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o +twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o +obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o +twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o +obj-$(CONFIG_CRYPTO_TWOFISH_AVX_X86_64) += twofish-avx-x86_64.o +twofish-avx-x86_64-y := twofish-avx-x86_64-asm_64.o twofish_avx_glue.o + obj-$(CONFIG_CRYPTO_SERPENT_SSE2_586) += serpent-sse2-i586.o +serpent-sse2-i586-y := serpent-sse2-i586-asm_32.o serpent_sse2_glue.o +obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o +serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o +obj-$(CONFIG_CRYPTO_SERPENT_AVX_X86_64) += serpent-avx-x86_64.o +serpent-avx-x86_64-y := serpent-avx-x86_64-asm_64.o serpent_avx_glue.o +obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o +serpent-avx2-y := serpent-avx2-asm_64.o serpent_avx2_glue.o obj-$(CONFIG_CRYPTO_DES3_EDE_X86_64) += des3_ede-x86_64.o +des3_ede-x86_64-y := des3_ede-asm_64.o des3_ede_glue.o + obj-$(CONFIG_CRYPTO_CAMELLIA_X86_64) += camellia-x86_64.o +camellia-x86_64-y := camellia-x86_64-asm_64.o camellia_glue.o +obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64) += camellia-aesni-avx-x86_64.o +camellia-aesni-avx-x86_64-y := camellia-aesni-avx-asm_64.o camellia_aesni_avx_glue.o +obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o +camellia-aesni-avx2-y := camellia-aesni-avx2-asm_64.o camellia_aesni_avx2_glue.o + obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o -obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o -obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o -obj-$(CONFIG_CRYPTO_CHACHA20_X86_64) += chacha-x86_64.o -obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o -obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o -obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o +blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o -obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o -obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o -obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o -obj-$(CONFIG_CRYPTO_SHA256_SSSE3) += sha256-ssse3.o -obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o -obj-$(CONFIG_CRYPTO_CRCT10DIF_PCLMUL) += crct10dif-pclmul.o -obj-$(CONFIG_CRYPTO_POLY1305_X86_64) += poly1305-x86_64.o +obj-$(CONFIG_CRYPTO_CAST5_AVX_X86_64) += cast5-avx-x86_64.o +cast5-avx-x86_64-y := cast5-avx-x86_64-asm_64.o cast5_avx_glue.o + +obj-$(CONFIG_CRYPTO_CAST6_AVX_X86_64) += cast6-avx-x86_64.o +cast6-avx-x86_64-y := cast6-avx-x86_64-asm_64.o cast6_avx_glue.o obj-$(CONFIG_CRYPTO_AEGIS128_AESNI_SSE2) += aegis128-aesni.o +aegis128-aesni-y := aegis128-aesni-asm.o aegis128-aesni-glue.o -obj-$(CONFIG_CRYPTO_NHPOLY1305_SSE2) += nhpoly1305-sse2.o -obj-$(CONFIG_CRYPTO_NHPOLY1305_AVX2) += nhpoly1305-avx2.o +obj-$(CONFIG_CRYPTO_CHACHA20_X86_64) += chacha-x86_64.o +chacha-x86_64-y := chacha-avx2-x86_64.o chacha-ssse3-x86_64.o chacha_glue.o +chacha-x86_64-$(CONFIG_AS_AVX512) += chacha-avx512vl-x86_64.o -# These modules require the assembler to support ADX. -ifeq ($(adx_supported),yes) - obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o -endif - -# These modules require assembler to support AVX. -ifeq ($(avx_supported),yes) - obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64) += \ - camellia-aesni-avx-x86_64.o - obj-$(CONFIG_CRYPTO_CAST5_AVX_X86_64) += cast5-avx-x86_64.o - obj-$(CONFIG_CRYPTO_CAST6_AVX_X86_64) += cast6-avx-x86_64.o - obj-$(CONFIG_CRYPTO_TWOFISH_AVX_X86_64) += twofish-avx-x86_64.o - obj-$(CONFIG_CRYPTO_SERPENT_AVX_X86_64) += serpent-avx-x86_64.o - obj-$(CONFIG_CRYPTO_BLAKE2S_X86) += blake2s-x86_64.o -endif - -# These modules require assembler to support AVX2. -ifeq ($(avx2_supported),yes) - obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o - obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o -endif +obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o +aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o +aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o aes_ctrby8_avx-x86_64.o -twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o -serpent-sse2-i586-y := serpent-sse2-i586-asm_32.o serpent_sse2_glue.o +obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o +sha1-ssse3-y := sha1_avx2_x86_64_asm.o sha1_ssse3_asm.o sha1_ssse3_glue.o +sha1-ssse3-$(CONFIG_AS_SHA1_NI) += sha1_ni_asm.o -des3_ede-x86_64-y := des3_ede-asm_64.o des3_ede_glue.o -camellia-x86_64-y := camellia-x86_64-asm_64.o camellia_glue.o -blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o -twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o -twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o -chacha-x86_64-y := chacha-ssse3-x86_64.o chacha_glue.o -serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o +obj-$(CONFIG_CRYPTO_SHA256_SSSE3) += sha256-ssse3.o +sha256-ssse3-y := sha256-ssse3-asm.o sha256-avx-asm.o sha256-avx2-asm.o sha256_ssse3_glue.o +sha256-ssse3-$(CONFIG_AS_SHA256_NI) += sha256_ni_asm.o -aegis128-aesni-y := aegis128-aesni-asm.o aegis128-aesni-glue.o +obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o +sha512-ssse3-y := sha512-ssse3-asm.o sha512-avx-asm.o sha512-avx2-asm.o sha512_ssse3_glue.o -nhpoly1305-sse2-y := nh-sse2-x86_64.o nhpoly1305-sse2-glue.o +obj-$(CONFIG_CRYPTO_BLAKE2S_X86) += blake2s-x86_64.o blake2s-x86_64-y := blake2s-core.o blake2s-glue.o -poly1305-x86_64-y := poly1305-x86_64-cryptogams.o poly1305_glue.o -ifneq ($(CONFIG_CRYPTO_POLY1305_X86_64),) -targets += poly1305-x86_64-cryptogams.S -endif - -ifeq ($(avx_supported),yes) - camellia-aesni-avx-x86_64-y := camellia-aesni-avx-asm_64.o \ - camellia_aesni_avx_glue.o - cast5-avx-x86_64-y := cast5-avx-x86_64-asm_64.o cast5_avx_glue.o - cast6-avx-x86_64-y := cast6-avx-x86_64-asm_64.o cast6_avx_glue.o - twofish-avx-x86_64-y := twofish-avx-x86_64-asm_64.o \ - twofish_avx_glue.o - serpent-avx-x86_64-y := serpent-avx-x86_64-asm_64.o \ - serpent_avx_glue.o -endif - -ifeq ($(avx2_supported),yes) - camellia-aesni-avx2-y := camellia-aesni-avx2-asm_64.o camellia_aesni_avx2_glue.o - chacha-x86_64-y += chacha-avx2-x86_64.o - serpent-avx2-y := serpent-avx2-asm_64.o serpent_avx2_glue.o - - nhpoly1305-avx2-y := nh-avx2-x86_64.o nhpoly1305-avx2-glue.o -endif - -ifeq ($(avx512_supported),yes) - chacha-x86_64-y += chacha-avx512vl-x86_64.o -endif -aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o -aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o aes_ctrby8_avx-x86_64.o +obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o -sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o -ifeq ($(avx2_supported),yes) -sha1-ssse3-y += sha1_avx2_x86_64_asm.o -endif -ifeq ($(sha1_ni_supported),yes) -sha1-ssse3-y += sha1_ni_asm.o -endif + +obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o crc32c-intel-y := crc32c-intel_glue.o crc32c-intel-$(CONFIG_64BIT) += crc32c-pcl-intel-asm_64.o + +obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o crc32-pclmul-y := crc32-pclmul_asm.o crc32-pclmul_glue.o -sha256-ssse3-y := sha256-ssse3-asm.o sha256-avx-asm.o sha256-avx2-asm.o sha256_ssse3_glue.o -ifeq ($(sha256_ni_supported),yes) -sha256-ssse3-y += sha256_ni_asm.o -endif -sha512-ssse3-y := sha512-ssse3-asm.o sha512-avx-asm.o sha512-avx2-asm.o sha512_ssse3_glue.o + +obj-$(CONFIG_CRYPTO_CRCT10DIF_PCLMUL) += crct10dif-pclmul.o crct10dif-pclmul-y := crct10dif-pcl-asm_64.o crct10dif-pclmul_glue.o +obj-$(CONFIG_CRYPTO_POLY1305_X86_64) += poly1305-x86_64.o +poly1305-x86_64-y := poly1305-x86_64-cryptogams.o poly1305_glue.o +targets += poly1305-x86_64-cryptogams.S + +obj-$(CONFIG_CRYPTO_NHPOLY1305_SSE2) += nhpoly1305-sse2.o +nhpoly1305-sse2-y := nh-sse2-x86_64.o nhpoly1305-sse2-glue.o +obj-$(CONFIG_CRYPTO_NHPOLY1305_AVX2) += nhpoly1305-avx2.o +nhpoly1305-avx2-y := nh-avx2-x86_64.o nhpoly1305-avx2-glue.o + +obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o + quiet_cmd_perlasm = PERLASM $@ cmd_perlasm = $(PERL) $< > $@ $(obj)/%.S: $(src)/%.pl FORCE diff --git a/arch/x86/crypto/aesni-intel_avx-x86_64.S b/arch/x86/crypto/aesni-intel_avx-x86_64.S index bfa1c0b3e5b4..0cea33295287 100644 --- a/arch/x86/crypto/aesni-intel_avx-x86_64.S +++ b/arch/x86/crypto/aesni-intel_avx-x86_64.S @@ -886,7 +886,6 @@ _less_than_8_bytes_left_\@: _partial_block_done_\@: .endm # PARTIAL_BLOCK -#ifdef CONFIG_AS_AVX ############################################################################### # GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) # Input: A and B (128-bits each, bit-reflected) @@ -1869,9 +1868,6 @@ key_256_finalize: ret SYM_FUNC_END(aesni_gcm_finalize_avx_gen2) -#endif /* CONFIG_AS_AVX */ - -#ifdef CONFIG_AS_AVX2 ############################################################################### # GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) # Input: A and B (128-bits each, bit-reflected) @@ -2839,5 +2835,3 @@ key_256_finalize4: FUNC_RESTORE ret SYM_FUNC_END(aesni_gcm_finalize_avx_gen4) - -#endif /* CONFIG_AS_AVX2 */ diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 75b6ea20491e..ad8a7188a2bf 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -185,7 +185,6 @@ static const struct aesni_gcm_tfm_s aesni_gcm_tfm_sse = { .finalize = &aesni_gcm_finalize, }; -#ifdef CONFIG_AS_AVX asmlinkage void aes_ctr_enc_128_avx_by8(const u8 *in, u8 *iv, void *keys, u8 *out, unsigned int num_bytes); asmlinkage void aes_ctr_enc_192_avx_by8(const u8 *in, u8 *iv, @@ -234,9 +233,6 @@ static const struct aesni_gcm_tfm_s aesni_gcm_tfm_avx_gen2 = { .finalize = &aesni_gcm_finalize_avx_gen2, }; -#endif - -#ifdef CONFIG_AS_AVX2 /* * asmlinkage void aesni_gcm_init_avx_gen4() * gcm_data *my_ctx_data, context data @@ -279,8 +275,6 @@ static const struct aesni_gcm_tfm_s aesni_gcm_tfm_avx_gen4 = { .finalize = &aesni_gcm_finalize_avx_gen4, }; -#endif - static inline struct aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm) { @@ -476,7 +470,6 @@ static void ctr_crypt_final(struct crypto_aes_ctx *ctx, crypto_inc(ctrblk, AES_BLOCK_SIZE); } -#ifdef CONFIG_AS_AVX static void aesni_ctr_enc_avx_tfm(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv) { @@ -493,7 +486,6 @@ static void aesni_ctr_enc_avx_tfm(struct crypto_aes_ctx *ctx, u8 *out, else aes_ctr_enc_256_avx_by8(in, iv, (void *)ctx, out, len); } -#endif static int ctr_crypt(struct skcipher_request *req) { @@ -711,14 +703,10 @@ static int gcmaes_crypt_by_sg(bool enc, struct aead_request *req, if (!enc) left -= auth_tag_len; -#ifdef CONFIG_AS_AVX2 if (left < AVX_GEN4_OPTSIZE && gcm_tfm == &aesni_gcm_tfm_avx_gen4) gcm_tfm = &aesni_gcm_tfm_avx_gen2; -#endif -#ifdef CONFIG_AS_AVX if (left < AVX_GEN2_OPTSIZE && gcm_tfm == &aesni_gcm_tfm_avx_gen2) gcm_tfm = &aesni_gcm_tfm_sse; -#endif /* Linearize assoc, if not already linear */ if (req->src->length >= assoclen && req->src->length && @@ -1076,31 +1064,24 @@ static int __init aesni_init(void) if (!x86_match_cpu(aesni_cpu_id)) return -ENODEV; #ifdef CONFIG_X86_64 -#ifdef CONFIG_AS_AVX2 if (boot_cpu_has(X86_FEATURE_AVX2)) { pr_info("AVX2 version of gcm_enc/dec engaged.\n"); aesni_gcm_tfm = &aesni_gcm_tfm_avx_gen4; } else -#endif -#ifdef CONFIG_AS_AVX if (boot_cpu_has(X86_FEATURE_AVX)) { pr_info("AVX version of gcm_enc/dec engaged.\n"); aesni_gcm_tfm = &aesni_gcm_tfm_avx_gen2; - } else -#endif - { + } else { pr_info("SSE version of gcm_enc/dec engaged.\n"); aesni_gcm_tfm = &aesni_gcm_tfm_sse; } aesni_ctr_enc_tfm = aesni_ctr_enc; -#ifdef CONFIG_AS_AVX if (boot_cpu_has(X86_FEATURE_AVX)) { /* optimize performance of ctr mode encryption transform */ aesni_ctr_enc_tfm = aesni_ctr_enc_avx_tfm; pr_info("AES CTR mode by8 optimization enabled\n"); } #endif -#endif err = crypto_register_alg(&aesni_cipher_alg); if (err) diff --git a/arch/x86/crypto/blake2s-core.S b/arch/x86/crypto/blake2s-core.S index 24910b766bdd..2ca79974f819 100644 --- a/arch/x86/crypto/blake2s-core.S +++ b/arch/x86/crypto/blake2s-core.S @@ -46,7 +46,6 @@ SIGMA2: #endif /* CONFIG_AS_AVX512 */ .text -#ifdef CONFIG_AS_SSSE3 SYM_FUNC_START(blake2s_compress_ssse3) testq %rdx,%rdx je .Lendofloop @@ -174,7 +173,6 @@ SYM_FUNC_START(blake2s_compress_ssse3) .Lendofloop: ret SYM_FUNC_END(blake2s_compress_ssse3) -#endif /* CONFIG_AS_SSSE3 */ #ifdef CONFIG_AS_AVX512 SYM_FUNC_START(blake2s_compress_avx512) diff --git a/arch/x86/crypto/chacha_glue.c b/arch/x86/crypto/chacha_glue.c index 68a74953efaf..b412c21ee06e 100644 --- a/arch/x86/crypto/chacha_glue.c +++ b/arch/x86/crypto/chacha_glue.c @@ -79,8 +79,7 @@ static void chacha_dosimd(u32 *state, u8 *dst, const u8 *src, } } - if (IS_ENABLED(CONFIG_AS_AVX2) && - static_branch_likely(&chacha_use_avx2)) { + if (static_branch_likely(&chacha_use_avx2)) { while (bytes >= CHACHA_BLOCK_SIZE * 8) { chacha_8block_xor_avx2(state, dst, src, bytes, nrounds); bytes -= CHACHA_BLOCK_SIZE * 8; @@ -288,8 +287,7 @@ static int __init chacha_simd_mod_init(void) static_branch_enable(&chacha_use_simd); - if (IS_ENABLED(CONFIG_AS_AVX2) && - boot_cpu_has(X86_FEATURE_AVX) && + if (boot_cpu_has(X86_FEATURE_AVX) && boot_cpu_has(X86_FEATURE_AVX2) && cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) { static_branch_enable(&chacha_use_avx2); diff --git a/arch/x86/crypto/poly1305-x86_64-cryptogams.pl b/arch/x86/crypto/poly1305-x86_64-cryptogams.pl index 7a6b5380a46f..137edcf038cb 100644 --- a/arch/x86/crypto/poly1305-x86_64-cryptogams.pl +++ b/arch/x86/crypto/poly1305-x86_64-cryptogams.pl @@ -404,10 +404,6 @@ ___ &end_function("poly1305_emit_x86_64"); if ($avx) { -if($kernel) { - $code .= "#ifdef CONFIG_AS_AVX\n"; -} - ######################################################################## # Layout of opaque area is following. # @@ -1516,16 +1512,8 @@ $code.=<<___; ___ &end_function("poly1305_emit_avx"); -if ($kernel) { - $code .= "#endif\n"; -} - if ($avx>1) { -if ($kernel) { - $code .= "#ifdef CONFIG_AS_AVX2\n"; -} - my ($H0,$H1,$H2,$H3,$H4, $MASK, $T4,$T0,$T1,$T2,$T3, $D0,$D1,$D2,$D3,$D4) = map("%ymm$_",(0..15)); my $S4=$MASK; @@ -2816,10 +2804,6 @@ ___ poly1305_blocks_avxN(0); &end_function("poly1305_blocks_avx2"); -if($kernel) { - $code .= "#endif\n"; -} - ####################################################################### if ($avx>2) { # On entry we have input length divisible by 64. But since inner loop diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c index 79bb58737d52..6dfec19f7d57 100644 --- a/arch/x86/crypto/poly1305_glue.c +++ b/arch/x86/crypto/poly1305_glue.c @@ -94,7 +94,7 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, BUILD_BUG_ON(PAGE_SIZE < POLY1305_BLOCK_SIZE || PAGE_SIZE % POLY1305_BLOCK_SIZE); - if (!IS_ENABLED(CONFIG_AS_AVX) || !static_branch_likely(&poly1305_use_avx) || + if (!static_branch_likely(&poly1305_use_avx) || (len < (POLY1305_BLOCK_SIZE * 18) && !state->is_base2_26) || !crypto_simd_usable()) { convert_to_base2_64(ctx); @@ -108,7 +108,7 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, kernel_fpu_begin(); if (IS_ENABLED(CONFIG_AS_AVX512) && static_branch_likely(&poly1305_use_avx512)) poly1305_blocks_avx512(ctx, inp, bytes, padbit); - else if (IS_ENABLED(CONFIG_AS_AVX2) && static_branch_likely(&poly1305_use_avx2)) + else if (static_branch_likely(&poly1305_use_avx2)) poly1305_blocks_avx2(ctx, inp, bytes, padbit); else poly1305_blocks_avx(ctx, inp, bytes, padbit); @@ -123,7 +123,7 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, static void poly1305_simd_emit(void *ctx, u8 mac[POLY1305_DIGEST_SIZE], const u32 nonce[4]) { - if (!IS_ENABLED(CONFIG_AS_AVX) || !static_branch_likely(&poly1305_use_avx)) + if (!static_branch_likely(&poly1305_use_avx)) poly1305_emit_x86_64(ctx, mac, nonce); else poly1305_emit_avx(ctx, mac, nonce); @@ -261,11 +261,10 @@ static struct shash_alg alg = { static int __init poly1305_simd_mod_init(void) { - if (IS_ENABLED(CONFIG_AS_AVX) && boot_cpu_has(X86_FEATURE_AVX) && + if (boot_cpu_has(X86_FEATURE_AVX) && cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) static_branch_enable(&poly1305_use_avx); - if (IS_ENABLED(CONFIG_AS_AVX2) && boot_cpu_has(X86_FEATURE_AVX) && - boot_cpu_has(X86_FEATURE_AVX2) && + if (boot_cpu_has(X86_FEATURE_AVX) && boot_cpu_has(X86_FEATURE_AVX2) && cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) static_branch_enable(&poly1305_use_avx2); if (IS_ENABLED(CONFIG_AS_AVX512) && boot_cpu_has(X86_FEATURE_AVX) && diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S index 12e2d19d7402..d25668d2a1e9 100644 --- a/arch/x86/crypto/sha1_ssse3_asm.S +++ b/arch/x86/crypto/sha1_ssse3_asm.S @@ -467,8 +467,6 @@ W_PRECALC_SSSE3 */ SHA1_VECTOR_ASM sha1_transform_ssse3 -#ifdef CONFIG_AS_AVX - .macro W_PRECALC_AVX .purgem W_PRECALC_00_15 @@ -553,5 +551,3 @@ W_PRECALC_AVX * const u8 *data, int blocks); */ SHA1_VECTOR_ASM sha1_transform_avx - -#endif diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c index d70b40ad594c..a801ffc10cbb 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c @@ -114,7 +114,6 @@ static void unregister_sha1_ssse3(void) crypto_unregister_shash(&sha1_ssse3_alg); } -#ifdef CONFIG_AS_AVX asmlinkage void sha1_transform_avx(struct sha1_state *state, const u8 *data, int blocks); @@ -175,13 +174,6 @@ static void unregister_sha1_avx(void) crypto_unregister_shash(&sha1_avx_alg); } -#else /* CONFIG_AS_AVX */ -static inline int register_sha1_avx(void) { return 0; } -static inline void unregister_sha1_avx(void) { } -#endif /* CONFIG_AS_AVX */ - - -#if defined(CONFIG_AS_AVX2) && (CONFIG_AS_AVX) #define SHA1_AVX2_BLOCK_OPTSIZE 4 /* optimal 4*64 bytes of SHA1 blocks */ asmlinkage void sha1_transform_avx2(struct sha1_state *state, @@ -253,11 +245,6 @@ static void unregister_sha1_avx2(void) crypto_unregister_shash(&sha1_avx2_alg); } -#else -static inline int register_sha1_avx2(void) { return 0; } -static inline void unregister_sha1_avx2(void) { } -#endif - #ifdef CONFIG_AS_SHA1_NI asmlinkage void sha1_ni_transform(struct sha1_state *digest, const u8 *data, int rounds); diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S index fcbc30f58c38..4739cd31b9db 100644 --- a/arch/x86/crypto/sha256-avx-asm.S +++ b/arch/x86/crypto/sha256-avx-asm.S @@ -47,7 +47,6 @@ # This code schedules 1 block at a time, with 4 lanes per block ######################################################################## -#ifdef CONFIG_AS_AVX #include <linux/linkage.h> ## assume buffers not aligned @@ -498,5 +497,3 @@ _SHUF_00BA: # shuffle xDxC -> DC00 _SHUF_DC00: .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF - -#endif diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S index 499d9ec129de..11ff60c29c8b 100644 --- a/arch/x86/crypto/sha256-avx2-asm.S +++ b/arch/x86/crypto/sha256-avx2-asm.S @@ -48,7 +48,6 @@ # This code schedules 2 blocks at a time, with 4 lanes per block ######################################################################## -#ifdef CONFIG_AS_AVX2 #include <linux/linkage.h> ## assume buffers not aligned @@ -767,5 +766,3 @@ _SHUF_00BA: .align 32 _SHUF_DC00: .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF,0x0b0a090803020100FFFFFFFFFFFFFFFF - -#endif diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c index 03ad657c04bd..6394b5fe8db6 100644 --- a/arch/x86/crypto/sha256_ssse3_glue.c +++ b/arch/x86/crypto/sha256_ssse3_glue.c @@ -144,7 +144,6 @@ static void unregister_sha256_ssse3(void) ARRAY_SIZE(sha256_ssse3_algs)); } -#ifdef CONFIG_AS_AVX asmlinkage void sha256_transform_avx(struct sha256_state *state, const u8 *data, int blocks); @@ -221,12 +220,6 @@ static void unregister_sha256_avx(void) ARRAY_SIZE(sha256_avx_algs)); } -#else -static inline int register_sha256_avx(void) { return 0; } -static inline void unregister_sha256_avx(void) { } -#endif - -#if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX) asmlinkage void sha256_transform_rorx(struct sha256_state *state, const u8 *data, int blocks); @@ -301,11 +294,6 @@ static void unregister_sha256_avx2(void) ARRAY_SIZE(sha256_avx2_algs)); } -#else -static inline int register_sha256_avx2(void) { return 0; } -static inline void unregister_sha256_avx2(void) { } -#endif - #ifdef CONFIG_AS_SHA256_NI asmlinkage void sha256_ni_transform(struct sha256_state *digest, const u8 *data, int rounds); diff --git a/arch/x86/crypto/sha512-avx-asm.S b/arch/x86/crypto/sha512-avx-asm.S index 90ea945ba5e6..63470fd6ae32 100644 --- a/arch/x86/crypto/sha512-avx-asm.S +++ b/arch/x86/crypto/sha512-avx-asm.S @@ -47,7 +47,6 @@ # ######################################################################## -#ifdef CONFIG_AS_AVX #include <linux/linkage.h> .text @@ -424,4 +423,3 @@ K512: .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 -#endif diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S index 3dd886b14e7d..3a44bdcfd583 100644 --- a/arch/x86/crypto/sha512-avx2-asm.S +++ b/arch/x86/crypto/sha512-avx2-asm.S @@ -49,7 +49,6 @@ # This code schedules 1 blocks at a time, with 4 lanes per block ######################################################################## -#ifdef CONFIG_AS_AVX2 #include <linux/linkage.h> .text @@ -749,5 +748,3 @@ PSHUFFLE_BYTE_FLIP_MASK: MASK_YMM_LO: .octa 0x00000000000000000000000000000000 .octa 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - -#endif diff --git a/arch/x86/crypto/sha512_ssse3_glue.c b/arch/x86/crypto/sha512_ssse3_glue.c index 1c444f41037c..82cc1b3ced1d 100644 --- a/arch/x86/crypto/sha512_ssse3_glue.c +++ b/arch/x86/crypto/sha512_ssse3_glue.c @@ -142,7 +142,6 @@ static void unregister_sha512_ssse3(void) ARRAY_SIZE(sha512_ssse3_algs)); } -#ifdef CONFIG_AS_AVX asmlinkage void sha512_transform_avx(struct sha512_state *state, const u8 *data, int blocks); static bool avx_usable(void) @@ -218,12 +217,7 @@ static void unregister_sha512_avx(void) crypto_unregister_shashes(sha512_avx_algs, ARRAY_SIZE(sha512_avx_algs)); } -#else -static inline int register_sha512_avx(void) { return 0; } -static inline void unregister_sha512_avx(void) { } -#endif -#if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX) asmlinkage void sha512_transform_rorx(struct sha512_state *state, const u8 *data, int blocks); @@ -298,10 +292,6 @@ static void unregister_sha512_avx2(void) crypto_unregister_shashes(sha512_avx2_algs, ARRAY_SIZE(sha512_avx2_algs)); } -#else -static inline int register_sha512_avx2(void) { return 0; } -static inline void unregister_sha512_avx2(void) { } -#endif static int __init sha512_ssse3_mod_init(void) { diff --git a/arch/x86/entry/vdso/.gitignore b/arch/x86/entry/vdso/.gitignore index aae8ffdd5880..37a6129d597b 100644 --- a/arch/x86/entry/vdso/.gitignore +++ b/arch/x86/entry/vdso/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds vdsox32.lds vdso32-syscall-syms.lds diff --git a/arch/x86/entry/vdso/vdso32/.gitignore b/arch/x86/entry/vdso/vdso32/.gitignore index e45fba9d0ced..5167384843b9 100644 --- a/arch/x86/entry/vdso/vdso32/.gitignore +++ b/arch/x86/entry/vdso/vdso32/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso32.lds diff --git a/arch/x86/entry/vdso/vdso32/vclock_gettime.c b/arch/x86/entry/vdso/vdso32/vclock_gettime.c index 1e82bd43286c..84a4a73f77f7 100644 --- a/arch/x86/entry/vdso/vdso32/vclock_gettime.c +++ b/arch/x86/entry/vdso/vdso32/vclock_gettime.c @@ -1,10 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #define BUILD_VDSO32 -#ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE -#undef CONFIG_OPTIMIZE_INLINING -#endif - #ifdef CONFIG_X86_64 /* diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 1ba72c563313..cf76d6631afa 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1476,6 +1476,12 @@ static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = { .mmio_init = tgl_l_uncore_mmio_init, }; +static const struct intel_uncore_init_fun icx_uncore_init __initconst = { + .cpu_init = icx_uncore_cpu_init, + .pci_init = icx_uncore_pci_init, + .mmio_init = icx_uncore_mmio_init, +}; + static const struct intel_uncore_init_fun snr_uncore_init __initconst = { .cpu_init = snr_uncore_cpu_init, .pci_init = snr_uncore_pci_init, @@ -1511,6 +1517,8 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_uncore_init), X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, &icl_uncore_init), X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, &icl_uncore_init), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &icx_uncore_init), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &icx_uncore_init), X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_l_uncore_init), X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_uncore_init), X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init), diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index b30429f8a53a..0da4a4605536 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -550,6 +550,9 @@ void skx_uncore_cpu_init(void); int snr_uncore_pci_init(void); void snr_uncore_cpu_init(void); void snr_uncore_mmio_init(void); +int icx_uncore_pci_init(void); +void icx_uncore_cpu_init(void); +void icx_uncore_mmio_init(void); /* uncore_nhmex.c */ void nhmex_uncore_cpu_init(void); diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 01023f0d935b..07652fa20ebb 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -382,6 +382,42 @@ #define SNR_IMC_MMIO_MEM0_OFFSET 0xd8 #define SNR_IMC_MMIO_MEM0_MASK 0x7FF +/* ICX CHA */ +#define ICX_C34_MSR_PMON_CTR0 0xb68 +#define ICX_C34_MSR_PMON_CTL0 0xb61 +#define ICX_C34_MSR_PMON_BOX_CTL 0xb60 +#define ICX_C34_MSR_PMON_BOX_FILTER0 0xb65 + +/* ICX IIO */ +#define ICX_IIO_MSR_PMON_CTL0 0xa58 +#define ICX_IIO_MSR_PMON_CTR0 0xa51 +#define ICX_IIO_MSR_PMON_BOX_CTL 0xa50 + +/* ICX IRP */ +#define ICX_IRP0_MSR_PMON_CTL0 0xa4d +#define ICX_IRP0_MSR_PMON_CTR0 0xa4b +#define ICX_IRP0_MSR_PMON_BOX_CTL 0xa4a + +/* ICX M2PCIE */ +#define ICX_M2PCIE_MSR_PMON_CTL0 0xa46 +#define ICX_M2PCIE_MSR_PMON_CTR0 0xa41 +#define ICX_M2PCIE_MSR_PMON_BOX_CTL 0xa40 + +/* ICX UPI */ +#define ICX_UPI_PCI_PMON_CTL0 0x350 +#define ICX_UPI_PCI_PMON_CTR0 0x320 +#define ICX_UPI_PCI_PMON_BOX_CTL 0x318 +#define ICX_UPI_CTL_UMASK_EXT 0xffffff + +/* ICX M3UPI*/ +#define ICX_M3UPI_PCI_PMON_CTL0 0xd8 +#define ICX_M3UPI_PCI_PMON_CTR0 0xa8 +#define ICX_M3UPI_PCI_PMON_BOX_CTL 0xa0 + +/* ICX IMC */ +#define ICX_NUMBER_IMC_CHN 2 +#define ICX_IMC_MEM_STRIDE 0x4 + DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6"); DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); @@ -390,6 +426,7 @@ DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55"); DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57"); DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39"); +DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55"); DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16"); DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); @@ -4551,3 +4588,477 @@ void snr_uncore_mmio_init(void) } /* end of SNR uncore support */ + +/* ICX uncore support */ + +static unsigned icx_cha_msr_offsets[] = { + 0x2a0, 0x2ae, 0x2bc, 0x2ca, 0x2d8, 0x2e6, 0x2f4, 0x302, 0x310, + 0x31e, 0x32c, 0x33a, 0x348, 0x356, 0x364, 0x372, 0x380, 0x38e, + 0x3aa, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f0, 0x3fe, 0x40c, 0x41a, + 0x428, 0x436, 0x444, 0x452, 0x460, 0x46e, 0x47c, 0x0, 0xe, + 0x1c, 0x2a, 0x38, 0x46, +}; + +static int icx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + bool tie_en = !!(event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN); + + if (tie_en) { + reg1->reg = ICX_C34_MSR_PMON_BOX_FILTER0 + + icx_cha_msr_offsets[box->pmu->pmu_idx]; + reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID; + reg1->idx = 0; + } + + return 0; +} + +static struct intel_uncore_ops icx_uncore_chabox_ops = { + .init_box = ivbep_uncore_msr_init_box, + .disable_box = snbep_uncore_msr_disable_box, + .enable_box = snbep_uncore_msr_enable_box, + .disable_event = snbep_uncore_msr_disable_event, + .enable_event = snr_cha_enable_event, + .read_counter = uncore_msr_read_counter, + .hw_config = icx_cha_hw_config, +}; + +static struct intel_uncore_type icx_uncore_chabox = { + .name = "cha", + .num_counters = 4, + .perf_ctr_bits = 48, + .event_ctl = ICX_C34_MSR_PMON_CTL0, + .perf_ctr = ICX_C34_MSR_PMON_CTR0, + .box_ctl = ICX_C34_MSR_PMON_BOX_CTL, + .msr_offsets = icx_cha_msr_offsets, + .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, + .event_mask_ext = SNR_CHA_RAW_EVENT_MASK_EXT, + .constraints = skx_uncore_chabox_constraints, + .ops = &icx_uncore_chabox_ops, + .format_group = &snr_uncore_chabox_format_group, +}; + +static unsigned icx_msr_offsets[] = { + 0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0, +}; + +static struct event_constraint icx_uncore_iio_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x02, 0x3), + UNCORE_EVENT_CONSTRAINT(0x03, 0x3), + UNCORE_EVENT_CONSTRAINT(0x83, 0x3), + UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), + UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type icx_uncore_iio = { + .name = "iio", + .num_counters = 4, + .num_boxes = 6, + .perf_ctr_bits = 48, + .event_ctl = ICX_IIO_MSR_PMON_CTL0, + .perf_ctr = ICX_IIO_MSR_PMON_CTR0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, + .box_ctl = ICX_IIO_MSR_PMON_BOX_CTL, + .msr_offsets = icx_msr_offsets, + .constraints = icx_uncore_iio_constraints, + .ops = &skx_uncore_iio_ops, + .format_group = &snr_uncore_iio_format_group, +}; + +static struct intel_uncore_type icx_uncore_irp = { + .name = "irp", + .num_counters = 2, + .num_boxes = 6, + .perf_ctr_bits = 48, + .event_ctl = ICX_IRP0_MSR_PMON_CTL0, + .perf_ctr = ICX_IRP0_MSR_PMON_CTR0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .box_ctl = ICX_IRP0_MSR_PMON_BOX_CTL, + .msr_offsets = icx_msr_offsets, + .ops = &ivbep_uncore_msr_ops, + .format_group = &ivbep_uncore_format_group, +}; + +static struct event_constraint icx_uncore_m2pcie_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x14, 0x3), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type icx_uncore_m2pcie = { + .name = "m2pcie", + .num_counters = 4, + .num_boxes = 6, + .perf_ctr_bits = 48, + .event_ctl = ICX_M2PCIE_MSR_PMON_CTL0, + .perf_ctr = ICX_M2PCIE_MSR_PMON_CTR0, + .box_ctl = ICX_M2PCIE_MSR_PMON_BOX_CTL, + .msr_offsets = icx_msr_offsets, + .constraints = icx_uncore_m2pcie_constraints, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .ops = &ivbep_uncore_msr_ops, + .format_group = &ivbep_uncore_format_group, +}; + +enum perf_uncore_icx_iio_freerunning_type_id { + ICX_IIO_MSR_IOCLK, + ICX_IIO_MSR_BW_IN, + + ICX_IIO_FREERUNNING_TYPE_MAX, +}; + +static unsigned icx_iio_clk_freerunning_box_offsets[] = { + 0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0, +}; + +static unsigned icx_iio_bw_freerunning_box_offsets[] = { + 0x0, 0x10, 0x20, 0x90, 0xa0, 0xb0, +}; + +static struct freerunning_counters icx_iio_freerunning[] = { + [ICX_IIO_MSR_IOCLK] = { 0xa55, 0x1, 0x20, 1, 48, icx_iio_clk_freerunning_box_offsets }, + [ICX_IIO_MSR_BW_IN] = { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets }, +}; + +static struct uncore_event_desc icx_uncore_iio_freerunning_events[] = { + /* Free-Running IIO CLOCKS Counter */ + INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), + /* Free-Running IIO BANDWIDTH IN Counters */ + INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), + INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"), + INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"), + INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"), + INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"), + INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_type icx_uncore_iio_free_running = { + .name = "iio_free_running", + .num_counters = 9, + .num_boxes = 6, + .num_freerunning_types = ICX_IIO_FREERUNNING_TYPE_MAX, + .freerunning = icx_iio_freerunning, + .ops = &skx_uncore_iio_freerunning_ops, + .event_descs = icx_uncore_iio_freerunning_events, + .format_group = &skx_uncore_iio_freerunning_format_group, +}; + +static struct intel_uncore_type *icx_msr_uncores[] = { + &skx_uncore_ubox, + &icx_uncore_chabox, + &icx_uncore_iio, + &icx_uncore_irp, + &icx_uncore_m2pcie, + &skx_uncore_pcu, + &icx_uncore_iio_free_running, + NULL, +}; + +/* + * To determine the number of CHAs, it should read CAPID6(Low) and CAPID7 (High) + * registers which located at Device 30, Function 3 + */ +#define ICX_CAPID6 0x9c +#define ICX_CAPID7 0xa0 + +static u64 icx_count_chabox(void) +{ + struct pci_dev *dev = NULL; + u64 caps = 0; + + dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x345b, dev); + if (!dev) + goto out; + + pci_read_config_dword(dev, ICX_CAPID6, (u32 *)&caps); + pci_read_config_dword(dev, ICX_CAPID7, (u32 *)&caps + 1); +out: + pci_dev_put(dev); + return hweight64(caps); +} + +void icx_uncore_cpu_init(void) +{ + u64 num_boxes = icx_count_chabox(); + + if (WARN_ON(num_boxes > ARRAY_SIZE(icx_cha_msr_offsets))) + return; + icx_uncore_chabox.num_boxes = num_boxes; + uncore_msr_uncores = icx_msr_uncores; +} + +static struct intel_uncore_type icx_uncore_m2m = { + .name = "m2m", + .num_counters = 4, + .num_boxes = 4, + .perf_ctr_bits = 48, + .perf_ctr = SNR_M2M_PCI_PMON_CTR0, + .event_ctl = SNR_M2M_PCI_PMON_CTL0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .box_ctl = SNR_M2M_PCI_PMON_BOX_CTL, + .ops = &snr_m2m_uncore_pci_ops, + .format_group = &skx_uncore_format_group, +}; + +static struct attribute *icx_upi_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask_ext4.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + NULL, +}; + +static const struct attribute_group icx_upi_uncore_format_group = { + .name = "format", + .attrs = icx_upi_uncore_formats_attr, +}; + +static struct intel_uncore_type icx_uncore_upi = { + .name = "upi", + .num_counters = 4, + .num_boxes = 3, + .perf_ctr_bits = 48, + .perf_ctr = ICX_UPI_PCI_PMON_CTR0, + .event_ctl = ICX_UPI_PCI_PMON_CTL0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .event_mask_ext = ICX_UPI_CTL_UMASK_EXT, + .box_ctl = ICX_UPI_PCI_PMON_BOX_CTL, + .ops = &skx_upi_uncore_pci_ops, + .format_group = &icx_upi_uncore_format_group, +}; + +static struct event_constraint icx_uncore_m3upi_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x1c, 0x1), + UNCORE_EVENT_CONSTRAINT(0x1d, 0x1), + UNCORE_EVENT_CONSTRAINT(0x1e, 0x1), + UNCORE_EVENT_CONSTRAINT(0x1f, 0x1), + UNCORE_EVENT_CONSTRAINT(0x40, 0x7), + UNCORE_EVENT_CONSTRAINT(0x4e, 0x7), + UNCORE_EVENT_CONSTRAINT(0x4f, 0x7), + UNCORE_EVENT_CONSTRAINT(0x50, 0x7), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type icx_uncore_m3upi = { + .name = "m3upi", + .num_counters = 4, + .num_boxes = 3, + .perf_ctr_bits = 48, + .perf_ctr = ICX_M3UPI_PCI_PMON_CTR0, + .event_ctl = ICX_M3UPI_PCI_PMON_CTL0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .box_ctl = ICX_M3UPI_PCI_PMON_BOX_CTL, + .constraints = icx_uncore_m3upi_constraints, + .ops = &ivbep_uncore_pci_ops, + .format_group = &skx_uncore_format_group, +}; + +enum { + ICX_PCI_UNCORE_M2M, + ICX_PCI_UNCORE_UPI, + ICX_PCI_UNCORE_M3UPI, +}; + +static struct intel_uncore_type *icx_pci_uncores[] = { + [ICX_PCI_UNCORE_M2M] = &icx_uncore_m2m, + [ICX_PCI_UNCORE_UPI] = &icx_uncore_upi, + [ICX_PCI_UNCORE_M3UPI] = &icx_uncore_m3upi, + NULL, +}; + +static const struct pci_device_id icx_uncore_pci_ids[] = { + { /* M2M 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, ICX_PCI_UNCORE_M2M, 0), + }, + { /* M2M 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 0, ICX_PCI_UNCORE_M2M, 1), + }, + { /* M2M 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, ICX_PCI_UNCORE_M2M, 2), + }, + { /* M2M 3 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, ICX_PCI_UNCORE_M2M, 3), + }, + { /* UPI Link 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(2, 1, ICX_PCI_UNCORE_UPI, 0), + }, + { /* UPI Link 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(3, 1, ICX_PCI_UNCORE_UPI, 1), + }, + { /* UPI Link 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 1, ICX_PCI_UNCORE_UPI, 2), + }, + { /* M3UPI Link 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(5, 1, ICX_PCI_UNCORE_M3UPI, 0), + }, + { /* M3UPI Link 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(6, 1, ICX_PCI_UNCORE_M3UPI, 1), + }, + { /* M3UPI Link 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(7, 1, ICX_PCI_UNCORE_M3UPI, 2), + }, + { /* end: all zeroes */ } +}; + +static struct pci_driver icx_uncore_pci_driver = { + .name = "icx_uncore", + .id_table = icx_uncore_pci_ids, +}; + +int icx_uncore_pci_init(void) +{ + /* ICX UBOX DID */ + int ret = snbep_pci2phy_map_init(0x3450, SKX_CPUNODEID, + SKX_GIDNIDMAP, true); + + if (ret) + return ret; + + uncore_pci_uncores = icx_pci_uncores; + uncore_pci_driver = &icx_uncore_pci_driver; + return 0; +} + +static void icx_uncore_imc_init_box(struct intel_uncore_box *box) +{ + unsigned int box_ctl = box->pmu->type->box_ctl + + box->pmu->type->mmio_offset * (box->pmu->pmu_idx % ICX_NUMBER_IMC_CHN); + int mem_offset = (box->pmu->pmu_idx / ICX_NUMBER_IMC_CHN) * ICX_IMC_MEM_STRIDE + + SNR_IMC_MMIO_MEM0_OFFSET; + + __snr_uncore_mmio_init_box(box, box_ctl, mem_offset); +} + +static struct intel_uncore_ops icx_uncore_mmio_ops = { + .init_box = icx_uncore_imc_init_box, + .exit_box = uncore_mmio_exit_box, + .disable_box = snr_uncore_mmio_disable_box, + .enable_box = snr_uncore_mmio_enable_box, + .disable_event = snr_uncore_mmio_disable_event, + .enable_event = snr_uncore_mmio_enable_event, + .read_counter = uncore_mmio_read_counter, +}; + +static struct intel_uncore_type icx_uncore_imc = { + .name = "imc", + .num_counters = 4, + .num_boxes = 8, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR, + .fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL, + .event_descs = hswep_uncore_imc_events, + .perf_ctr = SNR_IMC_MMIO_PMON_CTR0, + .event_ctl = SNR_IMC_MMIO_PMON_CTL0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .box_ctl = SNR_IMC_MMIO_PMON_BOX_CTL, + .mmio_offset = SNR_IMC_MMIO_OFFSET, + .ops = &icx_uncore_mmio_ops, + .format_group = &skx_uncore_format_group, +}; + +enum perf_uncore_icx_imc_freerunning_type_id { + ICX_IMC_DCLK, + ICX_IMC_DDR, + ICX_IMC_DDRT, + + ICX_IMC_FREERUNNING_TYPE_MAX, +}; + +static struct freerunning_counters icx_imc_freerunning[] = { + [ICX_IMC_DCLK] = { 0x22b0, 0x0, 0, 1, 48 }, + [ICX_IMC_DDR] = { 0x2290, 0x8, 0, 2, 48 }, + [ICX_IMC_DDRT] = { 0x22a0, 0x8, 0, 2, 48 }, +}; + +static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = { + INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"), + + INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"), + INTEL_UNCORE_EVENT_DESC(read.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"), + INTEL_UNCORE_EVENT_DESC(write.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"), + + INTEL_UNCORE_EVENT_DESC(ddrt_read, "event=0xff,umask=0x30"), + INTEL_UNCORE_EVENT_DESC(ddrt_read.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(ddrt_read.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(ddrt_write, "event=0xff,umask=0x31"), + INTEL_UNCORE_EVENT_DESC(ddrt_write.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(ddrt_write.unit, "MiB"), + { /* end: all zeroes */ }, +}; + +static void icx_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) +{ + int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE + + SNR_IMC_MMIO_MEM0_OFFSET; + + __snr_uncore_mmio_init_box(box, uncore_mmio_box_ctl(box), mem_offset); +} + +static struct intel_uncore_ops icx_uncore_imc_freerunning_ops = { + .init_box = icx_uncore_imc_freerunning_init_box, + .exit_box = uncore_mmio_exit_box, + .read_counter = uncore_mmio_read_counter, + .hw_config = uncore_freerunning_hw_config, +}; + +static struct intel_uncore_type icx_uncore_imc_free_running = { + .name = "imc_free_running", + .num_counters = 5, + .num_boxes = 4, + .num_freerunning_types = ICX_IMC_FREERUNNING_TYPE_MAX, + .freerunning = icx_imc_freerunning, + .ops = &icx_uncore_imc_freerunning_ops, + .event_descs = icx_uncore_imc_freerunning_events, + .format_group = &skx_uncore_iio_freerunning_format_group, +}; + +static struct intel_uncore_type *icx_mmio_uncores[] = { + &icx_uncore_imc, + &icx_uncore_imc_free_running, + NULL, +}; + +void icx_uncore_mmio_init(void) +{ + uncore_mmio_uncores = icx_mmio_uncores; +} + +/* end of ICX uncore support */ diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index b0da5320bcff..624f5d9b0f79 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -20,6 +20,7 @@ #include <linux/mm.h> #include <linux/hyperv.h> #include <linux/slab.h> +#include <linux/kernel.h> #include <linux/cpuhotplug.h> #include <linux/syscore_ops.h> #include <clocksource/hyperv_timer.h> @@ -419,11 +420,14 @@ void hyperv_cleanup(void) } EXPORT_SYMBOL_GPL(hyperv_cleanup); -void hyperv_report_panic(struct pt_regs *regs, long err) +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) { static bool panic_reported; u64 guest_id; + if (in_die && !panic_on_oops) + return; + /* * We prefer to report panic on 'die' chain as we have proper * registers to report, but if we miss it (e.g. on BUG()) we need diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index ff6f3ca649b3..dd17c2da1af5 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -44,6 +44,7 @@ unsigned int x86_stepping(unsigned int sig); extern void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c); extern void switch_to_sld(unsigned long tifn); extern bool handle_user_split_lock(struct pt_regs *regs, long error_code); +extern bool handle_guest_split_lock(unsigned long ip); #else static inline void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) {} static inline void switch_to_sld(unsigned long tifn) {} @@ -51,5 +52,10 @@ static inline bool handle_user_split_lock(struct pt_regs *regs, long error_code) { return false; } + +static inline bool handle_guest_split_lock(unsigned long ip) +{ + return false; +} #endif #endif /* _ASM_X86_CPU_H */ diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h index f71a0cce9373..430fca13bb56 100644 --- a/arch/x86/include/asm/dwarf2.h +++ b/arch/x86/include/asm/dwarf2.h @@ -6,15 +6,6 @@ #warning "asm/dwarf2.h should be only included in pure assembly files" #endif -/* - * Macros for dwarf2 CFI unwind table entries. - * See "as.info" for details on these pseudo ops. Unfortunately - * they are only supported in very new binutils, so define them - * away for older version. - */ - -#ifdef CONFIG_AS_CFI - #define CFI_STARTPROC .cfi_startproc #define CFI_ENDPROC .cfi_endproc #define CFI_DEF_CFA .cfi_def_cfa @@ -30,13 +21,6 @@ #define CFI_UNDEFINED .cfi_undefined #define CFI_ESCAPE .cfi_escape -#ifdef CONFIG_AS_CFI_SIGNAL_FRAME -#define CFI_SIGNAL_FRAME .cfi_signal_frame -#else -#define CFI_SIGNAL_FRAME -#endif - -#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__) #ifndef BUILD_VDSO /* * Emit CFI data in .debug_frame sections, not .eh_frame sections. @@ -53,33 +37,5 @@ */ .cfi_sections .eh_frame, .debug_frame #endif -#endif - -#else - -/* - * Due to the structure of pre-exisiting code, don't use assembler line - * comment character # to ignore the arguments. Instead, use a dummy macro. - */ -.macro cfi_ignore a=0, b=0, c=0, d=0 -.endm - -#define CFI_STARTPROC cfi_ignore -#define CFI_ENDPROC cfi_ignore -#define CFI_DEF_CFA cfi_ignore -#define CFI_DEF_CFA_REGISTER cfi_ignore -#define CFI_DEF_CFA_OFFSET cfi_ignore -#define CFI_ADJUST_CFA_OFFSET cfi_ignore -#define CFI_OFFSET cfi_ignore -#define CFI_REL_OFFSET cfi_ignore -#define CFI_REGISTER cfi_ignore -#define CFI_RESTORE cfi_ignore -#define CFI_REMEMBER_STATE cfi_ignore -#define CFI_RESTORE_STATE cfi_ignore -#define CFI_UNDEFINED cfi_ignore -#define CFI_ESCAPE cfi_ignore -#define CFI_SIGNAL_FRAME cfi_ignore - -#endif #endif /* _ASM_X86_DWARF2_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index cdcf48d52a12..8391c115c0ec 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -178,8 +178,10 @@ extern void efi_free_boot_services(void); extern pgd_t * __init efi_uv1_memmap_phys_prolog(void); extern void __init efi_uv1_memmap_phys_epilog(pgd_t *save_pgd); +/* kexec external ABI */ struct efi_setup_data { u64 fw_vendor; + u64 __unused; u64 tables; u64 smbios; u64 reserved[8]; diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 92abc1e42bfc..29336574d0bc 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -376,6 +376,7 @@ struct hv_tsc_emulation_status { #define HVCALL_SEND_IPI_EX 0x0015 #define HVCALL_POST_MESSAGE 0x005c #define HVCALL_SIGNAL_EVENT 0x005d +#define HVCALL_RETARGET_INTERRUPT 0x007e #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0 @@ -405,6 +406,8 @@ enum HV_GENERIC_SET_FORMAT { HV_GENERIC_SET_ALL, }; +#define HV_PARTITION_ID_SELF ((u64)-1) + #define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0) #define HV_HYPERCALL_FAST_BIT BIT(16) #define HV_HYPERCALL_VARHEAD_OFFSET 17 @@ -909,4 +912,42 @@ struct hv_tlb_flush_ex { struct hv_partition_assist_pg { u32 tlb_lock_count; }; + +union hv_msi_entry { + u64 as_uint64; + struct { + u32 address; + u32 data; + } __packed; +}; + +struct hv_interrupt_entry { + u32 source; /* 1 for MSI(-X) */ + u32 reserved1; + union hv_msi_entry msi_entry; +} __packed; + +/* + * flags for hv_device_interrupt_target.flags + */ +#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 +#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 + +struct hv_device_interrupt_target { + u32 vector; + u32 flags; + union { + u64 vp_mask; + struct hv_vpset vp_set; + }; +} __packed; + +/* HvRetargetDeviceInterrupt hypercall */ +struct hv_retarget_device_interrupt { + u64 partition_id; /* use "self" */ + u64 device_id; + struct hv_interrupt_entry int_entry; + u64 reserved2; + struct hv_device_interrupt_target int_target; +} __packed __aligned(8); #endif diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a239a297be33..b3a5da27c2a5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -583,6 +583,7 @@ struct kvm_vcpu_arch { unsigned long cr4; unsigned long cr4_guest_owned_bits; unsigned long cr8; + u32 host_pkru; u32 pkru; u32 hflags; u64 efer; @@ -1098,8 +1099,6 @@ struct kvm_x86_ops { void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); - u64 (*get_dr6)(struct kvm_vcpu *vcpu); - void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value); void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu); void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); @@ -1463,6 +1462,7 @@ bool kvm_rdpmc(struct kvm_vcpu *vcpu); void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); +void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); @@ -1682,8 +1682,8 @@ void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, static inline bool kvm_irq_is_postable(struct kvm_lapic_irq *irq) { /* We can only post Fixed and LowPrio IRQs */ - return (irq->delivery_mode == dest_Fixed || - irq->delivery_mode == dest_LowestPrio); + return (irq->delivery_mode == APIC_DM_FIXED || + irq->delivery_mode == APIC_DM_LOWEST); } static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index 6685e1218959..7063b5a43220 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -41,7 +41,7 @@ struct microcode_amd { unsigned int mpb[0]; }; -#define PATCH_MAX_SIZE PAGE_SIZE +#define PATCH_MAX_SIZE (3 * PAGE_SIZE) #ifdef CONFIG_MICROCODE_AMD extern void __init load_ucode_amd_bsp(unsigned int family); diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index edc2c581704a..1c42ecbe75cb 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -4,6 +4,7 @@ #include <linux/types.h> #include <linux/nmi.h> +#include <linux/msi.h> #include <asm/io.h> #include <asm/hyperv-tlfs.h> #include <asm/nospec-branch.h> @@ -242,6 +243,13 @@ bool hv_vcpu_is_preempted(int vcpu); static inline void hv_apic_init(void) {} #endif +static inline void hv_set_msi_entry_from_desc(union hv_msi_entry *msi_entry, + struct msi_desc *msi_desc) +{ + msi_entry->address = msi_desc->msg.address_lo; + msi_entry->data = msi_desc->msg.data; +} + #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} static inline void hyperv_setup_mmu_ops(void) {} diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index c85e15010f48..a506a411474d 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -35,9 +35,7 @@ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) -#define VM_DATA_DEFAULT_FLAGS \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #define __PHYSICAL_START ALIGN(CONFIG_PHYSICAL_START, \ CONFIG_PHYSICAL_ALIGN) @@ -73,9 +71,6 @@ static inline phys_addr_t get_max_mapped(void) bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn); -extern unsigned long init_memory_mapping(unsigned long start, - unsigned long end); - extern void initmem_init(void); #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index afda66a6d325..4d02e64af1b3 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -25,6 +25,7 @@ #include <asm/x86_init.h> #include <asm/fpu/xstate.h> #include <asm/fpu/api.h> +#include <asm-generic/pgtable_uffd.h> extern pgd_t early_top_pgt[PTRS_PER_PGD]; int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); @@ -313,6 +314,23 @@ static inline pte_t pte_clear_flags(pte_t pte, pteval_t clear) return native_make_pte(v & ~clear); } +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +static inline int pte_uffd_wp(pte_t pte) +{ + return pte_flags(pte) & _PAGE_UFFD_WP; +} + +static inline pte_t pte_mkuffd_wp(pte_t pte) +{ + return pte_set_flags(pte, _PAGE_UFFD_WP); +} + +static inline pte_t pte_clear_uffd_wp(pte_t pte) +{ + return pte_clear_flags(pte, _PAGE_UFFD_WP); +} +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ + static inline pte_t pte_mkclean(pte_t pte) { return pte_clear_flags(pte, _PAGE_DIRTY); @@ -392,6 +410,23 @@ static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear) return native_make_pmd(v & ~clear); } +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +static inline int pmd_uffd_wp(pmd_t pmd) +{ + return pmd_flags(pmd) & _PAGE_UFFD_WP; +} + +static inline pmd_t pmd_mkuffd_wp(pmd_t pmd) +{ + return pmd_set_flags(pmd, _PAGE_UFFD_WP); +} + +static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_UFFD_WP); +} +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ + static inline pmd_t pmd_mkold(pmd_t pmd) { return pmd_clear_flags(pmd, _PAGE_ACCESSED); @@ -825,7 +860,10 @@ static inline unsigned long pmd_index(unsigned long address) * * this function returns the index of the entry in the pte page which would * control the given virtual address + * + * Also define macro so we can test if pte_index is defined for arch. */ +#define pte_index pte_index static inline unsigned long pte_index(unsigned long address) { return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -1043,6 +1081,9 @@ static inline void __meminit init_trampoline_default(void) void __init poking_init(void); +unsigned long init_memory_mapping(unsigned long start, + unsigned long end, pgprot_t prot); + # ifdef CONFIG_RANDOMIZE_MEMORY void __meminit init_trampoline(void); # else @@ -1374,6 +1415,38 @@ static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) #endif #endif +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +static inline pte_t pte_swp_mkuffd_wp(pte_t pte) +{ + return pte_set_flags(pte, _PAGE_SWP_UFFD_WP); +} + +static inline int pte_swp_uffd_wp(pte_t pte) +{ + return pte_flags(pte) & _PAGE_SWP_UFFD_WP; +} + +static inline pte_t pte_swp_clear_uffd_wp(pte_t pte) +{ + return pte_clear_flags(pte, _PAGE_SWP_UFFD_WP); +} + +static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd) +{ + return pmd_set_flags(pmd, _PAGE_SWP_UFFD_WP); +} + +static inline int pmd_swp_uffd_wp(pmd_t pmd) +{ + return pmd_flags(pmd) & _PAGE_SWP_UFFD_WP; +} + +static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_SWP_UFFD_WP); +} +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ + #define PKRU_AD_BIT 0x1 #define PKRU_WD_BIT 0x2 #define PKRU_BITS_PER_PKEY 2 diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 0b6c4042942a..df1373415f11 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -189,7 +189,7 @@ extern void sync_global_pgds(unsigned long start, unsigned long end); * * | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names - * | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry + * | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|F|SD|0| <- swp entry * * G (8) is aliased and used as a PROT_NONE indicator for * !present ptes. We need to start storing swap entries above @@ -197,9 +197,15 @@ extern void sync_global_pgds(unsigned long start, unsigned long end); * erratum where they can be incorrectly set by hardware on * non-present PTEs. * + * SD Bits 1-4 are not used in non-present format and available for + * special use described below: + * * SD (1) in swp entry is used to store soft dirty bit, which helps us * remember soft dirty over page migration * + * F (2) in swp entry is used to record when a pagetable is + * writeprotected by userfaultfd WP support. + * * Bit 7 in swp entry should be 0 because pmd_present checks not only P, * but also L and G. * diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 65c2ecd730c5..b6606fe6cfdf 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -32,6 +32,7 @@ #define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1 #define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1 +#define _PAGE_BIT_UFFD_WP _PAGE_BIT_SOFTW2 /* userfaultfd wrprotected */ #define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */ #define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 @@ -100,6 +101,14 @@ #define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0)) #endif +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +#define _PAGE_UFFD_WP (_AT(pteval_t, 1) << _PAGE_BIT_UFFD_WP) +#define _PAGE_SWP_UFFD_WP _PAGE_USER +#else +#define _PAGE_UFFD_WP (_AT(pteval_t, 0)) +#define _PAGE_SWP_UFFD_WP (_AT(pteval_t, 0)) +#endif + #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) #define _PAGE_DEVMAP (_AT(u64, 1) << _PAGE_BIT_DEVMAP) @@ -118,7 +127,8 @@ */ #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC) + _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \ + _PAGE_UFFD_WP) #define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE) /* diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h index 950532ccbc4a..ec2c0a094b5d 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -34,6 +34,7 @@ * The caller is required to take care of these. */ +int __set_memory_prot(unsigned long addr, int numpages, pgprot_t prot); int _set_memory_uc(unsigned long addr, int numpages); int _set_memory_wc(unsigned long addr, int numpages); int _set_memory_wt(unsigned long addr, int numpages); diff --git a/arch/x86/include/asm/xor_avx.h b/arch/x86/include/asm/xor_avx.h index d61ddf3d052b..0c4e5b5e3852 100644 --- a/arch/x86/include/asm/xor_avx.h +++ b/arch/x86/include/asm/xor_avx.h @@ -11,8 +11,6 @@ * Based on Ingo Molnar and Zach Brown's respective MMX and SSE routines */ -#ifdef CONFIG_AS_AVX - #include <linux/compiler.h> #include <asm/fpu/api.h> @@ -170,11 +168,4 @@ do { \ #define AVX_SELECT(FASTEST) \ (boot_cpu_has(X86_FEATURE_AVX) && boot_cpu_has(X86_FEATURE_OSXSAVE) ? &xor_block_avx : FASTEST) -#else - -#define AVX_XOR_SPEED {} - -#define AVX_SELECT(FASTEST) (FASTEST) - -#endif #endif diff --git a/arch/x86/kernel/.gitignore b/arch/x86/kernel/.gitignore index 08f4fd731469..ef66569e7e22 100644 --- a/arch/x86/kernel/.gitignore +++ b/arch/x86/kernel/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only vsyscall.lds vsyscall_32.lds vmlinux.lds diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 1ae5439a9a85..683ed9e12e6b 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -45,7 +45,7 @@ EXPORT_SYMBOL(acpi_disabled); #define PREFIX "ACPI: " int acpi_noirq; /* skip ACPI IRQ initialization */ -int acpi_nobgrt; /* skip ACPI BGRT */ +static int acpi_nobgrt; /* skip ACPI BGRT */ int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ EXPORT_SYMBOL(acpi_pci_disabled); diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index caf2edccbad2..49ae4e1ac9cd 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -161,7 +161,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, /* Make sure we are running on right CPU */ - retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx); + retval = call_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx, + false); if (retval == 0) { /* Use the hint in CST */ percpu_entry->states[cx->index].eax = cx->address; diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index 4e5f50236048..16133819415c 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -744,7 +744,8 @@ int __init gart_iommu_init(void) start_pfn = PFN_DOWN(aper_base); if (!pfn_range_is_mapped(start_pfn, end_pfn)) - init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); + init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT, + PAGE_KERNEL); pr_info("PCI-DMA: using GART IOMMU.\n"); iommu_size = check_iommu_size(info.aper_base, aper_size); diff --git a/arch/x86/kernel/cpu/.gitignore b/arch/x86/kernel/cpu/.gitignore index 667df55a4399..0bca7ef7426a 100644 --- a/arch/x86/kernel/cpu/.gitignore +++ b/arch/x86/kernel/cpu/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only capflags.c diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 9a26e972cdea..a19a680542ce 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -21,6 +21,7 @@ #include <asm/elf.h> #include <asm/cpu_device_id.h> #include <asm/cmdline.h> +#include <asm/traps.h> #ifdef CONFIG_X86_64 #include <linux/topology.h> @@ -1066,13 +1067,10 @@ static void split_lock_init(void) split_lock_verify_msr(sld_state != sld_off); } -bool handle_user_split_lock(struct pt_regs *regs, long error_code) +static void split_lock_warn(unsigned long ip) { - if ((regs->flags & X86_EFLAGS_AC) || sld_state == sld_fatal) - return false; - pr_warn_ratelimited("#AC: %s/%d took a split_lock trap at address: 0x%lx\n", - current->comm, current->pid, regs->ip); + current->comm, current->pid, ip); /* * Disable the split lock detection for this task so it can make @@ -1081,6 +1079,31 @@ bool handle_user_split_lock(struct pt_regs *regs, long error_code) */ sld_update_msr(false); set_tsk_thread_flag(current, TIF_SLD); +} + +bool handle_guest_split_lock(unsigned long ip) +{ + if (sld_state == sld_warn) { + split_lock_warn(ip); + return true; + } + + pr_warn_once("#AC: %s/%d %s split_lock trap at address: 0x%lx\n", + current->comm, current->pid, + sld_state == sld_fatal ? "fatal" : "bogus", ip); + + current->thread.error_code = 0; + current->thread.trap_nr = X86_TRAP_AC; + force_sig_fault(SIGBUS, BUS_ADRALN, NULL); + return false; +} +EXPORT_SYMBOL_GPL(handle_guest_split_lock); + +bool handle_user_split_lock(struct pt_regs *regs, long error_code) +{ + if ((regs->flags & X86_EFLAGS_AC) || sld_state == sld_fatal) + return false; + split_lock_warn(regs->ip); return true; } @@ -1096,35 +1119,53 @@ void switch_to_sld(unsigned long tifn) sld_update_msr(!(tifn & _TIF_SLD)); } -#define SPLIT_LOCK_CPU(model) {X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY} - /* - * The following processors have the split lock detection feature. But - * since they don't have the IA32_CORE_CAPABILITIES MSR, the feature cannot - * be enumerated. Enable it by family and model matching on these - * processors. + * Bits in the IA32_CORE_CAPABILITIES are not architectural, so they should + * only be trusted if it is confirmed that a CPU model implements a + * specific feature at a particular bit position. + * + * The possible driver data field values: + * + * - 0: CPU models that are known to have the per-core split-lock detection + * feature even though they do not enumerate IA32_CORE_CAPABILITIES. + * + * - 1: CPU models which may enumerate IA32_CORE_CAPABILITIES and if so use + * bit 5 to enumerate the per-core split-lock detection feature. */ static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { - SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_X), - SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_L), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, 0), + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, 1), + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, 1), + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, 1), {} }; void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) { - u64 ia32_core_caps = 0; + const struct x86_cpu_id *m; + u64 ia32_core_caps; - if (c->x86_vendor != X86_VENDOR_INTEL) + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) return; - if (cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) { - /* Enumerate features reported in IA32_CORE_CAPABILITIES MSR. */ + + m = x86_match_cpu(split_lock_cpu_ids); + if (!m) + return; + + switch (m->driver_data) { + case 0: + break; + case 1: + if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) + return; rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps); - } else if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) { - /* Enumerate split lock detection by family and model. */ - if (x86_match_cpu(split_lock_cpu_ids)) - ia32_core_caps |= MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT; + if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT)) + return; + break; + default: + return; } - if (ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT) - split_lock_setup(); + split_lock_setup(); } diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index caa032ce3fe3..ebf34c7bc8bc 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -227,8 +227,8 @@ static void __init ms_hyperv_init_platform(void) ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES); ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); - pr_info("Hyper-V: features 0x%x, hints 0x%x\n", - ms_hyperv.features, ms_hyperv.hints); + pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n", + ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features); ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS); ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS); @@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platform(void) cpuid_eax(HYPERV_CPUID_NESTED_FEATURES); } + /* + * Hyper-V expects to get crash register data or kmsg when + * crash enlightment is available and system crashes. Set + * crash_kexec_post_notifiers to be true to make sure that + * calling crash enlightment interface before running kdump + * kernel. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) + crash_kexec_post_notifiers = true; + #ifdef CONFIG_X86_LOCAL_APIC if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index 89049b343c7a..d8cc5223b7ce 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -578,6 +578,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) d->id = id; cpumask_set_cpu(cpu, &d->cpu_mask); + rdt_domain_reconfigure_cdp(r); + if (r->alloc_capable && domain_setup_ctrlval(r, d)) { kfree(d); return; diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index 181c992f448c..3dd13f3a8b23 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -601,5 +601,6 @@ bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); void __check_limbo(struct rdt_domain *d, bool force_free); bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r); bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r); +void rdt_domain_reconfigure_cdp(struct rdt_resource *r); #endif /* _ASM_X86_RESCTRL_INTERNAL_H */ diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 064e9ef44cd6..5a359d9fcc05 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -1859,6 +1859,19 @@ static int set_cache_qos_cfg(int level, bool enable) return 0; } +/* Restore the qos cfg state when a domain comes online */ +void rdt_domain_reconfigure_cdp(struct rdt_resource *r) +{ + if (!r->alloc_capable) + return; + + if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA]) + l2_qos_cfg_update(&r->alloc_enabled); + + if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA]) + l3_qos_cfg_update(&r->alloc_enabled); +} + /* * Enable or disable the MBA software controller * which helps user specify bandwidth in MBps. @@ -3072,7 +3085,8 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) * If the rdtgroup is a mon group and parent directory * is a valid "mon_groups" directory, remove the mon group. */ - if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) { + if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn && + rdtgrp != &rdtgroup_default) { if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP || rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) { ret = rdtgroup_ctrl_remove(kn, rdtgrp); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index e6b545047f38..4b3fa6cd3106 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -16,6 +16,7 @@ #include <linux/pci.h> #include <linux/root_dev.h> #include <linux/sfi.h> +#include <linux/hugetlb.h> #include <linux/tboot.h> #include <linux/usb/xhci-dbgp.h> @@ -1157,6 +1158,9 @@ void __init setup_arch(char **cmdline_p) initmem_init(); dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT); + if (boot_cpu_has(X86_FEATURE_GBPAGES)) + hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); + /* * Reserve memory for crash kernel after SRAT is parsed so that it * won't consume hotpluggable memory. diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index 4d732a444711..8d5cbe1bbb3b 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c @@ -81,7 +81,7 @@ #define UMIP_INST_SLDT 3 /* 0F 00 /0 */ #define UMIP_INST_STR 4 /* 0F 00 /1 */ -const char * const umip_insns[5] = { +static const char * const umip_insns[5] = { [UMIP_INST_SGDT] = "SGDT", [UMIP_INST_SIDT] = "SIDT", [UMIP_INST_SMSW] = "SMSW", diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 9fea0757db92..d8154e0684b6 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -107,8 +107,4 @@ config KVM_MMU_AUDIT This option adds a R/W kVM module parameter 'mmu_audit', which allows auditing of KVM MMU events at runtime. -# OK, it's a little counter-intuitive to do this, but it puts it neatly under -# the virtualization menu. -source "drivers/vhost/Kconfig" - endif # VIRTUALIZATION diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index a789759b7261..4a3081e9f4b5 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -3,6 +3,10 @@ ccflags-y += -Iarch/x86/kvm ccflags-$(CONFIG_KVM_WERROR) += -Werror +ifeq ($(CONFIG_FRAME_POINTER),y) +OBJECT_FILES_NON_STANDARD_vmenter.o := y +endif + KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 2f96ff9e60ee..f9d3b919823c 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1426,7 +1426,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *current_vcpu, u64 ingpa, * analyze it here, flush TLB regardless of the specified address space. */ kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, - vcpu_mask, &hv_vcpu->tlb_flush); + NULL, vcpu_mask, &hv_vcpu->tlb_flush); ret_success: /* We always do full TLB flush, set rep_done = rep_cnt. */ diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 750ff0b29404..d057376bd3d3 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -225,12 +225,12 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, } /* - * AMD SVM AVIC accelerate EOI write and do not trap, - * in-kernel IOAPIC will not be able to receive the EOI. - * In this case, we do lazy update of the pending EOI when - * trying to set IOAPIC irq. + * AMD SVM AVIC accelerate EOI write iff the interrupt is edge + * triggered, in which case the in-kernel IOAPIC will not be able + * to receive the EOI. In this case, we do a lazy update of the + * pending EOI when trying to set IOAPIC irq. */ - if (kvm_apicv_activated(ioapic->kvm)) + if (edge && kvm_apicv_activated(ioapic->kvm)) ioapic_lazy_update_eoi(ioapic, irq); /* diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index a7c3b3030e59..1429f506fe9e 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <asm/msr-index.h> +#include <asm/debugreg.h> #include "kvm_emulate.h" #include "trace.h" @@ -271,7 +272,7 @@ void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, svm->vmcb->save.rsp = nested_vmcb->save.rsp; svm->vmcb->save.rip = nested_vmcb->save.rip; svm->vmcb->save.dr7 = nested_vmcb->save.dr7; - svm->vmcb->save.dr6 = nested_vmcb->save.dr6; + svm->vcpu.arch.dr6 = nested_vmcb->save.dr6; svm->vmcb->save.cpl = nested_vmcb->save.cpl; svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa & ~0x0fffULL; @@ -490,7 +491,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm) nested_vmcb->save.rsp = vmcb->save.rsp; nested_vmcb->save.rax = vmcb->save.rax; nested_vmcb->save.dr7 = vmcb->save.dr7; - nested_vmcb->save.dr6 = vmcb->save.dr6; + nested_vmcb->save.dr6 = svm->vcpu.arch.dr6; nested_vmcb->save.cpl = vmcb->save.cpl; nested_vmcb->control.int_ctl = vmcb->control.int_ctl; @@ -614,26 +615,45 @@ static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) /* DB exceptions for our internal use must not cause vmexit */ static int nested_svm_intercept_db(struct vcpu_svm *svm) { - unsigned long dr6; + unsigned long dr6 = svm->vmcb->save.dr6; + + /* Always catch it and pass it to userspace if debugging. */ + if (svm->vcpu.guest_debug & + (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) + return NESTED_EXIT_HOST; /* if we're not singlestepping, it's not ours */ if (!svm->nmi_singlestep) - return NESTED_EXIT_DONE; + goto reflected_db; /* if it's not a singlestep exception, it's not ours */ - if (kvm_get_dr(&svm->vcpu, 6, &dr6)) - return NESTED_EXIT_DONE; if (!(dr6 & DR6_BS)) - return NESTED_EXIT_DONE; + goto reflected_db; /* if the guest is singlestepping, it should get the vmexit */ if (svm->nmi_singlestep_guest_rflags & X86_EFLAGS_TF) { disable_nmi_singlestep(svm); - return NESTED_EXIT_DONE; + goto reflected_db; } /* it's ours, the nested hypervisor must not see this one */ return NESTED_EXIT_HOST; + +reflected_db: + /* + * Synchronize guest DR6 here just like in kvm_deliver_exception_payload; + * it will be moved into the nested VMCB by nested_svm_vmexit. Once + * exceptions will be moved to svm_check_nested_events, all this stuff + * will just go away and we could just return NESTED_EXIT_HOST + * unconditionally. db_interception will queue the exception, which + * will be processed by svm_check_nested_events if a nested vmexit is + * required, and we will just use kvm_deliver_exception_payload to copy + * the payload to DR6 before vmexit. + */ + WARN_ON(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT); + svm->vcpu.arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); + svm->vcpu.arch.dr6 |= dr6 & ~DR6_FIXED_1; + return NESTED_EXIT_DONE; } static int nested_svm_intercept_ioio(struct vcpu_svm *svm) @@ -690,6 +710,9 @@ static int nested_svm_intercept(struct vcpu_svm *svm) if (svm->nested.intercept_exceptions & excp_bits) { if (exit_code == SVM_EXIT_EXCP_BASE + DB_VECTOR) vmexit = nested_svm_intercept_db(svm); + else if (exit_code == SVM_EXIT_EXCP_BASE + BP_VECTOR && + svm->vcpu.guest_debug & KVM_GUESTDBG_USE_SW_BP) + vmexit = NESTED_EXIT_HOST; else vmexit = NESTED_EXIT_DONE; } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index c86f7278509b..b627564e41f9 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1673,17 +1673,14 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) mark_dirty(svm->vmcb, VMCB_ASID); } -static u64 svm_get_dr6(struct kvm_vcpu *vcpu) +static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value) { - return to_svm(vcpu)->vmcb->save.dr6; -} - -static void svm_set_dr6(struct kvm_vcpu *vcpu, unsigned long value) -{ - struct vcpu_svm *svm = to_svm(vcpu); + struct vmcb *vmcb = svm->vmcb; - svm->vmcb->save.dr6 = value; - mark_dirty(svm->vmcb, VMCB_DR); + if (unlikely(value != vmcb->save.dr6)) { + vmcb->save.dr6 = value; + mark_dirty(vmcb, VMCB_DR); + } } static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) @@ -1694,9 +1691,12 @@ static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) get_debugreg(vcpu->arch.db[1], 1); get_debugreg(vcpu->arch.db[2], 2); get_debugreg(vcpu->arch.db[3], 3); - vcpu->arch.dr6 = svm_get_dr6(vcpu); + /* + * We cannot reset svm->vmcb->save.dr6 to DR6_FIXED_1|DR6_RTM here, + * because db_interception might need it. We can do it before vmentry. + */ + vcpu->arch.dr6 = svm->vmcb->save.dr6; vcpu->arch.dr7 = svm->vmcb->save.dr7; - vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT; set_dr_intercepts(svm); } @@ -1740,7 +1740,8 @@ static int db_interception(struct vcpu_svm *svm) if (!(svm->vcpu.guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) && !svm->nmi_singlestep) { - kvm_queue_exception(&svm->vcpu, DB_VECTOR); + u32 payload = (svm->vmcb->save.dr6 ^ DR6_RTM) & ~DR6_FIXED_1; + kvm_queue_exception_p(&svm->vcpu, DB_VECTOR, payload); return 1; } @@ -1753,6 +1754,8 @@ static int db_interception(struct vcpu_svm *svm) if (svm->vcpu.guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) { kvm_run->exit_reason = KVM_EXIT_DEBUG; + kvm_run->debug.arch.dr6 = svm->vmcb->save.dr6; + kvm_run->debug.arch.dr7 = svm->vmcb->save.dr7; kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip; kvm_run->debug.arch.exception = DB_VECTOR; @@ -3349,6 +3352,15 @@ static enum exit_fastpath_completion svm_vcpu_run(struct kvm_vcpu *vcpu) svm->vmcb->save.cr2 = vcpu->arch.cr2; + /* + * Run with all-zero DR6 unless needed, so that we can get the exact cause + * of a #DB. + */ + if (unlikely(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) + svm_set_dr6(svm, vcpu->arch.dr6); + else + svm_set_dr6(svm, DR6_FIXED_1 | DR6_RTM); + clgi(); kvm_load_guest_xsave_state(vcpu); @@ -3967,8 +3979,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .set_idt = svm_set_idt, .get_gdt = svm_get_gdt, .set_gdt = svm_set_gdt, - .get_dr6 = svm_get_dr6, - .set_dr6 = svm_set_dr6, .set_dr7 = svm_set_dr7, .sync_dirty_debug_regs = svm_sync_dirty_debug_regs, .cache_reg = svm_cache_reg, diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b516c24494e3..b644bbf85460 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5236,7 +5236,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) roots_to_free = KVM_MMU_ROOTS_ALL; break; default: - BUG_ON(1); + BUG(); break; } diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S index 87f3f24fef37..51d1a82742fd 100644 --- a/arch/x86/kvm/vmx/vmenter.S +++ b/arch/x86/kvm/vmx/vmenter.S @@ -82,6 +82,9 @@ SYM_FUNC_START(vmx_vmexit) /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE + /* Clear RFLAGS.CF and RFLAGS.ZF to preserve VM-Exit, i.e. !VM-Fail. */ + or $1, %_ASM_AX + pop %_ASM_AX .Lvmexit_skip_rsb: #endif diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 455cd2c8dbce..46aa3ca01929 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1381,7 +1381,6 @@ void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vmx_vcpu_pi_load(vcpu, cpu); - vmx->host_pkru = read_pkru(); vmx->host_debugctlmsr = get_debugctlmsr(); } @@ -4645,6 +4644,26 @@ static int handle_machine_check(struct kvm_vcpu *vcpu) return 1; } +/* + * If the host has split lock detection disabled, then #AC is + * unconditionally injected into the guest, which is the pre split lock + * detection behaviour. + * + * If the host has split lock detection enabled then #AC is + * only injected into the guest when: + * - Guest CPL == 3 (user mode) + * - Guest has #AC detection enabled in CR0 + * - Guest EFLAGS has AC bit set + */ +static inline bool guest_inject_ac(struct kvm_vcpu *vcpu) +{ + if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) + return true; + + return vmx_get_cpl(vcpu) == 3 && kvm_read_cr0_bits(vcpu, X86_CR0_AM) && + (kvm_get_rflags(vcpu) & X86_EFLAGS_AC); +} + static int handle_exception_nmi(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -4710,22 +4729,17 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) return handle_rmode_exception(vcpu, ex_no, error_code); switch (ex_no) { - case AC_VECTOR: - kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); - return 1; case DB_VECTOR: dr6 = vmx_get_exit_qual(vcpu); if (!(vcpu->guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { - vcpu->arch.dr6 &= ~DR_TRAP_BITS; - vcpu->arch.dr6 |= dr6 | DR6_RTM; if (is_icebp(intr_info)) WARN_ON(!skip_emulated_instruction(vcpu)); - kvm_queue_exception(vcpu, DB_VECTOR); + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); return 1; } - kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1; + kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7); /* fall through */ case BP_VECTOR: @@ -4741,6 +4755,20 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip; kvm_run->debug.arch.exception = ex_no; break; + case AC_VECTOR: + if (guest_inject_ac(vcpu)) { + kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); + return 1; + } + + /* + * Handle split lock. Depending on detection mode this will + * either warn and disable split lock detection for this + * task or force SIGBUS on it. + */ + if (handle_guest_split_lock(kvm_rip_read(vcpu))) + return 1; + fallthrough; default: kvm_run->exit_reason = KVM_EXIT_EXCEPTION; kvm_run->ex.exception = ex_no; @@ -4955,16 +4983,14 @@ static int handle_dr(struct kvm_vcpu *vcpu) * guest debugging itself. */ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { - vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; + vcpu->run->debug.arch.dr6 = DR6_BD | DR6_RTM | DR6_FIXED_1; vcpu->run->debug.arch.dr7 = dr7; vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu); vcpu->run->debug.arch.exception = DB_VECTOR; vcpu->run->exit_reason = KVM_EXIT_DEBUG; return 0; } else { - vcpu->arch.dr6 &= ~DR_TRAP_BITS; - vcpu->arch.dr6 |= DR6_BD | DR6_RTM; - kvm_queue_exception(vcpu, DB_VECTOR); + kvm_queue_exception_p(vcpu, DB_VECTOR, DR6_BD); return 1; } } @@ -4995,15 +5021,6 @@ static int handle_dr(struct kvm_vcpu *vcpu) return kvm_skip_emulated_instruction(vcpu); } -static u64 vmx_get_dr6(struct kvm_vcpu *vcpu) -{ - return vcpu->arch.dr6; -} - -static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) -{ -} - static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) { get_debugreg(vcpu->arch.db[0], 0); @@ -6615,11 +6632,6 @@ static enum exit_fastpath_completion vmx_vcpu_run(struct kvm_vcpu *vcpu) kvm_load_guest_xsave_state(vcpu); - if (static_cpu_has(X86_FEATURE_PKU) && - kvm_read_cr4_bits(vcpu, X86_CR4_PKE) && - vcpu->arch.pkru != vmx->host_pkru) - __write_pkru(vcpu->arch.pkru); - pt_guest_enter(vmx); if (vcpu_to_pmu(vcpu)->version) @@ -6704,18 +6716,6 @@ static enum exit_fastpath_completion vmx_vcpu_run(struct kvm_vcpu *vcpu) pt_guest_exit(vmx); - /* - * eager fpu is enabled if PKEY is supported and CR4 is switched - * back on host, so it is safe to read guest PKRU from current - * XSAVE. - */ - if (static_cpu_has(X86_FEATURE_PKU) && - kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) { - vcpu->arch.pkru = rdpkru(); - if (vcpu->arch.pkru != vmx->host_pkru) - __write_pkru(vmx->host_pkru); - } - kvm_load_host_xsave_state(vcpu); vmx->nested.nested_run_pending = 0; @@ -7785,8 +7785,6 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt, .set_gdt = vmx_set_gdt, - .get_dr6 = vmx_get_dr6, - .set_dr6 = vmx_set_dr6, .set_dr7 = vmx_set_dr7, .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs, .cache_reg = vmx_cache_reg, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8c0b77ac8dc6..542a00008caa 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -568,11 +568,12 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) } EXPORT_SYMBOL_GPL(kvm_requeue_exception); -static void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, - unsigned long payload) +void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, + unsigned long payload) { kvm_multiple_exception(vcpu, nr, false, 0, true, payload, false); } +EXPORT_SYMBOL_GPL(kvm_queue_exception_p); static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code, unsigned long payload) @@ -845,11 +846,25 @@ void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu) vcpu->arch.ia32_xss != host_xss) wrmsrl(MSR_IA32_XSS, vcpu->arch.ia32_xss); } + + if (static_cpu_has(X86_FEATURE_PKU) && + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) && + vcpu->arch.pkru != vcpu->arch.host_pkru) + __write_pkru(vcpu->arch.pkru); } EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state); void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) { + if (static_cpu_has(X86_FEATURE_PKU) && + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) { + vcpu->arch.pkru = rdpkru(); + if (vcpu->arch.pkru != vcpu->arch.host_pkru) + __write_pkru(vcpu->arch.host_pkru); + } + if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) { if (vcpu->arch.xcr0 != host_xcr0) @@ -935,19 +950,6 @@ EXPORT_SYMBOL_GPL(kvm_set_xcr); __reserved_bits; \ }) -static u64 kvm_host_cr4_reserved_bits(struct cpuinfo_x86 *c) -{ - u64 reserved_bits = __cr4_reserved_bits(cpu_has, c); - - if (kvm_cpu_cap_has(X86_FEATURE_LA57)) - reserved_bits &= ~X86_CR4_LA57; - - if (kvm_cpu_cap_has(X86_FEATURE_UMIP)) - reserved_bits &= ~X86_CR4_UMIP; - - return reserved_bits; -} - static int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { if (cr4 & cr4_reserved_bits) @@ -1067,12 +1069,6 @@ static void kvm_update_dr0123(struct kvm_vcpu *vcpu) } } -static void kvm_update_dr6(struct kvm_vcpu *vcpu) -{ - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) - kvm_x86_ops.set_dr6(vcpu, vcpu->arch.dr6); -} - static void kvm_update_dr7(struct kvm_vcpu *vcpu) { unsigned long dr7; @@ -1112,7 +1108,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) if (val & 0xffffffff00000000ULL) return -1; /* #GP */ vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu); - kvm_update_dr6(vcpu); break; case 5: /* fall through */ @@ -1148,10 +1143,7 @@ int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) case 4: /* fall through */ case 6: - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) - *val = vcpu->arch.dr6; - else - *val = kvm_x86_ops.get_dr6(vcpu); + *val = vcpu->arch.dr6; break; case 5: /* fall through */ @@ -3075,6 +3067,17 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_PERF_CTL: case MSR_AMD64_DC_CFG: case MSR_F15H_EX_CFG: + /* + * Intel Sandy Bridge CPUs must support the RAPL (running average power + * limit) MSRs. Just return 0, as we do not want to expose the host + * data here. Do not conditionalize this on CPUID, as KVM does not do + * so for existing CPU-specific MSRs. + */ + case MSR_RAPL_POWER_UNIT: + case MSR_PP0_ENERGY_STATUS: /* Power plane 0 (core) */ + case MSR_PP1_ENERGY_STATUS: /* Power plane 1 (graphics uncore) */ + case MSR_PKG_ENERGY_STATUS: /* Total package */ + case MSR_DRAM_ENERGY_STATUS: /* DRAM controller */ msr_info->data = 0; break; case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5: @@ -3389,6 +3392,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_GET_MSR_FEATURES: case KVM_CAP_MSR_PLATFORM_INFO: case KVM_CAP_EXCEPTION_PAYLOAD: + case KVM_CAP_SET_GUEST_DEBUG: r = 1; break; case KVM_CAP_SYNC_REGS: @@ -3574,6 +3578,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_x86_ops.vcpu_load(vcpu, cpu); + /* Save host pkru register if supported */ + vcpu->arch.host_pkru = read_pkru(); + /* Apply any externally detected TSC adjustments (due to suspend) */ if (unlikely(vcpu->arch.tsc_offset_adjustment)) { adjust_tsc_offset_host(vcpu, vcpu->arch.tsc_offset_adjustment); @@ -4025,7 +4032,6 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); kvm_update_dr0123(vcpu); vcpu->arch.dr6 = dbgregs->dr6; - kvm_update_dr6(vcpu); vcpu->arch.dr7 = dbgregs->dr7; kvm_update_dr7(vcpu); @@ -5064,10 +5070,13 @@ set_identity_unlock: r = -EFAULT; if (copy_from_user(&u.ps, argp, sizeof(u.ps))) goto out; + mutex_lock(&kvm->lock); r = -ENXIO; if (!kvm->arch.vpit) - goto out; + goto set_pit_out; r = kvm_vm_ioctl_set_pit(kvm, &u.ps); +set_pit_out: + mutex_unlock(&kvm->lock); break; } case KVM_GET_PIT2: { @@ -5087,10 +5096,13 @@ set_identity_unlock: r = -EFAULT; if (copy_from_user(&u.ps2, argp, sizeof(u.ps2))) goto out; + mutex_lock(&kvm->lock); r = -ENXIO; if (!kvm->arch.vpit) - goto out; + goto set_pit2_out; r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2); +set_pit2_out: + mutex_unlock(&kvm->lock); break; } case KVM_REINJECT_CONTROL: { @@ -5854,6 +5866,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt, { struct kvm_host_map map; struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + u64 page_line_mask; gpa_t gpa; char *kaddr; bool exchanged; @@ -5868,7 +5881,16 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt, (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) goto emul_write; - if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) + /* + * Emulate the atomic as a straight write to avoid #AC if SLD is + * enabled in the host and the access splits a cache line. + */ + if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) + page_line_mask = ~(cache_line_size() - 1); + else + page_line_mask = PAGE_MASK; + + if (((gpa + bytes - 1) & page_line_mask) != (gpa & page_line_mask)) goto emul_write; if (kvm_vcpu_map(vcpu, gpa_to_gfn(gpa), &map)) @@ -6659,7 +6681,7 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu) if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM; - kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; + kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu); kvm_run->debug.arch.exception = DB_VECTOR; kvm_run->exit_reason = KVM_EXIT_DEBUG; return 0; @@ -6719,9 +6741,7 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) vcpu->arch.db); if (dr6 != 0) { - vcpu->arch.dr6 &= ~DR_TRAP_BITS; - vcpu->arch.dr6 |= dr6 | DR6_RTM; - kvm_queue_exception(vcpu, DB_VECTOR); + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); *r = 1; return true; } @@ -8042,7 +8062,7 @@ void kvm_make_scan_ioapic_request_mask(struct kvm *kvm, zalloc_cpumask_var(&cpus, GFP_ATOMIC); kvm_make_vcpus_request_mask(kvm, KVM_REQ_SCAN_IOAPIC, - vcpu_bitmap, cpus); + NULL, vcpu_bitmap, cpus); free_cpumask_var(cpus); } @@ -8072,6 +8092,7 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); */ void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) { + struct kvm_vcpu *except; unsigned long old, new, expected; if (!kvm_x86_ops.check_apicv_inhibit_reasons || @@ -8096,7 +8117,17 @@ void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) trace_kvm_apicv_update_request(activate, bit); if (kvm_x86_ops.pre_update_apicv_exec_ctrl) kvm_x86_ops.pre_update_apicv_exec_ctrl(kvm, activate); - kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); + + /* + * Sending request to update APICV for all other vcpus, + * while update the calling vcpu immediately instead of + * waiting for another #VMEXIT to handle the request. + */ + except = kvm_get_running_vcpu(); + kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, + except); + if (except) + kvm_vcpu_update_apicv(except); } EXPORT_SYMBOL_GPL(kvm_request_apicv_update); @@ -8418,7 +8449,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); kvm_x86_ops.sync_dirty_debug_regs(vcpu); kvm_update_dr0123(vcpu); - kvm_update_dr6(vcpu); kvm_update_dr7(vcpu); vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; } @@ -9480,7 +9510,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); kvm_update_dr0123(vcpu); vcpu->arch.dr6 = DR6_INIT; - kvm_update_dr6(vcpu); vcpu->arch.dr7 = DR7_FIXED_1; kvm_update_dr7(vcpu); @@ -9662,7 +9691,9 @@ int kvm_arch_hardware_setup(void *opaque) if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) supported_xss = 0; - cr4_reserved_bits = kvm_host_cr4_reserved_bits(&boot_cpu_data); +#define __kvm_cpu_cap_has(UNUSED_, f) kvm_cpu_cap_has(f) + cr4_reserved_bits = __cr4_reserved_bits(__kvm_cpu_cap_has, UNUSED_); +#undef __kvm_cpu_cap_has if (kvm_has_tsc_control) { /* @@ -9694,7 +9725,8 @@ int kvm_arch_check_processor_compat(void *opaque) WARN_ON(!irqs_disabled()); - if (kvm_host_cr4_reserved_bits(c) != cr4_reserved_bits) + if (__cr4_reserved_bits(cpu_has, c) != + __cr4_reserved_bits(cpu_has, &boot_cpu_data)) return -EIO; return ops->check_processor_compatibility(); diff --git a/arch/x86/lib/.gitignore b/arch/x86/lib/.gitignore index 8df89f0a3fe6..8ae0f93ecbfd 100644 --- a/arch/x86/lib/.gitignore +++ b/arch/x86/lib/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only inat-tables.c diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 859519f5b342..a51df516b87b 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1222,7 +1222,7 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) return 1; /* read, not present: */ - if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + if (unlikely(!vma_is_accessible(vma))) return 1; return 0; diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index e7bb483557c9..1bba16c5742b 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -467,7 +467,7 @@ bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn) * the physical memory. To access them they are temporarily mapped. */ unsigned long __ref init_memory_mapping(unsigned long start, - unsigned long end) + unsigned long end, pgprot_t prot) { struct map_range mr[NR_RANGE_MR]; unsigned long ret = 0; @@ -481,7 +481,8 @@ unsigned long __ref init_memory_mapping(unsigned long start, for (i = 0; i < nr_range; i++) ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, - mr[i].page_size_mask); + mr[i].page_size_mask, + prot); add_pfn_range_mapped(start >> PAGE_SHIFT, ret >> PAGE_SHIFT); @@ -521,7 +522,7 @@ static unsigned long __init init_range_memory_mapping( */ can_use_brk_pgt = max(start, (u64)pgt_buf_end<<PAGE_SHIFT) >= min(end, (u64)pgt_buf_top<<PAGE_SHIFT); - init_memory_mapping(start, end); + init_memory_mapping(start, end, PAGE_KERNEL); mapped_ram_size += end - start; can_use_brk_pgt = true; } @@ -661,7 +662,7 @@ void __init init_mem_mapping(void) #endif /* the ISA range is always mapped regardless of memory holes */ - init_memory_mapping(0, ISA_END_ADDRESS); + init_memory_mapping(0, ISA_END_ADDRESS, PAGE_KERNEL); /* Init the trampoline, possibly with KASLR memory offset */ init_trampoline(); diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index de73992b8432..4222a010057a 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -257,7 +257,8 @@ static inline int __is_kernel_text(unsigned long addr) unsigned long __init kernel_physical_mapping_init(unsigned long start, unsigned long end, - unsigned long page_size_mask) + unsigned long page_size_mask, + pgprot_t prot) { int use_pse = page_size_mask == (1<<PG_LEVEL_2M); unsigned long last_map_addr = end; @@ -819,12 +820,24 @@ void __init mem_init(void) #ifdef CONFIG_MEMORY_HOTPLUG int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; - return __add_pages(nid, start_pfn, nr_pages, restrictions); + /* + * The page tables were already mapped at boot so if the caller + * requests a different mapping type then we must change all the + * pages with __set_memory_prot(). + */ + if (params->pgprot.pgprot != PAGE_KERNEL.pgprot) { + ret = __set_memory_prot(start, nr_pages, params->pgprot); + if (ret) + return ret; + } + + return __add_pages(nid, start_pfn, nr_pages, params); } void arch_remove_memory(int nid, u64 start, u64 size, diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 0a14711d3a93..3b289c2f75cd 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -585,7 +585,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, */ static unsigned long __meminit phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, - unsigned long page_size_mask, bool init) + unsigned long page_size_mask, pgprot_t _prot, bool init) { unsigned long pages = 0, paddr_next; unsigned long paddr_last = paddr_end; @@ -595,7 +595,7 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, for (; i < PTRS_PER_PUD; i++, paddr = paddr_next) { pud_t *pud; pmd_t *pmd; - pgprot_t prot = PAGE_KERNEL; + pgprot_t prot = _prot; vaddr = (unsigned long)__va(paddr); pud = pud_page + pud_index(vaddr); @@ -644,9 +644,12 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, if (page_size_mask & (1<<PG_LEVEL_1G)) { pages++; spin_lock(&init_mm.page_table_lock); + + prot = __pgprot(pgprot_val(prot) | __PAGE_KERNEL_LARGE); + set_pte_init((pte_t *)pud, pfn_pte((paddr & PUD_MASK) >> PAGE_SHIFT, - PAGE_KERNEL_LARGE), + prot), init); spin_unlock(&init_mm.page_table_lock); paddr_last = paddr_next; @@ -669,7 +672,7 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, static unsigned long __meminit phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end, - unsigned long page_size_mask, bool init) + unsigned long page_size_mask, pgprot_t prot, bool init) { unsigned long vaddr, vaddr_end, vaddr_next, paddr_next, paddr_last; @@ -679,7 +682,7 @@ phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end, if (!pgtable_l5_enabled()) return phys_pud_init((pud_t *) p4d_page, paddr, paddr_end, - page_size_mask, init); + page_size_mask, prot, init); for (; vaddr < vaddr_end; vaddr = vaddr_next) { p4d_t *p4d = p4d_page + p4d_index(vaddr); @@ -702,13 +705,13 @@ phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end, if (!p4d_none(*p4d)) { pud = pud_offset(p4d, 0); paddr_last = phys_pud_init(pud, paddr, __pa(vaddr_end), - page_size_mask, init); + page_size_mask, prot, init); continue; } pud = alloc_low_page(); paddr_last = phys_pud_init(pud, paddr, __pa(vaddr_end), - page_size_mask, init); + page_size_mask, prot, init); spin_lock(&init_mm.page_table_lock); p4d_populate_init(&init_mm, p4d, pud, init); @@ -722,7 +725,7 @@ static unsigned long __meminit __kernel_physical_mapping_init(unsigned long paddr_start, unsigned long paddr_end, unsigned long page_size_mask, - bool init) + pgprot_t prot, bool init) { bool pgd_changed = false; unsigned long vaddr, vaddr_start, vaddr_end, vaddr_next, paddr_last; @@ -743,13 +746,13 @@ __kernel_physical_mapping_init(unsigned long paddr_start, paddr_last = phys_p4d_init(p4d, __pa(vaddr), __pa(vaddr_end), page_size_mask, - init); + prot, init); continue; } p4d = alloc_low_page(); paddr_last = phys_p4d_init(p4d, __pa(vaddr), __pa(vaddr_end), - page_size_mask, init); + page_size_mask, prot, init); spin_lock(&init_mm.page_table_lock); if (pgtable_l5_enabled()) @@ -778,10 +781,10 @@ __kernel_physical_mapping_init(unsigned long paddr_start, unsigned long __meminit kernel_physical_mapping_init(unsigned long paddr_start, unsigned long paddr_end, - unsigned long page_size_mask) + unsigned long page_size_mask, pgprot_t prot) { return __kernel_physical_mapping_init(paddr_start, paddr_end, - page_size_mask, true); + page_size_mask, prot, true); } /* @@ -796,7 +799,8 @@ kernel_physical_mapping_change(unsigned long paddr_start, unsigned long page_size_mask) { return __kernel_physical_mapping_init(paddr_start, paddr_end, - page_size_mask, false); + page_size_mask, PAGE_KERNEL, + false); } #ifndef CONFIG_NUMA @@ -843,11 +847,11 @@ static void update_end_of_memory_vars(u64 start, u64 size) } int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { int ret; - ret = __add_pages(nid, start_pfn, nr_pages, restrictions); + ret = __add_pages(nid, start_pfn, nr_pages, params); WARN_ON_ONCE(ret); /* update max_pfn, max_low_pfn and high_memory */ @@ -858,14 +862,14 @@ int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, } int arch_add_memory(int nid, u64 start, u64 size, - struct mhp_restrictions *restrictions) + struct mhp_params *params) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - init_memory_mapping(start, start + size); + init_memory_mapping(start, start + size, params->pgprot); - return add_pages(nid, start_pfn, nr_pages, restrictions); + return add_pages(nid, start_pfn, nr_pages, params); } #define PAGE_INUSE 0xFD diff --git a/arch/x86/mm/mm_internal.h b/arch/x86/mm/mm_internal.h index eeae142062ed..3f37b5c80bb3 100644 --- a/arch/x86/mm/mm_internal.h +++ b/arch/x86/mm/mm_internal.h @@ -12,7 +12,8 @@ void early_ioremap_page_table_range_init(void); unsigned long kernel_physical_mapping_init(unsigned long start, unsigned long end, - unsigned long page_size_mask); + unsigned long page_size_mask, + pgprot_t prot); unsigned long kernel_physical_mapping_change(unsigned long start, unsigned long end, unsigned long page_size_mask); diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 99f7a68738f0..59ba008504dc 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -25,11 +25,8 @@ nodemask_t numa_nodes_parsed __initdata; struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; EXPORT_SYMBOL(node_data); -static struct numa_meminfo numa_meminfo -#ifndef CONFIG_MEMORY_HOTPLUG -__initdata -#endif -; +static struct numa_meminfo numa_meminfo __initdata_or_meminfo; +static struct numa_meminfo numa_reserved_meminfo __initdata_or_meminfo; static int numa_distance_cnt; static u8 *numa_distance; @@ -169,6 +166,19 @@ void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi) } /** + * numa_move_tail_memblk - Move a numa_memblk from one numa_meminfo to another + * @dst: numa_meminfo to append block to + * @idx: Index of memblk to remove + * @src: numa_meminfo to remove memblk from + */ +static void __init numa_move_tail_memblk(struct numa_meminfo *dst, int idx, + struct numa_meminfo *src) +{ + dst->blk[dst->nr_blks++] = src->blk[idx]; + numa_remove_memblk_from(idx, src); +} + +/** * numa_add_memblk - Add one numa_memblk to numa_meminfo * @nid: NUMA node ID of the new memblk * @start: Start address of the new memblk @@ -237,14 +247,19 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) for (i = 0; i < mi->nr_blks; i++) { struct numa_memblk *bi = &mi->blk[i]; - /* make sure all blocks are inside the limits */ + /* move / save reserved memory ranges */ + if (!memblock_overlaps_region(&memblock.memory, + bi->start, bi->end - bi->start)) { + numa_move_tail_memblk(&numa_reserved_meminfo, i--, mi); + continue; + } + + /* make sure all non-reserved blocks are inside the limits */ bi->start = max(bi->start, low); bi->end = min(bi->end, high); - /* and there's no empty or non-exist block */ - if (bi->start >= bi->end || - !memblock_overlaps_region(&memblock.memory, - bi->start, bi->end - bi->start)) + /* and there's no empty block */ + if (bi->start >= bi->end) numa_remove_memblk_from(i--, mi); } @@ -881,16 +896,38 @@ EXPORT_SYMBOL(cpumask_of_node); #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ -#ifdef CONFIG_MEMORY_HOTPLUG -int memory_add_physaddr_to_nid(u64 start) +#ifdef CONFIG_NUMA_KEEP_MEMINFO +static int meminfo_to_nid(struct numa_meminfo *mi, u64 start) { - struct numa_meminfo *mi = &numa_meminfo; - int nid = mi->blk[0].nid; int i; for (i = 0; i < mi->nr_blks; i++) if (mi->blk[i].start <= start && mi->blk[i].end > start) - nid = mi->blk[i].nid; + return mi->blk[i].nid; + return NUMA_NO_NODE; +} + +int phys_to_target_node(phys_addr_t start) +{ + int nid = meminfo_to_nid(&numa_meminfo, start); + + /* + * Prefer online nodes, but if reserved memory might be + * hot-added continue the search with reserved ranges. + */ + if (nid != NUMA_NO_NODE) + return nid; + + return meminfo_to_nid(&numa_reserved_meminfo, start); +} +EXPORT_SYMBOL_GPL(phys_to_target_node); + +int memory_add_physaddr_to_nid(u64 start) +{ + int nid = meminfo_to_nid(&numa_meminfo, start); + + if (nid == NUMA_NO_NODE) + nid = numa_meminfo.blk[0].nid; return nid; } EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 6d5424069e2b..59eca6a94ce7 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -1795,6 +1795,19 @@ static inline int cpa_clear_pages_array(struct page **pages, int numpages, CPA_PAGES_ARRAY, pages); } +/* + * _set_memory_prot is an internal helper for callers that have been passed + * a pgprot_t value from upper layers and a reservation has already been taken. + * If you want to set the pgprot to a specific page protocol, use the + * set_memory_xx() functions. + */ +int __set_memory_prot(unsigned long addr, int numpages, pgprot_t prot) +{ + return change_page_attr_set_clr(&addr, numpages, prot, + __pgprot(~pgprot_val(prot)), 0, 0, + NULL); +} + int _set_memory_uc(unsigned long addr, int numpages) { /* diff --git a/arch/x86/mm/pkeys.c b/arch/x86/mm/pkeys.c index c6f84c0b5d7a..8873ed1438a9 100644 --- a/arch/x86/mm/pkeys.c +++ b/arch/x86/mm/pkeys.c @@ -63,7 +63,7 @@ int __execute_only_pkey(struct mm_struct *mm) static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma) { /* Do this check first since the vm_flags should be hot */ - if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC) + if ((vma->vm_flags & VM_ACCESS_FLAGS) != VM_EXEC) return false; if (vma_pkey(vma) != vma->vm_mm->context.execute_only_pkey) return false; diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 211bb9358b73..c5e393f8bb3f 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -202,7 +202,7 @@ virt_to_phys_or_null_size(void *va, unsigned long size) int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - unsigned long pfn, text, pf; + unsigned long pfn, text, pf, rodata; struct page *page; unsigned npages; pgd_t *pgd = efi_mm.pgd; @@ -256,7 +256,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */ - npages = (__end_rodata_aligned - _text) >> PAGE_SHIFT; + npages = (_etext - _text) >> PAGE_SHIFT; text = __pa(_text); pfn = text >> PAGE_SHIFT; @@ -266,6 +266,14 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) return 1; } + npages = (__end_rodata - __start_rodata) >> PAGE_SHIFT; + rodata = __pa(__start_rodata); + pfn = rodata >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, rodata, npages, pf)) { + pr_err("Failed to map kernel rodata 1:1\n"); + return 1; + } + return 0; } @@ -638,7 +646,7 @@ efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, phys_vendor = virt_to_phys_or_null(vnd); phys_data = virt_to_phys_or_null_size(data, data_size); - if (!phys_name || !phys_data) + if (!phys_name || (data && !phys_data)) status = EFI_INVALID_PARAMETER; else status = efi_thunk(set_variable, phys_name, phys_vendor, @@ -669,7 +677,7 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, phys_vendor = virt_to_phys_or_null(vnd); phys_data = virt_to_phys_or_null_size(data, data_size); - if (!phys_name || !phys_data) + if (!phys_name || (data && !phys_data)) status = EFI_INVALID_PARAMETER; else status = efi_thunk(set_variable, phys_name, phys_vendor, diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index 607f58147311..c60255da5a6c 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -352,7 +352,8 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, if (type == EFI_MEMORY_MAPPED_IO) return ioremap(phys_addr, size); - last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); + last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size, + PAGE_KERNEL); if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { unsigned long top = last_map_pfn << PAGE_SHIFT; efi_ioremap(top, size - (top - phys_addr), type, attribute); diff --git a/arch/x86/realmode/rm/.gitignore b/arch/x86/realmode/rm/.gitignore index b6ed3a2555cb..6c3464f46166 100644 --- a/arch/x86/realmode/rm/.gitignore +++ b/arch/x86/realmode/rm/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only pasyms.h realmode.lds realmode.relocs diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore index be0ed065249b..d36dc7cf9115 100644 --- a/arch/x86/tools/.gitignore +++ b/arch/x86/tools/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only relocs diff --git a/arch/x86/um/asm/processor.h b/arch/x86/um/asm/processor.h index 593d5f3902bd..478710384b34 100644 --- a/arch/x86/um/asm/processor.h +++ b/arch/x86/um/asm/processor.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_PROCESSOR_H #define __UM_PROCESSOR_H +#include <linux/time-internal.h> /* include faultinfo structure */ #include <sysdep/faultinfo.h> @@ -21,12 +22,19 @@ #include <asm/user.h> /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) +static __always_inline void rep_nop(void) { __asm__ __volatile__("rep;nop": : :"memory"); } -#define cpu_relax() rep_nop() +static __always_inline void cpu_relax(void) +{ + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) + time_travel_ndelay(1); + else + rep_nop(); +} #define task_pt_regs(t) (&(t)->thread.regs) diff --git a/arch/x86/um/asm/vm-flags.h b/arch/x86/um/asm/vm-flags.h index 7c297e9e2413..df7a3896f5dd 100644 --- a/arch/x86/um/asm/vm-flags.h +++ b/arch/x86/um/asm/vm-flags.h @@ -9,17 +9,11 @@ #ifdef CONFIG_X86_32 -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC #else -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_DATA_FLAGS_EXEC) #endif #endif diff --git a/arch/x86/um/vdso/.gitignore b/arch/x86/um/vdso/.gitignore index f8b69d84238e..652e31d82582 100644 --- a/arch/x86/um/vdso/.gitignore +++ b/arch/x86/um/vdso/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vdso.lds diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 33b0e20df7fc..1a2d8a50dac4 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -985,7 +985,7 @@ void xen_enable_syscall(void) #endif /* CONFIG_X86_64 */ } -void __init xen_pvmmu_arch_setup(void) +static void __init xen_pvmmu_arch_setup(void) { HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c index 802ee5bba66c..8fb8a50a28b4 100644 --- a/arch/x86/xen/smp_pv.c +++ b/arch/x86/xen/smp_pv.c @@ -53,6 +53,7 @@ static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 }; static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 }; static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id); +void asm_cpu_bringup_and_idle(void); static void cpu_bringup(void) { @@ -309,7 +310,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) * pointing just below where pt_regs would be if it were a normal * kernel entry. */ - ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; + ctxt->user_regs.eip = (unsigned long)asm_cpu_bringup_and_idle; ctxt->flags = VGCF_IN_KERNEL; ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ ctxt->user_regs.ds = __USER_DS; diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 1d0cee3163e4..1ba601df3a37 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -35,7 +35,11 @@ SYM_CODE_START(startup_xen) rep __ASM_SIZE(stos) mov %_ASM_SI, xen_start_info - mov $init_thread_union+THREAD_SIZE, %_ASM_SP +#ifdef CONFIG_X86_64 + mov initial_stack(%rip), %rsp +#else + mov initial_stack, %esp +#endif #ifdef CONFIG_X86_64 /* Set up %gs. @@ -51,9 +55,19 @@ SYM_CODE_START(startup_xen) wrmsr #endif - jmp xen_start_kernel + call xen_start_kernel SYM_CODE_END(startup_xen) __FINIT + +#ifdef CONFIG_XEN_PV_SMP +.pushsection .text +SYM_CODE_START(asm_cpu_bringup_and_idle) + UNWIND_HINT_EMPTY + + call cpu_bringup_and_idle +SYM_CODE_END(asm_cpu_bringup_and_idle) +.popsection +#endif #endif .pushsection .text diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 32ee759a3fda..3a9f1e80394a 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -6,7 +6,7 @@ config XTENSA select ARCH_HAS_DMA_PREP_COHERENT if MMU select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU - select ARCH_HAS_UNCACHED_SEGMENT if MMU + select ARCH_HAS_DMA_SET_UNCACHED if MMU select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_WANT_FRAME_POINTERS @@ -122,7 +122,7 @@ config XTENSA_VARIANT_CUSTOM_NAME help Provide the name of a custom Xtensa processor variant. This CORENAME selects arch/xtensa/variant/CORENAME. - Dont forget you have to select MMU if you have one. + Don't forget you have to select MMU if you have one. config XTENSA_VARIANT_NAME string diff --git a/arch/xtensa/boot/.gitignore b/arch/xtensa/boot/.gitignore index 38177c7ebcab..615f1f741a03 100644 --- a/arch/xtensa/boot/.gitignore +++ b/arch/xtensa/boot/.gitignore @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only uImage zImage.redboot diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index efb91bfda2b4..1a14d38d9b33 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -14,7 +14,6 @@ HOSTFLAGS += -Iarch/$(ARCH)/boot/include BIG_ENDIAN := $(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#") -export ccflags-y export BIG_ENDIAN subdir-y := lib diff --git a/arch/xtensa/boot/boot-elf/.gitignore b/arch/xtensa/boot/boot-elf/.gitignore index 5ff8fbb8561b..7473404500cc 100644 --- a/arch/xtensa/boot/boot-elf/.gitignore +++ b/arch/xtensa/boot/boot-elf/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only boot.lds diff --git a/arch/xtensa/boot/lib/.gitignore b/arch/xtensa/boot/lib/.gitignore index 1629a6167755..805a8249252a 100644 --- a/arch/xtensa/boot/lib/.gitignore +++ b/arch/xtensa/boot/lib/.gitignore @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only inffast.c inflate.c inftrees.c diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index f4771c29c7e9..37ce25ef92d6 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -203,8 +203,5 @@ static inline unsigned long ___pa(unsigned long va) #endif /* __ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include <asm-generic/memory_model.h> #endif /* _XTENSA_PAGE_H */ diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 27ac17c9da09..8be0c0568c50 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -266,7 +266,6 @@ static inline void paging_init(void) { } static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITABLE; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_WRITABLE | _PAGE_HW_WRITE); return pte; } @@ -280,8 +279,6 @@ static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITABLE; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) - { return pte; } #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) & ~_PAGE_CA_MASK)) diff --git a/arch/xtensa/kernel/.gitignore b/arch/xtensa/kernel/.gitignore index c5f676c3c224..bbb90f92d051 100644 --- a/arch/xtensa/kernel/.gitignore +++ b/arch/xtensa/kernel/.gitignore @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only vmlinux.lds diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 72b6222daa0b..17c4384f8495 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -88,18 +88,12 @@ void arch_dma_prep_coherent(struct page *page, size_t size) /* * Memory caching is platform-dependent in noMMU xtensa configurations. - * The following two functions should be implemented in platform code - * in order to enable coherent DMA memory operations when CONFIG_MMU is not - * enabled. + * This function should be implemented in platform code in order to enable + * coherent DMA memory operations when CONFIG_MMU is not enabled. */ #ifdef CONFIG_MMU -void *uncached_kernel_address(void *p) +void *arch_dma_set_uncached(void *p, size_t size) { return p + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR; } - -void *cached_kernel_address(void *p) -{ - return p + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; -} #endif /* CONFIG_MMU */ diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index 83b244ce61ee..cd85a7a2722b 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -53,16 +53,12 @@ static void system_flush_invalidate_dcache_range(unsigned long start, #define IPI_IRQ 0 static irqreturn_t ipi_interrupt(int irq, void *dev_id); -static struct irqaction ipi_irqaction = { - .handler = ipi_interrupt, - .flags = IRQF_PERCPU, - .name = "ipi", -}; void ipi_init(void) { unsigned irq = irq_create_mapping(NULL, IPI_IRQ); - setup_irq(irq, &ipi_irqaction); + if (request_irq(irq, ipi_interrupt, IRQF_PERCPU, "ipi", NULL)) + pr_err("Failed to request irq %u (ipi)\n", irq); } static inline unsigned int get_core_count(void) diff --git a/arch/xtensa/kernel/syscalls/syscallhdr.sh b/arch/xtensa/kernel/syscalls/syscallhdr.sh index d37db641ca31..eebfb8a8ace6 100644 --- a/arch/xtensa/kernel/syscalls/syscallhdr.sh +++ b/arch/xtensa/kernel/syscalls/syscallhdr.sh @@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( printf "#define __NR_syscalls\t%s\n" "${nxt}" printf "#endif\n" printf "\n" - printf "#endif /* %s */" "${fileguard}" + printf "#endif /* %s */\n" "${fileguard}" ) > "$out" diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 69db8c93c1f9..77971fe4cc95 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -128,12 +128,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction timer_irqaction = { - .handler = timer_interrupt, - .flags = IRQF_TIMER, - .name = "timer", -}; - void local_timer_setup(unsigned cpu) { struct ccount_timer *timer = &per_cpu(ccount_timer, cpu); @@ -184,6 +178,8 @@ static inline void calibrate_ccount(void) void __init time_init(void) { + int irq; + of_clk_init(NULL); #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT pr_info("Calibrating CPU frequency "); @@ -199,7 +195,9 @@ void __init time_init(void) __func__); clocksource_register_hz(&ccount_clocksource, ccount_freq); local_timer_setup(0); - setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction); + irq = this_cpu_ptr(&ccount_timer)->evt.irq; + if (request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL)) + pr_err("Failed to request irq %d (timer)\n", irq); sched_clock_register(ccount_sched_clock_read, 32, ccount_freq); timer_probe(); } |