@@ -114,76 +114,111 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
114
114
return 0 ;
115
115
}
116
116
117
- /*
117
+ /**
118
+ * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
119
+ * @acpi_dev: ACPI device object.
120
+ * @modalias: Buffer to print into.
121
+ * @size: Size of the buffer.
122
+ *
118
123
* Creates hid/cid(s) string needed for modalias and uevent
119
124
* e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
120
125
* char *modalias: "acpi:IBM0001:ACPI0001"
121
126
* Return: 0: no _HID and no _CID
122
127
* -EINVAL: output error
123
128
* -ENOMEM: output is truncated
124
129
*/
125
- static int create_modalias (struct acpi_device * acpi_dev , char * modalias ,
126
- int size )
130
+ static int create_pnp_modalias (struct acpi_device * acpi_dev , char * modalias ,
131
+ int size )
127
132
{
128
133
int len ;
129
134
int count ;
130
135
struct acpi_hardware_id * id ;
131
136
132
- if (list_empty (& acpi_dev -> pnp .ids ))
133
- return 0 ;
134
-
135
137
/*
136
- * If the device has PRP0001 we expose DT compatible modalias
137
- * instead in form of of:NnameTCcompatible .
138
+ * Since we skip PRP0001 from the modalias below, 0 should be returned
139
+ * if PRP0001 is the only ACPI/PNP ID in the device's list .
138
140
*/
139
- if (acpi_dev -> data .of_compatible ) {
140
- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
141
- const union acpi_object * of_compatible , * obj ;
142
- int i , nval ;
143
- char * c ;
144
-
145
- acpi_get_name (acpi_dev -> handle , ACPI_SINGLE_NAME , & buf );
146
- /* DT strings are all in lower case */
147
- for (c = buf .pointer ; * c != '\0' ; c ++ )
148
- * c = tolower (* c );
149
-
150
- len = snprintf (modalias , size , "of:N%sT" , (char * )buf .pointer );
151
- ACPI_FREE (buf .pointer );
152
-
153
- of_compatible = acpi_dev -> data .of_compatible ;
154
- if (of_compatible -> type == ACPI_TYPE_PACKAGE ) {
155
- nval = of_compatible -> package .count ;
156
- obj = of_compatible -> package .elements ;
157
- } else { /* Must be ACPI_TYPE_STRING. */
158
- nval = 1 ;
159
- obj = of_compatible ;
160
- }
161
- for (i = 0 ; i < nval ; i ++ , obj ++ ) {
162
- count = snprintf (& modalias [len ], size , "C%s" ,
163
- obj -> string .pointer );
164
- if (count < 0 )
165
- return - EINVAL ;
166
- if (count >= size )
167
- return - ENOMEM ;
168
-
169
- len += count ;
170
- size -= count ;
171
- }
172
- } else {
173
- len = snprintf (modalias , size , "acpi:" );
174
- size -= len ;
141
+ count = 0 ;
142
+ list_for_each_entry (id , & acpi_dev -> pnp .ids , list )
143
+ if (strcmp (id -> id , "PRP0001" ))
144
+ count ++ ;
175
145
176
- list_for_each_entry (id , & acpi_dev -> pnp .ids , list ) {
177
- count = snprintf (& modalias [len ], size , "%s:" , id -> id );
178
- if (count < 0 )
179
- return - EINVAL ;
180
- if (count >= size )
181
- return - ENOMEM ;
182
- len += count ;
183
- size -= count ;
184
- }
146
+ if (!count )
147
+ return 0 ;
148
+
149
+ len = snprintf (modalias , size , "acpi:" );
150
+ if (len <= 0 )
151
+ return len ;
152
+
153
+ size -= len ;
154
+
155
+ list_for_each_entry (id , & acpi_dev -> pnp .ids , list ) {
156
+ if (!strcmp (id -> id , "PRP0001" ))
157
+ continue ;
158
+
159
+ count = snprintf (& modalias [len ], size , "%s:" , id -> id );
160
+ if (count < 0 )
161
+ return - EINVAL ;
162
+
163
+ if (count >= size )
164
+ return - ENOMEM ;
165
+
166
+ len += count ;
167
+ size -= count ;
185
168
}
169
+ modalias [len ] = '\0' ;
170
+ return len ;
171
+ }
172
+
173
+ /**
174
+ * create_of_modalias - Creates DT compatible string for modalias and uevent
175
+ * @acpi_dev: ACPI device object.
176
+ * @modalias: Buffer to print into.
177
+ * @size: Size of the buffer.
178
+ *
179
+ * Expose DT compatible modalias as of:NnameTCcompatible. This function should
180
+ * only be called for devices having PRP0001 in their list of ACPI/PNP IDs.
181
+ */
182
+ static int create_of_modalias (struct acpi_device * acpi_dev , char * modalias ,
183
+ int size )
184
+ {
185
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
186
+ const union acpi_object * of_compatible , * obj ;
187
+ int len , count ;
188
+ int i , nval ;
189
+ char * c ;
186
190
191
+ acpi_get_name (acpi_dev -> handle , ACPI_SINGLE_NAME , & buf );
192
+ /* DT strings are all in lower case */
193
+ for (c = buf .pointer ; * c != '\0' ; c ++ )
194
+ * c = tolower (* c );
195
+
196
+ len = snprintf (modalias , size , "of:N%sT" , (char * )buf .pointer );
197
+ ACPI_FREE (buf .pointer );
198
+
199
+ if (len <= 0 )
200
+ return len ;
201
+
202
+ of_compatible = acpi_dev -> data .of_compatible ;
203
+ if (of_compatible -> type == ACPI_TYPE_PACKAGE ) {
204
+ nval = of_compatible -> package .count ;
205
+ obj = of_compatible -> package .elements ;
206
+ } else { /* Must be ACPI_TYPE_STRING. */
207
+ nval = 1 ;
208
+ obj = of_compatible ;
209
+ }
210
+ for (i = 0 ; i < nval ; i ++ , obj ++ ) {
211
+ count = snprintf (& modalias [len ], size , "C%s" ,
212
+ obj -> string .pointer );
213
+ if (count < 0 )
214
+ return - EINVAL ;
215
+
216
+ if (count >= size )
217
+ return - ENOMEM ;
218
+
219
+ len += count ;
220
+ size -= count ;
221
+ }
187
222
modalias [len ] = '\0' ;
188
223
return len ;
189
224
}
@@ -236,61 +271,100 @@ static struct acpi_device *acpi_companion_match(const struct device *dev)
236
271
return adev ;
237
272
}
238
273
239
- /*
240
- * Creates uevent modalias field for ACPI enumerated devices.
241
- * Because the other buses does not support ACPI HIDs & CIDs.
242
- * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
243
- * "acpi:IBM0001:ACPI0001"
244
- */
245
- int acpi_device_uevent_modalias (struct device * dev , struct kobj_uevent_env * env )
274
+ static int __acpi_device_uevent_modalias (struct acpi_device * adev ,
275
+ struct kobj_uevent_env * env )
246
276
{
247
277
int len ;
248
278
249
- if (!acpi_companion_match ( dev ) )
279
+ if (!adev )
250
280
return - ENODEV ;
251
281
282
+ if (list_empty (& adev -> pnp .ids ))
283
+ return 0 ;
284
+
252
285
if (add_uevent_var (env , "MODALIAS=" ))
253
286
return - ENOMEM ;
254
- len = create_modalias (ACPI_COMPANION (dev ), & env -> buf [env -> buflen - 1 ],
255
- sizeof (env -> buf ) - env -> buflen );
256
- if (len <= 0 )
287
+
288
+ len = create_pnp_modalias (adev , & env -> buf [env -> buflen - 1 ],
289
+ sizeof (env -> buf ) - env -> buflen );
290
+ if (len < 0 )
257
291
return len ;
292
+
293
+ env -> buflen += len ;
294
+ if (!adev -> data .of_compatible )
295
+ return 0 ;
296
+
297
+ if (len > 0 && add_uevent_var (env , "MODALIAS=" ))
298
+ return - ENOMEM ;
299
+
300
+ len = create_of_modalias (adev , & env -> buf [env -> buflen - 1 ],
301
+ sizeof (env -> buf ) - env -> buflen );
302
+ if (len < 0 )
303
+ return len ;
304
+
258
305
env -> buflen += len ;
306
+
259
307
return 0 ;
260
308
}
261
- EXPORT_SYMBOL_GPL (acpi_device_uevent_modalias );
262
309
263
310
/*
264
- * Creates modalias sysfs attribute for ACPI enumerated devices.
311
+ * Creates uevent modalias field for ACPI enumerated devices.
265
312
* Because the other buses does not support ACPI HIDs & CIDs.
266
313
* e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
267
314
* "acpi:IBM0001:ACPI0001"
268
315
*/
269
- int acpi_device_modalias (struct device * dev , char * buf , int size )
316
+ int acpi_device_uevent_modalias (struct device * dev , struct kobj_uevent_env * env )
270
317
{
271
- int len ;
318
+ return __acpi_device_uevent_modalias (acpi_companion_match (dev ), env );
319
+ }
320
+ EXPORT_SYMBOL_GPL (acpi_device_uevent_modalias );
321
+
322
+ static int __acpi_device_modalias (struct acpi_device * adev , char * buf , int size )
323
+ {
324
+ int len , count ;
272
325
273
- if (!acpi_companion_match ( dev ) )
326
+ if (!adev )
274
327
return - ENODEV ;
275
328
276
- len = create_modalias (ACPI_COMPANION (dev ), buf , size - 1 );
277
- if (len <= 0 )
329
+ if (list_empty (& adev -> pnp .ids ))
330
+ return 0 ;
331
+
332
+ len = create_pnp_modalias (adev , buf , size - 1 );
333
+ if (len < 0 ) {
278
334
return len ;
279
- buf [len ++ ] = '\n' ;
335
+ } else if (len > 0 ) {
336
+ buf [len ++ ] = '\n' ;
337
+ size -= len ;
338
+ }
339
+ if (!adev -> data .of_compatible )
340
+ return len ;
341
+
342
+ count = create_of_modalias (adev , buf + len , size - 1 );
343
+ if (count < 0 ) {
344
+ return count ;
345
+ } else if (count > 0 ) {
346
+ len += count ;
347
+ buf [len ++ ] = '\n' ;
348
+ }
349
+
280
350
return len ;
281
351
}
352
+
353
+ /*
354
+ * Creates modalias sysfs attribute for ACPI enumerated devices.
355
+ * Because the other buses does not support ACPI HIDs & CIDs.
356
+ * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
357
+ * "acpi:IBM0001:ACPI0001"
358
+ */
359
+ int acpi_device_modalias (struct device * dev , char * buf , int size )
360
+ {
361
+ return __acpi_device_modalias (acpi_companion_match (dev ), buf , size );
362
+ }
282
363
EXPORT_SYMBOL_GPL (acpi_device_modalias );
283
364
284
365
static ssize_t
285
366
acpi_device_modalias_show (struct device * dev , struct device_attribute * attr , char * buf ) {
286
- struct acpi_device * acpi_dev = to_acpi_device (dev );
287
- int len ;
288
-
289
- len = create_modalias (acpi_dev , buf , 1024 );
290
- if (len <= 0 )
291
- return len ;
292
- buf [len ++ ] = '\n' ;
293
- return len ;
367
+ return __acpi_device_modalias (to_acpi_device (dev ), buf , 1024 );
294
368
}
295
369
static DEVICE_ATTR (modalias , 0444 , acpi_device_modalias_show , NULL) ;
296
370
@@ -1046,20 +1120,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
1046
1120
1047
1121
static int acpi_device_uevent (struct device * dev , struct kobj_uevent_env * env )
1048
1122
{
1049
- struct acpi_device * acpi_dev = to_acpi_device (dev );
1050
- int len ;
1051
-
1052
- if (list_empty (& acpi_dev -> pnp .ids ))
1053
- return 0 ;
1054
-
1055
- if (add_uevent_var (env , "MODALIAS=" ))
1056
- return - ENOMEM ;
1057
- len = create_modalias (acpi_dev , & env -> buf [env -> buflen - 1 ],
1058
- sizeof (env -> buf ) - env -> buflen );
1059
- if (len <= 0 )
1060
- return len ;
1061
- env -> buflen += len ;
1062
- return 0 ;
1123
+ return __acpi_device_uevent_modalias (to_acpi_device (dev ), env );
1063
1124
}
1064
1125
1065
1126
static void acpi_device_notify (acpi_handle handle , u32 event , void * data )
0 commit comments