Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/imx', 'spi/topic...
authorMark Brown <broonie@kernel.org>
Fri, 3 Oct 2014 15:33:41 +0000 (16:33 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 3 Oct 2014 15:33:41 +0000 (16:33 +0100)
1  2  3  4  5  6 
drivers/base/regmap/regmap.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-mxs.c
drivers/spi/spi-orion.c

Simple merge
Simple merge
Simple merge
index 345e7d61c399f54f59b4bee4ed07b1ef2c4c7304,c4675fa8b64552afac670212b3dc8b002c430f7b,c4675fa8b64552afac670212b3dc8b002c430f7b,c4675fa8b64552afac670212b3dc8b002c430f7b,c4675fa8b64552afac670212b3dc8b002c430f7b,acf8e48db16cdd6b77b691fc2593c092af63a5e0..835cdda6f4f586d1eb31fccf6904f4203a82ddcd
@@@@@@@ -88,25 -88,25 -88,25 -88,25 -88,25 -105,59 +105,59 @@@@@@@ static int orion_spi_baudrate_set(struc
      
        tclk_hz = clk_get_rate(orion_spi->clk);
      
-----   /*
-----    * the supported rates are: 4,6,8...30
-----    * round up as we look for equal or less speed
-----    */
-----   rate = DIV_ROUND_UP(tclk_hz, speed);
-----   rate = roundup(rate, 2);
+++++   if (devdata->typ == ARMADA_SPI) {
+++++           unsigned int clk, spr, sppr, sppr2, err;
+++++           unsigned int best_spr, best_sppr, best_err;
+     
 ----   /* check if requested speed is too small */
 ----   if (rate > 30)
 ----           return -EINVAL;
+++++           best_err = speed;
+++++           best_spr = 0;
+++++           best_sppr = 0;
+     
 ----   if (rate < 4)
 ----           rate = 4;
+++++           /* Iterate over the valid range looking for best fit */
+++++           for (sppr = 0; sppr < 8; sppr++) {
+++++                   sppr2 = 0x1 << sppr;
+++++ 
+++++                   spr = tclk_hz / sppr2;
+++++                   spr = DIV_ROUND_UP(spr, speed);
+++++                   if ((spr == 0) || (spr > 15))
+++++                           continue;
 ++++ 
-       /* check if requested speed is too small */
-       if (rate > 30)
-               return -EINVAL;
+++++                   clk = tclk_hz / (spr * sppr2);
+++++                   err = speed - clk;
 ++++ 
-       if (rate < 4)
-               rate = 4;
+++++                   if (err < best_err) {
+++++                           best_spr = spr;
+++++                           best_sppr = sppr;
+++++                           best_err = err;
+++++                   }
+++++           }
+     
 ----   /* Convert the rate to SPI clock divisor value. */
 ----   prescale = 0x10 + rate/2;
+++++           if ((best_sppr == 0) && (best_spr == 0))
+++++                   return -EINVAL;
+++++ 
+++++           prescale = ((best_sppr & 0x6) << 5) |
+++++                   ((best_sppr & 0x1) << 4) | best_spr;
+++++   } else {
+++++           /*
+++++            * the supported rates are: 4,6,8...30
+++++            * round up as we look for equal or less speed
+++++            */
+++++           rate = DIV_ROUND_UP(tclk_hz, speed);
+++++           rate = roundup(rate, 2);
+++++ 
+++++           /* check if requested speed is too small */
+++++           if (rate > 30)
+++++                   return -EINVAL;
 ++++ 
-       /* Convert the rate to SPI clock divisor value. */
-       prescale = 0x10 + rate/2;
+++++           if (rate < 4)
+++++                   rate = 4;
+++++ 
+++++           /* Convert the rate to SPI clock divisor value. */
+++++           prescale = 0x10 + rate/2;
+++++   }
      
        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
-----   reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale);
+++++   reg = ((reg & ~devdata->prescale_mask) | prescale);
        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
      
        return 0;