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

drm/tegra: sor: Move register programming out of ->init()

The hardware is not guaranteed to be enabled during execution of the
tegra_sor_init() function, which can lead to a crash on some Tegra SoCs.
Fix this by moving all register programming into code that is guaranteed
to only be executed when the hardware is enabled.

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

+11 -13
+11 -13
drivers/gpu/drm/tegra/sor.c
··· 2161 2161 { 2162 2162 u32 value; 2163 2163 2164 + /* 2165 + * Enable and unmask the HDA codec SCRATCH0 register interrupt. This 2166 + * is used for interoperability between the HDA codec driver and the 2167 + * HDMI/DP driver. 2168 + */ 2169 + value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0; 2170 + tegra_sor_writel(sor, value, SOR_INT_ENABLE); 2171 + tegra_sor_writel(sor, value, SOR_INT_MASK); 2172 + 2164 2173 tegra_sor_write_eld(sor); 2165 2174 2166 2175 value = SOR_AUDIO_HDA_PRESENSE_ELDV | SOR_AUDIO_HDA_PRESENSE_PD; ··· 2179 2170 static void tegra_sor_audio_unprepare(struct tegra_sor *sor) 2180 2171 { 2181 2172 tegra_sor_writel(sor, 0, SOR_AUDIO_HDA_PRESENSE); 2173 + tegra_sor_writel(sor, 0, SOR_INT_MASK); 2174 + tegra_sor_writel(sor, 0, SOR_INT_ENABLE); 2182 2175 } 2183 2176 2184 2177 static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor) ··· 2822 2811 struct tegra_sor *sor = host1x_client_to_sor(client); 2823 2812 int connector = DRM_MODE_CONNECTOR_Unknown; 2824 2813 int encoder = DRM_MODE_ENCODER_NONE; 2825 - u32 value; 2826 2814 int err; 2827 2815 2828 2816 if (!sor->aux) { ··· 2924 2914 if (err < 0) 2925 2915 return err; 2926 2916 2927 - /* 2928 - * Enable and unmask the HDA codec SCRATCH0 register interrupt. This 2929 - * is used for interoperability between the HDA codec driver and the 2930 - * HDMI/DP driver. 2931 - */ 2932 - value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0; 2933 - tegra_sor_writel(sor, value, SOR_INT_ENABLE); 2934 - tegra_sor_writel(sor, value, SOR_INT_MASK); 2935 - 2936 2917 return 0; 2937 2918 } 2938 2919 ··· 2931 2930 { 2932 2931 struct tegra_sor *sor = host1x_client_to_sor(client); 2933 2932 int err; 2934 - 2935 - tegra_sor_writel(sor, 0, SOR_INT_MASK); 2936 - tegra_sor_writel(sor, 0, SOR_INT_ENABLE); 2937 2933 2938 2934 tegra_output_exit(&sor->output); 2939 2935