void __init ps3_mm_vas_create(unsigned long* htab_size) { int result; u64 start_address; u64 size; u64 access_right; u64 max_page_size; u64 flags; result = lv1_query_logical_partition_address_region_info(0, &start_address, &size, &access_right, &max_page_size, &flags); if (result) { DBG("%s:%d: lv1_query_logical_partition_address_region_info " "failed: %s\n", __func__, __LINE__, ps3_result(result)); goto fail; } if (max_page_size < PAGE_SHIFT_16M) { DBG("%s:%d: bad max_page_size %llxh\n", __func__, __LINE__, max_page_size); goto fail; } BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE > HTAB_SIZE_MAX); BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE < HTAB_SIZE_MIN); result = lv1_construct_virtual_address_space(CONFIG_PS3_HTAB_SIZE, 2, make_page_sizes(PAGE_SHIFT_16M, PAGE_SHIFT_64K), &map.vas_id, &map.htab_size); if (result) { DBG("%s:%d: lv1_construct_virtual_address_space failed: %s\n", __func__, __LINE__, ps3_result(result)); goto fail; } result = lv1_select_virtual_address_space(map.vas_id); if (result) { DBG("%s:%d: lv1_select_virtual_address_space failed: %s\n", __func__, __LINE__, ps3_result(result)); goto fail; } *htab_size = map.htab_size; debug_dump_map(&map); return; fail: panic("ps3_mm_vas_create failed"); }
u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr) { int result; u64 counter0415; u64 counter2637; if (phys_ctr >= NR_PHYS_CTRS) { dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, __LINE__, phys_ctr); return 0; } result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415, &counter2637); if (result) { dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " "phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr, ps3_result(result)); return 0; } switch (phys_ctr) { case 0: return counter0415 >> 32; case 1: return counter0415 & PS3_PM_COUNTER_MASK_LO; case 2: return counter2637 >> 32; case 3: return counter2637 & PS3_PM_COUNTER_MASK_LO; default: BUG(); } return 0; }
static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev) { int result; BUG_ON(!dev->bus_id); mutex_lock(&usage_hack.mutex); if (ps3_is_device(dev, 1, 1)) { usage_hack.sb_11++; if (usage_hack.sb_11 > 1) { result = 0; goto done; } } if (ps3_is_device(dev, 1, 2)) { usage_hack.sb_12++; if (usage_hack.sb_12 > 1) { result = 0; goto done; } } result = lv1_open_device(dev->bus_id, dev->dev_id, 0); if (result) { pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__, __LINE__, ps3_result(result)); result = -EPERM; } done: mutex_unlock(&usage_hack.mutex); return result; }
static int ps3_mm_region_create(struct mem_region *r, unsigned long size) { int result; u64 muid; r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M); DBG("%s:%d requested %lxh\n", __func__, __LINE__, size); DBG("%s:%d actual %llxh\n", __func__, __LINE__, r->size); DBG("%s:%d difference %llxh (%lluMB)\n", __func__, __LINE__, size - r->size, (size - r->size) / 1024 / 1024); if (r->size == 0) { DBG("%s:%d: size == 0\n", __func__, __LINE__); result = -1; goto zero_region; } result = lv1_allocate_memory(r->size, PAGE_SHIFT_16M, 0, ALLOCATE_MEMORY_TRY_ALT_UNIT, &r->base, &muid); if (result || r->base < map.rm.size) { DBG("%s:%d: lv1_allocate_memory failed: %s\n", __func__, __LINE__, ps3_result(result)); goto zero_region; } r->destroy = 1; r->offset = r->base - map.rm.size; return result; zero_region: r->size = r->base = r->offset = 0; return result; }
int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, unsigned int *virq) { int result; struct ps3_private *pd; result = ps3_virq_setup(cpu, outlet, virq); if (result) { pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); goto fail_setup; } pd = irq_get_chip_data(*virq); /* Binds outlet to cpu + virq. */ result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq, outlet, 0); if (result) { pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); result = -EPERM; goto fail_connect; } return result; fail_connect: ps3_virq_destroy(*virq); fail_setup: return result; }
static int __init enable_spu(struct spu *spu) { int result; result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id, spu_pdata(spu)->resource_id); if (result) { pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n", __func__, __LINE__, ps3_result(result)); goto fail_enable; } result = setup_areas(spu); if (result) goto fail_areas; result = setup_interrupts(spu); if (result) goto fail_interrupts; return 0; fail_interrupts: spu_unmap(spu); fail_areas: lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); fail_enable: return result; }
int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq) { int result; unsigned long outlet; unsigned long lpar_addr; BUG_ON(!is_kernel_addr((unsigned long)virt_addr_bmp)); lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp)); result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); if (result) { pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } *virq = irq_create_mapping(NULL, outlet); pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, outlet, *virq); return 0; }
int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, enum ps3_cpu_binding cpu, unsigned int *virq) { /* this should go in system-bus.c */ int result; result = ps3_event_receive_port_setup(cpu, virq); if (result) return result; result = lv1_connect_interrupt_event_receive_port(dev->bus_id, dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); if (result) { pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); ps3_event_receive_port_destroy(*virq); *virq = NO_IRQ; return result; } pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, dev->interrupt_id, *virq); return 0; }
int ps3_connect_event_irq(const struct ps3_device_id *did, unsigned int interrupt_id, unsigned int *virq) { int result; result = ps3_alloc_event_irq(virq); if (result) return result; result = lv1_connect_interrupt_event_receive_port(did->bus_id, did->dev_id, virq_to_hw(*virq), interrupt_id); if (result) { pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); ps3_free_event_irq(*virq); *virq = NO_IRQ; return result; } pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, interrupt_id, *virq); return 0; }
int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, unsigned int virq) { /* this should go in system-bus.c */ int result; pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, dev->interrupt_id, virq); result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, dev->dev_id, virq_to_hw(virq), dev->interrupt_id); if (result) pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); result = ps3_event_receive_port_destroy(virq); BUG_ON(result); /* * ps3_event_receive_port_destroy() destroys the IRQ plug, * so don't call ps3_irq_plug_destroy() here. */ result = ps3_virq_destroy(virq); BUG_ON(result); pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; }
int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, unsigned int virq) { /* */ int result; DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, dev->interrupt_id, virq); result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, dev->dev_id, virq_to_hw(virq), dev->interrupt_id); if (result) FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); result = ps3_event_receive_port_destroy(virq); BUG_ON(result); /* */ result = ps3_virq_destroy(virq); BUG_ON(result); DBG(" <- %s:%d\n", __func__, __LINE__); return result; }
u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg) { int result = 0; u64 val = 0; switch (reg) { case pm_control: return lpm_priv->shadow.pm_control; case trace_address: return CBE_PM_TRACE_BUF_EMPTY; case pm_start_stop: return lpm_priv->shadow.pm_start_stop; case pm_interval: result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val); if (result) { val = 0; dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: " "reg %u, %s\n", __func__, __LINE__, reg, ps3_result(result)); } return (u32)val; case group_control: return lpm_priv->shadow.group_control; case debug_bus_control: return lpm_priv->shadow.debug_bus_control; case pm_status: result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id, &val); if (result) { val = 0; dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: " "reg %u, %s\n", __func__, __LINE__, reg, ps3_result(result)); } return (u32)val; case ext_tr_timer: return 0; default: dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, __LINE__, reg); BUG(); break; } return 0; }
static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int apsize, int ssize) { int result; u64 hpte_v, hpte_r; u64 inserted_index; u64 evicted_v, evicted_r; u64 hpte_v_array[4], hpte_rs; unsigned long flags; long ret = -1; /* * lv1_insert_htab_entry() will search for victim * entry in both primary and secondary pte group */ vflags &= ~HPTE_V_SECONDARY; hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize) | rflags; spin_lock_irqsave(&ps3_htab_lock, flags); /* talk hvc to replace entries BOLTED == 0 */ result = lv1_insert_htab_entry(PS3_LPAR_VAS_ID_CURRENT, hpte_group, hpte_v, hpte_r, HPTE_V_BOLTED, 0, &inserted_index, &evicted_v, &evicted_r); if (result) { /* all entries bolted !*/ pr_info("%s:result=%s vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n", __func__, ps3_result(result), vpn, pa, hpte_group, hpte_v, hpte_r); BUG(); } /* * see if the entry is inserted into secondary pteg */ result = lv1_read_htab_entries(PS3_LPAR_VAS_ID_CURRENT, inserted_index & ~0x3UL, &hpte_v_array[0], &hpte_v_array[1], &hpte_v_array[2], &hpte_v_array[3], &hpte_rs); BUG_ON(result); if (hpte_v_array[inserted_index % 4] & HPTE_V_SECONDARY) ret = (inserted_index & 7) | (1 << 3); else ret = inserted_index & 7; spin_unlock_irqrestore(&ps3_htab_lock, flags); return ret; }
int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, unsigned int *virq) { int result; struct ps3_private *pd; /* This defines the default interrupt distribution policy. */ if (cpu == PS3_BINDING_CPU_ANY) cpu = 0; pd = &per_cpu(ps3_private, cpu); *virq = irq_create_mapping(NULL, outlet); if (*virq == NO_IRQ) { pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", __func__, __LINE__, outlet); result = -ENOMEM; goto fail_create; } /* Binds outlet to cpu + virq. */ result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); if (result) { pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); result = -EPERM; goto fail_connect; } pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, outlet, cpu, *virq); result = set_irq_chip_data(*virq, pd); if (result) { pr_debug("%s:%d: set_irq_chip_data failed\n", __func__, __LINE__); goto fail_set; } return result; fail_set: lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq); fail_connect: irq_dispose_mapping(*virq); fail_create: return result; }
void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) { u64 counter0415; u64 counter0415_mask; u64 counter2637; u64 counter2637_mask; int result; if (phys_ctr >= NR_PHYS_CTRS) { dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, __LINE__, phys_ctr); return; } switch (phys_ctr) { case 0: counter0415 = (u64)val << 32; counter0415_mask = PS3_PM_COUNTER_MASK_HI; counter2637 = 0x0; counter2637_mask = 0x0; break; case 1: counter0415 = (u64)val; counter0415_mask = PS3_PM_COUNTER_MASK_LO; counter2637 = 0x0; counter2637_mask = 0x0; break; case 2: counter0415 = 0x0; counter0415_mask = 0x0; counter2637 = (u64)val << 32; counter2637_mask = PS3_PM_COUNTER_MASK_HI; break; case 3: counter0415 = 0x0; counter0415_mask = 0x0; counter2637 = (u64)val; counter2637_mask = PS3_PM_COUNTER_MASK_LO; break; default: BUG(); } result = lv1_set_lpm_counter(lpm_priv->lpm_id, counter0415, counter0415_mask, counter2637, counter2637_mask, &counter0415, &counter2637); if (result) dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " "phys_ctr %u, val %u, %s\n", __func__, __LINE__, phys_ctr, val, ps3_result(result)); }
void ps3_enable_pm(u32 cpu) { int result; u64 tmp; int insert_bookmark = 0; lpm_priv->tb_count = 0; if (use_start_stop_bookmark) { if (!(lpm_priv->shadow.pm_start_stop & (PS3_PM_START_STOP_START_MASK | PS3_PM_START_STOP_STOP_MASK))) { result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, (PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START | PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START | PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP | PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP), 0xFFFFFFFFFFFFFFFFULL, &tmp); if (result) dev_err(sbd_core(), "%s:%u: " "lv1_set_lpm_trigger_control failed: " "%s\n", __func__, __LINE__, ps3_result(result)); insert_bookmark = !result; } } result = lv1_start_lpm(lpm_priv->lpm_id); if (result) dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n", __func__, __LINE__, ps3_result(result)); if (use_start_stop_bookmark && !result && insert_bookmark) ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START); }
int ps3_free_io_irq(unsigned int virq) { int result; result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); if (result) pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); irq_dispose_mapping(virq); return result; }
int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, unsigned long count, unsigned long *bytes_copied) { int result; *bytes_copied = 0; if (!lpm_priv->tb_cache) return -EPERM; if (offset >= lpm_priv->tb_count) return 0; count = min_t(u64, count, lpm_priv->tb_count - offset); while (*bytes_copied < count) { const unsigned long request = count - *bytes_copied; u64 tmp; result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, request, &tmp); if (result) { dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", __func__, __LINE__, request, offset); dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " "failed: %s\n", __func__, __LINE__, ps3_result(result)); return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; } result = copy_to_user(buf, lpm_priv->tb_cache, tmp); if (result) { dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n", __func__, __LINE__, tmp, buf); dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n", __func__, __LINE__, result); return -EFAULT; } buf += tmp; *bytes_copied += tmp; offset += tmp; } dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, *bytes_copied); return 0; }
static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r) { int result; dump_mmio_region(r); result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id, r->lpar_addr); if (result) pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n", __func__, __LINE__, ps3_result(result)); r->lpar_addr = 0; return result; }
int ps3_io_irq_destroy(unsigned int virq) { int result; result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); if (result) pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); result = ps3_irq_plug_destroy(virq); BUG_ON(result); return result; }
int ps3_free_vuart_irq(unsigned int virq) { int result; result = lv1_deconfigure_virtual_uart_irq(); if (result) { pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } irq_dispose_mapping(virq); return result; }
static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r) { int result; result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id, r->bus_addr, r->len, r->page_size, &r->lpar_addr); if (result) { pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n", __func__, __LINE__, ps3_result(result)); r->lpar_addr = 0; } dump_mmio_region(r); return result; }
static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4) { int result; dump_node(0, n1, n2, n3, n4, 0, 0); result = lv1_delete_repository_node(n1, n2, n3, n4); if (result) { pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n", __func__, __LINE__, ps3_result(result)); return -ENOENT; } return 0; }
static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long vpn, int psize, int apsize, int ssize, int local) { int result; u64 hpte_v, want_v, hpte_rs; u64 hpte_v_array[4]; unsigned long flags; long ret; want_v = hpte_encode_avpn(vpn, psize, ssize); spin_lock_irqsave(&ps3_htab_lock, flags); result = lv1_read_htab_entries(PS3_LPAR_VAS_ID_CURRENT, slot & ~0x3UL, &hpte_v_array[0], &hpte_v_array[1], &hpte_v_array[2], &hpte_v_array[3], &hpte_rs); if (result) { pr_info("%s: result=%s read vpn=%lx slot=%lx psize=%d\n", __func__, ps3_result(result), vpn, slot, psize); BUG(); } hpte_v = hpte_v_array[slot % 4]; /* * As lv1_read_htab_entries() does not give us the RPN, we can * not synthesize the new hpte_r value here, and therefore can * not update the hpte with lv1_insert_htab_entry(), so we * instead invalidate it and ask the caller to update it via * ps3_hpte_insert() by returning a -1 value. */ if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { /* not found */ ret = -1; } else { /* entry found, just invalidate it */ result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0); ret = -1; } spin_unlock_irqrestore(&ps3_htab_lock, flags); return ret; }
int ps3_free_event_irq(unsigned int virq) { int result; pr_debug(" -> %s:%d\n", __func__, __LINE__); result = lv1_destruct_event_receive_port(virq_to_hw(virq)); if (result) pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); irq_dispose_mapping(virq); pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; }
int ps3_vuart_irq_destroy(unsigned int virq) { int result; result = lv1_deconfigure_virtual_uart_irq(); if (result) { pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } result = ps3_irq_plug_destroy(virq); BUG_ON(result); return result; }
static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn, int psize, int apsize, int ssize, int local) { unsigned long flags; int result; spin_lock_irqsave(&ps3_htab_lock, flags); result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0); if (result) { pr_info("%s: result=%s vpn=%lx slot=%lx psize=%d\n", __func__, ps3_result(result), vpn, slot, psize); BUG(); } spin_unlock_irqrestore(&ps3_htab_lock, flags); }
int ps3_irq_plug_destroy(unsigned int virq) { int result; const struct ps3_private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, pd->node, pd->cpu, virq); result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); if (result) pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); ps3_virq_destroy(virq); return result; }
int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, unsigned int *virq) { int result; u64 outlet; result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); if (result) { pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } result = ps3_irq_plug_setup(cpu, outlet, virq); BUG_ON(result); return result; }
int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) { int result; u64 outlet; result = lv1_construct_event_receive_port(&outlet); if (result) { pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); *virq = NO_IRQ; return result; } result = ps3_irq_plug_setup(cpu, outlet, virq); BUG_ON(result); return result; }