Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branches 'spi/topic/fsl-lpspi', 'spi/topic/imx', 'spi/topic/jcore' and 'spi/topic/omap' into spi-next

+581 -17
+19
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
··· 1 + * Freescale Low Power SPI (LPSPI) for i.MX 2 + 3 + Required properties: 4 + - compatible : 5 + - "fsl,imx7ulp-spi" for LPSPI compatible with the one integrated on i.MX7ULP soc 6 + - reg : address and length of the lpspi master registers 7 + - interrupt-parent : core interrupt controller 8 + - interrupts : lpspi interrupt 9 + - clocks : lpspi clock specifier 10 + 11 + Examples: 12 + 13 + lpspi2: lpspi@40290000 { 14 + compatible = "fsl,imx7ulp-spi"; 15 + reg = <0x40290000 0x10000>; 16 + interrupt-parent = <&intc>; 17 + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; 18 + clocks = <&clks IMX7ULP_CLK_LPSPI2>; 19 + };
+6
drivers/spi/Kconfig
··· 271 271 has only been tested with m25p80 type chips. The hardware has no 272 272 support for other types of SPI peripherals. 273 273 274 + config SPI_FSL_LPSPI 275 + tristate "Freescale i.MX LPSPI controller" 276 + depends on ARCH_MXC || COMPILE_TEST 277 + help 278 + This enables Freescale i.MX LPSPI controllers in master mode. 279 + 274 280 config SPI_GPIO 275 281 tristate "GPIO-based bitbanging SPI Master" 276 282 depends on GPIOLIB || COMPILE_TEST
+1
drivers/spi/Makefile
··· 44 44 obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o 45 45 obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o 46 46 obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o 47 + obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o 47 48 obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o 48 49 obj-$(CONFIG_SPI_GPIO) += spi-gpio.o 49 50 obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
+525
drivers/spi/spi-fsl-lpspi.c
··· 1 + /* 2 + * Freescale i.MX7ULP LPSPI driver 3 + * 4 + * Copyright 2016 Freescale Semiconductor, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #include <linux/clk.h> 19 + #include <linux/completion.h> 20 + #include <linux/delay.h> 21 + #include <linux/err.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/io.h> 24 + #include <linux/irq.h> 25 + #include <linux/kernel.h> 26 + #include <linux/module.h> 27 + #include <linux/of.h> 28 + #include <linux/of_device.h> 29 + #include <linux/platform_device.h> 30 + #include <linux/slab.h> 31 + #include <linux/spi/spi.h> 32 + #include <linux/spi/spi_bitbang.h> 33 + #include <linux/types.h> 34 + 35 + #define DRIVER_NAME "fsl_lpspi" 36 + 37 + /* i.MX7ULP LPSPI registers */ 38 + #define IMX7ULP_VERID 0x0 39 + #define IMX7ULP_PARAM 0x4 40 + #define IMX7ULP_CR 0x10 41 + #define IMX7ULP_SR 0x14 42 + #define IMX7ULP_IER 0x18 43 + #define IMX7ULP_DER 0x1c 44 + #define IMX7ULP_CFGR0 0x20 45 + #define IMX7ULP_CFGR1 0x24 46 + #define IMX7ULP_DMR0 0x30 47 + #define IMX7ULP_DMR1 0x34 48 + #define IMX7ULP_CCR 0x40 49 + #define IMX7ULP_FCR 0x58 50 + #define IMX7ULP_FSR 0x5c 51 + #define IMX7ULP_TCR 0x60 52 + #define IMX7ULP_TDR 0x64 53 + #define IMX7ULP_RSR 0x70 54 + #define IMX7ULP_RDR 0x74 55 + 56 + /* General control register field define */ 57 + #define CR_RRF BIT(9) 58 + #define CR_RTF BIT(8) 59 + #define CR_RST BIT(1) 60 + #define CR_MEN BIT(0) 61 + #define SR_TCF BIT(10) 62 + #define SR_RDF BIT(1) 63 + #define SR_TDF BIT(0) 64 + #define IER_TCIE BIT(10) 65 + #define IER_RDIE BIT(1) 66 + #define IER_TDIE BIT(0) 67 + #define CFGR1_PCSCFG BIT(27) 68 + #define CFGR1_PCSPOL BIT(8) 69 + #define CFGR1_NOSTALL BIT(3) 70 + #define CFGR1_MASTER BIT(0) 71 + #define RSR_RXEMPTY BIT(1) 72 + #define TCR_CPOL BIT(31) 73 + #define TCR_CPHA BIT(30) 74 + #define TCR_CONT BIT(21) 75 + #define TCR_CONTC BIT(20) 76 + #define TCR_RXMSK BIT(19) 77 + #define TCR_TXMSK BIT(18) 78 + 79 + static int clkdivs[] = {1, 2, 4, 8, 16, 32, 64, 128}; 80 + 81 + struct lpspi_config { 82 + u8 bpw; 83 + u8 chip_select; 84 + u8 prescale; 85 + u16 mode; 86 + u32 speed_hz; 87 + }; 88 + 89 + struct fsl_lpspi_data { 90 + struct device *dev; 91 + void __iomem *base; 92 + struct clk *clk; 93 + 94 + void *rx_buf; 95 + const void *tx_buf; 96 + void (*tx)(struct fsl_lpspi_data *); 97 + void (*rx)(struct fsl_lpspi_data *); 98 + 99 + u32 remain; 100 + u8 txfifosize; 101 + u8 rxfifosize; 102 + 103 + struct lpspi_config config; 104 + struct completion xfer_done; 105 + }; 106 + 107 + static const struct of_device_id fsl_lpspi_dt_ids[] = { 108 + { .compatible = "fsl,imx7ulp-spi", }, 109 + { /* sentinel */ } 110 + }; 111 + MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids); 112 + 113 + #define LPSPI_BUF_RX(type) \ 114 + static void fsl_lpspi_buf_rx_##type(struct fsl_lpspi_data *fsl_lpspi) \ 115 + { \ 116 + unsigned int val = readl(fsl_lpspi->base + IMX7ULP_RDR); \ 117 + \ 118 + if (fsl_lpspi->rx_buf) { \ 119 + *(type *)fsl_lpspi->rx_buf = val; \ 120 + fsl_lpspi->rx_buf += sizeof(type); \ 121 + } \ 122 + } 123 + 124 + #define LPSPI_BUF_TX(type) \ 125 + static void fsl_lpspi_buf_tx_##type(struct fsl_lpspi_data *fsl_lpspi) \ 126 + { \ 127 + type val = 0; \ 128 + \ 129 + if (fsl_lpspi->tx_buf) { \ 130 + val = *(type *)fsl_lpspi->tx_buf; \ 131 + fsl_lpspi->tx_buf += sizeof(type); \ 132 + } \ 133 + \ 134 + fsl_lpspi->remain -= sizeof(type); \ 135 + writel(val, fsl_lpspi->base + IMX7ULP_TDR); \ 136 + } 137 + 138 + LPSPI_BUF_RX(u8) 139 + LPSPI_BUF_TX(u8) 140 + LPSPI_BUF_RX(u16) 141 + LPSPI_BUF_TX(u16) 142 + LPSPI_BUF_RX(u32) 143 + LPSPI_BUF_TX(u32) 144 + 145 + static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi, 146 + unsigned int enable) 147 + { 148 + writel(enable, fsl_lpspi->base + IMX7ULP_IER); 149 + } 150 + 151 + static int lpspi_prepare_xfer_hardware(struct spi_master *master) 152 + { 153 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); 154 + 155 + return clk_prepare_enable(fsl_lpspi->clk); 156 + } 157 + 158 + static int lpspi_unprepare_xfer_hardware(struct spi_master *master) 159 + { 160 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); 161 + 162 + clk_disable_unprepare(fsl_lpspi->clk); 163 + 164 + return 0; 165 + } 166 + 167 + static int fsl_lpspi_txfifo_empty(struct fsl_lpspi_data *fsl_lpspi) 168 + { 169 + u32 txcnt; 170 + unsigned long orig_jiffies = jiffies; 171 + 172 + do { 173 + txcnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff; 174 + 175 + if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { 176 + dev_dbg(fsl_lpspi->dev, "txfifo empty timeout\n"); 177 + return -ETIMEDOUT; 178 + } 179 + cond_resched(); 180 + 181 + } while (txcnt); 182 + 183 + return 0; 184 + } 185 + 186 + static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi) 187 + { 188 + u8 txfifo_cnt; 189 + 190 + txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff; 191 + 192 + while (txfifo_cnt < fsl_lpspi->txfifosize) { 193 + if (!fsl_lpspi->remain) 194 + break; 195 + fsl_lpspi->tx(fsl_lpspi); 196 + txfifo_cnt++; 197 + } 198 + 199 + if (!fsl_lpspi->remain && (txfifo_cnt < fsl_lpspi->txfifosize)) 200 + writel(0, fsl_lpspi->base + IMX7ULP_TDR); 201 + else 202 + fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE); 203 + } 204 + 205 + static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi) 206 + { 207 + while (!(readl(fsl_lpspi->base + IMX7ULP_RSR) & RSR_RXEMPTY)) 208 + fsl_lpspi->rx(fsl_lpspi); 209 + } 210 + 211 + static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi, 212 + bool is_first_xfer) 213 + { 214 + u32 temp = 0; 215 + 216 + temp |= fsl_lpspi->config.bpw - 1; 217 + temp |= fsl_lpspi->config.prescale << 27; 218 + temp |= (fsl_lpspi->config.mode & 0x3) << 30; 219 + temp |= (fsl_lpspi->config.chip_select & 0x3) << 24; 220 + 221 + /* 222 + * Set TCR_CONT will keep SS asserted after current transfer. 223 + * For the first transfer, clear TCR_CONTC to assert SS. 224 + * For subsequent transfer, set TCR_CONTC to keep SS asserted. 225 + */ 226 + temp |= TCR_CONT; 227 + if (is_first_xfer) 228 + temp &= ~TCR_CONTC; 229 + else 230 + temp |= TCR_CONTC; 231 + 232 + writel(temp, fsl_lpspi->base + IMX7ULP_TCR); 233 + 234 + dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp); 235 + } 236 + 237 + static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi) 238 + { 239 + u32 temp; 240 + 241 + temp = fsl_lpspi->txfifosize >> 1 | (fsl_lpspi->rxfifosize >> 1) << 16; 242 + 243 + writel(temp, fsl_lpspi->base + IMX7ULP_FCR); 244 + 245 + dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp); 246 + } 247 + 248 + static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) 249 + { 250 + struct lpspi_config config = fsl_lpspi->config; 251 + unsigned int perclk_rate, scldiv; 252 + u8 prescale; 253 + 254 + perclk_rate = clk_get_rate(fsl_lpspi->clk); 255 + for (prescale = 0; prescale < 8; prescale++) { 256 + scldiv = perclk_rate / 257 + (clkdivs[prescale] * config.speed_hz) - 2; 258 + if (scldiv < 256) { 259 + fsl_lpspi->config.prescale = prescale; 260 + break; 261 + } 262 + } 263 + 264 + if (prescale == 8 && scldiv >= 256) 265 + return -EINVAL; 266 + 267 + writel(scldiv, fsl_lpspi->base + IMX7ULP_CCR); 268 + 269 + dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale =%d, scldiv=%d\n", 270 + perclk_rate, config.speed_hz, prescale, scldiv); 271 + 272 + return 0; 273 + } 274 + 275 + static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi) 276 + { 277 + u32 temp; 278 + int ret; 279 + 280 + temp = CR_RST; 281 + writel(temp, fsl_lpspi->base + IMX7ULP_CR); 282 + writel(0, fsl_lpspi->base + IMX7ULP_CR); 283 + 284 + ret = fsl_lpspi_set_bitrate(fsl_lpspi); 285 + if (ret) 286 + return ret; 287 + 288 + fsl_lpspi_set_watermark(fsl_lpspi); 289 + 290 + temp = CFGR1_PCSCFG | CFGR1_MASTER | CFGR1_NOSTALL; 291 + if (fsl_lpspi->config.mode & SPI_CS_HIGH) 292 + temp |= CFGR1_PCSPOL; 293 + writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1); 294 + 295 + temp = readl(fsl_lpspi->base + IMX7ULP_CR); 296 + temp |= CR_RRF | CR_RTF | CR_MEN; 297 + writel(temp, fsl_lpspi->base + IMX7ULP_CR); 298 + 299 + return 0; 300 + } 301 + 302 + static void fsl_lpspi_setup_transfer(struct spi_device *spi, 303 + struct spi_transfer *t) 304 + { 305 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(spi->master); 306 + 307 + fsl_lpspi->config.mode = spi->mode; 308 + fsl_lpspi->config.bpw = t ? t->bits_per_word : spi->bits_per_word; 309 + fsl_lpspi->config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; 310 + fsl_lpspi->config.chip_select = spi->chip_select; 311 + 312 + if (!fsl_lpspi->config.speed_hz) 313 + fsl_lpspi->config.speed_hz = spi->max_speed_hz; 314 + if (!fsl_lpspi->config.bpw) 315 + fsl_lpspi->config.bpw = spi->bits_per_word; 316 + 317 + /* Initialize the functions for transfer */ 318 + if (fsl_lpspi->config.bpw <= 8) { 319 + fsl_lpspi->rx = fsl_lpspi_buf_rx_u8; 320 + fsl_lpspi->tx = fsl_lpspi_buf_tx_u8; 321 + } else if (fsl_lpspi->config.bpw <= 16) { 322 + fsl_lpspi->rx = fsl_lpspi_buf_rx_u16; 323 + fsl_lpspi->tx = fsl_lpspi_buf_tx_u16; 324 + } else { 325 + fsl_lpspi->rx = fsl_lpspi_buf_rx_u32; 326 + fsl_lpspi->tx = fsl_lpspi_buf_tx_u32; 327 + } 328 + 329 + fsl_lpspi_config(fsl_lpspi); 330 + } 331 + 332 + static int fsl_lpspi_transfer_one(struct spi_master *master, 333 + struct spi_device *spi, 334 + struct spi_transfer *t) 335 + { 336 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); 337 + int ret; 338 + 339 + fsl_lpspi->tx_buf = t->tx_buf; 340 + fsl_lpspi->rx_buf = t->rx_buf; 341 + fsl_lpspi->remain = t->len; 342 + 343 + reinit_completion(&fsl_lpspi->xfer_done); 344 + fsl_lpspi_write_tx_fifo(fsl_lpspi); 345 + 346 + ret = wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ); 347 + if (!ret) { 348 + dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n"); 349 + return -ETIMEDOUT; 350 + } 351 + 352 + ret = fsl_lpspi_txfifo_empty(fsl_lpspi); 353 + if (ret) 354 + return ret; 355 + 356 + fsl_lpspi_read_rx_fifo(fsl_lpspi); 357 + 358 + return 0; 359 + } 360 + 361 + static int fsl_lpspi_transfer_one_msg(struct spi_master *master, 362 + struct spi_message *msg) 363 + { 364 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); 365 + struct spi_device *spi = msg->spi; 366 + struct spi_transfer *xfer; 367 + bool is_first_xfer = true; 368 + u32 temp; 369 + int ret; 370 + 371 + msg->status = 0; 372 + msg->actual_length = 0; 373 + 374 + list_for_each_entry(xfer, &msg->transfers, transfer_list) { 375 + fsl_lpspi_setup_transfer(spi, xfer); 376 + fsl_lpspi_set_cmd(fsl_lpspi, is_first_xfer); 377 + 378 + is_first_xfer = false; 379 + 380 + ret = fsl_lpspi_transfer_one(master, spi, xfer); 381 + if (ret < 0) 382 + goto complete; 383 + 384 + msg->actual_length += xfer->len; 385 + } 386 + 387 + complete: 388 + /* de-assert SS, then finalize current message */ 389 + temp = readl(fsl_lpspi->base + IMX7ULP_TCR); 390 + temp &= ~TCR_CONTC; 391 + writel(temp, fsl_lpspi->base + IMX7ULP_TCR); 392 + 393 + msg->status = ret; 394 + spi_finalize_current_message(master); 395 + 396 + return ret; 397 + } 398 + 399 + static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id) 400 + { 401 + struct fsl_lpspi_data *fsl_lpspi = dev_id; 402 + u32 temp; 403 + 404 + fsl_lpspi_intctrl(fsl_lpspi, 0); 405 + temp = readl(fsl_lpspi->base + IMX7ULP_SR); 406 + 407 + fsl_lpspi_read_rx_fifo(fsl_lpspi); 408 + 409 + if (temp & SR_TDF) { 410 + fsl_lpspi_write_tx_fifo(fsl_lpspi); 411 + 412 + if (!fsl_lpspi->remain) 413 + complete(&fsl_lpspi->xfer_done); 414 + 415 + return IRQ_HANDLED; 416 + } 417 + 418 + return IRQ_NONE; 419 + } 420 + 421 + static int fsl_lpspi_probe(struct platform_device *pdev) 422 + { 423 + struct fsl_lpspi_data *fsl_lpspi; 424 + struct spi_master *master; 425 + struct resource *res; 426 + int ret, irq; 427 + u32 temp; 428 + 429 + master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_lpspi_data)); 430 + if (!master) 431 + return -ENOMEM; 432 + 433 + platform_set_drvdata(pdev, master); 434 + 435 + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); 436 + master->bus_num = pdev->id; 437 + 438 + fsl_lpspi = spi_master_get_devdata(master); 439 + fsl_lpspi->dev = &pdev->dev; 440 + 441 + master->transfer_one_message = fsl_lpspi_transfer_one_msg; 442 + master->prepare_transfer_hardware = lpspi_prepare_xfer_hardware; 443 + master->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware; 444 + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 445 + master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; 446 + master->dev.of_node = pdev->dev.of_node; 447 + master->bus_num = pdev->id; 448 + 449 + init_completion(&fsl_lpspi->xfer_done); 450 + 451 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 452 + fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res); 453 + if (IS_ERR(fsl_lpspi->base)) { 454 + ret = PTR_ERR(fsl_lpspi->base); 455 + goto out_master_put; 456 + } 457 + 458 + irq = platform_get_irq(pdev, 0); 459 + if (irq < 0) { 460 + ret = irq; 461 + goto out_master_put; 462 + } 463 + 464 + ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0, 465 + dev_name(&pdev->dev), fsl_lpspi); 466 + if (ret) { 467 + dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret); 468 + goto out_master_put; 469 + } 470 + 471 + fsl_lpspi->clk = devm_clk_get(&pdev->dev, "ipg"); 472 + if (IS_ERR(fsl_lpspi->clk)) { 473 + ret = PTR_ERR(fsl_lpspi->clk); 474 + goto out_master_put; 475 + } 476 + 477 + ret = clk_prepare_enable(fsl_lpspi->clk); 478 + if (ret) { 479 + dev_err(&pdev->dev, "can't enable lpspi clock, ret=%d\n", ret); 480 + goto out_master_put; 481 + } 482 + 483 + temp = readl(fsl_lpspi->base + IMX7ULP_PARAM); 484 + fsl_lpspi->txfifosize = 1 << (temp & 0x0f); 485 + fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f); 486 + 487 + clk_disable_unprepare(fsl_lpspi->clk); 488 + 489 + ret = devm_spi_register_master(&pdev->dev, master); 490 + if (ret < 0) { 491 + dev_err(&pdev->dev, "spi_register_master error.\n"); 492 + goto out_master_put; 493 + } 494 + 495 + return 0; 496 + 497 + out_master_put: 498 + spi_master_put(master); 499 + 500 + return ret; 501 + } 502 + 503 + static int fsl_lpspi_remove(struct platform_device *pdev) 504 + { 505 + struct spi_master *master = platform_get_drvdata(pdev); 506 + struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); 507 + 508 + clk_disable_unprepare(fsl_lpspi->clk); 509 + 510 + return 0; 511 + } 512 + 513 + static struct platform_driver fsl_lpspi_driver = { 514 + .driver = { 515 + .name = DRIVER_NAME, 516 + .of_match_table = fsl_lpspi_dt_ids, 517 + }, 518 + .probe = fsl_lpspi_probe, 519 + .remove = fsl_lpspi_remove, 520 + }; 521 + module_platform_driver(fsl_lpspi_driver); 522 + 523 + MODULE_DESCRIPTION("LPSPI Master Controller driver"); 524 + MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>"); 525 + MODULE_LICENSE("GPL");
+27 -8
drivers/spi/spi-imx.c
··· 173 173 174 174 /* MX21, MX27 */ 175 175 static unsigned int spi_imx_clkdiv_1(unsigned int fin, 176 - unsigned int fspi, unsigned int max) 176 + unsigned int fspi, unsigned int max, unsigned int *fres) 177 177 { 178 178 int i; 179 179 180 180 for (i = 2; i < max; i++) 181 181 if (fspi * mxc_clkdivs[i] >= fin) 182 - return i; 182 + break; 183 183 184 - return max; 184 + *fres = fin / mxc_clkdivs[i]; 185 + return i; 185 186 } 186 187 187 188 /* MX1, MX31, MX35, MX51 CSPI */ ··· 443 442 #define MX31_CSPICTRL_ENABLE (1 << 0) 444 443 #define MX31_CSPICTRL_MASTER (1 << 1) 445 444 #define MX31_CSPICTRL_XCH (1 << 2) 445 + #define MX31_CSPICTRL_SMC (1 << 3) 446 446 #define MX31_CSPICTRL_POL (1 << 4) 447 447 #define MX31_CSPICTRL_PHA (1 << 5) 448 448 #define MX31_CSPICTRL_SSCTL (1 << 6) ··· 453 451 #define MX31_CSPICTRL_CS_SHIFT 24 454 452 #define MX35_CSPICTRL_CS_SHIFT 12 455 453 #define MX31_CSPICTRL_DR_SHIFT 16 454 + 455 + #define MX31_CSPI_DMAREG 0x10 456 + #define MX31_DMAREG_RH_DEN (1<<4) 457 + #define MX31_DMAREG_TH_DEN (1<<1) 456 458 457 459 #define MX31_CSPISTATUS 0x14 458 460 #define MX31_STATUS_RR (1 << 3) ··· 517 511 (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : 518 512 MX31_CSPICTRL_CS_SHIFT); 519 513 514 + if (spi_imx->usedma) 515 + reg |= MX31_CSPICTRL_SMC; 516 + 520 517 writel(reg, spi_imx->base + MXC_CSPICTRL); 521 518 522 519 reg = readl(spi_imx->base + MX31_CSPI_TESTREG); ··· 528 519 else 529 520 reg &= ~MX31_TEST_LBC; 530 521 writel(reg, spi_imx->base + MX31_CSPI_TESTREG); 522 + 523 + if (spi_imx->usedma) { 524 + /* configure DMA requests when RXFIFO is half full and 525 + when TXFIFO is half empty */ 526 + writel(MX31_DMAREG_RH_DEN | MX31_DMAREG_TH_DEN, 527 + spi_imx->base + MX31_CSPI_DMAREG); 528 + } 531 529 532 530 return 0; 533 531 } ··· 590 574 struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); 591 575 unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; 592 576 unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; 577 + unsigned int clk; 593 578 594 - reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) << 595 - MX21_CSPICTRL_DR_SHIFT; 579 + reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max, &clk) 580 + << MX21_CSPICTRL_DR_SHIFT; 581 + spi_imx->spi_bus_clk = clk; 582 + 596 583 reg |= config->bpw - 1; 597 584 598 585 if (spi->mode & SPI_CPHA) ··· 1263 1244 1264 1245 spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); 1265 1246 /* 1266 - * Only validated on i.mx6 now, can remove the constrain if validated on 1267 - * other chips. 1247 + * Only validated on i.mx35 and i.mx6 now, can remove the constraint 1248 + * if validated on other chips. 1268 1249 */ 1269 - if (is_imx51_ecspi(spi_imx)) { 1250 + if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) { 1270 1251 ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); 1271 1252 if (ret == -EPROBE_DEFER) 1272 1253 goto out_clk_put;
+1
drivers/spi/spi-jcore.c
··· 214 214 { .compatible = "jcore,spi2" }, 215 215 {}, 216 216 }; 217 + MODULE_DEVICE_TABLE(of, jcore_spi_of_match); 217 218 218 219 static struct platform_driver jcore_spi_driver = { 219 220 .probe = jcore_spi_probe,
+2 -9
drivers/spi/spi-omap2-mcspi.c
··· 1386 1386 regs_offset = pdata->regs_offset; 1387 1387 1388 1388 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1389 - if (r == NULL) { 1390 - status = -ENODEV; 1391 - goto free_master; 1392 - } 1393 - 1394 - r->start += regs_offset; 1395 - r->end += regs_offset; 1396 - mcspi->phys = r->start; 1397 - 1398 1389 mcspi->base = devm_ioremap_resource(&pdev->dev, r); 1399 1390 if (IS_ERR(mcspi->base)) { 1400 1391 status = PTR_ERR(mcspi->base); 1401 1392 goto free_master; 1402 1393 } 1394 + mcspi->phys = r->start + regs_offset; 1395 + mcspi->base += regs_offset; 1403 1396 1404 1397 mcspi->dev = &pdev->dev; 1405 1398