@@ -610,16 +610,28 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
610610 return 0 ;
611611}
612612
613+ /**
614+ * acpi_video_device_EDID() - Get EDID from ACPI _DDC
615+ * @device: video output device (LCD, CRT, ..)
616+ * @edid: address for returned EDID pointer
617+ * @length: _DDC length to request (must be a multiple of 128)
618+ *
619+ * Get EDID from ACPI _DDC. On success, a pointer to the EDID data is written
620+ * to the @edid address, and the length of the EDID is returned. The caller is
621+ * responsible for freeing the edid pointer.
622+ *
623+ * Return the length of EDID (positive value) on success or error (negative
624+ * value).
625+ */
613626static int
614- acpi_video_device_EDID (struct acpi_video_device * device ,
615- union acpi_object * * edid , int length )
627+ acpi_video_device_EDID (struct acpi_video_device * device , void * * edid , int length )
616628{
617- int status ;
629+ acpi_status status ;
618630 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER , NULL };
619631 union acpi_object * obj ;
620632 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
621633 struct acpi_object_list args = { 1 , & arg0 };
622-
634+ int ret ;
623635
624636 * edid = NULL ;
625637
@@ -636,16 +648,17 @@ acpi_video_device_EDID(struct acpi_video_device *device,
636648
637649 obj = buffer .pointer ;
638650
639- if (obj && obj -> type == ACPI_TYPE_BUFFER )
640- * edid = obj ;
641- else {
651+ if (obj && obj -> type == ACPI_TYPE_BUFFER ) {
652+ * edid = kmemdup (obj -> buffer .pointer , obj -> buffer .length , GFP_KERNEL );
653+ ret = * edid ? obj -> buffer .length : - ENOMEM ;
654+ } else {
642655 acpi_handle_debug (device -> dev -> handle ,
643656 "Invalid _DDC data for length %d\n" , length );
644- status = - EFAULT ;
645- kfree (obj );
657+ ret = - EFAULT ;
646658 }
647659
648- return status ;
660+ kfree (obj );
661+ return ret ;
649662}
650663
651664/* bus */
@@ -1435,9 +1448,7 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
14351448{
14361449 struct acpi_video_bus * video ;
14371450 struct acpi_video_device * video_device ;
1438- union acpi_object * buffer = NULL ;
1439- acpi_status status ;
1440- int i , length ;
1451+ int i , length , ret ;
14411452
14421453 if (!device || !acpi_driver_data (device ))
14431454 return - EINVAL ;
@@ -1477,16 +1488,10 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
14771488 }
14781489
14791490 for (length = 512 ; length > 0 ; length -= 128 ) {
1480- status = acpi_video_device_EDID (video_device , & buffer ,
1481- length );
1482- if (ACPI_SUCCESS (status ))
1483- break ;
1491+ ret = acpi_video_device_EDID (video_device , edid , length );
1492+ if (ret > 0 )
1493+ return ret ;
14841494 }
1485- if (!length )
1486- continue ;
1487-
1488- * edid = buffer -> buffer .pointer ;
1489- return length ;
14901495 }
14911496
14921497 return - ENODEV ;
0 commit comments