Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cdedf40 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: edac: Add workaround for using cti to trigger pmu irq"

parents 321b3f2d 1b1d3e9f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -171,6 +171,15 @@ config ARCH_MSM8994_V1_TLBI_WA
	  [39:38] bits of VA are tied to zero and due to which TLBI
	  operations with VA or ASID will not work.

config MSM8994_V1_PMUIRQ_WA
	bool "Enable MSM8994 v1 PMU-CTI IRQ workaround"
	depends on ARCH_MSM8994 && CORESIGHT_CTI
	help
	  This enables support for the MSM8994 v1 PMU-CTI IRQ workaround.
	  This workaround is required for MSM8994 V1 revision where the
	  percpu PMU interrupt is incorrectly connected to the corresponding
	  CPUs in the other cluster.

config ARCH_XGENE
	bool "AppliedMicro X-Gene SOC Family"
	help
+7 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/percpu.h>
#include <soc/qcom/cti-pmu-irq.h>

#include <asm/cputype.h>

@@ -655,9 +656,11 @@ static irqreturn_t arm64_sbe_handler(int irq, void *drvdata)
	u32 pmovsr, cntr;
	struct erp_local_data errdata;
	unsigned long flags;
	int overflow = 0;
	int overflow = 0, ret = IRQ_HANDLED;
	int cpu = raw_smp_processor_id();

	msm_cti_pmu_irq_ack(cpu);

	errdata.drv = *((struct erp_drvdata **)drvdata);
	cntr = errdata.drv->mem_perf_counter;
	arm64_pmu_lock(NULL, &flags);
@@ -672,10 +675,10 @@ static irqreturn_t arm64_sbe_handler(int irq, void *drvdata)
		arm64_erp_local_handler(&errdata);
		sbe_enable_event(errdata.drv);
	} else {
		return armv8pmu_handle_irq(irq, NULL);
		ret = armv8pmu_handle_irq(irq, NULL);
	}

	return IRQ_HANDLED;
	return ret;
}

static int request_erp_irq(struct platform_device *pdev, const char *propname,
@@ -842,6 +845,7 @@ static int arm64_cpu_erp_probe(struct platform_device *pdev)
	drv->mem_perf_counter = arm64_pmu_get_last_counter();
	cpu_pm_register_notifier(&(drv->nb));
	arm64_pmu_irq_handled_externally();
	schedule_on_each_cpu(msm_enable_cti_pmu_workaround);
	on_each_cpu(sbe_enable_event, drv, 1);
	on_each_cpu(arm64_enable_pmu_irq, &sbe_irq, 1);

+1 −0
Original line number Diff line number Diff line
@@ -57,3 +57,4 @@ endif
obj-$(CONFIG_MSM_SYSMON_COMM) += sysmon.o
obj-$(CONFIG_CP_ACCESS64) += cpaccess64.o
obj-$(CONFIG_MSM_CPU_PWR_CTL) += cpu_pwr_ctl.o
obj-$(CONFIG_MSM8994_V1_PMUIRQ_WA) += cti-pmu-irq.o
+76 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/coresight-cti.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include <soc/qcom/cti-pmu-irq.h>

static struct coresight_cti *msm_cti_cpux[NR_CPUS];
static const char * const coresight_cpu_name[] = {
	"coresight-cti-cpu0",
	"coresight-cti-cpu1",
	"coresight-cti-cpu2",
	"coresight-cti-cpu3",
	"coresight-cti-cpu4",
	"coresight-cti-cpu5",
	"coresight-cti-cpu6",
	"coresight-cti-cpu7",
};

struct coresight_cti *msm_get_cpu_cti(int cpu)
{
	return coresight_cti_get(coresight_cpu_name[cpu]);
}

void msm_cti_pmu_irq_ack(int cpu)
{
	int ret = coresight_cti_ack_trig(msm_cti_cpux[cpu], 2);
	if (ret)
		pr_err("Failed to Acknowledge CTI-PMU Irq on CPU %d - %d\n",
								cpu, ret);
}

void msm_enable_cti_pmu_workaround(struct work_struct *work)
{
	struct coresight_cti *cti_cpux;
	int trigin = 1;
	int trigout = 2;
	int ch = 2;
	int cpu = smp_processor_id();
	int ret;

	cti_cpux = coresight_cti_get(coresight_cpu_name[cpu]);
	if (IS_ERR(cti_cpux))
		goto err;

	msm_cti_cpux[cpu] = cti_cpux;

	ret = coresight_cti_map_trigin(cti_cpux, trigin, ch);
	if (ret)
		goto err_in;
	ret = coresight_cti_map_trigout(cti_cpux, trigout, ch);
	if (ret)
		goto err_out;
	coresight_cti_enable_gate(cti_cpux, ch);
	pr_info("%s for CPU %d\n", __func__, cpu);

	return;
err_out:
	coresight_cti_unmap_trigin(cti_cpux, trigin, ch);
err_in:
	coresight_cti_put(cti_cpux);
err:
	pr_err("Failed to enable CTI-PMU workaround on CPU %d - %d\n",
								cpu, ret);
}
+27 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __MSM_CTI_PMU_IRQ_H
#define __MSM_CTI_PMU_IRQ_H

#include <linux/workqueue.h>

#ifdef CONFIG_MSM8994_V1_PMUIRQ_WA
void msm_enable_cti_pmu_workaround(struct work_struct *work);
struct coresight_cti *msm_get_cpu_cti(int cpu);
void msm_cti_pmu_irq_ack(int cpu);
#else
static inline void msm_enable_cti_pmu_workaround(struct work_struct *work) { }
static inline struct coresight_cti *msm_get_cpu_cti(int cpu) { return NULL; }
static inline void msm_cti_pmu_irq_ack(int cpu) { }
#endif
#endif