| .. | .. |
|---|
| 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: |
|---|