mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-01 12:04:08 +00:00
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "A set of updates and bugfixes for the new designware-baytrail driver. And a documentation bugfix" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: imx: add required clocks property to binding i2c: designware-baytrail: baytrail_i2c_acquire() might sleep i2c: designware-baytrail: cross-check lock functions i2c: designware-baytrail: fix sparse warnings i2c: designware-baytrail: fix typo in error path i2c: designware-baytrail: describe magic numbers
This commit is contained in:
commit
2cf3afcd4c
2 changed files with 22 additions and 19 deletions
|
@ -7,6 +7,7 @@ Required properties:
|
||||||
- "fsl,vf610-i2c" for I2C compatible with the one integrated on Vybrid vf610 SoC
|
- "fsl,vf610-i2c" for I2C compatible with the one integrated on Vybrid vf610 SoC
|
||||||
- reg : Should contain I2C/HS-I2C registers location and length
|
- reg : Should contain I2C/HS-I2C registers location and length
|
||||||
- interrupts : Should contain I2C/HS-I2C interrupt
|
- interrupts : Should contain I2C/HS-I2C interrupt
|
||||||
|
- clocks : Should contain the I2C/HS-I2C clock specifier
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz.
|
- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz.
|
||||||
|
|
|
@ -17,27 +17,31 @@
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
#include <asm/iosf_mbi.h>
|
#include <asm/iosf_mbi.h>
|
||||||
|
|
||||||
#include "i2c-designware-core.h"
|
#include "i2c-designware-core.h"
|
||||||
|
|
||||||
#define SEMAPHORE_TIMEOUT 100
|
#define SEMAPHORE_TIMEOUT 100
|
||||||
#define PUNIT_SEMAPHORE 0x7
|
#define PUNIT_SEMAPHORE 0x7
|
||||||
|
#define PUNIT_SEMAPHORE_BIT BIT(0)
|
||||||
|
#define PUNIT_SEMAPHORE_ACQUIRE BIT(1)
|
||||||
|
|
||||||
static unsigned long acquired;
|
static unsigned long acquired;
|
||||||
|
|
||||||
static int get_sem(struct device *dev, u32 *sem)
|
static int get_sem(struct device *dev, u32 *sem)
|
||||||
{
|
{
|
||||||
u32 reg_val;
|
u32 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, PUNIT_SEMAPHORE,
|
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, PUNIT_SEMAPHORE,
|
||||||
®_val);
|
&data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "iosf failed to read punit semaphore\n");
|
dev_err(dev, "iosf failed to read punit semaphore\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sem = reg_val & 0x1;
|
*sem = data & PUNIT_SEMAPHORE_BIT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -52,27 +56,29 @@ static void reset_semaphore(struct device *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = data & 0xfffffffe;
|
data &= ~PUNIT_SEMAPHORE_BIT;
|
||||||
if (iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE,
|
if (iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE,
|
||||||
PUNIT_SEMAPHORE, data))
|
PUNIT_SEMAPHORE, data))
|
||||||
dev_err(dev, "iosf failed to reset punit semaphore during write\n");
|
dev_err(dev, "iosf failed to reset punit semaphore during write\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
|
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
|
||||||
{
|
{
|
||||||
u32 sem = 0;
|
u32 sem;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long start, end;
|
unsigned long start, end;
|
||||||
|
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
if (!dev || !dev->dev)
|
if (!dev || !dev->dev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!dev->acquire_lock)
|
if (!dev->release_lock)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* host driver writes 0x2 to side band semaphore register */
|
/* host driver writes to side band semaphore register */
|
||||||
ret = iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE,
|
ret = iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE,
|
||||||
PUNIT_SEMAPHORE, 0x2);
|
PUNIT_SEMAPHORE, PUNIT_SEMAPHORE_ACQUIRE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev->dev, "iosf punit semaphore request failed\n");
|
dev_err(dev->dev, "iosf punit semaphore request failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -81,7 +87,7 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
|
||||||
/* host driver waits for bit 0 to be set in semaphore register */
|
/* host driver waits for bit 0 to be set in semaphore register */
|
||||||
start = jiffies;
|
start = jiffies;
|
||||||
end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
|
end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
|
||||||
while (!time_after(jiffies, end)) {
|
do {
|
||||||
ret = get_sem(dev->dev, &sem);
|
ret = get_sem(dev->dev, &sem);
|
||||||
if (!ret && sem) {
|
if (!ret && sem) {
|
||||||
acquired = jiffies;
|
acquired = jiffies;
|
||||||
|
@ -91,14 +97,14 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep_range(1000, 2000);
|
usleep_range(1000, 2000);
|
||||||
}
|
} while (time_before(jiffies, end));
|
||||||
|
|
||||||
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
|
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
|
||||||
reset_semaphore(dev->dev);
|
reset_semaphore(dev->dev);
|
||||||
|
|
||||||
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ,
|
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ,
|
||||||
PUNIT_SEMAPHORE, &sem);
|
PUNIT_SEMAPHORE, &sem);
|
||||||
if (!ret)
|
if (ret)
|
||||||
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
|
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
|
||||||
else
|
else
|
||||||
dev_err(dev->dev, "PUNIT SEM: %d\n", sem);
|
dev_err(dev->dev, "PUNIT SEM: %d\n", sem);
|
||||||
|
@ -107,9 +113,8 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
|
||||||
|
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(baytrail_i2c_acquire);
|
|
||||||
|
|
||||||
void baytrail_i2c_release(struct dw_i2c_dev *dev)
|
static void baytrail_i2c_release(struct dw_i2c_dev *dev)
|
||||||
{
|
{
|
||||||
if (!dev || !dev->dev)
|
if (!dev || !dev->dev)
|
||||||
return;
|
return;
|
||||||
|
@ -121,7 +126,6 @@ void baytrail_i2c_release(struct dw_i2c_dev *dev)
|
||||||
dev_dbg(dev->dev, "punit semaphore held for %ums\n",
|
dev_dbg(dev->dev, "punit semaphore held for %ums\n",
|
||||||
jiffies_to_msecs(jiffies - acquired));
|
jiffies_to_msecs(jiffies - acquired));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(baytrail_i2c_release);
|
|
||||||
|
|
||||||
int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
|
int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
|
||||||
{
|
{
|
||||||
|
@ -137,7 +141,6 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
|
status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
|
||||||
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -153,7 +156,6 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_dw_eval_lock_support);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
|
MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
|
||||||
MODULE_DESCRIPTION("Baytrail I2C Semaphore driver");
|
MODULE_DESCRIPTION("Baytrail I2C Semaphore driver");
|
||||||
|
|
Loading…
Add table
Reference in a new issue