Linux I2C development
 help / color / mirror / Atom feed
* [PATCH v3 06/12] i2c: designware-baytrail: Disallow the CPU to enter C6 or C7 while holding the punit semaphore
From: Hans de Goede @ 2017-02-10 10:27 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: russianneuromancer @ ya . ru, intel-gfx, dri-devel, Hans de Goede,
	linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-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 disallowing 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>
Tested-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
---
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
Changes in v4:
-Rename i2c_dw_eval_lock_support to i2c_dw_probe_lock_support so that we can
 add a matching i2c_dw_remove_lock_support cleanup function
-Move qm_pos removal to new i2c_dw_remove_lock_support function
-Move pm_qos_add_request to the end of i2c_dw_probe_lock_support
Changes in v5:
-Update the pm_qos for a latency of 0 *before* requesting the semaphore,
 instead of doing it while waiting for the request to be acked
---
 drivers/i2c/busses/i2c-designware-baytrail.c | 24 ++++++++++++++++++++++--
 drivers/i2c/busses/i2c-designware-core.h     |  9 +++++++--
 drivers/i2c/busses/i2c-designware-platdrv.c  |  4 +++-
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index cf02222..650a700 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>
 
@@ -56,6 +57,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)
@@ -72,11 +75,18 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
 	if (!dev->release_lock)
 		return 0;
 
+	/*
+	 * 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);
+
 	/* host driver writes to side band semaphore register */
 	ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, sem);
 	if (ret) {
 		dev_err(dev->dev, "iosf punit semaphore request failed\n");
-		return ret;
+		goto out;
 	}
 
 	/* host driver waits for bit 0 to be set in semaphore register */
@@ -95,6 +105,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");
+out:
 	reset_semaphore(dev);
 
 	ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
@@ -121,7 +132,7 @@ static void baytrail_i2c_release(struct dw_i2c_dev *dev)
 		jiffies_to_msecs(jiffies - acquired));
 }
 
-int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
+int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev)
 {
 	acpi_status status;
 	unsigned long long shared_host = 0;
@@ -149,5 +160,14 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev)
 	dev->release_lock = baytrail_i2c_release;
 	dev->pm_runtime_disabled = true;
 
+	pm_qos_add_request(&dev->pm_qos, PM_QOS_CPU_DMA_LATENCY,
+			   PM_QOS_DEFAULT_VALUE);
+
 	return 0;
 }
+
+void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev)
+{
+	if (dev->acquire_lock)
+		pm_qos_remove_request(&dev->pm_qos);
+}
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 2c50571..94a5fd1 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -23,6 +23,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/pm_qos.h>
 
 #define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C |			\
 					I2C_FUNC_SMBUS_BYTE |		\
@@ -75,6 +76,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
@@ -122,6 +124,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;
@@ -139,7 +142,9 @@ extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev);
 extern int i2c_dw_probe(struct dw_i2c_dev *dev);
 
 #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL)
-extern int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev);
+extern int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev);
+extern void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev);
 #else
-static inline int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) { return 0; }
+static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; }
+static inline void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) {}
 #endif
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 3eede7b..d474db0 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -238,7 +238,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	r = i2c_dw_eval_lock_support(dev);
+	r = i2c_dw_probe_lock_support(dev);
 	if (r)
 		return r;
 
@@ -307,6 +307,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
 	if (!dev->pm_runtime_disabled)
 		pm_runtime_disable(&pdev->dev);
 
+	i2c_dw_remove_lock_support(dev);
+
 	return 0;
 }
 
-- 
2.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* [PATCH v3 07/12] i2c: designware-baytrail: Fix race when resetting the semaphore
From: Hans de Goede @ 2017-02-10 10:27 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: russianneuromancer @ ya . ru, intel-gfx, dri-devel, Hans de Goede,
	linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-1-hdegoede@redhat.com>

Use iosf_mbi_modify instead of iosf_mbi_read + iosf_mbi_write so that
we keep the iosf_mbi_lock locked during the read-modify-write done to
reset the semaphore.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
---
Changes in v5:
-New patch in v5 of this patch-set
---
 drivers/i2c/busses/i2c-designware-baytrail.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 650a700..8df529c 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -47,15 +47,8 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
 
 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->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_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE,
+			    0, PUNIT_SEMAPHORE_BIT))
 		dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
 
 	pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
-- 
2.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* [PATCH v3 08/12] i2c: designware-baytrail: Add support for cherrytrail
From: Hans de Goede @ 2017-02-10 10:27 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: russianneuromancer @ ya . ru, intel-gfx, dri-devel, Hans de Goede,
	linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-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>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.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
Changes in v4:
-s/CHV/CHT/
---
 drivers/i2c/busses/i2c-designware-baytrail.c | 19 +++++++++++++++----
 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, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 8df529c..3effc9a 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -24,17 +24,27 @@
 
 #define SEMAPHORE_TIMEOUT	100
 #define PUNIT_SEMAPHORE		0x7
+#define PUNIT_SEMAPHORE_CHT	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_CHT;
+	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;
 
-	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;
@@ -47,7 +57,7 @@ static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
 
 static void reset_semaphore(struct dw_i2c_dev *dev)
 {
-	if (iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE,
+	if (iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, get_sem_addr(dev),
 			    0, PUNIT_SEMAPHORE_BIT))
 		dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
 
@@ -56,6 +66,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;
@@ -76,7 +87,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
 	pm_qos_update_request(&dev->pm_qos, 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");
 		goto out;
@@ -101,7 +112,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
 out:
 	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 94a5fd1..a8e74ca 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -135,6 +135,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 d6423cf..ed485b6 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);
 };
@@ -170,6 +172,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
@@ -237,6 +248,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);
@@ -317,13 +329,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 d474db0..df0ff7d 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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* [PATCH v3 09/12] i2c: designware-baytrail: Acquire P-Unit access on bus acquire
From: Hans de Goede @ 2017-02-10 10:27 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: Takashi Iwai, russianneuromancer @ ya . ru, intel-gfx, dri-devel,
	Hans de Goede, linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-1-hdegoede@redhat.com>

Acquire P-Unit access to stop others from accessing the P-Unit while the
PMIC i2c bus is in use. This is necessary because accessing the P-Unit
from the kernel may result in the P-Unit trying to access the PMIC i2c
bus, which results in a hang when it happens while we own the PMIC i2c
bus semaphore.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=155241
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: tagorereddy <tagore.chandan@gmail.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
---
Changes in v2:
-Spelling: P-Unit, PMIC
-Adjust for iosf_mbi_punit_lock/_unlock to _acquire/_release rename
---
 drivers/i2c/busses/i2c-designware-baytrail.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 3effc9a..7eddc3b 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -62,6 +62,8 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
 		dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
 
 	pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
+
+	iosf_mbi_punit_release();
 }
 
 static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
@@ -79,6 +81,8 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
 	if (!dev->release_lock)
 		return 0;
 
+	iosf_mbi_punit_acquire();
+
 	/*
 	 * 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
-- 
2.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related

* [PATCH v3 10/12] i2c: designware-baytrail: Call pmic_bus_access_notifier_chain
From: Hans de Goede @ 2017-02-10 10:28 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: Takashi Iwai, russianneuromancer @ ya . ru, intel-gfx, dri-devel,
	Hans de Goede, linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-1-hdegoede@redhat.com>

Call the iosf_mbi pmic_bus_access_notifier_chain on bus acquire / release.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=155241
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: tagorereddy <tagore.chandan@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
---
Changes in v2:
-Spelling: P-Unit, PMIC
---
 drivers/i2c/busses/i2c-designware-baytrail.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c
index 7eddc3b..1749a0f 100644
--- a/drivers/i2c/busses/i2c-designware-baytrail.c
+++ b/drivers/i2c/busses/i2c-designware-baytrail.c
@@ -63,6 +63,8 @@ static void reset_semaphore(struct dw_i2c_dev *dev)
 
 	pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
 
+	iosf_mbi_call_pmic_bus_access_notifier_chain(MBI_PMIC_BUS_ACCESS_END,
+						     NULL);
 	iosf_mbi_punit_release();
 }
 
@@ -82,6 +84,8 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
 		return 0;
 
 	iosf_mbi_punit_acquire();
+	iosf_mbi_call_pmic_bus_access_notifier_chain(MBI_PMIC_BUS_ACCESS_BEGIN,
+						     NULL);
 
 	/*
 	 * Disallow the CPU to enter C6 or C7 state, entering these states
-- 
2.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related

* [PATCH v3 11/12] drm/i915: Add intel_uncore_suspend / resume functions
From: Hans de Goede @ 2017-02-10 10:28 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: Takashi Iwai, russianneuromancer @ ya . ru, intel-gfx, dri-devel,
	Hans de Goede, linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-1-hdegoede@redhat.com>

Rename intel_uncore_early_sanitize to intel_uncore_resume, dropping the
(always true) restore_forcewake argument and add a new intel_uncore_resume
function to replace the intel_uncore_forcewake_reset(dev_priv, false)
calls done from the suspend / runtime_suspend functions and make
intel_uncore_forcewake_reset private.

This is a preparation patch for adding PMIC bus access notifier support.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=155241
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: tagorereddy <tagore.chandan@gmail.com>
---
Changes in v2:
-Spelling: P-Unit, PMIC
Changes in v3:
-Rename intel_uncore_resume to intel_uncore_resume_early
-Keep intel_uncore_forcewake_reset name as is
---
 drivers/gpu/drm/i915/i915_drv.c     |  6 +++---
 drivers/gpu/drm/i915/i915_drv.h     |  6 ++----
 drivers/gpu/drm/i915/intel_uncore.c | 14 +++++++++-----
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a17dde8..8d75249 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1506,7 +1506,7 @@ static int i915_drm_suspend(struct drm_device *dev)
 	opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
 	intel_opregion_notify_adapter(dev_priv, opregion_target_state);
 
-	intel_uncore_forcewake_reset(dev_priv, false);
+	intel_uncore_suspend(dev_priv);
 	intel_opregion_unregister(dev_priv);
 
 	intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
@@ -1751,7 +1751,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
 		DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
 			  ret);
 
-	intel_uncore_early_sanitize(dev_priv, true);
+	intel_uncore_resume_early(dev_priv);
 
 	if (IS_GEN9_LP(dev_priv)) {
 		if (!dev_priv->suspended_to_idle)
@@ -2396,7 +2396,7 @@ static int intel_runtime_suspend(struct device *kdev)
 		return ret;
 	}
 
-	intel_uncore_forcewake_reset(dev_priv, false);
+	intel_uncore_suspend(dev_priv);
 
 	enable_rpm_wakeref_asserts(dev_priv);
 	WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 604b20f..998239f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3010,14 +3010,12 @@ int intel_irq_install(struct drm_i915_private *dev_priv);
 void intel_irq_uninstall(struct drm_i915_private *dev_priv);
 
 extern void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
-extern void intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
-					bool restore_forcewake);
 extern void intel_uncore_init(struct drm_i915_private *dev_priv);
 extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
 extern bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
 extern void intel_uncore_fini(struct drm_i915_private *dev_priv);
-extern void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
-					 bool restore);
+extern void intel_uncore_suspend(struct drm_i915_private *dev_priv);
+extern void intel_uncore_resume_early(struct drm_i915_private *dev_priv);
 const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
 void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
 				enum forcewake_domains domains);
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 1ff8fd9..b6d726b 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -257,8 +257,8 @@ intel_uncore_fw_release_timer(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
-void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
-				  bool restore)
+static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
+					 bool restore)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
@@ -434,10 +434,14 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
 	intel_uncore_forcewake_reset(dev_priv, restore_forcewake);
 }
 
-void intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
-				 bool restore_forcewake)
+void intel_uncore_suspend(struct drm_i915_private *dev_priv)
 {
-	__intel_uncore_early_sanitize(dev_priv, restore_forcewake);
+	intel_uncore_forcewake_reset(dev_priv, false);
+}
+
+void intel_uncore_resume_early(struct drm_i915_private *dev_priv)
+{
+	__intel_uncore_early_sanitize(dev_priv, true);
 	i915_check_and_clear_faults(dev_priv);
 }
 
-- 
2.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related

* [PATCH v3 12/12] drm/i915: Listen for PMIC bus access notifications
From: Hans de Goede @ 2017-02-10 10:28 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: Takashi Iwai, russianneuromancer @ ya . ru, intel-gfx, dri-devel,
	Hans de Goede, linux-i2c, Mika Westerberg
In-Reply-To: <20170210102802.20898-1-hdegoede@redhat.com>

Listen for PMIC bus access notifications and get FORCEWAKE_ALL while
the bus is accessed to avoid needing to do any forcewakes, which need
PMIC bus access, while the PMIC bus is busy:

This fixes errors like these showing up in dmesg, usually followed
by a gfx or system freeze:

[drm:fw_domains_get [i915]] *ERROR* render: timed out waiting for forcewake ack request.
[drm:fw_domains_get [i915]] *MEDIA* render: timed out waiting for forcewake ack request.
i2c_designware 808622C1:06: punit semaphore timed out, resetting
i2c_designware 808622C1:06: PUNIT SEM: 2
i2c_designware 808622C1:06: couldn't acquire bus ownership

Downside of this approach is that it causes wakeups whenever the PMIC
bus is accessed. Unfortunately we cannot simply wait for the PMIC bus
to go idle when we hit a race, as forcewakes may be done from interrupt
handlers where we cannot sleep to wait for the i2c PMIC bus access to
finish.

Note that the notifications and thus the wakeups will only happen on
baytrail / cherrytrail devices using PMICs with a shared i2c bus for
P-Unit and host PMIC access (i2c busses with a _SEM method in their
APCI node), e.g. an axp288 PMIC.

I plan to write some patches for drivers accessing the PMIC bus to
limit their bus accesses to a bare minimum (e.g. cache registers, do not
update battery level more often then 4 times a minute), to limit the
amount of wakeups.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=155241
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: tagorereddy <tagore.chandan@gmail.com>
---
Changes in v2:
-Spelling: P-Unit, PMIC
Changes in v3:
-Improve comment explaining why we call intel_uncore_forcewake_get(ALL) on
 MBI_PMIC_BUS_ACCESS_BEGIN notification
---
 drivers/gpu/drm/i915/Kconfig        |  1 +
 drivers/gpu/drm/i915/i915_drv.h     |  1 +
 drivers/gpu/drm/i915/intel_uncore.c | 39 +++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 1ae0bb9..a5cd5da 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -20,6 +20,7 @@ config DRM_I915
 	select ACPI_VIDEO if ACPI
 	select ACPI_BUTTON if ACPI
 	select SYNC_FILE
+	select IOSF_MBI
 	help
 	  Choose this option if you have a system that has "Intel Graphics
 	  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 998239f..4e405d0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -725,6 +725,7 @@ struct intel_uncore {
 	const struct intel_forcewake_range *fw_domains_table;
 	unsigned int fw_domains_table_entries;
 
+	struct notifier_block pmic_bus_access_nb;
 	struct intel_uncore_funcs funcs;
 
 	unsigned fifo_count;
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index b6d726b..1be3cdc 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -25,6 +25,7 @@
 #include "intel_drv.h"
 #include "i915_vgpu.h"
 
+#include <asm/iosf_mbi.h>
 #include <linux/pm_runtime.h>
 
 #define FORCEWAKE_ACK_TIMEOUT_MS 50
@@ -436,12 +437,16 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
 
 void intel_uncore_suspend(struct drm_i915_private *dev_priv)
 {
+	iosf_mbi_unregister_pmic_bus_access_notifier(
+		&dev_priv->uncore.pmic_bus_access_nb);
 	intel_uncore_forcewake_reset(dev_priv, false);
 }
 
 void intel_uncore_resume_early(struct drm_i915_private *dev_priv)
 {
 	__intel_uncore_early_sanitize(dev_priv, true);
+	iosf_mbi_register_pmic_bus_access_notifier(
+		&dev_priv->uncore.pmic_bus_access_nb);
 	i915_check_and_clear_faults(dev_priv);
 }
 
@@ -1329,6 +1334,32 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
 	dev_priv->uncore.fw_domains_table_entries = ARRAY_SIZE((d)); \
 }
 
+static int i915_pmic_bus_access_notifier(struct notifier_block *nb,
+					 unsigned long action, void *data)
+{
+	struct drm_i915_private *dev_priv = container_of(nb,
+			struct drm_i915_private, uncore.pmic_bus_access_nb);
+
+	switch (action) {
+	case MBI_PMIC_BUS_ACCESS_BEGIN:
+		/*
+		 * forcewake all now to make sure that we don't need to do a
+		 * forcewake later which on systems where this notifier gets
+		 * called requires the punit to access to the shared pmic i2c
+		 * bus, which will be busy after this notification, leading to:
+		 * "render: timed out waiting for forcewake ack request."
+		 * errors.
+		 */
+		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+		break;
+	case MBI_PMIC_BUS_ACCESS_END:
+		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 void intel_uncore_init(struct drm_i915_private *dev_priv)
 {
 	i915_check_vgpu(dev_priv);
@@ -1338,6 +1369,8 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
 	__intel_uncore_early_sanitize(dev_priv, false);
 
 	dev_priv->uncore.unclaimed_mmio_check = 1;
+	dev_priv->uncore.pmic_bus_access_nb.notifier_call =
+		i915_pmic_bus_access_notifier;
 
 	switch (INTEL_INFO(dev_priv)->gen) {
 	default:
@@ -1392,6 +1425,9 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
 	if (INTEL_GEN(dev_priv) >= 8)
 		intel_shadow_table_check();
 
+	iosf_mbi_register_pmic_bus_access_notifier(
+		&dev_priv->uncore.pmic_bus_access_nb);
+
 	i915_check_and_clear_faults(dev_priv);
 }
 #undef ASSIGN_WRITE_MMIO_VFUNCS
@@ -1399,6 +1435,9 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
 
 void intel_uncore_fini(struct drm_i915_private *dev_priv)
 {
+	iosf_mbi_unregister_pmic_bus_access_notifier(
+		&dev_priv->uncore.pmic_bus_access_nb);
+
 	/* Paranoia: make sure we have disabled everything before we exit. */
 	intel_uncore_sanitize(dev_priv);
 	intel_uncore_forcewake_reset(dev_priv, false);
-- 
2.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related

* [PATCH v3 00/12] coordinate cht i2c-pmic and i915-punit accesses
From: Hans de Goede @ 2017-02-10 10:27 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Ville Syrjälä,
	Jarkko Nikula, Wolfram Sang, Len Brown, Andy Shevchenko,
	Thomas Gleixner, H . Peter Anvin
  Cc: Hans de Goede, intel-gfx, dri-devel, Mika Westerberg,
	Takashi Iwai, russianneuromancer @ ya . ru, linux-i2c

Hi All,

Here is v3 of my cht i2c-pmic and i915-punit access coordination
patchset. New in this version is the dropping of the punit_acquire /
_release calls around punit accesses in the i915 driver, these seem
to be unnecessary in this case acquiring the pmic-bus semaphore in
the punit seems to be enough. We do definitely need the forcewake stuff
done by "drm/i915: Listen for PMIC bus access notifications", without
that cht devices which have a pmic which makes the kernel share the bus
with the punit see forcewake timeouts followed by a lockup.

Also new in this version is some renames + extra comments in patch 11 and 12
as reqested by Ville.

This patch-set includes 6 i2c patches, these patches are ready for merging,
they have Wolfram's (the i2c maintainer's) ack. The problem is the 6th i2c
patch which fixes the punit semaphore support in i2c-designware-baytrail.c,
which fixes the i2c-designware not binding to the pmic (axp288) i2c bus.
But with this fixed we actually start triggering the coordination problems
the rest of this patch-set addresses.

So the plan (again with Wolfram's ack) is for all these patches
including the i2c-designware ones to go upstream through the drm-intel
tree, to avoid an intermediate state were things don't work.

As for the how and why of this patchset, let me copy and paste the
cover letter of v1 of this set which is still mostly valid:

### being v1 cover letter ###

This series fixes an issue where the following messages are shown in dmesg:
[drm:fw_domains_get [i915]] *ERROR* render: timed out waiting for forcewake ack request.
[drm:fw_domains_get [i915]] *MEDIA* render: timed out waiting for forcewake ack request.
i2c_designware 808622C1:06: punit semaphore timed out, resetting
i2c_designware 808622C1:06: PUNIT SEM: 2
i2c_designware 808622C1:06: couldn't acquire bus ownership

Usually followed by a gfx or system freeze, this is happening both on my
cherrytrail tablet as well as being seen by an user commenting on:
https://bugzilla.kernel.org/show_bug.cgi?id=155241

This problem is triggered by my patch series to fix the punit i2c bus
semaphore code in drivers/i2c/busses/designware-baytrail.c .

Which actually allows i2c access to pmic-s wich need bus-access arbritration
for the first time on cherrytrail, combined with patches from me to actually
make the axp288_fuel_gauge driver load, which leads to regular pmic i2c
accesses (when userspace checks the battery level).

The fix / workaround
====================

Testing has shown that just taking the punit i2c bus semaphore on
i2c accesses to a shared pmic i2c bus is not enough to avoid problem,
e.g. besides this series to coordinate i915 access, we also need:
https://patchwork.ozlabs.org/patch/710070/

This series introduces 2 mechanisms to coordinate direct pmic accesses
vs punit requests which lead to pmic accesses. The first mechanism is
a simple mutex, which works well for the direct punit accesses the i915
code does. However testing has shown this is not enough, we also need
to avoid doing a forcewake when a driver is directly accessing the pmic
i2c bus, otherwise we get the timeout errors quoted above, the fact
that after the forcewake errors the designware-baytrail.c code also
fails to acquire the lock, suggests that doing forcewakes during the
access window causes the i2c bus to get stuck (or the punit to get
confused).

The deal with the forcewake issue a notifier is introduced which allows
drivers to get notified before any pmic i2c transfer begins (and after
it ends). This is used in the i915 driver to do a
forcewake_get(FORCEWAKE_ALL) before the access begins avoiding needing to
it while the access is in progress.

Testing has shown that this avoids the problem for both me and the user,
where as before it could be reproduced at will.

The implementation of the fix
=============================

I've decided to put the mutex and the notifier in the iosf_mbi code,
as that is somewhat of a common middle ground between the i915 driver and
the designware-baytrail.c code, with the latter already depending on the
iosf_mbi code. I'm open for moving them if someone has a suggestion for a
better place to put them.

If iosf_mbi support is not enabled then all the functions used will become
static inline NOPs and nothing changes on the i915 side.

If the code is enabled and runs on a system which does not need pmic i2c
bus arbritration, then the mutex lock / unlock calls added to the i915 code
will still be made, but there won't be any contention, so other then the
overhead of the lock / unlock there will not be any delays. These calls are
not made in any hot paths.

The biggest downside IMHO is that taking FORCEWAKE_ALL before each bus
access will cause extra GPU wakeups, and thus powerdrain. I plan to make
the impact of this minimal by modifying any drivers (axp288 code, with
which I'm quite familiar by now) to limit their i2c accesses to a bare
minimum. Specifically I plan to e.g. cache the battery level and wait
at least 15 seconds (max 4 times a minute) before getting a fresh reading
even if userspace asks for it more often, combined with some mechanism
to only do 1 access-begin and 1 access-end notification for i2c accesses
in quick succession.

Alternatives
============

It would be tempting to say that this is not worth the trouble and we
should just disallow direct i2c accesses to the pmic bus. Unfortunately
that will cause some major issues on affected devices:
-No battery monitoring
-No "AC" plugged in monitoring
-If booted with a normal USB-A -> micro-USB cable, or no cable, plugged
 in and then the user replaces the cable with an otg USB-host cable /
 adapter, the id-pin shorting will enable a 5v boost convertor, but we
 need to disable the pmic's USB-Vbus path otherwise it will start drawing
 current from the boost convertor, leading to aprox 300mA of extra
 battery drain, this is done by the axp288_charger driver, which needs
 direct i2c access to the pmic bus

Way forward
===========

I realize the workaround this patch-set adds is not the prettiest code
ever seen, but I see no otherway to get things like battery monitoring
and proper OTG support working on affected devices without breaking
drm/i915 support. So I would like to see this merged in some form, I'm
happy to make any kind of requested changes; and/or to try alternative
fixes.

### end v1 cover letter ###

Regards,

Hans

^ permalink raw reply

* [RFC PATCH] i2c:mux: Driver for PCA9641 I2C Master Arbiter
From: Vidya Sagar Ravipati @ 2017-02-10 10:43 UTC (permalink / raw)
  To: jdelvare, linux, wsa, linux-i2c; +Cc: roopa, vidya.chowdary

From: Vidya Sagar Ravipati <vidya@cumulusnetworks.com>

This patch adds support for PCA9641, an I2C Bus Master Arbiter.
NXP PCA9641 arbiter is modeled as single channel I2C Multiplexer
to be able to utilize the I2C multiplexer framework similar to
PCA9541.

Enhancing PCA9541 driver to support PCA9641 i2c master arbiter
http://www.nxp.com/documents/data_sheet/PCA9641.pdf

Signed-off-by: Vidya Sagar Ravipati <vidya@cumulusnetworks.com>
Signed-off-by: Luffy<Luffy.Cheng@quantatw.com>
---
 drivers/i2c/muxes/i2c-mux-pca9541.c | 157 ++++++++++++++++++++++++++++++++++--
 1 file changed, 152 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index 77840f7..89d8518 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -59,6 +59,36 @@
 #define PCA9541_ISTAT_MYTEST	(1 << 6)
 #define PCA9541_ISTAT_NMYTEST	(1 << 7)
 
+#define PCA9641_ID		0
+#define PCA9641_ID_MAGIC	0x38
+#define PCA9641_CONTROL		0x01
+#define PCA9641_STATUS		0x02
+
+#define PCA9641_CONTROL		0x01
+#define PCA9641_CTL_LOCK_REQ		(1 << 0)
+#define PCA9641_CTL_LOCK_GRANT		(1 << 1)
+#define PCA9641_CTL_BUS_CONNECT		(1 << 2)
+#define PCA9641_CTL_BUS_INIT		(1 << 3)
+#define PCA9641_CTL_SMBUS_SWRST		(1 << 4)
+#define PCA9641_CTL_IDLE_TIMER_DIS	(1 << 5)
+#define PCA9641_CTL_SMBUS_DIS		(1 << 6)
+#define PCA9641_CTL_PRIORITY		(1 << 7)
+
+#define PCA9641_STATUS		0x02
+#define PCA9641_STS_OTHER_LOCK		(1 << 0)
+#define PCA9641_STS_BUS_INIT_FAIL	(1 << 1)
+#define PCA9641_STS_BUS_HUNG		(1 << 2)
+#define PCA9641_STS_MBOX_EMPTY		(1 << 3)
+#define PCA9641_STS_MBOX_FULL		(1 << 4)
+#define PCA9641_STS_TEST_INT		(1 << 5)
+#define PCA9641_STS_SCL_IO		(1 << 6)
+#define PCA9641_STS_SDA_IO		(1 << 7)
+
+#define PCA9641_RES_TIME       0x03
+
+#define other_lock(x)  ((x) & PCA9641_STS_OTHER_LOCK)
+#define lock_grant(x)  ((x) & PCA9641_CTL_LOCK_GRANT)
+
 #define BUSON		(PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
 #define MYBUS		(PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
 #define mybus(x)	(!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
@@ -73,13 +103,20 @@
 #define SELECT_DELAY_LONG	1000
 
 struct pca9541 {
+	int device_type;
 	struct i2c_client *client;
 	unsigned long select_timeout;
 	unsigned long arb_timeout;
 };
 
+enum pca9x41 {
+	PCA9541 = 0,
+	PCA9641
+};
+
 static const struct i2c_device_id pca9541_id[] = {
-	{"pca9541", 0},
+	{"pca9541", PCA9541},
+	{"pca9641", PCA9641},
 	{}
 };
 
@@ -178,12 +215,17 @@ static int pca9541_reg_read(struct i2c_client *client, u8 command)
 /* Release bus. Also reset NTESTON and BUSINIT if it was set. */
 static void pca9541_release_bus(struct i2c_client *client)
 {
+	struct pca9541 *data = i2c_get_clientdata(client);
 	int reg;
 
-	reg = pca9541_reg_read(client, PCA9541_CONTROL);
-	if (reg >= 0 && !busoff(reg) && mybus(reg))
-		pca9541_reg_write(client, PCA9541_CONTROL,
-				  (reg & PCA9541_CTL_NBUSON) >> 1);
+	if (data->device_type == PCA9541) {
+		reg = pca9541_reg_read(client, PCA9541_CONTROL);
+		if (reg >= 0 && !busoff(reg) && mybus(reg))
+			pca9541_reg_write(client, PCA9541_CONTROL,
+				(reg & PCA9541_CTL_NBUSON) >> 1);
+	} else
+		pca9541_reg_write(client, PCA9641_CONTROL, 0);
+
 }
 
 /*
@@ -294,6 +336,90 @@ static int pca9541_arbitrate(struct i2c_client *client)
 	return 0;
 }
 
+/*
+ * Channel arbitration
+ *
+ * Return values:
+ *  <0: error
+ *  0 : bus not acquired
+ *  1 : bus acquired
+ */
+static int pca9641_arbitrate(struct i2c_client *client)
+{
+	struct pca9541 *data = i2c_get_clientdata(client);
+	int reg_ctl, reg_sts;
+
+	reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
+	if (reg_ctl < 0)
+		return reg_ctl;
+
+	reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
+	if (!other_lock(reg_sts) && !lock_grant(reg_ctl)) {
+		/*
+		 * Bus is off. Request ownership or turn it on unless
+		 * other master requested ownership.
+		 */
+		/* FIXME: bus reserve time (1-255) for without interrupt */
+		/*  Lock forever
+		 * pca9541_reg_write(client, PCA9641_RES_TIME, 0);
+		 */
+		reg_ctl |= PCA9641_CTL_LOCK_REQ;
+		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+
+		/* FIXME: If need Wait for lock grant */
+		udelay(100);
+
+		reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
+
+		if (lock_grant(reg_ctl)) {
+			/*
+			 * Other master did not request ownership,
+			 * or arbitration timeout expired. Take the bus.
+			 */
+			reg_ctl |= PCA9641_CTL_BUS_CONNECT;
+			pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+			data->select_timeout = SELECT_DELAY_SHORT;
+
+			return 1;
+		} else {
+			/*
+			 * Other master requested ownership.
+			 * Set extra long timeout to give it time to acquire it.
+			 */
+			data->select_timeout = SELECT_DELAY_LONG * 2;
+		}
+	} else if (lock_grant(reg_ctl)) {
+		/*
+		 * Bus is on, and we own it. We are done with acquisition.
+		 */
+		reg_ctl |= PCA9641_CTL_BUS_CONNECT;
+		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+
+		return 1;
+	} else if (other_lock(reg_sts)) {
+		/*
+		 * Other master owns the bus.
+		 * If arbitration timeout has expired, force ownership.
+		 * Otherwise request it.
+		 */
+		data->select_timeout = SELECT_DELAY_LONG;
+		reg_ctl |= PCA9641_CTL_LOCK_REQ;
+		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
+
+		/*
+		 * if (time_is_before_eq_jiffies(data->arb_timeout)) {
+		 * TODO:Time is up, take the bus and reset it.
+		 *
+		 *} else {
+		 * TODO: Request bus ownership if needed
+		 *
+		 *}
+		 */
+	}
+
+	return 0;
+}
+
 static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
 	struct pca9541 *data = i2c_mux_priv(muxc);
@@ -306,6 +432,11 @@ static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
 		/* force bus ownership after this time */
 
 	do {
+		if (data->device_type == PCA9541)
+			ret = pca9541_arbitrate(client);
+		else
+			ret = pca9641_arbitrate(client);
+
 		ret = pca9541_arbitrate(client);
 		if (ret)
 			return ret < 0 ? ret : 0;
@@ -328,6 +459,17 @@ static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
 	return 0;
 }
 
+static int pca9641_detect_id(struct i2c_client *client)
+{
+	int reg;
+
+	reg = pca9541_reg_read(client, PCA9641_ID);
+	if (reg == PCA9641_ID_MAGIC)
+		return 1;
+	else
+		return 0;
+}
+
 /*
  * I2C init/probing/exit functions
  */
@@ -335,6 +477,7 @@ static int pca9541_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
 	struct i2c_adapter *adap = client->adapter;
+	kernel_ulong_t device_id = id->driver_data;
 	struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
 	struct i2c_mux_core *muxc;
 	struct pca9541 *data;
@@ -344,6 +487,9 @@ static int pca9541_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
+	if (device_id == PCA9641 && !pca9641_detect_id(client))
+		return ret;
+
 	/*
 	 * I2C accesses are unprotected here.
 	 * We have to lock the adapter before releasing the bus.
@@ -366,6 +512,7 @@ static int pca9541_probe(struct i2c_client *client,
 	data = i2c_mux_priv(muxc);
 	data->client = client;
 
+	data->device_type = device_id;
 	i2c_set_clientdata(client, muxc);
 
 	ret = i2c_mux_add_adapter(muxc, force, 0, 0);
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH] i2c: designware: Fix regression when dynamic TAR update is disabled
From: Jarkko Nikula @ 2017-02-10 10:48 UTC (permalink / raw)
  To: Suravee Suthikulpanit, De Marchi, Lucas,
	mika.westerberg@linux.intel.com,
	andriy.shevchenko@linux.intel.com,
	Nehal-Bakulchandra.Shah@amd.com
  Cc: wsa@the-dreams.de, linux-kernel@vger.kernel.org,
	linux-i2c@vger.kernel.org, Shyam-sundar.S-k@amd.com
In-Reply-To: <110f9081-ddba-82c2-6ba3-f92bc36d0bc3@amd.com>

On 10.02.2017 08:38, Suravee Suthikulpanit wrote:
> At this points, my understanding is there are probably two options here:
>
> 1) Keep the commit 63d0f0a6952a (i2c: designware: detect when dynamic
> tar update
>    is possible) and apply V2 of this patch in 4.10. We might need to
> back-port the change
>    to v4.9 stable as well.
>
> 2) Revert the 63d0f0a6952a (i2c: designware: detect when dynamic tar
> update is possible) in 4.10,
>    and also in v4.9 stable as well.
>
I'm fine with both options. Maybe revert as commit 0317e6c0f1dc ("i2c: 
designware: do not disable adapter after transfer") was also reverted 
and this revert doesn't seem to cause conflicts.

-- 
Jarkko

^ permalink raw reply

* Re: [PATCH] i2c: exynos5: fix arbitration lost handling
From: Andrzej Hajda @ 2017-02-10 11:01 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-i2c, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	Krzysztof Kozlowski, Javier Martinez Canillas, linux-samsung-soc
In-Reply-To: <1b67bbf6-dd31-c473-8284-dba9a0ffe440@samsung.com>

On 10.02.2017 08:39, Andrzej Hajda wrote:
> On 09.02.2017 17:27, Wolfram Sang wrote:
>> On Thu, Jan 05, 2017 at 01:06:53PM +0100, Andrzej Hajda wrote:
>>> In case of arbitration lost adequate interrupt sometimes is not signaled. As
>>> a result transfer timeouts and is not retried, as it should. To avoid such
>>> cases code is added to check transaction status in case of every interrupt.
>>>
>>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>>> ---
>>> +
>>> +		switch (trans_status & HSI2C_MASTER_ST_MASK) {
>>> +		case HSI2C_MASTER_ST_LOSE:
>>> +			i2c->state = -EAGAIN;
>>> +			goto stop;
>>> +		}
>> Why not using if() instead of switch() as in the rest of the driver?
> Following reasons (not serious ones):
> 1. With if() the line should be split anyway to keep 80 chars per line
> limit, and the result looks less readable, so no gain:
>         if ((trans_status & HSI2C_MASTER_ST_MASK) ==
>              HSI2C_MASTER_ST_LOSE) {
>             i2c->state = -EAGAIN;
>             goto stop;
>         }
> 2. It is ready to handle other status values as well, without repeating
> long if() clause, in fact during tests I have added more values, but
> finally they went out.
> 3. In the rest of the functions if() is used because code tests if some
> bits are set, here we test if some bit field have specific value,
> slightly different thing.
>
> Of course I can change to if() if you prefer it.
>
>> And there is arbitration lost checking already with int_status &
>> HSI2C_INT_TRANS_ABORT. Any guess why it doesn't trigger?
>>
> Nope. This patch is just a result of comparing register values during
> good and bad transfer.
> I have looked for similar issues over the net, but without ultimate
> answer, some hints are that master can check status of SDA line too early.
> Anyway it works correctly with gpio bit-banging driver, it suggests
> there could be something wrong in hsi2c logic.

I have just found in spec of newer version of the chip configuration bit
NO_ARB_FASTSDA. Citation:
> This bit deactivates the modified logic of the
> abnormal operation when the SCL is falling. Then,
> other I2C device quickly lowers the SDA line, and
> SDA has fallen before the first PCLK period
> elapses.
> 0 = Skip the master arbitration checking during the
> first PCLK period after SCL falls
> 1 = Restore original logic

I have no hardware with newer chip to really test if this solves the
issue, but I suppose it could, the only problem is that this bit is not
present in current chip version, Exynos5433.

Regards
Andrzej


>
> Regards
> Andrzej
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply

* [PATCH] Set sda-hold-time based on ACPI *CNT value
From: chin.yew.tan @ 2017-02-10 11:15 UTC (permalink / raw)
  To: jarkko.nikula, andriy.shevchenko, mika.westerberg; +Cc: linux-i2c

From: Tan Chin Yew <chin.yew.tan@intel.com>

For I2c to operate correctly under all speed mode, sda-hold-time need to
be perfectly tuned. However, sda-hold-time is precalculated according to
circuit parameter which make it platform-specific.

In order to get accurate sda-hold-time for all platforms, pretuned
sda-hold-time for particular platform is stored in ACPI table and driver
to load the sda holding time from ACPI table.

This patch read the I2c sda-hold-time from ACPI table and assigned the
suitable hold time based on the i2c clock frequency.

Tested on Intel Apollo Lake.

Tan Chin Yew (1):
  i2c: designware: Get selected speed mode sda-hold-time via ACPI

 drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH] Set sda-hold-time based on ACPI *CNT value
From: chin.yew.tan @ 2017-02-10 11:28 UTC (permalink / raw)
  To: jarkko.nikula, andriy.shevchenko, mika.westerberg; +Cc: linux-i2c

From: Tan Chin Yew <chin.yew.tan@intel.com>

For I2c to operate correctly under all speed mode, sda-hold-time need to
be perfectly tuned. However, sda-hold-time is precalculated according to
circuit parameter which make it platform-specific.

In order to get accurate sda-hold-time for all platforms, pretuned
sda-hold-time for particular platform is stored in ACPI table and driver
to load the sda holding time from ACPI table.

This patch read the I2c sda-hold-time from ACPI table and assigned the
suitable hold time based on the i2c clock frequency.

Tested on Intel Apollo Lake.

Tan Chin Yew (1):
  i2c: designware: Get selected speed mode sda-hold-time via ACPI

 drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH] i2c: designware: Get selected speed mode sda-hold-time via ACPI
From: chin.yew.tan @ 2017-02-10 11:28 UTC (permalink / raw)
  To: jarkko.nikula, andriy.shevchenko, mika.westerberg; +Cc: linux-i2c
In-Reply-To: <1486726118-19447-1-git-send-email-chin.yew.tan@intel.com>

From: Tan Chin Yew <chin.yew.tan@intel.com>

Sda-hold-time is an important parameter for tuning i2c to meet the
electrical specification especially for high speed. I2C with incorrect
sda-hold-time may cause lost arbitration error. Now, the driver is able to
get sda-hold-time for all the speed supported.

Signed-off-by: Tan Chin Yew <chin.yew.tan@intel.com>
---
 drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 6ce4313..aa33088 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -101,15 +101,28 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
 	dev->rx_fifo_depth = 32;
 
 	/*
-	 * Try to get SDA hold time and *CNT values from an ACPI method if
-	 * it exists for both supported speed modes.
+	 * Try to get SDA hold time and *CNT values from an ACPI method for
+	 * selected speed modes.
 	 */
-	dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL);
-	dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
+	switch (dev->clk_freq) {
+	case 100000:
+		dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt,
 			   &dev->sda_hold_time);
-	dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, NULL);
-	dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, NULL);
-
+		break;
+	case 1000000:
+		dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt,
+			   &dev->sda_hold_time);
+		break;
+	case 3400000:
+		dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt,
+			   &dev->sda_hold_time);
+		break;
+	default:
+		dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
+			   &dev->sda_hold_time);
+		break;
+	}
+
 	id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
 	if (id && id->driver_data)
 		dev->accessor_flags |= (u32)id->driver_data;
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v6 0/3] i2c: mux: pca954x: Add interrupt controller support
From: Wolfram Sang @ 2017-02-10 12:52 UTC (permalink / raw)
  To: Peter Rosin; +Cc: Phil Reid, linux-i2c
In-Reply-To: <8a11d374-a9f9-0e58-d01f-1cc72827c5e9@axentia.se>

[-- Attachment #1: Type: text/plain, Size: 2871 bytes --]

Hi Peter,

> initializer for the 'handled' variable. I amended the previously
> posted fixup and was just about to send you the pull request when
> you started to add patches to i2c/for-next.

Oh, sorry! I wasn't sure if we agreed that you send pull-requests for
v4.11 already or starting with v4.12. And since there seems to be no rc8
for 4.11 I decided to start pulling in.

> probably not happen (anytime soon). I'm going to short out the wait
> and just send a reworked pull request. See below.

Perfect!

> A few thing to take away from this. Phil didn't post the series to
> LKML, and the kbuild bots didn't find the series until I added it to
> my i2c-mux tree. Fengguang indicated that the kbuild bot will now
> (or soon) start to track the i2c list, which might be good to know.

Well, I asked Fengguang to remove the i2c list from that feature a
while ago. People send out RFCs, debug patches, etc... and for all those
build bot reports are just noise IMO.

Build testing plus sparse+smatch testing for the patches when I apply
them to my tree and then having my branches additionally checked by
build bot works well for me. I will happily share my super-simple
'ninja-check' script with you which runs various code checkers when
compiling. It is basically adding "W=1 C=1 CHECK='ninja-check'" to the
kernel build command-line.

I hope you are open for this workflow. But we can discuss, of course.

> submission. So, from now on I think I'm just going to change my
> acks to some message saying that the patch(es) have been added
> to i2c-mux/for-next (in case the submission is clear-cut i2c-mux
> and not at all about i2c-the-rest). If I just ack a submission I'll
> expect you to pick it up. Ok?

Perfect!

> The question then becomes at approximately which point you'll need
> a pull request? Or should you perhaps be pulling in my tree
> on a more continuous level so that everything i2c-related is
> available in one tree (i.e. your tree)?

I prefer pull requests a little bit. Then, I get a consistent state
approved by you and already checked by build bot. BTW is your tree in
linux-next as well?

> sign-off when you pull? It's not a big thing, but all things being
> equal, I'd prefer the commits to stay as-is...

Sure thing. It might have been done automatically, will check and fix my
scripts...

> 
> Cheers,
> peda
> 
> The following changes since commit 7a308bb3016f57e5be11a677d15b821536419d36:
> 
>   Linux 4.10-rc5 (2017-01-22 12:54:15 -0800)
> 
> are available in the git repository at:
> 
>   https://github.com/peda-r/i2c-mux.git i2c-mux/for-next
> 
> for you to fetch changes up to f2114795f721bd5028284ddf84b150798a9b7a73:
> 
>   i2c: mux: pca954x: Add interrupt controller support (2017-02-10 08:23:51 +0100)

And pulled! Thank you for the work!

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [RFC PATCH] i2c:mux: Driver for PCA9641 I2C Master Arbiter
From: Peter Rosin @ 2017-02-10 13:17 UTC (permalink / raw)
  To: Vidya Sagar Ravipati, jdelvare, linux, wsa, linux-i2c
  Cc: roopa, vidya.chowdary
In-Reply-To: <1486723418-13311-1-git-send-email-vidya@cumulusnetworks.com>

On 2017-02-10 11:43, Vidya Sagar Ravipati wrote:
> From: Vidya Sagar Ravipati <vidya@cumulusnetworks.com>
> 
> This patch adds support for PCA9641, an I2C Bus Master Arbiter.
> NXP PCA9641 arbiter is modeled as single channel I2C Multiplexer
> to be able to utilize the I2C multiplexer framework similar to
> PCA9541.
> 
> Enhancing PCA9541 driver to support PCA9641 i2c master arbiter
> http://www.nxp.com/documents/data_sheet/PCA9641.pdf
> 
> Signed-off-by: Vidya Sagar Ravipati <vidya@cumulusnetworks.com>
> Signed-off-by: Luffy<Luffy.Cheng@quantatw.com>

Missing a space after Luffy, and why isn't it Luffy Cheng <...> or
something like that? And your sign-off should probably be last.

> ---
>  drivers/i2c/muxes/i2c-mux-pca9541.c | 157 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 152 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
> index 77840f7..89d8518 100644
> --- a/drivers/i2c/muxes/i2c-mux-pca9541.c
> +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
> @@ -59,6 +59,36 @@
>  #define PCA9541_ISTAT_MYTEST	(1 << 6)
>  #define PCA9541_ISTAT_NMYTEST	(1 << 7)
>  
> +#define PCA9641_ID		0
> +#define PCA9641_ID_MAGIC	0x38
> +#define PCA9641_CONTROL		0x01
> +#define PCA9641_STATUS		0x02
> +
> +#define PCA9641_CONTROL		0x01

You're redefining PCA9641_CONTROL here, please don't.

> +#define PCA9641_CTL_LOCK_REQ		(1 << 0)

BIT(0)

> +#define PCA9641_CTL_LOCK_GRANT		(1 << 1)

BIT(1), etc

> +#define PCA9641_CTL_BUS_CONNECT		(1 << 2)
> +#define PCA9641_CTL_BUS_INIT		(1 << 3)
> +#define PCA9641_CTL_SMBUS_SWRST		(1 << 4)
> +#define PCA9641_CTL_IDLE_TIMER_DIS	(1 << 5)
> +#define PCA9641_CTL_SMBUS_DIS		(1 << 6)
> +#define PCA9641_CTL_PRIORITY		(1 << 7)
> +
> +#define PCA9641_STATUS		0x02

You're redefining PCA9641_STATUS here, please don't.

> +#define PCA9641_STS_OTHER_LOCK		(1 << 0)
> +#define PCA9641_STS_BUS_INIT_FAIL	(1 << 1)
> +#define PCA9641_STS_BUS_HUNG		(1 << 2)
> +#define PCA9641_STS_MBOX_EMPTY		(1 << 3)
> +#define PCA9641_STS_MBOX_FULL		(1 << 4)
> +#define PCA9641_STS_TEST_INT		(1 << 5)
> +#define PCA9641_STS_SCL_IO		(1 << 6)
> +#define PCA9641_STS_SDA_IO		(1 << 7)
> +
> +#define PCA9641_RES_TIME       0x03
> +
> +#define other_lock(x)  ((x) & PCA9641_STS_OTHER_LOCK)
> +#define lock_grant(x)  ((x) & PCA9641_CTL_LOCK_GRANT)
> +
>  #define BUSON		(PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
>  #define MYBUS		(PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
>  #define mybus(x)	(!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
> @@ -73,13 +103,20 @@
>  #define SELECT_DELAY_LONG	1000
>  
>  struct pca9541 {
> +	int device_type;
>  	struct i2c_client *client;
>  	unsigned long select_timeout;
>  	unsigned long arb_timeout;
>  };
>  
> +enum pca9x41 {
> +	PCA9541 = 0,
> +	PCA9641
> +};
> +
>  static const struct i2c_device_id pca9541_id[] = {
> -	{"pca9541", 0},
> +	{"pca9541", PCA9541},
> +	{"pca9641", PCA9641},
>  	{}
>  };
>  
> @@ -178,12 +215,17 @@ static int pca9541_reg_read(struct i2c_client *client, u8 command)
>  /* Release bus. Also reset NTESTON and BUSINIT if it was set. */
>  static void pca9541_release_bus(struct i2c_client *client)
>  {
> +	struct pca9541 *data = i2c_get_clientdata(client);
>  	int reg;
>  
> -	reg = pca9541_reg_read(client, PCA9541_CONTROL);
> -	if (reg >= 0 && !busoff(reg) && mybus(reg))
> -		pca9541_reg_write(client, PCA9541_CONTROL,
> -				  (reg & PCA9541_CTL_NBUSON) >> 1);
> +	if (data->device_type == PCA9541) {
> +		reg = pca9541_reg_read(client, PCA9541_CONTROL);
> +		if (reg >= 0 && !busoff(reg) && mybus(reg))
> +			pca9541_reg_write(client, PCA9541_CONTROL,
> +				(reg & PCA9541_CTL_NBUSON) >> 1);
> +	} else
> +		pca9541_reg_write(client, PCA9641_CONTROL, 0);
> +
>  }
>  
>  /*
> @@ -294,6 +336,90 @@ static int pca9541_arbitrate(struct i2c_client *client)
>  	return 0;
>  }
>  
> +/*
> + * Channel arbitration
> + *
> + * Return values:
> + *  <0: error
> + *  0 : bus not acquired
> + *  1 : bus acquired
> + */
> +static int pca9641_arbitrate(struct i2c_client *client)
> +{
> +	struct pca9541 *data = i2c_get_clientdata(client);
> +	int reg_ctl, reg_sts;
> +
> +	reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
> +	if (reg_ctl < 0)
> +		return reg_ctl;
> +
> +	reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
> +	if (!other_lock(reg_sts) && !lock_grant(reg_ctl)) {

I would reorder the checks as:

	if (lock_grant(reg_ctl)) {
		...
	} else if (other_lock(reg_ctl)) {
		...
	} else {
		...
	}

> +		/*
> +		 * Bus is off. Request ownership or turn it on unless
> +		 * other master requested ownership.
> +		 */
> +		/* FIXME: bus reserve time (1-255) for without interrupt */
> +		/*  Lock forever
> +		 * pca9541_reg_write(client, PCA9641_RES_TIME, 0);
> +		 */

Why is the above three separate comments?

> +		reg_ctl |= PCA9641_CTL_LOCK_REQ;
> +		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
> +
> +		/* FIXME: If need Wait for lock grant */

Sorry, I fail to parse this comment.

> +		udelay(100);
> +
> +		reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
> +
> +		if (lock_grant(reg_ctl)) {
> +			/*
> +			 * Other master did not request ownership,
> +			 * or arbitration timeout expired. Take the bus.
> +			 */
> +			reg_ctl |= PCA9641_CTL_BUS_CONNECT;
> +			pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
> +			data->select_timeout = SELECT_DELAY_SHORT;
> +
> +			return 1;
> +		} else {
> +			/*
> +			 * Other master requested ownership.
> +			 * Set extra long timeout to give it time to acquire it.
> +			 */
> +			data->select_timeout = SELECT_DELAY_LONG * 2;
> +		}
> +	} else if (lock_grant(reg_ctl)) {
> +		/*
> +		 * Bus is on, and we own it. We are done with acquisition.
> +		 */
> +		reg_ctl |= PCA9641_CTL_BUS_CONNECT;
> +		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
> +
> +		return 1;
> +	} else if (other_lock(reg_sts)) {
> +		/*
> +		 * Other master owns the bus.
> +		 * If arbitration timeout has expired, force ownership.
> +		 * Otherwise request it.
> +		 */
> +		data->select_timeout = SELECT_DELAY_LONG;
> +		reg_ctl |= PCA9641_CTL_LOCK_REQ;
> +		pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
> +
> +		/*
> +		 * if (time_is_before_eq_jiffies(data->arb_timeout)) {
> +		 * TODO:Time is up, take the bus and reset it.
> +		 *
> +		 *} else {
> +		 * TODO: Request bus ownership if needed
> +		 *
> +		 *}
> +		 */

Looks like you didn't finish this part? Why not?

> +	}
> +
> +	return 0;
> +}
> +
>  static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
>  {
>  	struct pca9541 *data = i2c_mux_priv(muxc);
> @@ -306,6 +432,11 @@ static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
>  		/* force bus ownership after this time */
>  
>  	do {
> +		if (data->device_type == PCA9541)
> +			ret = pca9541_arbitrate(client);
> +		else
> +			ret = pca9641_arbitrate(client);
> +
>  		ret = pca9541_arbitrate(client);

I think you meant to remove this line.

>  		if (ret)
>  			return ret < 0 ? ret : 0;
> @@ -328,6 +459,17 @@ static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
>  	return 0;
>  }
>  
> +static int pca9641_detect_id(struct i2c_client *client)
> +{
> +	int reg;
> +
> +	reg = pca9541_reg_read(client, PCA9641_ID);
> +	if (reg == PCA9641_ID_MAGIC)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
>  /*
>   * I2C init/probing/exit functions
>   */
> @@ -335,6 +477,7 @@ static int pca9541_probe(struct i2c_client *client,
>  			 const struct i2c_device_id *id)
>  {
>  	struct i2c_adapter *adap = client->adapter;
> +	kernel_ulong_t device_id = id->driver_data;
>  	struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
>  	struct i2c_mux_core *muxc;
>  	struct pca9541 *data;
> @@ -344,6 +487,9 @@ static int pca9541_probe(struct i2c_client *client,
>  	if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
>  		return -ENODEV;
>  
> +	if (device_id == PCA9641 && !pca9641_detect_id(client))
> +		return ret;

ret is just wrong here.

Cheers,
peda

> +
>  	/*
>  	 * I2C accesses are unprotected here.
>  	 * We have to lock the adapter before releasing the bus.
> @@ -366,6 +512,7 @@ static int pca9541_probe(struct i2c_client *client,
>  	data = i2c_mux_priv(muxc);
>  	data->client = client;
>  
> +	data->device_type = device_id;
>  	i2c_set_clientdata(client, muxc);
>  
>  	ret = i2c_mux_add_adapter(muxc, force, 0, 0);
> 

^ permalink raw reply

* Re: [PATCH] i2c: designware: Get selected speed mode sda-hold-time via ACPI
From: Andy Shevchenko @ 2017-02-10 12:31 UTC (permalink / raw)
  To: chin.yew.tan, jarkko.nikula, mika.westerberg; +Cc: linux-i2c
In-Reply-To: <1486726118-19447-2-git-send-email-chin.yew.tan@intel.com>

On Fri, 2017-02-10 at 19:28 +0800, chin.yew.tan@intel.com wrote:
> From: Tan Chin Yew <chin.yew.tan@intel.com>
> 
> Sda-hold-time is an important parameter for tuning i2c to meet the
> electrical specification especially for high speed. I2C with incorrect
> sda-hold-time may cause lost arbitration error. Now, the driver is
> able to
> get sda-hold-time for all the speed supported.
> 

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Couple of nitpicks below.

> Signed-off-by: Tan Chin Yew <chin.yew.tan@intel.com>
> ---
>  drivers/i2c/busses/i2c-designware-platdrv.c | 27
> ++++++++++++++++++++-------
>  1 file changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
> b/drivers/i2c/busses/i2c-designware-platdrv.c
> index 6ce4313..aa33088 100644
> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -101,15 +101,28 @@ static int dw_i2c_acpi_configure(struct
> platform_device *pdev)
>  	dev->rx_fifo_depth = 32;
>  
>  	/*
> -	 * Try to get SDA hold time and *CNT values from an ACPI
> method if
> -	 * it exists for both supported speed modes.
> +	 * Try to get SDA hold time and *CNT values from an ACPI
> method for
> +	 * selected speed modes.
>  	 */
> -	dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev-
> >ss_lcnt, NULL);
> -	dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev-
> >fs_lcnt,
> +	switch (dev->clk_freq) {
> +	case 100000:
> +		dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev-
> >ss_lcnt,

>  			   &dev->sda_hold_time);

This indentation should go in a way that & character in the same column
as p (in "p(s" context above).

> -	dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev-
> >fp_lcnt, NULL);
> -	dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev-
> >hs_lcnt, NULL);
> -
> +		break;
> +	case 1000000:
> +		dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev-
> >fp_lcnt,
> +			   &dev->sda_hold_time);
> +		break;
> +	case 3400000:
> +		dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev-
> >hs_lcnt,
> +			   &dev->sda_hold_time);
> +		break;

Can we prepend default with

case 400000:

here?

> +	default:


> +		dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev-
> >fs_lcnt,
> +			   &dev->sda_hold_time);
> +		break;
> +	}
> +
>  	id = acpi_match_device(pdev->dev.driver->acpi_match_table,
> &pdev->dev);
>  	if (id && id->driver_data)
>  		dev->accessor_flags |= (u32)id->driver_data;

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply

* Re: [PATCH] i2c: designware: Get selected speed mode sda-hold-time via ACPI
From: Jarkko Nikula @ 2017-02-10 12:28 UTC (permalink / raw)
  To: chin.yew.tan, andriy.shevchenko, mika.westerberg; +Cc: linux-i2c
In-Reply-To: <1486726118-19447-2-git-send-email-chin.yew.tan@intel.com>

On 10.02.2017 13:28, chin.yew.tan@intel.com wrote:
> From: Tan Chin Yew <chin.yew.tan@intel.com>
>
> Sda-hold-time is an important parameter for tuning i2c to meet the
> electrical specification especially for high speed. I2C with incorrect
> sda-hold-time may cause lost arbitration error. Now, the driver is able to
> get sda-hold-time for all the speed supported.
>
> Signed-off-by: Tan Chin Yew <chin.yew.tan@intel.com>
> ---
>  drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++++++++++++++++-------
>  1 file changed, 20 insertions(+), 7 deletions(-)
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>

^ permalink raw reply

* [PULL REQUEST] i2c for 4.10
From: Wolfram Sang @ 2017-02-10 14:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 860 bytes --]

Linus,

here are two bugfixes (proper IO mapping and use of mutex) for a driver
feature we introduced in this cycle. Please pull.

Thanks,

   Wolfram


The following changes since commit d5adbfcd5f7bcc6fa58a41c5c5ada0e5c826ce2c:

  Linux 4.10-rc7 (2017-02-05 15:10:58 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-current

for you to fetch changes up to bbb27fc33d44e7b8d96369810654df4ee1837566:

  i2c: piix4: Request the SMBUS semaphore inside the mutex (2017-02-09 17:13:01 +0100)

----------------------------------------------------------------
Ricardo Ribalda Delgado (2):
      i2c: piix4: Fix request_region size
      i2c: piix4: Request the SMBUS semaphore inside the mutex

 drivers/i2c/busses/i2c-piix4.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4] eeprom/at24: use device_property_*() functions instead of of_get_property()
From: Wolfram Sang @ 2017-02-10 15:34 UTC (permalink / raw)
  To: Ben Gardner; +Cc: linux-i2c, linux-kernel, Andy Shevchenko
In-Reply-To: <1486661768-21456-1-git-send-email-gardner.ben@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1320 bytes --]

On Thu, Feb 09, 2017 at 11:36:08AM -0600, Ben Gardner wrote:
> Allow the at24 driver to get configuration information from both OF and
> ACPI by using the more generic device_property functions.
> This change was inspired by the at25.c driver.
> 
> I have a custom board with a ST M24C02 EEPROM attached to an I2C bus.
> With the following ACPI construct, this patch instantiates a working
> instance of the driver.
> 
> Device (EEP0) {
>  Name (_HID, "PRP0001")
>  Name (_DSD, Package () {
>   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>   Package () {
>    Package () {"compatible", Package () {"st,24c02"}},
>    Package () {"pagesize", 16},
>   },
>  })
>  Name (_CRS, ResourceTemplate () {
>   I2cSerialBus (
>    0x0057, ControllerInitiated, 400000,
>    AddressingMode7Bit, "\\_SB.PCI0.I2C3", 0x00,
>    ResourceConsumer,,)
>  })
> }
> 
> Note: Matching the driver to the I2C device requires another patch.
>  http://www.spinics.net/lists/linux-acpi/msg71914.html

This should have been below the "---" because dependencies are not
relevant in the git history.

> 
> Signed-off-by: Ben Gardner <gardner.ben@gmail.com>

Please send new patches not in-reply-to old patches, seperate threads
are easier to find IMHO.

Other than that:

Applied to for-next, thanks!



[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] i2c: exynos5: fix arbitration lost handling
From: Wolfram Sang @ 2017-02-10 15:49 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: linux-i2c, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	Krzysztof Kozlowski, Javier Martinez Canillas, linux-samsung-soc
In-Reply-To: <1b67bbf6-dd31-c473-8284-dba9a0ffe440@samsung.com>

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

On Fri, Feb 10, 2017 at 08:39:58AM +0100, Andrzej Hajda wrote:
> On 09.02.2017 17:27, Wolfram Sang wrote:
> > On Thu, Jan 05, 2017 at 01:06:53PM +0100, Andrzej Hajda wrote:
> >> In case of arbitration lost adequate interrupt sometimes is not signaled. As
> >> a result transfer timeouts and is not retried, as it should. To avoid such
> >> cases code is added to check transaction status in case of every interrupt.
> >>
> >> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> >> ---
> >> +
> >> +		switch (trans_status & HSI2C_MASTER_ST_MASK) {
> >> +		case HSI2C_MASTER_ST_LOSE:
> >> +			i2c->state = -EAGAIN;
> >> +			goto stop;
> >> +		}
> > Why not using if() instead of switch() as in the rest of the driver?
> 
> Following reasons (not serious ones):

I see. It is probably a taste thing, but a switch() with just one case
in it looks like something has been forgotten :) We can change it back
to switch() if ever more states need to be added.

Given that I am not super strict with the 80 char limit anyhow and it
will miss the limit by a few chars only, I'd prefer the if statement
actually.

Other than this, I am OK with applying the patch for 4.11. Can you
resend with the above change?

Thanks,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/2] i2c: Add Tegra BPMP I2C proxy driver
From: Wolfram Sang @ 2017-02-10 16:37 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Alexandre Courbot, Jon Hunter, linux-i2c,
	linux-tegra
In-Reply-To: <20170127083939.20393-3-thierry.reding@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]

Hi there,

> +static int tegra_bpmp_i2c_msg_len_check(struct i2c_msg *msgs, unsigned int num)
> +{
> +	size_t tx_len = 0, rx_len = 0;
> +	unsigned int i;
> +
> +	for (i = 0; i < num; i++)
> +		if (!(msgs[i].flags & I2C_M_RD))
> +			tx_len += SERIALI2C_HDR_SIZE + msgs[i].len;
> +
> +	if (tx_len > TEGRA_I2C_IPC_MAX_IN_BUF_SIZE)
> +		return -EINVAL;
> +
> +	for (i = 0; i < num; i++)
> +		if ((msgs[i].flags & I2C_M_RD))
> +			rx_len += msgs[i].len;

You could have done with iterating over all msgs only once, but no need
to fix. I think I'll update the i2c core quirks feature to support your
case and rework that incrementally.

> +	/* TODO: move this somewhere else */
> +	memset(&request, 0, sizeof(request));
> +	memset(&response, 0, sizeof(response));

So? :)

> +	i2c->adapter.class = I2C_CLASS_HWMON;

Do you really need that?

> +	err = i2c_add_adapter(&i2c->adapter);
> +	if (err < 0) {
> +		dev_err(&pdev->dev, "failed to add I2C adapter: %d\n", err);

No error message here, the core will do that.

> +static int __init tegra_bpmp_i2c_init_driver(void)
> +{
> +	return platform_driver_register(&tegra_bpmp_i2c_driver);
> +}
> +subsys_initcall(tegra_bpmp_i2c_init_driver);

Have you tried if subsys_initcall is really really necessary?

Thanks,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v6 0/3] i2c: mux: pca954x: Add interrupt controller support
From: Peter Rosin @ 2017-02-10 21:46 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linux-i2c
In-Reply-To: <20170210125205.c2gzgi65x4bi3eys@ninjato>

On 2017-02-10 13:52, Wolfram Sang wrote:
> Hi Peter,
> 
>> initializer for the 'handled' variable. I amended the previously
>> posted fixup and was just about to send you the pull request when
>> you started to add patches to i2c/for-next.
> 
> Oh, sorry! I wasn't sure if we agreed that you send pull-requests for
> v4.11 already or starting with v4.12. And since there seems to be no rc8
> for 4.11 I decided to start pulling in.

FWIW, I think you did the right thing, and it was me that should have
been clearer from the start. No big thing, just a few patches.

> Build testing plus sparse+smatch testing for the patches when I apply
> them to my tree and then having my branches additionally checked by
> build bot works well for me. I will happily share my super-simple
> 'ninja-check' script with you which runs various code checkers when
> compiling. It is basically adding "W=1 C=1 CHECK='ninja-check'" to the
> kernel build command-line.
> 
> I hope you are open for this workflow. But we can discuss, of course.

No trouble at all, and I'll certainly have a look at the script, so
please send it my way. Thanks!

>> The question then becomes at approximately which point you'll need
>> a pull request? Or should you perhaps be pulling in my tree
>> on a more continuous level so that everything i2c-related is
>> available in one tree (i.e. your tree)?
> 
> I prefer pull requests a little bit. Then, I get a consistent state
> approved by you and already checked by build bot. BTW is your tree in
> linux-next as well?

Nope, it's not, but I intend to fix that for the next round. Ok, I think
we have a sane plan, people should be testing linux-next anyway...

Cheers,
Peter

^ permalink raw reply

* Re: [PATCH v6 0/3] i2c: mux: pca954x: Add interrupt controller support
From: Wolfram Sang @ 2017-02-11  2:40 UTC (permalink / raw)
  To: Peter Rosin; +Cc: linux-i2c
In-Reply-To: <3632e933-6bc9-4d40-f489-1af958f0fd4b@axentia.se>

[-- Attachment #1: Type: text/plain, Size: 1671 bytes --]


> No trouble at all, and I'll certainly have a look at the script, so
> please send it my way. Thanks!

Some notes first:: sparse and smatch are probably the most useful for
kernel builds. spatch (=coccinelle) is nice, too, but needs quite a bit
more time for checking. cppcheck occasionally finds something that the
others don't, flawfinder not really. There are some false positives,
too, so you need to get a bit used to read the output. So, here you go:

=== ninja-check
#!/bin/sh -u
# wrapper to call various static checkers for kernel builds.
# Use: make C=1 CHECK='ninja-check' ...
# done by Wolfram Sang in 2012-14, version 20140514 - WTFPLv2

check_for()
{
	command -v $1 > /dev/null
	ret=$?
	[ $ret -eq 0 ] && echo "    $1" | tr a-z A-Z
	return $ret
}

# Get filename (last argument)
eval file_to_check=\${$#}

check_for sparse && sparse -Wsparse-all "$@"

check_for smatch && smatch --two-passes --project=kernel "$@" 1>&2

# Don't provide include-dirs since number of code paths increases drastically (#defines!) and '-f' checks all of them. Just suppress the warning.
check_for cppcheck && cppcheck -f -q --platform=unix64 --template=gcc --enable=all --language=c --suppress=missingInclude --suppress=clarifyCalculation --suppress=unmatchedSuppression --suppress=variableScope "$file_to_check"

check_for spatch && MODE=report scripts/coccicheck "$file_to_check" 1>&2

check_for flawfinder && flawfinder --minlevel=0 --quiet --dataonly --singleline "$file_to_check" 1>&2

# RATS mainly checks for dangerous functions. Not so useful for kernel analysis. flawfinder does string checking, too.
#check_for rats && rats --resultsonly -w 3 "$file_to_check" 1>&2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* RE: [PATCH] i2c: designware: Fix regression when dynamic TAR update is disabled
From: Shah, Nehal-bakulchandra @ 2017-02-13  4:15 UTC (permalink / raw)
  To: Jarkko Nikula, Suthikulpanit, Suravee, De Marchi, Lucas,
	mika.westerberg@linux.intel.com,
	andriy.shevchenko@linux.intel.com
  Cc: wsa@the-dreams.de, linux-kernel@vger.kernel.org,
	linux-i2c@vger.kernel.org, S-k, Shyam-sundar
In-Reply-To: <d1db459e-59a4-72d8-e21c-bb44545f10e6@linux.intel.com>

It is better to revert the 63d0f0a6952a.  

-----Original Message-----
From: Jarkko Nikula [mailto:jarkko.nikula@linux.intel.com] 
Sent: Friday, February 10, 2017 4:19 PM
To: Suthikulpanit, Suravee <Suravee.Suthikulpanit@amd.com>; De Marchi, Lucas <lucas.demarchi@intel.com>; mika.westerberg@linux.intel.com; andriy.shevchenko@linux.intel.com; Shah, Nehal-bakulchandra <Nehal-bakulchandra.Shah@amd.com>
Cc: wsa@the-dreams.de; linux-kernel@vger.kernel.org; linux-i2c@vger.kernel.org; S-k, Shyam-sundar <Shyam-sundar.S-k@amd.com>
Subject: Re: [PATCH] i2c: designware: Fix regression when dynamic TAR update is disabled

On 10.02.2017 08:38, Suravee Suthikulpanit wrote:
> At this points, my understanding is there are probably two options here:
>
> 1) Keep the commit 63d0f0a6952a (i2c: designware: detect when dynamic 
> tar update
>    is possible) and apply V2 of this patch in 4.10. We might need to 
> back-port the change
>    to v4.9 stable as well.
>
> 2) Revert the 63d0f0a6952a (i2c: designware: detect when dynamic tar 
> update is possible) in 4.10,
>    and also in v4.9 stable as well.
>
I'm fine with both options. Maybe revert as commit 0317e6c0f1dc ("i2c: 
designware: do not disable adapter after transfer") was also reverted and this revert doesn't seem to cause conflicts.

--
Jarkko

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox