diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-04-18 18:16:44 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-04-30 01:37:18 -0400 |
commit | 5400480f5411aab31939747371c6690a02ee7780 (patch) | |
tree | 4fa927215a522c96abe0d1d44f0431474211edcc /drivers/macintosh | |
parent | 7a4b15cdf3d607152ba23fa4aa2bf072c6810924 (diff) |
powerpc/pmac: Convert windfarm_lm75 to new i2c probing
This simplifies the driver to stop using the deprecated attach interface
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/windfarm_lm75_sensor.c | 124 |
1 files changed, 30 insertions, 94 deletions
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 4d6a90a1372b..4cc3f935709d 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "windfarm.h" | 24 | #include "windfarm.h" |
25 | 25 | ||
26 | #define VERSION "0.2" | 26 | #define VERSION "1.0" |
27 | 27 | ||
28 | #undef DEBUG | 28 | #undef DEBUG |
29 | 29 | ||
@@ -36,8 +36,8 @@ | |||
36 | struct wf_lm75_sensor { | 36 | struct wf_lm75_sensor { |
37 | int ds1775 : 1; | 37 | int ds1775 : 1; |
38 | int inited : 1; | 38 | int inited : 1; |
39 | struct i2c_client *i2c; | 39 | struct i2c_client *i2c; |
40 | struct wf_sensor sens; | 40 | struct wf_sensor sens; |
41 | }; | 41 | }; |
42 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) | 42 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) |
43 | 43 | ||
@@ -90,40 +90,19 @@ static struct wf_sensor_ops wf_lm75_ops = { | |||
90 | 90 | ||
91 | static int wf_lm75_probe(struct i2c_client *client, | 91 | static int wf_lm75_probe(struct i2c_client *client, |
92 | const struct i2c_device_id *id) | 92 | const struct i2c_device_id *id) |
93 | { | 93 | { |
94 | struct wf_lm75_sensor *lm; | 94 | struct wf_lm75_sensor *lm; |
95 | int rc; | 95 | int rc, ds1775 = id->driver_data; |
96 | 96 | const char *name, *loc; | |
97 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); | ||
98 | if (lm == NULL) | ||
99 | return -ENODEV; | ||
100 | |||
101 | lm->inited = 0; | ||
102 | lm->ds1775 = id->driver_data; | ||
103 | lm->i2c = client; | ||
104 | lm->sens.name = client->dev.platform_data; | ||
105 | lm->sens.ops = &wf_lm75_ops; | ||
106 | i2c_set_clientdata(client, lm); | ||
107 | |||
108 | rc = wf_register_sensor(&lm->sens); | ||
109 | if (rc) | ||
110 | kfree(lm); | ||
111 | |||
112 | return rc; | ||
113 | } | ||
114 | |||
115 | static struct i2c_driver wf_lm75_driver; | ||
116 | |||
117 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | ||
118 | u8 addr, int ds1775, | ||
119 | const char *loc) | ||
120 | { | ||
121 | struct i2c_board_info info; | ||
122 | struct i2c_client *client; | ||
123 | char *name; | ||
124 | 97 | ||
125 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | 98 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
126 | ds1775 ? "ds1775" : "lm75", addr); | 99 | ds1775 ? "ds1775" : "lm75", client->addr); |
100 | |||
101 | loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL); | ||
102 | if (!loc) { | ||
103 | dev_warn(&client->dev, "Missing hwsensor-location property!\n"); | ||
104 | return -ENXIO; | ||
105 | } | ||
127 | 106 | ||
128 | /* Usual rant about sensor names not beeing very consistent in | 107 | /* Usual rant about sensor names not beeing very consistent in |
129 | * the device-tree, oh well ... | 108 | * the device-tree, oh well ... |
@@ -138,67 +117,24 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | |||
138 | else if (!strcmp(loc, "HD Temp")) | 117 | else if (!strcmp(loc, "HD Temp")) |
139 | name = "hard-drive-temp"; | 118 | name = "hard-drive-temp"; |
140 | else | 119 | else |
141 | goto fail; | 120 | return -ENXIO; |
142 | 121 | ||
143 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
144 | info.addr = (addr >> 1) & 0x7f; | ||
145 | info.platform_data = name; | ||
146 | strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE); | ||
147 | |||
148 | client = i2c_new_device(adapter, &info); | ||
149 | if (client == NULL) { | ||
150 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | ||
151 | ds1775 ? "ds1775" : "lm75", name); | ||
152 | goto fail; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Let i2c-core delete that device on driver removal. | ||
157 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
158 | */ | ||
159 | list_add_tail(&client->detected, &wf_lm75_driver.clients); | ||
160 | return client; | ||
161 | fail: | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
165 | static int wf_lm75_attach(struct i2c_adapter *adapter) | ||
166 | { | ||
167 | struct device_node *busnode, *dev; | ||
168 | struct pmac_i2c_bus *bus; | ||
169 | 122 | ||
170 | DBG("wf_lm75: adapter %s detected\n", adapter->name); | 123 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); |
171 | 124 | if (lm == NULL) | |
172 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
173 | if (bus == NULL) | ||
174 | return -ENODEV; | 125 | return -ENODEV; |
175 | busnode = pmac_i2c_get_bus_node(bus); | ||
176 | 126 | ||
177 | DBG("wf_lm75: bus found, looking for device...\n"); | 127 | lm->inited = 0; |
178 | 128 | lm->ds1775 = ds1775; | |
179 | /* Now look for lm75(s) in there */ | 129 | lm->i2c = client; |
180 | for (dev = NULL; | 130 | lm->sens.name = (char *)name; /* XXX fix constness in structure */ |
181 | (dev = of_get_next_child(busnode, dev)) != NULL;) { | 131 | lm->sens.ops = &wf_lm75_ops; |
182 | const char *loc = | 132 | i2c_set_clientdata(client, lm); |
183 | of_get_property(dev, "hwsensor-location", NULL); | ||
184 | u8 addr; | ||
185 | 133 | ||
186 | /* We must re-match the adapter in order to properly check | 134 | rc = wf_register_sensor(&lm->sens); |
187 | * the channel on multibus setups | 135 | if (rc) |
188 | */ | 136 | kfree(lm); |
189 | if (!pmac_i2c_match_adapter(dev, adapter)) | 137 | return rc; |
190 | continue; | ||
191 | addr = pmac_i2c_get_dev_addr(dev); | ||
192 | if (loc == NULL || addr == 0) | ||
193 | continue; | ||
194 | /* real lm75 */ | ||
195 | if (of_device_is_compatible(dev, "lm75")) | ||
196 | wf_lm75_create(adapter, addr, 0, loc); | ||
197 | /* ds1775 (compatible, better resolution */ | ||
198 | else if (of_device_is_compatible(dev, "ds1775")) | ||
199 | wf_lm75_create(adapter, addr, 1, loc); | ||
200 | } | ||
201 | return 0; | ||
202 | } | 138 | } |
203 | 139 | ||
204 | static int wf_lm75_remove(struct i2c_client *client) | 140 | static int wf_lm75_remove(struct i2c_client *client) |
@@ -217,16 +153,16 @@ static int wf_lm75_remove(struct i2c_client *client) | |||
217 | } | 153 | } |
218 | 154 | ||
219 | static const struct i2c_device_id wf_lm75_id[] = { | 155 | static const struct i2c_device_id wf_lm75_id[] = { |
220 | { "wf_lm75", 0 }, | 156 | { "MAC,lm75", 0 }, |
221 | { "wf_ds1775", 1 }, | 157 | { "MAC,ds1775", 1 }, |
222 | { } | 158 | { } |
223 | }; | 159 | }; |
160 | MODULE_DEVICE_TABLE(i2c, wf_lm75_id); | ||
224 | 161 | ||
225 | static struct i2c_driver wf_lm75_driver = { | 162 | static struct i2c_driver wf_lm75_driver = { |
226 | .driver = { | 163 | .driver = { |
227 | .name = "wf_lm75", | 164 | .name = "wf_lm75", |
228 | }, | 165 | }, |
229 | .attach_adapter = wf_lm75_attach, | ||
230 | .probe = wf_lm75_probe, | 166 | .probe = wf_lm75_probe, |
231 | .remove = wf_lm75_remove, | 167 | .remove = wf_lm75_remove, |
232 | .id_table = wf_lm75_id, | 168 | .id_table = wf_lm75_id, |