Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Hans de Goede and committed by
Hans de Goede
af0ab55f c16c4ba7

+42 -2
+25
arch/x86/include/asm/iosf_mbi.h
··· 146 146 int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); 147 147 148 148 /** 149 + * iosf_mbi_unregister_pmic_bus_access_notifier_unlocked - Unregister PMIC bus 150 + * notifier, unlocked 151 + * 152 + * Like iosf_mbi_unregister_pmic_bus_access_notifier(), but for use when the 153 + * caller has already called iosf_mbi_punit_acquire() itself. 154 + * 155 + * @nb: notifier_block to unregister 156 + */ 157 + int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( 158 + struct notifier_block *nb); 159 + 160 + /** 149 161 * iosf_mbi_call_pmic_bus_access_notifier_chain - Call PMIC bus notifier chain 150 162 * 151 163 * @val: action to pass into listener's notifier_call function 152 164 * @v: data pointer to pass into listener's notifier_call function 153 165 */ 154 166 int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v); 167 + 168 + /** 169 + * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired. 170 + */ 171 + void iosf_mbi_assert_punit_acquired(void); 155 172 156 173 #else /* CONFIG_IOSF_MBI is not enabled */ 157 174 static inline ··· 213 196 return 0; 214 197 } 215 198 199 + static inline int 200 + iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb) 201 + { 202 + return 0; 203 + } 204 + 216 205 static inline 217 206 int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) 218 207 { 219 208 return 0; 220 209 } 210 + 211 + static inline void iosf_mbi_assert_punit_acquired(void) {} 221 212 222 213 #endif /* CONFIG_IOSF_MBI */ 223 214
+17 -2
arch/x86/platform/intel/iosf_mbi.c
··· 218 218 } 219 219 EXPORT_SYMBOL(iosf_mbi_register_pmic_bus_access_notifier); 220 220 221 + int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( 222 + struct notifier_block *nb) 223 + { 224 + iosf_mbi_assert_punit_acquired(); 225 + 226 + return blocking_notifier_chain_unregister( 227 + &iosf_mbi_pmic_bus_access_notifier, nb); 228 + } 229 + EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier_unlocked); 230 + 221 231 int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) 222 232 { 223 233 int ret; 224 234 225 235 /* Wait for the bus to go inactive before unregistering */ 226 236 mutex_lock(&iosf_mbi_punit_mutex); 227 - ret = blocking_notifier_chain_unregister( 228 - &iosf_mbi_pmic_bus_access_notifier, nb); 237 + ret = iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(nb); 229 238 mutex_unlock(&iosf_mbi_punit_mutex); 230 239 231 240 return ret; ··· 247 238 &iosf_mbi_pmic_bus_access_notifier, val, v); 248 239 } 249 240 EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain); 241 + 242 + void iosf_mbi_assert_punit_acquired(void) 243 + { 244 + WARN_ON(!mutex_is_locked(&iosf_mbi_punit_mutex)); 245 + } 246 + EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired); 250 247 251 248 #ifdef CONFIG_IOSF_MBI_DEBUG 252 249 static u32 dbg_mdr;