@@ -899,6 +899,7 @@ static void tegra_mc_num_channel_enabled(struct tegra_mc *mc)
static int tegra_mc_probe(struct platform_device *pdev)
{
+ struct resource *res;
struct tegra_mc *mc;
u64 mask;
int err;
@@ -923,7 +924,13 @@ static int tegra_mc_probe(struct platform_device *pdev)
/* length of MC tick in nanoseconds */
mc->tick = 30;
- mc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (mc->soc->num_channels) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sid");
+ if (res)
+ mc->regs = devm_ioremap_resource(&pdev->dev, res);
+ } else {
+ mc->regs = devm_platform_ioremap_resource(pdev, 0);
+ }
if (IS_ERR(mc->regs))
return PTR_ERR(mc->regs);
@@ -112,11 +112,11 @@ icc_provider_to_tegra_mc(struct icc_provider *provider)
static inline u32 mc_ch_readl(const struct tegra_mc *mc, int ch,
unsigned long offset)
{
- if (!mc->bcast_ch_regs)
- return 0;
-
- if (ch == MC_BROADCAST_CHANNEL)
+ if (ch == MC_BROADCAST_CHANNEL) {
+ if (!mc->bcast_ch_regs)
+ return 0;
return readl_relaxed(mc->bcast_ch_regs + offset);
+ }
return readl_relaxed(mc->ch_regs[ch] + offset);
}
@@ -124,13 +124,13 @@ static inline u32 mc_ch_readl(const struct tegra_mc *mc, int ch,
static inline void mc_ch_writel(const struct tegra_mc *mc, int ch,
u32 value, unsigned long offset)
{
- if (!mc->bcast_ch_regs)
- return;
-
- if (ch == MC_BROADCAST_CHANNEL)
+ if (ch == MC_BROADCAST_CHANNEL) {
+ if (!mc->bcast_ch_regs)
+ return;
writel_relaxed(value, mc->bcast_ch_regs + offset);
- else
+ } else {
writel_relaxed(value, mc->ch_regs[ch] + offset);
+ }
}
static inline u32 mc_readl(const struct tegra_mc *mc, unsigned long offset)
@@ -26,20 +26,16 @@
static int tegra186_mc_probe(struct tegra_mc *mc)
{
struct platform_device *pdev = to_platform_device(mc->dev);
+ struct resource *res;
unsigned int i;
char name[8];
int err;
- mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
- if (IS_ERR(mc->bcast_ch_regs)) {
- if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
- dev_warn(&pdev->dev,
- "Broadcast channel is missing, please update your device-tree\n");
- mc->bcast_ch_regs = NULL;
- goto populate;
- }
-
- return PTR_ERR(mc->bcast_ch_regs);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "broadcast");
+ if (res) {
+ mc->bcast_ch_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mc->bcast_ch_regs))
+ return PTR_ERR(mc->bcast_ch_regs);
}
mc->ch_regs = devm_kcalloc(mc->dev, mc->soc->num_channels, sizeof(*mc->ch_regs),
@@ -121,6 +117,9 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
if (!tegra_dev_iommu_get_stream_id(dev, &sid))
return 0;
+ if (!mc->regs)
+ return 0;
+
while (!of_parse_phandle_with_args(dev->of_node, "interconnects", "#interconnect-cells",
index, &args)) {
if (args.np == mc->dev->of_node && args.args_count != 0) {
@@ -146,6 +145,9 @@ static int tegra186_mc_resume(struct tegra_mc *mc)
#if IS_ENABLED(CONFIG_IOMMU_API)
unsigned int i;
+ if (!mc->regs)
+ return 0;
+
for (i = 0; i < mc->soc->num_clients; i++) {
const struct tegra_mc_client *client = &mc->soc->clients[i];
MC SID and Broadbast channel register access is restricted for Guest VM. In Tegra MC driver, consider both the regions as optional and skip access to restricted registers from Guest if a region is not present in Guest DT. Signed-off-by: Sumit Gupta <sumitg@nvidia.com> --- drivers/memory/tegra/mc.c | 9 ++++++++- drivers/memory/tegra/mc.h | 18 +++++++++--------- drivers/memory/tegra/tegra186.c | 22 ++++++++++++---------- 3 files changed, 29 insertions(+), 20 deletions(-)