diff options
| -rw-r--r-- | drivers/acpi/video_detect.c | 16 | ||||
| -rw-r--r-- | drivers/cpufreq/exynos-cpufreq.c | 6 |
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 815f75ef2411..2922f1f252d5 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
| 34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
| 35 | #include <linux/workqueue.h> | ||
| 35 | #include <acpi/video.h> | 36 | #include <acpi/video.h> |
| 36 | 37 | ||
| 37 | ACPI_MODULE_NAME("video"); | 38 | ACPI_MODULE_NAME("video"); |
| @@ -41,6 +42,7 @@ void acpi_video_unregister_backlight(void); | |||
| 41 | 42 | ||
| 42 | static bool backlight_notifier_registered; | 43 | static bool backlight_notifier_registered; |
| 43 | static struct notifier_block backlight_nb; | 44 | static struct notifier_block backlight_nb; |
| 45 | static struct work_struct backlight_notify_work; | ||
| 44 | 46 | ||
| 45 | static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef; | 47 | static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef; |
| 46 | static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef; | 48 | static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef; |
| @@ -262,6 +264,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = { | |||
| 262 | { }, | 264 | { }, |
| 263 | }; | 265 | }; |
| 264 | 266 | ||
| 267 | /* This uses a workqueue to avoid various locking ordering issues */ | ||
| 268 | static void acpi_video_backlight_notify_work(struct work_struct *work) | ||
| 269 | { | ||
| 270 | if (acpi_video_get_backlight_type() != acpi_backlight_video) | ||
| 271 | acpi_video_unregister_backlight(); | ||
| 272 | } | ||
| 273 | |||
| 265 | static int acpi_video_backlight_notify(struct notifier_block *nb, | 274 | static int acpi_video_backlight_notify(struct notifier_block *nb, |
| 266 | unsigned long val, void *bd) | 275 | unsigned long val, void *bd) |
| 267 | { | 276 | { |
| @@ -269,9 +278,8 @@ static int acpi_video_backlight_notify(struct notifier_block *nb, | |||
| 269 | 278 | ||
| 270 | /* A raw bl registering may change video -> native */ | 279 | /* A raw bl registering may change video -> native */ |
| 271 | if (backlight->props.type == BACKLIGHT_RAW && | 280 | if (backlight->props.type == BACKLIGHT_RAW && |
| 272 | val == BACKLIGHT_REGISTERED && | 281 | val == BACKLIGHT_REGISTERED) |
| 273 | acpi_video_get_backlight_type() != acpi_backlight_video) | 282 | schedule_work(&backlight_notify_work); |
| 274 | acpi_video_unregister_backlight(); | ||
| 275 | 283 | ||
| 276 | return NOTIFY_OK; | 284 | return NOTIFY_OK; |
| 277 | } | 285 | } |
| @@ -304,6 +312,8 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void) | |||
| 304 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 312 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
| 305 | ACPI_UINT32_MAX, find_video, NULL, | 313 | ACPI_UINT32_MAX, find_video, NULL, |
| 306 | &video_caps, NULL); | 314 | &video_caps, NULL); |
| 315 | INIT_WORK(&backlight_notify_work, | ||
| 316 | acpi_video_backlight_notify_work); | ||
| 307 | backlight_nb.notifier_call = acpi_video_backlight_notify; | 317 | backlight_nb.notifier_call = acpi_video_backlight_notify; |
| 308 | backlight_nb.priority = 0; | 318 | backlight_nb.priority = 0; |
| 309 | if (backlight_register_notifier(&backlight_nb) == 0) | 319 | if (backlight_register_notifier(&backlight_nb) == 0) |
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index ae5b2bd3a978..fa3dd840a837 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
| @@ -180,7 +180,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 180 | ret = exynos5250_cpufreq_init(exynos_info); | 180 | ret = exynos5250_cpufreq_init(exynos_info); |
| 181 | } else { | 181 | } else { |
| 182 | pr_err("%s: Unknown SoC type\n", __func__); | 182 | pr_err("%s: Unknown SoC type\n", __func__); |
| 183 | return -ENODEV; | 183 | ret = -ENODEV; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | if (ret) | 186 | if (ret) |
| @@ -188,12 +188,14 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 188 | 188 | ||
| 189 | if (exynos_info->set_freq == NULL) { | 189 | if (exynos_info->set_freq == NULL) { |
| 190 | dev_err(&pdev->dev, "No set_freq function (ERR)\n"); | 190 | dev_err(&pdev->dev, "No set_freq function (ERR)\n"); |
| 191 | ret = -EINVAL; | ||
| 191 | goto err_vdd_arm; | 192 | goto err_vdd_arm; |
| 192 | } | 193 | } |
| 193 | 194 | ||
| 194 | arm_regulator = regulator_get(NULL, "vdd_arm"); | 195 | arm_regulator = regulator_get(NULL, "vdd_arm"); |
| 195 | if (IS_ERR(arm_regulator)) { | 196 | if (IS_ERR(arm_regulator)) { |
| 196 | dev_err(&pdev->dev, "failed to get resource vdd_arm\n"); | 197 | dev_err(&pdev->dev, "failed to get resource vdd_arm\n"); |
| 198 | ret = -EINVAL; | ||
| 197 | goto err_vdd_arm; | 199 | goto err_vdd_arm; |
| 198 | } | 200 | } |
| 199 | 201 | ||
| @@ -225,7 +227,7 @@ err_cpufreq_reg: | |||
| 225 | regulator_put(arm_regulator); | 227 | regulator_put(arm_regulator); |
| 226 | err_vdd_arm: | 228 | err_vdd_arm: |
| 227 | kfree(exynos_info); | 229 | kfree(exynos_info); |
| 228 | return -EINVAL; | 230 | return ret; |
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | static struct platform_driver exynos_cpufreq_platdrv = { | 233 | static struct platform_driver exynos_cpufreq_platdrv = { |
