Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tegra: sor - Protect CRC debugfs against enable state

Accessing the CRC debugfs file will hang the system if the SOR is not
enabled, so make sure that it is stays enabled until the CRC has been
read.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+45 -24
+45 -24
drivers/gpu/drm/tegra/sor.c
··· 34 34 35 35 struct tegra_dpaux *dpaux; 36 36 37 + struct mutex lock; 37 38 bool enabled; 38 39 39 40 struct dentry *debugfs; ··· 300 299 unsigned int vbe, vse, hbe, hse, vbs, hbs, i; 301 300 struct tegra_sor *sor = to_sor(output); 302 301 unsigned long value; 303 - int err; 302 + int err = 0; 303 + 304 + mutex_lock(&sor->lock); 304 305 305 306 if (sor->enabled) 306 - return 0; 307 + goto unlock; 307 308 308 309 err = clk_prepare_enable(sor->clk); 309 310 if (err < 0) 310 - return err; 311 + goto unlock; 311 312 312 313 reset_control_deassert(sor->rst); 313 314 ··· 391 388 err = tegra_io_rail_power_on(TEGRA_IO_RAIL_LVDS); 392 389 if (err < 0) { 393 390 dev_err(sor->dev, "failed to power on I/O rail: %d\n", err); 394 - return err; 391 + goto unlock; 395 392 } 396 393 397 394 usleep_range(5, 100); ··· 515 512 if (err < 0) { 516 513 dev_err(sor->dev, "failed to probe eDP link: %d\n", 517 514 err); 518 - return err; 515 + goto unlock; 519 516 } 520 517 521 518 err = drm_dp_link_power_up(aux, &link); 522 519 if (err < 0) { 523 520 dev_err(sor->dev, "failed to power up eDP link: %d\n", 524 521 err); 525 - return err; 522 + goto unlock; 526 523 } 527 524 528 525 err = drm_dp_link_configure(aux, &link); 529 526 if (err < 0) { 530 527 dev_err(sor->dev, "failed to configure eDP link: %d\n", 531 528 err); 532 - return err; 529 + goto unlock; 533 530 } 534 531 535 532 rate = drm_dp_link_rate_to_bw_code(link.rate); ··· 564 561 if (err < 0) { 565 562 dev_err(sor->dev, "DP fast link training failed: %d\n", 566 563 err); 567 - return err; 564 + goto unlock; 568 565 } 569 566 570 567 dev_dbg(sor->dev, "fast link training succeeded\n"); ··· 573 570 err = tegra_sor_power_up(sor, 250); 574 571 if (err < 0) { 575 572 dev_err(sor->dev, "failed to power up SOR: %d\n", err); 576 - return err; 573 + goto unlock; 577 574 } 578 575 579 576 /* start display controller in continuous mode */ ··· 638 635 err = tegra_sor_setup_pwm(sor, 250); 639 636 if (err < 0) { 640 637 dev_err(sor->dev, "failed to setup PWM: %d\n", err); 641 - return err; 638 + goto unlock; 642 639 } 643 640 644 641 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); ··· 650 647 err = tegra_sor_attach(sor); 651 648 if (err < 0) { 652 649 dev_err(sor->dev, "failed to attach SOR: %d\n", err); 653 - return err; 650 + goto unlock; 654 651 } 655 652 656 653 err = tegra_sor_wakeup(sor); 657 654 if (err < 0) { 658 655 dev_err(sor->dev, "failed to enable DC: %d\n", err); 659 - return err; 656 + goto unlock; 660 657 } 661 658 662 659 sor->enabled = true; 663 660 664 - return 0; 661 + unlock: 662 + mutex_unlock(&sor->lock); 663 + return err; 665 664 } 666 665 667 666 static int tegra_sor_detach(struct tegra_sor *sor) ··· 791 786 struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); 792 787 struct tegra_sor *sor = to_sor(output); 793 788 unsigned long value; 794 - int err; 789 + int err = 0; 790 + 791 + mutex_lock(&sor->lock); 795 792 796 793 if (!sor->enabled) 797 - return 0; 794 + goto unlock; 798 795 799 796 err = tegra_sor_detach(sor); 800 797 if (err < 0) { 801 798 dev_err(sor->dev, "failed to detach SOR: %d\n", err); 802 - return err; 799 + goto unlock; 803 800 } 804 801 805 802 tegra_sor_writel(sor, 0, SOR_STATE_1); ··· 842 835 err = tegra_sor_power_down(sor); 843 836 if (err < 0) { 844 837 dev_err(sor->dev, "failed to power down SOR: %d\n", err); 845 - return err; 838 + goto unlock; 846 839 } 847 840 848 841 if (sor->dpaux) { 849 842 err = tegra_dpaux_disable(sor->dpaux); 850 843 if (err < 0) { 851 844 dev_err(sor->dev, "failed to disable DP: %d\n", err); 852 - return err; 845 + goto unlock; 853 846 } 854 847 } 855 848 856 849 err = tegra_io_rail_power_off(TEGRA_IO_RAIL_LVDS); 857 850 if (err < 0) { 858 851 dev_err(sor->dev, "failed to power off I/O rail: %d\n", err); 859 - return err; 852 + goto unlock; 860 853 } 861 854 862 855 reset_control_assert(sor->rst); ··· 864 857 865 858 sor->enabled = false; 866 859 867 - return 0; 860 + unlock: 861 + mutex_unlock(&sor->lock); 862 + return err; 868 863 } 869 864 870 865 static int tegra_output_sor_setup_clock(struct tegra_output *output, ··· 961 952 size_t size, loff_t *ppos) 962 953 { 963 954 struct tegra_sor *sor = file->private_data; 955 + ssize_t num, err; 964 956 char buf[10]; 965 - ssize_t num; 966 957 u32 value; 967 - int err; 958 + 959 + mutex_lock(&sor->lock); 960 + 961 + if (!sor->enabled) { 962 + err = -EAGAIN; 963 + goto unlock; 964 + } 968 965 969 966 value = tegra_sor_readl(sor, SOR_STATE_1); 970 967 value &= ~SOR_STATE_ASY_CRC_MODE_MASK; ··· 986 971 987 972 err = tegra_sor_crc_wait(sor, 100); 988 973 if (err < 0) 989 - return err; 974 + goto unlock; 990 975 991 976 tegra_sor_writel(sor, SOR_CRC_A_RESET, SOR_CRC_A); 992 977 value = tegra_sor_readl(sor, SOR_CRC_B); 993 978 994 979 num = scnprintf(buf, sizeof(buf), "%08x\n", value); 995 980 996 - return simple_read_from_buffer(buffer, size, ppos, buf, num); 981 + err = simple_read_from_buffer(buffer, size, ppos, buf, num); 982 + 983 + unlock: 984 + mutex_unlock(&sor->lock); 985 + return err; 997 986 } 998 987 999 988 static const struct file_operations tegra_sor_crc_fops = { ··· 1186 1167 INIT_LIST_HEAD(&sor->client.list); 1187 1168 sor->client.ops = &sor_client_ops; 1188 1169 sor->client.dev = &pdev->dev; 1170 + 1171 + mutex_init(&sor->lock); 1189 1172 1190 1173 err = host1x_client_register(&sor->client); 1191 1174 if (err < 0) {