+ struct sn_irq_info *sn_irq_info = sn_irq[irq];
+ struct sn_irq_info *tmp_sn_irq_info;
+ int cpuid, cpuphys;
+ nasid_t t_nasid; /* nasid to target */
+ int t_slice; /* slice to target */
+
+ /* allocate a temp sn_irq_info struct to get new target info */
+ tmp_sn_irq_info = kmalloc(sizeof(*tmp_sn_irq_info), GFP_KERNEL);
+ if (!tmp_sn_irq_info)
+ return;
+
+ cpuid = first_cpu(mask);
+ cpuphys = cpu_physical_id(cpuid);
+ t_nasid = cpuid_to_nasid(cpuid);
+ t_slice = cpuid_to_slice(cpuid);
+
+ while (sn_irq_info) {
+ int status;
+ int local_widget;
+ uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge;
+ nasid_t local_nasid = NASID_GET(bridge);
+
+ if (!bridge)
+ break; /* irq is not a device interrupt */
+
+ if (local_nasid & 1)
+ local_widget = TIO_SWIN_WIDGETNUM(bridge);
+ else
+ local_widget = SWIN_WIDGETNUM(bridge);
+
+ /* Free the old PROM sn_irq_info structure */
+ sn_intr_free(local_nasid, local_widget, sn_irq_info);
+
+ /* allocate a new PROM sn_irq_info struct */
+ status = sn_intr_alloc(local_nasid, local_widget,
+ __pa(tmp_sn_irq_info), irq, t_nasid,
+ t_slice);
+
+ if (status == 0) {
+ /* Update kernels sn_irq_info with new target info */
+ unregister_intr_pda(sn_irq_info);
+ sn_irq_info->irq_cpuid = cpuid;
+ sn_irq_info->irq_nasid = t_nasid;
+ sn_irq_info->irq_slice = t_slice;
+ sn_irq_info->irq_xtalkaddr =
+ tmp_sn_irq_info->irq_xtalkaddr;
+ sn_irq_info->irq_cookie = tmp_sn_irq_info->irq_cookie;
+ register_intr_pda(sn_irq_info);
+
+ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type)) {
+ pcibr_change_devices_irq(sn_irq_info);
+ }
+
+ sn_irq_info = sn_irq_info->irq_next;
+