diff options
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/therm_adt746x.c | 84 |
1 files changed, 42 insertions, 42 deletions
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c0621d50c8a0..4a8bf467ff43 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -71,7 +71,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations " | |||
71 | "(default 0)"); | 71 | "(default 0)"); |
72 | 72 | ||
73 | struct thermostat { | 73 | struct thermostat { |
74 | struct i2c_client clt; | 74 | struct i2c_client *clt; |
75 | u8 temps[3]; | 75 | u8 temps[3]; |
76 | u8 cached_temp[3]; | 76 | u8 cached_temp[3]; |
77 | u8 initial_limits[3]; | 77 | u8 initial_limits[3]; |
@@ -86,9 +86,6 @@ static struct of_device * of_dev; | |||
86 | static struct thermostat* thermostat; | 86 | static struct thermostat* thermostat; |
87 | static struct task_struct *thread_therm = NULL; | 87 | static struct task_struct *thread_therm = NULL; |
88 | 88 | ||
89 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | ||
90 | int busno); | ||
91 | |||
92 | static void write_both_fan_speed(struct thermostat *th, int speed); | 89 | static void write_both_fan_speed(struct thermostat *th, int speed); |
93 | static void write_fan_speed(struct thermostat *th, int speed, int fan); | 90 | static void write_fan_speed(struct thermostat *th, int speed, int fan); |
94 | 91 | ||
@@ -100,7 +97,7 @@ write_reg(struct thermostat* th, int reg, u8 data) | |||
100 | 97 | ||
101 | tmp[0] = reg; | 98 | tmp[0] = reg; |
102 | tmp[1] = data; | 99 | tmp[1] = data; |
103 | rc = i2c_master_send(&th->clt, (const char *)tmp, 2); | 100 | rc = i2c_master_send(th->clt, (const char *)tmp, 2); |
104 | if (rc < 0) | 101 | if (rc < 0) |
105 | return rc; | 102 | return rc; |
106 | if (rc != 2) | 103 | if (rc != 2) |
@@ -115,12 +112,12 @@ read_reg(struct thermostat* th, int reg) | |||
115 | int rc; | 112 | int rc; |
116 | 113 | ||
117 | reg_addr = (u8)reg; | 114 | reg_addr = (u8)reg; |
118 | rc = i2c_master_send(&th->clt, ®_addr, 1); | 115 | rc = i2c_master_send(th->clt, ®_addr, 1); |
119 | if (rc < 0) | 116 | if (rc < 0) |
120 | return rc; | 117 | return rc; |
121 | if (rc != 1) | 118 | if (rc != 1) |
122 | return -ENODEV; | 119 | return -ENODEV; |
123 | rc = i2c_master_recv(&th->clt, (char *)&data, 1); | 120 | rc = i2c_master_recv(th->clt, (char *)&data, 1); |
124 | if (rc < 0) | 121 | if (rc < 0) |
125 | return rc; | 122 | return rc; |
126 | return data; | 123 | return data; |
@@ -130,26 +127,36 @@ static int | |||
130 | attach_thermostat(struct i2c_adapter *adapter) | 127 | attach_thermostat(struct i2c_adapter *adapter) |
131 | { | 128 | { |
132 | unsigned long bus_no; | 129 | unsigned long bus_no; |
130 | struct i2c_board_info info; | ||
131 | struct i2c_client *client; | ||
133 | 132 | ||
134 | if (strncmp(adapter->name, "uni-n", 5)) | 133 | if (strncmp(adapter->name, "uni-n", 5)) |
135 | return -ENODEV; | 134 | return -ENODEV; |
136 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); | 135 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); |
137 | if (bus_no != therm_bus) | 136 | if (bus_no != therm_bus) |
138 | return -ENODEV; | 137 | return -ENODEV; |
139 | return attach_one_thermostat(adapter, therm_address, bus_no); | 138 | |
139 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
140 | strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE); | ||
141 | info.addr = therm_address; | ||
142 | client = i2c_new_device(adapter, &info); | ||
143 | if (!client) | ||
144 | return -ENODEV; | ||
145 | |||
146 | /* | ||
147 | * Let i2c-core delete that device on driver removal. | ||
148 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
149 | */ | ||
150 | list_add_tail(&client->detected, &client->driver->clients); | ||
151 | return 0; | ||
140 | } | 152 | } |
141 | 153 | ||
142 | static int | 154 | static int |
143 | detach_thermostat(struct i2c_adapter *adapter) | 155 | remove_thermostat(struct i2c_client *client) |
144 | { | 156 | { |
145 | struct thermostat* th; | 157 | struct thermostat *th = i2c_get_clientdata(client); |
146 | int i; | 158 | int i; |
147 | 159 | ||
148 | if (thermostat == NULL) | ||
149 | return 0; | ||
150 | |||
151 | th = thermostat; | ||
152 | |||
153 | if (thread_therm != NULL) { | 160 | if (thread_therm != NULL) { |
154 | kthread_stop(thread_therm); | 161 | kthread_stop(thread_therm); |
155 | } | 162 | } |
@@ -165,8 +172,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
165 | 172 | ||
166 | write_both_fan_speed(th, -1); | 173 | write_both_fan_speed(th, -1); |
167 | 174 | ||
168 | i2c_detach_client(&th->clt); | ||
169 | |||
170 | thermostat = NULL; | 175 | thermostat = NULL; |
171 | 176 | ||
172 | kfree(th); | 177 | kfree(th); |
@@ -174,14 +179,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
174 | return 0; | 179 | return 0; |
175 | } | 180 | } |
176 | 181 | ||
177 | static struct i2c_driver thermostat_driver = { | ||
178 | .driver = { | ||
179 | .name = "therm_adt746x", | ||
180 | }, | ||
181 | .attach_adapter = attach_thermostat, | ||
182 | .detach_adapter = detach_thermostat, | ||
183 | }; | ||
184 | |||
185 | static int read_fan_speed(struct thermostat *th, u8 addr) | 182 | static int read_fan_speed(struct thermostat *th, u8 addr) |
186 | { | 183 | { |
187 | u8 tmp[2]; | 184 | u8 tmp[2]; |
@@ -369,8 +366,8 @@ static void set_limit(struct thermostat *th, int i) | |||
369 | th->limits[i] = default_limits_local[i] + limit_adjust; | 366 | th->limits[i] = default_limits_local[i] + limit_adjust; |
370 | } | 367 | } |
371 | 368 | ||
372 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | 369 | static int probe_thermostat(struct i2c_client *client, |
373 | int busno) | 370 | const struct i2c_device_id *id) |
374 | { | 371 | { |
375 | struct thermostat* th; | 372 | struct thermostat* th; |
376 | int rc; | 373 | int rc; |
@@ -383,16 +380,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
383 | if (!th) | 380 | if (!th) |
384 | return -ENOMEM; | 381 | return -ENOMEM; |
385 | 382 | ||
386 | th->clt.addr = addr; | 383 | i2c_set_clientdata(client, th); |
387 | th->clt.adapter = adapter; | 384 | th->clt = client; |
388 | th->clt.driver = &thermostat_driver; | ||
389 | strcpy(th->clt.name, "thermostat"); | ||
390 | 385 | ||
391 | rc = read_reg(th, 0); | 386 | rc = read_reg(th, 0); |
392 | if (rc < 0) { | 387 | if (rc < 0) { |
393 | printk(KERN_ERR "adt746x: Thermostat failed to read config " | 388 | dev_err(&client->dev, "Thermostat failed to read config!\n"); |
394 | "from bus %d !\n", | ||
395 | busno); | ||
396 | kfree(th); | 389 | kfree(th); |
397 | return -ENODEV; | 390 | return -ENODEV; |
398 | } | 391 | } |
@@ -421,14 +414,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
421 | 414 | ||
422 | thermostat = th; | 415 | thermostat = th; |
423 | 416 | ||
424 | if (i2c_attach_client(&th->clt)) { | ||
425 | printk(KERN_INFO "adt746x: Thermostat failed to attach " | ||
426 | "client !\n"); | ||
427 | thermostat = NULL; | ||
428 | kfree(th); | ||
429 | return -ENODEV; | ||
430 | } | ||
431 | |||
432 | /* be sure to really write fan speed the first time */ | 417 | /* be sure to really write fan speed the first time */ |
433 | th->last_speed[0] = -2; | 418 | th->last_speed[0] = -2; |
434 | th->last_speed[1] = -2; | 419 | th->last_speed[1] = -2; |
@@ -454,6 +439,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
454 | return 0; | 439 | return 0; |
455 | } | 440 | } |
456 | 441 | ||
442 | static const struct i2c_device_id therm_adt746x_id[] = { | ||
443 | { "therm_adt746x", 0 }, | ||
444 | { } | ||
445 | }; | ||
446 | |||
447 | static struct i2c_driver thermostat_driver = { | ||
448 | .driver = { | ||
449 | .name = "therm_adt746x", | ||
450 | }, | ||
451 | .attach_adapter = attach_thermostat, | ||
452 | .probe = probe_thermostat, | ||
453 | .remove = remove_thermostat, | ||
454 | .id_table = therm_adt746x_id, | ||
455 | }; | ||
456 | |||
457 | /* | 457 | /* |
458 | * Now, unfortunately, sysfs doesn't give us a nice void * we could | 458 | * Now, unfortunately, sysfs doesn't give us a nice void * we could |
459 | * pass around to the attribute functions, so we don't really have | 459 | * pass around to the attribute functions, so we don't really have |