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