Re: [PATCH 4/4] ACPI: video - cleanup video device registration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2009-08-08 at 15:26 +0800, Dmitry Torokhov wrote:
> Split sub-device (backlight, cooling, video output) registration into
> separate functions, ensure that failure in one would not affect others,
> don't crash when backlight registration fails.
> 
> Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx>
> ---
> 
>  drivers/acpi/video.c |  418 +++++++++++++++++++++++++++-----------------------
>  1 files changed, 224 insertions(+), 194 deletions(-)
> 
> diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> index 5407e0b..bc5082b 100644
> --- a/drivers/acpi/video.c
> +++ b/drivers/acpi/video.c

> @@ -1705,86 +1775,85 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id
>         return NULL;
>  }
> 
> -static int
> -acpi_video_bus_get_one_device(struct acpi_device *device,
> -                             struct acpi_video_bus *video)
> +static int acpi_video_bus_add_device(struct acpi_device *device,
> +                                    unsigned long long device_id,
> +                                    struct acpi_video_bus *video)
>  {
> -       unsigned long long device_id;
> -       int status;
>         struct acpi_video_device *data;
>         struct acpi_video_device_attrib* attribute;
> +       int status;
> 
> -       if (!device || !video)
> -               return -EINVAL;
> -
> -       status =
> -           acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
> -       if (ACPI_SUCCESS(status)) {
> -
> -               data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
> -               if (!data)
> -                       return -ENOMEM;
> +       data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
> +       if (!data)
> +               return -ENOMEM;
> 
> -               strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
> -               strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
> -               device->driver_data = data;
> +       strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
> +       strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
> +       device->driver_data = data;
> 
> -               data->device_id = device_id;
> -               data->video = video;
> -               data->dev = device;
> +       data->device_id = device_id;
> +       data->video = video;
> +       data->dev = device;
> 
> -               attribute = acpi_video_get_device_attr(video, device_id);
> +       attribute = acpi_video_get_device_attr(video, device_id);
> 
> -               if((attribute != NULL) && attribute->device_id_scheme) {
> -                       switch (attribute->display_type) {
> -                       case ACPI_VIDEO_DISPLAY_CRT:
> -                               data->flags.crt = 1;
> -                               break;
> -                       case ACPI_VIDEO_DISPLAY_TV:
> -                               data->flags.tvout = 1;
> -                               break;
> -                       case ACPI_VIDEO_DISPLAY_DVI:
> -                               data->flags.dvi = 1;
> -                               break;
> -                       case ACPI_VIDEO_DISPLAY_LCD:
> -                               data->flags.lcd = 1;
> -                               break;
> -                       default:
> -                               data->flags.unknown = 1;
> -                               break;
> -                       }
> -                       if(attribute->bios_can_detect)
> -                               data->flags.bios = 1;
> -               } else
> +       if (attribute && attribute->device_id_scheme) {
> +               switch (attribute->display_type) {
> +               case ACPI_VIDEO_DISPLAY_CRT:
> +                       data->flags.crt = 1;
> +                       break;
> +               case ACPI_VIDEO_DISPLAY_TV:
> +                       data->flags.tvout = 1;
> +                       break;
> +               case ACPI_VIDEO_DISPLAY_DVI:
> +                       data->flags.dvi = 1;
> +                       break;
> +               case ACPI_VIDEO_DISPLAY_LCD:
> +                       data->flags.lcd = 1;
> +                       break;
> +               default:
>                         data->flags.unknown = 1;
> +                       break;
> +               }
> +               if(attribute->bios_can_detect)
> +                       data->flags.bios = 1;
> +       } else
> +               data->flags.unknown = 1;
> 
> -               acpi_video_device_bind(video, data);
> -               acpi_video_device_find_cap(data);
> +       acpi_video_device_bind(video, data);
> +       acpi_video_device_find_cap(data);
> 
> -               status = acpi_install_notify_handler(device->handle,
> -                                                    ACPI_DEVICE_NOTIFY,
> -                                                    acpi_video_device_notify,
> -                                                    data);
> -               if (ACPI_FAILURE(status)) {
> -                       printk(KERN_ERR PREFIX
> -                                         "Error installing notify handler\n");
> -                       if(data->brightness)
> -                               kfree(data->brightness->levels);
> -                       kfree(data->brightness);
> -                       kfree(data);
> -                       return -ENODEV;
> -               }
> +       if (acpi_video_backlight_support()) {
> +               acpi_video_init_brightness(data);
> +               acpi_video_device_add_backlight(data);
> +               acpi_video_device_add_cooling_dev(data);

we should check the return value of acpi_video_init_brightness first.
No backlight device or thermal cooling device if the video device
doesn't support backlight control well.

Both patch 02 and patch 04 look okay to me.

thanks,
rui

> +       }
> 
> -               mutex_lock(&video->device_list_lock);
> -               list_add_tail(&data->entry, &video->video_device_list);
> -               mutex_unlock(&video->device_list_lock);
> +       if (acpi_video_display_switch_support())
> +               acpi_video_device_add_output_dev(data);
> 
> -               acpi_video_device_add_fs(device);
> +       status = acpi_install_notify_handler(device->handle,
> +                                            ACPI_DEVICE_NOTIFY,
> +                                            acpi_video_device_notify,
> +                                            data);
> +       if (ACPI_FAILURE(status)) {
> +               printk(KERN_ERR PREFIX "Error installing notify handler\n");
> 
> -               return 0;
> +               acpi_video_device_remove_output_dev(data);
> +               acpi_video_device_remove_cooling_dev(data);
> +               acpi_video_device_remove_backlight(data);
> +               acpi_video_free_brightness_data(data);
> +               kfree(data);
> +               return -ENODEV;
>         }
> 
> -       return -ENOENT;
> +       acpi_video_device_add_fs(device);
> +
> +       mutex_lock(&video->device_list_lock);
> +       list_add_tail(&data->entry, &video->video_device_list);
> +       mutex_unlock(&video->device_list_lock);
> +
> +       return 0;
>  }
> 
>  /*
> @@ -1982,88 +2051,51 @@ out:
>         return result;
>  }
> 
> -static int
> +static void
>  acpi_video_bus_get_devices(struct acpi_video_bus *video,
>                            struct acpi_device *device)
>  {
> -       int status = 0;
>         struct acpi_device *dev;
> +       unsigned long long device_id;
> +       int status;
> 
>         acpi_video_device_enumerate(video);
> 
>         list_for_each_entry(dev, &device->children, node) {
> -
> -               status = acpi_video_bus_get_one_device(dev, video);
> -               if (ACPI_FAILURE(status)) {
> -                       printk(KERN_WARNING PREFIX
> -                                       "Cant attach device");
> -                       continue;
> -               }
> +               status = acpi_evaluate_integer(device->handle, "_ADR", NULL,
> +                                       &device_id);
> +               if (ACPI_SUCCESS(status))
> +                       acpi_video_bus_add_device(dev, device_id, video);
>         }
> -       return status;
>  }
> 
> -static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
> +static void acpi_video_bus_remove_device(struct acpi_video_device *device)
>  {
> -       acpi_status status;
> -       struct acpi_video_bus *video;
> -
> -
> -       if (!device || !device->video)
> -               return -ENOENT;
> -
> -       video = device->video;
> +       list_del(&device->entry);
> 
>         acpi_video_device_remove_fs(device->dev);
> 
> -       status = acpi_remove_notify_handler(device->dev->handle,
> -                                           ACPI_DEVICE_NOTIFY,
> -                                           acpi_video_device_notify);
> +       acpi_remove_notify_handler(device->dev->handle,
> +                               ACPI_DEVICE_NOTIFY, acpi_video_device_notify);
> 
> -       if (device->backlight) {
> -               sysfs_remove_link(&device->backlight->dev.kobj, "device");
> -               backlight_device_unregister(device->backlight);
> -       }
> +       acpi_video_device_remove_output_dev(device);
> +       acpi_video_device_remove_cooling_dev(device);
> +       acpi_video_device_remove_backlight(device);
> +       acpi_video_free_brightness_data(device);
> 
> -       if (device->cooling_dev) {
> -               sysfs_remove_link(&device->dev->dev.kobj,
> -                                 "thermal_cooling");
> -               sysfs_remove_link(&device->cooling_dev->device.kobj,
> -                                 "device");
> -               thermal_cooling_device_unregister(device->cooling_dev);
> -               device->cooling_dev = NULL;
> -       }
> -
> -       video_output_unregister(device->output_dev);
> -
> -       return 0;
> +       kfree(device);
>  }
> 
> -static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
> +static void acpi_video_bus_put_devices(struct acpi_video_bus *video)
>  {
> -       int status;
>         struct acpi_video_device *dev, *next;
> 
>         mutex_lock(&video->device_list_lock);
> 
> -       list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
> -
> -               status = acpi_video_bus_put_one_device(dev);
> -               if (ACPI_FAILURE(status))
> -                       printk(KERN_WARNING PREFIX
> -                              "hhuuhhuu bug in acpi video driver.\n");
> -
> -               if (dev->brightness) {
> -                       kfree(dev->brightness->levels);
> -                       kfree(dev->brightness);
> -               }
> -               list_del(&dev->entry);
> -               kfree(dev);
> -       }
> +       list_for_each_entry_safe(dev, next, &video->video_device_list, entry)
> +               acpi_video_bus_remove_device(dev);
> 
>         mutex_unlock(&video->device_list_lock);
> -
> -       return 0;
>  }
> 
>  /* acpi_video interface */
> @@ -2129,8 +2161,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
>         input_sync(input);
>         input_report_key(input, keycode, 0);
>         input_sync(input);
> -
> -       return;
>  }
> 
>  static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux