sclp_config.c 1.9 KB

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