diff options
Diffstat (limited to 'drivers')
84 files changed, 1131 insertions, 390 deletions
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c index e9626bf6ca29..d6c1b10f6c25 100644 --- a/drivers/acpi/nfit/mce.c +++ b/drivers/acpi/nfit/mce.c | |||
| @@ -25,8 +25,12 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, | |||
| 25 | struct acpi_nfit_desc *acpi_desc; | 25 | struct acpi_nfit_desc *acpi_desc; |
| 26 | struct nfit_spa *nfit_spa; | 26 | struct nfit_spa *nfit_spa; |
| 27 | 27 | ||
| 28 | /* We only care about memory errors */ | 28 | /* We only care about uncorrectable memory errors */ |
| 29 | if (!mce_is_memory_error(mce)) | 29 | if (!mce_is_memory_error(mce) || mce_is_correctable(mce)) |
| 30 | return NOTIFY_DONE; | ||
| 31 | |||
| 32 | /* Verify the address reported in the MCE is valid. */ | ||
| 33 | if (!mce_usable_address(mce)) | ||
| 30 | return NOTIFY_DONE; | 34 | return NOTIFY_DONE; |
| 31 | 35 | ||
| 32 | /* | 36 | /* |
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 10ecb232245d..4b1ff5bc256a 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c | |||
| @@ -1,14 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Renesas R-Car SATA driver | 3 | * Renesas R-Car SATA driver |
| 3 | * | 4 | * |
| 4 | * Author: Vladimir Barinov <source@cogentembedded.com> | 5 | * Author: Vladimir Barinov <source@cogentembedded.com> |
| 5 | * Copyright (C) 2013-2015 Cogent Embedded, Inc. | 6 | * Copyright (C) 2013-2015 Cogent Embedded, Inc. |
| 6 | * Copyright (C) 2013-2015 Renesas Solutions Corp. | 7 | * Copyright (C) 2013-2015 Renesas Solutions Corp. |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | 8 | */ |
| 13 | 9 | ||
| 14 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 56452cabce5b..0ed4b200fa58 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
| @@ -1919,6 +1919,7 @@ static int negotiate_mq(struct blkfront_info *info) | |||
| 1919 | GFP_KERNEL); | 1919 | GFP_KERNEL); |
| 1920 | if (!info->rinfo) { | 1920 | if (!info->rinfo) { |
| 1921 | xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); | 1921 | xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); |
| 1922 | info->nr_rings = 0; | ||
| 1922 | return -ENOMEM; | 1923 | return -ENOMEM; |
| 1923 | } | 1924 | } |
| 1924 | 1925 | ||
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index ef0ca9414f37..ff83e899df71 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c | |||
| @@ -210,6 +210,7 @@ static int of_fixed_factor_clk_remove(struct platform_device *pdev) | |||
| 210 | { | 210 | { |
| 211 | struct clk *clk = platform_get_drvdata(pdev); | 211 | struct clk *clk = platform_get_drvdata(pdev); |
| 212 | 212 | ||
| 213 | of_clk_del_provider(pdev->dev.of_node); | ||
| 213 | clk_unregister_fixed_factor(clk); | 214 | clk_unregister_fixed_factor(clk); |
| 214 | 215 | ||
| 215 | return 0; | 216 | return 0; |
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index c981159b02c0..792735d7e46e 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c | |||
| @@ -325,6 +325,7 @@ static struct clk_regmap axg_fclk_div2 = { | |||
| 325 | .ops = &clk_regmap_gate_ops, | 325 | .ops = &clk_regmap_gate_ops, |
| 326 | .parent_names = (const char *[]){ "fclk_div2_div" }, | 326 | .parent_names = (const char *[]){ "fclk_div2_div" }, |
| 327 | .num_parents = 1, | 327 | .num_parents = 1, |
| 328 | .flags = CLK_IS_CRITICAL, | ||
| 328 | }, | 329 | }, |
| 329 | }; | 330 | }; |
| 330 | 331 | ||
| @@ -349,6 +350,18 @@ static struct clk_regmap axg_fclk_div3 = { | |||
| 349 | .ops = &clk_regmap_gate_ops, | 350 | .ops = &clk_regmap_gate_ops, |
| 350 | .parent_names = (const char *[]){ "fclk_div3_div" }, | 351 | .parent_names = (const char *[]){ "fclk_div3_div" }, |
| 351 | .num_parents = 1, | 352 | .num_parents = 1, |
| 353 | /* | ||
| 354 | * FIXME: | ||
| 355 | * This clock, as fdiv2, is used by the SCPI FW and is required | ||
| 356 | * by the platform to operate correctly. | ||
| 357 | * Until the following condition are met, we need this clock to | ||
| 358 | * be marked as critical: | ||
| 359 | * a) The SCPI generic driver claims and enable all the clocks | ||
| 360 | * it needs | ||
| 361 | * b) CCF has a clock hand-off mechanism to make the sure the | ||
| 362 | * clock stays on until the proper driver comes along | ||
| 363 | */ | ||
| 364 | .flags = CLK_IS_CRITICAL, | ||
| 352 | }, | 365 | }, |
| 353 | }; | 366 | }; |
| 354 | 367 | ||
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 9309cfaaa464..4ada9668fd49 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
| @@ -506,6 +506,18 @@ static struct clk_regmap gxbb_fclk_div3 = { | |||
| 506 | .ops = &clk_regmap_gate_ops, | 506 | .ops = &clk_regmap_gate_ops, |
| 507 | .parent_names = (const char *[]){ "fclk_div3_div" }, | 507 | .parent_names = (const char *[]){ "fclk_div3_div" }, |
| 508 | .num_parents = 1, | 508 | .num_parents = 1, |
| 509 | /* | ||
| 510 | * FIXME: | ||
| 511 | * This clock, as fdiv2, is used by the SCPI FW and is required | ||
| 512 | * by the platform to operate correctly. | ||
| 513 | * Until the following condition are met, we need this clock to | ||
| 514 | * be marked as critical: | ||
| 515 | * a) The SCPI generic driver claims and enable all the clocks | ||
| 516 | * it needs | ||
| 517 | * b) CCF has a clock hand-off mechanism to make the sure the | ||
| 518 | * clock stays on until the proper driver comes along | ||
| 519 | */ | ||
| 520 | .flags = CLK_IS_CRITICAL, | ||
| 509 | }, | 521 | }, |
| 510 | }; | 522 | }; |
| 511 | 523 | ||
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index e4ca6a45f313..ef1b267cb058 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c | |||
| @@ -265,7 +265,7 @@ static struct clk_fixed_factor cxo = { | |||
| 265 | .div = 1, | 265 | .div = 1, |
| 266 | .hw.init = &(struct clk_init_data){ | 266 | .hw.init = &(struct clk_init_data){ |
| 267 | .name = "cxo", | 267 | .name = "cxo", |
| 268 | .parent_names = (const char *[]){ "xo_board" }, | 268 | .parent_names = (const char *[]){ "xo-board" }, |
| 269 | .num_parents = 1, | 269 | .num_parents = 1, |
| 270 | .ops = &clk_fixed_factor_ops, | 270 | .ops = &clk_fixed_factor_ops, |
| 271 | }, | 271 | }, |
diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c index 9c38895542f4..d4350bb10b83 100644 --- a/drivers/clocksource/i8253.c +++ b/drivers/clocksource/i8253.c | |||
| @@ -20,6 +20,13 @@ | |||
| 20 | DEFINE_RAW_SPINLOCK(i8253_lock); | 20 | DEFINE_RAW_SPINLOCK(i8253_lock); |
| 21 | EXPORT_SYMBOL(i8253_lock); | 21 | EXPORT_SYMBOL(i8253_lock); |
| 22 | 22 | ||
| 23 | /* | ||
| 24 | * Handle PIT quirk in pit_shutdown() where zeroing the counter register | ||
| 25 | * restarts the PIT, negating the shutdown. On platforms with the quirk, | ||
| 26 | * platform specific code can set this to false. | ||
| 27 | */ | ||
| 28 | bool i8253_clear_counter_on_shutdown __ro_after_init = true; | ||
| 29 | |||
| 23 | #ifdef CONFIG_CLKSRC_I8253 | 30 | #ifdef CONFIG_CLKSRC_I8253 |
| 24 | /* | 31 | /* |
| 25 | * Since the PIT overflows every tick, its not very useful | 32 | * Since the PIT overflows every tick, its not very useful |
| @@ -109,8 +116,11 @@ static int pit_shutdown(struct clock_event_device *evt) | |||
| 109 | raw_spin_lock(&i8253_lock); | 116 | raw_spin_lock(&i8253_lock); |
| 110 | 117 | ||
| 111 | outb_p(0x30, PIT_MODE); | 118 | outb_p(0x30, PIT_MODE); |
| 112 | outb_p(0, PIT_CH0); | 119 | |
| 113 | outb_p(0, PIT_CH0); | 120 | if (i8253_clear_counter_on_shutdown) { |
| 121 | outb_p(0, PIT_CH0); | ||
| 122 | outb_p(0, PIT_CH0); | ||
| 123 | } | ||
| 114 | 124 | ||
| 115 | raw_spin_unlock(&i8253_lock); | 125 | raw_spin_unlock(&i8253_lock); |
| 116 | return 0; | 126 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index d0102cfc8efb..104b2e0d893b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -151,6 +151,7 @@ extern int amdgpu_compute_multipipe; | |||
| 151 | extern int amdgpu_gpu_recovery; | 151 | extern int amdgpu_gpu_recovery; |
| 152 | extern int amdgpu_emu_mode; | 152 | extern int amdgpu_emu_mode; |
| 153 | extern uint amdgpu_smu_memory_pool_size; | 153 | extern uint amdgpu_smu_memory_pool_size; |
| 154 | extern uint amdgpu_dc_feature_mask; | ||
| 154 | extern struct amdgpu_mgpu_info mgpu_info; | 155 | extern struct amdgpu_mgpu_info mgpu_info; |
| 155 | 156 | ||
| 156 | #ifdef CONFIG_DRM_AMDGPU_SI | 157 | #ifdef CONFIG_DRM_AMDGPU_SI |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 943dbf3c5da1..8de55f7f1a3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
| @@ -127,6 +127,9 @@ int amdgpu_compute_multipipe = -1; | |||
| 127 | int amdgpu_gpu_recovery = -1; /* auto */ | 127 | int amdgpu_gpu_recovery = -1; /* auto */ |
| 128 | int amdgpu_emu_mode = 0; | 128 | int amdgpu_emu_mode = 0; |
| 129 | uint amdgpu_smu_memory_pool_size = 0; | 129 | uint amdgpu_smu_memory_pool_size = 0; |
| 130 | /* FBC (bit 0) disabled by default*/ | ||
| 131 | uint amdgpu_dc_feature_mask = 0; | ||
| 132 | |||
| 130 | struct amdgpu_mgpu_info mgpu_info = { | 133 | struct amdgpu_mgpu_info mgpu_info = { |
| 131 | .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), | 134 | .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), |
| 132 | }; | 135 | }; |
| @@ -631,6 +634,14 @@ module_param(halt_if_hws_hang, int, 0644); | |||
| 631 | MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (default), 1 = on)"); | 634 | MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (default), 1 = on)"); |
| 632 | #endif | 635 | #endif |
| 633 | 636 | ||
| 637 | /** | ||
| 638 | * DOC: dcfeaturemask (uint) | ||
| 639 | * Override display features enabled. See enum DC_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h. | ||
| 640 | * The default is the current set of stable display features. | ||
| 641 | */ | ||
| 642 | MODULE_PARM_DESC(dcfeaturemask, "all stable DC features enabled (default))"); | ||
| 643 | module_param_named(dcfeaturemask, amdgpu_dc_feature_mask, uint, 0444); | ||
| 644 | |||
| 634 | static const struct pci_device_id pciidlist[] = { | 645 | static const struct pci_device_id pciidlist[] = { |
| 635 | #ifdef CONFIG_DRM_AMDGPU_SI | 646 | #ifdef CONFIG_DRM_AMDGPU_SI |
| 636 | {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, | 647 | {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c index 2d4473557b0d..d13fc4fcb517 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c | |||
| @@ -49,6 +49,7 @@ int vega20_reg_base_init(struct amdgpu_device *adev) | |||
| 49 | adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); | 49 | adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); |
| 50 | adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); | 50 | adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); |
| 51 | adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); | 51 | adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); |
| 52 | adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i])); | ||
| 52 | } | 53 | } |
| 53 | return 0; | 54 | return 0; |
| 54 | } | 55 | } |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index b0df6dc9a775..c1262f62cd9f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -429,6 +429,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) | |||
| 429 | adev->asic_type < CHIP_RAVEN) | 429 | adev->asic_type < CHIP_RAVEN) |
| 430 | init_data.flags.gpu_vm_support = true; | 430 | init_data.flags.gpu_vm_support = true; |
| 431 | 431 | ||
| 432 | if (amdgpu_dc_feature_mask & DC_FBC_MASK) | ||
| 433 | init_data.flags.fbc_support = true; | ||
| 434 | |||
| 432 | /* Display Core create. */ | 435 | /* Display Core create. */ |
| 433 | adev->dm.dc = dc_create(&init_data); | 436 | adev->dm.dc = dc_create(&init_data); |
| 434 | 437 | ||
| @@ -1524,13 +1527,6 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) | |||
| 1524 | { | 1527 | { |
| 1525 | struct amdgpu_display_manager *dm = bl_get_data(bd); | 1528 | struct amdgpu_display_manager *dm = bl_get_data(bd); |
| 1526 | 1529 | ||
| 1527 | /* | ||
| 1528 | * PWM interperts 0 as 100% rather than 0% because of HW | ||
| 1529 | * limitation for level 0.So limiting minimum brightness level | ||
| 1530 | * to 1. | ||
| 1531 | */ | ||
| 1532 | if (bd->props.brightness < 1) | ||
| 1533 | return 1; | ||
| 1534 | if (dc_link_set_backlight_level(dm->backlight_link, | 1530 | if (dc_link_set_backlight_level(dm->backlight_link, |
| 1535 | bd->props.brightness, 0, 0)) | 1531 | bd->props.brightness, 0, 0)) |
| 1536 | return 0; | 1532 | return 0; |
| @@ -2707,18 +2703,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2707 | drm_connector = &aconnector->base; | 2703 | drm_connector = &aconnector->base; |
| 2708 | 2704 | ||
| 2709 | if (!aconnector->dc_sink) { | 2705 | if (!aconnector->dc_sink) { |
| 2710 | /* | 2706 | if (!aconnector->mst_port) { |
| 2711 | * Create dc_sink when necessary to MST | 2707 | sink = create_fake_sink(aconnector); |
| 2712 | * Don't apply fake_sink to MST | 2708 | if (!sink) |
| 2713 | */ | 2709 | return stream; |
| 2714 | if (aconnector->mst_port) { | ||
| 2715 | dm_dp_mst_dc_sink_create(drm_connector); | ||
| 2716 | return stream; | ||
| 2717 | } | 2710 | } |
| 2718 | |||
| 2719 | sink = create_fake_sink(aconnector); | ||
| 2720 | if (!sink) | ||
| 2721 | return stream; | ||
| 2722 | } else { | 2711 | } else { |
| 2723 | sink = aconnector->dc_sink; | 2712 | sink = aconnector->dc_sink; |
| 2724 | } | 2713 | } |
| @@ -3308,7 +3297,7 @@ void dm_drm_plane_destroy_state(struct drm_plane *plane, | |||
| 3308 | static const struct drm_plane_funcs dm_plane_funcs = { | 3297 | static const struct drm_plane_funcs dm_plane_funcs = { |
| 3309 | .update_plane = drm_atomic_helper_update_plane, | 3298 | .update_plane = drm_atomic_helper_update_plane, |
| 3310 | .disable_plane = drm_atomic_helper_disable_plane, | 3299 | .disable_plane = drm_atomic_helper_disable_plane, |
| 3311 | .destroy = drm_plane_cleanup, | 3300 | .destroy = drm_primary_helper_destroy, |
| 3312 | .reset = dm_drm_plane_reset, | 3301 | .reset = dm_drm_plane_reset, |
| 3313 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, | 3302 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, |
| 3314 | .atomic_destroy_state = dm_drm_plane_destroy_state, | 3303 | .atomic_destroy_state = dm_drm_plane_destroy_state, |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 978b34a5011c..924a38a1fc44 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
| @@ -160,8 +160,6 @@ struct amdgpu_dm_connector { | |||
| 160 | struct mutex hpd_lock; | 160 | struct mutex hpd_lock; |
| 161 | 161 | ||
| 162 | bool fake_enable; | 162 | bool fake_enable; |
| 163 | |||
| 164 | bool mst_connected; | ||
| 165 | }; | 163 | }; |
| 166 | 164 | ||
| 167 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) | 165 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 03601d717fed..d02c32a1039c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
| @@ -205,40 +205,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { | |||
| 205 | .atomic_get_property = amdgpu_dm_connector_atomic_get_property | 205 | .atomic_get_property = amdgpu_dm_connector_atomic_get_property |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | ||
| 209 | { | ||
| 210 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
| 211 | struct dc_sink *dc_sink; | ||
| 212 | struct dc_sink_init_data init_params = { | ||
| 213 | .link = aconnector->dc_link, | ||
| 214 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | ||
| 215 | |||
| 216 | /* FIXME none of this is safe. we shouldn't touch aconnector here in | ||
| 217 | * atomic_check | ||
| 218 | */ | ||
| 219 | |||
| 220 | /* | ||
| 221 | * TODO: Need to further figure out why ddc.algo is NULL while MST port exists | ||
| 222 | */ | ||
| 223 | if (!aconnector->port || !aconnector->port->aux.ddc.algo) | ||
| 224 | return; | ||
| 225 | |||
| 226 | ASSERT(aconnector->edid); | ||
| 227 | |||
| 228 | dc_sink = dc_link_add_remote_sink( | ||
| 229 | aconnector->dc_link, | ||
| 230 | (uint8_t *)aconnector->edid, | ||
| 231 | (aconnector->edid->extensions + 1) * EDID_LENGTH, | ||
| 232 | &init_params); | ||
| 233 | |||
| 234 | dc_sink->priv = aconnector; | ||
| 235 | aconnector->dc_sink = dc_sink; | ||
| 236 | |||
| 237 | if (aconnector->dc_sink) | ||
| 238 | amdgpu_dm_update_freesync_caps( | ||
| 239 | connector, aconnector->edid); | ||
| 240 | } | ||
| 241 | |||
| 242 | static int dm_dp_mst_get_modes(struct drm_connector *connector) | 208 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
| 243 | { | 209 | { |
| 244 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 210 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| @@ -319,12 +285,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) | |||
| 319 | struct amdgpu_device *adev = dev->dev_private; | 285 | struct amdgpu_device *adev = dev->dev_private; |
| 320 | struct amdgpu_encoder *amdgpu_encoder; | 286 | struct amdgpu_encoder *amdgpu_encoder; |
| 321 | struct drm_encoder *encoder; | 287 | struct drm_encoder *encoder; |
| 322 | const struct drm_connector_helper_funcs *connector_funcs = | ||
| 323 | connector->base.helper_private; | ||
| 324 | struct drm_encoder *enc_master = | ||
| 325 | connector_funcs->best_encoder(&connector->base); | ||
| 326 | 288 | ||
| 327 | DRM_DEBUG_KMS("enc master is %p\n", enc_master); | ||
| 328 | amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); | 289 | amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); |
| 329 | if (!amdgpu_encoder) | 290 | if (!amdgpu_encoder) |
| 330 | return NULL; | 291 | return NULL; |
| @@ -354,25 +315,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 354 | struct amdgpu_device *adev = dev->dev_private; | 315 | struct amdgpu_device *adev = dev->dev_private; |
| 355 | struct amdgpu_dm_connector *aconnector; | 316 | struct amdgpu_dm_connector *aconnector; |
| 356 | struct drm_connector *connector; | 317 | struct drm_connector *connector; |
| 357 | struct drm_connector_list_iter conn_iter; | ||
| 358 | |||
| 359 | drm_connector_list_iter_begin(dev, &conn_iter); | ||
| 360 | drm_for_each_connector_iter(connector, &conn_iter) { | ||
| 361 | aconnector = to_amdgpu_dm_connector(connector); | ||
| 362 | if (aconnector->mst_port == master | ||
| 363 | && !aconnector->port) { | ||
| 364 | DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n", | ||
| 365 | aconnector, connector->base.id, aconnector->mst_port); | ||
| 366 | |||
| 367 | aconnector->port = port; | ||
| 368 | drm_connector_set_path_property(connector, pathprop); | ||
| 369 | |||
| 370 | drm_connector_list_iter_end(&conn_iter); | ||
| 371 | aconnector->mst_connected = true; | ||
| 372 | return &aconnector->base; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | drm_connector_list_iter_end(&conn_iter); | ||
| 376 | 318 | ||
| 377 | aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); | 319 | aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); |
| 378 | if (!aconnector) | 320 | if (!aconnector) |
| @@ -421,8 +363,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 421 | */ | 363 | */ |
| 422 | amdgpu_dm_connector_funcs_reset(connector); | 364 | amdgpu_dm_connector_funcs_reset(connector); |
| 423 | 365 | ||
| 424 | aconnector->mst_connected = true; | ||
| 425 | |||
| 426 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", | 366 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", |
| 427 | aconnector, connector->base.id, aconnector->mst_port); | 367 | aconnector, connector->base.id, aconnector->mst_port); |
| 428 | 368 | ||
| @@ -434,6 +374,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 434 | static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | 374 | static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, |
| 435 | struct drm_connector *connector) | 375 | struct drm_connector *connector) |
| 436 | { | 376 | { |
| 377 | struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); | ||
| 378 | struct drm_device *dev = master->base.dev; | ||
| 379 | struct amdgpu_device *adev = dev->dev_private; | ||
| 437 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 380 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| 438 | 381 | ||
| 439 | DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", | 382 | DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", |
| @@ -447,7 +390,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 447 | aconnector->dc_sink = NULL; | 390 | aconnector->dc_sink = NULL; |
| 448 | } | 391 | } |
| 449 | 392 | ||
| 450 | aconnector->mst_connected = false; | 393 | drm_connector_unregister(connector); |
| 394 | if (adev->mode_info.rfbdev) | ||
| 395 | drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector); | ||
| 396 | drm_connector_put(connector); | ||
| 451 | } | 397 | } |
| 452 | 398 | ||
| 453 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | 399 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) |
| @@ -458,18 +404,10 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
| 458 | drm_kms_helper_hotplug_event(dev); | 404 | drm_kms_helper_hotplug_event(dev); |
| 459 | } | 405 | } |
| 460 | 406 | ||
| 461 | static void dm_dp_mst_link_status_reset(struct drm_connector *connector) | ||
| 462 | { | ||
| 463 | mutex_lock(&connector->dev->mode_config.mutex); | ||
| 464 | drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); | ||
| 465 | mutex_unlock(&connector->dev->mode_config.mutex); | ||
| 466 | } | ||
| 467 | |||
| 468 | static void dm_dp_mst_register_connector(struct drm_connector *connector) | 407 | static void dm_dp_mst_register_connector(struct drm_connector *connector) |
| 469 | { | 408 | { |
| 470 | struct drm_device *dev = connector->dev; | 409 | struct drm_device *dev = connector->dev; |
| 471 | struct amdgpu_device *adev = dev->dev_private; | 410 | struct amdgpu_device *adev = dev->dev_private; |
| 472 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
| 473 | 411 | ||
| 474 | if (adev->mode_info.rfbdev) | 412 | if (adev->mode_info.rfbdev) |
| 475 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); | 413 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); |
| @@ -477,9 +415,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) | |||
| 477 | DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); | 415 | DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); |
| 478 | 416 | ||
| 479 | drm_connector_register(connector); | 417 | drm_connector_register(connector); |
| 480 | |||
| 481 | if (aconnector->mst_connected) | ||
| 482 | dm_dp_mst_link_status_reset(connector); | ||
| 483 | } | 418 | } |
| 484 | 419 | ||
| 485 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { | 420 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 8cf51da26657..2da851b40042 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | |||
| @@ -31,6 +31,5 @@ struct amdgpu_dm_connector; | |||
| 31 | 31 | ||
| 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, | 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |
| 33 | struct amdgpu_dm_connector *aconnector); | 33 | struct amdgpu_dm_connector *aconnector); |
| 34 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector); | ||
| 35 | 34 | ||
| 36 | #endif | 35 | #endif |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index fb04a4ad141f..5da2186b3615 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
| @@ -1722,7 +1722,7 @@ static void write_i2c_retimer_setting( | |||
| 1722 | i2c_success = i2c_write(pipe_ctx, slave_address, | 1722 | i2c_success = i2c_write(pipe_ctx, slave_address, |
| 1723 | buffer, sizeof(buffer)); | 1723 | buffer, sizeof(buffer)); |
| 1724 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ | 1724 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ |
| 1725 | offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", | 1725 | offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", |
| 1726 | slave_address, buffer[0], buffer[1], i2c_success?1:0); | 1726 | slave_address, buffer[0], buffer[1], i2c_success?1:0); |
| 1727 | if (!i2c_success) | 1727 | if (!i2c_success) |
| 1728 | /* Write failure */ | 1728 | /* Write failure */ |
| @@ -1734,7 +1734,7 @@ static void write_i2c_retimer_setting( | |||
| 1734 | i2c_success = i2c_write(pipe_ctx, slave_address, | 1734 | i2c_success = i2c_write(pipe_ctx, slave_address, |
| 1735 | buffer, sizeof(buffer)); | 1735 | buffer, sizeof(buffer)); |
| 1736 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ | 1736 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ |
| 1737 | offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", | 1737 | offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", |
| 1738 | slave_address, buffer[0], buffer[1], i2c_success?1:0); | 1738 | slave_address, buffer[0], buffer[1], i2c_success?1:0); |
| 1739 | if (!i2c_success) | 1739 | if (!i2c_success) |
| 1740 | /* Write failure */ | 1740 | /* Write failure */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 199527171100..b57fa61b3034 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
| @@ -169,6 +169,7 @@ struct link_training_settings; | |||
| 169 | struct dc_config { | 169 | struct dc_config { |
| 170 | bool gpu_vm_support; | 170 | bool gpu_vm_support; |
| 171 | bool disable_disp_pll_sharing; | 171 | bool disable_disp_pll_sharing; |
| 172 | bool fbc_support; | ||
| 172 | }; | 173 | }; |
| 173 | 174 | ||
| 174 | enum visual_confirm { | 175 | enum visual_confirm { |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index b75ede5f84f7..b459867a05b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
| @@ -1736,7 +1736,12 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx, | |||
| 1736 | if (events->force_trigger) | 1736 | if (events->force_trigger) |
| 1737 | value |= 0x1; | 1737 | value |= 0x1; |
| 1738 | 1738 | ||
| 1739 | value |= 0x84; | 1739 | if (num_pipes) { |
| 1740 | struct dc *dc = pipe_ctx[0]->stream->ctx->dc; | ||
| 1741 | |||
| 1742 | if (dc->fbc_compressor) | ||
| 1743 | value |= 0x84; | ||
| 1744 | } | ||
| 1740 | 1745 | ||
| 1741 | for (i = 0; i < num_pipes; i++) | 1746 | for (i = 0; i < num_pipes; i++) |
| 1742 | pipe_ctx[i]->stream_res.tg->funcs-> | 1747 | pipe_ctx[i]->stream_res.tg->funcs-> |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index e3624ca24574..7c9fd9052ee2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | |||
| @@ -1362,7 +1362,8 @@ static bool construct( | |||
| 1362 | pool->base.sw_i2cs[i] = NULL; | 1362 | pool->base.sw_i2cs[i] = NULL; |
| 1363 | } | 1363 | } |
| 1364 | 1364 | ||
| 1365 | dc->fbc_compressor = dce110_compressor_create(ctx); | 1365 | if (dc->config.fbc_support) |
| 1366 | dc->fbc_compressor = dce110_compressor_create(ctx); | ||
| 1366 | 1367 | ||
| 1367 | if (!underlay_create(ctx, &pool->base)) | 1368 | if (!underlay_create(ctx, &pool->base)) |
| 1368 | goto res_create_fail; | 1369 | goto res_create_fail; |
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 2083c308007c..470d7b89071a 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
| @@ -133,6 +133,10 @@ enum PP_FEATURE_MASK { | |||
| 133 | PP_AVFS_MASK = 0x40000, | 133 | PP_AVFS_MASK = 0x40000, |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | enum DC_FEATURE_MASK { | ||
| 137 | DC_FBC_MASK = 0x1, | ||
| 138 | }; | ||
| 139 | |||
| 136 | /** | 140 | /** |
| 137 | * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks | 141 | * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks |
| 138 | */ | 142 | */ |
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index d2e7c0fa96c2..8eb0bb241210 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h | |||
| @@ -1325,7 +1325,7 @@ struct atom_smu_info_v3_3 { | |||
| 1325 | struct atom_common_table_header table_header; | 1325 | struct atom_common_table_header table_header; |
| 1326 | uint8_t smuip_min_ver; | 1326 | uint8_t smuip_min_ver; |
| 1327 | uint8_t smuip_max_ver; | 1327 | uint8_t smuip_max_ver; |
| 1328 | uint8_t smu_rsd1; | 1328 | uint8_t waflclk_ss_mode; |
| 1329 | uint8_t gpuclk_ss_mode; | 1329 | uint8_t gpuclk_ss_mode; |
| 1330 | uint16_t sclk_ss_percentage; | 1330 | uint16_t sclk_ss_percentage; |
| 1331 | uint16_t sclk_ss_rate_10hz; | 1331 | uint16_t sclk_ss_rate_10hz; |
| @@ -1355,7 +1355,10 @@ struct atom_smu_info_v3_3 { | |||
| 1355 | uint32_t syspll3_1_vco_freq_10khz; | 1355 | uint32_t syspll3_1_vco_freq_10khz; |
| 1356 | uint32_t bootup_fclk_10khz; | 1356 | uint32_t bootup_fclk_10khz; |
| 1357 | uint32_t bootup_waflclk_10khz; | 1357 | uint32_t bootup_waflclk_10khz; |
| 1358 | uint32_t reserved[3]; | 1358 | uint32_t smu_info_caps; |
| 1359 | uint16_t waflclk_ss_percentage; // in unit of 0.001% | ||
| 1360 | uint16_t smuinitoffset; | ||
| 1361 | uint32_t reserved; | ||
| 1359 | }; | 1362 | }; |
| 1360 | 1363 | ||
| 1361 | /* | 1364 | /* |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 57143d51e3ee..99861f32b1f9 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
| @@ -120,6 +120,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) | |||
| 120 | data->registry_data.disable_auto_wattman = 1; | 120 | data->registry_data.disable_auto_wattman = 1; |
| 121 | data->registry_data.auto_wattman_debug = 0; | 121 | data->registry_data.auto_wattman_debug = 0; |
| 122 | data->registry_data.auto_wattman_sample_period = 100; | 122 | data->registry_data.auto_wattman_sample_period = 100; |
| 123 | data->registry_data.fclk_gfxclk_ratio = 0x3F6CCCCD; | ||
| 123 | data->registry_data.auto_wattman_threshold = 50; | 124 | data->registry_data.auto_wattman_threshold = 50; |
| 124 | data->registry_data.gfxoff_controlled_by_driver = 1; | 125 | data->registry_data.gfxoff_controlled_by_driver = 1; |
| 125 | data->gfxoff_allowed = false; | 126 | data->gfxoff_allowed = false; |
| @@ -829,6 +830,28 @@ static int vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr) | |||
| 829 | return 0; | 830 | return 0; |
| 830 | } | 831 | } |
| 831 | 832 | ||
| 833 | static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr) | ||
| 834 | { | ||
| 835 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 836 | |||
| 837 | if (data->smu_features[GNLD_DPM_UCLK].enabled) | ||
| 838 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 839 | PPSMC_MSG_SetUclkFastSwitch, | ||
| 840 | 1); | ||
| 841 | |||
| 842 | return 0; | ||
| 843 | } | ||
| 844 | |||
| 845 | static int vega20_send_clock_ratio(struct pp_hwmgr *hwmgr) | ||
| 846 | { | ||
| 847 | struct vega20_hwmgr *data = | ||
| 848 | (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 849 | |||
| 850 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 851 | PPSMC_MSG_SetFclkGfxClkRatio, | ||
| 852 | data->registry_data.fclk_gfxclk_ratio); | ||
| 853 | } | ||
| 854 | |||
| 832 | static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr) | 855 | static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr) |
| 833 | { | 856 | { |
| 834 | struct vega20_hwmgr *data = | 857 | struct vega20_hwmgr *data = |
| @@ -1532,6 +1555,16 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
| 1532 | "[EnableDPMTasks] Failed to enable all smu features!", | 1555 | "[EnableDPMTasks] Failed to enable all smu features!", |
| 1533 | return result); | 1556 | return result); |
| 1534 | 1557 | ||
| 1558 | result = vega20_notify_smc_display_change(hwmgr); | ||
| 1559 | PP_ASSERT_WITH_CODE(!result, | ||
| 1560 | "[EnableDPMTasks] Failed to notify smc display change!", | ||
| 1561 | return result); | ||
| 1562 | |||
| 1563 | result = vega20_send_clock_ratio(hwmgr); | ||
| 1564 | PP_ASSERT_WITH_CODE(!result, | ||
| 1565 | "[EnableDPMTasks] Failed to send clock ratio!", | ||
| 1566 | return result); | ||
| 1567 | |||
| 1535 | /* Initialize UVD/VCE powergating state */ | 1568 | /* Initialize UVD/VCE powergating state */ |
| 1536 | vega20_init_powergate_state(hwmgr); | 1569 | vega20_init_powergate_state(hwmgr); |
| 1537 | 1570 | ||
| @@ -1972,19 +2005,6 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, | |||
| 1972 | return ret; | 2005 | return ret; |
| 1973 | } | 2006 | } |
| 1974 | 2007 | ||
| 1975 | static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr, | ||
| 1976 | bool has_disp) | ||
| 1977 | { | ||
| 1978 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 1979 | |||
| 1980 | if (data->smu_features[GNLD_DPM_UCLK].enabled) | ||
| 1981 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 1982 | PPSMC_MSG_SetUclkFastSwitch, | ||
| 1983 | has_disp ? 1 : 0); | ||
| 1984 | |||
| 1985 | return 0; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, | 2008 | int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, |
| 1989 | struct pp_display_clock_request *clock_req) | 2009 | struct pp_display_clock_request *clock_req) |
| 1990 | { | 2010 | { |
| @@ -2044,13 +2064,6 @@ static int vega20_notify_smc_display_config_after_ps_adjustment( | |||
| 2044 | struct pp_display_clock_request clock_req; | 2064 | struct pp_display_clock_request clock_req; |
| 2045 | int ret = 0; | 2065 | int ret = 0; |
| 2046 | 2066 | ||
| 2047 | if ((hwmgr->display_config->num_display > 1) && | ||
| 2048 | !hwmgr->display_config->multi_monitor_in_sync && | ||
| 2049 | !hwmgr->display_config->nb_pstate_switch_disable) | ||
| 2050 | vega20_notify_smc_display_change(hwmgr, false); | ||
| 2051 | else | ||
| 2052 | vega20_notify_smc_display_change(hwmgr, true); | ||
| 2053 | |||
| 2054 | min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk; | 2067 | min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk; |
| 2055 | min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk; | 2068 | min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk; |
| 2056 | min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock; | 2069 | min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index 56fe6a0d42e8..25faaa5c5b10 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | |||
| @@ -328,6 +328,7 @@ struct vega20_registry_data { | |||
| 328 | uint8_t disable_auto_wattman; | 328 | uint8_t disable_auto_wattman; |
| 329 | uint32_t auto_wattman_debug; | 329 | uint32_t auto_wattman_debug; |
| 330 | uint32_t auto_wattman_sample_period; | 330 | uint32_t auto_wattman_sample_period; |
| 331 | uint32_t fclk_gfxclk_ratio; | ||
| 331 | uint8_t auto_wattman_threshold; | 332 | uint8_t auto_wattman_threshold; |
| 332 | uint8_t log_avfs_param; | 333 | uint8_t log_avfs_param; |
| 333 | uint8_t enable_enginess; | 334 | uint8_t enable_enginess; |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h index 45d64a81e945..4f63a736ea0e 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h | |||
| @@ -105,7 +105,8 @@ | |||
| 105 | #define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x4B | 105 | #define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x4B |
| 106 | #define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x4C | 106 | #define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x4C |
| 107 | #define PPSMC_MSG_WaflTest 0x4D | 107 | #define PPSMC_MSG_WaflTest 0x4D |
| 108 | // Unused ID 0x4E to 0x50 | 108 | #define PPSMC_MSG_SetFclkGfxClkRatio 0x4E |
| 109 | // Unused ID 0x4F to 0x50 | ||
| 109 | #define PPSMC_MSG_AllowGfxOff 0x51 | 110 | #define PPSMC_MSG_AllowGfxOff 0x51 |
| 110 | #define PPSMC_MSG_DisallowGfxOff 0x52 | 111 | #define PPSMC_MSG_DisallowGfxOff 0x52 |
| 111 | #define PPSMC_MSG_GetPptLimit 0x53 | 112 | #define PPSMC_MSG_GetPptLimit 0x53 |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index e7c3ed6c9a2e..9b476368aa31 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c | |||
| @@ -93,7 +93,7 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job) | |||
| 93 | * If the GPU managed to complete this jobs fence, the timout is | 93 | * If the GPU managed to complete this jobs fence, the timout is |
| 94 | * spurious. Bail out. | 94 | * spurious. Bail out. |
| 95 | */ | 95 | */ |
| 96 | if (fence_completed(gpu, submit->out_fence->seqno)) | 96 | if (dma_fence_is_signaled(submit->out_fence)) |
| 97 | return; | 97 | return; |
| 98 | 98 | ||
| 99 | /* | 99 | /* |
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 94529aa82339..aef487dd8731 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c | |||
| @@ -164,13 +164,6 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end) | |||
| 164 | return frm; | 164 | return frm; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc) | ||
| 168 | { | ||
| 169 | struct decon_context *ctx = crtc->ctx; | ||
| 170 | |||
| 171 | return decon_get_frame_count(ctx, false); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void decon_setup_trigger(struct decon_context *ctx) | 167 | static void decon_setup_trigger(struct decon_context *ctx) |
| 175 | { | 168 | { |
| 176 | if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG)) | 169 | if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG)) |
| @@ -536,7 +529,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { | |||
| 536 | .disable = decon_disable, | 529 | .disable = decon_disable, |
| 537 | .enable_vblank = decon_enable_vblank, | 530 | .enable_vblank = decon_enable_vblank, |
| 538 | .disable_vblank = decon_disable_vblank, | 531 | .disable_vblank = decon_disable_vblank, |
| 539 | .get_vblank_counter = decon_get_vblank_counter, | ||
| 540 | .atomic_begin = decon_atomic_begin, | 532 | .atomic_begin = decon_atomic_begin, |
| 541 | .update_plane = decon_update_plane, | 533 | .update_plane = decon_update_plane, |
| 542 | .disable_plane = decon_disable_plane, | 534 | .disable_plane = decon_disable_plane, |
| @@ -554,7 +546,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | |||
| 554 | int ret; | 546 | int ret; |
| 555 | 547 | ||
| 556 | ctx->drm_dev = drm_dev; | 548 | ctx->drm_dev = drm_dev; |
| 557 | drm_dev->max_vblank_count = 0xffffffff; | ||
| 558 | 549 | ||
| 559 | for (win = ctx->first_win; win < WINDOWS_NR; win++) { | 550 | for (win = ctx->first_win; win < WINDOWS_NR; win++) { |
| 560 | ctx->configs[win].pixel_formats = decon_formats; | 551 | ctx->configs[win].pixel_formats = decon_formats; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index eea90251808f..2696289ecc78 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
| @@ -162,16 +162,6 @@ static void exynos_drm_crtc_disable_vblank(struct drm_crtc *crtc) | |||
| 162 | exynos_crtc->ops->disable_vblank(exynos_crtc); | 162 | exynos_crtc->ops->disable_vblank(exynos_crtc); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | static u32 exynos_drm_crtc_get_vblank_counter(struct drm_crtc *crtc) | ||
| 166 | { | ||
| 167 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
| 168 | |||
| 169 | if (exynos_crtc->ops->get_vblank_counter) | ||
| 170 | return exynos_crtc->ops->get_vblank_counter(exynos_crtc); | ||
| 171 | |||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | static const struct drm_crtc_funcs exynos_crtc_funcs = { | 165 | static const struct drm_crtc_funcs exynos_crtc_funcs = { |
| 176 | .set_config = drm_atomic_helper_set_config, | 166 | .set_config = drm_atomic_helper_set_config, |
| 177 | .page_flip = drm_atomic_helper_page_flip, | 167 | .page_flip = drm_atomic_helper_page_flip, |
| @@ -181,7 +171,6 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = { | |||
| 181 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, | 171 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, |
| 182 | .enable_vblank = exynos_drm_crtc_enable_vblank, | 172 | .enable_vblank = exynos_drm_crtc_enable_vblank, |
| 183 | .disable_vblank = exynos_drm_crtc_disable_vblank, | 173 | .disable_vblank = exynos_drm_crtc_disable_vblank, |
| 184 | .get_vblank_counter = exynos_drm_crtc_get_vblank_counter, | ||
| 185 | }; | 174 | }; |
| 186 | 175 | ||
| 187 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | 176 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index ec9604f1272b..5e61e707f955 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
| @@ -135,7 +135,6 @@ struct exynos_drm_crtc_ops { | |||
| 135 | void (*disable)(struct exynos_drm_crtc *crtc); | 135 | void (*disable)(struct exynos_drm_crtc *crtc); |
| 136 | int (*enable_vblank)(struct exynos_drm_crtc *crtc); | 136 | int (*enable_vblank)(struct exynos_drm_crtc *crtc); |
| 137 | void (*disable_vblank)(struct exynos_drm_crtc *crtc); | 137 | void (*disable_vblank)(struct exynos_drm_crtc *crtc); |
| 138 | u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc); | ||
| 139 | enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc, | 138 | enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc, |
| 140 | const struct drm_display_mode *mode); | 139 | const struct drm_display_mode *mode); |
| 141 | bool (*mode_fixup)(struct exynos_drm_crtc *crtc, | 140 | bool (*mode_fixup)(struct exynos_drm_crtc *crtc, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 07af7758066d..d81e62ae286a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <drm/drmP.h> | 15 | #include <drm/drmP.h> |
| 16 | #include <drm/drm_crtc_helper.h> | 16 | #include <drm/drm_crtc_helper.h> |
| 17 | #include <drm/drm_fb_helper.h> | ||
| 17 | #include <drm/drm_mipi_dsi.h> | 18 | #include <drm/drm_mipi_dsi.h> |
| 18 | #include <drm/drm_panel.h> | 19 | #include <drm/drm_panel.h> |
| 19 | #include <drm/drm_atomic_helper.h> | 20 | #include <drm/drm_atomic_helper.h> |
| @@ -1474,12 +1475,12 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) | |||
| 1474 | { | 1475 | { |
| 1475 | struct exynos_dsi *dsi = encoder_to_dsi(encoder); | 1476 | struct exynos_dsi *dsi = encoder_to_dsi(encoder); |
| 1476 | struct drm_connector *connector = &dsi->connector; | 1477 | struct drm_connector *connector = &dsi->connector; |
| 1478 | struct drm_device *drm = encoder->dev; | ||
| 1477 | int ret; | 1479 | int ret; |
| 1478 | 1480 | ||
| 1479 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 1481 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
| 1480 | 1482 | ||
| 1481 | ret = drm_connector_init(encoder->dev, connector, | 1483 | ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs, |
| 1482 | &exynos_dsi_connector_funcs, | ||
| 1483 | DRM_MODE_CONNECTOR_DSI); | 1484 | DRM_MODE_CONNECTOR_DSI); |
| 1484 | if (ret) { | 1485 | if (ret) { |
| 1485 | DRM_ERROR("Failed to initialize connector with drm\n"); | 1486 | DRM_ERROR("Failed to initialize connector with drm\n"); |
| @@ -1489,7 +1490,12 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) | |||
| 1489 | connector->status = connector_status_disconnected; | 1490 | connector->status = connector_status_disconnected; |
| 1490 | drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); | 1491 | drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); |
| 1491 | drm_connector_attach_encoder(connector, encoder); | 1492 | drm_connector_attach_encoder(connector, encoder); |
| 1493 | if (!drm->registered) | ||
| 1494 | return 0; | ||
| 1492 | 1495 | ||
| 1496 | connector->funcs->reset(connector); | ||
| 1497 | drm_fb_helper_add_one_connector(drm->fb_helper, connector); | ||
| 1498 | drm_connector_register(connector); | ||
| 1493 | return 0; | 1499 | return 0; |
| 1494 | } | 1500 | } |
| 1495 | 1501 | ||
| @@ -1527,7 +1533,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, | |||
| 1527 | } | 1533 | } |
| 1528 | 1534 | ||
| 1529 | dsi->panel = of_drm_find_panel(device->dev.of_node); | 1535 | dsi->panel = of_drm_find_panel(device->dev.of_node); |
| 1530 | if (dsi->panel) { | 1536 | if (IS_ERR(dsi->panel)) { |
| 1537 | dsi->panel = NULL; | ||
| 1538 | } else { | ||
| 1531 | drm_panel_attach(dsi->panel, &dsi->connector); | 1539 | drm_panel_attach(dsi->panel, &dsi->connector); |
| 1532 | dsi->connector.status = connector_status_connected; | 1540 | dsi->connector.status = connector_status_connected; |
| 1533 | } | 1541 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 918dd2c82209..01d182289efa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
| @@ -192,7 +192,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev) | |||
| 192 | struct drm_fb_helper *helper; | 192 | struct drm_fb_helper *helper; |
| 193 | int ret; | 193 | int ret; |
| 194 | 194 | ||
| 195 | if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector) | 195 | if (!dev->mode_config.num_crtc) |
| 196 | return 0; | 196 | return 0; |
| 197 | 197 | ||
| 198 | fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); | 198 | fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 2402395a068d..58e166effa45 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
| @@ -1905,7 +1905,6 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) | |||
| 1905 | vgpu_free_mm(mm); | 1905 | vgpu_free_mm(mm); |
| 1906 | return ERR_PTR(-ENOMEM); | 1906 | return ERR_PTR(-ENOMEM); |
| 1907 | } | 1907 | } |
| 1908 | mm->ggtt_mm.last_partial_off = -1UL; | ||
| 1909 | 1908 | ||
| 1910 | return mm; | 1909 | return mm; |
| 1911 | } | 1910 | } |
| @@ -1930,7 +1929,6 @@ void _intel_vgpu_mm_release(struct kref *mm_ref) | |||
| 1930 | invalidate_ppgtt_mm(mm); | 1929 | invalidate_ppgtt_mm(mm); |
| 1931 | } else { | 1930 | } else { |
| 1932 | vfree(mm->ggtt_mm.virtual_ggtt); | 1931 | vfree(mm->ggtt_mm.virtual_ggtt); |
| 1933 | mm->ggtt_mm.last_partial_off = -1UL; | ||
| 1934 | } | 1932 | } |
| 1935 | 1933 | ||
| 1936 | vgpu_free_mm(mm); | 1934 | vgpu_free_mm(mm); |
| @@ -2168,6 +2166,8 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
| 2168 | struct intel_gvt_gtt_entry e, m; | 2166 | struct intel_gvt_gtt_entry e, m; |
| 2169 | dma_addr_t dma_addr; | 2167 | dma_addr_t dma_addr; |
| 2170 | int ret; | 2168 | int ret; |
| 2169 | struct intel_gvt_partial_pte *partial_pte, *pos, *n; | ||
| 2170 | bool partial_update = false; | ||
| 2171 | 2171 | ||
| 2172 | if (bytes != 4 && bytes != 8) | 2172 | if (bytes != 4 && bytes != 8) |
| 2173 | return -EINVAL; | 2173 | return -EINVAL; |
| @@ -2178,68 +2178,57 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
| 2178 | if (!vgpu_gmadr_is_valid(vgpu, gma)) | 2178 | if (!vgpu_gmadr_is_valid(vgpu, gma)) |
| 2179 | return 0; | 2179 | return 0; |
| 2180 | 2180 | ||
| 2181 | ggtt_get_guest_entry(ggtt_mm, &e, g_gtt_index); | 2181 | e.type = GTT_TYPE_GGTT_PTE; |
| 2182 | |||
| 2183 | memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, | 2182 | memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, |
| 2184 | bytes); | 2183 | bytes); |
| 2185 | 2184 | ||
| 2186 | /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes | 2185 | /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes |
| 2187 | * write, we assume the two 4 bytes writes are consecutive. | 2186 | * write, save the first 4 bytes in a list and update virtual |
| 2188 | * Otherwise, we abort and report error | 2187 | * PTE. Only update shadow PTE when the second 4 bytes comes. |
| 2189 | */ | 2188 | */ |
| 2190 | if (bytes < info->gtt_entry_size) { | 2189 | if (bytes < info->gtt_entry_size) { |
| 2191 | if (ggtt_mm->ggtt_mm.last_partial_off == -1UL) { | 2190 | bool found = false; |
| 2192 | /* the first partial part*/ | 2191 | |
| 2193 | ggtt_mm->ggtt_mm.last_partial_off = off; | 2192 | list_for_each_entry_safe(pos, n, |
| 2194 | ggtt_mm->ggtt_mm.last_partial_data = e.val64; | 2193 | &ggtt_mm->ggtt_mm.partial_pte_list, list) { |
| 2195 | return 0; | 2194 | if (g_gtt_index == pos->offset >> |
| 2196 | } else if ((g_gtt_index == | 2195 | info->gtt_entry_size_shift) { |
| 2197 | (ggtt_mm->ggtt_mm.last_partial_off >> | 2196 | if (off != pos->offset) { |
| 2198 | info->gtt_entry_size_shift)) && | 2197 | /* the second partial part*/ |
| 2199 | (off != ggtt_mm->ggtt_mm.last_partial_off)) { | 2198 | int last_off = pos->offset & |
| 2200 | /* the second partial part */ | 2199 | (info->gtt_entry_size - 1); |
| 2201 | 2200 | ||
| 2202 | int last_off = ggtt_mm->ggtt_mm.last_partial_off & | 2201 | memcpy((void *)&e.val64 + last_off, |
| 2203 | (info->gtt_entry_size - 1); | 2202 | (void *)&pos->data + last_off, |
| 2204 | 2203 | bytes); | |
| 2205 | memcpy((void *)&e.val64 + last_off, | 2204 | |
| 2206 | (void *)&ggtt_mm->ggtt_mm.last_partial_data + | 2205 | list_del(&pos->list); |
| 2207 | last_off, bytes); | 2206 | kfree(pos); |
| 2208 | 2207 | found = true; | |
| 2209 | ggtt_mm->ggtt_mm.last_partial_off = -1UL; | 2208 | break; |
| 2210 | } else { | 2209 | } |
| 2211 | int last_offset; | 2210 | |
| 2212 | 2211 | /* update of the first partial part */ | |
| 2213 | gvt_vgpu_err("failed to populate guest ggtt entry: abnormal ggtt entry write sequence, last_partial_off=%lx, offset=%x, bytes=%d, ggtt entry size=%d\n", | 2212 | pos->data = e.val64; |
| 2214 | ggtt_mm->ggtt_mm.last_partial_off, off, | 2213 | ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index); |
| 2215 | bytes, info->gtt_entry_size); | 2214 | return 0; |
| 2216 | 2215 | } | |
| 2217 | /* set host ggtt entry to scratch page and clear | 2216 | } |
| 2218 | * virtual ggtt entry as not present for last | ||
| 2219 | * partially write offset | ||
| 2220 | */ | ||
| 2221 | last_offset = ggtt_mm->ggtt_mm.last_partial_off & | ||
| 2222 | (~(info->gtt_entry_size - 1)); | ||
| 2223 | |||
| 2224 | ggtt_get_host_entry(ggtt_mm, &m, last_offset); | ||
| 2225 | ggtt_invalidate_pte(vgpu, &m); | ||
| 2226 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); | ||
| 2227 | ops->clear_present(&m); | ||
| 2228 | ggtt_set_host_entry(ggtt_mm, &m, last_offset); | ||
| 2229 | ggtt_invalidate(gvt->dev_priv); | ||
| 2230 | |||
| 2231 | ggtt_get_guest_entry(ggtt_mm, &e, last_offset); | ||
| 2232 | ops->clear_present(&e); | ||
| 2233 | ggtt_set_guest_entry(ggtt_mm, &e, last_offset); | ||
| 2234 | |||
| 2235 | ggtt_mm->ggtt_mm.last_partial_off = off; | ||
| 2236 | ggtt_mm->ggtt_mm.last_partial_data = e.val64; | ||
| 2237 | 2217 | ||
| 2238 | return 0; | 2218 | if (!found) { |
| 2219 | /* the first partial part */ | ||
| 2220 | partial_pte = kzalloc(sizeof(*partial_pte), GFP_KERNEL); | ||
| 2221 | if (!partial_pte) | ||
| 2222 | return -ENOMEM; | ||
| 2223 | partial_pte->offset = off; | ||
| 2224 | partial_pte->data = e.val64; | ||
| 2225 | list_add_tail(&partial_pte->list, | ||
| 2226 | &ggtt_mm->ggtt_mm.partial_pte_list); | ||
| 2227 | partial_update = true; | ||
| 2239 | } | 2228 | } |
| 2240 | } | 2229 | } |
| 2241 | 2230 | ||
| 2242 | if (ops->test_present(&e)) { | 2231 | if (!partial_update && (ops->test_present(&e))) { |
| 2243 | gfn = ops->get_pfn(&e); | 2232 | gfn = ops->get_pfn(&e); |
| 2244 | m = e; | 2233 | m = e; |
| 2245 | 2234 | ||
| @@ -2263,16 +2252,18 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
| 2263 | } else | 2252 | } else |
| 2264 | ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); | 2253 | ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); |
| 2265 | } else { | 2254 | } else { |
| 2266 | ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index); | ||
| 2267 | ggtt_invalidate_pte(vgpu, &m); | ||
| 2268 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); | 2255 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); |
| 2269 | ops->clear_present(&m); | 2256 | ops->clear_present(&m); |
| 2270 | } | 2257 | } |
| 2271 | 2258 | ||
| 2272 | out: | 2259 | out: |
| 2260 | ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index); | ||
| 2261 | |||
| 2262 | ggtt_get_host_entry(ggtt_mm, &e, g_gtt_index); | ||
| 2263 | ggtt_invalidate_pte(vgpu, &e); | ||
| 2264 | |||
| 2273 | ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); | 2265 | ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); |
| 2274 | ggtt_invalidate(gvt->dev_priv); | 2266 | ggtt_invalidate(gvt->dev_priv); |
| 2275 | ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index); | ||
| 2276 | return 0; | 2267 | return 0; |
| 2277 | } | 2268 | } |
| 2278 | 2269 | ||
| @@ -2430,6 +2421,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) | |||
| 2430 | 2421 | ||
| 2431 | intel_vgpu_reset_ggtt(vgpu, false); | 2422 | intel_vgpu_reset_ggtt(vgpu, false); |
| 2432 | 2423 | ||
| 2424 | INIT_LIST_HEAD(>t->ggtt_mm->ggtt_mm.partial_pte_list); | ||
| 2425 | |||
| 2433 | return create_scratch_page_tree(vgpu); | 2426 | return create_scratch_page_tree(vgpu); |
| 2434 | } | 2427 | } |
| 2435 | 2428 | ||
| @@ -2454,6 +2447,14 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu) | |||
| 2454 | 2447 | ||
| 2455 | static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu) | 2448 | static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu) |
| 2456 | { | 2449 | { |
| 2450 | struct intel_gvt_partial_pte *pos; | ||
| 2451 | |||
| 2452 | list_for_each_entry(pos, | ||
| 2453 | &vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list, list) { | ||
| 2454 | gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n", | ||
| 2455 | pos->offset, pos->data); | ||
| 2456 | kfree(pos); | ||
| 2457 | } | ||
| 2457 | intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm); | 2458 | intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm); |
| 2458 | vgpu->gtt.ggtt_mm = NULL; | 2459 | vgpu->gtt.ggtt_mm = NULL; |
| 2459 | } | 2460 | } |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 7a9b36176efb..d8cb04cc946d 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #define _GVT_GTT_H_ | 35 | #define _GVT_GTT_H_ |
| 36 | 36 | ||
| 37 | #define I915_GTT_PAGE_SHIFT 12 | 37 | #define I915_GTT_PAGE_SHIFT 12 |
| 38 | #define I915_GTT_PAGE_MASK (~(I915_GTT_PAGE_SIZE - 1)) | ||
| 39 | 38 | ||
| 40 | struct intel_vgpu_mm; | 39 | struct intel_vgpu_mm; |
| 41 | 40 | ||
| @@ -133,6 +132,12 @@ enum intel_gvt_mm_type { | |||
| 133 | 132 | ||
| 134 | #define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES | 133 | #define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES |
| 135 | 134 | ||
| 135 | struct intel_gvt_partial_pte { | ||
| 136 | unsigned long offset; | ||
| 137 | u64 data; | ||
| 138 | struct list_head list; | ||
| 139 | }; | ||
| 140 | |||
| 136 | struct intel_vgpu_mm { | 141 | struct intel_vgpu_mm { |
| 137 | enum intel_gvt_mm_type type; | 142 | enum intel_gvt_mm_type type; |
| 138 | struct intel_vgpu *vgpu; | 143 | struct intel_vgpu *vgpu; |
| @@ -157,8 +162,7 @@ struct intel_vgpu_mm { | |||
| 157 | } ppgtt_mm; | 162 | } ppgtt_mm; |
| 158 | struct { | 163 | struct { |
| 159 | void *virtual_ggtt; | 164 | void *virtual_ggtt; |
| 160 | unsigned long last_partial_off; | 165 | struct list_head partial_pte_list; |
| 161 | u64 last_partial_data; | ||
| 162 | } ggtt_mm; | 166 | } ggtt_mm; |
| 163 | }; | 167 | }; |
| 164 | }; | 168 | }; |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 90f50f67909a..aa280bb07125 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -1609,7 +1609,7 @@ static int bxt_gt_disp_pwron_write(struct intel_vgpu *vgpu, | |||
| 1609 | return 0; | 1609 | return 0; |
| 1610 | } | 1610 | } |
| 1611 | 1611 | ||
| 1612 | static int bxt_edp_psr_imr_iir_write(struct intel_vgpu *vgpu, | 1612 | static int edp_psr_imr_iir_write(struct intel_vgpu *vgpu, |
| 1613 | unsigned int offset, void *p_data, unsigned int bytes) | 1613 | unsigned int offset, void *p_data, unsigned int bytes) |
| 1614 | { | 1614 | { |
| 1615 | vgpu_vreg(vgpu, offset) = 0; | 1615 | vgpu_vreg(vgpu, offset) = 0; |
| @@ -2607,6 +2607,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) | |||
| 2607 | MMIO_DFH(_MMIO(0x1a178), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); | 2607 | MMIO_DFH(_MMIO(0x1a178), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); |
| 2608 | MMIO_DFH(_MMIO(0x1a17c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); | 2608 | MMIO_DFH(_MMIO(0x1a17c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); |
| 2609 | MMIO_DFH(_MMIO(0x2217c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); | 2609 | MMIO_DFH(_MMIO(0x2217c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); |
| 2610 | |||
| 2611 | MMIO_DH(EDP_PSR_IMR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write); | ||
| 2612 | MMIO_DH(EDP_PSR_IIR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write); | ||
| 2610 | return 0; | 2613 | return 0; |
| 2611 | } | 2614 | } |
| 2612 | 2615 | ||
| @@ -3205,9 +3208,6 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt) | |||
| 3205 | MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT); | 3208 | MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT); |
| 3206 | MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C), D_BXT); | 3209 | MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C), D_BXT); |
| 3207 | 3210 | ||
| 3208 | MMIO_DH(EDP_PSR_IMR, D_BXT, NULL, bxt_edp_psr_imr_iir_write); | ||
| 3209 | MMIO_DH(EDP_PSR_IIR, D_BXT, NULL, bxt_edp_psr_imr_iir_write); | ||
| 3210 | |||
| 3211 | MMIO_D(RC6_CTX_BASE, D_BXT); | 3211 | MMIO_D(RC6_CTX_BASE, D_BXT); |
| 3212 | 3212 | ||
| 3213 | MMIO_D(GEN8_PUSHBUS_CONTROL, D_BXT); | 3213 | MMIO_D(GEN8_PUSHBUS_CONTROL, D_BXT); |
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index 10e63eea5492..36a5147cd01e 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c | |||
| @@ -131,7 +131,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { | |||
| 131 | {RCS, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */ | 131 | {RCS, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */ |
| 132 | 132 | ||
| 133 | {RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ | 133 | {RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ |
| 134 | {RCS, GEN9_CSFE_CHICKEN1_RCS, 0x0, false}, /* 0x20d4 */ | 134 | {RCS, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */ |
| 135 | 135 | ||
| 136 | {RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ | 136 | {RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ |
| 137 | {RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ | 137 | {RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 44e2c0f5ec50..ffdbbac4400e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -1175,8 +1175,6 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv) | |||
| 1175 | return -EINVAL; | 1175 | return -EINVAL; |
| 1176 | } | 1176 | } |
| 1177 | 1177 | ||
| 1178 | dram_info->valid_dimm = true; | ||
| 1179 | |||
| 1180 | /* | 1178 | /* |
| 1181 | * If any of the channel is single rank channel, worst case output | 1179 | * If any of the channel is single rank channel, worst case output |
| 1182 | * will be same as if single rank memory, so consider single rank | 1180 | * will be same as if single rank memory, so consider single rank |
| @@ -1193,8 +1191,7 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv) | |||
| 1193 | return -EINVAL; | 1191 | return -EINVAL; |
| 1194 | } | 1192 | } |
| 1195 | 1193 | ||
| 1196 | if (ch0.is_16gb_dimm || ch1.is_16gb_dimm) | 1194 | dram_info->is_16gb_dimm = ch0.is_16gb_dimm || ch1.is_16gb_dimm; |
| 1197 | dram_info->is_16gb_dimm = true; | ||
| 1198 | 1195 | ||
| 1199 | dev_priv->dram_info.symmetric_memory = intel_is_dram_symmetric(val_ch0, | 1196 | dev_priv->dram_info.symmetric_memory = intel_is_dram_symmetric(val_ch0, |
| 1200 | val_ch1, | 1197 | val_ch1, |
| @@ -1314,7 +1311,6 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) | |||
| 1314 | return -EINVAL; | 1311 | return -EINVAL; |
| 1315 | } | 1312 | } |
| 1316 | 1313 | ||
| 1317 | dram_info->valid_dimm = true; | ||
| 1318 | dram_info->valid = true; | 1314 | dram_info->valid = true; |
| 1319 | return 0; | 1315 | return 0; |
| 1320 | } | 1316 | } |
| @@ -1327,12 +1323,17 @@ intel_get_dram_info(struct drm_i915_private *dev_priv) | |||
| 1327 | int ret; | 1323 | int ret; |
| 1328 | 1324 | ||
| 1329 | dram_info->valid = false; | 1325 | dram_info->valid = false; |
| 1330 | dram_info->valid_dimm = false; | ||
| 1331 | dram_info->is_16gb_dimm = false; | ||
| 1332 | dram_info->rank = I915_DRAM_RANK_INVALID; | 1326 | dram_info->rank = I915_DRAM_RANK_INVALID; |
| 1333 | dram_info->bandwidth_kbps = 0; | 1327 | dram_info->bandwidth_kbps = 0; |
| 1334 | dram_info->num_channels = 0; | 1328 | dram_info->num_channels = 0; |
| 1335 | 1329 | ||
| 1330 | /* | ||
| 1331 | * Assume 16Gb DIMMs are present until proven otherwise. | ||
| 1332 | * This is only used for the level 0 watermark latency | ||
| 1333 | * w/a which does not apply to bxt/glk. | ||
| 1334 | */ | ||
| 1335 | dram_info->is_16gb_dimm = !IS_GEN9_LP(dev_priv); | ||
| 1336 | |||
| 1336 | if (INTEL_GEN(dev_priv) < 9 || IS_GEMINILAKE(dev_priv)) | 1337 | if (INTEL_GEN(dev_priv) < 9 || IS_GEMINILAKE(dev_priv)) |
| 1337 | return; | 1338 | return; |
| 1338 | 1339 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8624b4bdc242..9102571e9692 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1948,7 +1948,6 @@ struct drm_i915_private { | |||
| 1948 | 1948 | ||
| 1949 | struct dram_info { | 1949 | struct dram_info { |
| 1950 | bool valid; | 1950 | bool valid; |
| 1951 | bool valid_dimm; | ||
| 1952 | bool is_16gb_dimm; | 1951 | bool is_16gb_dimm; |
| 1953 | u8 num_channels; | 1952 | u8 num_channels; |
| 1954 | enum dram_rank { | 1953 | enum dram_rank { |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 09187286d346..1aaccbe7e1de 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -460,7 +460,7 @@ eb_validate_vma(struct i915_execbuffer *eb, | |||
| 460 | * any non-page-aligned or non-canonical addresses. | 460 | * any non-page-aligned or non-canonical addresses. |
| 461 | */ | 461 | */ |
| 462 | if (unlikely(entry->flags & EXEC_OBJECT_PINNED && | 462 | if (unlikely(entry->flags & EXEC_OBJECT_PINNED && |
| 463 | entry->offset != gen8_canonical_addr(entry->offset & PAGE_MASK))) | 463 | entry->offset != gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK))) |
| 464 | return -EINVAL; | 464 | return -EINVAL; |
| 465 | 465 | ||
| 466 | /* pad_to_size was once a reserved field, so sanitize it */ | 466 | /* pad_to_size was once a reserved field, so sanitize it */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 56c7f8637311..47c302543799 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -1757,7 +1757,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *base, struct seq_file *m) | |||
| 1757 | if (i == 4) | 1757 | if (i == 4) |
| 1758 | continue; | 1758 | continue; |
| 1759 | 1759 | ||
| 1760 | seq_printf(m, "\t\t(%03d, %04d) %08lx: ", | 1760 | seq_printf(m, "\t\t(%03d, %04d) %08llx: ", |
| 1761 | pde, pte, | 1761 | pde, pte, |
| 1762 | (pde * GEN6_PTES + pte) * I915_GTT_PAGE_SIZE); | 1762 | (pde * GEN6_PTES + pte) * I915_GTT_PAGE_SIZE); |
| 1763 | for (i = 0; i < 4; i++) { | 1763 | for (i = 0; i < 4; i++) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 7e2af5f4f39b..28039290655c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h | |||
| @@ -42,13 +42,15 @@ | |||
| 42 | #include "i915_selftest.h" | 42 | #include "i915_selftest.h" |
| 43 | #include "i915_timeline.h" | 43 | #include "i915_timeline.h" |
| 44 | 44 | ||
| 45 | #define I915_GTT_PAGE_SIZE_4K BIT(12) | 45 | #define I915_GTT_PAGE_SIZE_4K BIT_ULL(12) |
| 46 | #define I915_GTT_PAGE_SIZE_64K BIT(16) | 46 | #define I915_GTT_PAGE_SIZE_64K BIT_ULL(16) |
| 47 | #define I915_GTT_PAGE_SIZE_2M BIT(21) | 47 | #define I915_GTT_PAGE_SIZE_2M BIT_ULL(21) |
| 48 | 48 | ||
| 49 | #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K | 49 | #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K |
| 50 | #define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M | 50 | #define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M |
| 51 | 51 | ||
| 52 | #define I915_GTT_PAGE_MASK -I915_GTT_PAGE_SIZE | ||
| 53 | |||
| 52 | #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE | 54 | #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE |
| 53 | 55 | ||
| 54 | #define I915_FENCE_REG_NONE -1 | 56 | #define I915_FENCE_REG_NONE -1 |
| @@ -659,20 +661,20 @@ int i915_gem_gtt_insert(struct i915_address_space *vm, | |||
| 659 | u64 start, u64 end, unsigned int flags); | 661 | u64 start, u64 end, unsigned int flags); |
| 660 | 662 | ||
| 661 | /* Flags used by pin/bind&friends. */ | 663 | /* Flags used by pin/bind&friends. */ |
| 662 | #define PIN_NONBLOCK BIT(0) | 664 | #define PIN_NONBLOCK BIT_ULL(0) |
| 663 | #define PIN_MAPPABLE BIT(1) | 665 | #define PIN_MAPPABLE BIT_ULL(1) |
| 664 | #define PIN_ZONE_4G BIT(2) | 666 | #define PIN_ZONE_4G BIT_ULL(2) |
| 665 | #define PIN_NONFAULT BIT(3) | 667 | #define PIN_NONFAULT BIT_ULL(3) |
| 666 | #define PIN_NOEVICT BIT(4) | 668 | #define PIN_NOEVICT BIT_ULL(4) |
| 667 | 669 | ||
| 668 | #define PIN_MBZ BIT(5) /* I915_VMA_PIN_OVERFLOW */ | 670 | #define PIN_MBZ BIT_ULL(5) /* I915_VMA_PIN_OVERFLOW */ |
| 669 | #define PIN_GLOBAL BIT(6) /* I915_VMA_GLOBAL_BIND */ | 671 | #define PIN_GLOBAL BIT_ULL(6) /* I915_VMA_GLOBAL_BIND */ |
| 670 | #define PIN_USER BIT(7) /* I915_VMA_LOCAL_BIND */ | 672 | #define PIN_USER BIT_ULL(7) /* I915_VMA_LOCAL_BIND */ |
| 671 | #define PIN_UPDATE BIT(8) | 673 | #define PIN_UPDATE BIT_ULL(8) |
| 672 | 674 | ||
| 673 | #define PIN_HIGH BIT(9) | 675 | #define PIN_HIGH BIT_ULL(9) |
| 674 | #define PIN_OFFSET_BIAS BIT(10) | 676 | #define PIN_OFFSET_BIAS BIT_ULL(10) |
| 675 | #define PIN_OFFSET_FIXED BIT(11) | 677 | #define PIN_OFFSET_FIXED BIT_ULL(11) |
| 676 | #define PIN_OFFSET_MASK (-I915_GTT_PAGE_SIZE) | 678 | #define PIN_OFFSET_MASK (-I915_GTT_PAGE_SIZE) |
| 677 | 679 | ||
| 678 | #endif | 680 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7c491ea3d052..e31c27e45734 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -2095,8 +2095,12 @@ enum i915_power_well_id { | |||
| 2095 | 2095 | ||
| 2096 | /* ICL PHY DFLEX registers */ | 2096 | /* ICL PHY DFLEX registers */ |
| 2097 | #define PORT_TX_DFLEXDPMLE1 _MMIO(0x1638C0) | 2097 | #define PORT_TX_DFLEXDPMLE1 _MMIO(0x1638C0) |
| 2098 | #define DFLEXDPMLE1_DPMLETC_MASK(n) (0xf << (4 * (n))) | 2098 | #define DFLEXDPMLE1_DPMLETC_MASK(tc_port) (0xf << (4 * (tc_port))) |
| 2099 | #define DFLEXDPMLE1_DPMLETC(n, x) ((x) << (4 * (n))) | 2099 | #define DFLEXDPMLE1_DPMLETC_ML0(tc_port) (1 << (4 * (tc_port))) |
| 2100 | #define DFLEXDPMLE1_DPMLETC_ML1_0(tc_port) (3 << (4 * (tc_port))) | ||
| 2101 | #define DFLEXDPMLE1_DPMLETC_ML3(tc_port) (8 << (4 * (tc_port))) | ||
| 2102 | #define DFLEXDPMLE1_DPMLETC_ML3_2(tc_port) (12 << (4 * (tc_port))) | ||
| 2103 | #define DFLEXDPMLE1_DPMLETC_ML3_0(tc_port) (15 << (4 * (tc_port))) | ||
| 2100 | 2104 | ||
| 2101 | /* BXT PHY Ref registers */ | 2105 | /* BXT PHY Ref registers */ |
| 2102 | #define _PORT_REF_DW3_A 0x16218C | 2106 | #define _PORT_REF_DW3_A 0x16218C |
| @@ -4593,12 +4597,12 @@ enum { | |||
| 4593 | 4597 | ||
| 4594 | #define DRM_DIP_ENABLE (1 << 28) | 4598 | #define DRM_DIP_ENABLE (1 << 28) |
| 4595 | #define PSR_VSC_BIT_7_SET (1 << 27) | 4599 | #define PSR_VSC_BIT_7_SET (1 << 27) |
| 4596 | #define VSC_SELECT_MASK (0x3 << 26) | 4600 | #define VSC_SELECT_MASK (0x3 << 25) |
| 4597 | #define VSC_SELECT_SHIFT 26 | 4601 | #define VSC_SELECT_SHIFT 25 |
| 4598 | #define VSC_DIP_HW_HEA_DATA (0 << 26) | 4602 | #define VSC_DIP_HW_HEA_DATA (0 << 25) |
| 4599 | #define VSC_DIP_HW_HEA_SW_DATA (1 << 26) | 4603 | #define VSC_DIP_HW_HEA_SW_DATA (1 << 25) |
| 4600 | #define VSC_DIP_HW_DATA_SW_HEA (2 << 26) | 4604 | #define VSC_DIP_HW_DATA_SW_HEA (2 << 25) |
| 4601 | #define VSC_DIP_SW_HEA_DATA (3 << 26) | 4605 | #define VSC_DIP_SW_HEA_DATA (3 << 25) |
| 4602 | #define VDIP_ENABLE_PPS (1 << 24) | 4606 | #define VDIP_ENABLE_PPS (1 << 24) |
| 4603 | 4607 | ||
| 4604 | /* Panel power sequencing */ | 4608 | /* Panel power sequencing */ |
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 769f3f586661..ee3ca2de983b 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c | |||
| @@ -144,6 +144,9 @@ static const struct { | |||
| 144 | /* HDMI N/CTS table */ | 144 | /* HDMI N/CTS table */ |
| 145 | #define TMDS_297M 297000 | 145 | #define TMDS_297M 297000 |
| 146 | #define TMDS_296M 296703 | 146 | #define TMDS_296M 296703 |
| 147 | #define TMDS_594M 594000 | ||
| 148 | #define TMDS_593M 593407 | ||
| 149 | |||
| 147 | static const struct { | 150 | static const struct { |
| 148 | int sample_rate; | 151 | int sample_rate; |
| 149 | int clock; | 152 | int clock; |
| @@ -164,6 +167,20 @@ static const struct { | |||
| 164 | { 176400, TMDS_297M, 18816, 247500 }, | 167 | { 176400, TMDS_297M, 18816, 247500 }, |
| 165 | { 192000, TMDS_296M, 23296, 281250 }, | 168 | { 192000, TMDS_296M, 23296, 281250 }, |
| 166 | { 192000, TMDS_297M, 20480, 247500 }, | 169 | { 192000, TMDS_297M, 20480, 247500 }, |
| 170 | { 44100, TMDS_593M, 8918, 937500 }, | ||
| 171 | { 44100, TMDS_594M, 9408, 990000 }, | ||
| 172 | { 48000, TMDS_593M, 5824, 562500 }, | ||
| 173 | { 48000, TMDS_594M, 6144, 594000 }, | ||
| 174 | { 32000, TMDS_593M, 5824, 843750 }, | ||
| 175 | { 32000, TMDS_594M, 3072, 445500 }, | ||
| 176 | { 88200, TMDS_593M, 17836, 937500 }, | ||
| 177 | { 88200, TMDS_594M, 18816, 990000 }, | ||
| 178 | { 96000, TMDS_593M, 11648, 562500 }, | ||
| 179 | { 96000, TMDS_594M, 12288, 594000 }, | ||
| 180 | { 176400, TMDS_593M, 35672, 937500 }, | ||
| 181 | { 176400, TMDS_594M, 37632, 990000 }, | ||
| 182 | { 192000, TMDS_593M, 23296, 562500 }, | ||
| 183 | { 192000, TMDS_594M, 24576, 594000 }, | ||
| 167 | }; | 184 | }; |
| 168 | 185 | ||
| 169 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ | 186 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ |
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 29075c763428..8d74276029e6 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c | |||
| @@ -2138,16 +2138,8 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv, | |||
| 2138 | static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv, | 2138 | static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv, |
| 2139 | int pixel_rate) | 2139 | int pixel_rate) |
| 2140 | { | 2140 | { |
| 2141 | if (INTEL_GEN(dev_priv) >= 10) | 2141 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
| 2142 | return DIV_ROUND_UP(pixel_rate, 2); | 2142 | return DIV_ROUND_UP(pixel_rate, 2); |
| 2143 | else if (IS_GEMINILAKE(dev_priv)) | ||
| 2144 | /* | ||
| 2145 | * FIXME: Avoid using a pixel clock that is more than 99% of the cdclk | ||
| 2146 | * as a temporary workaround. Use a higher cdclk instead. (Note that | ||
| 2147 | * intel_compute_max_dotclk() limits the max pixel clock to 99% of max | ||
| 2148 | * cdclk.) | ||
| 2149 | */ | ||
| 2150 | return DIV_ROUND_UP(pixel_rate * 100, 2 * 99); | ||
| 2151 | else if (IS_GEN9(dev_priv) || | 2143 | else if (IS_GEN9(dev_priv) || |
| 2152 | IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) | 2144 | IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) |
| 2153 | return pixel_rate; | 2145 | return pixel_rate; |
| @@ -2543,14 +2535,8 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) | |||
| 2543 | { | 2535 | { |
| 2544 | int max_cdclk_freq = dev_priv->max_cdclk_freq; | 2536 | int max_cdclk_freq = dev_priv->max_cdclk_freq; |
| 2545 | 2537 | ||
| 2546 | if (INTEL_GEN(dev_priv) >= 10) | 2538 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
| 2547 | return 2 * max_cdclk_freq; | 2539 | return 2 * max_cdclk_freq; |
| 2548 | else if (IS_GEMINILAKE(dev_priv)) | ||
| 2549 | /* | ||
| 2550 | * FIXME: Limiting to 99% as a temporary workaround. See | ||
| 2551 | * intel_min_cdclk() for details. | ||
| 2552 | */ | ||
| 2553 | return 2 * max_cdclk_freq * 99 / 100; | ||
| 2554 | else if (IS_GEN9(dev_priv) || | 2540 | else if (IS_GEN9(dev_priv) || |
| 2555 | IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) | 2541 | IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) |
| 2556 | return max_cdclk_freq; | 2542 | return max_cdclk_freq; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9741cc419e1b..23d8008a93bb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -12768,17 +12768,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 12768 | intel_check_cpu_fifo_underruns(dev_priv); | 12768 | intel_check_cpu_fifo_underruns(dev_priv); |
| 12769 | intel_check_pch_fifo_underruns(dev_priv); | 12769 | intel_check_pch_fifo_underruns(dev_priv); |
| 12770 | 12770 | ||
| 12771 | if (!new_crtc_state->active) { | 12771 | /* FIXME unify this for all platforms */ |
| 12772 | /* | 12772 | if (!new_crtc_state->active && |
| 12773 | * Make sure we don't call initial_watermarks | 12773 | !HAS_GMCH_DISPLAY(dev_priv) && |
| 12774 | * for ILK-style watermark updates. | 12774 | dev_priv->display.initial_watermarks) |
| 12775 | * | 12775 | dev_priv->display.initial_watermarks(intel_state, |
| 12776 | * No clue what this is supposed to achieve. | 12776 | to_intel_crtc_state(new_crtc_state)); |
| 12777 | */ | ||
| 12778 | if (INTEL_GEN(dev_priv) >= 9) | ||
| 12779 | dev_priv->display.initial_watermarks(intel_state, | ||
| 12780 | to_intel_crtc_state(new_crtc_state)); | ||
| 12781 | } | ||
| 12782 | } | 12777 | } |
| 12783 | } | 12778 | } |
| 12784 | 12779 | ||
| @@ -14646,7 +14641,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, | |||
| 14646 | fb->height < SKL_MIN_YUV_420_SRC_H || | 14641 | fb->height < SKL_MIN_YUV_420_SRC_H || |
| 14647 | (fb->width % 4) != 0 || (fb->height % 4) != 0)) { | 14642 | (fb->width % 4) != 0 || (fb->height % 4) != 0)) { |
| 14648 | DRM_DEBUG_KMS("src dimensions not correct for NV12\n"); | 14643 | DRM_DEBUG_KMS("src dimensions not correct for NV12\n"); |
| 14649 | return -EINVAL; | 14644 | goto err; |
| 14650 | } | 14645 | } |
| 14651 | 14646 | ||
| 14652 | for (i = 0; i < fb->format->num_planes; i++) { | 14647 | for (i = 0; i < fb->format->num_planes; i++) { |
diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index cdf19553ffac..5d5336fbe7b0 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c | |||
| @@ -297,8 +297,10 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) | |||
| 297 | lpe_audio_platdev_destroy(dev_priv); | 297 | lpe_audio_platdev_destroy(dev_priv); |
| 298 | 298 | ||
| 299 | irq_free_desc(dev_priv->lpe_audio.irq); | 299 | irq_free_desc(dev_priv->lpe_audio.irq); |
| 300 | } | ||
| 301 | 300 | ||
| 301 | dev_priv->lpe_audio.irq = -1; | ||
| 302 | dev_priv->lpe_audio.platdev = NULL; | ||
| 303 | } | ||
| 302 | 304 | ||
| 303 | /** | 305 | /** |
| 304 | * intel_lpe_audio_notify() - notify lpe audio event | 306 | * intel_lpe_audio_notify() - notify lpe audio event |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1db9b8328275..245f0022bcfd 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -2881,8 +2881,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, | |||
| 2881 | * any underrun. If not able to get Dimm info assume 16GB dimm | 2881 | * any underrun. If not able to get Dimm info assume 16GB dimm |
| 2882 | * to avoid any underrun. | 2882 | * to avoid any underrun. |
| 2883 | */ | 2883 | */ |
| 2884 | if (!dev_priv->dram_info.valid_dimm || | 2884 | if (dev_priv->dram_info.is_16gb_dimm) |
| 2885 | dev_priv->dram_info.is_16gb_dimm) | ||
| 2886 | wm[0] += 1; | 2885 | wm[0] += 1; |
| 2887 | 2886 | ||
| 2888 | } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { | 2887 | } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { |
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index 8d03f64eabd7..5c22f2c8d4cf 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c | |||
| @@ -551,7 +551,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) | |||
| 551 | err = igt_check_page_sizes(vma); | 551 | err = igt_check_page_sizes(vma); |
| 552 | 552 | ||
| 553 | if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) { | 553 | if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) { |
| 554 | pr_err("page_sizes.gtt=%u, expected %lu\n", | 554 | pr_err("page_sizes.gtt=%u, expected %llu\n", |
| 555 | vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K); | 555 | vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K); |
| 556 | err = -EINVAL; | 556 | err = -EINVAL; |
| 557 | } | 557 | } |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 8e2e269db97e..127d81513671 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | |||
| @@ -1337,7 +1337,7 @@ static int igt_gtt_reserve(void *arg) | |||
| 1337 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | 1337 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); |
| 1338 | if (vma->node.start != total || | 1338 | if (vma->node.start != total || |
| 1339 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { | 1339 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { |
| 1340 | pr_err("i915_gem_gtt_reserve (pass 1) placement failed, found (%llx + %llx), expected (%llx + %lx)\n", | 1340 | pr_err("i915_gem_gtt_reserve (pass 1) placement failed, found (%llx + %llx), expected (%llx + %llx)\n", |
| 1341 | vma->node.start, vma->node.size, | 1341 | vma->node.start, vma->node.size, |
| 1342 | total, 2*I915_GTT_PAGE_SIZE); | 1342 | total, 2*I915_GTT_PAGE_SIZE); |
| 1343 | err = -EINVAL; | 1343 | err = -EINVAL; |
| @@ -1386,7 +1386,7 @@ static int igt_gtt_reserve(void *arg) | |||
| 1386 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | 1386 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); |
| 1387 | if (vma->node.start != total || | 1387 | if (vma->node.start != total || |
| 1388 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { | 1388 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { |
| 1389 | pr_err("i915_gem_gtt_reserve (pass 2) placement failed, found (%llx + %llx), expected (%llx + %lx)\n", | 1389 | pr_err("i915_gem_gtt_reserve (pass 2) placement failed, found (%llx + %llx), expected (%llx + %llx)\n", |
| 1390 | vma->node.start, vma->node.size, | 1390 | vma->node.start, vma->node.size, |
| 1391 | total, 2*I915_GTT_PAGE_SIZE); | 1391 | total, 2*I915_GTT_PAGE_SIZE); |
| 1392 | err = -EINVAL; | 1392 | err = -EINVAL; |
| @@ -1430,7 +1430,7 @@ static int igt_gtt_reserve(void *arg) | |||
| 1430 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | 1430 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); |
| 1431 | if (vma->node.start != offset || | 1431 | if (vma->node.start != offset || |
| 1432 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { | 1432 | vma->node.size != 2*I915_GTT_PAGE_SIZE) { |
| 1433 | pr_err("i915_gem_gtt_reserve (pass 3) placement failed, found (%llx + %llx), expected (%llx + %lx)\n", | 1433 | pr_err("i915_gem_gtt_reserve (pass 3) placement failed, found (%llx + %llx), expected (%llx + %llx)\n", |
| 1434 | vma->node.start, vma->node.size, | 1434 | vma->node.start, vma->node.size, |
| 1435 | offset, 2*I915_GTT_PAGE_SIZE); | 1435 | offset, 2*I915_GTT_PAGE_SIZE); |
| 1436 | err = -EINVAL; | 1436 | err = -EINVAL; |
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c index af7dcb6da351..e7eb0d1e17be 100644 --- a/drivers/gpu/drm/sun4i/sun4i_lvds.c +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c | |||
| @@ -75,7 +75,7 @@ static void sun4i_lvds_encoder_enable(struct drm_encoder *encoder) | |||
| 75 | 75 | ||
| 76 | DRM_DEBUG_DRIVER("Enabling LVDS output\n"); | 76 | DRM_DEBUG_DRIVER("Enabling LVDS output\n"); |
| 77 | 77 | ||
| 78 | if (!IS_ERR(tcon->panel)) { | 78 | if (tcon->panel) { |
| 79 | drm_panel_prepare(tcon->panel); | 79 | drm_panel_prepare(tcon->panel); |
| 80 | drm_panel_enable(tcon->panel); | 80 | drm_panel_enable(tcon->panel); |
| 81 | } | 81 | } |
| @@ -88,7 +88,7 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder) | |||
| 88 | 88 | ||
| 89 | DRM_DEBUG_DRIVER("Disabling LVDS output\n"); | 89 | DRM_DEBUG_DRIVER("Disabling LVDS output\n"); |
| 90 | 90 | ||
| 91 | if (!IS_ERR(tcon->panel)) { | 91 | if (tcon->panel) { |
| 92 | drm_panel_disable(tcon->panel); | 92 | drm_panel_disable(tcon->panel); |
| 93 | drm_panel_unprepare(tcon->panel); | 93 | drm_panel_unprepare(tcon->panel); |
| 94 | } | 94 | } |
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index bf068da6b12e..f4a22689eb54 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c | |||
| @@ -135,7 +135,7 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder) | |||
| 135 | 135 | ||
| 136 | DRM_DEBUG_DRIVER("Enabling RGB output\n"); | 136 | DRM_DEBUG_DRIVER("Enabling RGB output\n"); |
| 137 | 137 | ||
| 138 | if (!IS_ERR(tcon->panel)) { | 138 | if (tcon->panel) { |
| 139 | drm_panel_prepare(tcon->panel); | 139 | drm_panel_prepare(tcon->panel); |
| 140 | drm_panel_enable(tcon->panel); | 140 | drm_panel_enable(tcon->panel); |
| 141 | } | 141 | } |
| @@ -148,7 +148,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) | |||
| 148 | 148 | ||
| 149 | DRM_DEBUG_DRIVER("Disabling RGB output\n"); | 149 | DRM_DEBUG_DRIVER("Disabling RGB output\n"); |
| 150 | 150 | ||
| 151 | if (!IS_ERR(tcon->panel)) { | 151 | if (tcon->panel) { |
| 152 | drm_panel_disable(tcon->panel); | 152 | drm_panel_disable(tcon->panel); |
| 153 | drm_panel_unprepare(tcon->panel); | 153 | drm_panel_unprepare(tcon->panel); |
| 154 | } | 154 | } |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index c78cd35a1294..f949287d926c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | |||
| @@ -491,7 +491,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, | |||
| 491 | sun4i_tcon0_mode_set_common(tcon, mode); | 491 | sun4i_tcon0_mode_set_common(tcon, mode); |
| 492 | 492 | ||
| 493 | /* Set dithering if needed */ | 493 | /* Set dithering if needed */ |
| 494 | sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); | 494 | if (tcon->panel) |
| 495 | sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); | ||
| 495 | 496 | ||
| 496 | /* Adjust clock delay */ | 497 | /* Adjust clock delay */ |
| 497 | clk_delay = sun4i_tcon_get_clk_delay(mode, 0); | 498 | clk_delay = sun4i_tcon_get_clk_delay(mode, 0); |
| @@ -555,7 +556,7 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, | |||
| 555 | * Following code is a way to avoid quirks all around TCON | 556 | * Following code is a way to avoid quirks all around TCON |
| 556 | * and DOTCLOCK drivers. | 557 | * and DOTCLOCK drivers. |
| 557 | */ | 558 | */ |
| 558 | if (!IS_ERR(tcon->panel)) { | 559 | if (tcon->panel) { |
| 559 | struct drm_panel *panel = tcon->panel; | 560 | struct drm_panel *panel = tcon->panel; |
| 560 | struct drm_connector *connector = panel->connector; | 561 | struct drm_connector *connector = panel->connector; |
| 561 | struct drm_display_info display_info = connector->display_info; | 562 | struct drm_display_info display_info = connector->display_info; |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index cf2a18571d48..a132c37d7334 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
| @@ -380,6 +380,9 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev, | |||
| 380 | mutex_unlock(&vgasr_mutex); | 380 | mutex_unlock(&vgasr_mutex); |
| 381 | return -EINVAL; | 381 | return -EINVAL; |
| 382 | } | 382 | } |
| 383 | /* notify if GPU has been already bound */ | ||
| 384 | if (ops->gpu_bound) | ||
| 385 | ops->gpu_bound(pdev, id); | ||
| 383 | } | 386 | } |
| 384 | mutex_unlock(&vgasr_mutex); | 387 | mutex_unlock(&vgasr_mutex); |
| 385 | 388 | ||
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c index aec253b44156..3cd7229b6e54 100644 --- a/drivers/hid/hid-alps.c +++ b/drivers/hid/hid-alps.c | |||
| @@ -660,6 +660,20 @@ exit: | |||
| 660 | return ret; | 660 | return ret; |
| 661 | } | 661 | } |
| 662 | 662 | ||
| 663 | static int alps_sp_open(struct input_dev *dev) | ||
| 664 | { | ||
| 665 | struct hid_device *hid = input_get_drvdata(dev); | ||
| 666 | |||
| 667 | return hid_hw_open(hid); | ||
| 668 | } | ||
| 669 | |||
| 670 | static void alps_sp_close(struct input_dev *dev) | ||
| 671 | { | ||
| 672 | struct hid_device *hid = input_get_drvdata(dev); | ||
| 673 | |||
| 674 | hid_hw_close(hid); | ||
| 675 | } | ||
| 676 | |||
| 663 | static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) | 677 | static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) |
| 664 | { | 678 | { |
| 665 | struct alps_dev *data = hid_get_drvdata(hdev); | 679 | struct alps_dev *data = hid_get_drvdata(hdev); |
| @@ -733,6 +747,10 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) | |||
| 733 | input2->id.version = input->id.version; | 747 | input2->id.version = input->id.version; |
| 734 | input2->dev.parent = input->dev.parent; | 748 | input2->dev.parent = input->dev.parent; |
| 735 | 749 | ||
| 750 | input_set_drvdata(input2, hdev); | ||
| 751 | input2->open = alps_sp_open; | ||
| 752 | input2->close = alps_sp_close; | ||
| 753 | |||
| 736 | __set_bit(EV_KEY, input2->evbit); | 754 | __set_bit(EV_KEY, input2->evbit); |
| 737 | data->sp_btn_cnt = (data->sp_btn_info & 0x0F); | 755 | data->sp_btn_cnt = (data->sp_btn_info & 0x0F); |
| 738 | for (i = 0; i < data->sp_btn_cnt; i++) | 756 | for (i = 0; i < data->sp_btn_cnt; i++) |
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index dc6d6477e961..a1fa2fc8c9b5 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c | |||
| @@ -359,6 +359,9 @@ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) | |||
| 359 | u32 value; | 359 | u32 value; |
| 360 | int ret; | 360 | int ret; |
| 361 | 361 | ||
| 362 | if (!IS_ENABLED(CONFIG_ASUS_WMI)) | ||
| 363 | return false; | ||
| 364 | |||
| 362 | ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, | 365 | ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, |
| 363 | ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); | 366 | ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); |
| 364 | hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); | 367 | hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f63489c882bb..c0d668944dbe 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -927,6 +927,9 @@ | |||
| 927 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003 | 927 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003 |
| 928 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 | 928 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 |
| 929 | 929 | ||
| 930 | #define I2C_VENDOR_ID_RAYDIUM 0x2386 | ||
| 931 | #define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33 | ||
| 932 | |||
| 930 | #define USB_VENDOR_ID_RAZER 0x1532 | 933 | #define USB_VENDOR_ID_RAZER 0x1532 |
| 931 | #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D | 934 | #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D |
| 932 | 935 | ||
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 52c3b01917e7..8237dd86fb17 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c | |||
| @@ -107,7 +107,6 @@ static const struct hid_device_id hid_quirks[] = { | |||
| 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, |
| 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, |
| 109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, | 109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, |
| 110 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS), HID_QUIRK_NOGET }, | ||
| 111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, | 110 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, |
| 112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, | 111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 113 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, | 112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 4aab96cf0818..3cde7c1b9c33 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) | 49 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) |
| 50 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) | 50 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
| 51 | #define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) | 51 | #define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) |
| 52 | #define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3) | ||
| 52 | 53 | ||
| 53 | /* flags */ | 54 | /* flags */ |
| 54 | #define I2C_HID_STARTED 0 | 55 | #define I2C_HID_STARTED 0 |
| @@ -158,6 +159,8 @@ struct i2c_hid { | |||
| 158 | 159 | ||
| 159 | bool irq_wake_enabled; | 160 | bool irq_wake_enabled; |
| 160 | struct mutex reset_lock; | 161 | struct mutex reset_lock; |
| 162 | |||
| 163 | unsigned long sleep_delay; | ||
| 161 | }; | 164 | }; |
| 162 | 165 | ||
| 163 | static const struct i2c_hid_quirks { | 166 | static const struct i2c_hid_quirks { |
| @@ -172,6 +175,8 @@ static const struct i2c_hid_quirks { | |||
| 172 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, | 175 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, |
| 173 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | | 176 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | |
| 174 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | 177 | I2C_HID_QUIRK_NO_RUNTIME_PM }, |
| 178 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, | ||
| 179 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, | ||
| 175 | { 0, 0 } | 180 | { 0, 0 } |
| 176 | }; | 181 | }; |
| 177 | 182 | ||
| @@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) | |||
| 387 | { | 392 | { |
| 388 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 393 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
| 389 | int ret; | 394 | int ret; |
| 395 | unsigned long now, delay; | ||
| 390 | 396 | ||
| 391 | i2c_hid_dbg(ihid, "%s\n", __func__); | 397 | i2c_hid_dbg(ihid, "%s\n", __func__); |
| 392 | 398 | ||
| @@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) | |||
| 404 | goto set_pwr_exit; | 410 | goto set_pwr_exit; |
| 405 | } | 411 | } |
| 406 | 412 | ||
| 413 | if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && | ||
| 414 | power_state == I2C_HID_PWR_ON) { | ||
| 415 | now = jiffies; | ||
| 416 | if (time_after(ihid->sleep_delay, now)) { | ||
| 417 | delay = jiffies_to_usecs(ihid->sleep_delay - now); | ||
| 418 | usleep_range(delay, delay + 1); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 407 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, | 422 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, |
| 408 | 0, NULL, 0, NULL, 0); | 423 | 0, NULL, 0, NULL, 0); |
| 409 | 424 | ||
| 425 | if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && | ||
| 426 | power_state == I2C_HID_PWR_SLEEP) | ||
| 427 | ihid->sleep_delay = jiffies + msecs_to_jiffies(20); | ||
| 428 | |||
| 410 | if (ret) | 429 | if (ret) |
| 411 | dev_err(&client->dev, "failed to change power setting.\n"); | 430 | dev_err(&client->dev, "failed to change power setting.\n"); |
| 412 | 431 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index cac262a912c1..89f2976f9c53 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | |||
| @@ -331,6 +331,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { | |||
| 331 | .driver_data = (void *)&sipodev_desc | 331 | .driver_data = (void *)&sipodev_desc |
| 332 | }, | 332 | }, |
| 333 | { | 333 | { |
| 334 | .ident = "Direkt-Tek DTLAPY133-1", | ||
| 335 | .matches = { | ||
| 336 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), | ||
| 337 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"), | ||
| 338 | }, | ||
| 339 | .driver_data = (void *)&sipodev_desc | ||
| 340 | }, | ||
| 341 | { | ||
| 334 | .ident = "Mediacom Flexbook Edge 11", | 342 | .ident = "Mediacom Flexbook Edge 11", |
| 335 | .matches = { | 343 | .matches = { |
| 336 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), | 344 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 23872d08308c..a746017fac17 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
| @@ -512,14 +512,24 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
| 512 | if (cmd == HIDIOCGCOLLECTIONINDEX) { | 512 | if (cmd == HIDIOCGCOLLECTIONINDEX) { |
| 513 | if (uref->usage_index >= field->maxusage) | 513 | if (uref->usage_index >= field->maxusage) |
| 514 | goto inval; | 514 | goto inval; |
| 515 | uref->usage_index = | ||
| 516 | array_index_nospec(uref->usage_index, | ||
| 517 | field->maxusage); | ||
| 515 | } else if (uref->usage_index >= field->report_count) | 518 | } else if (uref->usage_index >= field->report_count) |
| 516 | goto inval; | 519 | goto inval; |
| 517 | } | 520 | } |
| 518 | 521 | ||
| 519 | if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) && | 522 | if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { |
| 520 | (uref_multi->num_values > HID_MAX_MULTI_USAGES || | 523 | if (uref_multi->num_values > HID_MAX_MULTI_USAGES || |
| 521 | uref->usage_index + uref_multi->num_values > field->report_count)) | 524 | uref->usage_index + uref_multi->num_values > |
| 522 | goto inval; | 525 | field->report_count) |
| 526 | goto inval; | ||
| 527 | |||
| 528 | uref->usage_index = | ||
| 529 | array_index_nospec(uref->usage_index, | ||
| 530 | field->report_count - | ||
| 531 | uref_multi->num_values); | ||
| 532 | } | ||
| 523 | 533 | ||
| 524 | switch (cmd) { | 534 | switch (cmd) { |
| 525 | case HIDIOCGUSAGE: | 535 | case HIDIOCGUSAGE: |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 975c95169884..84f61cec6319 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
| @@ -649,8 +649,10 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, | |||
| 649 | if (info[i]->config[j] & HWMON_T_INPUT) { | 649 | if (info[i]->config[j] & HWMON_T_INPUT) { |
| 650 | err = hwmon_thermal_add_sensor(dev, | 650 | err = hwmon_thermal_add_sensor(dev, |
| 651 | hwdev, j); | 651 | hwdev, j); |
| 652 | if (err) | 652 | if (err) { |
| 653 | goto free_device; | 653 | device_unregister(hdev); |
| 654 | goto ida_remove; | ||
| 655 | } | ||
| 654 | } | 656 | } |
| 655 | } | 657 | } |
| 656 | } | 658 | } |
| @@ -658,8 +660,6 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, | |||
| 658 | 660 | ||
| 659 | return hdev; | 661 | return hdev; |
| 660 | 662 | ||
| 661 | free_device: | ||
| 662 | device_unregister(hdev); | ||
| 663 | free_hwmon: | 663 | free_hwmon: |
| 664 | kfree(hwdev); | 664 | kfree(hwdev); |
| 665 | ida_remove: | 665 | ida_remove: |
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index 0ccca87f5271..293dd1c6c7b3 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c | |||
| @@ -181,7 +181,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *devattr, | |||
| 181 | return sprintf(buf, "%s\n", sdata->label); | 181 | return sprintf(buf, "%s\n", sdata->label); |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | static int __init get_logical_cpu(int hwcpu) | 184 | static int get_logical_cpu(int hwcpu) |
| 185 | { | 185 | { |
| 186 | int cpu; | 186 | int cpu; |
| 187 | 187 | ||
| @@ -192,9 +192,8 @@ static int __init get_logical_cpu(int hwcpu) | |||
| 192 | return -ENOENT; | 192 | return -ENOENT; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static void __init make_sensor_label(struct device_node *np, | 195 | static void make_sensor_label(struct device_node *np, |
| 196 | struct sensor_data *sdata, | 196 | struct sensor_data *sdata, const char *label) |
| 197 | const char *label) | ||
| 198 | { | 197 | { |
| 199 | u32 id; | 198 | u32 id; |
| 200 | size_t n; | 199 | size_t n; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 56ccb1ea7da5..f2c681971201 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -224,6 +224,15 @@ config I2C_NFORCE2_S4985 | |||
| 224 | This driver can also be built as a module. If so, the module | 224 | This driver can also be built as a module. If so, the module |
| 225 | will be called i2c-nforce2-s4985. | 225 | will be called i2c-nforce2-s4985. |
| 226 | 226 | ||
| 227 | config I2C_NVIDIA_GPU | ||
| 228 | tristate "NVIDIA GPU I2C controller" | ||
| 229 | depends on PCI | ||
| 230 | help | ||
| 231 | If you say yes to this option, support will be included for the | ||
| 232 | NVIDIA GPU I2C controller which is used to communicate with the GPU's | ||
| 233 | Type-C controller. This driver can also be built as a module called | ||
| 234 | i2c-nvidia-gpu. | ||
| 235 | |||
| 227 | config I2C_SIS5595 | 236 | config I2C_SIS5595 |
| 228 | tristate "SiS 5595" | 237 | tristate "SiS 5595" |
| 229 | depends on PCI | 238 | depends on PCI |
| @@ -752,7 +761,7 @@ config I2C_OCORES | |||
| 752 | 761 | ||
| 753 | config I2C_OMAP | 762 | config I2C_OMAP |
| 754 | tristate "OMAP I2C adapter" | 763 | tristate "OMAP I2C adapter" |
| 755 | depends on ARCH_OMAP | 764 | depends on ARCH_OMAP || ARCH_K3 |
| 756 | default y if MACH_OMAP_H3 || MACH_OMAP_OSK | 765 | default y if MACH_OMAP_H3 || MACH_OMAP_OSK |
| 757 | help | 766 | help |
| 758 | If you say yes to this option, support will be included for the | 767 | If you say yes to this option, support will be included for the |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 18b26af82b1c..5f0cb6915969 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
| @@ -19,6 +19,7 @@ obj-$(CONFIG_I2C_ISCH) += i2c-isch.o | |||
| 19 | obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o | 19 | obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o |
| 20 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o | 20 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o |
| 21 | obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o | 21 | obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o |
| 22 | obj-$(CONFIG_I2C_NVIDIA_GPU) += i2c-nvidia-gpu.o | ||
| 22 | obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o | 23 | obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o |
| 23 | obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o | 24 | obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o |
| 24 | obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o | 25 | obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o |
diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c new file mode 100644 index 000000000000..8822357bca0c --- /dev/null +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c | |||
| @@ -0,0 +1,368 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Nvidia GPU I2C controller Driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. | ||
| 6 | * Author: Ajay Gupta <ajayg@nvidia.com> | ||
| 7 | */ | ||
| 8 | #include <linux/delay.h> | ||
| 9 | #include <linux/i2c.h> | ||
| 10 | #include <linux/interrupt.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/pci.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/pm.h> | ||
| 15 | #include <linux/pm_runtime.h> | ||
| 16 | |||
| 17 | #include <asm/unaligned.h> | ||
| 18 | |||
| 19 | /* I2C definitions */ | ||
| 20 | #define I2C_MST_CNTL 0x00 | ||
| 21 | #define I2C_MST_CNTL_GEN_START BIT(0) | ||
| 22 | #define I2C_MST_CNTL_GEN_STOP BIT(1) | ||
| 23 | #define I2C_MST_CNTL_CMD_READ (1 << 2) | ||
| 24 | #define I2C_MST_CNTL_CMD_WRITE (2 << 2) | ||
| 25 | #define I2C_MST_CNTL_BURST_SIZE_SHIFT 6 | ||
| 26 | #define I2C_MST_CNTL_GEN_NACK BIT(28) | ||
| 27 | #define I2C_MST_CNTL_STATUS GENMASK(30, 29) | ||
| 28 | #define I2C_MST_CNTL_STATUS_OKAY (0 << 29) | ||
| 29 | #define I2C_MST_CNTL_STATUS_NO_ACK (1 << 29) | ||
| 30 | #define I2C_MST_CNTL_STATUS_TIMEOUT (2 << 29) | ||
| 31 | #define I2C_MST_CNTL_STATUS_BUS_BUSY (3 << 29) | ||
| 32 | #define I2C_MST_CNTL_CYCLE_TRIGGER BIT(31) | ||
| 33 | |||
| 34 | #define I2C_MST_ADDR 0x04 | ||
| 35 | |||
| 36 | #define I2C_MST_I2C0_TIMING 0x08 | ||
| 37 | #define I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ 0x10e | ||
| 38 | #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT 16 | ||
| 39 | #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX 255 | ||
| 40 | #define I2C_MST_I2C0_TIMING_TIMEOUT_CHECK BIT(24) | ||
| 41 | |||
| 42 | #define I2C_MST_DATA 0x0c | ||
| 43 | |||
| 44 | #define I2C_MST_HYBRID_PADCTL 0x20 | ||
| 45 | #define I2C_MST_HYBRID_PADCTL_MODE_I2C BIT(0) | ||
| 46 | #define I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV BIT(14) | ||
| 47 | #define I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV BIT(15) | ||
| 48 | |||
| 49 | struct gpu_i2c_dev { | ||
| 50 | struct device *dev; | ||
| 51 | void __iomem *regs; | ||
| 52 | struct i2c_adapter adapter; | ||
| 53 | struct i2c_board_info *gpu_ccgx_ucsi; | ||
| 54 | }; | ||
| 55 | |||
| 56 | static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd) | ||
| 57 | { | ||
| 58 | u32 val; | ||
| 59 | |||
| 60 | /* enable I2C */ | ||
| 61 | val = readl(i2cd->regs + I2C_MST_HYBRID_PADCTL); | ||
| 62 | val |= I2C_MST_HYBRID_PADCTL_MODE_I2C | | ||
| 63 | I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV | | ||
| 64 | I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV; | ||
| 65 | writel(val, i2cd->regs + I2C_MST_HYBRID_PADCTL); | ||
| 66 | |||
| 67 | /* enable 100KHZ mode */ | ||
| 68 | val = I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ; | ||
| 69 | val |= (I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX | ||
| 70 | << I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT); | ||
| 71 | val |= I2C_MST_I2C0_TIMING_TIMEOUT_CHECK; | ||
| 72 | writel(val, i2cd->regs + I2C_MST_I2C0_TIMING); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd) | ||
| 76 | { | ||
| 77 | unsigned long target = jiffies + msecs_to_jiffies(1000); | ||
| 78 | u32 val; | ||
| 79 | |||
| 80 | do { | ||
| 81 | val = readl(i2cd->regs + I2C_MST_CNTL); | ||
| 82 | if (!(val & I2C_MST_CNTL_CYCLE_TRIGGER)) | ||
| 83 | break; | ||
| 84 | if ((val & I2C_MST_CNTL_STATUS) != | ||
| 85 | I2C_MST_CNTL_STATUS_BUS_BUSY) | ||
| 86 | break; | ||
| 87 | usleep_range(500, 600); | ||
| 88 | } while (time_is_after_jiffies(target)); | ||
| 89 | |||
| 90 | if (time_is_before_jiffies(target)) { | ||
| 91 | dev_err(i2cd->dev, "i2c timeout error %x\n", val); | ||
| 92 | return -ETIME; | ||
| 93 | } | ||
| 94 | |||
| 95 | val = readl(i2cd->regs + I2C_MST_CNTL); | ||
| 96 | switch (val & I2C_MST_CNTL_STATUS) { | ||
| 97 | case I2C_MST_CNTL_STATUS_OKAY: | ||
| 98 | return 0; | ||
| 99 | case I2C_MST_CNTL_STATUS_NO_ACK: | ||
| 100 | return -EIO; | ||
| 101 | case I2C_MST_CNTL_STATUS_TIMEOUT: | ||
| 102 | return -ETIME; | ||
| 103 | default: | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len) | ||
| 109 | { | ||
| 110 | int status; | ||
| 111 | u32 val; | ||
| 112 | |||
| 113 | val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ | | ||
| 114 | (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) | | ||
| 115 | I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK; | ||
| 116 | writel(val, i2cd->regs + I2C_MST_CNTL); | ||
| 117 | |||
| 118 | status = gpu_i2c_check_status(i2cd); | ||
| 119 | if (status < 0) | ||
| 120 | return status; | ||
| 121 | |||
| 122 | val = readl(i2cd->regs + I2C_MST_DATA); | ||
| 123 | switch (len) { | ||
| 124 | case 1: | ||
| 125 | data[0] = val; | ||
| 126 | break; | ||
| 127 | case 2: | ||
| 128 | put_unaligned_be16(val, data); | ||
| 129 | break; | ||
| 130 | case 3: | ||
| 131 | put_unaligned_be16(val >> 8, data); | ||
| 132 | data[2] = val; | ||
| 133 | break; | ||
| 134 | case 4: | ||
| 135 | put_unaligned_be32(val, data); | ||
| 136 | break; | ||
| 137 | default: | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | return status; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int gpu_i2c_start(struct gpu_i2c_dev *i2cd) | ||
| 144 | { | ||
| 145 | writel(I2C_MST_CNTL_GEN_START, i2cd->regs + I2C_MST_CNTL); | ||
| 146 | return gpu_i2c_check_status(i2cd); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int gpu_i2c_stop(struct gpu_i2c_dev *i2cd) | ||
| 150 | { | ||
| 151 | writel(I2C_MST_CNTL_GEN_STOP, i2cd->regs + I2C_MST_CNTL); | ||
| 152 | return gpu_i2c_check_status(i2cd); | ||
| 153 | } | ||
| 154 | |||
| 155 | static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data) | ||
| 156 | { | ||
| 157 | u32 val; | ||
| 158 | |||
| 159 | writel(data, i2cd->regs + I2C_MST_DATA); | ||
| 160 | |||
| 161 | val = I2C_MST_CNTL_CMD_WRITE | (1 << I2C_MST_CNTL_BURST_SIZE_SHIFT); | ||
| 162 | writel(val, i2cd->regs + I2C_MST_CNTL); | ||
| 163 | |||
| 164 | return gpu_i2c_check_status(i2cd); | ||
| 165 | } | ||
| 166 | |||
| 167 | static int gpu_i2c_master_xfer(struct i2c_adapter *adap, | ||
| 168 | struct i2c_msg *msgs, int num) | ||
| 169 | { | ||
| 170 | struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap); | ||
| 171 | int status, status2; | ||
| 172 | int i, j; | ||
| 173 | |||
| 174 | /* | ||
| 175 | * The controller supports maximum 4 byte read due to known | ||
| 176 | * limitation of sending STOP after every read. | ||
| 177 | */ | ||
| 178 | for (i = 0; i < num; i++) { | ||
| 179 | if (msgs[i].flags & I2C_M_RD) { | ||
| 180 | /* program client address before starting read */ | ||
| 181 | writel(msgs[i].addr, i2cd->regs + I2C_MST_ADDR); | ||
| 182 | /* gpu_i2c_read has implicit start */ | ||
| 183 | status = gpu_i2c_read(i2cd, msgs[i].buf, msgs[i].len); | ||
| 184 | if (status < 0) | ||
| 185 | goto stop; | ||
| 186 | } else { | ||
| 187 | u8 addr = i2c_8bit_addr_from_msg(msgs + i); | ||
| 188 | |||
| 189 | status = gpu_i2c_start(i2cd); | ||
| 190 | if (status < 0) { | ||
| 191 | if (i == 0) | ||
| 192 | return status; | ||
| 193 | goto stop; | ||
| 194 | } | ||
| 195 | |||
| 196 | status = gpu_i2c_write(i2cd, addr); | ||
| 197 | if (status < 0) | ||
| 198 | goto stop; | ||
| 199 | |||
| 200 | for (j = 0; j < msgs[i].len; j++) { | ||
| 201 | status = gpu_i2c_write(i2cd, msgs[i].buf[j]); | ||
| 202 | if (status < 0) | ||
| 203 | goto stop; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | status = gpu_i2c_stop(i2cd); | ||
| 208 | if (status < 0) | ||
| 209 | return status; | ||
| 210 | |||
| 211 | return i; | ||
| 212 | stop: | ||
| 213 | status2 = gpu_i2c_stop(i2cd); | ||
| 214 | if (status2 < 0) | ||
| 215 | dev_err(i2cd->dev, "i2c stop failed %d\n", status2); | ||
| 216 | return status; | ||
| 217 | } | ||
| 218 | |||
| 219 | static const struct i2c_adapter_quirks gpu_i2c_quirks = { | ||
| 220 | .max_read_len = 4, | ||
| 221 | .flags = I2C_AQ_COMB_WRITE_THEN_READ, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static u32 gpu_i2c_functionality(struct i2c_adapter *adap) | ||
| 225 | { | ||
| 226 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
| 227 | } | ||
| 228 | |||
| 229 | static const struct i2c_algorithm gpu_i2c_algorithm = { | ||
| 230 | .master_xfer = gpu_i2c_master_xfer, | ||
| 231 | .functionality = gpu_i2c_functionality, | ||
| 232 | }; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * This driver is for Nvidia GPU cards with USB Type-C interface. | ||
| 236 | * We want to identify the cards using vendor ID and class code only | ||
| 237 | * to avoid dependency of adding product id for any new card which | ||
| 238 | * requires this driver. | ||
| 239 | * Currently there is no class code defined for UCSI device over PCI | ||
| 240 | * so using UNKNOWN class for now and it will be updated when UCSI | ||
| 241 | * over PCI gets a class code. | ||
| 242 | * There is no other NVIDIA cards with UNKNOWN class code. Even if the | ||
| 243 | * driver gets loaded for an undesired card then eventually i2c_read() | ||
| 244 | * (initiated from UCSI i2c_client) will timeout or UCSI commands will | ||
| 245 | * timeout. | ||
| 246 | */ | ||
| 247 | #define PCI_CLASS_SERIAL_UNKNOWN 0x0c80 | ||
| 248 | static const struct pci_device_id gpu_i2c_ids[] = { | ||
| 249 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 250 | PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00}, | ||
| 251 | { } | ||
| 252 | }; | ||
| 253 | MODULE_DEVICE_TABLE(pci, gpu_i2c_ids); | ||
| 254 | |||
| 255 | static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq) | ||
| 256 | { | ||
| 257 | struct i2c_client *ccgx_client; | ||
| 258 | |||
| 259 | i2cd->gpu_ccgx_ucsi = devm_kzalloc(i2cd->dev, | ||
| 260 | sizeof(*i2cd->gpu_ccgx_ucsi), | ||
| 261 | GFP_KERNEL); | ||
| 262 | if (!i2cd->gpu_ccgx_ucsi) | ||
| 263 | return -ENOMEM; | ||
| 264 | |||
| 265 | strlcpy(i2cd->gpu_ccgx_ucsi->type, "ccgx-ucsi", | ||
| 266 | sizeof(i2cd->gpu_ccgx_ucsi->type)); | ||
| 267 | i2cd->gpu_ccgx_ucsi->addr = 0x8; | ||
| 268 | i2cd->gpu_ccgx_ucsi->irq = irq; | ||
| 269 | ccgx_client = i2c_new_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi); | ||
| 270 | if (!ccgx_client) | ||
| 271 | return -ENODEV; | ||
| 272 | |||
| 273 | return 0; | ||
| 274 | } | ||
| 275 | |||
| 276 | static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
| 277 | { | ||
| 278 | struct gpu_i2c_dev *i2cd; | ||
| 279 | int status; | ||
| 280 | |||
| 281 | i2cd = devm_kzalloc(&pdev->dev, sizeof(*i2cd), GFP_KERNEL); | ||
| 282 | if (!i2cd) | ||
| 283 | return -ENOMEM; | ||
| 284 | |||
| 285 | i2cd->dev = &pdev->dev; | ||
| 286 | dev_set_drvdata(&pdev->dev, i2cd); | ||
| 287 | |||
| 288 | status = pcim_enable_device(pdev); | ||
| 289 | if (status < 0) { | ||
| 290 | dev_err(&pdev->dev, "pcim_enable_device failed %d\n", status); | ||
| 291 | return status; | ||
| 292 | } | ||
| 293 | |||
| 294 | pci_set_master(pdev); | ||
| 295 | |||
| 296 | i2cd->regs = pcim_iomap(pdev, 0, 0); | ||
| 297 | if (!i2cd->regs) { | ||
| 298 | dev_err(&pdev->dev, "pcim_iomap failed\n"); | ||
| 299 | return -ENOMEM; | ||
| 300 | } | ||
| 301 | |||
| 302 | status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); | ||
| 303 | if (status < 0) { | ||
| 304 | dev_err(&pdev->dev, "pci_alloc_irq_vectors err %d\n", status); | ||
| 305 | return status; | ||
| 306 | } | ||
| 307 | |||
| 308 | gpu_enable_i2c_bus(i2cd); | ||
| 309 | |||
| 310 | i2c_set_adapdata(&i2cd->adapter, i2cd); | ||
| 311 | i2cd->adapter.owner = THIS_MODULE; | ||
| 312 | strlcpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter", | ||
| 313 | sizeof(i2cd->adapter.name)); | ||
| 314 | i2cd->adapter.algo = &gpu_i2c_algorithm; | ||
| 315 | i2cd->adapter.quirks = &gpu_i2c_quirks; | ||
| 316 | i2cd->adapter.dev.parent = &pdev->dev; | ||
| 317 | status = i2c_add_adapter(&i2cd->adapter); | ||
| 318 | if (status < 0) | ||
| 319 | goto free_irq_vectors; | ||
| 320 | |||
| 321 | status = gpu_populate_client(i2cd, pdev->irq); | ||
| 322 | if (status < 0) { | ||
| 323 | dev_err(&pdev->dev, "gpu_populate_client failed %d\n", status); | ||
| 324 | goto del_adapter; | ||
| 325 | } | ||
| 326 | |||
| 327 | return 0; | ||
| 328 | |||
| 329 | del_adapter: | ||
| 330 | i2c_del_adapter(&i2cd->adapter); | ||
| 331 | free_irq_vectors: | ||
| 332 | pci_free_irq_vectors(pdev); | ||
| 333 | return status; | ||
| 334 | } | ||
| 335 | |||
| 336 | static void gpu_i2c_remove(struct pci_dev *pdev) | ||
| 337 | { | ||
| 338 | struct gpu_i2c_dev *i2cd = dev_get_drvdata(&pdev->dev); | ||
| 339 | |||
| 340 | i2c_del_adapter(&i2cd->adapter); | ||
| 341 | pci_free_irq_vectors(pdev); | ||
| 342 | } | ||
| 343 | |||
| 344 | static int gpu_i2c_resume(struct device *dev) | ||
| 345 | { | ||
| 346 | struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev); | ||
| 347 | |||
| 348 | gpu_enable_i2c_bus(i2cd); | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | static UNIVERSAL_DEV_PM_OPS(gpu_i2c_driver_pm, NULL, gpu_i2c_resume, NULL); | ||
| 353 | |||
| 354 | static struct pci_driver gpu_i2c_driver = { | ||
| 355 | .name = "nvidia-gpu", | ||
| 356 | .id_table = gpu_i2c_ids, | ||
| 357 | .probe = gpu_i2c_probe, | ||
| 358 | .remove = gpu_i2c_remove, | ||
| 359 | .driver = { | ||
| 360 | .pm = &gpu_i2c_driver_pm, | ||
| 361 | }, | ||
| 362 | }; | ||
| 363 | |||
| 364 | module_pci_driver(gpu_i2c_driver); | ||
| 365 | |||
| 366 | MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>"); | ||
| 367 | MODULE_DESCRIPTION("Nvidia GPU I2C controller Driver"); | ||
| 368 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 527f55c8c4c7..db075bc0d952 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c | |||
| @@ -571,18 +571,19 @@ static int geni_i2c_probe(struct platform_device *pdev) | |||
| 571 | 571 | ||
| 572 | dev_dbg(&pdev->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); | 572 | dev_dbg(&pdev->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); |
| 573 | 573 | ||
| 574 | ret = i2c_add_adapter(&gi2c->adap); | ||
| 575 | if (ret) { | ||
| 576 | dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret); | ||
| 577 | return ret; | ||
| 578 | } | ||
| 579 | |||
| 580 | gi2c->suspended = 1; | 574 | gi2c->suspended = 1; |
| 581 | pm_runtime_set_suspended(gi2c->se.dev); | 575 | pm_runtime_set_suspended(gi2c->se.dev); |
| 582 | pm_runtime_set_autosuspend_delay(gi2c->se.dev, I2C_AUTO_SUSPEND_DELAY); | 576 | pm_runtime_set_autosuspend_delay(gi2c->se.dev, I2C_AUTO_SUSPEND_DELAY); |
| 583 | pm_runtime_use_autosuspend(gi2c->se.dev); | 577 | pm_runtime_use_autosuspend(gi2c->se.dev); |
| 584 | pm_runtime_enable(gi2c->se.dev); | 578 | pm_runtime_enable(gi2c->se.dev); |
| 585 | 579 | ||
| 580 | ret = i2c_add_adapter(&gi2c->adap); | ||
| 581 | if (ret) { | ||
| 582 | dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret); | ||
| 583 | pm_runtime_disable(gi2c->se.dev); | ||
| 584 | return ret; | ||
| 585 | } | ||
| 586 | |||
| 586 | return 0; | 587 | return 0; |
| 587 | } | 588 | } |
| 588 | 589 | ||
| @@ -590,8 +591,8 @@ static int geni_i2c_remove(struct platform_device *pdev) | |||
| 590 | { | 591 | { |
| 591 | struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); | 592 | struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); |
| 592 | 593 | ||
| 593 | pm_runtime_disable(gi2c->se.dev); | ||
| 594 | i2c_del_adapter(&gi2c->adap); | 594 | i2c_del_adapter(&gi2c->adap); |
| 595 | pm_runtime_disable(gi2c->se.dev); | ||
| 595 | return 0; | 596 | return 0; |
| 596 | } | 597 | } |
| 597 | 598 | ||
diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c index ce7acd115dd8..1870cf87afe1 100644 --- a/drivers/leds/trigger/ledtrig-pattern.c +++ b/drivers/leds/trigger/ledtrig-pattern.c | |||
| @@ -75,8 +75,6 @@ static void pattern_trig_timer_function(struct timer_list *t) | |||
| 75 | { | 75 | { |
| 76 | struct pattern_trig_data *data = from_timer(data, t, timer); | 76 | struct pattern_trig_data *data = from_timer(data, t, timer); |
| 77 | 77 | ||
| 78 | mutex_lock(&data->lock); | ||
| 79 | |||
| 80 | for (;;) { | 78 | for (;;) { |
| 81 | if (!data->is_indefinite && !data->repeat) | 79 | if (!data->is_indefinite && !data->repeat) |
| 82 | break; | 80 | break; |
| @@ -87,9 +85,10 @@ static void pattern_trig_timer_function(struct timer_list *t) | |||
| 87 | data->curr->brightness); | 85 | data->curr->brightness); |
| 88 | mod_timer(&data->timer, | 86 | mod_timer(&data->timer, |
| 89 | jiffies + msecs_to_jiffies(data->curr->delta_t)); | 87 | jiffies + msecs_to_jiffies(data->curr->delta_t)); |
| 90 | 88 | if (!data->next->delta_t) { | |
| 91 | /* Skip the tuple with zero duration */ | 89 | /* Skip the tuple with zero duration */ |
| 92 | pattern_trig_update_patterns(data); | 90 | pattern_trig_update_patterns(data); |
| 91 | } | ||
| 93 | /* Select next tuple */ | 92 | /* Select next tuple */ |
| 94 | pattern_trig_update_patterns(data); | 93 | pattern_trig_update_patterns(data); |
| 95 | } else { | 94 | } else { |
| @@ -116,8 +115,6 @@ static void pattern_trig_timer_function(struct timer_list *t) | |||
| 116 | 115 | ||
| 117 | break; | 116 | break; |
| 118 | } | 117 | } |
| 119 | |||
| 120 | mutex_unlock(&data->lock); | ||
| 121 | } | 118 | } |
| 122 | 119 | ||
| 123 | static int pattern_trig_start_pattern(struct led_classdev *led_cdev) | 120 | static int pattern_trig_start_pattern(struct led_classdev *led_cdev) |
| @@ -176,14 +173,10 @@ static ssize_t repeat_store(struct device *dev, struct device_attribute *attr, | |||
| 176 | if (res < -1 || res == 0) | 173 | if (res < -1 || res == 0) |
| 177 | return -EINVAL; | 174 | return -EINVAL; |
| 178 | 175 | ||
| 179 | /* | ||
| 180 | * Clear previous patterns' performence firstly, and remove the timer | ||
| 181 | * without mutex lock to avoid dead lock. | ||
| 182 | */ | ||
| 183 | del_timer_sync(&data->timer); | ||
| 184 | |||
| 185 | mutex_lock(&data->lock); | 176 | mutex_lock(&data->lock); |
| 186 | 177 | ||
| 178 | del_timer_sync(&data->timer); | ||
| 179 | |||
| 187 | if (data->is_hw_pattern) | 180 | if (data->is_hw_pattern) |
| 188 | led_cdev->pattern_clear(led_cdev); | 181 | led_cdev->pattern_clear(led_cdev); |
| 189 | 182 | ||
| @@ -234,14 +227,10 @@ static ssize_t pattern_trig_store_patterns(struct led_classdev *led_cdev, | |||
| 234 | struct pattern_trig_data *data = led_cdev->trigger_data; | 227 | struct pattern_trig_data *data = led_cdev->trigger_data; |
| 235 | int ccount, cr, offset = 0, err = 0; | 228 | int ccount, cr, offset = 0, err = 0; |
| 236 | 229 | ||
| 237 | /* | ||
| 238 | * Clear previous patterns' performence firstly, and remove the timer | ||
| 239 | * without mutex lock to avoid dead lock. | ||
| 240 | */ | ||
| 241 | del_timer_sync(&data->timer); | ||
| 242 | |||
| 243 | mutex_lock(&data->lock); | 230 | mutex_lock(&data->lock); |
| 244 | 231 | ||
| 232 | del_timer_sync(&data->timer); | ||
| 233 | |||
| 245 | if (data->is_hw_pattern) | 234 | if (data->is_hw_pattern) |
| 246 | led_cdev->pattern_clear(led_cdev); | 235 | led_cdev->pattern_clear(led_cdev); |
| 247 | 236 | ||
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index e514d57a0419..aa983422aa97 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
| @@ -207,7 +207,7 @@ comment "Disk-On-Chip Device Drivers" | |||
| 207 | config MTD_DOCG3 | 207 | config MTD_DOCG3 |
| 208 | tristate "M-Systems Disk-On-Chip G3" | 208 | tristate "M-Systems Disk-On-Chip G3" |
| 209 | select BCH | 209 | select BCH |
| 210 | select BCH_CONST_PARAMS | 210 | select BCH_CONST_PARAMS if !MTD_NAND_BCH |
| 211 | select BITREVERSE | 211 | select BITREVERSE |
| 212 | help | 212 | help |
| 213 | This provides an MTD device driver for the M-Systems DiskOnChip | 213 | This provides an MTD device driver for the M-Systems DiskOnChip |
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 784c6e1a0391..fd5fe12d7461 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
| @@ -221,7 +221,14 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, | |||
| 221 | info->mtd = info->subdev[0].mtd; | 221 | info->mtd = info->subdev[0].mtd; |
| 222 | ret = 0; | 222 | ret = 0; |
| 223 | } else if (info->num_subdev > 1) { | 223 | } else if (info->num_subdev > 1) { |
| 224 | struct mtd_info *cdev[nr]; | 224 | struct mtd_info **cdev; |
| 225 | |||
| 226 | cdev = kmalloc_array(nr, sizeof(*cdev), GFP_KERNEL); | ||
| 227 | if (!cdev) { | ||
| 228 | ret = -ENOMEM; | ||
| 229 | goto err; | ||
| 230 | } | ||
| 231 | |||
| 225 | /* | 232 | /* |
| 226 | * We detected multiple devices. Concatenate them together. | 233 | * We detected multiple devices. Concatenate them together. |
| 227 | */ | 234 | */ |
| @@ -230,6 +237,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, | |||
| 230 | 237 | ||
| 231 | info->mtd = mtd_concat_create(cdev, info->num_subdev, | 238 | info->mtd = mtd_concat_create(cdev, info->num_subdev, |
| 232 | plat->name); | 239 | plat->name); |
| 240 | kfree(cdev); | ||
| 233 | if (info->mtd == NULL) { | 241 | if (info->mtd == NULL) { |
| 234 | ret = -ENXIO; | 242 | ret = -ENXIO; |
| 235 | goto err; | 243 | goto err; |
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 05bd0779fe9b..71050a0b31df 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c | |||
| @@ -590,7 +590,6 @@ retry: | |||
| 590 | 590 | ||
| 591 | /** | 591 | /** |
| 592 | * panic_nand_wait - [GENERIC] wait until the command is done | 592 | * panic_nand_wait - [GENERIC] wait until the command is done |
| 593 | * @mtd: MTD device structure | ||
| 594 | * @chip: NAND chip structure | 593 | * @chip: NAND chip structure |
| 595 | * @timeo: timeout | 594 | * @timeo: timeout |
| 596 | * | 595 | * |
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index e24db817154e..d846428ef038 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c | |||
| @@ -996,7 +996,7 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf, | |||
| 996 | err_unmap: | 996 | err_unmap: |
| 997 | dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE); | 997 | dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE); |
| 998 | 998 | ||
| 999 | return 0; | 999 | return ret; |
| 1000 | } | 1000 | } |
| 1001 | 1001 | ||
| 1002 | static ssize_t cqspi_read(struct spi_nor *nor, loff_t from, | 1002 | static ssize_t cqspi_read(struct spi_nor *nor, loff_t from, |
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 9407ca5f9443..3e54e31889c7 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
| @@ -3250,12 +3250,14 @@ static int spi_nor_init_params(struct spi_nor *nor, | |||
| 3250 | memcpy(&sfdp_params, params, sizeof(sfdp_params)); | 3250 | memcpy(&sfdp_params, params, sizeof(sfdp_params)); |
| 3251 | memcpy(&prev_map, &nor->erase_map, sizeof(prev_map)); | 3251 | memcpy(&prev_map, &nor->erase_map, sizeof(prev_map)); |
| 3252 | 3252 | ||
| 3253 | if (spi_nor_parse_sfdp(nor, &sfdp_params)) | 3253 | if (spi_nor_parse_sfdp(nor, &sfdp_params)) { |
| 3254 | nor->addr_width = 0; | ||
| 3254 | /* restore previous erase map */ | 3255 | /* restore previous erase map */ |
| 3255 | memcpy(&nor->erase_map, &prev_map, | 3256 | memcpy(&nor->erase_map, &prev_map, |
| 3256 | sizeof(nor->erase_map)); | 3257 | sizeof(nor->erase_map)); |
| 3257 | else | 3258 | } else { |
| 3258 | memcpy(params, &sfdp_params, sizeof(*params)); | 3259 | memcpy(params, &sfdp_params, sizeof(*params)); |
| 3260 | } | ||
| 3259 | } | 3261 | } |
| 3260 | 3262 | ||
| 3261 | return 0; | 3263 | return 0; |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 2e65be8b1387..559d567693b8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -1519,8 +1519,10 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id) | |||
| 1519 | if (ns->ndev) | 1519 | if (ns->ndev) |
| 1520 | nvme_nvm_update_nvm_info(ns); | 1520 | nvme_nvm_update_nvm_info(ns); |
| 1521 | #ifdef CONFIG_NVME_MULTIPATH | 1521 | #ifdef CONFIG_NVME_MULTIPATH |
| 1522 | if (ns->head->disk) | 1522 | if (ns->head->disk) { |
| 1523 | nvme_update_disk_info(ns->head->disk, ns, id); | 1523 | nvme_update_disk_info(ns->head->disk, ns, id); |
| 1524 | blk_queue_stack_limits(ns->head->disk->queue, ns->queue); | ||
| 1525 | } | ||
| 1524 | #endif | 1526 | #endif |
| 1525 | } | 1527 | } |
| 1526 | 1528 | ||
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 5e3cc8c59a39..9901afd804ce 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c | |||
| @@ -285,6 +285,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) | |||
| 285 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); | 285 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); |
| 286 | /* set to a default value for 512 until disk is validated */ | 286 | /* set to a default value for 512 until disk is validated */ |
| 287 | blk_queue_logical_block_size(q, 512); | 287 | blk_queue_logical_block_size(q, 512); |
| 288 | blk_set_stacking_limits(&q->limits); | ||
| 288 | 289 | ||
| 289 | /* we need to propagate up the VMC settings */ | 290 | /* we need to propagate up the VMC settings */ |
| 290 | if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) | 291 | if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) |
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index f4efe289dc7b..a5f9bbce863f 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c | |||
| @@ -420,7 +420,7 @@ static void nvmet_p2pmem_ns_add_p2p(struct nvmet_ctrl *ctrl, | |||
| 420 | struct pci_dev *p2p_dev; | 420 | struct pci_dev *p2p_dev; |
| 421 | int ret; | 421 | int ret; |
| 422 | 422 | ||
| 423 | if (!ctrl->p2p_client) | 423 | if (!ctrl->p2p_client || !ns->use_p2pmem) |
| 424 | return; | 424 | return; |
| 425 | 425 | ||
| 426 | if (ns->p2p_dev) { | 426 | if (ns->p2p_dev) { |
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index ddce100be57a..3f7971d3706d 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c | |||
| @@ -122,7 +122,6 @@ struct nvmet_rdma_device { | |||
| 122 | int inline_page_count; | 122 | int inline_page_count; |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | static struct workqueue_struct *nvmet_rdma_delete_wq; | ||
| 126 | static bool nvmet_rdma_use_srq; | 125 | static bool nvmet_rdma_use_srq; |
| 127 | module_param_named(use_srq, nvmet_rdma_use_srq, bool, 0444); | 126 | module_param_named(use_srq, nvmet_rdma_use_srq, bool, 0444); |
| 128 | MODULE_PARM_DESC(use_srq, "Use shared receive queue."); | 127 | MODULE_PARM_DESC(use_srq, "Use shared receive queue."); |
| @@ -1274,12 +1273,12 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id, | |||
| 1274 | 1273 | ||
| 1275 | if (queue->host_qid == 0) { | 1274 | if (queue->host_qid == 0) { |
| 1276 | /* Let inflight controller teardown complete */ | 1275 | /* Let inflight controller teardown complete */ |
| 1277 | flush_workqueue(nvmet_rdma_delete_wq); | 1276 | flush_scheduled_work(); |
| 1278 | } | 1277 | } |
| 1279 | 1278 | ||
| 1280 | ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn); | 1279 | ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn); |
| 1281 | if (ret) { | 1280 | if (ret) { |
| 1282 | queue_work(nvmet_rdma_delete_wq, &queue->release_work); | 1281 | schedule_work(&queue->release_work); |
| 1283 | /* Destroying rdma_cm id is not needed here */ | 1282 | /* Destroying rdma_cm id is not needed here */ |
| 1284 | return 0; | 1283 | return 0; |
| 1285 | } | 1284 | } |
| @@ -1344,7 +1343,7 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue) | |||
| 1344 | 1343 | ||
| 1345 | if (disconnect) { | 1344 | if (disconnect) { |
| 1346 | rdma_disconnect(queue->cm_id); | 1345 | rdma_disconnect(queue->cm_id); |
| 1347 | queue_work(nvmet_rdma_delete_wq, &queue->release_work); | 1346 | schedule_work(&queue->release_work); |
| 1348 | } | 1347 | } |
| 1349 | } | 1348 | } |
| 1350 | 1349 | ||
| @@ -1374,7 +1373,7 @@ static void nvmet_rdma_queue_connect_fail(struct rdma_cm_id *cm_id, | |||
| 1374 | mutex_unlock(&nvmet_rdma_queue_mutex); | 1373 | mutex_unlock(&nvmet_rdma_queue_mutex); |
| 1375 | 1374 | ||
| 1376 | pr_err("failed to connect queue %d\n", queue->idx); | 1375 | pr_err("failed to connect queue %d\n", queue->idx); |
| 1377 | queue_work(nvmet_rdma_delete_wq, &queue->release_work); | 1376 | schedule_work(&queue->release_work); |
| 1378 | } | 1377 | } |
| 1379 | 1378 | ||
| 1380 | /** | 1379 | /** |
| @@ -1656,17 +1655,8 @@ static int __init nvmet_rdma_init(void) | |||
| 1656 | if (ret) | 1655 | if (ret) |
| 1657 | goto err_ib_client; | 1656 | goto err_ib_client; |
| 1658 | 1657 | ||
| 1659 | nvmet_rdma_delete_wq = alloc_workqueue("nvmet-rdma-delete-wq", | ||
| 1660 | WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0); | ||
| 1661 | if (!nvmet_rdma_delete_wq) { | ||
| 1662 | ret = -ENOMEM; | ||
| 1663 | goto err_unreg_transport; | ||
| 1664 | } | ||
| 1665 | |||
| 1666 | return 0; | 1658 | return 0; |
| 1667 | 1659 | ||
| 1668 | err_unreg_transport: | ||
| 1669 | nvmet_unregister_transport(&nvmet_rdma_ops); | ||
| 1670 | err_ib_client: | 1660 | err_ib_client: |
| 1671 | ib_unregister_client(&nvmet_rdma_ib_client); | 1661 | ib_unregister_client(&nvmet_rdma_ib_client); |
| 1672 | return ret; | 1662 | return ret; |
| @@ -1674,7 +1664,6 @@ err_ib_client: | |||
| 1674 | 1664 | ||
| 1675 | static void __exit nvmet_rdma_exit(void) | 1665 | static void __exit nvmet_rdma_exit(void) |
| 1676 | { | 1666 | { |
| 1677 | destroy_workqueue(nvmet_rdma_delete_wq); | ||
| 1678 | nvmet_unregister_transport(&nvmet_rdma_ops); | 1667 | nvmet_unregister_transport(&nvmet_rdma_ops); |
| 1679 | ib_unregister_client(&nvmet_rdma_ib_client); | 1668 | ib_unregister_client(&nvmet_rdma_ib_client); |
| 1680 | WARN_ON_ONCE(!list_empty(&nvmet_rdma_queue_list)); | 1669 | WARN_ON_ONCE(!list_empty(&nvmet_rdma_queue_list)); |
diff --git a/drivers/of/device.c b/drivers/of/device.c index 0f27fad9fe94..5592437bb3d1 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
| @@ -149,9 +149,11 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) | |||
| 149 | * set by the driver. | 149 | * set by the driver. |
| 150 | */ | 150 | */ |
| 151 | mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1); | 151 | mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1); |
| 152 | dev->bus_dma_mask = mask; | ||
| 153 | dev->coherent_dma_mask &= mask; | 152 | dev->coherent_dma_mask &= mask; |
| 154 | *dev->dma_mask &= mask; | 153 | *dev->dma_mask &= mask; |
| 154 | /* ...but only set bus mask if we found valid dma-ranges earlier */ | ||
| 155 | if (!ret) | ||
| 156 | dev->bus_dma_mask = mask; | ||
| 155 | 157 | ||
| 156 | coherent = of_dma_is_coherent(np); | 158 | coherent = of_dma_is_coherent(np); |
| 157 | dev_dbg(dev, "device is%sdma coherent\n", | 159 | dev_dbg(dev, "device is%sdma coherent\n", |
diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 35c64a4295e0..fe6b13608e51 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c | |||
| @@ -104,9 +104,14 @@ static int __init of_numa_parse_distance_map_v1(struct device_node *map) | |||
| 104 | distance = of_read_number(matrix, 1); | 104 | distance = of_read_number(matrix, 1); |
| 105 | matrix++; | 105 | matrix++; |
| 106 | 106 | ||
| 107 | if ((nodea == nodeb && distance != LOCAL_DISTANCE) || | ||
| 108 | (nodea != nodeb && distance <= LOCAL_DISTANCE)) { | ||
| 109 | pr_err("Invalid distance[node%d -> node%d] = %d\n", | ||
| 110 | nodea, nodeb, distance); | ||
| 111 | return -EINVAL; | ||
| 112 | } | ||
| 113 | |||
| 107 | numa_set_distance(nodea, nodeb, distance); | 114 | numa_set_distance(nodea, nodeb, distance); |
| 108 | pr_debug("distance[node%d -> node%d] = %d\n", | ||
| 109 | nodea, nodeb, distance); | ||
| 110 | 115 | ||
| 111 | /* Set default distance of node B->A same as A->B */ | 116 | /* Set default distance of node B->A same as A->B */ |
| 112 | if (nodeb > nodea) | 117 | if (nodeb > nodea) |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ff6ba6d86cd8..cc56cb3b3eca 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
| @@ -1614,10 +1614,10 @@ static void sci_request_dma(struct uart_port *port) | |||
| 1614 | hrtimer_init(&s->rx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1614 | hrtimer_init(&s->rx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 1615 | s->rx_timer.function = rx_timer_fn; | 1615 | s->rx_timer.function = rx_timer_fn; |
| 1616 | 1616 | ||
| 1617 | s->chan_rx_saved = s->chan_rx = chan; | ||
| 1618 | |||
| 1617 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | 1619 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
| 1618 | sci_submit_rx(s); | 1620 | sci_submit_rx(s); |
| 1619 | |||
| 1620 | s->chan_rx_saved = s->chan_rx = chan; | ||
| 1621 | } | 1621 | } |
| 1622 | } | 1622 | } |
| 1623 | 1623 | ||
| @@ -3102,6 +3102,7 @@ static struct uart_driver sci_uart_driver = { | |||
| 3102 | static int sci_remove(struct platform_device *dev) | 3102 | static int sci_remove(struct platform_device *dev) |
| 3103 | { | 3103 | { |
| 3104 | struct sci_port *port = platform_get_drvdata(dev); | 3104 | struct sci_port *port = platform_get_drvdata(dev); |
| 3105 | unsigned int type = port->port.type; /* uart_remove_... clears it */ | ||
| 3105 | 3106 | ||
| 3106 | sci_ports_in_use &= ~BIT(port->port.line); | 3107 | sci_ports_in_use &= ~BIT(port->port.line); |
| 3107 | uart_remove_one_port(&sci_uart_driver, &port->port); | 3108 | uart_remove_one_port(&sci_uart_driver, &port->port); |
| @@ -3112,8 +3113,7 @@ static int sci_remove(struct platform_device *dev) | |||
| 3112 | sysfs_remove_file(&dev->dev.kobj, | 3113 | sysfs_remove_file(&dev->dev.kobj, |
| 3113 | &dev_attr_rx_fifo_trigger.attr); | 3114 | &dev_attr_rx_fifo_trigger.attr); |
| 3114 | } | 3115 | } |
| 3115 | if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB || | 3116 | if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF) { |
| 3116 | port->port.type == PORT_HSCIF) { | ||
| 3117 | sysfs_remove_file(&dev->dev.kobj, | 3117 | sysfs_remove_file(&dev->dev.kobj, |
| 3118 | &dev_attr_rx_fifo_timeout.attr); | 3118 | &dev_attr_rx_fifo_timeout.attr); |
| 3119 | } | 3119 | } |
diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 7576ceace571..f438eaa68246 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c | |||
| @@ -77,7 +77,7 @@ speed_t tty_termios_baud_rate(struct ktermios *termios) | |||
| 77 | else | 77 | else |
| 78 | cbaud += 15; | 78 | cbaud += 15; |
| 79 | } | 79 | } |
| 80 | return baud_table[cbaud]; | 80 | return cbaud >= n_baud_table ? 0 : baud_table[cbaud]; |
| 81 | } | 81 | } |
| 82 | EXPORT_SYMBOL(tty_termios_baud_rate); | 82 | EXPORT_SYMBOL(tty_termios_baud_rate); |
| 83 | 83 | ||
| @@ -113,7 +113,7 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios) | |||
| 113 | else | 113 | else |
| 114 | cbaud += 15; | 114 | cbaud += 15; |
| 115 | } | 115 | } |
| 116 | return baud_table[cbaud]; | 116 | return cbaud >= n_baud_table ? 0 : baud_table[cbaud]; |
| 117 | #else /* IBSHIFT */ | 117 | #else /* IBSHIFT */ |
| 118 | return tty_termios_baud_rate(termios); | 118 | return tty_termios_baud_rate(termios); |
| 119 | #endif /* IBSHIFT */ | 119 | #endif /* IBSHIFT */ |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 55370e651db3..41ec8e5010f3 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -1548,7 +1548,7 @@ static void csi_K(struct vc_data *vc, int vpar) | |||
| 1548 | scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count); | 1548 | scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count); |
| 1549 | vc->vc_need_wrap = 0; | 1549 | vc->vc_need_wrap = 0; |
| 1550 | if (con_should_update(vc)) | 1550 | if (con_should_update(vc)) |
| 1551 | do_update_region(vc, (unsigned long) start, count); | 1551 | do_update_region(vc, (unsigned long)(start + offset), count); |
| 1552 | } | 1552 | } |
| 1553 | 1553 | ||
| 1554 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ | 1554 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ |
diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig index e36d6c73c4a4..78118883f96c 100644 --- a/drivers/usb/typec/ucsi/Kconfig +++ b/drivers/usb/typec/ucsi/Kconfig | |||
| @@ -23,6 +23,16 @@ config TYPEC_UCSI | |||
| 23 | 23 | ||
| 24 | if TYPEC_UCSI | 24 | if TYPEC_UCSI |
| 25 | 25 | ||
| 26 | config UCSI_CCG | ||
| 27 | tristate "UCSI Interface Driver for Cypress CCGx" | ||
| 28 | depends on I2C | ||
| 29 | help | ||
| 30 | This driver enables UCSI support on platforms that expose a | ||
| 31 | Cypress CCGx Type-C controller over I2C interface. | ||
| 32 | |||
| 33 | To compile the driver as a module, choose M here: the module will be | ||
| 34 | called ucsi_ccg. | ||
| 35 | |||
| 26 | config UCSI_ACPI | 36 | config UCSI_ACPI |
| 27 | tristate "UCSI ACPI Interface Driver" | 37 | tristate "UCSI ACPI Interface Driver" |
| 28 | depends on ACPI | 38 | depends on ACPI |
diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile index 7afbea512207..2f4900b26210 100644 --- a/drivers/usb/typec/ucsi/Makefile +++ b/drivers/usb/typec/ucsi/Makefile | |||
| @@ -8,3 +8,5 @@ typec_ucsi-y := ucsi.o | |||
| 8 | typec_ucsi-$(CONFIG_TRACING) += trace.o | 8 | typec_ucsi-$(CONFIG_TRACING) += trace.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_UCSI_ACPI) += ucsi_acpi.o | 10 | obj-$(CONFIG_UCSI_ACPI) += ucsi_acpi.o |
| 11 | |||
| 12 | obj-$(CONFIG_UCSI_CCG) += ucsi_ccg.o | ||
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c new file mode 100644 index 000000000000..de8a43bdff68 --- /dev/null +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c | |||
| @@ -0,0 +1,307 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * UCSI driver for Cypress CCGx Type-C controller | ||
| 4 | * | ||
| 5 | * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved. | ||
| 6 | * Author: Ajay Gupta <ajayg@nvidia.com> | ||
| 7 | * | ||
| 8 | * Some code borrowed from drivers/usb/typec/ucsi/ucsi_acpi.c | ||
| 9 | */ | ||
| 10 | #include <linux/acpi.h> | ||
| 11 | #include <linux/delay.h> | ||
| 12 | #include <linux/i2c.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 17 | #include <asm/unaligned.h> | ||
| 18 | #include "ucsi.h" | ||
| 19 | |||
| 20 | struct ucsi_ccg { | ||
| 21 | struct device *dev; | ||
| 22 | struct ucsi *ucsi; | ||
| 23 | struct ucsi_ppm ppm; | ||
| 24 | struct i2c_client *client; | ||
| 25 | }; | ||
| 26 | |||
| 27 | #define CCGX_RAB_INTR_REG 0x06 | ||
| 28 | #define CCGX_RAB_UCSI_CONTROL 0x39 | ||
| 29 | #define CCGX_RAB_UCSI_CONTROL_START BIT(0) | ||
| 30 | #define CCGX_RAB_UCSI_CONTROL_STOP BIT(1) | ||
| 31 | #define CCGX_RAB_UCSI_DATA_BLOCK(offset) (0xf000 | ((offset) & 0xff)) | ||
| 32 | |||
| 33 | static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) | ||
| 34 | { | ||
| 35 | struct i2c_client *client = uc->client; | ||
| 36 | const struct i2c_adapter_quirks *quirks = client->adapter->quirks; | ||
| 37 | unsigned char buf[2]; | ||
| 38 | struct i2c_msg msgs[] = { | ||
| 39 | { | ||
| 40 | .addr = client->addr, | ||
| 41 | .flags = 0x0, | ||
| 42 | .len = sizeof(buf), | ||
| 43 | .buf = buf, | ||
| 44 | }, | ||
| 45 | { | ||
| 46 | .addr = client->addr, | ||
| 47 | .flags = I2C_M_RD, | ||
| 48 | .buf = data, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | u32 rlen, rem_len = len, max_read_len = len; | ||
| 52 | int status; | ||
| 53 | |||
| 54 | /* check any max_read_len limitation on i2c adapter */ | ||
| 55 | if (quirks && quirks->max_read_len) | ||
| 56 | max_read_len = quirks->max_read_len; | ||
| 57 | |||
| 58 | while (rem_len > 0) { | ||
| 59 | msgs[1].buf = &data[len - rem_len]; | ||
| 60 | rlen = min_t(u16, rem_len, max_read_len); | ||
| 61 | msgs[1].len = rlen; | ||
| 62 | put_unaligned_le16(rab, buf); | ||
| 63 | status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
| 64 | if (status < 0) { | ||
| 65 | dev_err(uc->dev, "i2c_transfer failed %d\n", status); | ||
| 66 | return status; | ||
| 67 | } | ||
| 68 | rab += rlen; | ||
| 69 | rem_len -= rlen; | ||
| 70 | } | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) | ||
| 76 | { | ||
| 77 | struct i2c_client *client = uc->client; | ||
| 78 | unsigned char *buf; | ||
| 79 | struct i2c_msg msgs[] = { | ||
| 80 | { | ||
| 81 | .addr = client->addr, | ||
| 82 | .flags = 0x0, | ||
| 83 | } | ||
| 84 | }; | ||
| 85 | int status; | ||
| 86 | |||
| 87 | buf = kzalloc(len + sizeof(rab), GFP_KERNEL); | ||
| 88 | if (!buf) | ||
| 89 | return -ENOMEM; | ||
| 90 | |||
| 91 | put_unaligned_le16(rab, buf); | ||
| 92 | memcpy(buf + sizeof(rab), data, len); | ||
| 93 | |||
| 94 | msgs[0].len = len + sizeof(rab); | ||
| 95 | msgs[0].buf = buf; | ||
| 96 | |||
| 97 | status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
| 98 | if (status < 0) { | ||
| 99 | dev_err(uc->dev, "i2c_transfer failed %d\n", status); | ||
| 100 | kfree(buf); | ||
| 101 | return status; | ||
| 102 | } | ||
| 103 | |||
| 104 | kfree(buf); | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int ucsi_ccg_init(struct ucsi_ccg *uc) | ||
| 109 | { | ||
| 110 | unsigned int count = 10; | ||
| 111 | u8 data; | ||
| 112 | int status; | ||
| 113 | |||
| 114 | data = CCGX_RAB_UCSI_CONTROL_STOP; | ||
| 115 | status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data)); | ||
| 116 | if (status < 0) | ||
| 117 | return status; | ||
| 118 | |||
| 119 | data = CCGX_RAB_UCSI_CONTROL_START; | ||
| 120 | status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data)); | ||
| 121 | if (status < 0) | ||
| 122 | return status; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Flush CCGx RESPONSE queue by acking interrupts. Above ucsi control | ||
| 126 | * register write will push response which must be cleared. | ||
| 127 | */ | ||
| 128 | do { | ||
| 129 | status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data)); | ||
| 130 | if (status < 0) | ||
| 131 | return status; | ||
| 132 | |||
| 133 | if (!data) | ||
| 134 | return 0; | ||
| 135 | |||
| 136 | status = ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data)); | ||
| 137 | if (status < 0) | ||
| 138 | return status; | ||
| 139 | |||
| 140 | usleep_range(10000, 11000); | ||
| 141 | } while (--count); | ||
| 142 | |||
| 143 | return -ETIMEDOUT; | ||
| 144 | } | ||
| 145 | |||
| 146 | static int ucsi_ccg_send_data(struct ucsi_ccg *uc) | ||
| 147 | { | ||
| 148 | u8 *ppm = (u8 *)uc->ppm.data; | ||
| 149 | int status; | ||
| 150 | u16 rab; | ||
| 151 | |||
| 152 | rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_out)); | ||
| 153 | status = ccg_write(uc, rab, ppm + | ||
| 154 | offsetof(struct ucsi_data, message_out), | ||
| 155 | sizeof(uc->ppm.data->message_out)); | ||
| 156 | if (status < 0) | ||
| 157 | return status; | ||
| 158 | |||
| 159 | rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, ctrl)); | ||
| 160 | return ccg_write(uc, rab, ppm + offsetof(struct ucsi_data, ctrl), | ||
| 161 | sizeof(uc->ppm.data->ctrl)); | ||
| 162 | } | ||
| 163 | |||
| 164 | static int ucsi_ccg_recv_data(struct ucsi_ccg *uc) | ||
| 165 | { | ||
| 166 | u8 *ppm = (u8 *)uc->ppm.data; | ||
| 167 | int status; | ||
| 168 | u16 rab; | ||
| 169 | |||
| 170 | rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, cci)); | ||
| 171 | status = ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, cci), | ||
| 172 | sizeof(uc->ppm.data->cci)); | ||
| 173 | if (status < 0) | ||
| 174 | return status; | ||
| 175 | |||
| 176 | rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_in)); | ||
| 177 | return ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, message_in), | ||
| 178 | sizeof(uc->ppm.data->message_in)); | ||
| 179 | } | ||
| 180 | |||
| 181 | static int ucsi_ccg_ack_interrupt(struct ucsi_ccg *uc) | ||
| 182 | { | ||
| 183 | int status; | ||
| 184 | unsigned char data; | ||
| 185 | |||
| 186 | status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data)); | ||
| 187 | if (status < 0) | ||
| 188 | return status; | ||
| 189 | |||
| 190 | return ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data)); | ||
| 191 | } | ||
| 192 | |||
| 193 | static int ucsi_ccg_sync(struct ucsi_ppm *ppm) | ||
| 194 | { | ||
| 195 | struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm); | ||
| 196 | int status; | ||
| 197 | |||
| 198 | status = ucsi_ccg_recv_data(uc); | ||
| 199 | if (status < 0) | ||
| 200 | return status; | ||
| 201 | |||
| 202 | /* ack interrupt to allow next command to run */ | ||
| 203 | return ucsi_ccg_ack_interrupt(uc); | ||
| 204 | } | ||
| 205 | |||
| 206 | static int ucsi_ccg_cmd(struct ucsi_ppm *ppm, struct ucsi_control *ctrl) | ||
| 207 | { | ||
| 208 | struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm); | ||
| 209 | |||
| 210 | ppm->data->ctrl.raw_cmd = ctrl->raw_cmd; | ||
| 211 | return ucsi_ccg_send_data(uc); | ||
| 212 | } | ||
| 213 | |||
| 214 | static irqreturn_t ccg_irq_handler(int irq, void *data) | ||
| 215 | { | ||
| 216 | struct ucsi_ccg *uc = data; | ||
| 217 | |||
| 218 | ucsi_notify(uc->ucsi); | ||
| 219 | |||
| 220 | return IRQ_HANDLED; | ||
| 221 | } | ||
| 222 | |||
| 223 | static int ucsi_ccg_probe(struct i2c_client *client, | ||
| 224 | const struct i2c_device_id *id) | ||
| 225 | { | ||
| 226 | struct device *dev = &client->dev; | ||
| 227 | struct ucsi_ccg *uc; | ||
| 228 | int status; | ||
| 229 | u16 rab; | ||
| 230 | |||
| 231 | uc = devm_kzalloc(dev, sizeof(*uc), GFP_KERNEL); | ||
| 232 | if (!uc) | ||
| 233 | return -ENOMEM; | ||
| 234 | |||
| 235 | uc->ppm.data = devm_kzalloc(dev, sizeof(struct ucsi_data), GFP_KERNEL); | ||
| 236 | if (!uc->ppm.data) | ||
| 237 | return -ENOMEM; | ||
| 238 | |||
| 239 | uc->ppm.cmd = ucsi_ccg_cmd; | ||
| 240 | uc->ppm.sync = ucsi_ccg_sync; | ||
| 241 | uc->dev = dev; | ||
| 242 | uc->client = client; | ||
| 243 | |||
| 244 | /* reset ccg device and initialize ucsi */ | ||
| 245 | status = ucsi_ccg_init(uc); | ||
| 246 | if (status < 0) { | ||
| 247 | dev_err(uc->dev, "ucsi_ccg_init failed - %d\n", status); | ||
| 248 | return status; | ||
| 249 | } | ||
| 250 | |||
| 251 | status = devm_request_threaded_irq(dev, client->irq, NULL, | ||
| 252 | ccg_irq_handler, | ||
| 253 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, | ||
| 254 | dev_name(dev), uc); | ||
| 255 | if (status < 0) { | ||
| 256 | dev_err(uc->dev, "request_threaded_irq failed - %d\n", status); | ||
| 257 | return status; | ||
| 258 | } | ||
| 259 | |||
| 260 | uc->ucsi = ucsi_register_ppm(dev, &uc->ppm); | ||
| 261 | if (IS_ERR(uc->ucsi)) { | ||
| 262 | dev_err(uc->dev, "ucsi_register_ppm failed\n"); | ||
| 263 | return PTR_ERR(uc->ucsi); | ||
| 264 | } | ||
| 265 | |||
| 266 | rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, version)); | ||
| 267 | status = ccg_read(uc, rab, (u8 *)(uc->ppm.data) + | ||
| 268 | offsetof(struct ucsi_data, version), | ||
| 269 | sizeof(uc->ppm.data->version)); | ||
| 270 | if (status < 0) { | ||
| 271 | ucsi_unregister_ppm(uc->ucsi); | ||
| 272 | return status; | ||
| 273 | } | ||
| 274 | |||
| 275 | i2c_set_clientdata(client, uc); | ||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int ucsi_ccg_remove(struct i2c_client *client) | ||
| 280 | { | ||
| 281 | struct ucsi_ccg *uc = i2c_get_clientdata(client); | ||
| 282 | |||
| 283 | ucsi_unregister_ppm(uc->ucsi); | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | static const struct i2c_device_id ucsi_ccg_device_id[] = { | ||
| 289 | {"ccgx-ucsi", 0}, | ||
| 290 | {} | ||
| 291 | }; | ||
| 292 | MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id); | ||
| 293 | |||
| 294 | static struct i2c_driver ucsi_ccg_driver = { | ||
| 295 | .driver = { | ||
| 296 | .name = "ucsi_ccg", | ||
| 297 | }, | ||
| 298 | .probe = ucsi_ccg_probe, | ||
| 299 | .remove = ucsi_ccg_remove, | ||
| 300 | .id_table = ucsi_ccg_device_id, | ||
| 301 | }; | ||
| 302 | |||
| 303 | module_i2c_driver(ucsi_ccg_driver); | ||
| 304 | |||
| 305 | MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>"); | ||
| 306 | MODULE_DESCRIPTION("UCSI driver for Cypress CCGx Type-C controller"); | ||
| 307 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index f15f89df1f36..7ea6fb6a2e5d 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
| @@ -914,7 +914,7 @@ int gnttab_dma_free_pages(struct gnttab_dma_alloc_args *args) | |||
| 914 | 914 | ||
| 915 | ret = xenmem_reservation_increase(args->nr_pages, args->frames); | 915 | ret = xenmem_reservation_increase(args->nr_pages, args->frames); |
| 916 | if (ret != args->nr_pages) { | 916 | if (ret != args->nr_pages) { |
| 917 | pr_debug("Failed to decrease reservation for DMA buffer\n"); | 917 | pr_debug("Failed to increase reservation for DMA buffer\n"); |
| 918 | ret = -EFAULT; | 918 | ret = -EFAULT; |
| 919 | } else { | 919 | } else { |
| 920 | ret = 0; | 920 | ret = 0; |
diff --git a/drivers/xen/privcmd-buf.c b/drivers/xen/privcmd-buf.c index df1ed37c3269..de01a6d0059d 100644 --- a/drivers/xen/privcmd-buf.c +++ b/drivers/xen/privcmd-buf.c | |||
| @@ -21,15 +21,9 @@ | |||
| 21 | 21 | ||
| 22 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
| 23 | 23 | ||
| 24 | static unsigned int limit = 64; | ||
| 25 | module_param(limit, uint, 0644); | ||
| 26 | MODULE_PARM_DESC(limit, "Maximum number of pages that may be allocated by " | ||
| 27 | "the privcmd-buf device per open file"); | ||
| 28 | |||
| 29 | struct privcmd_buf_private { | 24 | struct privcmd_buf_private { |
| 30 | struct mutex lock; | 25 | struct mutex lock; |
| 31 | struct list_head list; | 26 | struct list_head list; |
| 32 | unsigned int allocated; | ||
| 33 | }; | 27 | }; |
| 34 | 28 | ||
| 35 | struct privcmd_buf_vma_private { | 29 | struct privcmd_buf_vma_private { |
| @@ -60,13 +54,10 @@ static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv) | |||
| 60 | { | 54 | { |
| 61 | unsigned int i; | 55 | unsigned int i; |
| 62 | 56 | ||
| 63 | vma_priv->file_priv->allocated -= vma_priv->n_pages; | ||
| 64 | |||
| 65 | list_del(&vma_priv->list); | 57 | list_del(&vma_priv->list); |
| 66 | 58 | ||
| 67 | for (i = 0; i < vma_priv->n_pages; i++) | 59 | for (i = 0; i < vma_priv->n_pages; i++) |
| 68 | if (vma_priv->pages[i]) | 60 | __free_page(vma_priv->pages[i]); |
| 69 | __free_page(vma_priv->pages[i]); | ||
| 70 | 61 | ||
| 71 | kfree(vma_priv); | 62 | kfree(vma_priv); |
| 72 | } | 63 | } |
| @@ -146,8 +137,7 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 146 | unsigned int i; | 137 | unsigned int i; |
| 147 | int ret = 0; | 138 | int ret = 0; |
| 148 | 139 | ||
| 149 | if (!(vma->vm_flags & VM_SHARED) || count > limit || | 140 | if (!(vma->vm_flags & VM_SHARED)) |
| 150 | file_priv->allocated + count > limit) | ||
| 151 | return -EINVAL; | 141 | return -EINVAL; |
| 152 | 142 | ||
| 153 | vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *), | 143 | vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *), |
| @@ -155,19 +145,15 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 155 | if (!vma_priv) | 145 | if (!vma_priv) |
| 156 | return -ENOMEM; | 146 | return -ENOMEM; |
| 157 | 147 | ||
| 158 | vma_priv->n_pages = count; | 148 | for (i = 0; i < count; i++) { |
| 159 | count = 0; | ||
| 160 | for (i = 0; i < vma_priv->n_pages; i++) { | ||
| 161 | vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); | 149 | vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); |
| 162 | if (!vma_priv->pages[i]) | 150 | if (!vma_priv->pages[i]) |
| 163 | break; | 151 | break; |
| 164 | count++; | 152 | vma_priv->n_pages++; |
| 165 | } | 153 | } |
| 166 | 154 | ||
| 167 | mutex_lock(&file_priv->lock); | 155 | mutex_lock(&file_priv->lock); |
| 168 | 156 | ||
| 169 | file_priv->allocated += count; | ||
| 170 | |||
| 171 | vma_priv->file_priv = file_priv; | 157 | vma_priv->file_priv = file_priv; |
| 172 | vma_priv->users = 1; | 158 | vma_priv->users = 1; |
| 173 | 159 | ||
