Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.1-rc4 83 lines 2.1 kB view raw
1/* 2 * Support for hardware-assisted userspace interrupt masking. 3 * 4 * Copyright (C) 2010 Paul Mundt 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10#define pr_fmt(fmt) "intc: " fmt 11 12#include <linux/errno.h> 13#include <linux/sysdev.h> 14#include <linux/init.h> 15#include <linux/io.h> 16#include <asm/sizes.h> 17#include "internals.h" 18 19static void __iomem *uimask; 20 21static ssize_t 22show_intc_userimask(struct sysdev_class *cls, 23 struct sysdev_class_attribute *attr, char *buf) 24{ 25 return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); 26} 27 28static ssize_t 29store_intc_userimask(struct sysdev_class *cls, 30 struct sysdev_class_attribute *attr, 31 const char *buf, size_t count) 32{ 33 unsigned long level; 34 35 level = simple_strtoul(buf, NULL, 10); 36 37 /* 38 * Minimal acceptable IRQ levels are in the 2 - 16 range, but 39 * these are chomped so as to not interfere with normal IRQs. 40 * 41 * Level 1 is a special case on some CPUs in that it's not 42 * directly settable, but given that USERIMASK cuts off below a 43 * certain level, we don't care about this limitation here. 44 * Level 0 on the other hand equates to user masking disabled. 45 * 46 * We use the default priority level as a cut off so that only 47 * special case opt-in IRQs can be mangled. 48 */ 49 if (level >= intc_get_dfl_prio_level()) 50 return -EINVAL; 51 52 __raw_writel(0xa5 << 24 | level << 4, uimask); 53 54 return count; 55} 56 57static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR, 58 show_intc_userimask, store_intc_userimask); 59 60 61static int __init userimask_sysdev_init(void) 62{ 63 if (unlikely(!uimask)) 64 return -ENXIO; 65 66 return sysdev_class_create_file(&intc_sysdev_class, &attr_userimask); 67} 68late_initcall(userimask_sysdev_init); 69 70int register_intc_userimask(unsigned long addr) 71{ 72 if (unlikely(uimask)) 73 return -EBUSY; 74 75 uimask = ioremap_nocache(addr, SZ_4K); 76 if (unlikely(!uimask)) 77 return -ENOMEM; 78 79 pr_info("userimask support registered for levels 0 -> %d\n", 80 intc_get_dfl_prio_level() - 1); 81 82 return 0; 83}