Skip to content

Commit 77ab499

Browse files
digetxthierryreding
authored andcommitted
memory: tegra: Adapt for Tegra20 clock driver changes
Now Tegra20 and Tegra30 EMC drivers should provide clock-rounding functionality using the new Tegra clock driver API. Acked-by: Peter De Schrijver <[email protected]> Signed-off-by: Dmitry Osipenko <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent fa6749d commit 77ab499

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

drivers/memory/tegra/tegra20-emc.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/clk.h>
9+
#include <linux/clk/tegra.h>
910
#include <linux/completion.h>
1011
#include <linux/err.h>
1112
#include <linux/interrupt.h>
@@ -421,6 +422,44 @@ static int emc_setup_hw(struct tegra_emc *emc)
421422
return 0;
422423
}
423424

425+
static long emc_round_rate(unsigned long rate,
426+
unsigned long min_rate,
427+
unsigned long max_rate,
428+
void *arg)
429+
{
430+
struct emc_timing *timing = NULL;
431+
struct tegra_emc *emc = arg;
432+
unsigned int i;
433+
434+
min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
435+
436+
for (i = 0; i < emc->num_timings; i++) {
437+
if (emc->timings[i].rate < rate && i != emc->num_timings - 1)
438+
continue;
439+
440+
if (emc->timings[i].rate > max_rate) {
441+
i = max(i, 1u) - 1;
442+
443+
if (emc->timings[i].rate < min_rate)
444+
break;
445+
}
446+
447+
if (emc->timings[i].rate < min_rate)
448+
continue;
449+
450+
timing = &emc->timings[i];
451+
break;
452+
}
453+
454+
if (!timing) {
455+
dev_err(emc->dev, "no timing for rate %lu min %lu max %lu\n",
456+
rate, min_rate, max_rate);
457+
return -EINVAL;
458+
}
459+
460+
return timing->rate;
461+
}
462+
424463
static int tegra_emc_probe(struct platform_device *pdev)
425464
{
426465
struct device_node *np;
@@ -477,21 +516,28 @@ static int tegra_emc_probe(struct platform_device *pdev)
477516
return err;
478517
}
479518

519+
tegra20_clk_set_emc_round_callback(emc_round_rate, emc);
520+
480521
emc->clk = devm_clk_get(&pdev->dev, "emc");
481522
if (IS_ERR(emc->clk)) {
482523
err = PTR_ERR(emc->clk);
483524
dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
484-
return err;
525+
goto unset_cb;
485526
}
486527

487528
err = clk_notifier_register(emc->clk, &emc->clk_nb);
488529
if (err) {
489530
dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
490531
err);
491-
return err;
532+
goto unset_cb;
492533
}
493534

494535
return 0;
536+
537+
unset_cb:
538+
tegra20_clk_set_emc_round_callback(NULL, NULL);
539+
540+
return err;
495541
}
496542

497543
static const struct of_device_id tegra_emc_of_match[] = {

0 commit comments

Comments
 (0)