* [PATCH 3/4] i2c: octeon: thunderx: Limit register access retries
From: Jan Glauber @ 2016-12-09 9:31 UTC (permalink / raw)
To: Wolfram Sang
Cc: Paul Burton, Steven J . Hill, linux-i2c, linux-mips, David Daney,
Jan Glauber
In-Reply-To: <20161209093158.3161-1-jglauber@cavium.com>
Do not infinitely retry register readq and writeq operations
in order to not lock up the CPU in case the TWSI gets stuck.
Return -EIO in case of a failed data read. For all other
cases just return so subsequent operations will fail
and trigger the recovery.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/i2c/busses/i2c-octeon-core.c | 4 +++-
drivers/i2c/busses/i2c-octeon-core.h | 21 ++++++++++++++++-----
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 3d10f1a..1d8775799 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -342,7 +342,9 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
if (result)
return result;
- data[i] = octeon_i2c_data_read(i2c);
+ data[i] = octeon_i2c_data_read(i2c, &result);
+ if (result)
+ return result;
if (recv_len && i == 0) {
if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
return -EPROTO;
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
index 87151ea..e160f83 100644
--- a/drivers/i2c/busses/i2c-octeon-core.h
+++ b/drivers/i2c/busses/i2c-octeon-core.h
@@ -141,11 +141,14 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
*/
static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
{
+ int tries = 1000;
u64 tmp;
__raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
do {
tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ if (--tries < 0)
+ return;
} while ((tmp & SW_TWSI_V) != 0);
}
@@ -163,24 +166,32 @@ static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8
*
* The I2C core registers are accessed indirectly via the SW_TWSI CSR.
*/
-static inline u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
+static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
+ int *error)
{
+ int tries = 1000;
u64 tmp;
__raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
do {
tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ if (--tries < 0) {
+ /* signal that the returned data is invalid */
+ if (error)
+ *error = -EIO;
+ return 0;
+ }
} while ((tmp & SW_TWSI_V) != 0);
return tmp & 0xFF;
}
#define octeon_i2c_ctl_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
-#define octeon_i2c_data_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
+#define octeon_i2c_data_read(i2c, error) \
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
#define octeon_i2c_stat_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
/**
* octeon_i2c_read_int - read the TWSI_INT register
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related
* [PATCH 4/4] i2c: octeon: thunderx: Add I2C_CLASS_HWMON
From: Jan Glauber @ 2016-12-09 9:31 UTC (permalink / raw)
To: Wolfram Sang
Cc: Paul Burton, Steven J . Hill, linux-i2c, linux-mips, David Daney,
Jan Glauber
In-Reply-To: <20161209093158.3161-1-jglauber@cavium.com>
It was reported that ipmi_ssif fails to create the
ipmi device on some systems if the adapter class is not containing
I2C_CLASS_HWMON. Fix it by setting the class.
Reported-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/i2c/busses/i2c-octeon-platdrv.c | 1 +
drivers/i2c/busses/i2c-thunderx-pcidrv.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
index 917524c..809b868 100644
--- a/drivers/i2c/busses/i2c-octeon-platdrv.c
+++ b/drivers/i2c/busses/i2c-octeon-platdrv.c
@@ -239,6 +239,7 @@ static int octeon_i2c_probe(struct platform_device *pdev)
i2c->adap = octeon_i2c_ops;
i2c->adap.timeout = msecs_to_jiffies(2);
i2c->adap.retries = 5;
+ i2c->adap.class = I2C_CLASS_HWMON;
i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
i2c->adap.dev.parent = &pdev->dev;
i2c->adap.dev.of_node = node;
diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
index bba5b42..9e3365f 100644
--- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
@@ -205,6 +205,7 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
i2c->adap = thunderx_i2c_ops;
i2c->adap.retries = 5;
+ i2c->adap.class = I2C_CLASS_HWMON;
i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
i2c->adap.dev.parent = dev;
i2c->adap.dev.of_node = pdev->dev.of_node;
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related
* [PATCH 2/2] i2c: designware-baytrail: Add support for cherrytrail
From: Hans de Goede @ 2016-12-09 11:01 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai, linux-i2c,
Hans de Goede
In-Reply-To: <20161209110154.7157-1-hdegoede@redhat.com>
The cherrytrail punit has the pmic i2c bus access semaphore at a
different register address.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 3 ++-
drivers/i2c/busses/i2c-designware-core.h | 2 ++
drivers/i2c/busses/i2c-designware-pcidrv.c | 25 ++++++++++++++++++-------
drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index a3f581c..938ff3b 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -22,7 +22,8 @@
#include "i2c-designware-core.h"
#define SEMAPHORE_TIMEOUT 100
-#define PUNIT_SEMAPHORE 0x7
+#define PUNIT_SEMAPHORE ((dev->accessor_flags & ACCESS_IS_CHERRYTRAIL) \
+ ? 0x10e : 0x7)
#define PUNIT_SEMAPHORE_BIT BIT(0)
#define PUNIT_SEMAPHORE_ACQUIRE BIT(1)
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 0d44d2a..4a66959 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -123,6 +123,8 @@ struct dw_i2c_dev {
#define ACCESS_SWAP 0x00000001
#define ACCESS_16BIT 0x00000002
#define ACCESS_INTR_MASK 0x00000004
+/* Not really an accessor_flag but also set through driver_data */
+#define ACCESS_IS_CHERRYTRAIL 0x00000008
extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern void i2c_dw_disable(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 96f8230..d774bab 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
medfield,
merrifield,
baytrail,
+ cherrytrail,
haswell,
};
@@ -174,6 +175,14 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &hsw_config,
},
+ [cherrytrail] = {
+ .bus_num = -1,
+ .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
+ .tx_fifo_depth = 32,
+ .rx_fifo_depth = 32,
+ .functionality = I2C_FUNC_10BIT_ADDR,
+ .scl_sda_cfg = &byt_config,
+ },
};
#ifdef CONFIG_PM
@@ -241,6 +250,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pdev->irq;
+ if (id->driver_data == cherrytrail)
+ dev->accessor_flags |= ACCESS_IS_CHERRYTRAIL;
if (controller->setup) {
r = controller->setup(pdev, controller);
@@ -321,13 +332,13 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9c61), haswell },
{ PCI_VDEVICE(INTEL, 0x9c62), haswell },
/* Braswell / Cherrytrail */
- { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
+ { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 0b42a12..8974467 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -123,7 +123,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3432", 0 },
{ "INT3433", 0 },
{ "80860F41", 0 },
- { "808622C1", 0 },
+ { "808622C1", ACCESS_IS_CHERRYTRAIL },
{ "AMD0010", ACCESS_INTR_MASK },
{ "AMDI0010", ACCESS_INTR_MASK },
{ "AMDI0510", 0 },
--
2.9.3
^ permalink raw reply related
* [PATCH 1/2] i2c: designware-baytrail: Pass dw_i2c_dev into helper functions
From: Hans de Goede @ 2016-12-09 11:01 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai, linux-i2c,
Hans de Goede
Pass dw_i2c_dev into the helper functions, this is a preparation patch
for adding cherrytrail support.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 1590ad0..a3f581c 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -28,14 +28,14 @@
static unsigned long acquired;
-static int get_sem(struct device *dev, u32 *sem)
+static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
{
u32 data;
int ret;
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
if (ret) {
- dev_err(dev, "iosf failed to read punit semaphore\n");
+ dev_err(dev->dev, "iosf failed to read punit semaphore\n");
return ret;
}
@@ -44,18 +44,18 @@ static int get_sem(struct device *dev, u32 *sem)
return 0;
}
-static void reset_semaphore(struct device *dev)
+static void reset_semaphore(struct dw_i2c_dev *dev)
{
u32 data;
if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
- dev_err(dev, "iosf failed to reset punit semaphore during read\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during read\n");
return;
}
data &= ~PUNIT_SEMAPHORE_BIT;
if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
- dev_err(dev, "iosf failed to reset punit semaphore during write\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
}
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -83,7 +83,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
start = jiffies;
end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
do {
- ret = get_sem(dev->dev, &sem);
+ ret = get_sem(dev, &sem);
if (!ret && sem) {
acquired = jiffies;
dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
@@ -95,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
} while (time_before(jiffies, end));
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
if (ret)
@@ -116,7 +116,7 @@ static void baytrail_i2c_release(struct dw_i2c_dev *dev)
if (!dev->acquire_lock)
return;
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
dev_dbg(dev->dev, "punit semaphore held for %ums\n",
jiffies_to_msecs(jiffies - acquired));
}
--
2.9.3
^ permalink raw reply related
* Re: [PATCH 1/2] i2c: designware-baytrail: Pass dw_i2c_dev into helper functions
From: Andy Shevchenko @ 2016-12-09 11:23 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, linux-i2c
In-Reply-To: <20161209110154.7157-1-hdegoede@redhat.com>
On Fri, 2016-12-09 at 12:01 +0100, Hans de Goede wrote:
> Pass dw_i2c_dev into the helper functions, this is a preparation patch
> for adding cherrytrail support.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Reviewed-by: Takashi Iwai <tiwai@suse.de>
> Tested-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> drivers/i2c/busses/i2c-designware-baytrail.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c
> b/drivers/i2c/busses/i2c-designware-baytrail.c
> index 1590ad0..a3f581c 100644
> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
> @@ -28,14 +28,14 @@
>
> static unsigned long acquired;
>
> -static int get_sem(struct device *dev, u32 *sem)
> +static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
> {
> u32 data;
> int ret;
>
> ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &data);
> if (ret) {
> - dev_err(dev, "iosf failed to read punit
> semaphore\n");
> + dev_err(dev->dev, "iosf failed to read punit
> semaphore\n");
> return ret;
> }
>
> @@ -44,18 +44,18 @@ static int get_sem(struct device *dev, u32 *sem)
> return 0;
> }
>
> -static void reset_semaphore(struct device *dev)
> +static void reset_semaphore(struct dw_i2c_dev *dev)
> {
> u32 data;
>
> if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &data)) {
> - dev_err(dev, "iosf failed to reset punit semaphore
> during read\n");
> + dev_err(dev->dev, "iosf failed to reset punit
> semaphore during read\n");
> return;
> }
>
> data &= ~PUNIT_SEMAPHORE_BIT;
> if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
> PUNIT_SEMAPHORE, data))
> - dev_err(dev, "iosf failed to reset punit semaphore
> during write\n");
> + dev_err(dev->dev, "iosf failed to reset punit
> semaphore during write\n");
> }
>
> static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
> @@ -83,7 +83,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev
> *dev)
> start = jiffies;
> end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
> do {
> - ret = get_sem(dev->dev, &sem);
> + ret = get_sem(dev, &sem);
> if (!ret && sem) {
> acquired = jiffies;
> dev_dbg(dev->dev, "punit semaphore acquired
> after %ums\n",
> @@ -95,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev
> *dev)
> } while (time_before(jiffies, end));
>
> dev_err(dev->dev, "punit semaphore timed out, resetting\n");
> - reset_semaphore(dev->dev);
> + reset_semaphore(dev);
>
> ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &sem);
> if (ret)
> @@ -116,7 +116,7 @@ static void baytrail_i2c_release(struct dw_i2c_dev
> *dev)
> if (!dev->acquire_lock)
> return;
>
> - reset_semaphore(dev->dev);
> + reset_semaphore(dev);
> dev_dbg(dev->dev, "punit semaphore held for %ums\n",
> jiffies_to_msecs(jiffies - acquired));
> }
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH 2/2] i2c: designware-baytrail: Add support for cherrytrail
From: Andy Shevchenko @ 2016-12-09 11:29 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, linux-i2c
In-Reply-To: <20161209110154.7157-2-hdegoede@redhat.com>
On Fri, 2016-12-09 at 12:01 +0100, Hans de Goede wrote:
> The cherrytrail punit has the pmic i2c bus access semaphore at a
> different register address.
Thanks for the patch. My comments below.
> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
> @@ -22,7 +22,8 @@
> #include "i2c-designware-core.h"
>
> #define SEMAPHORE_TIMEOUT 100
> -#define PUNIT_SEMAPHORE 0x7
> +#define PUNIT_SEMAPHORE ((dev->accessor_flags &
> ACCESS_IS_CHERRYTRAIL) \
> + ? 0x10e : 0x7)
Personally I don't like this.
What if we do it in a helper function
static u32 get_sem_addr()
{
...
return addr;
}
And user
{
u32 addr = get_sem_addr(...);
iosf...(..., addr, ...);
}
> --- a/drivers/i2c/busses/i2c-designware-core.h
> +++ b/drivers/i2c/busses/i2c-designware-core.h
> @@ -123,6 +123,8 @@ struct dw_i2c_dev {
> #define ACCESS_SWAP 0x00000001
> #define ACCESS_16BIT 0x00000002
> #define ACCESS_INTR_MASK 0x00000004
> +/* Not really an accessor_flag but also set through driver_data */
> +#define ACCESS_IS_CHERRYTRAIL 0x00000008
Don't like it either. Here two ways I see:
Introduce another member to keep non-accessor flags, or rename existing
one and create new flags with some other prefix.
>
> extern int i2c_dw_init(struct dw_i2c_dev *dev);
> extern void i2c_dw_disable(struct dw_i2c_dev *dev);
> diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c
> b/drivers/i2c/busses/i2c-designware-pcidrv.c
> index 96f8230..d774bab 100644
> --- a/drivers/i2c/busses/i2c-designware-pcidrv.c
> +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
> @@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
> medfield,
> merrifield,
> baytrail,
> + cherrytrail,
> haswell,
> };
>
> @@ -174,6 +175,14 @@ static struct dw_pci_controller
> dw_pci_controllers[] = {
> .functionality = I2C_FUNC_10BIT_ADDR,
> .scl_sda_cfg = &hsw_config,
> },
> + [cherrytrail] = {
> + .bus_num = -1,
> + .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
> + .tx_fifo_depth = 32,
> + .rx_fifo_depth = 32,
> + .functionality = I2C_FUNC_10BIT_ADDR,
> + .scl_sda_cfg = &byt_config,
Would be ugly if we actually put...
> + },
> };
>
> #ifdef CONFIG_PM
> @@ -241,6 +250,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
> dev->base = pcim_iomap_table(pdev)[0];
> dev->dev = &pdev->dev;
> dev->irq = pdev->irq;
> + if (id->driver_data == cherrytrail)
> + dev->accessor_flags |= ACCESS_IS_CHERRYTRAIL;
...above inside the struct dw_pci_controller?
>
> if (controller->setup) {
> r = controller->setup(pdev, controller);
> @@ -321,13 +332,13 @@ static const struct pci_device_id
> i2_designware_pci_ids[] = {
> { PCI_VDEVICE(INTEL, 0x9c61), haswell },
> { PCI_VDEVICE(INTEL, 0x9c62), haswell },
> /* Braswell / Cherrytrail */
> - { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
> + { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
> { 0,}
> };
> MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
> b/drivers/i2c/busses/i2c-designware-platdrv.c
> index 0b42a12..8974467 100644
> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -123,7 +123,7 @@ static const struct acpi_device_id
> dw_i2c_acpi_match[] = {
> { "INT3432", 0 },
> { "INT3433", 0 },
> { "80860F41", 0 },
> - { "808622C1", 0 },
> + { "808622C1", ACCESS_IS_CHERRYTRAIL },
> { "AMD0010", ACCESS_INTR_MASK },
> { "AMDI0010", ACCESS_INTR_MASK },
> { "AMDI0510", 0 },
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH 2/2] i2c: designware-baytrail: Add support for cherrytrail
From: Hans de Goede @ 2016-12-10 10:34 UTC (permalink / raw)
To: Andy Shevchenko, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, linux-i2c
In-Reply-To: <1481282952.30772.50.camel@linux.intel.com>
Hi,
On 09-12-16 12:29, Andy Shevchenko wrote:
> On Fri, 2016-12-09 at 12:01 +0100, Hans de Goede wrote:
>> The cherrytrail punit has the pmic i2c bus access semaphore at a
>> different register address.
>
> Thanks for the patch. My comments below.
>
>> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
>> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
>> @@ -22,7 +22,8 @@
>> #include "i2c-designware-core.h"
>>
>> #define SEMAPHORE_TIMEOUT 100
>> -#define PUNIT_SEMAPHORE 0x7
>> +#define PUNIT_SEMAPHORE ((dev->accessor_flags &
>> ACCESS_IS_CHERRYTRAIL) \
>> + ? 0x10e : 0x7)
>
> Personally I don't like this.
>
> What if we do it in a helper function
>
> static u32 get_sem_addr()
> {
> ...
> return addr;
> }
>
> And user
>
> {
> u32 addr = get_sem_addr(...);
>
> iosf...(..., addr, ...);
> }
Ok I will change this for the next version.
>
>
>> --- a/drivers/i2c/busses/i2c-designware-core.h
>> +++ b/drivers/i2c/busses/i2c-designware-core.h
>> @@ -123,6 +123,8 @@ struct dw_i2c_dev {
>> #define ACCESS_SWAP 0x00000001
>> #define ACCESS_16BIT 0x00000002
>> #define ACCESS_INTR_MASK 0x00000004
>> +/* Not really an accessor_flag but also set through driver_data */
>> +#define ACCESS_IS_CHERRYTRAIL 0x00000008
>
> Don't like it either. Here two ways I see:
> Introduce another member to keep non-accessor flags, or rename existing
> one and create new flags with some other prefix.
Ok, I will introduce a new patch in the next version of the
series which renames the flags field as preparation
for the other changes.
>
>>
>> extern int i2c_dw_init(struct dw_i2c_dev *dev);
>> extern void i2c_dw_disable(struct dw_i2c_dev *dev);
>> diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c
>> b/drivers/i2c/busses/i2c-designware-pcidrv.c
>> index 96f8230..d774bab 100644
>> --- a/drivers/i2c/busses/i2c-designware-pcidrv.c
>> +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
>> @@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
>> medfield,
>> merrifield,
>> baytrail,
>> + cherrytrail,
>> haswell,
>> };
>>
>> @@ -174,6 +175,14 @@ static struct dw_pci_controller
>> dw_pci_controllers[] = {
>> .functionality = I2C_FUNC_10BIT_ADDR,
>> .scl_sda_cfg = &hsw_config,
>> },
>
>> + [cherrytrail] = {
>> + .bus_num = -1,
>> + .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
>> + .tx_fifo_depth = 32,
>> + .rx_fifo_depth = 32,
>> + .functionality = I2C_FUNC_10BIT_ADDR,
>> + .scl_sda_cfg = &byt_config,
>
> Would be ugly if we actually put...
>
>> + },
>> };
>>
>> #ifdef CONFIG_PM
>> @@ -241,6 +250,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
>> dev->base = pcim_iomap_table(pdev)[0];
>> dev->dev = &pdev->dev;
>> dev->irq = pdev->irq;
>> + if (id->driver_data == cherrytrail)
>> + dev->accessor_flags |= ACCESS_IS_CHERRYTRAIL;
>
> ...above inside the struct dw_pci_controller?
Ack.
Note BTW that while trying to get battery readings from the axp288
pmic on my tablet now that the punit semaphore is working I repeatedly
locked up my tablet. Without any i2c client drivers loaded a simple
"i2cdump -y 14 0x34" would lookup the tablet in 1 - 3 runs guaranteed,
and that is only reading from the pmic.
I managed to find a fix for this which I will include (as a separate
patch) in the next version of my series. This will also hopefully
fix the infamous: https://bugzilla.kernel.org/show_bug.cgi?id=109051,
as I could also make things work without my fix with
"intel_idle.max_cstate=0" so they seem to be related.
Regards,
Hans
>
>>
>> if (controller->setup) {
>> r = controller->setup(pdev, controller);
>> @@ -321,13 +332,13 @@ static const struct pci_device_id
>> i2_designware_pci_ids[] = {
>> { PCI_VDEVICE(INTEL, 0x9c61), haswell },
>> { PCI_VDEVICE(INTEL, 0x9c62), haswell },
>> /* Braswell / Cherrytrail */
>> - { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
>> - { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
>> + { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
>> { 0,}
>> };
>> MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
>> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
>> b/drivers/i2c/busses/i2c-designware-platdrv.c
>> index 0b42a12..8974467 100644
>> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
>> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
>> @@ -123,7 +123,7 @@ static const struct acpi_device_id
>> dw_i2c_acpi_match[] = {
>> { "INT3432", 0 },
>> { "INT3433", 0 },
>> { "80860F41", 0 },
>> - { "808622C1", 0 },
>> + { "808622C1", ACCESS_IS_CHERRYTRAIL },
>> { "AMD0010", ACCESS_INTR_MASK },
>> { "AMDI0010", ACCESS_INTR_MASK },
>> { "AMDI0510", 0 },
>
^ permalink raw reply
* [PATCH v2 1/5] i2c: designware: Rename accessor_flags to flags
From: Hans de Goede @ 2016-12-10 14:19 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
Rename accessor_flags to flags, so that we can use the field for
other flags too. This is a preparation patch for adding cherrytrail
support to the punit semaphore code.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/i2c/busses/i2c-designware-core.c | 14 +++++++-------
drivers/i2c/busses/i2c-designware-core.h | 2 +-
drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index b403fa5..b6a7989 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -177,13 +177,13 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
{
u32 value;
- if (dev->accessor_flags & ACCESS_16BIT)
+ if (dev->flags & ACCESS_16BIT)
value = readw_relaxed(dev->base + offset) |
(readw_relaxed(dev->base + offset + 2) << 16);
else
value = readl_relaxed(dev->base + offset);
- if (dev->accessor_flags & ACCESS_SWAP)
+ if (dev->flags & ACCESS_SWAP)
return swab32(value);
else
return value;
@@ -191,10 +191,10 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
{
- if (dev->accessor_flags & ACCESS_SWAP)
+ if (dev->flags & ACCESS_SWAP)
b = swab32(b);
- if (dev->accessor_flags & ACCESS_16BIT) {
+ if (dev->flags & ACCESS_16BIT) {
writew_relaxed((u16)b, dev->base + offset);
writew_relaxed((u16)(b >> 16), dev->base + offset + 2);
} else {
@@ -339,10 +339,10 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
reg = dw_readl(dev, DW_IC_COMP_TYPE);
if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
/* Configure register endianess access */
- dev->accessor_flags |= ACCESS_SWAP;
+ dev->flags |= ACCESS_SWAP;
} else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
/* Configure register access mode 16bit */
- dev->accessor_flags |= ACCESS_16BIT;
+ dev->flags |= ACCESS_16BIT;
} else if (reg != DW_IC_COMP_TYPE_VALUE) {
dev_err(dev->dev, "Unknown Synopsys component type: "
"0x%08x\n", reg);
@@ -886,7 +886,7 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
tx_aborted:
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
complete(&dev->cmd_complete);
- else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+ else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
/* workaround to trigger pending interrupt */
stat = dw_readl(dev, DW_IC_INTR_MASK);
i2c_dw_disable_int(dev);
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 0d44d2a..fb143f5 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -95,7 +95,7 @@ struct dw_i2c_dev {
unsigned int status;
u32 abort_source;
int irq;
- u32 accessor_flags;
+ u32 flags;
struct i2c_adapter adapter;
u32 functionality;
u32 master_cfg;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 0b42a12..97a2ca1 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -112,7 +112,7 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
- dev->accessor_flags |= (u32)id->driver_data;
+ dev->flags |= (u32)id->driver_data;
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/5] i2c: designware-baytrail: Pass dw_i2c_dev into helper functions
From: Hans de Goede @ 2016-12-10 14:19 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210141908.16470-1-hdegoede@redhat.com>
Pass dw_i2c_dev into the helper functions, this is a preparation patch
for the punit semaphore fixes done in the other patches in this set.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 1590ad0..a3f581c 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -28,14 +28,14 @@
static unsigned long acquired;
-static int get_sem(struct device *dev, u32 *sem)
+static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
{
u32 data;
int ret;
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
if (ret) {
- dev_err(dev, "iosf failed to read punit semaphore\n");
+ dev_err(dev->dev, "iosf failed to read punit semaphore\n");
return ret;
}
@@ -44,18 +44,18 @@ static int get_sem(struct device *dev, u32 *sem)
return 0;
}
-static void reset_semaphore(struct device *dev)
+static void reset_semaphore(struct dw_i2c_dev *dev)
{
u32 data;
if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
- dev_err(dev, "iosf failed to reset punit semaphore during read\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during read\n");
return;
}
data &= ~PUNIT_SEMAPHORE_BIT;
if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
- dev_err(dev, "iosf failed to reset punit semaphore during write\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
}
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -83,7 +83,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
start = jiffies;
end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
do {
- ret = get_sem(dev->dev, &sem);
+ ret = get_sem(dev, &sem);
if (!ret && sem) {
acquired = jiffies;
dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
@@ -95,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
} while (time_before(jiffies, end));
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
if (ret)
@@ -116,7 +116,7 @@ static void baytrail_i2c_release(struct dw_i2c_dev *dev)
if (!dev->acquire_lock)
return;
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
dev_dbg(dev->dev, "punit semaphore held for %ums\n",
jiffies_to_msecs(jiffies - acquired));
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 3/5] i2c: designware-baytrail: Only check iosf_mbi_available() for shared hosts
From: Hans de Goede @ 2016-12-10 14:19 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210141908.16470-1-hdegoede@redhat.com>
There is no need to delay the probe if iosf_mbi_available() returns
false when an i2c bus is not using the punit semaphore.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index a3f581c..a419777 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -139,14 +139,14 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
return 0;
if (shared_host) {
+ if (!iosf_mbi_available())
+ return -EPROBE_DEFER;
+
dev_info(dev->dev, "I2C bus managed by PUNIT\n");
dev->acquire_lock = baytrail_i2c_acquire;
dev->release_lock = baytrail_i2c_release;
dev->pm_runtime_disabled = true;
}
- if (!iosf_mbi_available())
- return -EPROBE_DEFER;
-
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 4/5] i2c: designware-baytrail: Force the CPU to C1 state while holding the punit semaphore
From: Hans de Goede @ 2016-12-10 14:19 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210141908.16470-1-hdegoede@redhat.com>
On my cherrytrail tablet with axp288 pmic, just doing a bunch of repeated
reads from the pmic, e.g. "i2cdump -y 14 0x34" would lookup the tablet in
1 - 3 runs guaranteed.
This seems to be causes by the cpuidle / intel_idle driver trying to
change the C-state while we hold the punit bus semaphore, at which point
everything just hangs.
Avoid this by forcing the CPU to C1 before acquiring the punit bus
semaphore.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=109051
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 12 ++++++++++++
drivers/i2c/busses/i2c-designware-core.h | 3 +++
drivers/i2c/busses/i2c-designware-platdrv.c | 3 +++
3 files changed, 18 insertions(+)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index a419777..4f10ebb 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/pm_qos.h>
#include <asm/iosf_mbi.h>
@@ -33,6 +34,13 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
u32 data;
int ret;
+ /*
+ * Force CPU to C1 state, otherwise if the cpuidle / intel_idle
+ * driver tries to change the C state while we're holding the
+ * semaphore, the SoC hangs.
+ */
+ pm_qos_update_request(&dev->pm_qos, 0);
+
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
if (ret) {
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
@@ -56,6 +64,8 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
data &= ~PUNIT_SEMAPHORE_BIT;
if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
+
+ pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
}
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -143,6 +153,8 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
return -EPROBE_DEFER;
dev_info(dev->dev, "I2C bus managed by PUNIT\n");
+ pm_qos_add_request(&dev->pm_qos, PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
dev->acquire_lock = baytrail_i2c_acquire;
dev->release_lock = baytrail_i2c_release;
dev->pm_runtime_disabled = true;
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index fb143f5..47d284c 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -22,6 +22,7 @@
*
*/
+#include <linux/pm_qos.h>
#define DW_IC_CON_MASTER 0x1
#define DW_IC_CON_SPEED_STD 0x2
@@ -67,6 +68,7 @@
* @fp_lcnt: fast plus LCNT value
* @hs_hcnt: high speed HCNT value
* @hs_lcnt: high speed LCNT value
+ * @pm_qos: pm_qos_request used while holding a hardware lock on the bus
* @acquire_lock: function to acquire a hardware lock on the bus
* @release_lock: function to release a hardware lock on the bus
* @pm_runtime_disabled: true if pm runtime is disabled
@@ -114,6 +116,7 @@ struct dw_i2c_dev {
u16 fp_lcnt;
u16 hs_hcnt;
u16 hs_lcnt;
+ struct pm_qos_request pm_qos;
int (*acquire_lock)(struct dw_i2c_dev *dev);
void (*release_lock)(struct dw_i2c_dev *dev);
bool pm_runtime_disabled;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 97a2ca1..6d72929 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -291,6 +291,9 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
+ if (dev->acquire_lock)
+ pm_qos_remove_request(&dev->pm_qos);
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 5/5] i2c: designware-baytrail: Add support for cherrytrail
From: Hans de Goede @ 2016-12-10 14:19 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210141908.16470-1-hdegoede@redhat.com>
The cherrytrail punit has the pmic i2c bus access semaphore at a
different register address.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
---
Changes in v2:
-Adjust for accessor_flags -> flags rename
-Add flags field to struct dw_pci_controller
-Add get_sem_addr() helper replacing MODEL_CHERRYTRAIL flag checking in
PUNIT_SEMAPHORE macro
---
drivers/i2c/busses/i2c-designware-baytrail.c | 22 +++++++++++++++++-----
drivers/i2c/busses/i2c-designware-core.h | 1 +
drivers/i2c/busses/i2c-designware-pcidrv.c | 26 +++++++++++++++++++-------
drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
4 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 4f10ebb..16cfe16 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -24,13 +24,23 @@
#define SEMAPHORE_TIMEOUT 100
#define PUNIT_SEMAPHORE 0x7
+#define PUNIT_SEMAPHORE_CHV 0x10e
#define PUNIT_SEMAPHORE_BIT BIT(0)
#define PUNIT_SEMAPHORE_ACQUIRE BIT(1)
static unsigned long acquired;
+static u32 get_sem_addr(struct dw_i2c_dev *dev)
+{
+ if (dev->flags & MODEL_CHERRYTRAIL)
+ return PUNIT_SEMAPHORE_CHV;
+ else
+ return PUNIT_SEMAPHORE;
+}
+
static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
{
+ u32 addr = get_sem_addr(dev);
u32 data;
int ret;
@@ -41,7 +51,7 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
*/
pm_qos_update_request(&dev->pm_qos, 0);
- ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
+ ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &data);
if (ret) {
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
return ret;
@@ -54,15 +64,16 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
static void reset_semaphore(struct dw_i2c_dev *dev)
{
+ u32 addr = get_sem_addr(dev);
u32 data;
- if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
+ if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &data)) {
dev_err(dev->dev, "iosf failed to reset punit semaphore during read\n");
return;
}
data &= ~PUNIT_SEMAPHORE_BIT;
- if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
+ if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, data))
dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
@@ -70,6 +81,7 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
{
+ u32 addr = get_sem_addr(dev);
u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
int ret;
unsigned long start, end;
@@ -83,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
return 0;
/* host driver writes to side band semaphore register */
- ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, sem);
+ ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, sem);
if (ret) {
dev_err(dev->dev, "iosf punit semaphore request failed\n");
return ret;
@@ -107,7 +119,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
reset_semaphore(dev);
- ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
+ ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &sem);
if (ret)
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
else
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 47d284c..735fc63 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -126,6 +126,7 @@ struct dw_i2c_dev {
#define ACCESS_SWAP 0x00000001
#define ACCESS_16BIT 0x00000002
#define ACCESS_INTR_MASK 0x00000004
+#define MODEL_CHERRYTRAIL 0x00000008
extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern void i2c_dw_disable(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 96f8230..4e53a9f 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
medfield,
merrifield,
baytrail,
+ cherrytrail,
haswell,
};
@@ -63,6 +64,7 @@ struct dw_pci_controller {
u32 rx_fifo_depth;
u32 clk_khz;
u32 functionality;
+ u32 flags;
struct dw_scl_sda_cfg *scl_sda_cfg;
int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c);
};
@@ -174,6 +176,15 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &hsw_config,
},
+ [cherrytrail] = {
+ .bus_num = -1,
+ .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
+ .tx_fifo_depth = 32,
+ .rx_fifo_depth = 32,
+ .functionality = I2C_FUNC_10BIT_ADDR,
+ .flags = MODEL_CHERRYTRAIL,
+ .scl_sda_cfg = &byt_config,
+ },
};
#ifdef CONFIG_PM
@@ -241,6 +252,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pdev->irq;
+ dev->flags |= controller->flags;
if (controller->setup) {
r = controller->setup(pdev, controller);
@@ -321,13 +333,13 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9c61), haswell },
{ PCI_VDEVICE(INTEL, 0x9c62), haswell },
/* Braswell / Cherrytrail */
- { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
+ { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 6d72929..589f07e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -123,7 +123,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3432", 0 },
{ "INT3433", 0 },
{ "80860F41", 0 },
- { "808622C1", 0 },
+ { "808622C1", MODEL_CHERRYTRAIL },
{ "AMD0010", ACCESS_INTR_MASK },
{ "AMDI0010", ACCESS_INTR_MASK },
{ "AMDI0510", 0 },
--
2.9.3
^ permalink raw reply related
* Re: [PATCH v2 1/5] i2c: designware: Rename accessor_flags to flags
From: Andy Shevchenko @ 2016-12-10 14:36 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <20161210141908.16470-1-hdegoede@redhat.com>
On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
> Rename accessor_flags to flags, so that we can use the field for
> other flags too. This is a preparation patch for adding cherrytrail
> support to the punit semaphore code.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> drivers/i2c/busses/i2c-designware-core.c | 14 +++++++-------
> drivers/i2c/busses/i2c-designware-core.h | 2 +-
> drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
> 3 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-designware-core.c
> b/drivers/i2c/busses/i2c-designware-core.c
> index b403fa5..b6a7989 100644
> --- a/drivers/i2c/busses/i2c-designware-core.c
> +++ b/drivers/i2c/busses/i2c-designware-core.c
> @@ -177,13 +177,13 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int
> offset)
> {
> u32 value;
>
> - if (dev->accessor_flags & ACCESS_16BIT)
> + if (dev->flags & ACCESS_16BIT)
> value = readw_relaxed(dev->base + offset) |
> (readw_relaxed(dev->base + offset + 2) <<
> 16);
> else
> value = readl_relaxed(dev->base + offset);
>
> - if (dev->accessor_flags & ACCESS_SWAP)
> + if (dev->flags & ACCESS_SWAP)
> return swab32(value);
> else
> return value;
> @@ -191,10 +191,10 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int
> offset)
>
> static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
> {
> - if (dev->accessor_flags & ACCESS_SWAP)
> + if (dev->flags & ACCESS_SWAP)
> b = swab32(b);
>
> - if (dev->accessor_flags & ACCESS_16BIT) {
> + if (dev->flags & ACCESS_16BIT) {
> writew_relaxed((u16)b, dev->base + offset);
> writew_relaxed((u16)(b >> 16), dev->base + offset +
> 2);
> } else {
> @@ -339,10 +339,10 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
> reg = dw_readl(dev, DW_IC_COMP_TYPE);
> if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
> /* Configure register endianess access */
> - dev->accessor_flags |= ACCESS_SWAP;
> + dev->flags |= ACCESS_SWAP;
> } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
> /* Configure register access mode 16bit */
> - dev->accessor_flags |= ACCESS_16BIT;
> + dev->flags |= ACCESS_16BIT;
> } else if (reg != DW_IC_COMP_TYPE_VALUE) {
> dev_err(dev->dev, "Unknown Synopsys component type: "
> "0x%08x\n", reg);
> @@ -886,7 +886,7 @@ static irqreturn_t i2c_dw_isr(int this_irq, void
> *dev_id)
> tx_aborted:
> if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) ||
> dev->msg_err)
> complete(&dev->cmd_complete);
> - else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
> + else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
> /* workaround to trigger pending interrupt */
> stat = dw_readl(dev, DW_IC_INTR_MASK);
> i2c_dw_disable_int(dev);
> diff --git a/drivers/i2c/busses/i2c-designware-core.h
> b/drivers/i2c/busses/i2c-designware-core.h
> index 0d44d2a..fb143f5 100644
> --- a/drivers/i2c/busses/i2c-designware-core.h
> +++ b/drivers/i2c/busses/i2c-designware-core.h
> @@ -95,7 +95,7 @@ struct dw_i2c_dev {
> unsigned int status;
> u32 abort_source;
> int irq;
> - u32 accessor_flags;
> + u32 flags;
> struct i2c_adapter adapter;
> u32 functionality;
> u32 master_cfg;
> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
> b/drivers/i2c/busses/i2c-designware-platdrv.c
> index 0b42a12..97a2ca1 100644
> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -112,7 +112,7 @@ static int dw_i2c_acpi_configure(struct
> platform_device *pdev)
>
> id = acpi_match_device(pdev->dev.driver->acpi_match_table,
> &pdev->dev);
> if (id && id->driver_data)
> - dev->accessor_flags |= (u32)id->driver_data;
> + dev->flags |= (u32)id->driver_data;
>
> return 0;
> }
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH v2 4/5] i2c: designware-baytrail: Force the CPU to C1 state while holding the punit semaphore
From: Andy Shevchenko @ 2016-12-10 14:53 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang, Len Brown
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <20161210141908.16470-4-hdegoede@redhat.com>
+Cc: Len
Len, I think you would be interested by this.
Hans, thanks for the change! Most probably we will anticipate Len's ACK
on this one.
On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
> On my cherrytrail tablet with axp288 pmic, just doing a bunch of
> repeated
> reads from the pmic, e.g. "i2cdump -y 14 0x34" would lookup the tablet
> in
> 1 - 3 runs guaranteed.
>
> This seems to be causes by the cpuidle / intel_idle driver trying to
> change the C-state while we hold the punit bus semaphore, at which
> point
> everything just hangs.
>
> Avoid this by forcing the CPU to C1 before acquiring the punit bus
> semaphore.
Isn't it C0? C1 as far as I remember is halted state.
> @@ -33,6 +34,13 @@ static int get_sem(struct dw_i2c_dev *dev, u32
> *sem)
> u32 data;
> int ret;
>
> + /*
> + * Force CPU to C1 state, otherwise if the cpuidle /
> intel_idle
> + * driver tries to change the C state while we're holding the
> + * semaphore, the SoC hangs.
C0?
> + */
> + pm_qos_update_request(&dev->pm_qos, 0);
C1 is when you set 1 here, right?
> platform_device *pdev)
> if (!dev->pm_runtime_disabled)
> pm_runtime_disable(&pdev->dev);
> + if (dev->acquire_lock)
> + pm_qos_remove_request(&dev->pm_qos);
> +
Perhaps you need to do this in -core.c. Otherwise you missed PCI case.
(Even with PCI enumerated host with ACPI-enabled firmware you may get
_SEM object present)
> return 0;
> }
>
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH v2 3/5] i2c: designware-baytrail: Only check iosf_mbi_available() for shared hosts
From: Andy Shevchenko @ 2016-12-10 14:54 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <20161210141908.16470-3-hdegoede@redhat.com>
On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
> There is no need to delay the probe if iosf_mbi_available() returns
> false when an i2c bus is not using the punit semaphore.
> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
> @@ -139,14 +139,14 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev
> *dev)
> return 0;
>
> if (shared_host) {
> + if (!iosf_mbi_available())
> + return -EPROBE_DEFER;
> +
Looking to the implementation of i2c_dw_eval_lock_support() I would
rewrite this like
if (!shared_host)
return 0;
> dev_info(dev->dev, "I2C bus managed by PUNIT\n");
> dev->acquire_lock = baytrail_i2c_acquire;
> dev->release_lock = baytrail_i2c_release;
> dev->pm_runtime_disabled = true;
> }
>
> - if (!iosf_mbi_available())
> - return -EPROBE_DEFER;
> -
> return 0;
> }
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH v2 5/5] i2c: designware-baytrail: Add support for cherrytrail
From: Andy Shevchenko @ 2016-12-10 15:01 UTC (permalink / raw)
To: Hans de Goede, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <20161210141908.16470-5-hdegoede@redhat.com>
On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
> The cherrytrail punit has the pmic i2c bus access semaphore at a
> different register address.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Reviewed-by: Takashi Iwai <tiwai@suse.de>
> Tested-by: Takashi Iwai <tiwai@suse.de>
> ---
> Changes in v2:
> -Adjust for accessor_flags -> flags rename
> -Add flags field to struct dw_pci_controller
> -Add get_sem_addr() helper replacing MODEL_CHERRYTRAIL flag checking
> in
> PUNIT_SEMAPHORE macro
Yes! That's exactly what I would like to see.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
P.S. One very minor comment, perhaps make a gap between ACCESS_* and
MODEL_* flags, like starting MODEL_XXX from 0x10?
> ---
> drivers/i2c/busses/i2c-designware-baytrail.c | 22 +++++++++++++++++
> -----
> drivers/i2c/busses/i2c-designware-core.h | 1 +
> drivers/i2c/busses/i2c-designware-pcidrv.c | 26
> +++++++++++++++++++-------
> drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
> 4 files changed, 38 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c
> b/drivers/i2c/busses/i2c-designware-baytrail.c
> index 4f10ebb..16cfe16 100644
> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
> @@ -24,13 +24,23 @@
>
> #define SEMAPHORE_TIMEOUT 100
> #define PUNIT_SEMAPHORE 0x7
> +#define PUNIT_SEMAPHORE_CHV 0x10e
> #define PUNIT_SEMAPHORE_BIT BIT(0)
> #define PUNIT_SEMAPHORE_ACQUIRE BIT(1)
>
> static unsigned long acquired;
>
> +static u32 get_sem_addr(struct dw_i2c_dev *dev)
> +{
> + if (dev->flags & MODEL_CHERRYTRAIL)
> + return PUNIT_SEMAPHORE_CHV;
> + else
> + return PUNIT_SEMAPHORE;
> +}
> +
> static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
> {
> + u32 addr = get_sem_addr(dev);
> u32 data;
> int ret;
>
> @@ -41,7 +51,7 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
> */
> pm_qos_update_request(&dev->pm_qos, 0);
>
> - ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &data);
> + ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr,
> &data);
> if (ret) {
> dev_err(dev->dev, "iosf failed to read punit
> semaphore\n");
> return ret;
> @@ -54,15 +64,16 @@ static int get_sem(struct dw_i2c_dev *dev, u32
> *sem)
>
> static void reset_semaphore(struct dw_i2c_dev *dev)
> {
> + u32 addr = get_sem_addr(dev);
> u32 data;
>
> - if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &data)) {
> + if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr,
> &data)) {
> dev_err(dev->dev, "iosf failed to reset punit
> semaphore during read\n");
> return;
> }
>
> data &= ~PUNIT_SEMAPHORE_BIT;
> - if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
> PUNIT_SEMAPHORE, data))
> + if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr,
> data))
> dev_err(dev->dev, "iosf failed to reset punit
> semaphore during write\n");
>
> pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
> @@ -70,6 +81,7 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
>
> static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
> {
> + u32 addr = get_sem_addr(dev);
> u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
> int ret;
> unsigned long start, end;
> @@ -83,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev
> *dev)
> return 0;
>
> /* host driver writes to side band semaphore register */
> - ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
> PUNIT_SEMAPHORE, sem);
> + ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr,
> sem);
> if (ret) {
> dev_err(dev->dev, "iosf punit semaphore request
> failed\n");
> return ret;
> @@ -107,7 +119,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev
> *dev)
> dev_err(dev->dev, "punit semaphore timed out, resetting\n");
> reset_semaphore(dev);
>
> - ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
> PUNIT_SEMAPHORE, &sem);
> + ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr,
> &sem);
> if (ret)
> dev_err(dev->dev, "iosf failed to read punit
> semaphore\n");
> else
> diff --git a/drivers/i2c/busses/i2c-designware-core.h
> b/drivers/i2c/busses/i2c-designware-core.h
> index 47d284c..735fc63 100644
> --- a/drivers/i2c/busses/i2c-designware-core.h
> +++ b/drivers/i2c/busses/i2c-designware-core.h
> @@ -126,6 +126,7 @@ struct dw_i2c_dev {
> #define ACCESS_SWAP 0x00000001
> #define ACCESS_16BIT 0x00000002
> #define ACCESS_INTR_MASK 0x00000004
> +#define MODEL_CHERRYTRAIL 0x00000008
>
> extern int i2c_dw_init(struct dw_i2c_dev *dev);
> extern void i2c_dw_disable(struct dw_i2c_dev *dev);
> diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c
> b/drivers/i2c/busses/i2c-designware-pcidrv.c
> index 96f8230..4e53a9f 100644
> --- a/drivers/i2c/busses/i2c-designware-pcidrv.c
> +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
> @@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
> medfield,
> merrifield,
> baytrail,
> + cherrytrail,
> haswell,
> };
>
> @@ -63,6 +64,7 @@ struct dw_pci_controller {
> u32 rx_fifo_depth;
> u32 clk_khz;
> u32 functionality;
> + u32 flags;
> struct dw_scl_sda_cfg *scl_sda_cfg;
> int (*setup)(struct pci_dev *pdev, struct dw_pci_controller
> *c);
> };
> @@ -174,6 +176,15 @@ static struct dw_pci_controller
> dw_pci_controllers[] = {
> .functionality = I2C_FUNC_10BIT_ADDR,
> .scl_sda_cfg = &hsw_config,
> },
> + [cherrytrail] = {
> + .bus_num = -1,
> + .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
> + .tx_fifo_depth = 32,
> + .rx_fifo_depth = 32,
> + .functionality = I2C_FUNC_10BIT_ADDR,
> + .flags = MODEL_CHERRYTRAIL,
> + .scl_sda_cfg = &byt_config,
> + },
> };
>
> #ifdef CONFIG_PM
> @@ -241,6 +252,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
> dev->base = pcim_iomap_table(pdev)[0];
> dev->dev = &pdev->dev;
> dev->irq = pdev->irq;
> + dev->flags |= controller->flags;
>
> if (controller->setup) {
> r = controller->setup(pdev, controller);
> @@ -321,13 +333,13 @@ static const struct pci_device_id
> i2_designware_pci_ids[] = {
> { PCI_VDEVICE(INTEL, 0x9c61), haswell },
> { PCI_VDEVICE(INTEL, 0x9c62), haswell },
> /* Braswell / Cherrytrail */
> - { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
> - { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
> + { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
> + { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
> { 0,}
> };
> MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
> b/drivers/i2c/busses/i2c-designware-platdrv.c
> index 6d72929..589f07e 100644
> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -123,7 +123,7 @@ static const struct acpi_device_id
> dw_i2c_acpi_match[] = {
> { "INT3432", 0 },
> { "INT3433", 0 },
> { "80860F41", 0 },
> - { "808622C1", 0 },
> + { "808622C1", MODEL_CHERRYTRAIL },
> { "AMD0010", ACCESS_INTR_MASK },
> { "AMDI0010", ACCESS_INTR_MASK },
> { "AMDI0510", 0 },
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: [PATCH v6 4/9] dt-bindings: iio: iio-mux: document iio-mux bindings
From: Jonathan Cameron @ 2016-12-10 18:21 UTC (permalink / raw)
To: Peter Rosin, Rob Herring
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Wolfram Sang, Mark Rutland,
Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
Jonathan Corbet, Arnd Bergmann, Greg Kroah-Hartman,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <ea58cfe1-88ed-f215-59df-e9ffba485eaa-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
On 06/12/16 09:18, Peter Rosin wrote:
> On 2016-12-06 00:26, Rob Herring wrote:
>> On Wed, Nov 30, 2016 at 09:16:58AM +0100, Peter Rosin wrote:
>>> Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
>>> ---
>>> .../bindings/iio/multiplexer/iio-mux.txt | 40 ++++++++++++++++++++++
>>> MAINTAINERS | 6 ++++
>>> 2 files changed, 46 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
>>
>> I'm still not convinced about this binding, but don't really have more
>> comments ATM. Sending 6 versions in 2 weeks or so doesn't really help
>> either.
>
> Sorry about the noise, I'll try to be more careful going forward. On
> the flip side, I haven't touched the code since v6.
>
> I don't see how bindings that are as flexible as the current (and
> original) phandle link between the mux consumer and the mux controller
> would look, and at the same time be simpler to understand. You need
> to be able to refer to a mux controller from several mux consumers, and
> you need to support several mux controllers in one node (the ADG792A
> case). And, AFAICT, the complex case wasn't really the problem, it was
> that it is overly complex to describe the simple case of one mux
> consumer and one mux controller. But in your comment for v2 [1] you
> said that I was working around limitations with shared GPIO pins. But
> solving that in the GPIO subsystem would not solve all that the
> phandle approach is solving, since you would not have support for
> ADG792A (or other non-GPIO controlled muxes). So, I think listing
> the gpio pins inside the mux consumer node is a non-starter, the mux
> controller has to live in its own node with its own compatible.
>
> Would you be happier if I managed to marry the phandle approach with
> the option of having the mux controller as a child node of the mux
> consumer for the simple case?
>
> I added an example at the end of this message (the same as the first
> example in v4 [2], at least in principle) for easy comparison between
> the phandle and the controller-in-child-node approaches. I can't say
> that I personally find the difference all that significant, and do not
> think it is worth it. As I see it, the "simple option" would just muddy
> the waters...
>
> [1] http://marc.info/?l=linux-kernel&m=147948334204795&w=2
> [2] http://marc.info/?l=linux-kernel&m=148001364904240&w=2
>
>>> diff --git a/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt b/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
>>> new file mode 100644
>>> index 000000000000..8080cf790d82
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
>>> @@ -0,0 +1,40 @@
>>> +IIO multiplexer bindings
>>> +
>>> +If a multiplexer is used to select which hardware signal is fed to
>>> +e.g. an ADC channel, these bindings describe that situation.
>>> +
>>> +Required properties:
>>> +- compatible : "iio-mux"
>>
>> This is a Linuxism. perhaps "adc-mux".
>
> No, that's not general enough, it could just as well be used to mux a
> temperature sensor. Or whatever. Hmmm, given that "iio-mux" is bad, perhaps
> "io-channel-mux" is better? That matches the io-channels property used to
> refer to the parent channel.
analog-mux maybe? Makes more sense out of context (though with io-channels defined on
the next line you have plenty of context here ;)
>
>>> +- io-channels : Channel node of the parent channel that has multiplexed
>>> + input.
>>> +- io-channel-names : Should be "parent".
>>> +- #address-cells = <1>;
>>> +- #size-cells = <0>;
>>> +- mux-controls : Mux controller node to use for operating the mux
>>> +- channels : List of strings, labeling the mux controller states.
>>> +
>>> +The multiplexer state as described in ../misc/mux-controller.txt
>>> +
>>> +For each non-empty string in the channels property, an iio channel will
>>> +be created. The number of this iio channel is the same as the index into
>>> +the list of strings in the channels property, and also matches the mux
>>> +controller state.
>>> +
>>> +Example:
>>> + mux: mux-controller {
>>> + compatible = "mux-gpio";
>>> + #mux-control-cells = <0>;
>>> +
>>> + mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>,
>>> + <&pioA 1 GPIO_ACTIVE_HIGH>;
>>> + };
>>> +
>>> + adc-mux {
>>> + compatible = "iio-mux";
>>> + io-channels = <&adc 0>;
>>> + io-channel-names = "parent";
>>> +
>>> + mux-controls = <&mux>;
>>> +
>>> + channels = "sync", "in", system-regulator";
>>> + };
>
> Describing the same as above, but with the mux controller as a child
> node.
>
> adc-mux {
> compatible = "iio-mux";
> io-channels = <&adc 0>;
> io-channel-names = "parent";
>
> channels = "sync", "in", system-regulator";
>
> mux-controller {
> compatible = "mux-gpio";
>
> mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>,
> <&pioA 1 GPIO_ACTIVE_HIGH>;
> };
> };
>
> Cheers,
> Peter
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 3/5] i2c: designware-baytrail: Only check iosf_mbi_available() for shared hosts
From: Hans de Goede @ 2016-12-10 19:26 UTC (permalink / raw)
To: Andy Shevchenko, Jarkko Nikula, Wolfram Sang
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <1481381660.7188.7.camel@linux.intel.com>
Hi,
On 10-12-16 15:54, Andy Shevchenko wrote:
> On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
>> There is no need to delay the probe if iosf_mbi_available() returns
>> false when an i2c bus is not using the punit semaphore.
>
>> --- a/drivers/i2c/busses/i2c-designware-baytrail.c
>> +++ b/drivers/i2c/busses/i2c-designware-baytrail.c
>> @@ -139,14 +139,14 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev
>> *dev)
>> return 0;
>>
>> if (shared_host) {
>> + if (!iosf_mbi_available())
>> + return -EPROBE_DEFER;
>> +
>
> Looking to the implementation of i2c_dw_eval_lock_support() I would
> rewrite this like
>
> if (!shared_host)
> return 0;
I had the same thought when writing this patch, so ack, will fix for v3.
Regards,
Hans
>
>> dev_info(dev->dev, "I2C bus managed by PUNIT\n");
>> dev->acquire_lock = baytrail_i2c_acquire;
>> dev->release_lock = baytrail_i2c_release;
>> dev->pm_runtime_disabled = true;
>> }
>>
>> - if (!iosf_mbi_available())
>> - return -EPROBE_DEFER;
>> -
>> return 0;
>> }
>
^ permalink raw reply
* Re: [PATCH v2 4/5] i2c: designware-baytrail: Force the CPU to C1 state while holding the punit semaphore
From: Hans de Goede @ 2016-12-10 19:33 UTC (permalink / raw)
To: Andy Shevchenko, Jarkko Nikula, Wolfram Sang, Len Brown
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <1481381595.7188.6.camel@linux.intel.com>
Hi,
On 10-12-16 15:53, Andy Shevchenko wrote:
> +Cc: Len
> Len, I think you would be interested by this.
>
> Hans, thanks for the change!
You're welcome I ended up comparing the code in
i2c-dw_i2c-Ported-punit-locking-patch-from-MCG-kerne.patch from:
https://github.com/01org/ProductionKernelQuilts/tree/master/uefi/cht-m1stable/patches
against the mainline code while I was trying to fix the maddening
problem of the entire SoC hanging more or less as soon
as I tried to use the pmic i2c bus and there I found
some fiddling with pm_qos which let to this patch.
> Most probably we will anticipate Len's ACK
> on this one.
>
> On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
>> On my cherrytrail tablet with axp288 pmic, just doing a bunch of
>> repeated
>> reads from the pmic, e.g. "i2cdump -y 14 0x34" would lookup the tablet
>> in
>> 1 - 3 runs guaranteed.
>>
>> This seems to be causes by the cpuidle / intel_idle driver trying to
>> change the C-state while we hold the punit bus semaphore, at which
>> point
>> everything just hangs.
>>
>> Avoid this by forcing the CPU to C1 before acquiring the punit bus
>> semaphore.
>
> Isn't it C0? C1 as far as I remember is halted state.
You're right, I will fix it.
>> @@ -33,6 +34,13 @@ static int get_sem(struct dw_i2c_dev *dev, u32
>> *sem)
>> u32 data;
>> int ret;
>>
>> + /*
>> + * Force CPU to C1 state, otherwise if the cpuidle /
>> intel_idle
>> + * driver tries to change the C state while we're holding the
>> + * semaphore, the SoC hangs.
>
> C0?
>
>> + */
>> + pm_qos_update_request(&dev->pm_qos, 0);
>
> C1 is when you set 1 here, right?
I believe so, yes.
>
>> platform_device *pdev)
>> if (!dev->pm_runtime_disabled)
>> pm_runtime_disable(&pdev->dev);
>
>> + if (dev->acquire_lock)
>> + pm_qos_remove_request(&dev->pm_qos);
>> +
>
> Perhaps you need to do this in -core.c. Otherwise you missed PCI case.
> (Even with PCI enumerated host with ACPI-enabled firmware you may get
> _SEM object present)
Currently only i2c-designware-plardrv.c calls i2c_dw_eval_lock_support()
which does the pm_qos_add_request, so I put it here to keep things
balanced.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v2 4/5] i2c: designware-baytrail: Force the CPU to C1 state while holding the punit semaphore
From: Hans de Goede @ 2016-12-10 19:59 UTC (permalink / raw)
To: Andy Shevchenko, Jarkko Nikula, Wolfram Sang, Len Brown
Cc: Mika Westerberg, Takashi Iwai, russianneuromancer @ ya . ru,
Vincent Gerris, linux-i2c
In-Reply-To: <a1e46965-9cef-1ec0-ddb4-3a527cd71045@redhat.com>
Hi,
On 10-12-16 20:33, Hans de Goede wrote:
> Hi,
>
> On 10-12-16 15:53, Andy Shevchenko wrote:
>> +Cc: Len
>> Len, I think you would be interested by this.
>>
>> Hans, thanks for the change!
>
> You're welcome I ended up comparing the code in
> i2c-dw_i2c-Ported-punit-locking-patch-from-MCG-kerne.patch from:
>
> https://github.com/01org/ProductionKernelQuilts/tree/master/uefi/cht-m1stable/patches
>
> against the mainline code while I was trying to fix the maddening
> problem of the entire SoC hanging more or less as soon
> as I tried to use the pmic i2c bus and there I found
> some fiddling with pm_qos which let to this patch.
>
>> Most probably we will anticipate Len's ACK
>> on this one.
>>
>> On Sat, 2016-12-10 at 15:19 +0100, Hans de Goede wrote:
>>> On my cherrytrail tablet with axp288 pmic, just doing a bunch of
>>> repeated
>>> reads from the pmic, e.g. "i2cdump -y 14 0x34" would lookup the tablet
>>> in
>>> 1 - 3 runs guaranteed.
>>>
>>> This seems to be causes by the cpuidle / intel_idle driver trying to
>>> change the C-state while we hold the punit bus semaphore, at which
>>> point
>>> everything just hangs.
>>>
>>> Avoid this by forcing the CPU to C1 before acquiring the punit bus
>>> semaphore.
>>
>> Isn't it C0? C1 as far as I remember is halted state.
>
> You're right, I will fix it.
Correction, upon closer reading of the docs, we cannot disallow
the CPU to enter C1 / force it to either C0 or C1, what we can
disallow is for it to enter C6/C7. Which also makes sense wrt
this bug, since entering C6/C7 involves turning of the
CPU-core power-plane, which requires the punit to access the pmic.
So I've changes the text in both the commit msg and the comment
to: "Disallow the CPU to enter C6 or C7"
I still need to re-test (just to make sure I did not cause
any regressions) and then I'll send a v3.
Regards,
Hans
>>> @@ -33,6 +34,13 @@ static int get_sem(struct dw_i2c_dev *dev, u32
>>> *sem)
>>> u32 data;
>>> int ret;
>>>
>>> + /*
>>> + * Force CPU to C1 state, otherwise if the cpuidle /
>>> intel_idle
>>> + * driver tries to change the C state while we're holding the
>>> + * semaphore, the SoC hangs.
>>
>> C0?
>>
>>> + */
>>> + pm_qos_update_request(&dev->pm_qos, 0);
>>
>> C1 is when you set 1 here, right?
>
> I believe so, yes.
>
>>
>>> platform_device *pdev)
>>> if (!dev->pm_runtime_disabled)
>>> pm_runtime_disable(&pdev->dev);
>>
>>> + if (dev->acquire_lock)
>>> + pm_qos_remove_request(&dev->pm_qos);
>>> +
>>
>> Perhaps you need to do this in -core.c. Otherwise you missed PCI case.
>> (Even with PCI enumerated host with ACPI-enabled firmware you may get
>> _SEM object present)
>
> Currently only i2c-designware-plardrv.c calls i2c_dw_eval_lock_support()
> which does the pm_qos_add_request, so I put it here to keep things
> balanced.
>
> Regards,
>
> Hans
^ permalink raw reply
* [PATCH v3 1/5] i2c: designware: Rename accessor_flags to flags
From: Hans de Goede @ 2016-12-10 22:43 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
Rename accessor_flags to flags, so that we can use the field for
other flags too. This is a preparation patch for adding cherrytrail
support to the punit semaphore code.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/i2c/busses/i2c-designware-core.c | 14 +++++++-------
drivers/i2c/busses/i2c-designware-core.h | 2 +-
drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index b403fa5..b6a7989 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -177,13 +177,13 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
{
u32 value;
- if (dev->accessor_flags & ACCESS_16BIT)
+ if (dev->flags & ACCESS_16BIT)
value = readw_relaxed(dev->base + offset) |
(readw_relaxed(dev->base + offset + 2) << 16);
else
value = readl_relaxed(dev->base + offset);
- if (dev->accessor_flags & ACCESS_SWAP)
+ if (dev->flags & ACCESS_SWAP)
return swab32(value);
else
return value;
@@ -191,10 +191,10 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
{
- if (dev->accessor_flags & ACCESS_SWAP)
+ if (dev->flags & ACCESS_SWAP)
b = swab32(b);
- if (dev->accessor_flags & ACCESS_16BIT) {
+ if (dev->flags & ACCESS_16BIT) {
writew_relaxed((u16)b, dev->base + offset);
writew_relaxed((u16)(b >> 16), dev->base + offset + 2);
} else {
@@ -339,10 +339,10 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
reg = dw_readl(dev, DW_IC_COMP_TYPE);
if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
/* Configure register endianess access */
- dev->accessor_flags |= ACCESS_SWAP;
+ dev->flags |= ACCESS_SWAP;
} else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
/* Configure register access mode 16bit */
- dev->accessor_flags |= ACCESS_16BIT;
+ dev->flags |= ACCESS_16BIT;
} else if (reg != DW_IC_COMP_TYPE_VALUE) {
dev_err(dev->dev, "Unknown Synopsys component type: "
"0x%08x\n", reg);
@@ -886,7 +886,7 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
tx_aborted:
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
complete(&dev->cmd_complete);
- else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+ else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
/* workaround to trigger pending interrupt */
stat = dw_readl(dev, DW_IC_INTR_MASK);
i2c_dw_disable_int(dev);
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 0d44d2a..fb143f5 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -95,7 +95,7 @@ struct dw_i2c_dev {
unsigned int status;
u32 abort_source;
int irq;
- u32 accessor_flags;
+ u32 flags;
struct i2c_adapter adapter;
u32 functionality;
u32 master_cfg;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 0b42a12..97a2ca1 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -112,7 +112,7 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
- dev->accessor_flags |= (u32)id->driver_data;
+ dev->flags |= (u32)id->driver_data;
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v3 2/5] i2c: designware-baytrail: Pass dw_i2c_dev into helper functions
From: Hans de Goede @ 2016-12-10 22:43 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210224350.10290-1-hdegoede@redhat.com>
Pass dw_i2c_dev into the helper functions, this is a preparation patch
for the punit semaphore fixes done in the other patches in this set.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/i2c/busses/i2c-designware-baytrail.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 1590ad0..a3f581c 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -28,14 +28,14 @@
static unsigned long acquired;
-static int get_sem(struct device *dev, u32 *sem)
+static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
{
u32 data;
int ret;
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
if (ret) {
- dev_err(dev, "iosf failed to read punit semaphore\n");
+ dev_err(dev->dev, "iosf failed to read punit semaphore\n");
return ret;
}
@@ -44,18 +44,18 @@ static int get_sem(struct device *dev, u32 *sem)
return 0;
}
-static void reset_semaphore(struct device *dev)
+static void reset_semaphore(struct dw_i2c_dev *dev)
{
u32 data;
if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
- dev_err(dev, "iosf failed to reset punit semaphore during read\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during read\n");
return;
}
data &= ~PUNIT_SEMAPHORE_BIT;
if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
- dev_err(dev, "iosf failed to reset punit semaphore during write\n");
+ dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
}
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -83,7 +83,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
start = jiffies;
end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
do {
- ret = get_sem(dev->dev, &sem);
+ ret = get_sem(dev, &sem);
if (!ret && sem) {
acquired = jiffies;
dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
@@ -95,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
} while (time_before(jiffies, end));
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
if (ret)
@@ -116,7 +116,7 @@ static void baytrail_i2c_release(struct dw_i2c_dev *dev)
if (!dev->acquire_lock)
return;
- reset_semaphore(dev->dev);
+ reset_semaphore(dev);
dev_dbg(dev->dev, "punit semaphore held for %ums\n",
jiffies_to_msecs(jiffies - acquired));
}
--
2.9.3
^ permalink raw reply related
* [PATCH v3 3/5] i2c: designware-baytrail: Only check iosf_mbi_available() for shared hosts
From: Hans de Goede @ 2016-12-10 22:43 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210224350.10290-1-hdegoede@redhat.com>
If (!shared_host) simply return 0, this avoids delaying the probe if
iosf_mbi_available() returns false when an i2c bus is not using the
punit semaphore.
Also move the if (!iosf_mbi_available()) check to above the
dev_info, so that we do not repeat the dev_info on every probe
until iosf_mbi_available() returns true.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-New patch in v2 of this set
Changes in v3:
-Use if (!shared_host) return 0, to simplify the non-shared_host path
and to avoid nested ifs
---
drivers/i2c/busses/i2c-designware-baytrail.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index a3f581c..cf02222 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -138,15 +138,16 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
if (ACPI_FAILURE(status))
return 0;
- if (shared_host) {
- dev_info(dev->dev, "I2C bus managed by PUNIT\n");
- dev->acquire_lock = baytrail_i2c_acquire;
- dev->release_lock = baytrail_i2c_release;
- dev->pm_runtime_disabled = true;
- }
+ if (!shared_host)
+ return 0;
if (!iosf_mbi_available())
return -EPROBE_DEFER;
+ dev_info(dev->dev, "I2C bus managed by PUNIT\n");
+ dev->acquire_lock = baytrail_i2c_acquire;
+ dev->release_lock = baytrail_i2c_release;
+ dev->pm_runtime_disabled = true;
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v3 4/5] i2c: designware-baytrail: Disallow the CPU to enter C6 or C7 while holding the punit semaphore
From: Hans de Goede @ 2016-12-10 22:43 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210224350.10290-1-hdegoede@redhat.com>
On my cherrytrail tablet with axp288 pmic, just doing a bunch of repeated
reads from the pmic, e.g. "i2cdump -y 14 0x34" would lookup the tablet in
1 - 3 runs guaranteed.
This seems to be causes by the cpu trying to enter C6 or C7 while we hold
the punit bus semaphore, at which point everything just hangs.
Avoid this by the CPU to enter C6 or C7 before acquiring the punit bus
semaphore.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=109051
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-New patch in v2 of this set
Changes in v3:
-Change commit message and comment in the code from "force the CPU to C1"
to "Disallow the CPU to enter C6 or C7", as the CPU may still be in either
C0 or C1 with the request pm_qos
---
drivers/i2c/busses/i2c-designware-baytrail.c | 12 ++++++++++++
drivers/i2c/busses/i2c-designware-core.h | 3 +++
drivers/i2c/busses/i2c-designware-platdrv.c | 3 +++
3 files changed, 18 insertions(+)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index cf02222..997d048 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/pm_qos.h>
#include <asm/iosf_mbi.h>
@@ -33,6 +34,13 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
u32 data;
int ret;
+ /*
+ * Disallow the CPU to enter C6 or C7 state, entering these states
+ * requires the punit to talk to the pmic and if this happens while
+ * we're holding the semaphore, the SoC hangs.
+ */
+ pm_qos_update_request(&dev->pm_qos, 0);
+
ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
if (ret) {
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
@@ -56,6 +64,8 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
data &= ~PUNIT_SEMAPHORE_BIT;
if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
+
+ pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
}
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -145,6 +155,8 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
return -EPROBE_DEFER;
dev_info(dev->dev, "I2C bus managed by PUNIT\n");
+ pm_qos_add_request(&dev->pm_qos, PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
dev->acquire_lock = baytrail_i2c_acquire;
dev->release_lock = baytrail_i2c_release;
dev->pm_runtime_disabled = true;
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index fb143f5..47d284c 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -22,6 +22,7 @@
*
*/
+#include <linux/pm_qos.h>
#define DW_IC_CON_MASTER 0x1
#define DW_IC_CON_SPEED_STD 0x2
@@ -67,6 +68,7 @@
* @fp_lcnt: fast plus LCNT value
* @hs_hcnt: high speed HCNT value
* @hs_lcnt: high speed LCNT value
+ * @pm_qos: pm_qos_request used while holding a hardware lock on the bus
* @acquire_lock: function to acquire a hardware lock on the bus
* @release_lock: function to release a hardware lock on the bus
* @pm_runtime_disabled: true if pm runtime is disabled
@@ -114,6 +116,7 @@ struct dw_i2c_dev {
u16 fp_lcnt;
u16 hs_hcnt;
u16 hs_lcnt;
+ struct pm_qos_request pm_qos;
int (*acquire_lock)(struct dw_i2c_dev *dev);
void (*release_lock)(struct dw_i2c_dev *dev);
bool pm_runtime_disabled;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 97a2ca1..6d72929 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -291,6 +291,9 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
+ if (dev->acquire_lock)
+ pm_qos_remove_request(&dev->pm_qos);
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v3 5/5] i2c: designware-baytrail: Add support for cherrytrail
From: Hans de Goede @ 2016-12-10 22:43 UTC (permalink / raw)
To: Jarkko Nikula, Wolfram Sang
Cc: Andy Shevchenko, Mika Westerberg, Takashi Iwai,
russianneuromancer @ ya . ru, Vincent Gerris, linux-i2c,
Hans de Goede
In-Reply-To: <20161210224350.10290-1-hdegoede@redhat.com>
The cherrytrail punit has the pmic i2c bus access semaphore at a
different register address.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Takashi Iwai <tiwai@suse.de>
---
Changes in v2:
-Adjust for accessor_flags -> flags rename
-Add flags field to struct dw_pci_controller
-Add get_sem_addr() helper replacing MODEL_CHERRYTRAIL flag checking in
PUNIT_SEMAPHORE macro
Changes in v3:
-Add a gap between ACCESS_* and MODEL_* flags as reserved space for
future ACCESS_* flags
---
drivers/i2c/busses/i2c-designware-baytrail.c | 22 +++++++++++++++++-----
drivers/i2c/busses/i2c-designware-core.h | 2 ++
drivers/i2c/busses/i2c-designware-pcidrv.c | 26 +++++++++++++++++++-------
drivers/i2c/busses/i2c-designware-platdrv.c | 2 +-
4 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 997d048..456a236 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -24,13 +24,23 @@
#define SEMAPHORE_TIMEOUT 100
#define PUNIT_SEMAPHORE 0x7
+#define PUNIT_SEMAPHORE_CHV 0x10e
#define PUNIT_SEMAPHORE_BIT BIT(0)
#define PUNIT_SEMAPHORE_ACQUIRE BIT(1)
static unsigned long acquired;
+static u32 get_sem_addr(struct dw_i2c_dev *dev)
+{
+ if (dev->flags & MODEL_CHERRYTRAIL)
+ return PUNIT_SEMAPHORE_CHV;
+ else
+ return PUNIT_SEMAPHORE;
+}
+
static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
{
+ u32 addr = get_sem_addr(dev);
u32 data;
int ret;
@@ -41,7 +51,7 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
*/
pm_qos_update_request(&dev->pm_qos, 0);
- ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data);
+ ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &data);
if (ret) {
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
return ret;
@@ -54,15 +64,16 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
static void reset_semaphore(struct dw_i2c_dev *dev)
{
+ u32 addr = get_sem_addr(dev);
u32 data;
- if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
+ if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &data)) {
dev_err(dev->dev, "iosf failed to reset punit semaphore during read\n");
return;
}
data &= ~PUNIT_SEMAPHORE_BIT;
- if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
+ if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, data))
dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
@@ -70,6 +81,7 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
{
+ u32 addr = get_sem_addr(dev);
u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
int ret;
unsigned long start, end;
@@ -83,7 +95,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
return 0;
/* host driver writes to side band semaphore register */
- ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, sem);
+ ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, sem);
if (ret) {
dev_err(dev->dev, "iosf punit semaphore request failed\n");
return ret;
@@ -107,7 +119,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
dev_err(dev->dev, "punit semaphore timed out, resetting\n");
reset_semaphore(dev);
- ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
+ ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &sem);
if (ret)
dev_err(dev->dev, "iosf failed to read punit semaphore\n");
else
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 47d284c..2db3177 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -127,6 +127,8 @@ struct dw_i2c_dev {
#define ACCESS_16BIT 0x00000002
#define ACCESS_INTR_MASK 0x00000004
+#define MODEL_CHERRYTRAIL 0x00000100
+
extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern void i2c_dw_disable(struct dw_i2c_dev *dev);
extern void i2c_dw_disable_int(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 96f8230..4e53a9f 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -45,6 +45,7 @@ enum dw_pci_ctl_id_t {
medfield,
merrifield,
baytrail,
+ cherrytrail,
haswell,
};
@@ -63,6 +64,7 @@ struct dw_pci_controller {
u32 rx_fifo_depth;
u32 clk_khz;
u32 functionality;
+ u32 flags;
struct dw_scl_sda_cfg *scl_sda_cfg;
int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c);
};
@@ -174,6 +176,15 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &hsw_config,
},
+ [cherrytrail] = {
+ .bus_num = -1,
+ .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
+ .tx_fifo_depth = 32,
+ .rx_fifo_depth = 32,
+ .functionality = I2C_FUNC_10BIT_ADDR,
+ .flags = MODEL_CHERRYTRAIL,
+ .scl_sda_cfg = &byt_config,
+ },
};
#ifdef CONFIG_PM
@@ -241,6 +252,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pdev->irq;
+ dev->flags |= controller->flags;
if (controller->setup) {
r = controller->setup(pdev, controller);
@@ -321,13 +333,13 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9c61), haswell },
{ PCI_VDEVICE(INTEL, 0x9c62), haswell },
/* Braswell / Cherrytrail */
- { PCI_VDEVICE(INTEL, 0x22C1), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C2), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C3), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C4), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C5), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C6), baytrail },
- { PCI_VDEVICE(INTEL, 0x22C7), baytrail },
+ { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
+ { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 6d72929..589f07e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -123,7 +123,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3432", 0 },
{ "INT3433", 0 },
{ "80860F41", 0 },
- { "808622C1", 0 },
+ { "808622C1", MODEL_CHERRYTRAIL },
{ "AMD0010", ACCESS_INTR_MASK },
{ "AMDI0010", ACCESS_INTR_MASK },
{ "AMDI0510", 0 },
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox