diff options
| author | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 09:55:01 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 11:08:21 -0400 |
| commit | 4617721c502b2ddaa4e324e86da4997edf738fa5 (patch) | |
| tree | 350aa83b47da0b574a814795392b20b0bed83cbc /drivers/pinctrl/mediatek/mtk-eint.h | |
| download | linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.tar.gz linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.zip | |
ftrace: Synchronize the initialization of ftrace_opsgrafted
There's some internal state that ftrace_ops needs to have set, but since
it can be declared outside of the ftrace.c code, it calls
ftrace_ops_init() on the ops in every global function. The issue is that
if two tasks call it on the same ops at the same time it is possible to
have the initialization of one corrupt the initialization of the other
call.
Create a ops_mutex to use to synchronize every initialization of the
ftrace_ops. The mutex is taken within checking the ftrace_ops flag that
states it was initializied but the flag is checked again after the mutex
has been taken. Checking first outside the mutex allows it to shortcut
having to take the mutex. But then the check needs to be done again after
the mute is taken in case of races.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home
Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock")
Reported-by: sashiko-bot@kernel.org
Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'drivers/pinctrl/mediatek/mtk-eint.h')
| -rw-r--r-- | drivers/pinctrl/mediatek/mtk-eint.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h new file mode 100644 index 000000000..3cdd6f631 --- /dev/null +++ b/drivers/pinctrl/mediatek/mtk-eint.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2014-2025 MediaTek Inc. + * + * Author: Maoguang Meng <maoguang.meng@mediatek.com> + * Sean Wang <sean.wang@mediatek.com> + * Hao Chang <ot_chhao.chang@mediatek.com> + * Qingliang Li <qingliang.li@mediatek.com> + */ +#ifndef __MTK_EINT_H +#define __MTK_EINT_H + +#include <linux/irqdomain.h> + +struct mtk_eint_regs { + unsigned int stat; + unsigned int ack; + unsigned int mask; + unsigned int mask_set; + unsigned int mask_clr; + unsigned int sens; + unsigned int sens_set; + unsigned int sens_clr; + unsigned int soft; + unsigned int soft_set; + unsigned int soft_clr; + unsigned int pol; + unsigned int pol_set; + unsigned int pol_clr; + unsigned int dom_en; + unsigned int dbnc_ctrl; + unsigned int dbnc_set; + unsigned int dbnc_clr; +}; + +struct mtk_eint_hw { + u8 port_mask; + u8 ports; + unsigned int ap_num; + unsigned int db_cnt; + const unsigned int *db_time; +}; + +struct mtk_eint_pin { + u16 number; + u8 instance; + u8 index; + bool debounce; + bool dual_edge; +}; + +extern const unsigned int debounce_time_mt2701[]; +extern const unsigned int debounce_time_mt6765[]; +extern const unsigned int debounce_time_mt6795[]; +extern const unsigned int debounce_time_mt6878[]; + +struct mtk_eint; + +struct mtk_eint_xt { + int (*get_gpio_n)(void *data, unsigned long eint_n, + unsigned int *gpio_n, + struct gpio_chip **gpio_chip); + int (*get_gpio_state)(void *data, unsigned long eint_n); + int (*set_gpio_as_eint)(void *data, unsigned long eint_n); +}; + +struct mtk_eint { + struct device *dev; + void __iomem **base; + int nbase; + u16 *base_pin_num; + struct irq_domain *domain; + int irq; + + int *dual_edge; + u16 **pin_list; + u32 **wake_mask; + u32 **cur_mask; + + /* Used to fit into various EINT device */ + const struct mtk_eint_hw *hw; + const struct mtk_eint_regs *regs; + struct mtk_eint_pin *pins; + u16 num_db_time; + + /* Used to fit into various pinctrl device */ + void *pctl; + const struct mtk_eint_xt *gpio_xlate; +}; + +#if IS_ENABLED(CONFIG_EINT_MTK) +int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin); +int mtk_eint_do_suspend(struct mtk_eint *eint); +int mtk_eint_do_resume(struct mtk_eint *eint); +int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n, + unsigned int debounce); +int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n); + +#else +static inline int mtk_eint_do_init(struct mtk_eint *eint, + struct mtk_eint_pin *eint_pin) +{ + return -EOPNOTSUPP; +} + +static inline int mtk_eint_do_suspend(struct mtk_eint *eint) +{ + return -EOPNOTSUPP; +} + +static inline int mtk_eint_do_resume(struct mtk_eint *eint) +{ + return -EOPNOTSUPP; +} + +static inline int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n, + unsigned int debounce) +{ + return -EOPNOTSUPP; +} + +static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n) +{ + return -EOPNOTSUPP; +} +#endif +#endif /* __MTK_EINT_H */ |
