summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h5
-rw-r--r--drivers/misc/tegra-throughput.c36
-rw-r--r--drivers/video/tegra/dc/ext/dev.c46
3 files changed, 41 insertions, 46 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index 47210c1cd87b..b60a913ff083 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -25,7 +25,6 @@
#include <linux/pm.h>
#include <linux/types.h>
#include <drm/drm_fixed.h>
-#include <linux/notifier.h>
#define TEGRA_MAX_DC 2
#define DC_N_WINDOWS 3
@@ -585,8 +584,8 @@ struct tegra_dc_edid {
struct tegra_dc_edid *tegra_dc_get_edid(struct tegra_dc *dc);
void tegra_dc_put_edid(struct tegra_dc_edid *edid);
-int tegra_dc_register_flip_notifier(struct notifier_block *nb);
-int tegra_dc_unregister_flip_notifier(struct notifier_block *nb);
+int tegra_dc_set_flip_callback(void (*callback)(void));
+int tegra_dc_unset_flip_callback(void);
int tegra_dc_get_panel_sync_rate(void);
#endif
diff --git a/drivers/misc/tegra-throughput.c b/drivers/misc/tegra-throughput.c
index 26573d8afc1a..366b0ecc10e6 100644
--- a/drivers/misc/tegra-throughput.c
+++ b/drivers/misc/tegra-throughput.c
@@ -19,7 +19,6 @@
#include <linux/kthread.h>
#include <linux/ktime.h>
-#include <linux/notifier.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -45,12 +44,10 @@ static void set_throughput_hint(struct work_struct *work)
nvhost_scale3d_set_throughput_hint(throughput_hint);
}
-static int throughput_flip_notifier(struct notifier_block *nb,
- unsigned long val,
- void *data)
+static int throughput_flip_callback(void)
{
- /* only register flips when a single display is active */
- if (val != 1 || multiple_app_disable)
+ /* only register flips when a single app is active */
+ if (multiple_app_disable)
return NOTIFY_DONE;
else {
long timediff;
@@ -65,7 +62,7 @@ static int throughput_flip_notifier(struct notifier_block *nb,
last_frame_time = (unsigned short) timediff;
if (last_frame_time == 0) {
- pr_warn("%s: notifications %lld nsec apart\n",
+ pr_warn("%s: flips %lld nsec apart\n",
__func__, now.tv64 - last_flip.tv64);
return NOTIFY_DONE;
}
@@ -82,10 +79,6 @@ static int throughput_flip_notifier(struct notifier_block *nb,
return NOTIFY_OK;
}
-static struct notifier_block throughput_flip_nb = {
- .notifier_call = throughput_flip_notifier,
-};
-
static int sync_rate;
static int throughput_active_app_count;
@@ -104,17 +97,15 @@ static void reset_target_frame_time(void)
__func__, sync_rate, target_frame_time);
}
-static int notifier_initialized;
+static int callback_initialized;
static int throughput_open(struct inode *inode, struct file *file)
{
- int need_init = 0;
-
spin_lock(&lock);
- if (!notifier_initialized) {
- notifier_initialized = 1;
- need_init = 1;
+ if (!callback_initialized) {
+ callback_initialized = 1;
+ tegra_dc_set_flip_callback(throughput_flip_callback);
}
throughput_active_app_count++;
@@ -123,8 +114,6 @@ static int throughput_open(struct inode *inode, struct file *file)
spin_unlock(&lock);
- if (need_init)
- tegra_dc_register_flip_notifier(&throughput_flip_nb);
pr_debug("throughput_open node %p file %p\n", inode, file);
@@ -133,23 +122,18 @@ static int throughput_open(struct inode *inode, struct file *file)
static int throughput_release(struct inode *inode, struct file *file)
{
- int need_deinit = 0;
-
spin_lock(&lock);
throughput_active_app_count--;
if (throughput_active_app_count == 0) {
reset_target_frame_time();
multiple_app_disable = 0;
- notifier_initialized = 0;
- need_deinit = 1;
+ callback_initialized = 0;
+ tegra_dc_unset_flip_callback();
}
spin_unlock(&lock);
- if (need_deinit)
- tegra_dc_unregister_flip_notifier(&throughput_flip_nb);
-
pr_debug("throughput_release node %p file %p\n", inode, file);
return 0;
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
index 92e42ce32ac2..8ec015cbde9b 100644
--- a/drivers/video/tegra/dc/ext/dev.c
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -274,31 +274,40 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext,
return 0;
}
-static struct srcu_notifier_head tegra_dc_flip_notifier_list;
-static bool init_tegra_dc_flip_notifier_list_called;
-static int __init init_tegra_dc_flip_notifier_list(void)
+static void (*flip_callback)(void);
+static spinlock_t flip_callback_lock;
+static bool init_tegra_dc_flip_callback_called;
+
+static int __init init_tegra_dc_flip_callback(void)
{
- srcu_init_notifier_head(&tegra_dc_flip_notifier_list);
- init_tegra_dc_flip_notifier_list_called = true;
+ spin_lock_init(&flip_callback_lock);
+ init_tegra_dc_flip_callback_called = true;
return 0;
}
-pure_initcall(init_tegra_dc_flip_notifier_list);
+pure_initcall(init_tegra_dc_flip_callback);
-int tegra_dc_register_flip_notifier(struct notifier_block *nb)
+int tegra_dc_set_flip_callback(void (*callback)(void))
{
- WARN_ON(!init_tegra_dc_flip_notifier_list_called);
+ WARN_ON(!init_tegra_dc_flip_callback_called);
+
+ spin_lock(&flip_callback_lock);
+ flip_callback = callback;
+ spin_unlock(&flip_callback_lock);
- return srcu_notifier_chain_register(
- &tegra_dc_flip_notifier_list, nb);
+ return 0;
}
-EXPORT_SYMBOL(tegra_dc_register_flip_notifier);
+EXPORT_SYMBOL(tegra_dc_set_flip_callback);
-int tegra_dc_unregister_flip_notifier(struct notifier_block *nb)
+int tegra_dc_unset_flip_callback()
{
- return srcu_notifier_chain_unregister(&tegra_dc_flip_notifier_list, nb);
+ spin_lock(&flip_callback_lock);
+ flip_callback = NULL;
+ spin_unlock(&flip_callback_lock);
+
+ return 0;
}
-EXPORT_SYMBOL(tegra_dc_unregister_flip_notifier);
+EXPORT_SYMBOL(tegra_dc_unset_flip_callback);
static void tegra_dc_ext_flip_worker(struct work_struct *work)
{
@@ -353,9 +362,12 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work)
tegra_dc_update_windows(wins, nr_win);
/* TODO: implement swapinterval here */
tegra_dc_sync_windows(wins, nr_win);
- if (!tegra_dc_has_multiple_dc())
- srcu_notifier_call_chain(&tegra_dc_flip_notifier_list,
- 1UL, NULL);
+ if (!tegra_dc_has_multiple_dc()) {
+ spin_lock(&flip_callback_lock);
+ if (flip_callback)
+ flip_callback();
+ spin_unlock(&flip_callback_lock);
+ }
}
for (i = 0; i < DC_N_WINDOWS; i++) {