Pull bsp-removal into release branch
authorTony Luck <tony.luck@intel.com>
Tue, 21 Mar 2006 16:16:21 +0000 (08:16 -0800)
committerTony Luck <tony.luck@intel.com>
Tue, 21 Mar 2006 16:16:21 +0000 (08:16 -0800)
1  2 
arch/ia64/Kconfig
arch/ia64/configs/tiger_defconfig
arch/ia64/kernel/acpi.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/time.c
arch/ia64/kernel/topology.c

diff --combined arch/ia64/Kconfig
index a85ea9d37f056de90e4eaecf5124404ef51ce767,5e0f58e37c5969275f33a86c6bfbb177093f0d71..ff7ae6b664e8af12509a0f5d19f0231ce34dd14d
@@@ -194,6 -194,7 +194,6 @@@ config IA64_L1_CACHE_SHIF
        default "7" if MCKINLEY
        default "6" if ITANIUM
  
 -# align cache-sensitive data to 64 bytes
  config IA64_CYCLONE
        bool "Cyclone (EXA) Time Source support"
        help
@@@ -271,6 -272,25 +271,25 @@@ config SCHED_SM
          Intel IA64 chips with MultiThreading at a cost of slightly increased
          overhead in some places. If unsure say N here.
  
+ config PERMIT_BSP_REMOVE
+       bool "Support removal of Bootstrap Processor"
+       depends on HOTPLUG_CPU
+       default n
+       ---help---
+       Say Y here if your platform SAL will support removal of BSP with HOTPLUG_CPU
+       support. 
+ config FORCE_CPEI_RETARGET
+       bool "Force assumption that CPEI can be re-targetted"
+       depends on PERMIT_BSP_REMOVE
+       default n
+       ---help---
+       Say Y if you need to force the assumption that CPEI can be re-targetted to
+       any cpu in the system. This hint is available via ACPI 3.0 specifications.
+       Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP.
+       This option it useful to enable this feature on older BIOS's as well.
+       You can also enable this by using boot command line option force_cpei=1.
  config PREEMPT
        bool "Preemptible Kernel"
          help
@@@ -373,9 -393,6 +392,9 @@@ config IA64_PALINF
          To use this option, you have to ensure that the "/proc file system
          support" (CONFIG_PROC_FS) is enabled, too.
  
 +config SGI_SN
 +      def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
 +
  source "drivers/firmware/Kconfig"
  
  source "fs/Kconfig.binfmt"
@@@ -453,7 -470,6 +472,7 @@@ source "arch/ia64/oprofile/Kconfig
  
  config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
 +      depends on EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index 125568118b847b97dbe217c5367d1a1871444699,aed034d339763bc0182ec073c5c5258a41ce1673..766bf495543249e44bfd69d92a31ebd3a69b47cc
@@@ -1,13 -1,14 +1,13 @@@
  #
  # Automatically generated make config: don't edit
 -# Linux kernel version: 2.6.15-rc4
 -# Fri Dec  2 16:06:32 2005
 +# Linux kernel version: 2.6.16-rc5
 +# Mon Feb 27 15:49:18 2006
  #
  
  #
  # Code maturity level options
  #
  CONFIG_EXPERIMENTAL=y
 -CONFIG_CLEAN_COMPILE=y
  CONFIG_LOCK_KERNEL=y
  CONFIG_INIT_ENV_ARG_LIMIT=32
  
@@@ -22,19 -23,18 +22,19 @@@ CONFIG_POSIX_MQUEUE=
  # CONFIG_BSD_PROCESS_ACCT is not set
  CONFIG_SYSCTL=y
  # CONFIG_AUDIT is not set
 -CONFIG_HOTPLUG=y
 -CONFIG_KOBJECT_UEVENT=y
  CONFIG_IKCONFIG=y
  CONFIG_IKCONFIG_PROC=y
  # CONFIG_CPUSETS is not set
  CONFIG_INITRAMFS_SOURCE=""
 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  # CONFIG_EMBEDDED is not set
  CONFIG_KALLSYMS=y
  CONFIG_KALLSYMS_ALL=y
  # CONFIG_KALLSYMS_EXTRA_PASS is not set
 +CONFIG_HOTPLUG=y
  CONFIG_PRINTK=y
  CONFIG_BUG=y
 +CONFIG_ELF_CORE=y
  CONFIG_BASE_FULL=y
  CONFIG_FUTEX=y
  CONFIG_EPOLL=y
@@@ -43,10 -43,8 +43,10 @@@ CONFIG_CC_ALIGN_FUNCTIONS=
  CONFIG_CC_ALIGN_LABELS=0
  CONFIG_CC_ALIGN_LOOPS=0
  CONFIG_CC_ALIGN_JUMPS=0
 +CONFIG_SLAB=y
  # CONFIG_TINY_SHMEM is not set
  CONFIG_BASE_SMALL=0
 +# CONFIG_SLOB is not set
  
  #
  # Loadable module support
@@@ -90,7 -88,7 +90,7 @@@ CONFIG_TIME_INTERPOLATION=
  CONFIG_EFI=y
  CONFIG_GENERIC_IOMAP=y
  CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 -CONFIG_ZONE_DMA_IS_DMA32=y
 +CONFIG_DMA_IS_DMA32=y
  # CONFIG_IA64_GENERIC is not set
  CONFIG_IA64_DIG=y
  # CONFIG_IA64_HP_ZX1 is not set
@@@ -116,6 -114,8 +116,8 @@@ CONFIG_FORCE_MAX_ZONEORDER=1
  CONFIG_SMP=y
  CONFIG_NR_CPUS=4
  CONFIG_HOTPLUG_CPU=y
+ CONFIG_PERMIT_BSP_REMOVE=y
+ CONFIG_FORCE_CPEI_RETARGET=y
  # CONFIG_SCHED_SMT is not set
  # CONFIG_PREEMPT is not set
  CONFIG_SELECT_MEMORY_MODEL=y
@@@ -164,7 -164,6 +166,7 @@@ CONFIG_ACPI_HOTPLUG_CPU=
  CONFIG_ACPI_THERMAL=m
  CONFIG_ACPI_BLACKLIST_YEAR=0
  # CONFIG_ACPI_DEBUG is not set
 +CONFIG_ACPI_EC=y
  CONFIG_ACPI_POWER=y
  CONFIG_ACPI_SYSTEM=y
  CONFIG_ACPI_CONTAINER=m
@@@ -206,7 -205,6 +208,7 @@@ CONFIG_NET=
  #
  # Networking options
  #
 +# CONFIG_NETDEBUG is not set
  CONFIG_PACKET=y
  # CONFIG_PACKET_MMAP is not set
  CONFIG_UNIX=y
@@@ -241,11 -239,6 +243,11 @@@ CONFIG_TCP_CONG_BIC=
  # SCTP Configuration (EXPERIMENTAL)
  #
  # CONFIG_IP_SCTP is not set
 +
 +#
 +# TIPC Configuration (EXPERIMENTAL)
 +#
 +# CONFIG_TIPC is not set
  # CONFIG_ATM is not set
  # CONFIG_BRIDGE is not set
  # CONFIG_VLAN_8021Q is not set
@@@ -335,7 -328,6 +337,7 @@@ CONFIG_BLK_DEV_INITRD=
  # ATA/ATAPI/MFM/RLL support
  #
  CONFIG_IDE=y
 +CONFIG_IDE_MAX_HWIFS=4
  CONFIG_BLK_DEV_IDE=y
  
  #
@@@ -453,7 -445,13 +455,7 @@@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=6
  CONFIG_SCSI_QLOGIC_FC=y
  # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
  CONFIG_SCSI_QLOGIC_1280=y
 -CONFIG_SCSI_QLA2XXX=y
 -CONFIG_SCSI_QLA21XX=m
 -CONFIG_SCSI_QLA22XX=m
 -CONFIG_SCSI_QLA2300=m
 -CONFIG_SCSI_QLA2322=m
 -# CONFIG_SCSI_QLA6312 is not set
 -# CONFIG_SCSI_QLA24XX is not set
 +# CONFIG_SCSI_QLA_FC is not set
  # CONFIG_SCSI_LPFC is not set
  # CONFIG_SCSI_DC395x is not set
  # CONFIG_SCSI_DC390T is not set
@@@ -569,14 -567,12 +571,14 @@@ CONFIG_E100=
  # CONFIG_DL2K is not set
  CONFIG_E1000=y
  # CONFIG_E1000_NAPI is not set
 +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
  # CONFIG_NS83820 is not set
  # CONFIG_HAMACHI is not set
  # CONFIG_YELLOWFIN is not set
  # CONFIG_R8169 is not set
  # CONFIG_SIS190 is not set
  # CONFIG_SKGE is not set
 +# CONFIG_SKY2 is not set
  # CONFIG_SK98LIN is not set
  # CONFIG_VIA_VELOCITY is not set
  CONFIG_TIGON3=y
@@@ -681,15 -677,12 +683,15 @@@ CONFIG_VT=
  CONFIG_VT_CONSOLE=y
  CONFIG_HW_CONSOLE=y
  CONFIG_SERIAL_NONSTANDARD=y
 +# CONFIG_COMPUTONE is not set
  # CONFIG_ROCKETPORT is not set
  # CONFIG_CYCLADES is not set
  # CONFIG_DIGIEPCA is not set
 +# CONFIG_MOXA_INTELLIO is not set
  # CONFIG_MOXA_SMARTIO is not set
  # CONFIG_ISI is not set
  # CONFIG_SYNCLINKMP is not set
 +# CONFIG_SYNCLINK_GT is not set
  # CONFIG_N_HDLC is not set
  # CONFIG_SPECIALIX is not set
  # CONFIG_SX is not set
@@@ -702,7 -695,6 +704,7 @@@ CONFIG_SERIAL_8250=
  CONFIG_SERIAL_8250_CONSOLE=y
  CONFIG_SERIAL_8250_ACPI=y
  CONFIG_SERIAL_8250_NR_UARTS=6
 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  CONFIG_SERIAL_8250_EXTENDED=y
  CONFIG_SERIAL_8250_SHARE_IRQ=y
  # CONFIG_SERIAL_8250_DETECT_IRQ is not set
@@@ -747,10 -739,10 +749,10 @@@ CONFIG_DRM_SIS=
  # CONFIG_DRM_VIA is not set
  # CONFIG_DRM_SAVAGE is not set
  CONFIG_RAW_DRIVER=m
 +CONFIG_MAX_RAW_DEVS=256
  CONFIG_HPET=y
  # CONFIG_HPET_RTC_IRQ is not set
  CONFIG_HPET_MMAP=y
 -CONFIG_MAX_RAW_DEVS=256
  # CONFIG_HANGCHECK_TIMER is not set
  
  #
  #
  # CONFIG_I2C is not set
  
 +#
 +# SPI support
 +#
 +# CONFIG_SPI is not set
 +# CONFIG_SPI_MASTER is not set
 +
  #
  # Dallas's 1-wire bus
  #
  #
  CONFIG_HWMON=y
  # CONFIG_HWMON_VID is not set
 +# CONFIG_SENSORS_F71805F is not set
  # CONFIG_HWMON_DEBUG_CHIP is not set
  
  #
@@@ -870,15 -855,12 +872,15 @@@ CONFIG_USB_STORAGE=
  # CONFIG_USB_STORAGE_SDDR09 is not set
  # CONFIG_USB_STORAGE_SDDR55 is not set
  # CONFIG_USB_STORAGE_JUMPSHOT is not set
 +# CONFIG_USB_STORAGE_ALAUDA is not set
 +# CONFIG_USB_LIBUSUAL is not set
  
  #
  # USB Input Devices
  #
  CONFIG_USB_HID=y
  CONFIG_USB_HIDINPUT=y
 +# CONFIG_USB_HIDINPUT_POWERBOOK is not set
  # CONFIG_HID_FF is not set
  # CONFIG_USB_HIDDEV is not set
  # CONFIG_USB_AIPTEK is not set
  # CONFIG_USB_YEALINK is not set
  # CONFIG_USB_XPAD is not set
  # CONFIG_USB_ATI_REMOTE is not set
 +# CONFIG_USB_ATI_REMOTE2 is not set
  # CONFIG_USB_KEYSPAN_REMOTE is not set
  # CONFIG_USB_APPLETOUCH is not set
  
  # CONFIG_INFINIBAND is not set
  
  #
 -# SN Devices
 +# EDAC - error detection and reporting (RAS)
  #
  
  #
@@@ -1000,7 -981,6 +1002,7 @@@ CONFIG_XFS_EXPORT=
  # CONFIG_XFS_SECURITY is not set
  # CONFIG_XFS_POSIX_ACL is not set
  # CONFIG_XFS_RT is not set
 +# CONFIG_OCFS2_FS is not set
  # CONFIG_MINIX_FS is not set
  # CONFIG_ROMFS_FS is not set
  CONFIG_INOTIFY=y
@@@ -1042,7 -1022,6 +1044,7 @@@ CONFIG_HUGETLBFS=
  CONFIG_HUGETLB_PAGE=y
  CONFIG_RAMFS=y
  # CONFIG_RELAYFS_FS is not set
 +# CONFIG_CONFIGFS_FS is not set
  
  #
  # Miscellaneous filesystems
@@@ -1112,7 -1091,6 +1114,7 @@@ CONFIG_MSDOS_PARTITION=
  CONFIG_SGI_PARTITION=y
  # CONFIG_ULTRIX_PARTITION is not set
  # CONFIG_SUN_PARTITION is not set
 +# CONFIG_KARMA_PARTITION is not set
  CONFIG_EFI_PARTITION=y
  
  #
@@@ -1180,20 -1158,18 +1182,20 @@@ CONFIG_GENERIC_PENDING_IRQ=
  # Kernel hacking
  #
  # CONFIG_PRINTK_TIME is not set
 -CONFIG_DEBUG_KERNEL=y
  CONFIG_MAGIC_SYSRQ=y
 +CONFIG_DEBUG_KERNEL=y
  CONFIG_LOG_BUF_SHIFT=20
  CONFIG_DETECT_SOFTLOCKUP=y
  # CONFIG_SCHEDSTATS is not set
  # CONFIG_DEBUG_SLAB is not set
 +CONFIG_DEBUG_MUTEXES=y
  # CONFIG_DEBUG_SPINLOCK is not set
  # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
  # CONFIG_DEBUG_KOBJECT is not set
  # CONFIG_DEBUG_INFO is not set
  # CONFIG_DEBUG_FS is not set
  # CONFIG_DEBUG_VM is not set
 +CONFIG_FORCED_INLINING=y
  # CONFIG_RCU_TORTURE_TEST is not set
  CONFIG_IA64_GRANULE_16MB=y
  # CONFIG_IA64_GRANULE_64MB is not set
diff --combined arch/ia64/kernel/acpi.c
index ecd44bdc8394fee371fc944af433163d0adb3952,8d350b33a20fbc96e7881736517c2fa4d23ffefc..4722ec51c70c6583ca38729f181d3779ad2e5146
@@@ -284,19 -284,24 +284,24 @@@ acpi_parse_plat_int_src(acpi_table_entr
        return 0;
  }
  
+ #ifdef CONFIG_HOTPLUG_CPU
  unsigned int can_cpei_retarget(void)
  {
        extern int cpe_vector;
+       extern unsigned int force_cpei_retarget;
  
        /*
         * Only if CPEI is supported and the override flag
         * is present, otherwise return that its re-targettable
         * if we are in polling mode.
         */
-       if (cpe_vector > 0 && !acpi_cpei_override)
-               return 0;
-       else
-               return 1;
+       if (cpe_vector > 0) {
+               if (acpi_cpei_override || force_cpei_retarget)
+                       return 1;
+               else
+                       return 0;
+       }
+       return 1;
  }
  
  unsigned int is_cpu_cpei_target(unsigned int cpu)
@@@ -315,6 -320,7 +320,7 @@@ void set_cpei_target_cpu(unsigned int c
  {
        acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
  }
+ #endif
  
  unsigned int get_cpei_target_cpu(void)
  {
@@@ -567,16 -573,16 +573,16 @@@ void __init acpi_numa_arch_fixup(void
   * success: return IRQ number (>=0)
   * failure: return < 0
   */
 -int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
 +int acpi_register_gsi(u32 gsi, int triggering, int polarity)
  {
        if (has_8259 && gsi < 16)
                return isa_irq_to_vector(gsi);
  
        return iosapic_register_intr(gsi,
 -                                   (active_high_low ==
 +                                   (polarity ==
                                      ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH :
                                     IOSAPIC_POL_LOW,
 -                                   (edge_level ==
 +                                   (triggering ==
                                      ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
                                     IOSAPIC_LEVEL);
  }
@@@ -761,59 -767,6 +767,59 @@@ int acpi_map_cpu2node(acpi_handle handl
        return (0);
  }
  
 +int additional_cpus __initdata = -1;
 +
 +static __init int setup_additional_cpus(char *s)
 +{
 +      if (s)
 +              additional_cpus = simple_strtol(s, NULL, 0);
 +
 +      return 0;
 +}
 +
 +early_param("additional_cpus", setup_additional_cpus);
 +
 +/*
 + * cpu_possible_map should be static, it cannot change as cpu's
 + * are onlined, or offlined. The reason is per-cpu data-structures
 + * are allocated by some modules at init time, and dont expect to
 + * do this dynamically on cpu arrival/departure.
 + * cpu_present_map on the other hand can change dynamically.
 + * In case when cpu_hotplug is not compiled, then we resort to current
 + * behaviour, which is cpu_possible == cpu_present.
 + * - Ashok Raj
 + *
 + * Three ways to find out the number of additional hotplug CPUs:
 + * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
 + * - The user can overwrite it with additional_cpus=NUM
 + * - Otherwise don't reserve additional CPUs.
 + */
 +__init void prefill_possible_map(void)
 +{
 +      int i;
 +      int possible, disabled_cpus;
 +
 +      disabled_cpus = total_cpus - available_cpus;
 +
 +      if (additional_cpus == -1) {
 +              if (disabled_cpus > 0)
 +                      additional_cpus = disabled_cpus;
 +              else
 +                      additional_cpus = 0;
 +      }
 +
 +      possible = available_cpus + additional_cpus;
 +
 +      if (possible > NR_CPUS)
 +              possible = NR_CPUS;
 +
 +      printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
 +              possible, max((possible - available_cpus), 0));
 +
 +      for (i = 0; i < possible; i++)
 +              cpu_set(i, cpu_possible_map);
 +}
 +
  int acpi_map_lsapic(acpi_handle handle, int *pcpu)
  {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
diff --combined arch/ia64/kernel/mca.c
index ee7eec9ee57648cee03a84aeacea97651577131d,967571b466a2c92f94abe9e8dc8a68f25d390cc7..87fb7cecead00422e2aaf19671b4dfbaf99bf2a4
@@@ -289,6 -289,7 +289,7 @@@ ia64_mca_log_sal_error_record(int sal_i
  #ifdef CONFIG_ACPI
  
  int cpe_vector = -1;
+ int ia64_cpe_irq = -1;
  
  static irqreturn_t
  ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
@@@ -766,7 -767,7 +767,7 @@@ ia64_mca_modify_original_stack(struct p
                        l = strlen(previous_current->comm);
                snprintf(comm, sizeof(comm), "%s %*s %d",
                        current->comm, l, previous_current->comm,
 -                      previous_current->thread_info->cpu);
 +                      task_thread_info(previous_current)->cpu);
        }
        memcpy(current->comm, comm, sizeof(current->comm));
  
@@@ -1423,7 -1424,7 +1424,7 @@@ format_mca_init_stack(void *mca_data, u
        struct task_struct *p = (struct task_struct *)((char *)mca_data + offset);
        struct thread_info *ti;
        memset(p, 0, KERNEL_STACK_SIZE);
 -      ti = (struct thread_info *)((char *)p + IA64_TASK_SIZE);
 +      ti = task_thread_info(p);
        ti->flags = _TIF_MCA_INIT;
        ti->preempt_count = 1;
        ti->task = p;
@@@ -1444,11 -1445,13 +1445,13 @@@ void __devini
  ia64_mca_cpu_init(void *cpu_data)
  {
        void *pal_vaddr;
+       static int first_time = 1;
  
-       if (smp_processor_id() == 0) {
+       if (first_time) {
                void *mca_data;
                int cpu;
  
+               first_time = 0;
                mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
                                         * NR_CPUS + KERNEL_STACK_SIZE);
                mca_data = (void *)(((unsigned long)mca_data +
@@@ -1704,6 -1707,7 +1707,7 @@@ ia64_mca_late_init(void
                                        desc = irq_descp(irq);
                                        desc->status |= IRQ_PER_CPU;
                                        setup_irq(irq, &mca_cpe_irqaction);
+                                       ia64_cpe_irq = irq;
                                }
                        ia64_mca_register_cpev(cpe_vector);
                        IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
index 9c5194b385dab33ce122152ee665306fe2cbf761,18c51c37a9a35e825427519ebd90e51dd25c308c..077f21216b654cc433cb58c2104b11c7954b8b19
@@@ -38,9 -38,7 +38,9 @@@
  #include <linux/pagemap.h>
  #include <linux/mount.h>
  #include <linux/bitops.h>
 +#include <linux/capability.h>
  #include <linux/rcupdate.h>
 +#include <linux/completion.h>
  
  #include <asm/errno.h>
  #include <asm/intrinsics.h>
@@@ -287,7 -285,7 +287,7 @@@ typedef struct pfm_context 
  
        unsigned long           ctx_ovfl_regs[4];       /* which registers overflowed (notification) */
  
 -      struct semaphore        ctx_restart_sem;        /* use for blocking notification mode */
 +      struct completion       ctx_restart_done;       /* use for blocking notification mode */
  
        unsigned long           ctx_used_pmds[4];       /* bitmask of PMD used            */
        unsigned long           ctx_all_pmds[4];        /* bitmask of all accessible PMDs */
@@@ -629,11 -627,9 +629,11 @@@ static int pfm_write_ibr_dbr(int mode, 
  
  #include "perfmon_itanium.h"
  #include "perfmon_mckinley.h"
 +#include "perfmon_montecito.h"
  #include "perfmon_generic.h"
  
  static pmu_config_t *pmu_confs[]={
 +      &pmu_conf_mont,
        &pmu_conf_mck,
        &pmu_conf_ita,
        &pmu_conf_gen, /* must be last */
@@@ -1713,7 -1709,7 +1713,7 @@@ static voi
  pfm_syswide_force_stop(void *info)
  {
        pfm_context_t   *ctx = (pfm_context_t *)info;
 -      struct pt_regs *regs = ia64_task_regs(current);
 +      struct pt_regs *regs = task_pt_regs(current);
        struct task_struct *owner;
        unsigned long flags;
        int ret;
@@@ -1818,7 -1814,7 +1818,7 @@@ pfm_flush(struct file *filp
        is_system = ctx->ctx_fl_system;
  
        task = PFM_CTX_TASK(ctx);
 -      regs = ia64_task_regs(task);
 +      regs = task_pt_regs(task);
  
        DPRINT(("ctx_state=%d is_current=%d\n",
                state,
@@@ -1948,7 -1944,7 +1948,7 @@@ pfm_close(struct inode *inode, struct f
        is_system = ctx->ctx_fl_system;
  
        task = PFM_CTX_TASK(ctx);
 -      regs = ia64_task_regs(task);
 +      regs = task_pt_regs(task);
  
        DPRINT(("ctx_state=%d is_current=%d\n", 
                state,
                /*
                 * force task to wake up from MASKED state
                 */
 -              up(&ctx->ctx_restart_sem);
 +              complete(&ctx->ctx_restart_done);
  
                DPRINT(("waking up ctx_state=%d\n", state));
  
@@@ -2707,7 -2703,7 +2707,7 @@@ pfm_context_create(pfm_context_t *ctx, 
        /*
         * init restart semaphore to locked
         */
 -      sema_init(&ctx->ctx_restart_sem, 0);
 +      init_completion(&ctx->ctx_restart_done);
  
        /*
         * activation is used in SMP only
@@@ -3688,7 -3684,7 +3688,7 @@@ pfm_restart(pfm_context_t *ctx, void *a
         */
        if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
                DPRINT(("unblocking [%d] \n", task->pid));
 -              up(&ctx->ctx_restart_sem);
 +              complete(&ctx->ctx_restart_done);
        } else {
                DPRINT(("[%d] armed exit trap\n", task->pid));
  
@@@ -4055,7 -4051,7 +4055,7 @@@ pfm_stop(pfm_context_t *ctx, void *arg
                 */
                ia64_psr(regs)->up = 0;
        } else {
 -              tregs = ia64_task_regs(task);
 +              tregs = task_pt_regs(task);
  
                /*
                 * stop monitoring at the user level
@@@ -4137,7 -4133,7 +4137,7 @@@ pfm_start(pfm_context_t *ctx, void *arg
                ia64_psr(regs)->up = 1;
  
        } else {
 -              tregs = ia64_task_regs(ctx->ctx_task);
 +              tregs = task_pt_regs(ctx->ctx_task);
  
                /*
                 * start monitoring at the kernel level the next
@@@ -4407,7 -4403,7 +4407,7 @@@ pfm_context_load(pfm_context_t *ctx, vo
                /*
                 * when not current, task MUST be stopped, so this is safe
                 */
 -              regs = ia64_task_regs(task);
 +              regs = task_pt_regs(task);
  
                /* force a full reload */
                ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
@@@ -4533,7 -4529,7 +4533,7 @@@ pfm_context_unload(pfm_context_t *ctx, 
        /*
         * per-task mode
         */
 -      tregs = task == current ? regs : ia64_task_regs(task);
 +      tregs = task == current ? regs : task_pt_regs(task);
  
        if (task == current) {
                /*
@@@ -4596,7 -4592,7 +4596,7 @@@ pfm_exit_thread(struct task_struct *tas
  {
        pfm_context_t *ctx;
        unsigned long flags;
 -      struct pt_regs *regs = ia64_task_regs(task);
 +      struct pt_regs *regs = task_pt_regs(task);
        int ret, state;
        int free_ok = 0;
  
@@@ -4929,7 -4925,7 +4929,7 @@@ restart_args
        if (unlikely(ret)) goto abort_locked;
  
  skip_fd:
 -      ret = (*func)(ctx, args_k, count, ia64_task_regs(current));
 +      ret = (*func)(ctx, args_k, count, task_pt_regs(current));
  
        call_made = 1;
  
@@@ -5053,7 -5049,7 +5053,7 @@@ pfm_handle_work(void
  
        pfm_clear_task_notify();
  
 -      regs = ia64_task_regs(current);
 +      regs = task_pt_regs(current);
  
        /*
         * extract reason for being here and clear
         * may go through without blocking on SMP systems
         * if restart has been received already by the time we call down()
         */
 -      ret = down_interruptible(&ctx->ctx_restart_sem);
 +      ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
  
        DPRINT(("after block sleeping ret=%d\n", ret));
  
@@@ -5797,7 -5793,7 +5797,7 @@@ pfm_syst_wide_update_task(struct task_s
         * on every CPU, so we can rely on the pid to identify the idle task.
         */
        if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) {
 -              regs = ia64_task_regs(task);
 +              regs = task_pt_regs(task);
                ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0;
                return;
        }
@@@ -5880,7 -5876,7 +5880,7 @@@ pfm_save_regs(struct task_struct *task
        flags = pfm_protect_ctx_ctxsw(ctx);
  
        if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
 -              struct pt_regs *regs = ia64_task_regs(task);
 +              struct pt_regs *regs = task_pt_regs(task);
  
                pfm_clear_psr_up();
  
@@@ -6080,7 -6076,7 +6080,7 @@@ pfm_load_regs (struct task_struct *task
        BUG_ON(psr & IA64_PSR_I);
  
        if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) {
 -              struct pt_regs *regs = ia64_task_regs(task);
 +              struct pt_regs *regs = task_pt_regs(task);
  
                BUG_ON(ctx->ctx_smpl_hdr);
  
@@@ -6449,7 -6445,7 +6449,7 @@@ pfm_alt_save_pmu_state(void *data
  {
        struct pt_regs *regs;
  
 -      regs = ia64_task_regs(current);
 +      regs = task_pt_regs(current);
  
        DPRINT(("called\n"));
  
@@@ -6475,7 -6471,7 +6475,7 @@@ pfm_alt_restore_pmu_state(void *data
  {
        struct pt_regs *regs;
  
 -      regs = ia64_task_regs(current);
 +      regs = task_pt_regs(current);
  
        DPRINT(("called\n"));
  
@@@ -6722,6 -6718,7 +6722,7 @@@ __initcall(pfm_init)
  void
  pfm_init_percpu (void)
  {
+       static int first_time=1;
        /*
         * make sure no measurement is active
         * (may inherit programmed PMCs from EFI).
         */
        pfm_unfreeze_pmu();
  
-       if (smp_processor_id() == 0)
+       if (first_time) {
                register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+               first_time=0;
+       }
  
        ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR);
        ia64_srlz_d();
@@@ -6757,7 -6756,7 +6760,7 @@@ dump_pmu_state(const char *from
        local_irq_save(flags);
  
        this_cpu = smp_processor_id();
 -      regs     = ia64_task_regs(current);
 +      regs     = task_pt_regs(current);
        info     = PFM_CPUINFO_GET();
        dcr      = ia64_getreg(_IA64_REG_CR_DCR);
  
index b681ef34a86e13a5ecab3a7e1ec2eb6b7378e847,e9d37bf67d691189d221d693ad05015ec1498e01..c4b633b36daba12b16b9ebe650b54f009c349fd9
  #endif
  
  #ifdef CONFIG_HOTPLUG_CPU
+ #ifdef CONFIG_PERMIT_BSP_REMOVE
+ #define bsp_remove_ok 1
+ #else
+ #define bsp_remove_ok 0
+ #endif
  /*
   * Store all idle threads, this can be reused instead of creating
   * a new thread. Also avoids complicated thread destroy functionality
@@@ -104,7 -110,7 +110,7 @@@ struct sal_to_os_boot *sal_state_for_bo
  /*
   * ITC synchronization related stuff:
   */
- #define MASTER        0
+ #define MASTER        (0)
  #define SLAVE (SMP_CACHE_BYTES/8)
  
  #define NUM_ROUNDS    64      /* magic value */
@@@ -129,7 -135,7 +135,7 @@@ DEFINE_PER_CPU(int, cpu_state)
  /* Bitmasks of currently online, and possible CPUs */
  cpumask_t cpu_online_map;
  EXPORT_SYMBOL(cpu_online_map);
 -cpumask_t cpu_possible_map;
 +cpumask_t cpu_possible_map = CPU_MASK_NONE;
  EXPORT_SYMBOL(cpu_possible_map);
  
  cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
@@@ -151,6 -157,27 +157,27 @@@ char __initdata no_int_routing
  
  unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
  
+ #ifdef CONFIG_FORCE_CPEI_RETARGET
+ #define CPEI_OVERRIDE_DEFAULT (1)
+ #else
+ #define CPEI_OVERRIDE_DEFAULT (0)
+ #endif
+ unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
+ static int __init
+ cmdl_force_cpei(char *str)
+ {
+       int value=0;
+       get_option (&str, &value);
+       force_cpei_retarget = value;
+       return 1;
+ }
+ __setup("force_cpei=", cmdl_force_cpei);
  static int __init
  nointroute (char *str)
  {
  
  __setup("nointroute", nointroute);
  
+ static void fix_b0_for_bsp(void)
+ {
+ #ifdef CONFIG_HOTPLUG_CPU
+       int cpuid;
+       static int fix_bsp_b0 = 1;
+       cpuid = smp_processor_id();
+       /*
+        * Cache the b0 value on the first AP that comes up
+        */
+       if (!(fix_bsp_b0 && cpuid))
+               return;
+       sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
+       printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
+       fix_bsp_b0 = 0;
+ #endif
+ }
  void
  sync_master (void *arg)
  {
@@@ -327,8 -375,9 +375,9 @@@ smp_setup_percpu_timer (void
  static void __devinit
  smp_callin (void)
  {
-       int cpuid, phys_id;
+       int cpuid, phys_id, itc_master;
        extern void ia64_init_itm(void);
+       extern volatile int time_keeper_id;
  
  #ifdef CONFIG_PERFMON
        extern void pfm_init_percpu(void);
  
        cpuid = smp_processor_id();
        phys_id = hard_smp_processor_id();
+       itc_master = time_keeper_id;
  
        if (cpu_online(cpuid)) {
                printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
                BUG();
        }
  
+       fix_b0_for_bsp();
        lock_ipi_calllock();
        cpu_set(cpuid, cpu_online_map);
        unlock_ipi_calllock();
                 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
                 * local_bh_enable(), which bugs out if irqs are not enabled...
                 */
-               Dprintk("Going to syncup ITC with BP.\n");
-               ia64_sync_itc(0);
+               Dprintk("Going to syncup ITC with ITC Master.\n");
+               ia64_sync_itc(itc_master);
        }
  
        /*
@@@ -506,6 -558,9 +558,6 @@@ smp_build_cpu_map (void
  
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
                ia64_cpu_to_sapicid[cpu] = -1;
 -#ifdef CONFIG_HOTPLUG_CPU
 -              cpu_set(cpu, cpu_possible_map);
 -#endif
        }
  
        ia64_cpu_to_sapicid[0] = boot_cpu_id;
@@@ -635,6 -690,47 +687,47 @@@ remove_siblinginfo(int cpu
  }
  
  extern void fixup_irqs(void);
+ int migrate_platform_irqs(unsigned int cpu)
+ {
+       int new_cpei_cpu;
+       irq_desc_t *desc = NULL;
+       cpumask_t       mask;
+       int             retval = 0;
+       /*
+        * dont permit CPEI target to removed.
+        */
+       if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
+               printk ("CPU (%d) is CPEI Target\n", cpu);
+               if (can_cpei_retarget()) {
+                       /*
+                        * Now re-target the CPEI to a different processor
+                        */
+                       new_cpei_cpu = any_online_cpu(cpu_online_map);
+                       mask = cpumask_of_cpu(new_cpei_cpu);
+                       set_cpei_target_cpu(new_cpei_cpu);
+                       desc = irq_descp(ia64_cpe_irq);
+                       /*
+                        * Switch for now, immediatly, we need to do fake intr
+                        * as other interrupts, but need to study CPEI behaviour with
+                        * polling before making changes.
+                        */
+                       if (desc) {
+                               desc->handler->disable(ia64_cpe_irq);
+                               desc->handler->set_affinity(ia64_cpe_irq, mask);
+                               desc->handler->enable(ia64_cpe_irq);
+                               printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
+                       }
+               }
+               if (!desc) {
+                       printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
+                       retval = -EBUSY;
+               }
+       }
+       return retval;
+ }
  /* must be called with cpucontrol mutex held */
  int __cpu_disable(void)
  {
        /*
         * dont permit boot processor for now
         */
-       if (cpu == 0)
-               return -EBUSY;
+       if (cpu == 0 && !bsp_remove_ok) {
+               printk ("Your platform does not support removal of BSP\n");
+               return (-EBUSY);
+       }
+       cpu_clear(cpu, cpu_online_map);
+       if (migrate_platform_irqs(cpu)) {
+               cpu_set(cpu, cpu_online_map);
+               return (-EBUSY);
+       }
  
        remove_siblinginfo(cpu);
        cpu_clear(cpu, cpu_online_map);
diff --combined arch/ia64/kernel/time.c
index 307d01e15b2ea359c043d11c5e19a0bc57bd1002,1ca130a83856ede14be2b4e8d932ffdb29647b97..ac167436e9364ffc23fe3bde276019e5fae93d7e
@@@ -32,7 -32,7 +32,7 @@@
  
  extern unsigned long wall_jiffies;
  
#define TIME_KEEPER_ID        0       /* smp_processor_id() of time-keeper */
volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
  
  #ifdef CONFIG_IA64_DEBUG_IRQ
  
@@@ -71,7 -71,7 +71,7 @@@ timer_interrupt (int irq, void *dev_id
  
                new_itm += local_cpu_data->itm_delta;
  
-               if (smp_processor_id() == TIME_KEEPER_ID) {
+               if (smp_processor_id() == time_keeper_id) {
                        /*
                         * Here we are in the timer irq handler. We have irqs locally
                         * disabled, but we don't know if the timer_bh is running on
@@@ -236,6 -236,11 +236,11 @@@ static struct irqaction timer_irqactio
        .name =         "timer"
  };
  
+ void __devinit ia64_disable_timer(void)
+ {
+       ia64_set_itv(1 << 16);
+ }
  void __init
  time_init (void)
  {
        set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
  }
  
 -#define SMALLUSECS 100
 +/*
 + * Generic udelay assumes that if preemption is allowed and the thread
 + * migrates to another CPU, that the ITC values are synchronized across
 + * all CPUs.
 + */
 +static void
 +ia64_itc_udelay (unsigned long usecs)
 +{
 +      unsigned long start = ia64_get_itc();
 +      unsigned long end = start + usecs*local_cpu_data->cyc_per_usec;
 +
 +      while (time_before(ia64_get_itc(), end))
 +              cpu_relax();
 +}
 +
 +void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay;
  
  void
  udelay (unsigned long usecs)
  {
 -      unsigned long start;
 -      unsigned long cycles;
 -      unsigned long smallusecs;
 +      (*ia64_udelay)(usecs);
 +}
 +EXPORT_SYMBOL(udelay);
  
 -      /*
 -       * Execute the non-preemptible delay loop (because the ITC might
 -       * not be synchronized between CPUS) in relatively short time
 -       * chunks, allowing preemption between the chunks.
 -       */
 -      while (usecs > 0) {
 -              smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs;
 -              preempt_disable();
 -              cycles = smallusecs*local_cpu_data->cyc_per_usec;
 -              start = ia64_get_itc();
 +static unsigned long long ia64_itc_printk_clock(void)
 +{
 +      if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
 +              return sched_clock();
 +      return 0;
 +}
 +
 +static unsigned long long ia64_default_printk_clock(void)
 +{
 +      return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
 +              (1000000000/HZ);
 +}
  
 -              while (ia64_get_itc() - start < cycles)
 -                      cpu_relax();
 +unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
  
 -              preempt_enable();
 -              usecs -= smallusecs;
 -      }
 +unsigned long long printk_clock(void)
 +{
 +      return ia64_printk_clock();
 +}
 +
 +void __init
 +ia64_setup_printk_clock(void)
 +{
 +      if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
 +              ia64_printk_clock = ia64_itc_printk_clock;
  }
 -EXPORT_SYMBOL(udelay);
index 6e5eea19fa672bb0199f997e0888fc91d98ad77c,c9562d94b9c3a6e9b4bc9bc88ed49a82b980d128..3b6fd798c4d68c2a1cbbed752e875286b1d3ff85
@@@ -36,7 -36,7 +36,7 @@@ int arch_register_cpu(int num
        parent = &sysfs_nodes[cpu_to_node(num)];
  #endif /* CONFIG_NUMA */
  
- #ifdef CONFIG_ACPI
+ #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
        /*
         * If CPEI cannot be re-targetted, and this is
         * CPEI target, then dont create the control file
@@@ -71,33 -71,31 +71,33 @@@ static int __init topology_init(void
        int i, err = 0;
  
  #ifdef CONFIG_NUMA
 -      sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
 +      sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
        if (!sysfs_nodes) {
                err = -ENOMEM;
                goto out;
        }
 -      memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES);
  
 -      /* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */
 -      for_each_online_node(i)
 +      /*
 +       * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
 +       */
 +      for_each_online_node(i) {
                if ((err = register_node(&sysfs_nodes[i], i, 0)))
                        goto out;
 +      }
  #endif
  
 -      sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
 +      sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
        if (!sysfs_cpus) {
                err = -ENOMEM;
                goto out;
        }
 -      memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS);
  
 -      for_each_present_cpu(i)
 +      for_each_present_cpu(i) {
                if((err = arch_register_cpu(i)))
                        goto out;
 +      }
  out:
        return err;
  }
  
 -__initcall(topology_init);
 +subsys_initcall(topology_init);