memory: tegra: Deduplicate rate request management code

As is, the EMC drivers for each 32-bit platform contain almost
identical duplicated code for aggregating rate requests. Move this
code out to a shared tegra-emc-common file to reduce duplication,
and add kerneldoc comments.

Based on code from the tegra20-emc driver.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Link: https://patch.msgid.link/20260501-memory-refactor-v3-1-69fb1ae1a7ca@nvidia.com
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
This commit is contained in:
Mikko Perttunen 2026-05-01 16:00:52 +09:00 committed by Krzysztof Kozlowski
parent 754d60ad1c
commit 8879cff7f8
7 changed files with 215 additions and 305 deletions

View File

@ -17,6 +17,7 @@ config TEGRA20_EMC
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select PM_DEVFREQ
select DDR
select TEGRA_EMC_COMMON
help
This driver is for the External Memory Controller (EMC) found on
Tegra20 chips. The EMC controls the external DRAM on the board.
@ -29,6 +30,7 @@ config TEGRA30_EMC
depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
select PM_OPP
select DDR
select TEGRA_EMC_COMMON
help
This driver is for the External Memory Controller (EMC) found on
Tegra30 chips. The EMC controls the external DRAM on the board.
@ -41,6 +43,7 @@ config TEGRA124_EMC
depends on ARCH_TEGRA_124_SOC || COMPILE_TEST
select TEGRA124_CLK_EMC if ARCH_TEGRA
select PM_OPP
select TEGRA_EMC_COMMON
help
This driver is for the External Memory Controller (EMC) found on
Tegra124 chips. The EMC controls the external DRAM on the board.
@ -61,4 +64,7 @@ config TEGRA210_EMC
This driver is required to change memory timings / clock rate for
external memory.
config TEGRA_EMC_COMMON
tristate
endif

View File

@ -14,6 +14,7 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186.o tegra264.o
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
obj-$(CONFIG_TEGRA_EMC_COMMON) += tegra-emc-common.o
obj-$(CONFIG_TEGRA20_EMC) += tegra20-emc.o
obj-$(CONFIG_TEGRA30_EMC) += tegra30-emc.o
obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o

View File

@ -0,0 +1,143 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_opp.h>
#include "tegra-emc-common.h"
/**
* tegra_emc_rate_requests_init() - Initialize EMC rate request tracking
* @reqs: struct tegra_emc_rate_requests to initialize.
* @dev: EMC device.
*
* Initializes the rate request tracking state with default state
* (no active requests). Must be called before using @reqs with
* other functions.
*/
void tegra_emc_rate_requests_init(struct tegra_emc_rate_requests *reqs,
struct device *dev)
{
unsigned int i;
mutex_init(&reqs->rate_lock);
reqs->dev = dev;
for (i = 0; i < TEGRA_EMC_RATE_TYPE_MAX; i++) {
reqs->requested_rate[i].min_rate = 0;
reqs->requested_rate[i].max_rate = ULONG_MAX;
}
}
EXPORT_SYMBOL_GPL(tegra_emc_rate_requests_init);
/* Caller must hold reqs->rate_lock. */
static int tegra_emc_request_rate(struct tegra_emc_rate_requests *reqs,
unsigned long new_min_rate,
unsigned long new_max_rate,
enum tegra_emc_rate_request_type type)
{
struct tegra_emc_rate_request *req = reqs->requested_rate;
unsigned long min_rate = 0, max_rate = ULONG_MAX;
unsigned int i;
int err;
lockdep_assert_held(&reqs->rate_lock);
/* select minimum and maximum rates among the requested rates */
for (i = 0; i < TEGRA_EMC_RATE_TYPE_MAX; i++, req++) {
if (i == type) {
min_rate = max(new_min_rate, min_rate);
max_rate = min(new_max_rate, max_rate);
} else {
min_rate = max(req->min_rate, min_rate);
max_rate = min(req->max_rate, max_rate);
}
}
if (min_rate > max_rate) {
dev_err_ratelimited(reqs->dev, "%s: type %u: out of range: %lu %lu\n",
__func__, type, min_rate, max_rate);
return -ERANGE;
}
/*
* EMC rate-changes should go via OPP API because it manages voltage
* changes.
*/
err = dev_pm_opp_set_rate(reqs->dev, min_rate);
if (err)
return err;
reqs->requested_rate[type].min_rate = new_min_rate;
reqs->requested_rate[type].max_rate = new_max_rate;
return 0;
}
/**
* tegra_emc_set_min_rate() - Update minimum rate request for a request type
* @reqs: rate request tracking state
* @rate: new minimum rate in Hz requested by @type
* @type: type of request
*
* Records @rate as the new minimum rate request for @type, recalculates target
* rate based on all requests and applies new rate through the OPP API.
*
* Context: Sleeps. Requests to same @reqs are synchronized via mutex.
*
* Return:
* * %0 - success
* * %-ERANGE - request would cause minimum rate request to be higher than
* maximum rate request
* * other - setting new rate failed
*/
int tegra_emc_set_min_rate(struct tegra_emc_rate_requests *reqs,
unsigned long rate,
enum tegra_emc_rate_request_type type)
{
struct tegra_emc_rate_request *req = &reqs->requested_rate[type];
int ret;
mutex_lock(&reqs->rate_lock);
ret = tegra_emc_request_rate(reqs, rate, req->max_rate, type);
mutex_unlock(&reqs->rate_lock);
return ret;
}
EXPORT_SYMBOL_GPL(tegra_emc_set_min_rate);
/**
* tegra_emc_set_max_rate() - Update maximum rate request for a request type
* @reqs: rate request tracking state
* @rate: new maximum rate in Hz requested by @type
* @type: type of request
*
* Records @rate as the new maximum rate request for @type, recalculates target
* rate based on all requests and applies new rate through the OPP API.
*
* Context: Sleeps. Requests to same @reqs are synchronized via mutex.
*
* Return:
* * %0 - success
* * %-ERANGE - request would cause minimum rate request to be higher than
* maximum rate request
* * other - setting new rate failed
*/
int tegra_emc_set_max_rate(struct tegra_emc_rate_requests *reqs,
unsigned long rate,
enum tegra_emc_rate_request_type type)
{
struct tegra_emc_rate_request *req = &reqs->requested_rate[type];
int ret;
mutex_lock(&reqs->rate_lock);
ret = tegra_emc_request_rate(reqs, req->min_rate, rate, type);
mutex_unlock(&reqs->rate_lock);
return ret;
}
EXPORT_SYMBOL_GPL(tegra_emc_set_max_rate);
MODULE_DESCRIPTION("NVIDIA Tegra EMC common code");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef TEGRA_EMC_COMMON_H
#define TEGRA_EMC_COMMON_H
#include <linux/device.h>
#include <linux/mutex.h>
/**
* enum tegra_emc_rate_request_type - source of rate request
* @TEGRA_EMC_RATE_DEVFREQ: rate requested by devfreq governor
* @TEGRA_EMC_RATE_DEBUG: rate requested through debugfs knobs
* @TEGRA_EMC_RATE_ICC: rate requested by ICC framework
* @TEGRA_EMC_RATE_TYPE_MAX: number of valid request types
*/
enum tegra_emc_rate_request_type {
TEGRA_EMC_RATE_DEVFREQ,
TEGRA_EMC_RATE_DEBUG,
TEGRA_EMC_RATE_ICC,
TEGRA_EMC_RATE_TYPE_MAX,
};
struct tegra_emc_rate_request {
unsigned long min_rate;
unsigned long max_rate;
};
struct tegra_emc_rate_requests {
struct tegra_emc_rate_request requested_rate[TEGRA_EMC_RATE_TYPE_MAX];
/* Protects @requested_rate. */
struct mutex rate_lock;
struct device *dev;
};
void tegra_emc_rate_requests_init(struct tegra_emc_rate_requests *reqs,
struct device *dev);
int tegra_emc_set_min_rate(struct tegra_emc_rate_requests *reqs,
unsigned long rate,
enum tegra_emc_rate_request_type type);
int tegra_emc_set_max_rate(struct tegra_emc_rate_requests *reqs,
unsigned long rate,
enum tegra_emc_rate_request_type type);
#endif /* TEGRA_EMC_COMMON_H */

View File

@ -27,6 +27,7 @@
#include <soc/tegra/mc.h>
#include "mc.h"
#include "tegra-emc-common.h"
#define EMC_FBIO_CFG5 0x104
#define EMC_FBIO_CFG5_DRAM_TYPE_MASK 0x3
@ -467,17 +468,6 @@ struct emc_timing {
u32 emc_zcal_interval;
};
enum emc_rate_request_type {
EMC_RATE_DEBUG,
EMC_RATE_ICC,
EMC_RATE_TYPE_MAX,
};
struct emc_rate_request {
unsigned long min_rate;
unsigned long max_rate;
};
struct tegra_emc {
struct device *dev;
@ -503,14 +493,7 @@ struct tegra_emc {
struct icc_provider provider;
/*
* There are multiple sources in the EMC driver which could request
* a min/max clock rate, these rates are contained in this array.
*/
struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];
/* protect shared rate-change code path */
struct mutex rate_lock;
struct tegra_emc_rate_requests reqs;
};
/* Timing change sequence functions */
@ -1041,83 +1024,6 @@ tegra124_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code)
return NULL;
}
static void tegra124_emc_rate_requests_init(struct tegra_emc *emc)
{
unsigned int i;
for (i = 0; i < EMC_RATE_TYPE_MAX; i++) {
emc->requested_rate[i].min_rate = 0;
emc->requested_rate[i].max_rate = ULONG_MAX;
}
}
static int emc_request_rate(struct tegra_emc *emc,
unsigned long new_min_rate,
unsigned long new_max_rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = emc->requested_rate;
unsigned long min_rate = 0, max_rate = ULONG_MAX;
unsigned int i;
int err;
/* select minimum and maximum rates among the requested rates */
for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {
if (i == type) {
min_rate = max(new_min_rate, min_rate);
max_rate = min(new_max_rate, max_rate);
} else {
min_rate = max(req->min_rate, min_rate);
max_rate = min(req->max_rate, max_rate);
}
}
if (min_rate > max_rate) {
dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n",
__func__, type, min_rate, max_rate);
return -ERANGE;
}
/*
* EMC rate-changes should go via OPP API because it manages voltage
* changes.
*/
err = dev_pm_opp_set_rate(emc->dev, min_rate);
if (err)
return err;
emc->requested_rate[type].min_rate = new_min_rate;
emc->requested_rate[type].max_rate = new_max_rate;
return 0;
}
static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, rate, req->max_rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, req->min_rate, rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
/*
* debugfs interface
*
@ -1190,7 +1096,7 @@ static int tegra124_emc_debug_min_rate_set(void *data, u64 rate)
if (!tegra124_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -1220,7 +1126,7 @@ static int tegra124_emc_debug_max_rate_set(void *data, u64 rate)
if (!tegra124_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -1327,7 +1233,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
do_div(rate, ddr * dram_data_bus_width_bytes);
rate = min_t(u64, rate, U32_MAX);
err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);
if (err)
return err;
@ -1441,7 +1347,6 @@ static int tegra124_emc_probe(struct platform_device *pdev)
if (!emc)
return -ENOMEM;
mutex_init(&emc->rate_lock);
emc->dev = &pdev->dev;
emc->regs = devm_platform_ioremap_resource(pdev, 0);
@ -1487,7 +1392,7 @@ static int tegra124_emc_probe(struct platform_device *pdev)
if (err)
return err;
tegra124_emc_rate_requests_init(emc);
tegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);
if (IS_ENABLED(CONFIG_DEBUG_FS))
emc_debugfs_init(&pdev->dev, emc);

View File

@ -32,6 +32,7 @@
#include "../of_memory.h"
#include "mc.h"
#include "tegra-emc-common.h"
#define EMC_INTSTATUS 0x000
#define EMC_INTMASK 0x004
@ -182,18 +183,6 @@ struct emc_timing {
u32 data[ARRAY_SIZE(emc_timing_registers)];
};
enum emc_rate_request_type {
EMC_RATE_DEVFREQ,
EMC_RATE_DEBUG,
EMC_RATE_ICC,
EMC_RATE_TYPE_MAX,
};
struct emc_rate_request {
unsigned long min_rate;
unsigned long max_rate;
};
struct tegra_emc {
struct device *dev;
struct tegra_mc *mc;
@ -212,14 +201,7 @@ struct tegra_emc {
unsigned long max_rate;
} debugfs;
/*
* There are multiple sources in the EMC driver which could request
* a min/max clock rate, these rates are contained in this array.
*/
struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];
/* protect shared rate-change code path */
struct mutex rate_lock;
struct tegra_emc_rate_requests reqs;
struct devfreq_simple_ondemand_data ondemand_data;
@ -710,83 +692,6 @@ static long emc_round_rate(unsigned long rate,
return timing->rate;
}
static void tegra20_emc_rate_requests_init(struct tegra_emc *emc)
{
unsigned int i;
for (i = 0; i < EMC_RATE_TYPE_MAX; i++) {
emc->requested_rate[i].min_rate = 0;
emc->requested_rate[i].max_rate = ULONG_MAX;
}
}
static int emc_request_rate(struct tegra_emc *emc,
unsigned long new_min_rate,
unsigned long new_max_rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = emc->requested_rate;
unsigned long min_rate = 0, max_rate = ULONG_MAX;
unsigned int i;
int err;
/* select minimum and maximum rates among the requested rates */
for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {
if (i == type) {
min_rate = max(new_min_rate, min_rate);
max_rate = min(new_max_rate, max_rate);
} else {
min_rate = max(req->min_rate, min_rate);
max_rate = min(req->max_rate, max_rate);
}
}
if (min_rate > max_rate) {
dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n",
__func__, type, min_rate, max_rate);
return -ERANGE;
}
/*
* EMC rate-changes should go via OPP API because it manages voltage
* changes.
*/
err = dev_pm_opp_set_rate(emc->dev, min_rate);
if (err)
return err;
emc->requested_rate[type].min_rate = new_min_rate;
emc->requested_rate[type].max_rate = new_max_rate;
return 0;
}
static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, rate, req->max_rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, req->min_rate, rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
/*
* debugfs interface
*
@ -857,7 +762,7 @@ static int tegra20_emc_debug_min_rate_set(void *data, u64 rate)
if (!tegra20_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -887,7 +792,7 @@ static int tegra20_emc_debug_max_rate_set(void *data, u64 rate)
if (!tegra20_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -993,7 +898,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
do_div(rate, dram_data_bus_width_bytes);
rate = min_t(u64, rate, U32_MAX);
err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);
if (err)
return err;
@ -1111,7 +1016,7 @@ static int tegra20_emc_devfreq_target(struct device *dev, unsigned long *freq,
rate = dev_pm_opp_get_freq(opp);
dev_pm_opp_put(opp);
return emc_set_min_rate(emc, rate, EMC_RATE_DEVFREQ);
return tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEVFREQ);
}
static int tegra20_emc_devfreq_get_dev_status(struct device *dev,
@ -1190,7 +1095,6 @@ static int tegra20_emc_probe(struct platform_device *pdev)
if (!emc)
return -ENOMEM;
mutex_init(&emc->rate_lock);
emc->clk_nb.notifier_call = tegra20_emc_clk_change_notify;
emc->dev = &pdev->dev;
@ -1228,7 +1132,7 @@ static int tegra20_emc_probe(struct platform_device *pdev)
return err;
platform_set_drvdata(pdev, emc);
tegra20_emc_rate_requests_init(emc);
tegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);
tegra20_emc_debugfs_init(emc);
tegra20_emc_interconnect_init(emc);
tegra20_emc_devfreq_init(emc);

View File

@ -36,6 +36,7 @@
#include "../of_memory.h"
#include "mc.h"
#include "tegra-emc-common.h"
#define EMC_INTSTATUS 0x000
#define EMC_INTMASK 0x004
@ -341,17 +342,6 @@ struct emc_timing {
bool emc_cfg_dyn_self_ref;
};
enum emc_rate_request_type {
EMC_RATE_DEBUG,
EMC_RATE_ICC,
EMC_RATE_TYPE_MAX,
};
struct emc_rate_request {
unsigned long min_rate;
unsigned long max_rate;
};
struct tegra_emc {
struct device *dev;
struct tegra_mc *mc;
@ -383,14 +373,7 @@ struct tegra_emc {
unsigned long max_rate;
} debugfs;
/*
* There are multiple sources in the EMC driver which could request
* a min/max clock rate, these rates are contained in this array.
*/
struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];
/* protect shared rate-change code path */
struct mutex rate_lock;
struct tegra_emc_rate_requests reqs;
bool mrr_error;
};
@ -1228,83 +1211,6 @@ static long emc_round_rate(unsigned long rate,
return timing->rate;
}
static void tegra30_emc_rate_requests_init(struct tegra_emc *emc)
{
unsigned int i;
for (i = 0; i < EMC_RATE_TYPE_MAX; i++) {
emc->requested_rate[i].min_rate = 0;
emc->requested_rate[i].max_rate = ULONG_MAX;
}
}
static int emc_request_rate(struct tegra_emc *emc,
unsigned long new_min_rate,
unsigned long new_max_rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = emc->requested_rate;
unsigned long min_rate = 0, max_rate = ULONG_MAX;
unsigned int i;
int err;
/* select minimum and maximum rates among the requested rates */
for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {
if (i == type) {
min_rate = max(new_min_rate, min_rate);
max_rate = min(new_max_rate, max_rate);
} else {
min_rate = max(req->min_rate, min_rate);
max_rate = min(req->max_rate, max_rate);
}
}
if (min_rate > max_rate) {
dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n",
__func__, type, min_rate, max_rate);
return -ERANGE;
}
/*
* EMC rate-changes should go via OPP API because it manages voltage
* changes.
*/
err = dev_pm_opp_set_rate(emc->dev, min_rate);
if (err)
return err;
emc->requested_rate[type].min_rate = new_min_rate;
emc->requested_rate[type].max_rate = new_max_rate;
return 0;
}
static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, rate, req->max_rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,
enum emc_rate_request_type type)
{
struct emc_rate_request *req = &emc->requested_rate[type];
int ret;
mutex_lock(&emc->rate_lock);
ret = emc_request_rate(emc, req->min_rate, rate, type);
mutex_unlock(&emc->rate_lock);
return ret;
}
/*
* debugfs interface
*
@ -1375,7 +1281,7 @@ static int tegra30_emc_debug_min_rate_set(void *data, u64 rate)
if (!tegra30_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -1405,7 +1311,7 @@ static int tegra30_emc_debug_max_rate_set(void *data, u64 rate)
if (!tegra30_emc_validate_rate(emc, rate))
return -EINVAL;
err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);
err = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);
if (err < 0)
return err;
@ -1511,7 +1417,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
do_div(rate, ddr * dram_data_bus_width_bytes);
rate = min_t(u64, rate, U32_MAX);
err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
err = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);
if (err)
return err;
@ -1622,7 +1528,6 @@ static int tegra30_emc_probe(struct platform_device *pdev)
if (IS_ERR(emc->mc))
return PTR_ERR(emc->mc);
mutex_init(&emc->rate_lock);
emc->clk_nb.notifier_call = emc_clk_change_notify;
emc->dev = &pdev->dev;
@ -1664,7 +1569,7 @@ static int tegra30_emc_probe(struct platform_device *pdev)
return err;
platform_set_drvdata(pdev, emc);
tegra30_emc_rate_requests_init(emc);
tegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);
tegra30_emc_debugfs_init(emc);
tegra30_emc_interconnect_init(emc);