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>
This commit is contained in:
parent
5a1c98be1d
commit
f9d629c737
|
@ -1593,7 +1593,7 @@ static int destroy_queue(struct pl022 *pl022)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_controller_parameters(struct pl022 *pl022,
|
static int verify_controller_parameters(struct pl022 *pl022,
|
||||||
struct pl022_config_chip *chip_info)
|
struct pl022_config_chip const *chip_info)
|
||||||
{
|
{
|
||||||
if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI)
|
if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI)
|
||||||
|| (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) {
|
|| (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) {
|
||||||
|
@ -1614,12 +1614,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
|
||||||
"hierarchy is configured incorrectly\n");
|
"hierarchy is configured incorrectly\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (((chip_info->clk_freq).cpsdvsr < CPSDVR_MIN)
|
|
||||||
|| ((chip_info->clk_freq).cpsdvsr > CPSDVR_MAX)) {
|
|
||||||
dev_err(&pl022->adev->dev,
|
|
||||||
"cpsdvsr is configured incorrectly\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if ((chip_info->com_mode != INTERRUPT_TRANSFER)
|
if ((chip_info->com_mode != INTERRUPT_TRANSFER)
|
||||||
&& (chip_info->com_mode != DMA_TRANSFER)
|
&& (chip_info->com_mode != DMA_TRANSFER)
|
||||||
&& (chip_info->com_mode != POLLING_TRANSFER)) {
|
&& (chip_info->com_mode != POLLING_TRANSFER)) {
|
||||||
|
@ -1671,11 +1665,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chip_info->cs_control == NULL) {
|
|
||||||
dev_warn(&pl022->adev->dev,
|
|
||||||
"Chip Select Function is NULL for this chip\n");
|
|
||||||
chip_info->cs_control = null_cs_control;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1775,6 +1764,25 @@ static int calculate_effective_freq(struct pl022 *pl022,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A piece of default chip info unless the platform
|
||||||
|
* supplies it.
|
||||||
|
*/
|
||||||
|
static const struct pl022_config_chip pl022_default_chip_info = {
|
||||||
|
.com_mode = POLLING_TRANSFER,
|
||||||
|
.iface = SSP_INTERFACE_MOTOROLA_SPI,
|
||||||
|
.hierarchy = SSP_SLAVE,
|
||||||
|
.slave_tx_disable = DO_NOT_DRIVE_TX,
|
||||||
|
.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
|
||||||
|
.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
|
||||||
|
.ctrl_len = SSP_BITS_8,
|
||||||
|
.wait_state = SSP_MWIRE_WAIT_ZERO,
|
||||||
|
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
|
||||||
|
.cs_control = null_cs_control,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pl022_setup - setup function registered to SPI master framework
|
* pl022_setup - setup function registered to SPI master framework
|
||||||
* @spi: spi device which is requesting setup
|
* @spi: spi device which is requesting setup
|
||||||
|
@ -1789,8 +1797,9 @@ static int calculate_effective_freq(struct pl022 *pl022,
|
||||||
*/
|
*/
|
||||||
static int pl022_setup(struct spi_device *spi)
|
static int pl022_setup(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
struct pl022_config_chip *chip_info;
|
struct pl022_config_chip const *chip_info;
|
||||||
struct chip_data *chip;
|
struct chip_data *chip;
|
||||||
|
struct ssp_clock_params clk_freq;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
struct pl022 *pl022 = spi_master_get_devdata(spi->master);
|
struct pl022 *pl022 = spi_master_get_devdata(spi->master);
|
||||||
unsigned int bits = spi->bits_per_word;
|
unsigned int bits = spi->bits_per_word;
|
||||||
|
@ -1817,40 +1826,13 @@ static int pl022_setup(struct spi_device *spi)
|
||||||
chip_info = spi->controller_data;
|
chip_info = spi->controller_data;
|
||||||
|
|
||||||
if (chip_info == NULL) {
|
if (chip_info == NULL) {
|
||||||
|
chip_info = &pl022_default_chip_info;
|
||||||
/* spi_board_info.controller_data not is supplied */
|
/* spi_board_info.controller_data not is supplied */
|
||||||
dev_dbg(&spi->dev,
|
dev_dbg(&spi->dev,
|
||||||
"using default controller_data settings\n");
|
"using default controller_data settings\n");
|
||||||
|
} else
|
||||||
chip_info =
|
|
||||||
kzalloc(sizeof(struct pl022_config_chip), GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!chip_info) {
|
|
||||||
dev_err(&spi->dev,
|
|
||||||
"cannot allocate controller data\n");
|
|
||||||
status = -ENOMEM;
|
|
||||||
goto err_first_setup;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(&spi->dev, "allocated memory for controller data\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set controller data default values:
|
|
||||||
* Polling is supported by default
|
|
||||||
*/
|
|
||||||
chip_info->com_mode = POLLING_TRANSFER;
|
|
||||||
chip_info->iface = SSP_INTERFACE_MOTOROLA_SPI;
|
|
||||||
chip_info->hierarchy = SSP_SLAVE;
|
|
||||||
chip_info->slave_tx_disable = DO_NOT_DRIVE_TX;
|
|
||||||
chip_info->rx_lev_trig = SSP_RX_1_OR_MORE_ELEM;
|
|
||||||
chip_info->tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC;
|
|
||||||
chip_info->ctrl_len = SSP_BITS_8;
|
|
||||||
chip_info->wait_state = SSP_MWIRE_WAIT_ZERO;
|
|
||||||
chip_info->duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX;
|
|
||||||
chip_info->cs_control = null_cs_control;
|
|
||||||
} else {
|
|
||||||
dev_dbg(&spi->dev,
|
dev_dbg(&spi->dev,
|
||||||
"using user supplied controller_data settings\n");
|
"using user supplied controller_data settings\n");
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can override with custom divisors, else we use the board
|
* We can override with custom divisors, else we use the board
|
||||||
|
@ -1860,22 +1842,37 @@ static int pl022_setup(struct spi_device *spi)
|
||||||
&& (0 == chip_info->clk_freq.scr)) {
|
&& (0 == chip_info->clk_freq.scr)) {
|
||||||
status = calculate_effective_freq(pl022,
|
status = calculate_effective_freq(pl022,
|
||||||
spi->max_speed_hz,
|
spi->max_speed_hz,
|
||||||
&chip_info->clk_freq);
|
&clk_freq);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto err_config_params;
|
goto err_config_params;
|
||||||
} else {
|
} else {
|
||||||
if ((chip_info->clk_freq.cpsdvsr % 2) != 0)
|
memcpy(&clk_freq, &chip_info->clk_freq, sizeof(clk_freq));
|
||||||
chip_info->clk_freq.cpsdvsr =
|
if ((clk_freq.cpsdvsr % 2) != 0)
|
||||||
chip_info->clk_freq.cpsdvsr - 1;
|
clk_freq.cpsdvsr =
|
||||||
|
clk_freq.cpsdvsr - 1;
|
||||||
}
|
}
|
||||||
|
if ((clk_freq.cpsdvsr < CPSDVR_MIN)
|
||||||
|
|| (clk_freq.cpsdvsr > CPSDVR_MAX)) {
|
||||||
|
dev_err(&spi->dev,
|
||||||
|
"cpsdvsr is configured incorrectly\n");
|
||||||
|
goto err_config_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status = verify_controller_parameters(pl022, chip_info);
|
status = verify_controller_parameters(pl022, chip_info);
|
||||||
if (status) {
|
if (status) {
|
||||||
dev_err(&spi->dev, "controller data is incorrect");
|
dev_err(&spi->dev, "controller data is incorrect");
|
||||||
goto err_config_params;
|
goto err_config_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set controller state based on controller data */
|
/* Now set controller state based on controller data */
|
||||||
chip->xfer_type = chip_info->com_mode;
|
chip->xfer_type = chip_info->com_mode;
|
||||||
chip->cs_control = chip_info->cs_control;
|
if (!chip_info->cs_control) {
|
||||||
|
chip->cs_control = null_cs_control;
|
||||||
|
dev_warn(&spi->dev,
|
||||||
|
"chip select function is NULL for this chip\n");
|
||||||
|
} else
|
||||||
|
chip->cs_control = chip_info->cs_control;
|
||||||
|
|
||||||
if (bits <= 3) {
|
if (bits <= 3) {
|
||||||
/* PL022 doesn't support less than 4-bits */
|
/* PL022 doesn't support less than 4-bits */
|
||||||
|
@ -1932,7 +1929,7 @@ static int pl022_setup(struct spi_device *spi)
|
||||||
SSP_DMACR_MASK_TXDMAE, 1);
|
SSP_DMACR_MASK_TXDMAE, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
chip->cpsr = chip_info->clk_freq.cpsdvsr;
|
chip->cpsr = clk_freq.cpsdvsr;
|
||||||
|
|
||||||
/* Special setup for the ST micro extended control registers */
|
/* Special setup for the ST micro extended control registers */
|
||||||
if (pl022->vendor->extended_cr) {
|
if (pl022->vendor->extended_cr) {
|
||||||
|
@ -1989,7 +1986,7 @@ static int pl022_setup(struct spi_device *spi)
|
||||||
tmp = SSP_CLK_FIRST_EDGE;
|
tmp = SSP_CLK_FIRST_EDGE;
|
||||||
SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 7);
|
SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 7);
|
||||||
|
|
||||||
SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8);
|
SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8);
|
||||||
/* Loopback is available on all versions except PL023 */
|
/* Loopback is available on all versions except PL023 */
|
||||||
if (!pl022->vendor->pl023) {
|
if (!pl022->vendor->pl023) {
|
||||||
if (spi->mode & SPI_LOOP)
|
if (spi->mode & SPI_LOOP)
|
||||||
|
@ -2007,7 +2004,6 @@ static int pl022_setup(struct spi_device *spi)
|
||||||
return status;
|
return status;
|
||||||
err_config_params:
|
err_config_params:
|
||||||
spi_set_ctldata(spi, NULL);
|
spi_set_ctldata(spi, NULL);
|
||||||
err_first_setup:
|
|
||||||
kfree(chip);
|
kfree(chip);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue