diff options
Diffstat (limited to 'system/easy-kernel/therm_windtunnel.patch')
-rw-r--r-- | system/easy-kernel/therm_windtunnel.patch | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/system/easy-kernel/therm_windtunnel.patch b/system/easy-kernel/therm_windtunnel.patch new file mode 100644 index 000000000..5cfb92d7f --- /dev/null +++ b/system/easy-kernel/therm_windtunnel.patch @@ -0,0 +1,136 @@ +From 176cacef0119a441af14ccdfa125461635a1054d Mon Sep 17 00:00:00 2001 +From: Wolfram Sang <wsa@the-dreams.de> +Date: Tue, 25 Feb 2020 15:12:29 +0100 +Subject: [PATCH] macintosh: therm_windtunnel: fix regression when + instantiating devices + +commit 38b17afb0ebb9ecd41418d3c08bcf9198af4349d upstream. + +Removing attach_adapter from this driver caused a regression for at +least some machines. Those machines had the sensors described in their +DT, too, so they didn't need manual creation of the sensor devices. The +old code worked, though, because manual creation came first. Creation of +DT devices then failed later and caused error logs, but the sensors +worked nonetheless because of the manually created devices. + +When removing attach_adaper, manual creation now comes later and loses +the race. The sensor devices were already registered via DT, yet with +another binding, so the driver could not be bound to it. + +This fix refactors the code to remove the race and only manually creates +devices if there are no DT nodes present. Also, the DT binding is updated +to match both, the DT and manually created devices. Because we don't +know which device creation will be used at runtime, the code to start +the kthread is moved to do_probe() which will be called by both methods. + +Fixes: 3e7bed52719d ("macintosh: therm_windtunnel: drop using attach_adapter") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=201723 +Reported-by: Erhard Furtner <erhard_f@mailbox.org> +Tested-by: Erhard Furtner <erhard_f@mailbox.org> +Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc) +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +Cc: stable@kernel.org # v4.19+ +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/macintosh/therm_windtunnel.c | 52 +++++++++++++++++----------- + 1 file changed, 31 insertions(+), 21 deletions(-) + +diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c +index 8c744578122a..a0d87ed9da69 100644 +--- a/drivers/macintosh/therm_windtunnel.c ++++ b/drivers/macintosh/therm_windtunnel.c +@@ -300,9 +300,11 @@ static int control_loop(void *dummy) + /* i2c probing and setup */ + /************************************************************************/ + +-static int +-do_attach( struct i2c_adapter *adapter ) ++static void do_attach(struct i2c_adapter *adapter) + { ++ struct i2c_board_info info = { }; ++ struct device_node *np; ++ + /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ + static const unsigned short scan_ds1775[] = { + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +@@ -313,25 +315,24 @@ do_attach( struct i2c_adapter *adapter ) + I2C_CLIENT_END + }; + +- if( strncmp(adapter->name, "uni-n", 5) ) +- return 0; +- +- if( !x.running ) { +- struct i2c_board_info info; ++ if (x.running || strncmp(adapter->name, "uni-n", 5)) ++ return; + +- memset(&info, 0, sizeof(struct i2c_board_info)); +- strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); ++ } + +- strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); +- +- if( x.thermostat && x.fan ) { +- x.running = 1; +- x.poll_task = kthread_run(control_loop, NULL, "g4fand"); +- } + } +- return 0; + } + + static int +@@ -404,8 +405,8 @@ attach_thermostat( struct i2c_client *cl ) + enum chip { ds1775, adm1030 }; + + static const struct i2c_device_id therm_windtunnel_id[] = { +- { "therm_ds1775", ds1775 }, +- { "therm_adm1030", adm1030 }, ++ { "MAC,ds1775", ds1775 }, ++ { "MAC,adm1030", adm1030 }, + { } + }; + MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); +@@ -414,6 +415,7 @@ static int + do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + { + struct i2c_adapter *adapter = cl->adapter; ++ int ret = 0; + + if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA + | I2C_FUNC_SMBUS_WRITE_BYTE) ) +@@ -421,11 +423,19 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + + switch (id->driver_data) { + case adm1030: +- return attach_fan( cl ); ++ ret = attach_fan(cl); ++ break; + case ds1775: +- return attach_thermostat(cl); ++ ret = attach_thermostat(cl); ++ break; + } +- return 0; ++ ++ if (!x.running && x.thermostat && x.fan) { ++ x.running = 1; ++ x.poll_task = kthread_run(control_loop, NULL, "g4fand"); ++ } ++ ++ return ret; + } + + static struct i2c_driver g4fan_driver = { |