diff options
Diffstat (limited to 'drivers/thunderbolt/nhi.h')
-rw-r--r-- | drivers/thunderbolt/nhi.h | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index 317242939b31..630f44140530 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -7,45 +7,75 @@ #ifndef DSL3510_H_ #define DSL3510_H_ +#include <linux/idr.h> #include <linux/mutex.h> #include <linux/workqueue.h> /** * struct tb_nhi - thunderbolt native host interface + * @lock: Must be held during ring creation/destruction. Is acquired by + * interrupt_work when dispatching interrupts to individual rings. + * @pdev: Pointer to the PCI device + * @iobase: MMIO space of the NHI + * @tx_rings: All Tx rings available on this host controller + * @rx_rings: All Rx rings available on this host controller + * @msix_ida: Used to allocate MSI-X vectors for rings + * @interrupt_work: Work scheduled to handle ring interrupt when no + * MSI-X is used. + * @hop_count: Number of rings (end point hops) supported by NHI. */ struct tb_nhi { - struct mutex lock; /* - * Must be held during ring creation/destruction. - * Is acquired by interrupt_work when dispatching - * interrupts to individual rings. - **/ + struct mutex lock; struct pci_dev *pdev; void __iomem *iobase; struct tb_ring **tx_rings; struct tb_ring **rx_rings; + struct ida msix_ida; struct work_struct interrupt_work; - u32 hop_count; /* Number of rings (end point hops) supported by NHI. */ + u32 hop_count; }; /** * struct tb_ring - thunderbolt TX or RX ring associated with a NHI + * @lock: Lock serializing actions to this ring. Must be acquired after + * nhi->lock. + * @nhi: Pointer to the native host controller interface + * @size: Size of the ring + * @hop: Hop (DMA channel) associated with this ring + * @head: Head of the ring (write next descriptor here) + * @tail: Tail of the ring (complete next descriptor here) + * @descriptors: Allocated descriptors for this ring + * @queue: Queue holding frames to be transferred over this ring + * @in_flight: Queue holding frames that are currently in flight + * @work: Interrupt work structure + * @is_tx: Is the ring Tx or Rx + * @running: Is the ring running + * @irq: MSI-X irq number if the ring uses MSI-X. %0 otherwise. + * @vector: MSI-X vector number the ring uses (only set if @irq is > 0) + * @flags: Ring specific flags */ struct tb_ring { - struct mutex lock; /* must be acquired after nhi->lock */ + struct mutex lock; struct tb_nhi *nhi; int size; int hop; - int head; /* write next descriptor here */ - int tail; /* complete next descriptor here */ + int head; + int tail; struct ring_desc *descriptors; dma_addr_t descriptors_dma; struct list_head queue; struct list_head in_flight; struct work_struct work; - bool is_tx:1; /* rx otherwise */ + bool is_tx:1; bool running:1; + int irq; + u8 vector; + unsigned int flags; }; +/* Leave ring interrupt enabled on suspend */ +#define RING_FLAG_NO_SUSPEND BIT(0) + struct ring_frame; typedef void (*ring_cb)(struct tb_ring*, struct ring_frame*, bool canceled); @@ -64,8 +94,10 @@ struct ring_frame { #define TB_FRAME_SIZE 0x100 /* minimum size for ring_rx */ -struct tb_ring *ring_alloc_tx(struct tb_nhi *nhi, int hop, int size); -struct tb_ring *ring_alloc_rx(struct tb_nhi *nhi, int hop, int size); +struct tb_ring *ring_alloc_tx(struct tb_nhi *nhi, int hop, int size, + unsigned int flags); +struct tb_ring *ring_alloc_rx(struct tb_nhi *nhi, int hop, int size, + unsigned int flags); void ring_start(struct tb_ring *ring); void ring_stop(struct tb_ring *ring); void ring_free(struct tb_ring *ring); |