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

ASoC: stm32: sai: fix device and OF node leaks on

Merge series from Johan Hovold <johan@kernel.org>:

This series fixes device and OF node reference leaks during probe and
a clock prepare imbalance on probe failures.

Included is a related cleanup of an error path.

+44 -27
+4 -10
sound/soc/stm/stm32_sai.c
··· 138 138 if (!pdev) { 139 139 dev_err(&sai_client->pdev->dev, 140 140 "Device not found for node %pOFn\n", np_provider); 141 - of_node_put(np_provider); 142 141 return -ENODEV; 143 142 } 144 143 145 144 sai_provider = platform_get_drvdata(pdev); 145 + put_device(&pdev->dev); 146 146 if (!sai_provider) { 147 147 dev_err(&sai_client->pdev->dev, 148 148 "SAI sync provider data not found\n"); 149 - ret = -EINVAL; 150 - goto error; 149 + return -EINVAL; 151 150 } 152 151 153 152 /* Configure sync client */ 154 153 ret = stm32_sai_sync_conf_client(sai_client, synci); 155 154 if (ret < 0) 156 - goto error; 155 + return ret; 157 156 158 157 /* Configure sync provider */ 159 - ret = stm32_sai_sync_conf_provider(sai_provider, synco); 160 - 161 - error: 162 - put_device(&pdev->dev); 163 - of_node_put(np_provider); 164 - return ret; 158 + return stm32_sai_sync_conf_provider(sai_provider, synco); 165 159 } 166 160 167 161 static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai)
+40 -17
sound/soc/stm/stm32_sai_sub.c
··· 1586 1586 dev_err(&pdev->dev, 1587 1587 "External synchro not supported\n"); 1588 1588 of_node_put(args.np); 1589 - return -EINVAL; 1589 + ret = -EINVAL; 1590 + goto err_put_sync_provider; 1590 1591 } 1591 1592 sai->sync = SAI_SYNC_EXTERNAL; 1592 1593 ··· 1596 1595 (sai->synci > (SAI_GCR_SYNCIN_MAX + 1))) { 1597 1596 dev_err(&pdev->dev, "Wrong SAI index\n"); 1598 1597 of_node_put(args.np); 1599 - return -EINVAL; 1598 + ret = -EINVAL; 1599 + goto err_put_sync_provider; 1600 1600 } 1601 1601 1602 1602 if (of_property_match_string(args.np, "compatible", ··· 1611 1609 if (!sai->synco) { 1612 1610 dev_err(&pdev->dev, "Unknown SAI sub-block\n"); 1613 1611 of_node_put(args.np); 1614 - return -EINVAL; 1612 + ret = -EINVAL; 1613 + goto err_put_sync_provider; 1615 1614 } 1616 1615 } 1617 1616 ··· 1622 1619 1623 1620 of_node_put(args.np); 1624 1621 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck"); 1625 - if (IS_ERR(sai->sai_ck)) 1626 - return dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), 1627 - "Missing kernel clock sai_ck\n"); 1622 + if (IS_ERR(sai->sai_ck)) { 1623 + ret = dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), 1624 + "Missing kernel clock sai_ck\n"); 1625 + goto err_put_sync_provider; 1626 + } 1628 1627 1629 1628 ret = clk_prepare(sai->pdata->pclk); 1630 1629 if (ret < 0) 1631 - return ret; 1630 + goto err_put_sync_provider; 1632 1631 1633 1632 if (STM_SAI_IS_F4(sai->pdata)) 1634 1633 return 0; ··· 1639 1634 if (of_property_present(np, "#clock-cells")) { 1640 1635 ret = stm32_sai_add_mclk_provider(sai); 1641 1636 if (ret < 0) 1642 - return ret; 1637 + goto err_unprepare_pclk; 1643 1638 } else { 1644 1639 sai->sai_mclk = devm_clk_get_optional(&pdev->dev, "MCLK"); 1645 - if (IS_ERR(sai->sai_mclk)) 1646 - return PTR_ERR(sai->sai_mclk); 1640 + if (IS_ERR(sai->sai_mclk)) { 1641 + ret = PTR_ERR(sai->sai_mclk); 1642 + goto err_unprepare_pclk; 1643 + } 1647 1644 } 1648 1645 1649 1646 return 0; 1647 + 1648 + err_unprepare_pclk: 1649 + clk_unprepare(sai->pdata->pclk); 1650 + err_put_sync_provider: 1651 + of_node_put(sai->np_sync_provider); 1652 + 1653 + return ret; 1650 1654 } 1651 1655 1652 1656 static int stm32_sai_sub_probe(struct platform_device *pdev) ··· 1702 1688 IRQF_SHARED, dev_name(&pdev->dev), sai); 1703 1689 if (ret) { 1704 1690 dev_err(&pdev->dev, "IRQ request returned %d\n", ret); 1705 - return ret; 1691 + goto err_unprepare_pclk; 1706 1692 } 1707 1693 1708 1694 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) 1709 1695 conf = &stm32_sai_pcm_config_spdif; 1710 1696 1711 1697 ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0); 1712 - if (ret) 1713 - return dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); 1698 + if (ret) { 1699 + ret = dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); 1700 + goto err_unprepare_pclk; 1701 + } 1714 1702 1715 1703 ret = snd_soc_register_component(&pdev->dev, &stm32_component, 1716 1704 &sai->cpu_dai_drv, 1); 1717 - if (ret) { 1718 - snd_dmaengine_pcm_unregister(&pdev->dev); 1719 - return ret; 1720 - } 1705 + if (ret) 1706 + goto err_deregister_pcm_dma; 1721 1707 1722 1708 pm_runtime_enable(&pdev->dev); 1723 1709 1724 1710 return 0; 1711 + 1712 + err_deregister_pcm_dma: 1713 + snd_dmaengine_pcm_unregister(&pdev->dev); 1714 + err_unprepare_pclk: 1715 + clk_unprepare(sai->pdata->pclk); 1716 + of_node_put(sai->np_sync_provider); 1717 + 1718 + return ret; 1725 1719 } 1726 1720 1727 1721 static void stm32_sai_sub_remove(struct platform_device *pdev) ··· 1740 1718 snd_dmaengine_pcm_unregister(&pdev->dev); 1741 1719 snd_soc_unregister_component(&pdev->dev); 1742 1720 pm_runtime_disable(&pdev->dev); 1721 + of_node_put(sai->np_sync_provider); 1743 1722 } 1744 1723 1745 1724 static int stm32_sai_sub_suspend(struct device *dev)