diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-11-05 11:43:30 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2007-11-14 11:53:35 -0500 |
| commit | f51e83916a0a022d3d0ea39ae2f877c703032923 (patch) | |
| tree | 0341762efa85726c476c32efa118a53097a9e04f | |
| parent | 91c05c667b2d8e43e0bbc5f269bf45d4821001d6 (diff) | |
ACPI: video - add missing input_free_device()
If input_register_device() fails input_free_device() must
be called to release memory allocated for the device.
Also consolidate error handling in acpi_bus_video_add()
and handle input_allocate_device() failures.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/video.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index c0e4e7423fcd..be66a7c04d38 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -1897,14 +1897,10 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
| 1897 | static int instance; | 1897 | static int instance; |
| 1898 | static int acpi_video_bus_add(struct acpi_device *device) | 1898 | static int acpi_video_bus_add(struct acpi_device *device) |
| 1899 | { | 1899 | { |
| 1900 | int result = 0; | 1900 | acpi_status status; |
| 1901 | acpi_status status = 0; | 1901 | struct acpi_video_bus *video; |
| 1902 | struct acpi_video_bus *video = NULL; | ||
| 1903 | struct input_dev *input; | 1902 | struct input_dev *input; |
| 1904 | 1903 | int error; | |
| 1905 | |||
| 1906 | if (!device) | ||
| 1907 | return -EINVAL; | ||
| 1908 | 1904 | ||
| 1909 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); | 1905 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
| 1910 | if (!video) | 1906 | if (!video) |
| @@ -1923,13 +1919,13 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1923 | acpi_driver_data(device) = video; | 1919 | acpi_driver_data(device) = video; |
| 1924 | 1920 | ||
| 1925 | acpi_video_bus_find_cap(video); | 1921 | acpi_video_bus_find_cap(video); |
| 1926 | result = acpi_video_bus_check(video); | 1922 | error = acpi_video_bus_check(video); |
| 1927 | if (result) | 1923 | if (error) |
| 1928 | goto end; | 1924 | goto err_free_video; |
| 1929 | 1925 | ||
| 1930 | result = acpi_video_bus_add_fs(device); | 1926 | error = acpi_video_bus_add_fs(device); |
| 1931 | if (result) | 1927 | if (error) |
| 1932 | goto end; | 1928 | goto err_free_video; |
| 1933 | 1929 | ||
| 1934 | init_MUTEX(&video->sem); | 1930 | init_MUTEX(&video->sem); |
| 1935 | INIT_LIST_HEAD(&video->video_device_list); | 1931 | INIT_LIST_HEAD(&video->video_device_list); |
| @@ -1943,16 +1939,15 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1943 | if (ACPI_FAILURE(status)) { | 1939 | if (ACPI_FAILURE(status)) { |
| 1944 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1940 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
| 1945 | "Error installing notify handler\n")); | 1941 | "Error installing notify handler\n")); |
| 1946 | acpi_video_bus_stop_devices(video); | 1942 | error = -ENODEV; |
| 1947 | acpi_video_bus_put_devices(video); | 1943 | goto err_stop_video; |
| 1948 | kfree(video->attached_array); | ||
| 1949 | acpi_video_bus_remove_fs(device); | ||
| 1950 | result = -ENODEV; | ||
| 1951 | goto end; | ||
| 1952 | } | 1944 | } |
| 1953 | 1945 | ||
| 1954 | |||
| 1955 | video->input = input = input_allocate_device(); | 1946 | video->input = input = input_allocate_device(); |
| 1947 | if (!input) { | ||
| 1948 | error = -ENOMEM; | ||
| 1949 | goto err_uninstall_notify; | ||
| 1950 | } | ||
| 1956 | 1951 | ||
| 1957 | snprintf(video->phys, sizeof(video->phys), | 1952 | snprintf(video->phys, sizeof(video->phys), |
| 1958 | "%s/video/input0", acpi_device_hid(video->device)); | 1953 | "%s/video/input0", acpi_device_hid(video->device)); |
| @@ -1972,18 +1967,10 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1972 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | 1967 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); |
| 1973 | set_bit(KEY_DISPLAY_OFF, input->keybit); | 1968 | set_bit(KEY_DISPLAY_OFF, input->keybit); |
| 1974 | set_bit(KEY_UNKNOWN, input->keybit); | 1969 | set_bit(KEY_UNKNOWN, input->keybit); |
| 1975 | result = input_register_device(input); | ||
| 1976 | if (result) { | ||
| 1977 | acpi_remove_notify_handler(video->device->handle, | ||
| 1978 | ACPI_DEVICE_NOTIFY, | ||
| 1979 | acpi_video_bus_notify); | ||
| 1980 | acpi_video_bus_stop_devices(video); | ||
| 1981 | acpi_video_bus_put_devices(video); | ||
| 1982 | kfree(video->attached_array); | ||
| 1983 | acpi_video_bus_remove_fs(device); | ||
| 1984 | goto end; | ||
| 1985 | } | ||
| 1986 | 1970 | ||
| 1971 | error = input_register_device(input); | ||
| 1972 | if (error) | ||
| 1973 | goto err_free_input_dev; | ||
| 1987 | 1974 | ||
| 1988 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", | 1975 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", |
| 1989 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), | 1976 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), |
| @@ -1991,11 +1978,23 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1991 | video->flags.rom ? "yes" : "no", | 1978 | video->flags.rom ? "yes" : "no", |
| 1992 | video->flags.post ? "yes" : "no"); | 1979 | video->flags.post ? "yes" : "no"); |
| 1993 | 1980 | ||
| 1994 | end: | 1981 | return 0; |
| 1995 | if (result) | 1982 | |
| 1996 | kfree(video); | 1983 | err_free_input_dev: |
| 1984 | input_free_device(input); | ||
| 1985 | err_uninstall_notify: | ||
| 1986 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | ||
| 1987 | acpi_video_bus_notify); | ||
| 1988 | err_stop_video: | ||
| 1989 | acpi_video_bus_stop_devices(video); | ||
| 1990 | acpi_video_bus_put_devices(video); | ||
| 1991 | kfree(video->attached_array); | ||
| 1992 | acpi_video_bus_remove_fs(device); | ||
| 1993 | err_free_video: | ||
| 1994 | kfree(video); | ||
| 1995 | acpi_driver_data(device) = NULL; | ||
| 1997 | 1996 | ||
| 1998 | return result; | 1997 | return error; |
| 1999 | } | 1998 | } |
| 2000 | 1999 | ||
| 2001 | static int acpi_video_bus_remove(struct acpi_device *device, int type) | 2000 | static int acpi_video_bus_remove(struct acpi_device *device, int type) |
