diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2018-03-02 17:42:01 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-03-09 14:01:19 -0500 |
commit | ca7c22fc9e8d16b11b8be81254d5f59c5a9f5bcf (patch) | |
tree | cf6158cab52311a251c54d174490a1657a83edb5 | |
parent | 7d6e2143bed7dd61dac3a00321292b36d63c2a2f (diff) |
serial: mxs-auart: disable clks of Alphascale ASM9260
In case of Alphascale ASM9260 probe() enables s->clk and s->clk_ahb
via mxs_get_clks(), but there is no disable of the clocks.
The patch adds it to error paths and to mxs_auart_remove().
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Fixes: 254da0d753fb ("serial: mxs-auart: add Alphascale ASM9260 support")
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index caa8a41b6e71..76aa289652f7 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -1678,8 +1678,10 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1678 | return ret; | 1678 | return ret; |
1679 | 1679 | ||
1680 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1680 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1681 | if (!r) | 1681 | if (!r) { |
1682 | return -ENXIO; | 1682 | ret = -ENXIO; |
1683 | goto out_disable_clks; | ||
1684 | } | ||
1683 | 1685 | ||
1684 | s->port.mapbase = r->start; | 1686 | s->port.mapbase = r->start; |
1685 | s->port.membase = ioremap(r->start, resource_size(r)); | 1687 | s->port.membase = ioremap(r->start, resource_size(r)); |
@@ -1694,21 +1696,23 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1694 | s->mctrl_prev = 0; | 1696 | s->mctrl_prev = 0; |
1695 | 1697 | ||
1696 | irq = platform_get_irq(pdev, 0); | 1698 | irq = platform_get_irq(pdev, 0); |
1697 | if (irq < 0) | 1699 | if (irq < 0) { |
1698 | return irq; | 1700 | ret = irq; |
1701 | goto out_disable_clks; | ||
1702 | } | ||
1699 | 1703 | ||
1700 | s->port.irq = irq; | 1704 | s->port.irq = irq; |
1701 | ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0, | 1705 | ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0, |
1702 | dev_name(&pdev->dev), s); | 1706 | dev_name(&pdev->dev), s); |
1703 | if (ret) | 1707 | if (ret) |
1704 | return ret; | 1708 | goto out_disable_clks; |
1705 | 1709 | ||
1706 | platform_set_drvdata(pdev, s); | 1710 | platform_set_drvdata(pdev, s); |
1707 | 1711 | ||
1708 | ret = mxs_auart_init_gpios(s, &pdev->dev); | 1712 | ret = mxs_auart_init_gpios(s, &pdev->dev); |
1709 | if (ret) { | 1713 | if (ret) { |
1710 | dev_err(&pdev->dev, "Failed to initialize GPIOs.\n"); | 1714 | dev_err(&pdev->dev, "Failed to initialize GPIOs.\n"); |
1711 | return ret; | 1715 | goto out_disable_clks; |
1712 | } | 1716 | } |
1713 | 1717 | ||
1714 | /* | 1718 | /* |
@@ -1716,7 +1720,7 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1716 | */ | 1720 | */ |
1717 | ret = mxs_auart_request_gpio_irq(s); | 1721 | ret = mxs_auart_request_gpio_irq(s); |
1718 | if (ret) | 1722 | if (ret) |
1719 | return ret; | 1723 | goto out_disable_clks; |
1720 | 1724 | ||
1721 | auart_port[s->port.line] = s; | 1725 | auart_port[s->port.line] = s; |
1722 | 1726 | ||
@@ -1724,7 +1728,7 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1724 | 1728 | ||
1725 | ret = uart_add_one_port(&auart_driver, &s->port); | 1729 | ret = uart_add_one_port(&auart_driver, &s->port); |
1726 | if (ret) | 1730 | if (ret) |
1727 | goto out_disable_clks_free_qpio_irq; | 1731 | goto out_free_qpio_irq; |
1728 | 1732 | ||
1729 | /* ASM9260 don't have version reg */ | 1733 | /* ASM9260 don't have version reg */ |
1730 | if (is_asm9260_auart(s)) { | 1734 | if (is_asm9260_auart(s)) { |
@@ -1738,13 +1742,15 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1738 | 1742 | ||
1739 | return 0; | 1743 | return 0; |
1740 | 1744 | ||
1741 | out_disable_clks_free_qpio_irq: | 1745 | out_free_qpio_irq: |
1742 | if (s->clk) | ||
1743 | clk_disable_unprepare(s->clk_ahb); | ||
1744 | if (s->clk_ahb) | ||
1745 | clk_disable_unprepare(s->clk_ahb); | ||
1746 | mxs_auart_free_gpio_irq(s); | 1746 | mxs_auart_free_gpio_irq(s); |
1747 | auart_port[pdev->id] = NULL; | 1747 | auart_port[pdev->id] = NULL; |
1748 | |||
1749 | out_disable_clks: | ||
1750 | if (is_asm9260_auart(s)) { | ||
1751 | clk_disable_unprepare(s->clk); | ||
1752 | clk_disable_unprepare(s->clk_ahb); | ||
1753 | } | ||
1748 | return ret; | 1754 | return ret; |
1749 | } | 1755 | } |
1750 | 1756 | ||
@@ -1755,6 +1761,10 @@ static int mxs_auart_remove(struct platform_device *pdev) | |||
1755 | uart_remove_one_port(&auart_driver, &s->port); | 1761 | uart_remove_one_port(&auart_driver, &s->port); |
1756 | auart_port[pdev->id] = NULL; | 1762 | auart_port[pdev->id] = NULL; |
1757 | mxs_auart_free_gpio_irq(s); | 1763 | mxs_auart_free_gpio_irq(s); |
1764 | if (is_asm9260_auart(s)) { | ||
1765 | clk_disable_unprepare(s->clk); | ||
1766 | clk_disable_unprepare(s->clk_ahb); | ||
1767 | } | ||
1758 | 1768 | ||
1759 | return 0; | 1769 | return 0; |
1760 | } | 1770 | } |