sclp_config.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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/device.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 device *dev;
  28. s390_adjust_jiffies();
  29. pr_warning("cpu capability changed.\n");
  30. get_online_cpus();
  31. for_each_online_cpu(cpu) {
  32. dev = get_cpu_device(cpu);
  33. kobject_uevent(&dev->kobj, KOBJ_CHANGE);
  34. }
  35. put_online_cpus();
  36. }
  37. static void __ref sclp_cpu_change_notify(struct work_struct *work)
  38. {
  39. smp_rescan_cpus();
  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);