Selaa lähdekoodia

i2c SDA hung handling

Reinhard Russinger 5 kuukautta sitten
vanhempi
commit
d7dee6ffe9

+ 0 - 47
board/GfA/Display001/linux_4.4.94_rt19/linux-023-edt-ft5x06-shared-irq.disabled__patch

@@ -1,47 +0,0 @@
-diff -Naurp a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
---- a/drivers/input/touchscreen/edt-ft5x06.c	2018-01-30 21:28:53.696245462 +0100
-+++ b/drivers/input/touchscreen/edt-ft5x06.c	2018-01-30 21:28:19.220223683 +0100
-@@ -188,6 +188,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int
- 	int i, type, x, y, id;
- 	int offset, tplen, datalen;
- 	int error;
-+	
- 
- 	switch (tsdata->version) {
- 	case M06:
-@@ -532,7 +533,7 @@ static int edt_ft5x06_factory_mode(struc
- 	int ret;
- 	int error;
- 
--	disable_irq(client->irq);
-+//	disable_irq(client->irq);
- 
- 	if (!tsdata->raw_buffer) {
- 		tsdata->raw_bufsize = tsdata->num_x * tsdata->num_y *
-@@ -577,7 +578,7 @@ err_out:
- 	kfree(tsdata->raw_buffer);
- 	tsdata->raw_buffer = NULL;
- 	tsdata->factory_mode = false;
--	enable_irq(client->irq);
-+//	enable_irq(client->irq);
- 
- 	return error;
- 
-@@ -634,7 +635,7 @@ static int edt_ft5x06_work_mode(struct e
- 		edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
- 				  tsdata->report_rate);
- 
--	enable_irq(client->irq);
-+//	enable_irq(client->irq);
- 
- 	return 0;
- }
-@@ -1293,7 +1294,7 @@ static int edt_ft5x06_ts_probe(struct i2
- 
- 	error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- 					edt_ft5x06_ts_isr,
--					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
- 					client->name, tsdata);
- 	if (error) {
- 		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");

+ 92 - 0
board/GfA/Display001/linux_4.4.94_rt19/linux-044_i2c-omap-fix-sda-clocking.patch

@@ -0,0 +1,92 @@
+diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
+index 5d784d4..946f850 100644
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -474,34 +474,11 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
+ 	return 0;
+ }
+ 
+-static void omap_i2c_clock_pulse(struct omap_i2c_dev *dev)
+-{
+-	u32 reg;
+-	int i;
+-
+-	/* Enable testmode */
+-	reg = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+-	reg |= OMAP_I2C_SYSTEST_ST_EN;
+-	omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
+-
+-	for (i = 0; i < 9; i++) {
+-		reg |= OMAP_I2C_SYSTEST_SCL_O;
+-		omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
+-		mdelay(100);
+-		reg &= ~OMAP_I2C_SYSTEST_SCL_O;
+-		omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
+-		mdelay(100);
+-	}
+-
+-	/* Disable testmode */
+-	reg &= ~OMAP_I2C_SYSTEST_ST_EN;
+-	omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
+-}
+-
+-static void omap_i2c_bus_recover(struct omap_i2c_dev *dev)
++static int omap_i2c_bus_recover(struct omap_i2c_dev *dev)
+ {
+ 	u32 reg1;
+ 	u32 reg2;
++	int ret = 0;
+ 
+ 	/*
+ 	 * First differentiate SCL stuck low from SDA stuck low using our
+@@ -513,7 +490,7 @@ static void omap_i2c_bus_recover(struct omap_i2c_dev *dev)
+ 	 * bus, there's nothing more we can do; we will still try to Reset
+ 	 * our I2C IP anyway.
+ 	 */
+-
++	dev_err(dev->dev, "--> omap_i2c_bus_recover called!\n");
+ 	reg1 = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+ 	msleep(1);
+ 	reg2 = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+@@ -527,18 +504,21 @@ static void omap_i2c_bus_recover(struct omap_i2c_dev *dev)
+ 	if (!(reg1 & OMAP_I2C_SYSTEST_SDA_I_FUNC) &&
+ 			!(reg2 & OMAP_I2C_SYSTEST_SDA_I_FUNC)) {
+ 		dev_err(dev->dev, "SDA is stuck low, driving 9 pulses on SCL\n");
+-		omap_i2c_clock_pulse(dev);
++		i2c_generic_scl_recovery(&dev->adapter);
+ 
+ 		reg1 = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+ 		msleep(1);
+ 		reg2 = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+ 
+-		if ((reg1 & OMAP_I2C_SYSTEST_SDA_I_FUNC) &&
+-				(reg2 & OMAP_I2C_SYSTEST_SDA_I_FUNC)) {
++		if (!(reg1 & OMAP_I2C_SYSTEST_SDA_I_FUNC) &&
++				!(reg2 & OMAP_I2C_SYSTEST_SDA_I_FUNC)) {
+ 			dev_err(dev->dev, "SDA still stuck, resetting\n");
++			ret = -EBUSY;
+ 			omap_i2c_reset(dev);
+ 		}
+ 	}
++	
++	return 0;
+ }
+ 
+ /*
+@@ -776,10 +756,13 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
+ 	timeout = wait_for_completion_timeout(&omap->cmd_complete,
+ 						OMAP_I2C_TIMEOUT);
+ 	if (timeout == 0) {
++		int ret;
++		
+ 		dev_err(omap->dev, "controller timed out\n");
+-		omap_i2c_reset(omap);
+-		__omap_i2c_init(omap);
+-		return -ETIMEDOUT;
++                if((ret = omap_i2c_bus_recover(omap)))
++                        return ret;
++                        else
++                        return -ETIMEDOUT;
+ 	}
+ 
+ 	if (likely(!omap->cmd_err))

+ 1 - 0
package/gfasysinfo/Config.in

@@ -1,5 +1,6 @@
 config BR2_PACKAGE_GFASYSINFO
 	bool "GFASYSINFO"
+	select BR2_PACKAGE_GFAIPC
 	help
 	  
 	  GfA sysinfo service

+ 2 - 0
package/gfasysinfo/gfasysinfo.mk

@@ -8,6 +8,8 @@ GFASYSINFO_VERSION = 2024.10.28
 GFASYSINFO_SITE = https://gogs.reru.org/GfA/gfasysinfo.git
 GFASYSINFO_SITE_METHOD = git
 
+GFASYSINFO_DEPENDENCIES += gfaipc
+
 define GFASYSINFO_CONFIGURE_CMDS
 	(cd $(@D); $(TARGET_MAKE_ENV) $(HOST_DIR)/usr/bin/qmake)
 endef