From cb270eb1829b9e76182fd038c87e4e8df13cdedb Mon Sep 17 00:00:00 2001
From: Max Rees <maxcrees@me.com>
Date: Wed, 8 Jul 2020 20:32:33 -0500
Subject: system/easy-kernel: patch a few macintosh thermal issues (#283)

---
 system/easy-kernel/APKBUILD               |  10 +-
 system/easy-kernel/therm_windtunnel.patch | 136 ++++++++++++++++++++++
 system/easy-kernel/windfarm.patch         | 182 ++++++++++++++++++++++++++++++
 system/easy-kernel/windfarm_pm112.patch   |  99 ++++++++++++++++
 4 files changed, 425 insertions(+), 2 deletions(-)
 create mode 100644 system/easy-kernel/therm_windtunnel.patch
 create mode 100644 system/easy-kernel/windfarm.patch
 create mode 100644 system/easy-kernel/windfarm_pm112.patch

(limited to 'system')

diff --git a/system/easy-kernel/APKBUILD b/system/easy-kernel/APKBUILD
index 72d4a1c48..e85e842a3 100644
--- a/system/easy-kernel/APKBUILD
+++ b/system/easy-kernel/APKBUILD
@@ -5,7 +5,7 @@ _kflavour=""
 _patchver=0
 _pkgname=easy-kernel$_kflavour
 pkgver=5.4.5
-pkgrel=3
+pkgrel=4
 pkgname=$_pkgname-$pkgver-mc$_patchver
 pkgdesc="The Linux kernel, packaged for your convenience"
 url="https://kernel.org/"
@@ -33,6 +33,9 @@ source="https://cdn.kernel.org/pub/linux/kernel/v${_pkgmajver}.x/linux-${_pkgmin
 	asound-syntax-fix.patch
 	kernel.h
 	uapi-iphdr.patch
+	therm_windtunnel.patch
+	windfarm.patch
+	windfarm_pm112.patch
 	"
 builddir="$srcdir/linux-${_pkgminver}"
 
@@ -143,4 +146,7 @@ e5f8f07c588ebbaa53166711b9940aa6d14a72e017df50300f3817c34a1abc2931f191431246d313
 581da20b2e0db48fcb29fe97ce6cf5d2e6a7092cbe2fd1b48cbdaddc1bc15d24e2470e56394624ff61b94b6ccf25035d07a18d9cbc4c16ac7f2865913a13c0d8  config-m68k
 4b2cd7dd0010aaec617c756e7587be7fad6ff0ab3dbc1ed038e3dc72c9308fc9e347c6e5296c30711d914e286aa254600586e2ad954a5da226e6e4c1522b75b5  asound-syntax-fix.patch
 61dcd633d72876566b7738dd08856b26850c935b4a81ab2364711335fe01c397083160f530b3382bbc239c6a8135be6a032e93039083ec2cefdae2902429a2e0  kernel.h
-6f309a18c65c991240265afd200cc79a706f5d9e5d072838a9a641ab3676a5e4c32033f9767fc723ff4c45ee462169a0f77bd7dfe63b547d521dadd073f827a7  uapi-iphdr.patch"
+6f309a18c65c991240265afd200cc79a706f5d9e5d072838a9a641ab3676a5e4c32033f9767fc723ff4c45ee462169a0f77bd7dfe63b547d521dadd073f827a7  uapi-iphdr.patch
+33d1565228bfeed362f9ebf3a4a260469902d96002e7805516f705fafd7a488dfbe7683d911f6cb3e5293d02af026fb8fe593c058b6361457d7333323b3eabe7  therm_windtunnel.patch
+b83ed1db626211b38c2308902306ccb4f2e215f1d82356a0fe3798e227239586817ef341b5298e227cbf436ef3c19af80eb449cbd98c373f1de5dd461a1fdb4b  windfarm.patch
+e5667717e988d28b8450ffd06d6402212c26da992c2e8aa041f37e21cc3c1fbf54712a8216ebd3ef8ae59ac48c8ecdde5596a8c25028338f782b615c4a6c232c  windfarm_pm112.patch"
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 = {
diff --git a/system/easy-kernel/windfarm.patch b/system/easy-kernel/windfarm.patch
new file mode 100644
index 000000000..bad7fe159
--- /dev/null
+++ b/system/easy-kernel/windfarm.patch
@@ -0,0 +1,182 @@
+From f19bbb24a1082b2790eb113fcc5cd55fca340f49 Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa@the-dreams.de>
+Date: Tue, 3 Mar 2020 13:50:46 +0100
+Subject: [PATCH] macintosh: windfarm: fix MODINFO regression
+
+commit bcf3588d8ed3517e6ffaf083f034812aee9dc8e2 upstream.
+
+Commit af503716ac14 made sure OF devices get an OF style modalias with
+I2C events. It assumed all in-tree users were converted, yet it missed
+some Macintosh drivers.
+
+Add an OF module device table for all windfarm drivers to make them
+automatically load again.
+
+Fixes: af503716ac14 ("i2c: core: report OF style module alias for devices registered via OF")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=199471
+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.17+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/macintosh/windfarm_ad7417_sensor.c  |  7 +++++++
+ drivers/macintosh/windfarm_fcu_controls.c   |  7 +++++++
+ drivers/macintosh/windfarm_lm75_sensor.c    | 16 +++++++++++++++-
+ drivers/macintosh/windfarm_lm87_sensor.c    |  7 +++++++
+ drivers/macintosh/windfarm_max6690_sensor.c |  7 +++++++
+ drivers/macintosh/windfarm_smu_sat.c        |  7 +++++++
+ 6 files changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/macintosh/windfarm_ad7417_sensor.c b/drivers/macintosh/windfarm_ad7417_sensor.c
+index 125605987b44..e7dec328c7cf 100644
+--- a/drivers/macintosh/windfarm_ad7417_sensor.c
++++ b/drivers/macintosh/windfarm_ad7417_sensor.c
+@@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_ad7417_id);
+ 
++static const struct of_device_id wf_ad7417_of_id[] = {
++	{ .compatible = "ad7417", },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_ad7417_of_id);
++
+ static struct i2c_driver wf_ad7417_driver = {
+ 	.driver = {
+ 		.name	= "wf_ad7417",
++		.of_match_table = wf_ad7417_of_id,
+ 	},
+ 	.probe		= wf_ad7417_probe,
+ 	.remove		= wf_ad7417_remove,
+diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c
+index 3c971297b6dc..89b48e8ac6ef 100644
+--- a/drivers/macintosh/windfarm_fcu_controls.c
++++ b/drivers/macintosh/windfarm_fcu_controls.c
+@@ -582,9 +582,16 @@ static const struct i2c_device_id wf_fcu_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_fcu_id);
+ 
++static const struct of_device_id wf_fcu_of_id[] = {
++	{ .compatible = "fcu", },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_fcu_of_id);
++
+ static struct i2c_driver wf_fcu_driver = {
+ 	.driver = {
+ 		.name	= "wf_fcu",
++		.of_match_table = wf_fcu_of_id,
+ 	},
+ 	.probe		= wf_fcu_probe,
+ 	.remove		= wf_fcu_remove,
+diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
+index 282c28a17ea1..1e5fa09845e7 100644
+--- a/drivers/macintosh/windfarm_lm75_sensor.c
++++ b/drivers/macintosh/windfarm_lm75_sensor.c
+@@ -14,6 +14,7 @@
+ #include <linux/init.h>
+ #include <linux/wait.h>
+ #include <linux/i2c.h>
++#include <linux/of_device.h>
+ #include <asm/prom.h>
+ #include <asm/machdep.h>
+ #include <asm/io.h>
+@@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client,
+ 			 const struct i2c_device_id *id)
+ {	
+ 	struct wf_lm75_sensor *lm;
+-	int rc, ds1775 = id->driver_data;
++	int rc, ds1775;
+ 	const char *name, *loc;
+ 
++	if (id)
++		ds1775 = id->driver_data;
++	else
++		ds1775 = !!of_device_get_match_data(&client->dev);
++
+ 	DBG("wf_lm75: creating  %s device at address 0x%02x\n",
+ 	    ds1775 ? "ds1775" : "lm75", client->addr);
+ 
+@@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_lm75_id);
+ 
++static const struct of_device_id wf_lm75_of_id[] = {
++	{ .compatible = "lm75", .data = (void *)0},
++	{ .compatible = "ds1775", .data = (void *)1 },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_lm75_of_id);
++
+ static struct i2c_driver wf_lm75_driver = {
+ 	.driver = {
+ 		.name	= "wf_lm75",
++		.of_match_table = wf_lm75_of_id,
+ 	},
+ 	.probe		= wf_lm75_probe,
+ 	.remove		= wf_lm75_remove,
+diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c
+index e44525b19071..1a1f8f3f0abc 100644
+--- a/drivers/macintosh/windfarm_lm87_sensor.c
++++ b/drivers/macintosh/windfarm_lm87_sensor.c
+@@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_lm87_id);
+ 
++static const struct of_device_id wf_lm87_of_id[] = {
++	{ .compatible = "lm87cimt", },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_lm87_of_id);
++
+ static struct i2c_driver wf_lm87_driver = {
+ 	.driver = {
+ 		.name	= "wf_lm87",
++		.of_match_table = wf_lm87_of_id,
+ 	},
+ 	.probe		= wf_lm87_probe,
+ 	.remove		= wf_lm87_remove,
+diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
+index e666cc020683..1e7b03d44ad9 100644
+--- a/drivers/macintosh/windfarm_max6690_sensor.c
++++ b/drivers/macintosh/windfarm_max6690_sensor.c
+@@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
+ 
++static const struct of_device_id wf_max6690_of_id[] = {
++	{ .compatible = "max6690", },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_max6690_of_id);
++
+ static struct i2c_driver wf_max6690_driver = {
+ 	.driver = {
+ 		.name		= "wf_max6690",
++		.of_match_table = wf_max6690_of_id,
+ 	},
+ 	.probe		= wf_max6690_probe,
+ 	.remove		= wf_max6690_remove,
+diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
+index c84ec49c3741..cb75dc035616 100644
+--- a/drivers/macintosh/windfarm_smu_sat.c
++++ b/drivers/macintosh/windfarm_smu_sat.c
+@@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, wf_sat_id);
+ 
++static const struct of_device_id wf_sat_of_id[] = {
++	{ .compatible = "smu-sat", },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, wf_sat_of_id);
++
+ static struct i2c_driver wf_sat_driver = {
+ 	.driver = {
+ 		.name		= "wf_smu_sat",
++		.of_match_table = wf_sat_of_id,
+ 	},
+ 	.probe		= wf_sat_probe,
+ 	.remove		= wf_sat_remove,
diff --git a/system/easy-kernel/windfarm_pm112.patch b/system/easy-kernel/windfarm_pm112.patch
new file mode 100644
index 000000000..2b8e8a3ec
--- /dev/null
+++ b/system/easy-kernel/windfarm_pm112.patch
@@ -0,0 +1,99 @@
+From c6077abc067fb6bf57a2b1acffd918b1b9211047 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Thu, 23 Apr 2020 16:00:38 +1000
+Subject: [PATCH] drivers/macintosh: Fix memleak in windfarm_pm112 driver
+
+commit 93900337b9ac2f4eca427eff6d187be2dc3b5551 upstream.
+
+create_cpu_loop() calls smu_sat_get_sdb_partition() which does
+kmalloc() and returns the allocated buffer. In fact it's called twice,
+and neither buffer is freed.
+
+This results in a memory leak as reported by Erhard:
+  unreferenced object 0xc00000047081f840 (size 32):
+    comm "kwindfarm", pid 203, jiffies 4294880630 (age 5552.877s)
+    hex dump (first 32 bytes):
+      c8 06 02 7f ff 02 ff 01 fb bf 00 41 00 20 00 00  ...........A. ..
+      00 07 89 37 00 a0 00 00 00 00 00 00 00 00 00 00  ...7............
+    backtrace:
+      [<0000000083f0a65c>] .smu_sat_get_sdb_partition+0xc4/0x2d0 [windfarm_smu_sat]
+      [<000000003010fcb7>] .pm112_wf_notify+0x104c/0x13bc [windfarm_pm112]
+      [<00000000b958b2dd>] .notifier_call_chain+0xa8/0x180
+      [<0000000070490868>] .blocking_notifier_call_chain+0x64/0x90
+      [<00000000131d8149>] .wf_thread_func+0x114/0x1a0
+      [<000000000d54838d>] .kthread+0x13c/0x190
+      [<00000000669b72bc>] .ret_from_kernel_thread+0x58/0x64
+  unreferenced object 0xc0000004737089f0 (size 16):
+    comm "kwindfarm", pid 203, jiffies 4294880879 (age 5552.050s)
+    hex dump (first 16 bytes):
+      c4 04 01 7f 22 11 e0 e6 ff 55 7b 12 ec 11 00 00  ...."....U{.....
+    backtrace:
+      [<0000000083f0a65c>] .smu_sat_get_sdb_partition+0xc4/0x2d0 [windfarm_smu_sat]
+      [<00000000b94ef7e1>] .pm112_wf_notify+0x1294/0x13bc [windfarm_pm112]
+      [<00000000b958b2dd>] .notifier_call_chain+0xa8/0x180
+      [<0000000070490868>] .blocking_notifier_call_chain+0x64/0x90
+      [<00000000131d8149>] .wf_thread_func+0x114/0x1a0
+      [<000000000d54838d>] .kthread+0x13c/0x190
+      [<00000000669b72bc>] .ret_from_kernel_thread+0x58/0x64
+
+Fix it by rearranging the logic so we deal with each buffer
+separately, which then makes it easy to free the buffer once we're
+done with it.
+
+Fixes: ac171c46667c ("[PATCH] powerpc: Thermal control for dual core G5s")
+Cc: stable@vger.kernel.org # v2.6.16+
+Reported-by: Erhard F. <erhard_f@mailbox.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Tested-by: Erhard F. <erhard_f@mailbox.org>
+Link: https://lore.kernel.org/r/20200423060038.3308530-1-mpe@ellerman.id.au
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/macintosh/windfarm_pm112.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
+index 4150301a89a5..e8377ce0a95a 100644
+--- a/drivers/macintosh/windfarm_pm112.c
++++ b/drivers/macintosh/windfarm_pm112.c
+@@ -132,14 +132,6 @@ static int create_cpu_loop(int cpu)
+ 	s32 tmax;
+ 	int fmin;
+ 
+-	/* Get PID params from the appropriate SAT */
+-	hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
+-	if (hdr == NULL) {
+-		printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
+-		return -EINVAL;
+-	}
+-	piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+-
+ 	/* Get FVT params to get Tmax; if not found, assume default */
+ 	hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
+ 	if (hdr) {
+@@ -152,6 +144,16 @@ static int create_cpu_loop(int cpu)
+ 	if (tmax < cpu_all_tmax)
+ 		cpu_all_tmax = tmax;
+ 
++	kfree(hdr);
++
++	/* Get PID params from the appropriate SAT */
++	hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
++	if (hdr == NULL) {
++		printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
++		return -EINVAL;
++	}
++	piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
++
+ 	/*
+ 	 * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
+ 	 * 515 for the 2-way.  That appears to be overkill, so for now,
+@@ -174,6 +176,9 @@ static int create_cpu_loop(int cpu)
+ 		pid.min = fmin;
+ 
+ 	wf_cpu_pid_init(&cpu_pid[cpu], &pid);
++
++	kfree(hdr);
++
+ 	return 0;
+ }
+ 
-- 
cgit v1.2.3-70-g09d2