aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/smartreflex.c
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2011-02-14 21:42:34 +0530
committerTodd Poynor <toddpoynor@google.com>2011-11-30 15:28:30 -0800
commitfdfbe6430408f33d09fd77e2162ae61ee52a3c73 (patch)
treee57047cd984f56e5fdfb1c9cda54b52777171bd8 /arch/arm/mach-omap2/smartreflex.c
parent88f295e44d9b263d8094627690278164948f72bd (diff)
downloadkernel_samsung_tuna-fdfbe6430408f33d09fd77e2162ae61ee52a3c73.zip
kernel_samsung_tuna-fdfbe6430408f33d09fd77e2162ae61ee52a3c73.tar.gz
kernel_samsung_tuna-fdfbe6430408f33d09fd77e2162ae61ee52a3c73.tar.bz2
OMAP3+: SR: introduce notifier_control
We need some mechanism from class drivers to control when notifiers should be triggered and when not, currently we have none, which makes Class driver usage of the interrupt events almost impossible. We also ensure that disable/enable or irq is always guarenteed to be paired. The need to do this is because of the mixture of interrupt based and polling based operations that is implemented as the most optimal strategy for various SmartReflex AVS class Introduce an SmartReflex driver API for doing the same. This is useful for SmartReflex AVS class 1.5 or 2 drivers. Change-Id: Id5187a7631d4743c928ad20da31919e6fd71ce2e Signed-off-by: Nishanth Menon <nm@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/smartreflex.c')
-rw-r--r--arch/arm/mach-omap2/smartreflex.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 3796395..712bf98 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -50,6 +50,7 @@ struct omap_sr {
u32 senp_mod;
u32 senn_mod;
unsigned int irq;
+ bool irq_enabled;
void __iomem *base;
struct platform_device *pdev;
struct list_head node;
@@ -773,6 +774,70 @@ void sr_disable(struct voltagedomain *voltdm)
}
/**
+ * sr_notifier_control() - control the notifier mechanism
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ * @enable: true to enable notifiers and false to disable the same
+ *
+ * SR modules allow an MCU interrupt mechanism that vary based on the IP
+ * revision, we allow the system to generate interrupt if the class driver
+ * has capability to handle the same. it is upto the class driver to ensure
+ * the proper sequencing and handling for a clean implementation. returns
+ * 0 if all goes fine, else returns failure results
+ */
+int sr_notifier_control(struct voltagedomain *voltdm, bool enable)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+ u32 value = 0;
+
+ if (!sr) {
+ pr_warning("%s: sr corresponding to domain not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (!sr->autocomp_active)
+ return -EINVAL;
+
+ /* If I could never register an ISR, why bother?? */
+ if (!(sr_class && sr_class->notify && sr_class->notify_flags &&
+ sr->irq)) {
+ dev_warn(&sr->pdev->dev,
+ "%s: unable to setup IRQ without handling mechanism\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ switch (sr->ip_type) {
+ case SR_TYPE_V1:
+ value = notifier_to_irqen_v1(sr_class->notify_flags);
+ sr_modify_reg(sr, ERRCONFIG_V1, value,
+ (enable) ? value : 0);
+ break;
+ case SR_TYPE_V2:
+ value = notifier_to_irqen_v2(sr_class->notify_flags);
+ sr_write_reg(sr, (enable) ? IRQENABLE_SET : IRQENABLE_CLR,
+ value);
+ break;
+ default:
+ dev_warn(&sr->pdev->dev, "%s: unknown type of sr??\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!enable)
+ sr_write_reg(sr, IRQSTATUS, value);
+
+ if (enable != sr->irq_enabled) {
+ if (enable)
+ enable_irq(sr->irq);
+ else
+ disable_irq(sr->irq);
+ sr->irq_enabled = enable;
+ }
+
+ return 0;
+}
+
+/**
* sr_register_class() - API to register a smartreflex class parameters.
* @class_data: The structure containing various sr class specific data.
*