| .. | .. |
|---|
| 50 | 50 | #endif |
|---|
| 51 | 51 | |
|---|
| 52 | 52 | #include <linux/uaccess.h> |
|---|
| 53 | +#include <linux/cpuhotplug.h> |
|---|
| 53 | 54 | |
|---|
| 54 | 55 | #include "fiq_debugger.h" |
|---|
| 55 | 56 | #include "fiq_debugger_priv.h" |
|---|
| .. | .. |
|---|
| 148 | 149 | static bool initial_console_enable; |
|---|
| 149 | 150 | #endif |
|---|
| 150 | 151 | |
|---|
| 151 | | -#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE |
|---|
| 152 | | -static struct fiq_debugger_state *state_tf; |
|---|
| 153 | | -#endif |
|---|
| 154 | | - |
|---|
| 152 | +static struct fiq_debugger_state *g_state; |
|---|
| 155 | 153 | static bool fiq_kgdb_enable; |
|---|
| 156 | 154 | static bool fiq_debugger_disable; |
|---|
| 157 | 155 | |
|---|
| .. | .. |
|---|
| 263 | 261 | { |
|---|
| 264 | 262 | char buf[512]; |
|---|
| 265 | 263 | size_t len; |
|---|
| 266 | | - struct kmsg_dumper_iter dumper = { .active = true }; |
|---|
| 264 | + struct kmsg_dumper dumper = { .active = true }; |
|---|
| 267 | 265 | |
|---|
| 268 | | - kmsg_dump_rewind(&dumper); |
|---|
| 269 | | - while (kmsg_dump_get_line(&dumper, true, buf, |
|---|
| 266 | + |
|---|
| 267 | + kmsg_dump_rewind_nolock(&dumper); |
|---|
| 268 | + while (kmsg_dump_get_line_nolock(&dumper, true, buf, |
|---|
| 270 | 269 | sizeof(buf) - 1, &len)) { |
|---|
| 271 | 270 | buf[len] = 0; |
|---|
| 272 | 271 | fiq_debugger_puts(state, buf); |
|---|
| .. | .. |
|---|
| 1076 | 1075 | #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE |
|---|
| 1077 | 1076 | void fiq_debugger_fiq(void *regs, u32 cpu) |
|---|
| 1078 | 1077 | { |
|---|
| 1079 | | - struct fiq_debugger_state *state = state_tf; |
|---|
| 1078 | + struct fiq_debugger_state *state = g_state; |
|---|
| 1080 | 1079 | bool need_irq; |
|---|
| 1081 | 1080 | |
|---|
| 1082 | 1081 | if (!state) |
|---|
| .. | .. |
|---|
| 1443 | 1442 | return 0; |
|---|
| 1444 | 1443 | } |
|---|
| 1445 | 1444 | |
|---|
| 1445 | +static int fiq_debugger_cpu_offine_migrate_irq(unsigned int cpu) |
|---|
| 1446 | +{ |
|---|
| 1447 | + if (g_state && cpu == g_state->current_cpu) { |
|---|
| 1448 | + unsigned int new_cpu = cpumask_any_but(cpu_online_mask, cpu); |
|---|
| 1449 | + |
|---|
| 1450 | + if (new_cpu < nr_cpu_ids) |
|---|
| 1451 | + g_state->current_cpu = new_cpu; |
|---|
| 1452 | + } |
|---|
| 1453 | + |
|---|
| 1454 | + return 0; |
|---|
| 1455 | +} |
|---|
| 1456 | + |
|---|
| 1446 | 1457 | static int fiq_debugger_probe(struct platform_device *pdev) |
|---|
| 1447 | 1458 | { |
|---|
| 1448 | 1459 | int ret; |
|---|
| .. | .. |
|---|
| 1450 | 1461 | struct fiq_debugger_state *state; |
|---|
| 1451 | 1462 | int fiq; |
|---|
| 1452 | 1463 | int uart_irq; |
|---|
| 1464 | + enum cpuhp_state cs = -1; |
|---|
| 1453 | 1465 | |
|---|
| 1454 | 1466 | if (pdev->id >= MAX_FIQ_DEBUGGER_PORTS) |
|---|
| 1455 | 1467 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1555 | 1567 | pr_err("%s: could not install nmi irq handler\n", __func__); |
|---|
| 1556 | 1568 | irq_clear_status_flags(state->uart_irq, IRQ_NOAUTOEN); |
|---|
| 1557 | 1569 | ret = request_irq(state->uart_irq, fiq_debugger_uart_irq, |
|---|
| 1558 | | - IRQF_NO_SUSPEND, "debug", state); |
|---|
| 1570 | + IRQF_NO_SUSPEND | IRQF_NOBALANCING, "debug", state); |
|---|
| 1559 | 1571 | } else { |
|---|
| 1560 | 1572 | enable_nmi(state->uart_irq); |
|---|
| 1561 | 1573 | } |
|---|
| .. | .. |
|---|
| 1569 | 1581 | * can. |
|---|
| 1570 | 1582 | */ |
|---|
| 1571 | 1583 | enable_irq_wake(state->uart_irq); |
|---|
| 1584 | + |
|---|
| 1585 | + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, |
|---|
| 1586 | + "soc/fiq_debugger", |
|---|
| 1587 | + NULL, |
|---|
| 1588 | + fiq_debugger_cpu_offine_migrate_irq); |
|---|
| 1589 | + if (ret < 0) |
|---|
| 1590 | + pr_err("%s: could not setup cpu offine handler\n", __func__); |
|---|
| 1591 | + else |
|---|
| 1592 | + cs = ret; |
|---|
| 1572 | 1593 | } |
|---|
| 1573 | 1594 | |
|---|
| 1574 | 1595 | if (state->signal_irq >= 0) { |
|---|
| .. | .. |
|---|
| 1599 | 1620 | if (state->no_sleep) |
|---|
| 1600 | 1621 | fiq_debugger_handle_wakeup(state); |
|---|
| 1601 | 1622 | |
|---|
| 1602 | | -#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE |
|---|
| 1603 | | - state_tf = state; |
|---|
| 1604 | | -#endif |
|---|
| 1605 | | - |
|---|
| 1606 | 1623 | if (pdata->uart_init) { |
|---|
| 1607 | 1624 | ret = pdata->uart_init(pdev); |
|---|
| 1608 | 1625 | if (ret) |
|---|
| .. | .. |
|---|
| 1629 | 1646 | |
|---|
| 1630 | 1647 | /* switch to cpu0 default */ |
|---|
| 1631 | 1648 | fiq_debugger_switch_cpu(state, 0); |
|---|
| 1632 | | - |
|---|
| 1649 | + g_state = state; |
|---|
| 1633 | 1650 | return 0; |
|---|
| 1634 | 1651 | |
|---|
| 1635 | 1652 | err_register_irq: |
|---|
| .. | .. |
|---|
| 1640 | 1657 | clk_disable(state->clk); |
|---|
| 1641 | 1658 | if (state->clk) |
|---|
| 1642 | 1659 | clk_put(state->clk); |
|---|
| 1660 | + if (cs >= 0) |
|---|
| 1661 | + cpuhp_remove_state_nocalls(cs); |
|---|
| 1643 | 1662 | wakeup_source_remove(&state->debugger_wake_src); |
|---|
| 1644 | 1663 | __pm_relax(&state->debugger_wake_src); |
|---|
| 1645 | 1664 | platform_set_drvdata(pdev, NULL); |
|---|