.. | .. |
---|
20 | 20 | #include <linux/spi/spi.h> |
---|
21 | 21 | #include <linux/mutex.h> |
---|
22 | 22 | #include <linux/of.h> |
---|
| 23 | +#include <linux/reset.h> |
---|
| 24 | +#include <linux/pm_runtime.h> |
---|
23 | 25 | |
---|
24 | 26 | #define HSSPI_GLOBAL_CTRL_REG 0x0 |
---|
25 | 27 | #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 |
---|
.. | .. |
---|
161 | 163 | int step_size = HSSPI_BUFFER_LEN; |
---|
162 | 164 | const u8 *tx = t->tx_buf; |
---|
163 | 165 | u8 *rx = t->rx_buf; |
---|
| 166 | + u32 val = 0; |
---|
164 | 167 | |
---|
165 | 168 | bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); |
---|
166 | 169 | bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); |
---|
.. | .. |
---|
176 | 179 | step_size -= HSSPI_OPCODE_LEN; |
---|
177 | 180 | |
---|
178 | 181 | if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || |
---|
179 | | - (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) |
---|
| 182 | + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { |
---|
180 | 183 | opcode |= HSSPI_OP_MULTIBIT; |
---|
181 | 184 | |
---|
182 | | - __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT | |
---|
183 | | - 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff, |
---|
| 185 | + if (t->rx_nbits == SPI_NBITS_DUAL) |
---|
| 186 | + val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; |
---|
| 187 | + if (t->tx_nbits == SPI_NBITS_DUAL) |
---|
| 188 | + val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; |
---|
| 189 | + } |
---|
| 190 | + |
---|
| 191 | + __raw_writel(val | 0xff, |
---|
184 | 192 | bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); |
---|
185 | 193 | |
---|
186 | 194 | while (pending > 0) { |
---|
.. | .. |
---|
291 | 299 | |
---|
292 | 300 | msg->actual_length += t->len; |
---|
293 | 301 | |
---|
294 | | - if (t->delay_usecs) |
---|
295 | | - udelay(t->delay_usecs); |
---|
| 302 | + spi_transfer_delay_exec(t); |
---|
296 | 303 | |
---|
297 | 304 | if (t->cs_change) |
---|
298 | 305 | bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); |
---|
.. | .. |
---|
330 | 337 | { |
---|
331 | 338 | struct spi_master *master; |
---|
332 | 339 | struct bcm63xx_hsspi *bs; |
---|
333 | | - struct resource *res_mem; |
---|
334 | 340 | void __iomem *regs; |
---|
335 | 341 | struct device *dev = &pdev->dev; |
---|
336 | 342 | struct clk *clk, *pll_clk = NULL; |
---|
337 | 343 | int irq, ret; |
---|
338 | 344 | u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS; |
---|
| 345 | + struct reset_control *reset; |
---|
339 | 346 | |
---|
340 | 347 | irq = platform_get_irq(pdev, 0); |
---|
341 | | - if (irq < 0) { |
---|
342 | | - dev_err(dev, "no irq: %d\n", irq); |
---|
| 348 | + if (irq < 0) |
---|
343 | 349 | return irq; |
---|
344 | | - } |
---|
345 | 350 | |
---|
346 | | - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
347 | | - regs = devm_ioremap_resource(dev, res_mem); |
---|
| 351 | + regs = devm_platform_ioremap_resource(pdev, 0); |
---|
348 | 352 | if (IS_ERR(regs)) |
---|
349 | 353 | return PTR_ERR(regs); |
---|
350 | 354 | |
---|
.. | .. |
---|
353 | 357 | if (IS_ERR(clk)) |
---|
354 | 358 | return PTR_ERR(clk); |
---|
355 | 359 | |
---|
| 360 | + reset = devm_reset_control_get_optional_exclusive(dev, NULL); |
---|
| 361 | + if (IS_ERR(reset)) |
---|
| 362 | + return PTR_ERR(reset); |
---|
| 363 | + |
---|
356 | 364 | ret = clk_prepare_enable(clk); |
---|
357 | 365 | if (ret) |
---|
358 | 366 | return ret; |
---|
| 367 | + |
---|
| 368 | + ret = reset_control_reset(reset); |
---|
| 369 | + if (ret) { |
---|
| 370 | + dev_err(dev, "unable to reset device: %d\n", ret); |
---|
| 371 | + goto out_disable_clk; |
---|
| 372 | + } |
---|
359 | 373 | |
---|
360 | 374 | rate = clk_get_rate(clk); |
---|
361 | 375 | if (!rate) { |
---|
.. | .. |
---|
432 | 446 | if (ret) |
---|
433 | 447 | goto out_put_master; |
---|
434 | 448 | |
---|
| 449 | + pm_runtime_enable(&pdev->dev); |
---|
| 450 | + |
---|
435 | 451 | /* register and we are done */ |
---|
436 | 452 | ret = devm_spi_register_master(dev, master); |
---|
437 | 453 | if (ret) |
---|
438 | | - goto out_put_master; |
---|
| 454 | + goto out_pm_disable; |
---|
439 | 455 | |
---|
440 | 456 | return 0; |
---|
441 | 457 | |
---|
| 458 | +out_pm_disable: |
---|
| 459 | + pm_runtime_disable(&pdev->dev); |
---|
442 | 460 | out_put_master: |
---|
443 | 461 | spi_master_put(master); |
---|
444 | 462 | out_disable_pll_clk: |
---|