diff options
author | Pekon Gupta <pekon@ti.com> | 2013-10-24 08:50:25 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2013-11-07 02:33:11 -0500 |
commit | 70ba6d71ddcde8aa5a6e2b7f616e77b4bb96b984 (patch) | |
tree | d23df182928e29c7cea1b7048f221c553d32c665 /drivers/mtd/nand | |
parent | 32d42a855a6f1445373f3d680e9125344aca294c (diff) |
mtd: nand: omap: updated devm_xx for all resource allocation and free calls
"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt
Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.
- simplifies label for exiting probe during error
s/out_release_mem_region/return_error
Signed-off-by: Pekon Gupta <pekon@ti.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/omap2.c | 85 |
1 files changed, 35 insertions, 50 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 93aa35c8260c..ec40b8d10201 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1642,7 +1642,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1642 | return -ENODEV; | 1642 | return -ENODEV; |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL); | 1645 | info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info), |
1646 | GFP_KERNEL); | ||
1646 | if (!info) | 1647 | if (!info) |
1647 | return -ENOMEM; | 1648 | return -ENOMEM; |
1648 | 1649 | ||
@@ -1667,22 +1668,23 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1667 | if (res == NULL) { | 1668 | if (res == NULL) { |
1668 | err = -EINVAL; | 1669 | err = -EINVAL; |
1669 | dev_err(&pdev->dev, "error getting memory resource\n"); | 1670 | dev_err(&pdev->dev, "error getting memory resource\n"); |
1670 | goto out_free_info; | 1671 | goto return_error; |
1671 | } | 1672 | } |
1672 | 1673 | ||
1673 | info->phys_base = res->start; | 1674 | info->phys_base = res->start; |
1674 | info->mem_size = resource_size(res); | 1675 | info->mem_size = resource_size(res); |
1675 | 1676 | ||
1676 | if (!request_mem_region(info->phys_base, info->mem_size, | 1677 | if (!devm_request_mem_region(&pdev->dev, info->phys_base, |
1677 | pdev->dev.driver->name)) { | 1678 | info->mem_size, pdev->dev.driver->name)) { |
1678 | err = -EBUSY; | 1679 | err = -EBUSY; |
1679 | goto out_free_info; | 1680 | goto return_error; |
1680 | } | 1681 | } |
1681 | 1682 | ||
1682 | nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size); | 1683 | nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base, |
1684 | info->mem_size); | ||
1683 | if (!nand_chip->IO_ADDR_R) { | 1685 | if (!nand_chip->IO_ADDR_R) { |
1684 | err = -ENOMEM; | 1686 | err = -ENOMEM; |
1685 | goto out_release_mem_region; | 1687 | goto return_error; |
1686 | } | 1688 | } |
1687 | 1689 | ||
1688 | nand_chip->controller = &info->controller; | 1690 | nand_chip->controller = &info->controller; |
@@ -1710,14 +1712,14 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1710 | if (nand_scan_ident(mtd, 1, NULL)) { | 1712 | if (nand_scan_ident(mtd, 1, NULL)) { |
1711 | pr_err("nand device scan failed, may be bus-width mismatch\n"); | 1713 | pr_err("nand device scan failed, may be bus-width mismatch\n"); |
1712 | err = -ENXIO; | 1714 | err = -ENXIO; |
1713 | goto out_release_mem_region; | 1715 | goto return_error; |
1714 | } | 1716 | } |
1715 | 1717 | ||
1716 | /* check for small page devices */ | 1718 | /* check for small page devices */ |
1717 | if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) { | 1719 | if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) { |
1718 | pr_err("small page devices are not supported\n"); | 1720 | pr_err("small page devices are not supported\n"); |
1719 | err = -EINVAL; | 1721 | err = -EINVAL; |
1720 | goto out_release_mem_region; | 1722 | goto return_error; |
1721 | } | 1723 | } |
1722 | 1724 | ||
1723 | /* re-populate low-level callbacks based on xfer modes */ | 1725 | /* re-populate low-level callbacks based on xfer modes */ |
@@ -1745,7 +1747,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1745 | if (!info->dma) { | 1747 | if (!info->dma) { |
1746 | dev_err(&pdev->dev, "DMA engine request failed\n"); | 1748 | dev_err(&pdev->dev, "DMA engine request failed\n"); |
1747 | err = -ENXIO; | 1749 | err = -ENXIO; |
1748 | goto out_release_mem_region; | 1750 | goto return_error; |
1749 | } else { | 1751 | } else { |
1750 | struct dma_slave_config cfg; | 1752 | struct dma_slave_config cfg; |
1751 | 1753 | ||
@@ -1760,7 +1762,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1760 | if (err) { | 1762 | if (err) { |
1761 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", | 1763 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", |
1762 | err); | 1764 | err); |
1763 | goto out_release_mem_region; | 1765 | goto return_error; |
1764 | } | 1766 | } |
1765 | nand_chip->read_buf = omap_read_buf_dma_pref; | 1767 | nand_chip->read_buf = omap_read_buf_dma_pref; |
1766 | nand_chip->write_buf = omap_write_buf_dma_pref; | 1768 | nand_chip->write_buf = omap_write_buf_dma_pref; |
@@ -1772,30 +1774,32 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1772 | if (info->gpmc_irq_fifo <= 0) { | 1774 | if (info->gpmc_irq_fifo <= 0) { |
1773 | dev_err(&pdev->dev, "error getting fifo irq\n"); | 1775 | dev_err(&pdev->dev, "error getting fifo irq\n"); |
1774 | err = -ENODEV; | 1776 | err = -ENODEV; |
1775 | goto out_release_mem_region; | 1777 | goto return_error; |
1776 | } | 1778 | } |
1777 | err = request_irq(info->gpmc_irq_fifo, omap_nand_irq, | 1779 | err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo, |
1778 | IRQF_SHARED, "gpmc-nand-fifo", info); | 1780 | omap_nand_irq, IRQF_SHARED, |
1781 | "gpmc-nand-fifo", info); | ||
1779 | if (err) { | 1782 | if (err) { |
1780 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", | 1783 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", |
1781 | info->gpmc_irq_fifo, err); | 1784 | info->gpmc_irq_fifo, err); |
1782 | info->gpmc_irq_fifo = 0; | 1785 | info->gpmc_irq_fifo = 0; |
1783 | goto out_release_mem_region; | 1786 | goto return_error; |
1784 | } | 1787 | } |
1785 | 1788 | ||
1786 | info->gpmc_irq_count = platform_get_irq(pdev, 1); | 1789 | info->gpmc_irq_count = platform_get_irq(pdev, 1); |
1787 | if (info->gpmc_irq_count <= 0) { | 1790 | if (info->gpmc_irq_count <= 0) { |
1788 | dev_err(&pdev->dev, "error getting count irq\n"); | 1791 | dev_err(&pdev->dev, "error getting count irq\n"); |
1789 | err = -ENODEV; | 1792 | err = -ENODEV; |
1790 | goto out_release_mem_region; | 1793 | goto return_error; |
1791 | } | 1794 | } |
1792 | err = request_irq(info->gpmc_irq_count, omap_nand_irq, | 1795 | err = devm_request_irq(&pdev->dev, info->gpmc_irq_count, |
1793 | IRQF_SHARED, "gpmc-nand-count", info); | 1796 | omap_nand_irq, IRQF_SHARED, |
1797 | "gpmc-nand-count", info); | ||
1794 | if (err) { | 1798 | if (err) { |
1795 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", | 1799 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", |
1796 | info->gpmc_irq_count, err); | 1800 | info->gpmc_irq_count, err); |
1797 | info->gpmc_irq_count = 0; | 1801 | info->gpmc_irq_count = 0; |
1798 | goto out_release_mem_region; | 1802 | goto return_error; |
1799 | } | 1803 | } |
1800 | 1804 | ||
1801 | nand_chip->read_buf = omap_read_buf_irq_pref; | 1805 | nand_chip->read_buf = omap_read_buf_irq_pref; |
@@ -1807,7 +1811,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1807 | dev_err(&pdev->dev, | 1811 | dev_err(&pdev->dev, |
1808 | "xfer_type(%d) not supported!\n", pdata->xfer_type); | 1812 | "xfer_type(%d) not supported!\n", pdata->xfer_type); |
1809 | err = -EINVAL; | 1813 | err = -EINVAL; |
1810 | goto out_release_mem_region; | 1814 | goto return_error; |
1811 | } | 1815 | } |
1812 | 1816 | ||
1813 | /* populate MTD interface based on ECC scheme */ | 1817 | /* populate MTD interface based on ECC scheme */ |
@@ -1865,7 +1869,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1865 | #else | 1869 | #else |
1866 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | 1870 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); |
1867 | err = -EINVAL; | 1871 | err = -EINVAL; |
1868 | goto out_release_mem_region; | 1872 | goto return_error; |
1869 | #endif | 1873 | #endif |
1870 | 1874 | ||
1871 | case OMAP_ECC_BCH4_CODE_HW: | 1875 | case OMAP_ECC_BCH4_CODE_HW: |
@@ -1892,13 +1896,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1892 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { | 1896 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { |
1893 | pr_err("nand: error: could not initialize ELM\n"); | 1897 | pr_err("nand: error: could not initialize ELM\n"); |
1894 | err = -ENODEV; | 1898 | err = -ENODEV; |
1895 | goto out_release_mem_region; | 1899 | goto return_error; |
1896 | } | 1900 | } |
1897 | break; | 1901 | break; |
1898 | #else | 1902 | #else |
1899 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | 1903 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); |
1900 | err = -EINVAL; | 1904 | err = -EINVAL; |
1901 | goto out_release_mem_region; | 1905 | goto return_error; |
1902 | #endif | 1906 | #endif |
1903 | 1907 | ||
1904 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: | 1908 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: |
@@ -1926,13 +1930,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1926 | if (!nand_chip->ecc.priv) { | 1930 | if (!nand_chip->ecc.priv) { |
1927 | pr_err("nand: error: unable to use s/w BCH library\n"); | 1931 | pr_err("nand: error: unable to use s/w BCH library\n"); |
1928 | err = -EINVAL; | 1932 | err = -EINVAL; |
1929 | goto out_release_mem_region; | 1933 | goto return_error; |
1930 | } | 1934 | } |
1931 | break; | 1935 | break; |
1932 | #else | 1936 | #else |
1933 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | 1937 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); |
1934 | err = -EINVAL; | 1938 | err = -EINVAL; |
1935 | goto out_release_mem_region; | 1939 | goto return_error; |
1936 | #endif | 1940 | #endif |
1937 | 1941 | ||
1938 | case OMAP_ECC_BCH8_CODE_HW: | 1942 | case OMAP_ECC_BCH8_CODE_HW: |
@@ -1951,7 +1955,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1951 | /* This ECC scheme requires ELM H/W block */ | 1955 | /* This ECC scheme requires ELM H/W block */ |
1952 | if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) { | 1956 | if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) { |
1953 | pr_err("nand: error: could not initialize ELM\n"); | 1957 | pr_err("nand: error: could not initialize ELM\n"); |
1954 | goto out_release_mem_region; | 1958 | goto return_error; |
1955 | } | 1959 | } |
1956 | /* define ECC layout */ | 1960 | /* define ECC layout */ |
1957 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1961 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
@@ -1964,13 +1968,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1964 | #else | 1968 | #else |
1965 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | 1969 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); |
1966 | err = -EINVAL; | 1970 | err = -EINVAL; |
1967 | goto out_release_mem_region; | 1971 | goto return_error; |
1968 | #endif | 1972 | #endif |
1969 | 1973 | ||
1970 | default: | 1974 | default: |
1971 | pr_err("nand: error: invalid or unsupported ECC scheme\n"); | 1975 | pr_err("nand: error: invalid or unsupported ECC scheme\n"); |
1972 | err = -EINVAL; | 1976 | err = -EINVAL; |
1973 | goto out_release_mem_region; | 1977 | goto return_error; |
1974 | } | 1978 | } |
1975 | 1979 | ||
1976 | /* populate remaining ECC layout data */ | 1980 | /* populate remaining ECC layout data */ |
@@ -1983,13 +1987,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1983 | pr_err("not enough OOB bytes required = %d, available=%d\n", | 1987 | pr_err("not enough OOB bytes required = %d, available=%d\n", |
1984 | ecclayout->eccbytes, mtd->oobsize); | 1988 | ecclayout->eccbytes, mtd->oobsize); |
1985 | err = -EINVAL; | 1989 | err = -EINVAL; |
1986 | goto out_release_mem_region; | 1990 | goto return_error; |
1987 | } | 1991 | } |
1988 | 1992 | ||
1989 | /* second phase scan */ | 1993 | /* second phase scan */ |
1990 | if (nand_scan_tail(mtd)) { | 1994 | if (nand_scan_tail(mtd)) { |
1991 | err = -ENXIO; | 1995 | err = -ENXIO; |
1992 | goto out_release_mem_region; | 1996 | goto return_error; |
1993 | } | 1997 | } |
1994 | 1998 | ||
1995 | ppdata.of_node = pdata->of_node; | 1999 | ppdata.of_node = pdata->of_node; |
@@ -2000,21 +2004,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
2000 | 2004 | ||
2001 | return 0; | 2005 | return 0; |
2002 | 2006 | ||
2003 | out_release_mem_region: | 2007 | return_error: |
2004 | if (info->dma) | 2008 | if (info->dma) |
2005 | dma_release_channel(info->dma); | 2009 | dma_release_channel(info->dma); |
2006 | if (info->gpmc_irq_count > 0) | ||
2007 | free_irq(info->gpmc_irq_count, info); | ||
2008 | if (info->gpmc_irq_fifo > 0) | ||
2009 | free_irq(info->gpmc_irq_fifo, info); | ||
2010 | release_mem_region(info->phys_base, info->mem_size); | ||
2011 | out_free_info: | ||
2012 | if (nand_chip->ecc.priv) { | 2010 | if (nand_chip->ecc.priv) { |
2013 | nand_bch_free(nand_chip->ecc.priv); | 2011 | nand_bch_free(nand_chip->ecc.priv); |
2014 | nand_chip->ecc.priv = NULL; | 2012 | nand_chip->ecc.priv = NULL; |
2015 | } | 2013 | } |
2016 | kfree(info); | ||
2017 | |||
2018 | return err; | 2014 | return err; |
2019 | } | 2015 | } |
2020 | 2016 | ||
@@ -2028,20 +2024,9 @@ static int omap_nand_remove(struct platform_device *pdev) | |||
2028 | nand_bch_free(nand_chip->ecc.priv); | 2024 | nand_bch_free(nand_chip->ecc.priv); |
2029 | nand_chip->ecc.priv = NULL; | 2025 | nand_chip->ecc.priv = NULL; |
2030 | } | 2026 | } |
2031 | |||
2032 | if (info->dma) | 2027 | if (info->dma) |
2033 | dma_release_channel(info->dma); | 2028 | dma_release_channel(info->dma); |
2034 | |||
2035 | if (info->gpmc_irq_count > 0) | ||
2036 | free_irq(info->gpmc_irq_count, info); | ||
2037 | if (info->gpmc_irq_fifo > 0) | ||
2038 | free_irq(info->gpmc_irq_fifo, info); | ||
2039 | |||
2040 | /* Release NAND device, its internal structures and partitions */ | ||
2041 | nand_release(mtd); | 2029 | nand_release(mtd); |
2042 | iounmap(nand_chip->IO_ADDR_R); | ||
2043 | release_mem_region(info->phys_base, info->mem_size); | ||
2044 | kfree(info); | ||
2045 | return 0; | 2030 | return 0; |
2046 | } | 2031 | } |
2047 | 2032 | ||