userimask.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. #include <linux/errno.h>
  12. #include <linux/device.h>
  13. #include <linux/init.h>
  14. #include <linux/io.h>
  15. #include <linux/stat.h>
  16. #include <asm/sizes.h>
  17. #include "internals.h"
  18. static void __iomem *uimask;
  19. static ssize_t
  20. show_intc_userimask(struct device *dev,
  21. struct device_attribute *attr, char *buf)
  22. {
  23. return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
  24. }
  25. static ssize_t
  26. store_intc_userimask(struct device *dev,
  27. struct device_attribute *attr,
  28. const char *buf, size_t count)
  29. {
  30. unsigned long level;
  31. level = simple_strtoul(buf, NULL, 10);
  32. /*
  33. * Minimal acceptable IRQ levels are in the 2 - 16 range, but
  34. * these are chomped so as to not interfere with normal IRQs.
  35. *
  36. * Level 1 is a special case on some CPUs in that it's not
  37. * directly settable, but given that USERIMASK cuts off below a
  38. * certain level, we don't care about this limitation here.
  39. * Level 0 on the other hand equates to user masking disabled.
  40. *
  41. * We use the default priority level as a cut off so that only
  42. * special case opt-in IRQs can be mangled.
  43. */
  44. if (level >= intc_get_dfl_prio_level())
  45. return -EINVAL;
  46. __raw_writel(0xa5 << 24 | level << 4, uimask);
  47. return count;
  48. }
  49. static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR,
  50. show_intc_userimask, store_intc_userimask);
  51. static int __init userimask_sysdev_init(void)
  52. {
  53. if (unlikely(!uimask))
  54. return -ENXIO;
  55. return device_create_file(intc_subsys.dev_root, &dev_attr_userimask);
  56. }
  57. late_initcall(userimask_sysdev_init);
  58. int register_intc_userimask(unsigned long addr)
  59. {
  60. if (unlikely(uimask))
  61. return -EBUSY;
  62. uimask = ioremap_nocache(addr, SZ_4K);
  63. if (unlikely(!uimask))
  64. return -ENOMEM;
  65. pr_info("userimask support registered for levels 0 -> %d\n",
  66. intc_get_dfl_prio_level() - 1);
  67. return 0;
  68. }