Commit | Line | Data |
---|---|---|
31321b76 BD |
1 | Upgrading I2C Drivers to the new 2.6 Driver Model |
2 | ================================================= | |
3 | ||
4 | Ben Dooks <ben-linux@fluff.org> | |
5 | ||
6 | Introduction | |
7 | ------------ | |
8 | ||
9 | This guide outlines how to alter existing Linux 2.6 client drivers from | |
10 | the old to the new new binding methods. | |
11 | ||
12 | ||
13 | Example old-style driver | |
14 | ------------------------ | |
15 | ||
16 | ||
17 | struct example_state { | |
18 | struct i2c_client client; | |
19 | .... | |
20 | }; | |
21 | ||
22 | static struct i2c_driver example_driver; | |
23 | ||
24 | static unsigned short ignore[] = { I2C_CLIENT_END }; | |
25 | static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END }; | |
26 | ||
27 | I2C_CLIENT_INSMOD; | |
28 | ||
29 | static int example_attach(struct i2c_adapter *adap, int addr, int kind) | |
30 | { | |
31 | struct example_state *state; | |
32 | struct device *dev = &adap->dev; /* to use for dev_ reports */ | |
33 | int ret; | |
34 | ||
35 | state = kzalloc(sizeof(struct example_state), GFP_KERNEL); | |
36 | if (state == NULL) { | |
37 | dev_err(dev, "failed to create our state\n"); | |
38 | return -ENOMEM; | |
39 | } | |
40 | ||
41 | example->client.addr = addr; | |
42 | example->client.flags = 0; | |
43 | example->client.adapter = adap; | |
44 | ||
45 | i2c_set_clientdata(&state->i2c_client, state); | |
46 | strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE); | |
47 | ||
48 | ret = i2c_attach_client(&state->i2c_client); | |
49 | if (ret < 0) { | |
50 | dev_err(dev, "failed to attach client\n"); | |
51 | kfree(state); | |
52 | return ret; | |
53 | } | |
54 | ||
55 | dev = &state->i2c_client.dev; | |
56 | ||
57 | /* rest of the initialisation goes here. */ | |
58 | ||
59 | dev_info(dev, "example client created\n"); | |
60 | ||
61 | return 0; | |
62 | } | |
63 | ||
ed065e26 | 64 | static int example_detach(struct i2c_client *client) |
31321b76 BD |
65 | { |
66 | struct example_state *state = i2c_get_clientdata(client); | |
67 | ||
68 | i2c_detach_client(client); | |
69 | kfree(state); | |
70 | return 0; | |
71 | } | |
72 | ||
73 | static int example_attach_adapter(struct i2c_adapter *adap) | |
74 | { | |
75 | return i2c_probe(adap, &addr_data, example_attach); | |
76 | } | |
77 | ||
78 | static struct i2c_driver example_driver = { | |
79 | .driver = { | |
80 | .owner = THIS_MODULE, | |
81 | .name = "example", | |
5f835cef | 82 | .pm = &example_pm_ops, |
31321b76 BD |
83 | }, |
84 | .attach_adapter = example_attach_adapter, | |
ed065e26 | 85 | .detach_client = example_detach, |
31321b76 BD |
86 | }; |
87 | ||
88 | ||
89 | Updating the client | |
90 | ------------------- | |
91 | ||
92 | The new style binding model will check against a list of supported | |
93 | devices and their associated address supplied by the code registering | |
94 | the busses. This means that the driver .attach_adapter and | |
ed065e26 | 95 | .detach_client methods can be removed, along with the addr_data, |
31321b76 BD |
96 | as follows: |
97 | ||
98 | - static struct i2c_driver example_driver; | |
99 | ||
100 | - static unsigned short ignore[] = { I2C_CLIENT_END }; | |
101 | - static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END }; | |
102 | ||
103 | - I2C_CLIENT_INSMOD; | |
104 | ||
105 | - static int example_attach_adapter(struct i2c_adapter *adap) | |
106 | - { | |
107 | - return i2c_probe(adap, &addr_data, example_attach); | |
108 | - } | |
109 | ||
110 | static struct i2c_driver example_driver = { | |
111 | - .attach_adapter = example_attach_adapter, | |
ed065e26 | 112 | - .detach_client = example_detach, |
31321b76 BD |
113 | } |
114 | ||
115 | Add the probe and remove methods to the i2c_driver, as so: | |
116 | ||
117 | static struct i2c_driver example_driver = { | |
118 | + .probe = example_probe, | |
ed065e26 | 119 | + .remove = example_remove, |
31321b76 BD |
120 | } |
121 | ||
122 | Change the example_attach method to accept the new parameters | |
123 | which include the i2c_client that it will be working with: | |
124 | ||
125 | - static int example_attach(struct i2c_adapter *adap, int addr, int kind) | |
126 | + static int example_probe(struct i2c_client *client, | |
127 | + const struct i2c_device_id *id) | |
128 | ||
129 | Change the name of example_attach to example_probe to align it with the | |
130 | i2c_driver entry names. The rest of the probe routine will now need to be | |
131 | changed as the i2c_client has already been setup for use. | |
132 | ||
133 | The necessary client fields have already been setup before | |
134 | the probe function is called, so the following client setup | |
135 | can be removed: | |
136 | ||
137 | - example->client.addr = addr; | |
138 | - example->client.flags = 0; | |
139 | - example->client.adapter = adap; | |
140 | - | |
141 | - strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE); | |
142 | ||
143 | The i2c_set_clientdata is now: | |
144 | ||
145 | - i2c_set_clientdata(&state->client, state); | |
146 | + i2c_set_clientdata(client, state); | |
147 | ||
148 | The call to i2c_attach_client is no longer needed, if the probe | |
149 | routine exits successfully, then the driver will be automatically | |
150 | attached by the core. Change the probe routine as so: | |
151 | ||
152 | - ret = i2c_attach_client(&state->i2c_client); | |
153 | - if (ret < 0) { | |
154 | - dev_err(dev, "failed to attach client\n"); | |
155 | - kfree(state); | |
156 | - return ret; | |
157 | - } | |
158 | ||
159 | ||
160 | Remove the storage of 'struct i2c_client' from the 'struct example_state' | |
161 | as we are provided with the i2c_client in our example_probe. Instead we | |
162 | store a pointer to it for when it is needed. | |
163 | ||
164 | struct example_state { | |
165 | - struct i2c_client client; | |
166 | + struct i2c_client *client; | |
167 | ||
168 | the new i2c client as so: | |
169 | ||
170 | - struct device *dev = &adap->dev; /* to use for dev_ reports */ | |
171 | + struct device *dev = &i2c_client->dev; /* to use for dev_ reports */ | |
172 | ||
173 | And remove the change after our client is attached, as the driver no | |
174 | longer needs to register a new client structure with the core: | |
175 | ||
176 | - dev = &state->i2c_client.dev; | |
177 | ||
178 | In the probe routine, ensure that the new state has the client stored | |
179 | in it: | |
180 | ||
181 | static int example_probe(struct i2c_client *i2c_client, | |
182 | const struct i2c_device_id *id) | |
183 | { | |
184 | struct example_state *state; | |
185 | struct device *dev = &i2c_client->dev; | |
186 | int ret; | |
187 | ||
188 | state = kzalloc(sizeof(struct example_state), GFP_KERNEL); | |
189 | if (state == NULL) { | |
190 | dev_err(dev, "failed to create our state\n"); | |
191 | return -ENOMEM; | |
192 | } | |
193 | ||
194 | + state->client = i2c_client; | |
195 | ||
196 | Update the detach method, by changing the name to _remove and | |
197 | to delete the i2c_detach_client call. It is possible that you | |
c9f3f2d8 MI |
198 | can also remove the ret variable as it is not needed for any |
199 | of the core functions. | |
31321b76 | 200 | |
ed065e26 JD |
201 | - static int example_detach(struct i2c_client *client) |
202 | + static int example_remove(struct i2c_client *client) | |
31321b76 BD |
203 | { |
204 | struct example_state *state = i2c_get_clientdata(client); | |
205 | ||
206 | - i2c_detach_client(client); | |
207 | ||
208 | And finally ensure that we have the correct ID table for the i2c-core | |
209 | and other utilities: | |
210 | ||
211 | + struct i2c_device_id example_idtable[] = { | |
212 | + { "example", 0 }, | |
213 | + { } | |
214 | +}; | |
215 | + | |
216 | +MODULE_DEVICE_TABLE(i2c, example_idtable); | |
217 | ||
218 | static struct i2c_driver example_driver = { | |
219 | .driver = { | |
220 | .owner = THIS_MODULE, | |
221 | .name = "example", | |
222 | }, | |
223 | + .id_table = example_ids, | |
224 | ||
225 | ||
226 | Our driver should now look like this: | |
227 | ||
228 | struct example_state { | |
229 | struct i2c_client *client; | |
230 | .... | |
231 | }; | |
232 | ||
233 | static int example_probe(struct i2c_client *client, | |
234 | const struct i2c_device_id *id) | |
235 | { | |
236 | struct example_state *state; | |
237 | struct device *dev = &client->dev; | |
238 | ||
239 | state = kzalloc(sizeof(struct example_state), GFP_KERNEL); | |
240 | if (state == NULL) { | |
241 | dev_err(dev, "failed to create our state\n"); | |
242 | return -ENOMEM; | |
243 | } | |
244 | ||
245 | state->client = client; | |
246 | i2c_set_clientdata(client, state); | |
247 | ||
248 | /* rest of the initialisation goes here. */ | |
249 | ||
250 | dev_info(dev, "example client created\n"); | |
251 | ||
252 | return 0; | |
253 | } | |
254 | ||
ed065e26 | 255 | static int example_remove(struct i2c_client *client) |
31321b76 BD |
256 | { |
257 | struct example_state *state = i2c_get_clientdata(client); | |
258 | ||
259 | kfree(state); | |
260 | return 0; | |
261 | } | |
262 | ||
263 | static struct i2c_device_id example_idtable[] = { | |
264 | { "example", 0 }, | |
265 | { } | |
266 | }; | |
267 | ||
268 | MODULE_DEVICE_TABLE(i2c, example_idtable); | |
269 | ||
270 | static struct i2c_driver example_driver = { | |
271 | .driver = { | |
272 | .owner = THIS_MODULE, | |
273 | .name = "example", | |
5f835cef | 274 | .pm = &example_pm_ops, |
31321b76 BD |
275 | }, |
276 | .id_table = example_idtable, | |
277 | .probe = example_probe, | |
ed065e26 | 278 | .remove = example_remove, |
31321b76 | 279 | }; |