summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorspujar <spujar@nvidia.com>2018-10-12 01:32:22 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-10-27 09:06:38 -0400
commit7e332a46ed47a328380fde917231783c7eed3c18 (patch)
treee973fd63ad5f0c541e0f072925fa7907b1b63a78 /sound/pci/hda
parentf849f0bfbbc0639e7b6eb8b532eef1830f13735a (diff)
ALSA: hda: fix crashes in remove path
SErrors and kernel panic are seen when driver is unloaded. Following is the trace during hda_tegra_remove_sysfs, [<ffffff800104ea5c>] hda_tegra_remove_sysfs.isra.1+0x84/0xa8 [<ffffff8008761580>] platform_drv_remove+0x30/0x50 [<ffffff800875f1f0>] driver_detach+0xc8/0xd0 [<ffffff800875ddb4>] bus_remove_driver+0x64/0ister+0x34/0x58 [<ffffff8008761688>] platform_driver_unregister+0x20/0x30 [<ffffff80081524b8>] SyS_delete_module+0x1c8/0x210 [<ffffff8008083040>] el0_svc_naked+0x<2> CPU3: SError detected, daif=1c0, spsr=0x40c000c5, mpidr=80000101, esr=be000000 CPU1: SError detected, daif=140, spsr=0x20400145, mpidr=80000001, esr=be000000 Following trace is seen in snd_card_free path, PC is at hda_tegra_readw+0x20/0x38 [snd_hda_tegra] LR is at snd_hdac_bus_send_c3e07498f8 x26: ffffffc3a7baf904 x25: ffffff8009d78000 x24: ffffff8009f810d8 x23: ffffff9709] x15: aaaaaaaaaaaaaaab x14: 0000000000000002 x13: 0000000000000003 x12: 0000000000000018 x9 : 0000000000000000 x8 : 0001000000000000 x7 : 0000000000000030 x6 : ffffffc3ede8c160 x3 : 0000000000010000 x2 : 0000000000010000 x1 : ffffff800104e0b8 x0 : 000000000000 [<ffffff8008d1e808>]snd_hdac_bus_send_cmd+0x88/0x100 [<ffffff8008ccf294>] azx_send_cmd.part.7+0x144/0x240 [<ffffff8008d1c72c>] snd_hdac_codec_read+0x6c/0xb0 [<ffffff8008cc6a60>] hda_call_codec_resume+0x50/0x138 [<ffffff8008cc6b84>] hda_codec_run2c/0x40 [<ffffff800875da24>] bus_remove_device+0xe4/0x160 [<ffffff80087594e4>] device_del181.929313] [<ffffff8008ca120c>] snd_device_free_all+0x34/0x50 [<ffffff8008c9a1dc>] release_card_device+0x2ccard_free+0x70/0xa8 [<ffffff800104eadc>] hda_tegra_remove+0x4c/0x58 [snd_hda_tegra] [<ffffff800875ff74>] driver_unregister+0x34/0x58 [<ffffff8008761688>] platfvc_naked+0x34/0x38 This patch adds following to avoid such errors. - after kobject_put() set obj reference to NULL - free sound card first and then call runtime suspend Bug 200453666 Change-Id: I55c58661890734dd0718fec8e0b2b944ef8d4484 Signed-off-by: spujar <spujar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1925280 (cherry picked from commit 1fff9e75c6202d1657d4d0dffab4df633075ef80) Reviewed-on: https://git-master.nvidia.com/r/1935132 GVS: Gerrit_Virtual_Submit Reviewed-by: Mohan Kumar D <mkumard@nvidia.com> Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_tegra.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index d1b37d959..08f0ce256 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -722,6 +722,7 @@ static int hda_tegra_create_sysfs(struct hda_tegra *hda)
722 dev_info(hda->dev, "error in getting switch name" 722 dev_info(hda->dev, "error in getting switch name"
723 " for hda_pcm_id(%d)\n", apcm->info->device); 723 " for hda_pcm_id(%d)\n", apcm->info->device);
724 kobject_put(pcm_dev->kobj); 724 kobject_put(pcm_dev->kobj);
725 pcm_dev->kobj = NULL;
725 continue; 726 continue;
726 } 727 }
727 728
@@ -760,9 +761,11 @@ static void hda_tegra_remove_sysfs(struct device *dev)
760 sysfs_remove_file(pcm_dev->kobj, 761 sysfs_remove_file(pcm_dev->kobj,
761 &pcm_dev->name_attr.attr); 762 &pcm_dev->name_attr.attr);
762 kobject_put(pcm_dev->kobj); 763 kobject_put(pcm_dev->kobj);
764 pcm_dev->kobj = NULL;
763 } 765 }
764 } 766 }
765 kobject_put(hda->kobj); 767 kobject_put(hda->kobj);
768 hda->kobj = NULL;
766} 769}
767 770
768static void hda_tegra_probe_work(struct work_struct *work) 771static void hda_tegra_probe_work(struct work_struct *work)
@@ -831,14 +834,18 @@ out_free:
831 834
832static int hda_tegra_remove(struct platform_device *pdev) 835static int hda_tegra_remove(struct platform_device *pdev)
833{ 836{
834 pm_runtime_disable(&pdev->dev); 837 int ret;
835 if (!pm_runtime_status_suspended(&pdev->dev))
836 hda_tegra_runtime_suspend(&pdev->dev);
837 838
838 /* remove sysfs files */ 839 /* remove sysfs files */
839 hda_tegra_remove_sysfs(&pdev->dev); 840 hda_tegra_remove_sysfs(&pdev->dev);
840 841
841 return snd_card_free(dev_get_drvdata(&pdev->dev)); 842 ret = snd_card_free(dev_get_drvdata(&pdev->dev));
843
844 pm_runtime_disable(&pdev->dev);
845 if (!pm_runtime_status_suspended(&pdev->dev))
846 hda_tegra_runtime_suspend(&pdev->dev);
847
848 return ret;
842} 849}
843 850
844static void hda_tegra_shutdown(struct platform_device *pdev) 851static void hda_tegra_shutdown(struct platform_device *pdev)