spi/pl022: fix dubious allocation staticize platform data
authorLinus Walleij <linus.walleij@stericsson.com>
Fri, 1 Oct 2010 11:33:13 +0000 (13:33 +0200)
committerGrant Likely <grant.likely@secretlab.ca>
Wed, 13 Oct 2010 03:37:37 +0000 (21:37 -0600)
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>
drivers/spi/amba-pl022.c

index 19d54aa..fb3d1b3 100644 (file)
@@ -1593,7 +1593,7 @@ static int destroy_queue(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)
            || (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) {
@@ -1614,12 +1614,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
                        "hierarchy is configured incorrectly\n");
                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)
            && (chip_info->com_mode != DMA_TRANSFER)
            && (chip_info->com_mode != POLLING_TRANSFER)) {
@@ -1671,11 +1665,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
                        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;
 }
 
@@ -1775,6 +1764,25 @@ static int calculate_effective_freq(struct pl022 *pl022,
        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
  * @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)
 {
-       struct pl022_config_chip *chip_info;
+       struct pl022_config_chip const *chip_info;
        struct chip_data *chip;
+       struct ssp_clock_params clk_freq;
        int status = 0;
        struct pl022 *pl022 = spi_master_get_devdata(spi->master);
        unsigned int bits = spi->bits_per_word;
@@ -1817,40 +1826,13 @@ static int pl022_setup(struct spi_device *spi)
        chip_info = spi->controller_data;
 
        if (chip_info == NULL) {
+               chip_info = &pl022_default_chip_info;
                /* spi_board_info.controller_data not is supplied */
                dev_dbg(&spi->dev,
                        "using default controller_data settings\n");
-
-               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 {
+       } else
                dev_dbg(&spi->dev,
                        "using user supplied controller_data settings\n");
-       }
 
        /*
         * 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)) {
                status = calculate_effective_freq(pl022,
                                                  spi->max_speed_hz,
-                                                 &chip_info->clk_freq);
+                                                 &clk_freq);
                if (status < 0)
                        goto err_config_params;
        } else {
-               if ((chip_info->clk_freq.cpsdvsr % 2) != 0)
-                       chip_info->clk_freq.cpsdvsr =
-                               chip_info->clk_freq.cpsdvsr - 1;
+               memcpy(&clk_freq, &chip_info->clk_freq, sizeof(clk_freq));
+               if ((clk_freq.cpsdvsr % 2) != 0)
+                       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);
        if (status) {
                dev_err(&spi->dev, "controller data is incorrect");
                goto err_config_params;
        }
+
        /* Now set controller state based on controller data */
        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) {
                /* 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);
        }
 
-       chip->cpsr = chip_info->clk_freq.cpsdvsr;
+       chip->cpsr = clk_freq.cpsdvsr;
 
        /* Special setup for the ST micro extended control registers */
        if (pl022->vendor->extended_cr) {
@@ -1989,7 +1986,7 @@ static int pl022_setup(struct spi_device *spi)
                tmp = SSP_CLK_FIRST_EDGE;
        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 */
        if (!pl022->vendor->pl023) {
                if (spi->mode & SPI_LOOP)
@@ -2007,7 +2004,6 @@ static int pl022_setup(struct spi_device *spi)
        return status;
  err_config_params:
        spi_set_ctldata(spi, NULL);
- err_first_setup:
        kfree(chip);
        return status;
 }