diff options
| -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 | } |
