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

Commit 9c033e81 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman
Browse files

USB: ehci refcounts work on ppc7448



Remove atomic operations on the reference counter for EHCI queue heads.
On various platforms (including ppc7448), atomic operations are unusable
with dma-coherent memory.

Signed-off-by: default avatarSteven J. Hill <sjhill1@rockwellcollins.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 04d06ad0
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -64,9 +64,8 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
}
}




static void qh_destroy (struct kref *kref)
static void qh_destroy(struct ehci_qh *qh)
{
{
	struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref);
	struct ehci_hcd *ehci = qh->ehci;
	struct ehci_hcd *ehci = qh->ehci;


	/* clean qtds first, and know this is not linked */
	/* clean qtds first, and know this is not linked */
@@ -90,7 +89,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
		return qh;
		return qh;


	memset (qh, 0, sizeof *qh);
	memset (qh, 0, sizeof *qh);
	kref_init(&qh->kref);
	qh->refcount = 1;
	qh->ehci = ehci;
	qh->ehci = ehci;
	qh->qh_dma = dma;
	qh->qh_dma = dma;
	// INIT_LIST_HEAD (&qh->qh_list);
	// INIT_LIST_HEAD (&qh->qh_list);
@@ -112,13 +111,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
/* to share a qh (cpu threads, or hc) */
/* to share a qh (cpu threads, or hc) */
static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
{
{
	kref_get(&qh->kref);
	WARN_ON(!qh->refcount);
	qh->refcount++;
	return qh;
	return qh;
}
}


static inline void qh_put (struct ehci_qh *qh)
static inline void qh_put (struct ehci_qh *qh)
{
{
	kref_put(&qh->kref, qh_destroy);
	if (!--qh->refcount)
		qh_destroy(qh);
}
}


/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
+8 −1
Original line number Original line Diff line number Diff line
@@ -457,7 +457,14 @@ struct ehci_qh {
	struct ehci_qh		*reclaim;	/* next to reclaim */
	struct ehci_qh		*reclaim;	/* next to reclaim */


	struct ehci_hcd		*ehci;
	struct ehci_hcd		*ehci;
	struct kref		kref;

	/*
	 * Do NOT use atomic operations for QH refcounting. On some CPUs
	 * (PPC7448 for example), atomic operations cannot be performed on
	 * memory that is cache-inhibited (i.e. being used for DMA).
	 * Spinlocks are used to protect all QH fields.
	 */
	u32			refcount;
	unsigned		stamp;
	unsigned		stamp;


	u8			qh_state;
	u8			qh_state;