summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mic/host/mic_intr.h
blob: b14ba818006ff4505f6a116309c5f31746596e39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2013 Intel Corporation.
 *
 * Intel MIC Host driver.
 */
#ifndef _MIC_INTR_H_
#define _MIC_INTR_H_

#include <linux/bitops.h>
#include <linux/interrupt.h>
/*
 * The minimum number of msix vectors required for normal operation.
 * 3 for virtio network, console and block devices.
 * 1 for card shutdown notifications.
 * 4 for host owned DMA channels.
 * 1 for SCIF
 */
#define MIC_MIN_MSIX 9
#define MIC_NUM_OFFSETS 32

/**
 * mic_intr_source - The type of source that will generate
 * the interrupt.The number of types needs to be in sync with
 * MIC_NUM_INTR_TYPES
 *
 * MIC_INTR_DB: The source is a doorbell
 * MIC_INTR_DMA: The source is a DMA channel
 * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR
 * MIC_NUM_INTR_TYPES: Total number of interrupt sources.
 */
enum mic_intr_type {
	MIC_INTR_DB = 0,
	MIC_INTR_DMA,
	MIC_INTR_ERR,
	MIC_NUM_INTR_TYPES
};

/**
 * struct mic_intr_info - Contains h/w specific interrupt sources
 * information.
 *
 * @intr_start_idx: Contains the starting indexes of the
 * interrupt types.
 * @intr_len: Contains the length of the interrupt types.
 */
struct mic_intr_info {
	u16 intr_start_idx[MIC_NUM_INTR_TYPES];
	u16 intr_len[MIC_NUM_INTR_TYPES];
};

/**
 * struct mic_irq_info - OS specific irq information
 *
 * @next_avail_src: next available doorbell that can be assigned.
 * @msix_entries: msix entries allocated while setting up MSI-x
 * @mic_msi_map: The MSI/MSI-x mapping information.
 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
 * @cb_ida: callback ID allocator to track the callbacks registered.
 * @mic_intr_lock: spinlock to protect the interrupt callback list.
 * @mic_thread_lock: spinlock to protect the thread callback list.
 *		   This lock is used to protect against thread_fn while
 *		   mic_intr_lock is used to protect against interrupt handler.
 * @cb_list: Array of callback lists one for each source.
 * @mask: Mask used by the main thread fn to call the underlying thread fns.
 */
struct mic_irq_info {
	int next_avail_src;
	struct msix_entry *msix_entries;
	u32 *mic_msi_map;
	u16 num_vectors;
	struct ida cb_ida;
	spinlock_t mic_intr_lock;
	spinlock_t mic_thread_lock;
	struct list_head *cb_list;
	unsigned long mask;
};

/**
 * struct mic_intr_cb - Interrupt callback structure.
 *
 * @handler: The callback function
 * @thread_fn: The thread_fn.
 * @data: Private data of the requester.
 * @cb_id: The callback id. Identifies this callback.
 * @list: list head pointing to the next callback structure.
 */
struct mic_intr_cb {
	irq_handler_t handler;
	irq_handler_t thread_fn;
	void *data;
	int cb_id;
	struct list_head list;
};

/**
 * struct mic_irq - opaque pointer used as cookie
 */
struct mic_irq;

/* Forward declaration */
struct mic_device;

/**
 * struct mic_hw_intr_ops: MIC HW specific interrupt operations
 * @intr_init: Initialize H/W specific interrupt information.
 * @enable_interrupts: Enable interrupts from the hardware.
 * @disable_interrupts: Disable interrupts from the hardware.
 * @program_msi_to_src_map: Update MSI mapping registers with
 * irq information.
 * @read_msi_to_src_map: Read MSI mapping registers containing
 * irq information.
 */
struct mic_hw_intr_ops {
	void (*intr_init)(struct mic_device *mdev);
	void (*enable_interrupts)(struct mic_device *mdev);
	void (*disable_interrupts)(struct mic_device *mdev);
	void (*program_msi_to_src_map) (struct mic_device *mdev,
			int idx, int intr_src, bool set);
	u32 (*read_msi_to_src_map) (struct mic_device *mdev,
			int idx);
};

int mic_next_db(struct mic_device *mdev);
struct mic_irq *
mic_request_threaded_irq(struct mic_device *mdev,
			 irq_handler_t handler, irq_handler_t thread_fn,
			 const char *name, void *data, int intr_src,
			 enum mic_intr_type type);
void mic_free_irq(struct mic_device *mdev,
		struct mic_irq *cookie, void *data);
int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
void mic_intr_restore(struct mic_device *mdev);
#endif