x86/platform/intel/iosf_mbi: Add a mutex for P-Unit access

One some systems the P-Unit accesses the PMIC to change various voltages
through the same bus as other kernel drivers use for e.g. battery
monitoring.

If a driver sends requests to the P-Unit which require the P-Unit to access
the PMIC bus while another driver is also accessing the PMIC bus various
bad things happen.

This commit adds a mutex to protect the P-Unit against simultaneous
accesses and 2 functions to lock / unlock this mutex.

Note on these systems the i2c-bus driver will request a sempahore from the
P-Unit for exclusive access to the PMIC bus when i2c drivers are accessing
it, but this does not appear to be sufficient, we still need to avoid
making certain P-Unit requests during the access window to avoid problems.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=155241
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: tagorereddy <tagore.chandan@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20170210102802.20898-2-hdegoede@redhat.com
This commit is contained in:
Hans de Goede 2017-02-10 11:27:51 +01:00 committed by Daniel Vetter
parent 64a577196d
commit 9260a04097
2 changed files with 44 additions and 0 deletions

View File

@ -88,6 +88,33 @@ int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr);
*/ */
int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask); int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask);
/**
* iosf_mbi_punit_acquire() - Acquire access to the P-Unit
*
* One some systems the P-Unit accesses the PMIC to change various voltages
* through the same bus as other kernel drivers use for e.g. battery monitoring.
*
* If a driver sends requests to the P-Unit which require the P-Unit to access
* the PMIC bus while another driver is also accessing the PMIC bus various bad
* things happen.
*
* To avoid these problems this function must be called before accessing the
* P-Unit or the PMIC, be it through iosf_mbi* functions or through other means.
*
* Note on these systems the i2c-bus driver will request a sempahore from the
* P-Unit for exclusive access to the PMIC bus when i2c drivers are accessing
* it, but this does not appear to be sufficient, we still need to avoid making
* certain P-Unit requests during the access window to avoid problems.
*
* This function locks a mutex, as such it may sleep.
*/
void iosf_mbi_punit_acquire(void);
/**
* iosf_mbi_punit_release() - Release access to the P-Unit
*/
void iosf_mbi_punit_release(void);
#else /* CONFIG_IOSF_MBI is not enabled */ #else /* CONFIG_IOSF_MBI is not enabled */
static inline static inline
bool iosf_mbi_available(void) bool iosf_mbi_available(void)
@ -115,6 +142,10 @@ int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask)
WARN(1, "IOSF_MBI driver not available"); WARN(1, "IOSF_MBI driver not available");
return -EPERM; return -EPERM;
} }
static inline void iosf_mbi_punit_acquire(void) {}
static inline void iosf_mbi_punit_release(void) {}
#endif /* CONFIG_IOSF_MBI */ #endif /* CONFIG_IOSF_MBI */
#endif /* IOSF_MBI_SYMS_H */ #endif /* IOSF_MBI_SYMS_H */

View File

@ -34,6 +34,7 @@
static struct pci_dev *mbi_pdev; static struct pci_dev *mbi_pdev;
static DEFINE_SPINLOCK(iosf_mbi_lock); static DEFINE_SPINLOCK(iosf_mbi_lock);
static DEFINE_MUTEX(iosf_mbi_punit_mutex);
static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset) static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset)
{ {
@ -190,6 +191,18 @@ bool iosf_mbi_available(void)
} }
EXPORT_SYMBOL(iosf_mbi_available); EXPORT_SYMBOL(iosf_mbi_available);
void iosf_mbi_punit_acquire(void)
{
mutex_lock(&iosf_mbi_punit_mutex);
}
EXPORT_SYMBOL(iosf_mbi_punit_acquire);
void iosf_mbi_punit_release(void)
{
mutex_unlock(&iosf_mbi_punit_mutex);
}
EXPORT_SYMBOL(iosf_mbi_punit_release);
#ifdef CONFIG_IOSF_MBI_DEBUG #ifdef CONFIG_IOSF_MBI_DEBUG
static u32 dbg_mdr; static u32 dbg_mdr;
static u32 dbg_mcr; static u32 dbg_mcr;