@@ -114,76 +114,111 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
114114 return 0 ;
115115}
116116
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+ *
118123 * Creates hid/cid(s) string needed for modalias and uevent
119124 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
120125 * char *modalias: "acpi:IBM0001:ACPI0001"
121126 * Return: 0: no _HID and no _CID
122127 * -EINVAL: output error
123128 * -ENOMEM: output is truncated
124129*/
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 )
127132{
128133 int len ;
129134 int count ;
130135 struct acpi_hardware_id * id ;
131136
132- if (list_empty (& acpi_dev -> pnp .ids ))
133- return 0 ;
134-
135137 /*
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 .
138140 */
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 ++ ;
175145
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 ;
185168 }
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 ;
186190
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+ }
187222 modalias [len ] = '\0' ;
188223 return len ;
189224}
@@ -236,61 +271,100 @@ static struct acpi_device *acpi_companion_match(const struct device *dev)
236271 return adev ;
237272}
238273
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 )
246276{
247277 int len ;
248278
249- if (!acpi_companion_match ( dev ) )
279+ if (!adev )
250280 return - ENODEV ;
251281
282+ if (list_empty (& adev -> pnp .ids ))
283+ return 0 ;
284+
252285 if (add_uevent_var (env , "MODALIAS=" ))
253286 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 )
257291 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+
258305 env -> buflen += len ;
306+
259307 return 0 ;
260308}
261- EXPORT_SYMBOL_GPL (acpi_device_uevent_modalias );
262309
263310/*
264- * Creates modalias sysfs attribute for ACPI enumerated devices.
311+ * Creates uevent modalias field for ACPI enumerated devices.
265312 * Because the other buses does not support ACPI HIDs & CIDs.
266313 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
267314 * "acpi:IBM0001:ACPI0001"
268315 */
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 )
270317{
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 ;
272325
273- if (!acpi_companion_match ( dev ) )
326+ if (!adev )
274327 return - ENODEV ;
275328
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 ) {
278334 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+
280350 return len ;
281351}
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+ }
282363EXPORT_SYMBOL_GPL (acpi_device_modalias );
283364
284365static ssize_t
285366acpi_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 );
294368}
295369static DEVICE_ATTR (modalias , 0444 , acpi_device_modalias_show , NULL) ;
296370
@@ -1046,20 +1120,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
10461120
10471121static int acpi_device_uevent (struct device * dev , struct kobj_uevent_env * env )
10481122{
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 );
10631124}
10641125
10651126static void acpi_device_notify (acpi_handle handle , u32 event , void * data )
0 commit comments