diff options
author | spujar <spujar@nvidia.com> | 2018-10-12 01:32:22 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-10-27 09:06:38 -0400 |
commit | 7e332a46ed47a328380fde917231783c7eed3c18 (patch) | |
tree | e973fd63ad5f0c541e0f072925fa7907b1b63a78 /sound/pci/hda | |
parent | f849f0bfbbc0639e7b6eb8b532eef1830f13735a (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.c | 15 |
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 | ||
768 | static void hda_tegra_probe_work(struct work_struct *work) | 771 | static void hda_tegra_probe_work(struct work_struct *work) |
@@ -831,14 +834,18 @@ out_free: | |||
831 | 834 | ||
832 | static int hda_tegra_remove(struct platform_device *pdev) | 835 | static 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 | ||
844 | static void hda_tegra_shutdown(struct platform_device *pdev) | 851 | static void hda_tegra_shutdown(struct platform_device *pdev) |