sclp_config.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * Copyright IBM Corp. 2007
  3. * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
  4. */
  5. #define KMSG_COMPONENT "sclp_config"
  6. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  7. #include <linux/init.h>
  8. #include <linux/errno.h>
  9. #include <linux/cpu.h>
  10. #include <linux/device.h>
  11. #include <linux/workqueue.h>
  12. #include <asm/smp.h>
  13. #include "sclp.h"
  14. struct conf_mgm_data {
  15. u8 reserved;
  16. u8 ev_qualifier;
  17. } __attribute__((packed));
  18. #define EV_QUAL_CPU_CHANGE 1
  19. #define EV_QUAL_CAP_CHANGE 3
  20. static struct work_struct sclp_cpu_capability_work;
  21. static struct work_struct sclp_cpu_change_work;
  22. static void sclp_cpu_capability_notify(struct work_struct *work)
  23. {
  24. int cpu;
  25. struct device *dev;
  26. s390_adjust_jiffies();
  27. pr_info("CPU capability may have changed\n");
  28. get_online_cpus();
  29. for_each_online_cpu(cpu) {
  30. dev = get_cpu_device(cpu);
  31. kobject_uevent(&dev->kobj, KOBJ_CHANGE);
  32. }
  33. put_online_cpus();
  34. }
  35. static void __ref sclp_cpu_change_notify(struct work_struct *work)
  36. {
  37. lock_device_hotplug();
  38. smp_rescan_cpus();
  39. unlock_device_hotplug();
  40. }
  41. static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
  42. {
  43. struct conf_mgm_data *cdata;
  44. cdata = (struct conf_mgm_data *)(evbuf + 1);
  45. switch (cdata->ev_qualifier) {
  46. case EV_QUAL_CPU_CHANGE:
  47. schedule_work(&sclp_cpu_change_work);
  48. break;
  49. case EV_QUAL_CAP_CHANGE:
  50. schedule_work(&sclp_cpu_capability_work);
  51. break;
  52. }
  53. }
  54. static struct sclp_register sclp_conf_register =
  55. {
  56. .receive_mask = EVTYP_CONFMGMDATA_MASK,
  57. .receiver_fn = sclp_conf_receiver_fn,
  58. };
  59. static int __init sclp_conf_init(void)
  60. {
  61. INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
  62. INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
  63. return sclp_register(&sclp_conf_register);
  64. }
  65. __initcall(sclp_conf_init);