mirror of https://gitee.com/openkylin/linux.git
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:
parent
64a577196d
commit
9260a04097
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue