summaryrefslogtreecommitdiff
path: root/lib/refcount.c
diff options
context:
space:
mode:
authorGustavo Padovan <gustavo.padovan@collabora.com>2018-06-29 00:56:03 +0300
committerGustavo Padovan <gustavo.padovan@collabora.com>2018-06-29 00:56:03 +0300
commitc981c01164d5e47b98973f92d4680df4287275c2 (patch)
tree9f1513553c3136c8acd1a8bc9805cdd8aa16a483 /lib/refcount.c
parenteab976693153b9854bfa83d131374748f6ca4280 (diff)
parent83d83bebf40132e2d55ec58af666713cc76f9764 (diff)
downloadlinux-c981c01164d5e47b98973f92d4680df4287275c2.tar.xz
Merge tag 'ib-fbdev-drm-v4.19-deferred-console-takeover' of https://github.com/bzolnier/linux into drm-misc-next
Immutable branch between fbdev and drm for the v4.19 merge window (contains the deferred console takeover feature) Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com> # gpg: Signature made Thu 28 Jun 2018 10:24:50 AM -03 # gpg: using RSA key 7E33B63FA047C20B # gpg: Can't check signature: public key not found # Conflicts: # drivers/gpu/drm/i915/i915_gem.c # drivers/gpu/drm/i915/intel_crt.c # drivers/gpu/drm/i915/intel_display.c # drivers/gpu/drm/i915/intel_lrc.c Link: https://patchwork.freedesktop.org/patch/msgid/2462549.rLSfW9kX99@amdc3058
Diffstat (limited to 'lib/refcount.c')
-rw-r--r--lib/refcount.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/refcount.c b/lib/refcount.c
index 0eb48353abe3..d3b81cefce91 100644
--- a/lib/refcount.c
+++ b/lib/refcount.c
@@ -350,3 +350,31 @@ bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock)
}
EXPORT_SYMBOL(refcount_dec_and_lock);
+/**
+ * refcount_dec_and_lock_irqsave - return holding spinlock with disabled
+ * interrupts if able to decrement refcount to 0
+ * @r: the refcount
+ * @lock: the spinlock to be locked
+ * @flags: saved IRQ-flags if the is acquired
+ *
+ * Same as refcount_dec_and_lock() above except that the spinlock is acquired
+ * with disabled interupts.
+ *
+ * Return: true and hold spinlock if able to decrement refcount to 0, false
+ * otherwise
+ */
+bool refcount_dec_and_lock_irqsave(refcount_t *r, spinlock_t *lock,
+ unsigned long *flags)
+{
+ if (refcount_dec_not_one(r))
+ return false;
+
+ spin_lock_irqsave(lock, *flags);
+ if (!refcount_dec_and_test(r)) {
+ spin_unlock_irqrestore(lock, *flags);
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(refcount_dec_and_lock_irqsave);