diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 14:39:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 14:39:22 -0400 |
commit | 948869fa9f391664cfe008fa9968a1110bfd14fd (patch) | |
tree | 8cab813f6064d9bfa03fdfe6524277ca41e65305 /arch/mips/kernel/reset.c | |
parent | 2a56bb596b2c1fb612f9988afda9655c8c872a6e (diff) | |
parent | a5075e6226c42a8e64ea1b862eec7747dc46cb32 (diff) |
Merge tag 'mips_4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips
Pull MIPS updates from James Hogan:
"These are the main MIPS changes for 4.17. Rough overview:
(1) generic platform: Add support for Microsemi Ocelot SoCs
(2) crypto: Add CRC32 and CRC32C HW acceleration module
(3) Various cleanups and misc improvements
More detailed summary:
Miscellaneous:
- hang more efficiently on halt/powerdown/restart
- pm-cps: Block system suspend when a JTAG probe is present
- expand make help text for generic defconfigs
- refactor handling of legacy defconfigs
- determine the entry point from the ELF file header to fix microMIPS
for certain toolchains
- introduce isa-rev.h for MIPS_ISA_REV and use to simplify other code
Minor cleanups:
- DTS: boston/ci20: Unit name cleanups and correction
- kdump: Make the default for PHYSICAL_START always 64-bit
- constify gpio_led in Alchemy, AR7, and TXX9
- silence a couple of W=1 warnings
- remove duplicate includes
Platform support:
Generic platform:
- add support for Microsemi Ocelot
- dt-bindings: Add vendor prefix for Microsemi Corporation
- dt-bindings: Add bindings for Microsemi SoCs
- add ocelot SoC & PCB123 board DTS files
- MAINTAINERS: Add entry for Microsemi MIPS SoCs
- enable crc32-mips on r6 configs
ath79:
- fix AR724X_PLL_REG_PCIE_CONFIG offset
BCM47xx:
- firmware: Use mac_pton() for MAC address parsing
- add Luxul XAP1500/XWR1750 WiFi LEDs
- use standard reset button for Luxul XWR-1750
BMIPS:
- enable CONFIG_BRCMSTB_PM in bmips_stb_defconfig for build coverage
- add STB PM, wake-up timer, watchdog DT nodes
Octeon:
- drop '.' after newlines in printk calls
ralink:
- pci-mt7621: Enable PCIe on MT7688"
* tag 'mips_4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips: (37 commits)
MIPS: BCM47XX: Use standard reset button for Luxul XWR-1750
MIPS: BCM47XX: Add Luxul XAP1500/XWR1750 WiFi LEDs
MIPS: Make the default for PHYSICAL_START always 64-bit
MIPS: Use the entry point from the ELF file header
MAINTAINERS: Add entry for Microsemi MIPS SoCs
MIPS: generic: Add support for Microsemi Ocelot
MIPS: mscc: Add ocelot PCB123 device tree
MIPS: mscc: Add ocelot dtsi
dt-bindings: mips: Add bindings for Microsemi SoCs
dt-bindings: Add vendor prefix for Microsemi Corporation
MIPS: ath79: Fix AR724X_PLL_REG_PCIE_CONFIG offset
MIPS: pci-mt7620: Enable PCIe on MT7688
MIPS: pm-cps: Block system suspend when a JTAG probe is present
MIPS: VDSO: Replace __mips_isa_rev with MIPS_ISA_REV
MIPS: BPF: Replace __mips_isa_rev with MIPS_ISA_REV
MIPS: cpu-features.h: Replace __mips_isa_rev with MIPS_ISA_REV
MIPS: Introduce isa-rev.h to define MIPS_ISA_REV
MIPS: Hang more efficiently on halt/powerdown/restart
FIRMWARE: bcm47xx_nvram: Replace mac address parsing
MIPS: BMIPS: Add Broadcom STB watchdog nodes
...
Diffstat (limited to 'arch/mips/kernel/reset.c')
-rw-r--r-- | arch/mips/kernel/reset.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 7c746d3458e7..6288780b779e 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c | |||
@@ -13,6 +13,9 @@ | |||
13 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | 15 | ||
16 | #include <asm/compiler.h> | ||
17 | #include <asm/idle.h> | ||
18 | #include <asm/mipsregs.h> | ||
16 | #include <asm/reboot.h> | 19 | #include <asm/reboot.h> |
17 | 20 | ||
18 | /* | 21 | /* |
@@ -26,6 +29,62 @@ void (*pm_power_off)(void); | |||
26 | 29 | ||
27 | EXPORT_SYMBOL(pm_power_off); | 30 | EXPORT_SYMBOL(pm_power_off); |
28 | 31 | ||
32 | static void machine_hang(void) | ||
33 | { | ||
34 | /* | ||
35 | * We're hanging the system so we don't want to be interrupted anymore. | ||
36 | * Any interrupt handlers that ran would at best be useless & at worst | ||
37 | * go awry because the system isn't in a functional state. | ||
38 | */ | ||
39 | local_irq_disable(); | ||
40 | |||
41 | /* | ||
42 | * Mask all interrupts, giving us a better chance of remaining in the | ||
43 | * low power wait state. | ||
44 | */ | ||
45 | clear_c0_status(ST0_IM); | ||
46 | |||
47 | while (true) { | ||
48 | if (cpu_has_mips_r) { | ||
49 | /* | ||
50 | * We know that the wait instruction is supported so | ||
51 | * make use of it directly, leaving interrupts | ||
52 | * disabled. | ||
53 | */ | ||
54 | asm volatile( | ||
55 | ".set push\n\t" | ||
56 | ".set " MIPS_ISA_ARCH_LEVEL "\n\t" | ||
57 | "wait\n\t" | ||
58 | ".set pop"); | ||
59 | } else if (cpu_wait) { | ||
60 | /* | ||
61 | * Try the cpu_wait() callback. This isn't ideal since | ||
62 | * it'll re-enable interrupts, but that ought to be | ||
63 | * harmless given that they're all masked. | ||
64 | */ | ||
65 | cpu_wait(); | ||
66 | local_irq_disable(); | ||
67 | } else { | ||
68 | /* | ||
69 | * We're going to burn some power running round the | ||
70 | * loop, but we don't really have a choice. This isn't | ||
71 | * a path we should expect to run for long during | ||
72 | * typical use anyway. | ||
73 | */ | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * In most modern MIPS CPUs interrupts will cause the wait | ||
78 | * instruction to graduate even when disabled, and in some | ||
79 | * cases even when masked. In order to prevent a timer | ||
80 | * interrupt from continuously taking us out of the low power | ||
81 | * wait state, we clear any pending timer interrupt here. | ||
82 | */ | ||
83 | if (cpu_has_counter) | ||
84 | write_c0_compare(0); | ||
85 | } | ||
86 | } | ||
87 | |||
29 | void machine_restart(char *command) | 88 | void machine_restart(char *command) |
30 | { | 89 | { |
31 | if (_machine_restart) | 90 | if (_machine_restart) |
@@ -38,8 +97,7 @@ void machine_restart(char *command) | |||
38 | do_kernel_restart(command); | 97 | do_kernel_restart(command); |
39 | mdelay(1000); | 98 | mdelay(1000); |
40 | pr_emerg("Reboot failed -- System halted\n"); | 99 | pr_emerg("Reboot failed -- System halted\n"); |
41 | local_irq_disable(); | 100 | machine_hang(); |
42 | while (1); | ||
43 | } | 101 | } |
44 | 102 | ||
45 | void machine_halt(void) | 103 | void machine_halt(void) |
@@ -51,8 +109,7 @@ void machine_halt(void) | |||
51 | preempt_disable(); | 109 | preempt_disable(); |
52 | smp_send_stop(); | 110 | smp_send_stop(); |
53 | #endif | 111 | #endif |
54 | local_irq_disable(); | 112 | machine_hang(); |
55 | while (1); | ||
56 | } | 113 | } |
57 | 114 | ||
58 | void machine_power_off(void) | 115 | void machine_power_off(void) |
@@ -64,6 +121,5 @@ void machine_power_off(void) | |||
64 | preempt_disable(); | 121 | preempt_disable(); |
65 | smp_send_stop(); | 122 | smp_send_stop(); |
66 | #endif | 123 | #endif |
67 | local_irq_disable(); | 124 | machine_hang(); |
68 | while (1); | ||
69 | } | 125 | } |