diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2010-10-01 07:33:13 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-10-12 23:37:37 -0400 |
commit | f9d629c737cb6687216a0c540b5466a4bd8b070a (patch) | |
tree | d3bbbd872389b5fdc7f4b1ff42d5069d7e0df930 /drivers/spi | |
parent | 5a1c98be1de165c8ad1bd5343a5d779230669489 (diff) |
spi/pl022: fix dubious allocation staticize platform data
This removes some dubious allocation of a local chipinfo struct
in favor of a constant preset, tagging that one const revealed
further problems with platform data being modified so fixed up
these too.
Reported-by: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/amba-pl022.c | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 19d54aa31a36..fb3d1b31772d 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -1593,7 +1593,7 @@ static int destroy_queue(struct pl022 *pl022) | |||
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | static int verify_controller_parameters(struct pl022 *pl022, | 1595 | static int verify_controller_parameters(struct pl022 *pl022, |
1596 | struct pl022_config_chip *chip_info) | 1596 | struct pl022_config_chip const *chip_info) |
1597 | { | 1597 | { |
1598 | if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI) | 1598 | if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI) |
1599 | || (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) { | 1599 | || (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) { |
@@ -1614,12 +1614,6 @@ static int verify_controller_parameters(struct pl022 *pl022, | |||
1614 | "hierarchy is configured incorrectly\n"); | 1614 | "hierarchy is configured incorrectly\n"); |
1615 | return -EINVAL; | 1615 | return -EINVAL; |
1616 | } | 1616 | } |
1617 | if (((chip_info->clk_freq).cpsdvsr < CPSDVR_MIN) | ||
1618 | || ((chip_info->clk_freq).cpsdvsr > CPSDVR_MAX)) { | ||
1619 | dev_err(&pl022->adev->dev, | ||
1620 | "cpsdvsr is configured incorrectly\n"); | ||
1621 | return -EINVAL; | ||
1622 | } | ||
1623 | if ((chip_info->com_mode != INTERRUPT_TRANSFER) | 1617 | if ((chip_info->com_mode != INTERRUPT_TRANSFER) |
1624 | && (chip_info->com_mode != DMA_TRANSFER) | 1618 | && (chip_info->com_mode != DMA_TRANSFER) |
1625 | && (chip_info->com_mode != POLLING_TRANSFER)) { | 1619 | && (chip_info->com_mode != POLLING_TRANSFER)) { |
@@ -1671,11 +1665,6 @@ static int verify_controller_parameters(struct pl022 *pl022, | |||
1671 | return -EINVAL; | 1665 | return -EINVAL; |
1672 | } | 1666 | } |
1673 | } | 1667 | } |
1674 | if (chip_info->cs_control == NULL) { | ||
1675 | dev_warn(&pl022->adev->dev, | ||
1676 | "Chip Select Function is NULL for this chip\n"); | ||
1677 | chip_info->cs_control = null_cs_control; | ||
1678 | } | ||
1679 | return 0; | 1668 | return 0; |
1680 | } | 1669 | } |
1681 | 1670 | ||
@@ -1775,6 +1764,25 @@ static int calculate_effective_freq(struct pl022 *pl022, | |||
1775 | return 0; | 1764 | return 0; |
1776 | } | 1765 | } |
1777 | 1766 | ||
1767 | |||
1768 | /* | ||
1769 | * A piece of default chip info unless the platform | ||
1770 | * supplies it. | ||
1771 | */ | ||
1772 | static const struct pl022_config_chip pl022_default_chip_info = { | ||
1773 | .com_mode = POLLING_TRANSFER, | ||
1774 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | ||
1775 | .hierarchy = SSP_SLAVE, | ||
1776 | .slave_tx_disable = DO_NOT_DRIVE_TX, | ||
1777 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | ||
1778 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | ||
1779 | .ctrl_len = SSP_BITS_8, | ||
1780 | .wait_state = SSP_MWIRE_WAIT_ZERO, | ||
1781 | .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, | ||
1782 | .cs_control = null_cs_control, | ||
1783 | }; | ||
1784 | |||
1785 | |||
1778 | /** | 1786 | /** |
1779 | * pl022_setup - setup function registered to SPI master framework | 1787 | * pl022_setup - setup function registered to SPI master framework |
1780 | * @spi: spi device which is requesting setup | 1788 | * @spi: spi device which is requesting setup |
@@ -1789,8 +1797,9 @@ static int calculate_effective_freq(struct pl022 *pl022, | |||
1789 | */ | 1797 | */ |
1790 | static int pl022_setup(struct spi_device *spi) | 1798 | static int pl022_setup(struct spi_device *spi) |
1791 | { | 1799 | { |
1792 | struct pl022_config_chip *chip_info; | 1800 | struct pl022_config_chip const *chip_info; |
1793 | struct chip_data *chip; | 1801 | struct chip_data *chip; |
1802 | struct ssp_clock_params clk_freq; | ||
1794 | int status = 0; | 1803 | int status = 0; |
1795 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); | 1804 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); |
1796 | unsigned int bits = spi->bits_per_word; | 1805 | unsigned int bits = spi->bits_per_word; |
@@ -1817,40 +1826,13 @@ static int pl022_setup(struct spi_device *spi) | |||
1817 | chip_info = spi->controller_data; | 1826 | chip_info = spi->controller_data; |
1818 | 1827 | ||
1819 | if (chip_info == NULL) { | 1828 | if (chip_info == NULL) { |
1829 | chip_info = &pl022_default_chip_info; | ||
1820 | /* spi_board_info.controller_data not is supplied */ | 1830 | /* spi_board_info.controller_data not is supplied */ |
1821 | dev_dbg(&spi->dev, | 1831 | dev_dbg(&spi->dev, |
1822 | "using default controller_data settings\n"); | 1832 | "using default controller_data settings\n"); |
1823 | 1833 | } else | |
1824 | chip_info = | ||
1825 | kzalloc(sizeof(struct pl022_config_chip), GFP_KERNEL); | ||
1826 | |||
1827 | if (!chip_info) { | ||
1828 | dev_err(&spi->dev, | ||
1829 | "cannot allocate controller data\n"); | ||
1830 | status = -ENOMEM; | ||
1831 | goto err_first_setup; | ||
1832 | } | ||
1833 | |||
1834 | dev_dbg(&spi->dev, "allocated memory for controller data\n"); | ||
1835 | |||
1836 | /* | ||
1837 | * Set controller data default values: | ||
1838 | * Polling is supported by default | ||
1839 | */ | ||
1840 | chip_info->com_mode = POLLING_TRANSFER; | ||
1841 | chip_info->iface = SSP_INTERFACE_MOTOROLA_SPI; | ||
1842 | chip_info->hierarchy = SSP_SLAVE; | ||
1843 | chip_info->slave_tx_disable = DO_NOT_DRIVE_TX; | ||
1844 | chip_info->rx_lev_trig = SSP_RX_1_OR_MORE_ELEM; | ||
1845 | chip_info->tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC; | ||
1846 | chip_info->ctrl_len = SSP_BITS_8; | ||
1847 | chip_info->wait_state = SSP_MWIRE_WAIT_ZERO; | ||
1848 | chip_info->duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX; | ||
1849 | chip_info->cs_control = null_cs_control; | ||
1850 | } else { | ||
1851 | dev_dbg(&spi->dev, | 1834 | dev_dbg(&spi->dev, |
1852 | "using user supplied controller_data settings\n"); | 1835 | "using user supplied controller_data settings\n"); |
1853 | } | ||
1854 | 1836 | ||
1855 | /* | 1837 | /* |
1856 | * We can override with custom divisors, else we use the board | 1838 | * We can override with custom divisors, else we use the board |
@@ -1860,22 +1842,37 @@ static int pl022_setup(struct spi_device *spi) | |||
1860 | && (0 == chip_info->clk_freq.scr)) { | 1842 | && (0 == chip_info->clk_freq.scr)) { |
1861 | status = calculate_effective_freq(pl022, | 1843 | status = calculate_effective_freq(pl022, |
1862 | spi->max_speed_hz, | 1844 | spi->max_speed_hz, |
1863 | &chip_info->clk_freq); | 1845 | &clk_freq); |
1864 | if (status < 0) | 1846 | if (status < 0) |
1865 | goto err_config_params; | 1847 | goto err_config_params; |
1866 | } else { | 1848 | } else { |
1867 | if ((chip_info->clk_freq.cpsdvsr % 2) != 0) | 1849 | memcpy(&clk_freq, &chip_info->clk_freq, sizeof(clk_freq)); |
1868 | chip_info->clk_freq.cpsdvsr = | 1850 | if ((clk_freq.cpsdvsr % 2) != 0) |
1869 | chip_info->clk_freq.cpsdvsr - 1; | 1851 | clk_freq.cpsdvsr = |
1852 | clk_freq.cpsdvsr - 1; | ||
1870 | } | 1853 | } |
1854 | if ((clk_freq.cpsdvsr < CPSDVR_MIN) | ||
1855 | || (clk_freq.cpsdvsr > CPSDVR_MAX)) { | ||
1856 | dev_err(&spi->dev, | ||
1857 | "cpsdvsr is configured incorrectly\n"); | ||
1858 | goto err_config_params; | ||
1859 | } | ||
1860 | |||
1861 | |||
1871 | status = verify_controller_parameters(pl022, chip_info); | 1862 | status = verify_controller_parameters(pl022, chip_info); |
1872 | if (status) { | 1863 | if (status) { |
1873 | dev_err(&spi->dev, "controller data is incorrect"); | 1864 | dev_err(&spi->dev, "controller data is incorrect"); |
1874 | goto err_config_params; | 1865 | goto err_config_params; |
1875 | } | 1866 | } |
1867 | |||
1876 | /* Now set controller state based on controller data */ | 1868 | /* Now set controller state based on controller data */ |
1877 | chip->xfer_type = chip_info->com_mode; | 1869 | chip->xfer_type = chip_info->com_mode; |
1878 | chip->cs_control = chip_info->cs_control; | 1870 | if (!chip_info->cs_control) { |
1871 | chip->cs_control = null_cs_control; | ||
1872 | dev_warn(&spi->dev, | ||
1873 | "chip select function is NULL for this chip\n"); | ||
1874 | } else | ||
1875 | chip->cs_control = chip_info->cs_control; | ||
1879 | 1876 | ||
1880 | if (bits <= 3) { | 1877 | if (bits <= 3) { |
1881 | /* PL022 doesn't support less than 4-bits */ | 1878 | /* PL022 doesn't support less than 4-bits */ |
@@ -1932,7 +1929,7 @@ static int pl022_setup(struct spi_device *spi) | |||
1932 | SSP_DMACR_MASK_TXDMAE, 1); | 1929 | SSP_DMACR_MASK_TXDMAE, 1); |
1933 | } | 1930 | } |
1934 | 1931 | ||
1935 | chip->cpsr = chip_info->clk_freq.cpsdvsr; | 1932 | chip->cpsr = clk_freq.cpsdvsr; |
1936 | 1933 | ||
1937 | /* Special setup for the ST micro extended control registers */ | 1934 | /* Special setup for the ST micro extended control registers */ |
1938 | if (pl022->vendor->extended_cr) { | 1935 | if (pl022->vendor->extended_cr) { |
@@ -1989,7 +1986,7 @@ static int pl022_setup(struct spi_device *spi) | |||
1989 | tmp = SSP_CLK_FIRST_EDGE; | 1986 | tmp = SSP_CLK_FIRST_EDGE; |
1990 | SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 7); | 1987 | SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 7); |
1991 | 1988 | ||
1992 | SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8); | 1989 | SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8); |
1993 | /* Loopback is available on all versions except PL023 */ | 1990 | /* Loopback is available on all versions except PL023 */ |
1994 | if (!pl022->vendor->pl023) { | 1991 | if (!pl022->vendor->pl023) { |
1995 | if (spi->mode & SPI_LOOP) | 1992 | if (spi->mode & SPI_LOOP) |
@@ -2007,7 +2004,6 @@ static int pl022_setup(struct spi_device *spi) | |||
2007 | return status; | 2004 | return status; |
2008 | err_config_params: | 2005 | err_config_params: |
2009 | spi_set_ctldata(spi, NULL); | 2006 | spi_set_ctldata(spi, NULL); |
2010 | err_first_setup: | ||
2011 | kfree(chip); | 2007 | kfree(chip); |
2012 | return status; | 2008 | return status; |
2013 | } | 2009 | } |