sclp_config.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * drivers/s390/char/sclp_config.c
  3. *
  4. * Copyright IBM Corp. 2007
  5. * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/errno.h>
  9. #include <linux/cpu.h>
  10. #include <linux/sysdev.h>
  11. #include <linux/workqueue.h>
  12. #include <asm/smp.h>
  13. #include "sclp.h"
  14. #define TAG "sclp_config: "
  15. struct conf_mgm_data {
  16. u8 reserved;
  17. u8 ev_qualifier;
  18. } __attribute__((packed));
  19. #define EV_QUAL_CPU_CHANGE 1
  20. #define EV_QUAL_CAP_CHANGE 3
  21. static struct work_struct sclp_cpu_capability_work;
  22. static struct work_struct sclp_cpu_change_work;
  23. static void sclp_cpu_capability_notify(struct work_struct *work)
  24. {
  25. int cpu;
  26. struct sys_device *sysdev;
  27. printk(KERN_WARNING TAG "cpu capability changed.\n");
  28. get_online_cpus();
  29. for_each_online_cpu(cpu) {
  30. sysdev = get_cpu_sysdev(cpu);
  31. kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
  32. }
  33. put_online_cpus();
  34. }
  35. static void __ref sclp_cpu_change_notify(struct work_struct *work)
  36. {
  37. smp_rescan_cpus();
  38. }
  39. static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
  40. {
  41. struct conf_mgm_data *cdata;
  42. cdata = (struct conf_mgm_data *)(evbuf + 1);
  43. switch (cdata->ev_qualifier) {
  44. case EV_QUAL_CPU_CHANGE:
  45. schedule_work(&sclp_cpu_change_work);
  46. break;
  47. case EV_QUAL_CAP_CHANGE:
  48. schedule_work(&sclp_cpu_capability_work);
  49. break;
  50. }
  51. }
  52. static struct sclp_register sclp_conf_register =
  53. {
  54. .receive_mask = EVTYP_CONFMGMDATA_MASK,
  55. .receiver_fn = sclp_conf_receiver_fn,
  56. };
  57. static int __init sclp_conf_init(void)
  58. {
  59. int rc;
  60. INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
  61. INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
  62. rc = sclp_register(&sclp_conf_register);
  63. if (rc)
  64. return rc;
  65. if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
  66. printk(KERN_WARNING TAG "no configuration management.\n");
  67. sclp_unregister(&sclp_conf_register);
  68. rc = -ENOSYS;
  69. }
  70. return rc;
  71. }
  72. __initcall(sclp_conf_init);