| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * SPI driver for Nvidia's Tegra20 Serial Flash Controller. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Laxman Dewangan <ldewangan@nvidia.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 9 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 10 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 15 | | - * more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | 8 | */ |
|---|
| 20 | 9 | |
|---|
| 21 | 10 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 352 | 341 | goto exit; |
|---|
| 353 | 342 | } |
|---|
| 354 | 343 | msg->actual_length += xfer->len; |
|---|
| 355 | | - if (xfer->cs_change && xfer->delay_usecs) { |
|---|
| 344 | + if (xfer->cs_change && |
|---|
| 345 | + (xfer->delay_usecs || xfer->delay.value)) { |
|---|
| 356 | 346 | tegra_sflash_writel(tsd, tsd->def_command_reg, |
|---|
| 357 | 347 | SPI_COMMAND); |
|---|
| 358 | | - udelay(xfer->delay_usecs); |
|---|
| 348 | + spi_transfer_delay_exec(xfer); |
|---|
| 359 | 349 | } |
|---|
| 360 | 350 | } |
|---|
| 361 | 351 | ret = 0; |
|---|
| .. | .. |
|---|
| 369 | 359 | static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd) |
|---|
| 370 | 360 | { |
|---|
| 371 | 361 | struct spi_transfer *t = tsd->curr_xfer; |
|---|
| 372 | | - unsigned long flags; |
|---|
| 373 | 362 | |
|---|
| 374 | | - spin_lock_irqsave(&tsd->lock, flags); |
|---|
| 363 | + spin_lock(&tsd->lock); |
|---|
| 375 | 364 | if (tsd->tx_status || tsd->rx_status || (tsd->status_reg & SPI_BSY)) { |
|---|
| 376 | 365 | dev_err(tsd->dev, |
|---|
| 377 | 366 | "CpuXfer ERROR bit set 0x%x\n", tsd->status_reg); |
|---|
| .. | .. |
|---|
| 401 | 390 | tegra_sflash_calculate_curr_xfer_param(tsd->cur_spi, tsd, t); |
|---|
| 402 | 391 | tegra_sflash_start_cpu_based_transfer(tsd, t); |
|---|
| 403 | 392 | exit: |
|---|
| 404 | | - spin_unlock_irqrestore(&tsd->lock, flags); |
|---|
| 393 | + spin_unlock(&tsd->lock); |
|---|
| 405 | 394 | return IRQ_HANDLED; |
|---|
| 406 | 395 | } |
|---|
| 407 | 396 | |
|---|
| .. | .. |
|---|
| 430 | 419 | { |
|---|
| 431 | 420 | struct spi_master *master; |
|---|
| 432 | 421 | struct tegra_sflash_data *tsd; |
|---|
| 433 | | - struct resource *r; |
|---|
| 434 | 422 | int ret; |
|---|
| 435 | 423 | const struct of_device_id *match; |
|---|
| 436 | 424 | |
|---|
| .. | .. |
|---|
| 462 | 450 | &master->max_speed_hz)) |
|---|
| 463 | 451 | master->max_speed_hz = 25000000; /* 25MHz */ |
|---|
| 464 | 452 | |
|---|
| 465 | | - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 466 | | - tsd->base = devm_ioremap_resource(&pdev->dev, r); |
|---|
| 453 | + tsd->base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 467 | 454 | if (IS_ERR(tsd->base)) { |
|---|
| 468 | 455 | ret = PTR_ERR(tsd->base); |
|---|
| 469 | 456 | goto exit_free_master; |
|---|
| 470 | 457 | } |
|---|
| 471 | 458 | |
|---|
| 472 | | - tsd->irq = platform_get_irq(pdev, 0); |
|---|
| 459 | + ret = platform_get_irq(pdev, 0); |
|---|
| 460 | + if (ret < 0) |
|---|
| 461 | + goto exit_free_master; |
|---|
| 462 | + tsd->irq = ret; |
|---|
| 463 | + |
|---|
| 473 | 464 | ret = request_irq(tsd->irq, tegra_sflash_isr, 0, |
|---|
| 474 | 465 | dev_name(&pdev->dev), tsd); |
|---|
| 475 | 466 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 503 | 494 | ret = pm_runtime_get_sync(&pdev->dev); |
|---|
| 504 | 495 | if (ret < 0) { |
|---|
| 505 | 496 | dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret); |
|---|
| 497 | + pm_runtime_put_noidle(&pdev->dev); |
|---|
| 506 | 498 | goto exit_pm_disable; |
|---|
| 507 | 499 | } |
|---|
| 508 | 500 | |
|---|