Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright 2017 Thomas Gleixner <tglx@linutronix.de>
  3
  4#include <linux/irqdomain.h>
  5#include <linux/irq.h>
  6#include <linux/uaccess.h>
  7
  8#include "internals.h"
  9
 10static struct dentry *irq_dir;
 11
 12struct irq_bit_descr {
 13	unsigned int	mask;
 14	char		*name;
 15};
 16#define BIT_MASK_DESCR(m)	{ .mask = m, .name = #m }
 17
 18static void irq_debug_show_bits(struct seq_file *m, int ind, unsigned int state,
 19				const struct irq_bit_descr *sd, int size)
 20{
 21	int i;
 22
 23	for (i = 0; i < size; i++, sd++) {
 24		if (state & sd->mask)
 25			seq_printf(m, "%*s%s\n", ind + 12, "", sd->name);
 26	}
 27}
 28
 29#ifdef CONFIG_SMP
 30static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc)
 31{
 32	struct irq_data *data = irq_desc_get_irq_data(desc);
 33	const struct cpumask *msk;
 34
 35	msk = irq_data_get_affinity_mask(data);
 36	seq_printf(m, "affinity: %*pbl\n", cpumask_pr_args(msk));
 37#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
 38	msk = irq_data_get_effective_affinity_mask(data);
 39	seq_printf(m, "effectiv: %*pbl\n", cpumask_pr_args(msk));
 40#endif
 41#ifdef CONFIG_GENERIC_PENDING_IRQ
 42	msk = desc->pending_mask;
 43	seq_printf(m, "pending:  %*pbl\n", cpumask_pr_args(msk));
 44#endif
 45}
 46#else
 47static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc) { }
 48#endif
 49
 50static const struct irq_bit_descr irqchip_flags[] = {
 51	BIT_MASK_DESCR(IRQCHIP_SET_TYPE_MASKED),
 52	BIT_MASK_DESCR(IRQCHIP_EOI_IF_HANDLED),
 53	BIT_MASK_DESCR(IRQCHIP_MASK_ON_SUSPEND),
 54	BIT_MASK_DESCR(IRQCHIP_ONOFFLINE_ENABLED),
 55	BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE),
 56	BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE),
 57	BIT_MASK_DESCR(IRQCHIP_EOI_THREADED),
 58	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
 59	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI),
 60	BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND),
 61	BIT_MASK_DESCR(IRQCHIP_IMMUTABLE),
 62};
 63
 64static void
 65irq_debug_show_chip(struct seq_file *m, struct irq_data *data, int ind)
 66{
 67	struct irq_chip *chip = data->chip;
 68
 69	if (!chip) {
 70		seq_printf(m, "chip: None\n");
 71		return;
 72	}
 73	seq_printf(m, "%*schip:    ", ind, "");
 74	if (chip->irq_print_chip)
 75		chip->irq_print_chip(data, m);
 76	else
 77		seq_printf(m, "%s", chip->name);
 78	seq_printf(m, "\n%*sflags:   0x%lx\n", ind + 1, "", chip->flags);
 79	irq_debug_show_bits(m, ind, chip->flags, irqchip_flags,
 80			    ARRAY_SIZE(irqchip_flags));
 81}
 82
 83static void
 84irq_debug_show_data(struct seq_file *m, struct irq_data *data, int ind)
 85{
 86	seq_printf(m, "%*sdomain:  %s\n", ind, "",
 87		   data->domain ? data->domain->name : "");
 88	seq_printf(m, "%*shwirq:   0x%lx\n", ind + 1, "", data->hwirq);
 89	irq_debug_show_chip(m, data, ind + 1);
 90	if (data->domain && data->domain->ops && data->domain->ops->debug_show)
 91		data->domain->ops->debug_show(m, NULL, data, ind + 1);
 92#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
 93	if (!data->parent_data)
 94		return;
 95	seq_printf(m, "%*sparent:\n", ind + 1, "");
 96	irq_debug_show_data(m, data->parent_data, ind + 4);
 97#endif
 98}
 99
100static const struct irq_bit_descr irqdata_states[] = {
101	BIT_MASK_DESCR(IRQ_TYPE_EDGE_RISING),
102	BIT_MASK_DESCR(IRQ_TYPE_EDGE_FALLING),
103	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_HIGH),
104	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_LOW),
105	BIT_MASK_DESCR(IRQD_LEVEL),
106
107	BIT_MASK_DESCR(IRQD_ACTIVATED),
108	BIT_MASK_DESCR(IRQD_IRQ_STARTED),
109	BIT_MASK_DESCR(IRQD_IRQ_DISABLED),
110	BIT_MASK_DESCR(IRQD_IRQ_MASKED),
111	BIT_MASK_DESCR(IRQD_IRQ_INPROGRESS),
112
113	BIT_MASK_DESCR(IRQD_PER_CPU),
114	BIT_MASK_DESCR(IRQD_NO_BALANCING),
115
116	BIT_MASK_DESCR(IRQD_SINGLE_TARGET),
117	BIT_MASK_DESCR(IRQD_MOVE_PCNTXT),
118	BIT_MASK_DESCR(IRQD_AFFINITY_SET),
119	BIT_MASK_DESCR(IRQD_SETAFFINITY_PENDING),
120	BIT_MASK_DESCR(IRQD_AFFINITY_MANAGED),
121	BIT_MASK_DESCR(IRQD_AFFINITY_ON_ACTIVATE),
122	BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN),
123	BIT_MASK_DESCR(IRQD_CAN_RESERVE),
124	BIT_MASK_DESCR(IRQD_MSI_NOMASK_QUIRK),
125
126	BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU),
127
128	BIT_MASK_DESCR(IRQD_WAKEUP_STATE),
129	BIT_MASK_DESCR(IRQD_WAKEUP_ARMED),
130
131	BIT_MASK_DESCR(IRQD_DEFAULT_TRIGGER_SET),
132
133	BIT_MASK_DESCR(IRQD_HANDLE_ENFORCE_IRQCTX),
134
135	BIT_MASK_DESCR(IRQD_IRQ_ENABLED_ON_SUSPEND),
136};
137
138static const struct irq_bit_descr irqdesc_states[] = {
139	BIT_MASK_DESCR(_IRQ_NOPROBE),
140	BIT_MASK_DESCR(_IRQ_NOREQUEST),
141	BIT_MASK_DESCR(_IRQ_NOTHREAD),
142	BIT_MASK_DESCR(_IRQ_NOAUTOEN),
143	BIT_MASK_DESCR(_IRQ_NESTED_THREAD),
144	BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID),
145	BIT_MASK_DESCR(_IRQ_IS_POLLED),
146	BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY),
147	BIT_MASK_DESCR(_IRQ_HIDDEN),
148};
149
150static const struct irq_bit_descr irqdesc_istates[] = {
151	BIT_MASK_DESCR(IRQS_AUTODETECT),
152	BIT_MASK_DESCR(IRQS_SPURIOUS_DISABLED),
153	BIT_MASK_DESCR(IRQS_POLL_INPROGRESS),
154	BIT_MASK_DESCR(IRQS_ONESHOT),
155	BIT_MASK_DESCR(IRQS_REPLAY),
156	BIT_MASK_DESCR(IRQS_WAITING),
157	BIT_MASK_DESCR(IRQS_PENDING),
158	BIT_MASK_DESCR(IRQS_SUSPENDED),
159	BIT_MASK_DESCR(IRQS_NMI),
160};
161
162
163static int irq_debug_show(struct seq_file *m, void *p)
164{
165	struct irq_desc *desc = m->private;
166	struct irq_data *data;
167
168	raw_spin_lock_irq(&desc->lock);
169	data = irq_desc_get_irq_data(desc);
170	seq_printf(m, "handler:  %ps\n", desc->handle_irq);
171	seq_printf(m, "device:   %s\n", desc->dev_name);
172	seq_printf(m, "status:   0x%08x\n", desc->status_use_accessors);
173	irq_debug_show_bits(m, 0, desc->status_use_accessors, irqdesc_states,
174			    ARRAY_SIZE(irqdesc_states));
175	seq_printf(m, "istate:   0x%08x\n", desc->istate);
176	irq_debug_show_bits(m, 0, desc->istate, irqdesc_istates,
177			    ARRAY_SIZE(irqdesc_istates));
178	seq_printf(m, "ddepth:   %u\n", desc->depth);
179	seq_printf(m, "wdepth:   %u\n", desc->wake_depth);
180	seq_printf(m, "dstate:   0x%08x\n", irqd_get(data));
181	irq_debug_show_bits(m, 0, irqd_get(data), irqdata_states,
182			    ARRAY_SIZE(irqdata_states));
183	seq_printf(m, "node:     %d\n", irq_data_get_node(data));
184	irq_debug_show_masks(m, desc);
185	irq_debug_show_data(m, data, 0);
186	raw_spin_unlock_irq(&desc->lock);
187	return 0;
188}
189
190static int irq_debug_open(struct inode *inode, struct file *file)
191{
192	return single_open(file, irq_debug_show, inode->i_private);
193}
194
195static ssize_t irq_debug_write(struct file *file, const char __user *user_buf,
196			       size_t count, loff_t *ppos)
197{
198	struct irq_desc *desc = file_inode(file)->i_private;
199	char buf[8] = { 0, };
200	size_t size;
201
202	size = min(sizeof(buf) - 1, count);
203	if (copy_from_user(buf, user_buf, size))
204		return -EFAULT;
205
206	if (!strncmp(buf, "trigger", size)) {
207		int err = irq_inject_interrupt(irq_desc_get_irq(desc));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
209		return err ? err : count;
210	}
211
212	return count;
213}
214
215static const struct file_operations dfs_irq_ops = {
216	.open		= irq_debug_open,
217	.write		= irq_debug_write,
218	.read		= seq_read,
219	.llseek		= seq_lseek,
220	.release	= single_release,
221};
222
223void irq_debugfs_copy_devname(int irq, struct device *dev)
224{
225	struct irq_desc *desc = irq_to_desc(irq);
226	const char *name = dev_name(dev);
227
228	if (name)
229		desc->dev_name = kstrdup(name, GFP_KERNEL);
230}
231
232void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc)
233{
234	char name [10];
235
236	if (!irq_dir || !desc || desc->debugfs_file)
237		return;
238
239	sprintf(name, "%d", irq);
240	desc->debugfs_file = debugfs_create_file(name, 0644, irq_dir, desc,
241						 &dfs_irq_ops);
242}
243
244static int __init irq_debugfs_init(void)
245{
246	struct dentry *root_dir;
247	int irq;
248
249	root_dir = debugfs_create_dir("irq", NULL);
250
251	irq_domain_debugfs_init(root_dir);
252
253	irq_dir = debugfs_create_dir("irqs", root_dir);
254
255	irq_lock_sparse();
256	for_each_active_irq(irq)
257		irq_add_debugfs_entry(irq, irq_to_desc(irq));
258	irq_unlock_sparse();
259
260	return 0;
261}
262__initcall(irq_debugfs_init);
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright 2017 Thomas Gleixner <tglx@linutronix.de>
  3
  4#include <linux/irqdomain.h>
  5#include <linux/irq.h>
  6#include <linux/uaccess.h>
  7
  8#include "internals.h"
  9
 10static struct dentry *irq_dir;
 11
 12struct irq_bit_descr {
 13	unsigned int	mask;
 14	char		*name;
 15};
 16#define BIT_MASK_DESCR(m)	{ .mask = m, .name = #m }
 17
 18static void irq_debug_show_bits(struct seq_file *m, int ind, unsigned int state,
 19				const struct irq_bit_descr *sd, int size)
 20{
 21	int i;
 22
 23	for (i = 0; i < size; i++, sd++) {
 24		if (state & sd->mask)
 25			seq_printf(m, "%*s%s\n", ind + 12, "", sd->name);
 26	}
 27}
 28
 29#ifdef CONFIG_SMP
 30static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc)
 31{
 32	struct irq_data *data = irq_desc_get_irq_data(desc);
 33	struct cpumask *msk;
 34
 35	msk = irq_data_get_affinity_mask(data);
 36	seq_printf(m, "affinity: %*pbl\n", cpumask_pr_args(msk));
 37#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
 38	msk = irq_data_get_effective_affinity_mask(data);
 39	seq_printf(m, "effectiv: %*pbl\n", cpumask_pr_args(msk));
 40#endif
 41#ifdef CONFIG_GENERIC_PENDING_IRQ
 42	msk = desc->pending_mask;
 43	seq_printf(m, "pending:  %*pbl\n", cpumask_pr_args(msk));
 44#endif
 45}
 46#else
 47static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc) { }
 48#endif
 49
 50static const struct irq_bit_descr irqchip_flags[] = {
 51	BIT_MASK_DESCR(IRQCHIP_SET_TYPE_MASKED),
 52	BIT_MASK_DESCR(IRQCHIP_EOI_IF_HANDLED),
 53	BIT_MASK_DESCR(IRQCHIP_MASK_ON_SUSPEND),
 54	BIT_MASK_DESCR(IRQCHIP_ONOFFLINE_ENABLED),
 55	BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE),
 56	BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE),
 57	BIT_MASK_DESCR(IRQCHIP_EOI_THREADED),
 58	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
 59	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI),
 
 
 60};
 61
 62static void
 63irq_debug_show_chip(struct seq_file *m, struct irq_data *data, int ind)
 64{
 65	struct irq_chip *chip = data->chip;
 66
 67	if (!chip) {
 68		seq_printf(m, "chip: None\n");
 69		return;
 70	}
 71	seq_printf(m, "%*schip:    %s\n", ind, "", chip->name);
 72	seq_printf(m, "%*sflags:   0x%lx\n", ind + 1, "", chip->flags);
 
 
 
 
 73	irq_debug_show_bits(m, ind, chip->flags, irqchip_flags,
 74			    ARRAY_SIZE(irqchip_flags));
 75}
 76
 77static void
 78irq_debug_show_data(struct seq_file *m, struct irq_data *data, int ind)
 79{
 80	seq_printf(m, "%*sdomain:  %s\n", ind, "",
 81		   data->domain ? data->domain->name : "");
 82	seq_printf(m, "%*shwirq:   0x%lx\n", ind + 1, "", data->hwirq);
 83	irq_debug_show_chip(m, data, ind + 1);
 84	if (data->domain && data->domain->ops && data->domain->ops->debug_show)
 85		data->domain->ops->debug_show(m, NULL, data, ind + 1);
 86#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
 87	if (!data->parent_data)
 88		return;
 89	seq_printf(m, "%*sparent:\n", ind + 1, "");
 90	irq_debug_show_data(m, data->parent_data, ind + 4);
 91#endif
 92}
 93
 94static const struct irq_bit_descr irqdata_states[] = {
 95	BIT_MASK_DESCR(IRQ_TYPE_EDGE_RISING),
 96	BIT_MASK_DESCR(IRQ_TYPE_EDGE_FALLING),
 97	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_HIGH),
 98	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_LOW),
 99	BIT_MASK_DESCR(IRQD_LEVEL),
100
101	BIT_MASK_DESCR(IRQD_ACTIVATED),
102	BIT_MASK_DESCR(IRQD_IRQ_STARTED),
103	BIT_MASK_DESCR(IRQD_IRQ_DISABLED),
104	BIT_MASK_DESCR(IRQD_IRQ_MASKED),
105	BIT_MASK_DESCR(IRQD_IRQ_INPROGRESS),
106
107	BIT_MASK_DESCR(IRQD_PER_CPU),
108	BIT_MASK_DESCR(IRQD_NO_BALANCING),
109
110	BIT_MASK_DESCR(IRQD_SINGLE_TARGET),
111	BIT_MASK_DESCR(IRQD_MOVE_PCNTXT),
112	BIT_MASK_DESCR(IRQD_AFFINITY_SET),
113	BIT_MASK_DESCR(IRQD_SETAFFINITY_PENDING),
114	BIT_MASK_DESCR(IRQD_AFFINITY_MANAGED),
 
115	BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN),
116	BIT_MASK_DESCR(IRQD_CAN_RESERVE),
 
117
118	BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU),
119
120	BIT_MASK_DESCR(IRQD_WAKEUP_STATE),
121	BIT_MASK_DESCR(IRQD_WAKEUP_ARMED),
 
 
 
 
 
 
122};
123
124static const struct irq_bit_descr irqdesc_states[] = {
125	BIT_MASK_DESCR(_IRQ_NOPROBE),
126	BIT_MASK_DESCR(_IRQ_NOREQUEST),
127	BIT_MASK_DESCR(_IRQ_NOTHREAD),
128	BIT_MASK_DESCR(_IRQ_NOAUTOEN),
129	BIT_MASK_DESCR(_IRQ_NESTED_THREAD),
130	BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID),
131	BIT_MASK_DESCR(_IRQ_IS_POLLED),
132	BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY),
 
133};
134
135static const struct irq_bit_descr irqdesc_istates[] = {
136	BIT_MASK_DESCR(IRQS_AUTODETECT),
137	BIT_MASK_DESCR(IRQS_SPURIOUS_DISABLED),
138	BIT_MASK_DESCR(IRQS_POLL_INPROGRESS),
139	BIT_MASK_DESCR(IRQS_ONESHOT),
140	BIT_MASK_DESCR(IRQS_REPLAY),
141	BIT_MASK_DESCR(IRQS_WAITING),
142	BIT_MASK_DESCR(IRQS_PENDING),
143	BIT_MASK_DESCR(IRQS_SUSPENDED),
144	BIT_MASK_DESCR(IRQS_NMI),
145};
146
147
148static int irq_debug_show(struct seq_file *m, void *p)
149{
150	struct irq_desc *desc = m->private;
151	struct irq_data *data;
152
153	raw_spin_lock_irq(&desc->lock);
154	data = irq_desc_get_irq_data(desc);
155	seq_printf(m, "handler:  %ps\n", desc->handle_irq);
156	seq_printf(m, "device:   %s\n", desc->dev_name);
157	seq_printf(m, "status:   0x%08x\n", desc->status_use_accessors);
158	irq_debug_show_bits(m, 0, desc->status_use_accessors, irqdesc_states,
159			    ARRAY_SIZE(irqdesc_states));
160	seq_printf(m, "istate:   0x%08x\n", desc->istate);
161	irq_debug_show_bits(m, 0, desc->istate, irqdesc_istates,
162			    ARRAY_SIZE(irqdesc_istates));
163	seq_printf(m, "ddepth:   %u\n", desc->depth);
164	seq_printf(m, "wdepth:   %u\n", desc->wake_depth);
165	seq_printf(m, "dstate:   0x%08x\n", irqd_get(data));
166	irq_debug_show_bits(m, 0, irqd_get(data), irqdata_states,
167			    ARRAY_SIZE(irqdata_states));
168	seq_printf(m, "node:     %d\n", irq_data_get_node(data));
169	irq_debug_show_masks(m, desc);
170	irq_debug_show_data(m, data, 0);
171	raw_spin_unlock_irq(&desc->lock);
172	return 0;
173}
174
175static int irq_debug_open(struct inode *inode, struct file *file)
176{
177	return single_open(file, irq_debug_show, inode->i_private);
178}
179
180static ssize_t irq_debug_write(struct file *file, const char __user *user_buf,
181			       size_t count, loff_t *ppos)
182{
183	struct irq_desc *desc = file_inode(file)->i_private;
184	char buf[8] = { 0, };
185	size_t size;
186
187	size = min(sizeof(buf) - 1, count);
188	if (copy_from_user(buf, user_buf, size))
189		return -EFAULT;
190
191	if (!strncmp(buf, "trigger", size)) {
192		unsigned long flags;
193		int err;
194
195		/* Try the HW interface first */
196		err = irq_set_irqchip_state(irq_desc_get_irq(desc),
197					    IRQCHIP_STATE_PENDING, true);
198		if (!err)
199			return count;
200
201		/*
202		 * Otherwise, try to inject via the resend interface,
203		 * which may or may not succeed.
204		 */
205		chip_bus_lock(desc);
206		raw_spin_lock_irqsave(&desc->lock, flags);
207
208		if (irq_settings_is_level(desc) || desc->istate & IRQS_NMI) {
209			/* Can't do level nor NMIs, sorry */
210			err = -EINVAL;
211		} else {
212			desc->istate |= IRQS_PENDING;
213			check_irq_resend(desc);
214			err = 0;
215		}
216
217		raw_spin_unlock_irqrestore(&desc->lock, flags);
218		chip_bus_sync_unlock(desc);
219
220		return err ? err : count;
221	}
222
223	return count;
224}
225
226static const struct file_operations dfs_irq_ops = {
227	.open		= irq_debug_open,
228	.write		= irq_debug_write,
229	.read		= seq_read,
230	.llseek		= seq_lseek,
231	.release	= single_release,
232};
233
234void irq_debugfs_copy_devname(int irq, struct device *dev)
235{
236	struct irq_desc *desc = irq_to_desc(irq);
237	const char *name = dev_name(dev);
238
239	if (name)
240		desc->dev_name = kstrdup(name, GFP_KERNEL);
241}
242
243void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc)
244{
245	char name [10];
246
247	if (!irq_dir || !desc || desc->debugfs_file)
248		return;
249
250	sprintf(name, "%d", irq);
251	desc->debugfs_file = debugfs_create_file(name, 0644, irq_dir, desc,
252						 &dfs_irq_ops);
253}
254
255static int __init irq_debugfs_init(void)
256{
257	struct dentry *root_dir;
258	int irq;
259
260	root_dir = debugfs_create_dir("irq", NULL);
261
262	irq_domain_debugfs_init(root_dir);
263
264	irq_dir = debugfs_create_dir("irqs", root_dir);
265
266	irq_lock_sparse();
267	for_each_active_irq(irq)
268		irq_add_debugfs_entry(irq, irq_to_desc(irq));
269	irq_unlock_sparse();
270
271	return 0;
272}
273__initcall(irq_debugfs_init);