linux/drivers/s390/char/sclp_config.c
<<
>>
Prefs
   1/*
   2 *    Copyright IBM Corp. 2007
   3 *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
   4 */
   5
   6#define KMSG_COMPONENT "sclp_config"
   7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
   8
   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
  16#include "sclp.h"
  17
  18struct conf_mgm_data {
  19        u8 reserved;
  20        u8 ev_qualifier;
  21} __attribute__((packed));
  22
  23#define EV_QUAL_CPU_CHANGE      1
  24#define EV_QUAL_CAP_CHANGE      3
  25
  26static struct work_struct sclp_cpu_capability_work;
  27static struct work_struct sclp_cpu_change_work;
  28
  29static void sclp_cpu_capability_notify(struct work_struct *work)
  30{
  31        int cpu;
  32        struct device *dev;
  33
  34        s390_adjust_jiffies();
  35        pr_warning("cpu capability changed.\n");
  36        get_online_cpus();
  37        for_each_online_cpu(cpu) {
  38                dev = get_cpu_device(cpu);
  39                kobject_uevent(&dev->kobj, KOBJ_CHANGE);
  40        }
  41        put_online_cpus();
  42}
  43
  44static void __ref sclp_cpu_change_notify(struct work_struct *work)
  45{
  46        smp_rescan_cpus();
  47}
  48
  49static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
  50{
  51        struct conf_mgm_data *cdata;
  52
  53        cdata = (struct conf_mgm_data *)(evbuf + 1);
  54        switch (cdata->ev_qualifier) {
  55        case EV_QUAL_CPU_CHANGE:
  56                schedule_work(&sclp_cpu_change_work);
  57                break;
  58        case EV_QUAL_CAP_CHANGE:
  59                schedule_work(&sclp_cpu_capability_work);
  60                break;
  61        }
  62}
  63
  64static struct sclp_register sclp_conf_register =
  65{
  66        .receive_mask = EVTYP_CONFMGMDATA_MASK,
  67        .receiver_fn  = sclp_conf_receiver_fn,
  68};
  69
  70static int __init sclp_conf_init(void)
  71{
  72        INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
  73        INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
  74        return sclp_register(&sclp_conf_register);
  75}
  76
  77__initcall(sclp_conf_init);
  78