iommu: msm: Only allow supported perf. events

Only allow supported Performance Monitor Unit (PMU) events to be
selected by users when enabling performance monitoring. This ensures
a more user friendly user interface. Instead of users being allowed to
configure the PMU counters to count events and not seeing the counters
actually work, the PMU interface will now reject setting of counter events
that are not supported.

Change-Id: I5a515d3f3e24c5c66434847925dd92fb49110148
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
index fee8a4a..9265706 100644
--- a/drivers/iommu/msm_iommu_perfmon.c
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -90,6 +90,19 @@
 	return pos;
 }
 
+static int iommu_pm_event_class_supported(struct iommu_pmon *pmon,
+					  int event_class)
+{
+	unsigned int nevent_cls = pmon->nevent_cls_supported;
+	unsigned int i;
+
+	for (i = 0; i < nevent_cls; ++i) {
+		if (event_class == pmon->event_cls_supported[i])
+			return event_class;
+	}
+	return MSM_IOMMU_PMU_NO_EVENT_CLASS;
+}
+
 static const char *iommu_pm_find_event_class_name(int event_class)
 {
 	size_t array_len;
@@ -113,7 +126,8 @@
 	return event_class_name;
 }
 
-static int iommu_pm_find_event_class(const char *event_class_name)
+static int iommu_pm_find_event_class(struct iommu_pmon *pmon,
+				     const char *event_class_name)
 {
 	size_t array_len;
 	struct event_class *ptr;
@@ -134,6 +148,7 @@
 	}
 
 out:
+	event_class = iommu_pm_event_class_supported(pmon, event_class);
 	return event_class;
 }
 
@@ -389,11 +404,11 @@
 		rv = kstrtol(buf, 10, &value);
 		if (!rv) {
 			counter->current_event_class =
-				iommu_pm_find_event_class(
+				iommu_pm_find_event_class(pmon,
 					iommu_pm_find_event_class_name(value));
 		} else {
 			counter->current_event_class =
-						iommu_pm_find_event_class(buf);
+					iommu_pm_find_event_class(pmon, buf);
 	}	}
 
 	if (current_event_class != counter->current_event_class)