void register_pcibr_intr(int irq, pcibr_intr_t intr) { struct pcibr_intr_list_t *p = kmalloc(sizeof(struct pcibr_intr_list_t), GFP_KERNEL); struct pcibr_intr_list_t *list; int cpu = intr->bi_cpu; if (pcibr_intr_list == NULL) { pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL); if (pcibr_intr_list == NULL) pcibr_intr_list = vmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS); if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n"); memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS); } if (pdacpu(cpu).sn_last_irq < irq) { pdacpu(cpu).sn_last_irq = irq; } if (pdacpu(cpu).sn_first_irq == 0 || pdacpu(cpu).sn_first_irq > irq) pdacpu(cpu).sn_first_irq = irq; if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n"); if ((list = pcibr_intr_list[irq])) { while (list->next) list = list->next; list->next = p; p->next = NULL; p->intr = intr; } else { pcibr_intr_list[irq] = p; p->next = NULL; p->intr = intr; } }
static void register_intr_pda(struct sn_irq_info *sn_irq_info) { int irq = sn_irq_info->irq_irq; int cpu = sn_irq_info->irq_cpuid; if (pdacpu(cpu)->sn_last_irq < irq) { pdacpu(cpu)->sn_last_irq = irq; } if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq; }
void sn_migrate(struct task_struct *task) { pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu); volatile unsigned long *adr = last_pda->pio_write_status_addr; unsigned long val = last_pda->pio_write_status_val; /* */ while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != val)) cpu_relax(); }
static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) { int irq = sn_irq_info->irq_irq; int cpu = sn_irq_info->irq_cpuid; struct sn_irq_info *tmp_irq_info; int i, foundmatch; rcu_read_lock(); if (pdacpu(cpu)->sn_last_irq == irq) { foundmatch = 0; for (i = pdacpu(cpu)->sn_last_irq - 1; i && !foundmatch; i--) { list_for_each_entry_rcu(tmp_irq_info, sn_irq_lh[i], list) { if (tmp_irq_info->irq_cpuid == cpu) { foundmatch = 1; break; } } } pdacpu(cpu)->sn_last_irq = i; }
/** * sn_cpu_init - initialize per-cpu data areas * @cpuid: cpuid of the caller * * Called during cpu initialization on each cpu as it starts. * Currently, initializes the per-cpu data area for SNIA. * Also sets up a few fields in the nodepda. Also known as * platform_cpu_init() by the ia64 machvec code. */ void __init sn_cpu_init(void) { int cpuid; int cpuphyid; int nasid; int subnode; int slice; int cnode; int i; static int wars_have_been_checked; memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, &sn_coherency_id, &sn_region_size)) BUG(); sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; /* * The boot cpu makes this call again after platform initialization is * complete. */ if (nodepdaindr[0] == NULL) return; cpuid = smp_processor_id(); cpuphyid = get_sapicid(); if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) BUG(); for (i=0; i < MAX_NUMNODES; i++) { if (nodepdaindr[i]) { nodepdaindr[i]->phys_cpuid[cpuid].nasid = nasid; nodepdaindr[i]->phys_cpuid[cpuid].slice = slice; nodepdaindr[i]->phys_cpuid[cpuid].subnode = subnode; } } cnode = nasid_to_cnodeid(nasid); pda->p_nodepda = nodepdaindr[cnode]; pda->led_address = (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); pda->led_state = LED_ALWAYS_SET; pda->hb_count = HZ / 2; pda->hb_state = 0; pda->idle_flag = 0; if (cpuid != 0) { memcpy(pda->cnodeid_to_nasid_table, pdacpu(0)->cnodeid_to_nasid_table, sizeof(pda->cnodeid_to_nasid_table)); } /* * Check for WARs. * Only needs to be done once, on BSP. * Has to be done after loop above, because it uses pda.cnodeid_to_nasid_table[i]. * Has to be done before assignment below. */ if (!wars_have_been_checked) { sn_check_for_wars(); wars_have_been_checked = 1; } sn_hub_info->shub_1_1_found = shub_1_1_found; /* * Set up addresses of PIO/MEM write status registers. */ { u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3}; u64 *pio; pio = is_shub1() ? pio1 : pio2; pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]); pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; } /* * WAR addresses for SHUB 1.x. */ if (local_node_data->active_cpu_count++ == 0 && is_shub1()) { int buddy_nasid; buddy_nasid = cnodeid_to_nasid(numa_node_id() == num_online_nodes() - 1 ? 0 : numa_node_id() + 1); pda->pio_shub_war_cam_addr = (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, SH1_PI_CAM_CONTROL); } }