diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_platform.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpi_video.c | 78 | ||||
-rw-r--r-- | drivers/acpi/glue.c | 8 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 42 | ||||
-rw-r--r-- | drivers/acpi/video_detect.c | 9 |
5 files changed, 128 insertions, 16 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 06a67d5f2846..296b7a14893a 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) pdevinfo.res = resources; pdevinfo.num_res = count; pdevinfo.fwnode = acpi_fwnode_handle(adev); - pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0; + + if (acpi_dma_supported(adev)) + pdevinfo.dma_mask = DMA_BIT_MASK(32); + else + pdevinfo.dma_mask = 0; + pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) dev_err(&adev->dev, "platform device creation failed: %ld\n", diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 5778e8e4313a..3405f7a41e25 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -77,6 +77,12 @@ module_param(allow_duplicates, bool, 0644); static int disable_backlight_sysfs_if = -1; module_param(disable_backlight_sysfs_if, int, 0444); +static bool device_id_scheme = false; +module_param(device_id_scheme, bool, 0444); + +static bool only_lcd = false; +module_param(only_lcd, bool, 0444); + static int register_count; static DEFINE_MUTEX(register_count_mutex); static struct mutex video_list_lock; @@ -394,6 +400,18 @@ static int video_disable_backlight_sysfs_if( return 0; } +static int video_set_device_id_scheme(const struct dmi_system_id *d) +{ + device_id_scheme = true; + return 0; +} + +static int video_enable_only_lcd(const struct dmi_system_id *d) +{ + only_lcd = true; + return 0; +} + static struct dmi_system_id video_dmi_table[] = { /* * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 @@ -455,6 +473,33 @@ static struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"), }, }, + /* + * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set + * but the IDs actually follow the Device ID Scheme. + */ + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */ + .callback = video_set_device_id_scheme, + .ident = "ESPRIMO Mobile M9410", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), + }, + }, + /* + * Some machines have multiple video output devices, but only the one + * that is the type of LCD can do the backlight control so we should not + * register backlight interface for other video output devices. + */ + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */ + .callback = video_enable_only_lcd, + .ident = "ESPRIMO Mobile M9410", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), + }, + }, {} }; @@ -1003,7 +1048,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, attribute = acpi_video_get_device_attr(video, device_id); - if (attribute && attribute->device_id_scheme) { + if (attribute && (attribute->device_id_scheme || device_id_scheme)) { switch (attribute->display_type) { case ACPI_VIDEO_DISPLAY_CRT: data->flags.crt = 1; @@ -1568,15 +1613,6 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) static int count; char *name; - /* - * Do not create backlight device for video output - * device that is not in the enumerated list. - */ - if (!acpi_video_device_in_dod(device)) { - dev_dbg(&device->dev->dev, "not in _DOD list, ignore\n"); - return; - } - result = acpi_video_init_brightness(device); if (result) return; @@ -1657,6 +1693,22 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) mutex_unlock(&video->device_list_lock); } +static bool acpi_video_should_register_backlight(struct acpi_video_device *dev) +{ + /* + * Do not create backlight device for video output + * device that is not in the enumerated list. + */ + if (!acpi_video_device_in_dod(dev)) { + dev_dbg(&dev->dev->dev, "not in _DOD list, ignore\n"); + return false; + } + + if (only_lcd) + return dev->flags.lcd; + return true; +} + static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) { struct acpi_video_device *dev; @@ -1670,8 +1722,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) return 0; mutex_lock(&video->device_list_lock); - list_for_each_entry(dev, &video->video_device_list, entry) - acpi_video_dev_register_backlight(dev); + list_for_each_entry(dev, &video->video_device_list, entry) { + if (acpi_video_should_register_backlight(dev)) + acpi_video_dev_register_backlight(dev); + } mutex_unlock(&video->device_list_lock); video->backlight_registered = true; diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 1470ae4f98c0..5ea5dc219f56 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) struct list_head *physnode_list; unsigned int node_id; int retval = -EINVAL; - bool coherent; + enum dev_dma_attr attr; if (has_acpi_companion(dev)) { if (acpi_dev) { @@ -225,8 +225,10 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) if (!has_acpi_companion(dev)) ACPI_COMPANION_SET(dev, acpi_dev); - if (acpi_check_dma(acpi_dev, &coherent)) - arch_setup_dma_ops(dev, 0, 0, NULL, coherent); + attr = acpi_get_dma_attr(acpi_dev); + if (attr != DEV_DMA_NOT_SUPPORTED) + arch_setup_dma_ops(dev, 0, 0, NULL, + attr == DEV_DMA_COHERENT); acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index daf9fc8329e6..78d5f02a073b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1308,6 +1308,48 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp) kfree(pnp->unique_id); } +/** + * acpi_dma_supported - Check DMA support for the specified device. + * @adev: The pointer to acpi device + * + * Return false if DMA is not supported. Otherwise, return true + */ +bool acpi_dma_supported(struct acpi_device *adev) +{ + if (!adev) + return false; + + if (adev->flags.cca_seen) + return true; + + /* + * Per ACPI 6.0 sec 6.2.17, assume devices can do cache-coherent + * DMA on "Intel platforms". Presumably that includes all x86 and + * ia64, and other arches will set CONFIG_ACPI_CCA_REQUIRED=y. + */ + if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED)) + return true; + + return false; +} + +/** + * acpi_get_dma_attr - Check the supported DMA attr for the specified device. + * @adev: The pointer to acpi device + * + * Return enum dev_dma_attr. + */ +enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev) +{ + if (!acpi_dma_supported(adev)) + return DEV_DMA_NOT_SUPPORTED; + + if (adev->flags.coherent_dma) + return DEV_DMA_COHERENT; + else + return DEV_DMA_NON_COHERENT; +} + static void acpi_init_coherency(struct acpi_device *adev) { unsigned long long cca = 0; diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 0d3a384b508a..daaf1c4e1e0f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -233,6 +233,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */ + .callback = video_detect_force_video, + .ident = "Dell XPS14 L421X", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), + }, + }, + { /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ .callback = video_detect_force_video, .ident = "Dell XPS15 L521X", |