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

Commit 4e1b1bae authored by Jack Pham's avatar Jack Pham
Browse files

usb: diag: Replace kref_put_spinlock_irqsave() with kref_put_lock()



The kref structure has been changed to use refcount_t instead of
atomic_t. But also a new API function kref_put_lock() was added.
We can use this in place of defining our own locking version of
kref_put().

Change-Id: I0f7dc0c7c24f2b8e577b3b67cdd9422c4bd35514
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 6f456763
Loading
Loading
Loading
Loading
+5 −41
Original line number Diff line number Diff line
@@ -206,39 +206,7 @@ static inline struct diag_context *func_to_diag(struct usb_function *f)
	return container_of(f, struct diag_context, function);
}

/**
 * kref_put_spinlock_irqsave - decrement refcount for object.
 * @kref: object.
 * @release: pointer to the function that will clean up the object when the
 *	     last reference to the object is released.
 *	     This pointer is required, and it is not acceptable to pass kfree
 *	     in as this function.
 * @lock: lock to take in release case
 *
 * Behaves identical to kref_put with one exception.  If the reference count
 * drops to zero, the lock will be taken atomically wrt dropping the reference
 * count.  The release function has to call spin_unlock() without _irqrestore.
 */
static inline int kref_put_spinlock_irqsave(struct kref *kref,
		void (*release)(struct kref *kref),
		spinlock_t *lock)
{
	unsigned long flags;

	WARN_ON(release == NULL);
	if (atomic_add_unless(&kref->refcount, -1, 1))
		return 0;
	spin_lock_irqsave(lock, flags);
	if (atomic_dec_and_test(&kref->refcount)) {
		release(kref);
		local_irq_restore(flags);
		return 1;
	}
	spin_unlock_irqrestore(lock, flags);
	return 0;
}

/* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */
/* Called with ctxt->lock held; i.e. only use with kref_put_lock() */
static void diag_context_release(struct kref *kref)
{
	struct diag_context *ctxt =
@@ -321,8 +289,7 @@ static void diag_write_complete(struct usb_ep *ep,
	if (ctxt->ch && ctxt->ch->notify)
		ctxt->ch->notify(ctxt->ch->priv, USB_DIAG_WRITE_DONE, d_req);

	kref_put_spinlock_irqsave(&ctxt->kref, diag_context_release,
			&ctxt->lock);
	kref_put_lock(&ctxt->kref, diag_context_release, &ctxt->lock);
}

static void diag_read_complete(struct usb_ep *ep,
@@ -344,8 +311,7 @@ static void diag_read_complete(struct usb_ep *ep,
	if (ctxt->ch && ctxt->ch->notify)
		ctxt->ch->notify(ctxt->ch->priv, USB_DIAG_READ_DONE, d_req);

	kref_put_spinlock_irqsave(&ctxt->kref, diag_context_release,
			&ctxt->lock);
	kref_put_lock(&ctxt->kref, diag_context_release, &ctxt->lock);
}

/**
@@ -556,8 +522,7 @@ int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req)
	/* make sure context is still valid after releasing lock */
	if (ctxt != ch->priv_usb) {
		usb_ep_free_request(out, req);
		kref_put_spinlock_irqsave(&ctxt->kref, diag_context_release,
				&ctxt->lock);
		kref_put_lock(&ctxt->kref, diag_context_release, &ctxt->lock);
		return -EIO;
	}

@@ -633,8 +598,7 @@ int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req)
	/* make sure context is still valid after releasing lock */
	if (ctxt != ch->priv_usb) {
		usb_ep_free_request(in, req);
		kref_put_spinlock_irqsave(&ctxt->kref, diag_context_release,
				&ctxt->lock);
		kref_put_lock(&ctxt->kref, diag_context_release, &ctxt->lock);
		return -EIO;
	}