2007-04-27 18:01:56 +04:00
/*
* drivers / s390 / char / sclp_config . c
*
* Copyright IBM Corp . 2007
* Author ( s ) : Heiko Carstens < heiko . carstens @ de . ibm . com >
*/
2008-12-25 15:39:48 +03:00
# define KMSG_COMPONENT "sclp_config"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
2007-04-27 18:01:56 +04:00
# include <linux/init.h>
# include <linux/errno.h>
# include <linux/cpu.h>
2011-12-22 02:29:42 +04:00
# include <linux/device.h>
2007-04-27 18:01:56 +04:00
# include <linux/workqueue.h>
2008-04-30 15:38:37 +04:00
# include <asm/smp.h>
2007-04-27 18:01:56 +04:00
2008-12-25 15:39:48 +03:00
# include "sclp.h"
2007-04-27 18:01:56 +04:00
struct conf_mgm_data {
u8 reserved ;
u8 ev_qualifier ;
} __attribute__ ( ( packed ) ) ;
2008-04-30 15:38:37 +04:00
# define EV_QUAL_CPU_CHANGE 1
2007-04-27 18:01:56 +04:00
# define EV_QUAL_CAP_CHANGE 3
static struct work_struct sclp_cpu_capability_work ;
2008-04-30 15:38:37 +04:00
static struct work_struct sclp_cpu_change_work ;
2007-04-27 18:01:56 +04:00
static void sclp_cpu_capability_notify ( struct work_struct * work )
{
int cpu ;
2011-12-22 02:29:42 +04:00
struct device * dev ;
2007-04-27 18:01:56 +04:00
2011-01-05 14:48:18 +03:00
s390_adjust_jiffies ( ) ;
2008-12-25 15:39:48 +03:00
pr_warning ( " cpu capability changed. \n " ) ;
2008-01-25 23:08:02 +03:00
get_online_cpus ( ) ;
2007-04-27 18:01:56 +04:00
for_each_online_cpu ( cpu ) {
2011-12-22 02:29:42 +04:00
dev = get_cpu_device ( cpu ) ;
kobject_uevent ( & dev - > kobj , KOBJ_CHANGE ) ;
2007-04-27 18:01:56 +04:00
}
2008-01-25 23:08:02 +03:00
put_online_cpus ( ) ;
2007-04-27 18:01:56 +04:00
}
2008-07-14 11:57:28 +04:00
static void __ref sclp_cpu_change_notify ( struct work_struct * work )
{
2008-08-01 18:39:23 +04:00
smp_rescan_cpus ( ) ;
2008-04-30 15:38:37 +04:00
}
2007-04-27 18:01:56 +04:00
static void sclp_conf_receiver_fn ( struct evbuf_header * evbuf )
{
struct conf_mgm_data * cdata ;
cdata = ( struct conf_mgm_data * ) ( evbuf + 1 ) ;
2008-04-30 15:38:37 +04:00
switch ( cdata - > ev_qualifier ) {
case EV_QUAL_CPU_CHANGE :
schedule_work ( & sclp_cpu_change_work ) ;
break ;
case EV_QUAL_CAP_CHANGE :
2007-04-27 18:01:56 +04:00
schedule_work ( & sclp_cpu_capability_work ) ;
2008-04-30 15:38:37 +04:00
break ;
}
2007-04-27 18:01:56 +04:00
}
static struct sclp_register sclp_conf_register =
{
. receive_mask = EVTYP_CONFMGMDATA_MASK ,
. receiver_fn = sclp_conf_receiver_fn ,
} ;
static int __init sclp_conf_init ( void )
{
INIT_WORK ( & sclp_cpu_capability_work , sclp_cpu_capability_notify ) ;
2008-04-30 15:38:37 +04:00
INIT_WORK ( & sclp_cpu_change_work , sclp_cpu_change_notify ) ;
2011-05-23 12:24:37 +04:00
return sclp_register ( & sclp_conf_register ) ;
2007-04-27 18:01:56 +04:00
}
__initcall ( sclp_conf_init ) ;