]>
Commit | Line | Data |
---|---|---|
99eec250 GKH |
1 | From 33a470f6d5e1879c26f16f6b34dc09f82d44f6e9 Mon Sep 17 00:00:00 2001 |
2 | From: Jean Delvare <khali@linux-fr.org> | |
3 | Date: Sun, 31 Jan 2010 04:00:30 +0000 | |
4 | Subject: macintosh/therm_adt746x: Fix sysfs attributes lifetime | |
5 | ||
6 | From: Jean Delvare <khali@linux-fr.org> | |
7 | ||
8 | commit 33a470f6d5e1879c26f16f6b34dc09f82d44f6e9 upstream. | |
9 | ||
10 | Looking at drivers/macintosh/therm_adt746x.c, the sysfs files are | |
11 | created in thermostat_init() and removed in thermostat_exit(), which | |
12 | are the driver's init and exit functions. These files are backed-up by | |
13 | a per-device structure, so it looks like the wrong thing to do: the | |
14 | sysfs files have a lifetime longer than the data structure that is | |
15 | backing it up. | |
16 | ||
17 | I think that sysfs files creation should be moved to the end of | |
18 | probe_thermostat() and sysfs files removal should be moved to the | |
19 | beginning of remove_thermostat(). | |
20 | ||
21 | Signed-off-by: Jean Delvare <khali@linux-fr.org> | |
22 | Tested-by: Christian Kujau <lists@nerdbynature.de> | |
23 | Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> | |
24 | Cc: Colin Leroy <colin@colino.net> | |
25 | Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
27 | ||
28 | --- | |
29 | drivers/macintosh/therm_adt746x.c | 34 ++++++++++++++++++++++++---------- | |
30 | 1 file changed, 24 insertions(+), 10 deletions(-) | |
31 | ||
32 | --- a/drivers/macintosh/therm_adt746x.c | |
33 | +++ b/drivers/macintosh/therm_adt746x.c | |
34 | @@ -90,6 +90,8 @@ static struct task_struct *thread_therm | |
35 | ||
36 | static void write_both_fan_speed(struct thermostat *th, int speed); | |
37 | static void write_fan_speed(struct thermostat *th, int speed, int fan); | |
38 | +static void thermostat_create_files(void); | |
39 | +static void thermostat_remove_files(void); | |
40 | ||
41 | static int | |
42 | write_reg(struct thermostat* th, int reg, u8 data) | |
43 | @@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *cli | |
44 | struct thermostat *th = i2c_get_clientdata(client); | |
45 | int i; | |
46 | ||
47 | + thermostat_remove_files(); | |
48 | + | |
49 | if (thread_therm != NULL) { | |
50 | kthread_stop(thread_therm); | |
51 | } | |
52 | @@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_c | |
53 | return -ENOMEM; | |
54 | } | |
55 | ||
56 | + thermostat_create_files(); | |
57 | + | |
58 | return 0; | |
59 | } | |
60 | ||
61 | @@ -566,7 +572,6 @@ thermostat_init(void) | |
62 | struct device_node* np; | |
63 | const u32 *prop; | |
64 | int i = 0, offset = 0; | |
65 | - int err; | |
66 | ||
67 | np = of_find_node_by_name(NULL, "fan"); | |
68 | if (!np) | |
69 | @@ -633,6 +638,17 @@ thermostat_init(void) | |
70 | return -ENODEV; | |
71 | } | |
72 | ||
73 | +#ifndef CONFIG_I2C_POWERMAC | |
74 | + request_module("i2c-powermac"); | |
75 | +#endif | |
76 | + | |
77 | + return i2c_add_driver(&thermostat_driver); | |
78 | +} | |
79 | + | |
80 | +static void thermostat_create_files(void) | |
81 | +{ | |
82 | + int err; | |
83 | + | |
84 | err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); | |
85 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); | |
86 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); | |
87 | @@ -647,16 +663,9 @@ thermostat_init(void) | |
88 | if (err) | |
89 | printk(KERN_WARNING | |
90 | "Failed to create tempertaure attribute file(s).\n"); | |
91 | - | |
92 | -#ifndef CONFIG_I2C_POWERMAC | |
93 | - request_module("i2c-powermac"); | |
94 | -#endif | |
95 | - | |
96 | - return i2c_add_driver(&thermostat_driver); | |
97 | } | |
98 | ||
99 | -static void __exit | |
100 | -thermostat_exit(void) | |
101 | +static void thermostat_remove_files(void) | |
102 | { | |
103 | if (of_dev) { | |
104 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); | |
105 | @@ -673,9 +682,14 @@ thermostat_exit(void) | |
106 | device_remove_file(&of_dev->dev, | |
107 | &dev_attr_sensor2_fan_speed); | |
108 | ||
109 | - of_device_unregister(of_dev); | |
110 | } | |
111 | +} | |
112 | + | |
113 | +static void __exit | |
114 | +thermostat_exit(void) | |
115 | +{ | |
116 | i2c_del_driver(&thermostat_driver); | |
117 | + of_device_unregister(of_dev); | |
118 | } | |
119 | ||
120 | module_init(thermostat_init); |