diff options
author | Hans de Goede <j.w.r.degoede@gmail.com> | 2017-10-19 13:16:19 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2017-11-10 13:14:02 +0100 |
commit | af0ab55ffe2467fab82bc0909e469cba7701fac7 (patch) | |
tree | 0359ca061ca4a0612c9ee67c265011dd83b026d6 | |
parent | c16c4ba7250b681e103126c54481a8b17c073758 (diff) |
x86/platform/intel/iosf_mbi: Add unlocked PMIC bus access notifier unregister
For race free unregistration drivers may need to acquire PMIC bus access
through iosf_mbi_punit_acquire() and then (un)register the notifier without
dropping the lock.
This commit adds an unlocked variant of
iosf_mbi_unregister_pmic_bus_access_notifier for this use case.
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171019111620.26761-2-hdegoede@redhat.com
-rw-r--r-- | arch/x86/include/asm/iosf_mbi.h | 25 | ||||
-rw-r--r-- | arch/x86/platform/intel/iosf_mbi.c | 19 |
2 files changed, 42 insertions, 2 deletions
diff --git a/arch/x86/include/asm/iosf_mbi.h b/arch/x86/include/asm/iosf_mbi.h index c313cac36f56..eb959cd77994 100644 --- a/arch/x86/include/asm/iosf_mbi.h +++ b/arch/x86/include/asm/iosf_mbi.h @@ -146,6 +146,18 @@ int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb); int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); /** + * iosf_mbi_unregister_pmic_bus_access_notifier_unlocked - Unregister PMIC bus + * notifier, unlocked + * + * Like iosf_mbi_unregister_pmic_bus_access_notifier(), but for use when the + * caller has already called iosf_mbi_punit_acquire() itself. + * + * @nb: notifier_block to unregister + */ +int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( + struct notifier_block *nb); + +/** * iosf_mbi_call_pmic_bus_access_notifier_chain - Call PMIC bus notifier chain * * @val: action to pass into listener's notifier_call function @@ -153,6 +165,11 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); */ int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v); +/** + * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired. + */ +void iosf_mbi_assert_punit_acquired(void); + #else /* CONFIG_IOSF_MBI is not enabled */ static inline bool iosf_mbi_available(void) @@ -196,12 +213,20 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) return 0; } +static inline int +iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb) +{ + return 0; +} + static inline int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) { return 0; } +static inline void iosf_mbi_assert_punit_acquired(void) {} + #endif /* CONFIG_IOSF_MBI */ #endif /* IOSF_MBI_SYMS_H */ diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c index a952ac199741..6f37a2137a79 100644 --- a/arch/x86/platform/intel/iosf_mbi.c +++ b/arch/x86/platform/intel/iosf_mbi.c @@ -218,14 +218,23 @@ int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(iosf_mbi_register_pmic_bus_access_notifier); +int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( + struct notifier_block *nb) +{ + iosf_mbi_assert_punit_acquired(); + + return blocking_notifier_chain_unregister( + &iosf_mbi_pmic_bus_access_notifier, nb); +} +EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier_unlocked); + int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) { int ret; /* Wait for the bus to go inactive before unregistering */ mutex_lock(&iosf_mbi_punit_mutex); - ret = blocking_notifier_chain_unregister( - &iosf_mbi_pmic_bus_access_notifier, nb); + ret = iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(nb); mutex_unlock(&iosf_mbi_punit_mutex); return ret; @@ -239,6 +248,12 @@ int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) } EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain); +void iosf_mbi_assert_punit_acquired(void) +{ + WARN_ON(!mutex_is_locked(&iosf_mbi_punit_mutex)); +} +EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired); + #ifdef CONFIG_IOSF_MBI_DEBUG static u32 dbg_mdr; static u32 dbg_mcr; |