Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Support for hardware-assisted userspace interrupt masking.
0003  *
0004  * Copyright (C) 2010  Paul Mundt
0005  *
0006  * This file is subject to the terms and conditions of the GNU General Public
0007  * License.  See the file "COPYING" in the main directory of this archive
0008  * for more details.
0009  */
0010 #define pr_fmt(fmt) "intc: " fmt
0011 
0012 #include <linux/errno.h>
0013 #include <linux/device.h>
0014 #include <linux/init.h>
0015 #include <linux/io.h>
0016 #include <linux/stat.h>
0017 #include <linux/sizes.h>
0018 #include "internals.h"
0019 
0020 static void __iomem *uimask;
0021 
0022 static ssize_t
0023 show_intc_userimask(struct device *dev,
0024             struct device_attribute *attr, char *buf)
0025 {
0026     return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
0027 }
0028 
0029 static ssize_t
0030 store_intc_userimask(struct device *dev,
0031              struct device_attribute *attr,
0032              const char *buf, size_t count)
0033 {
0034     unsigned long level;
0035 
0036     level = simple_strtoul(buf, NULL, 10);
0037 
0038     /*
0039      * Minimal acceptable IRQ levels are in the 2 - 16 range, but
0040      * these are chomped so as to not interfere with normal IRQs.
0041      *
0042      * Level 1 is a special case on some CPUs in that it's not
0043      * directly settable, but given that USERIMASK cuts off below a
0044      * certain level, we don't care about this limitation here.
0045      * Level 0 on the other hand equates to user masking disabled.
0046      *
0047      * We use the default priority level as a cut off so that only
0048      * special case opt-in IRQs can be mangled.
0049      */
0050     if (level >= intc_get_dfl_prio_level())
0051         return -EINVAL;
0052 
0053     __raw_writel(0xa5 << 24 | level << 4, uimask);
0054 
0055     return count;
0056 }
0057 
0058 static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR,
0059            show_intc_userimask, store_intc_userimask);
0060 
0061 
0062 static int __init userimask_sysdev_init(void)
0063 {
0064     if (unlikely(!uimask))
0065         return -ENXIO;
0066 
0067     return device_create_file(intc_subsys.dev_root, &dev_attr_userimask);
0068 }
0069 late_initcall(userimask_sysdev_init);
0070 
0071 int register_intc_userimask(unsigned long addr)
0072 {
0073     if (unlikely(uimask))
0074         return -EBUSY;
0075 
0076     uimask = ioremap(addr, SZ_4K);
0077     if (unlikely(!uimask))
0078         return -ENOMEM;
0079 
0080     pr_info("userimask support registered for levels 0 -> %d\n",
0081         intc_get_dfl_prio_level() - 1);
0082 
0083     return 0;
0084 }