/** * get_tlabel - allocate a transaction label * @host: host to be used for transmission * @nodeid: the node ID of the transmission target * @wait: whether to sleep if no tlabel is available * * Every asynchronous transaction on the 1394 bus needs a transaction label to * match the response to the request. This label has to be different from any * other transaction label in an outstanding request to the same node to make * matching possible without ambiguity. * * There are 64 different tlabels, so an allocated tlabel has to be freed with * free_tlabel() after the transaction is complete (unless it's reused again for * the same target node). * * @wait must not be set to true if you are calling from interrupt context. * * Return value: The allocated transaction label or -1 if there was no free * tlabel and @wait is false. */ int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait) { int tlabel; unsigned long flags; if (wait) { down(&host->tlabel_count); } else { if (down_trylock(&host->tlabel_count)) return -1; } spin_lock_irqsave(&host->tlabel_lock, flags); if (host->tlabel_pool[0] != ~0) { tlabel = ffz(host->tlabel_pool[0]); host->tlabel_pool[0] |= 1 << tlabel; } else { tlabel = ffz(host->tlabel_pool[1]); host->tlabel_pool[1] |= 1 << tlabel; tlabel += 32; } spin_unlock_irqrestore(&host->tlabel_lock, flags); return tlabel; }
unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset) { unsigned long *word, *last; unsigned long first_bit, bit, base; word = addr + OFF_BY_START(offset); last = addr + OFF_BY_START(size-1); first_bit = offset % BITS_PER_LONG; base = offset - first_bit; if (offset >= size) return size; if (first_bit != 0) { int tmp = (*word++) & (~0UL << first_bit); bit = ffz(tmp); if (bit < BITS_PER_LONG) goto found; word++; base += BITS_PER_LONG; } while (word <= last) { if (*word != ~0UL) { bit = ffz(*word); goto found; } word++; base += BITS_PER_LONG; } return size; found: return base + bit; }
int bigsur_irq_demux(int irq) { int dmux_irq = irq; u8 mask, actv_irqs; u32 reg_num; DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq); /* decode the 1st level IRQ */ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* Get corresponding L2 ISR bitmask and ISR number */ mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]; reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW]; /* find the active IRQ's (XOR with inactive level)*/ actv_irqs = inb(isr_base-reg_num*isr_offset) ^ bigsur_l2_inactv_state[reg_num]; /* decode active IRQ's */ actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset)); /* if NEZ then we have an active L2 IRQ */ if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW; /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */ if(!irq_desc[dmux_irq].action && irq_desc[irq].action) dmux_irq = irq; DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n", irq, dmux_irq, mask, reg_num); } #ifdef CONFIG_HD64465 dmux_irq = hd64465_irq_demux(dmux_irq); #endif /* CONFIG_HD64465 */ DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq); return dmux_irq; }
/* * Free all allocated IRQs. * If only one of the IRQs grabbed was received, return it. * Otherwise, autoprobe failed. */ int probe_irq_off (unsigned long irqs) { unsigned int i, irqmask; irqmask = probe_mask; /* IRQs received */ /* free all allocated IRQs */ for (i = (NHWI - 1); i > 0; i--) { if (irqs & (1 << i)) { free_irq(i, NULL); } } #ifdef IRQ_DEBUG printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", (unsigned)irqs, irqmask); #endif /* what allocated IRQs did I receive? */ irqs &= irqmask; if (!irqs) /* none found... */ return 0; i = ffz(~irqs); if (irqs != (irqs & (1 << i))) /* multiple IRQs found? */ i = -i; return i; }
static inline int find_next_one_bit(void *addr, int size, int offset) { uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); int result = offset & ~(BITS_PER_LONG - 1); unsigned long tmp; if (offset >= size) return size; size -= result; offset &= (BITS_PER_LONG - 1); if (offset) { tmp = leBPL_to_cpup(p++); tmp &= ~0UL << offset; if (size < BITS_PER_LONG) goto found_first; if (tmp) goto found_middle; size -= BITS_PER_LONG; result += BITS_PER_LONG; } while (size & ~(BITS_PER_LONG - 1)) { tmp = leBPL_to_cpup(p++); if (tmp) goto found_middle; result += BITS_PER_LONG; size -= BITS_PER_LONG; } if (!size) return result; tmp = leBPL_to_cpup(p); found_first: tmp &= ~0UL >> (BITS_PER_LONG - size); found_middle: return result + ffz(~tmp); }
/* * Scan the free space map, for this zone, calculating the total * number of map bits in each free space fragment. * * Note: idmask is limited to 15 bits [3.2] */ static unsigned int scan_free_map(struct adfs_sb_info *asb, struct adfs_discmap *dm) { const unsigned int mapsize = dm->dm_endbit + 32; const unsigned int idlen = asb->s_idlen; const unsigned int frag_idlen = idlen <= 15 ? idlen : 15; const u32 idmask = (1 << frag_idlen) - 1; unsigned char *map = dm->dm_bh->b_data; unsigned int start = 8, mapptr; u32 frag; unsigned long total = 0; /* * get fragment id */ frag = GET_FRAG_ID(map, start, idmask); /* * If the freelink is null, then no free fragments * exist in this zone. */ if (frag == 0) return 0; do { start += frag; /* * get fragment id */ frag = GET_FRAG_ID(map, start, idmask); mapptr = start + idlen; /* * find end of fragment */ { __le32 *_map = (__le32 *)map; u32 v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31); while (v == 0) { mapptr = (mapptr & ~31) + 32; if (mapptr >= mapsize) goto error; v = le32_to_cpu(_map[mapptr >> 5]); } mapptr += 1 + ffz(~v); } total += mapptr - start; } while (frag >= idlen + 1); if (frag != 0) printk(KERN_ERR "adfs: undersized free fragment\n"); return total; error: printk(KERN_ERR "adfs: oversized free fragment\n"); return 0; }
static void dp264_device_interrupt(unsigned long vector, struct pt_regs * regs) { #if 1 printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n"); #else unsigned long pld; unsigned int i; /* Read the interrupt summary register of TSUNAMI */ pld = TSUNAMI_cchip->dir0.csr; /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 55) isa_device_interrupt(vector, regs); else handle_irq(16 + i, 16 + i, regs); #if 0 TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); tmp = TSUNAMI_cchip->dir0.csr; #endif } #endif }
/* * Return the next free block in the map. */ static int get_next_free_block(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { unsigned long long block, min_bs = td->o.rw_min_bs, lastb; int i; lastb = last_block(td, f, ddir); if (!lastb) return 1; i = f->last_free_lookup; block = i * BLOCKS_PER_MAP; while (block * min_bs < f->real_file_size && block * min_bs < f->io_size) { if (f->file_map[i] != -1UL) { block += ffz(f->file_map[i]); if (block > lastb) break; f->last_free_lookup = i; *b = block; return 0; } block += BLOCKS_PER_MAP; i++; } dprint(FD_IO, "failed finding a free block\n"); return 1; }
static void mikasa_device_interrupt(unsigned long vector) { unsigned long pld; unsigned int i; /* Read the interrupt summary registers */ pld = (((~inw(0x534) & 0x0000ffffUL) << 16) | (((unsigned long) inb(0xa0)) << 8) | inb(0x20)); /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i < 16) { isa_device_interrupt(vector); } else { handle_irq(i); } } }
static void rx164_device_interrupt(unsigned long vector) { unsigned long pld; volatile unsigned int *dirr; long i; /* Read the interrupt summary register. On Polaris, this is the DIRR register in PCI config space (offset 0x84). */ dirr = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x84); pld = *dirr; /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 20) { isa_no_iack_sc_device_interrupt(vector); } else { handle_irq(16+i); } } }
static inline void eb66_and_eb64p_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned long pld; unsigned int i; unsigned long flags; save_flags(flags); cli(); /* read the interrupt summary registers */ pld = inb(0x26) | (inb(0x27) << 8); /* * Now, for every possible bit set, work through * them and call the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 5) { isa_device_interrupt(vector, regs); } else { device_interrupt(16 + i, 16 + i, regs); } } restore_flags(flags); }
static int i8259_get_irq_number(int irq) { unsigned long isr; isr = inb(0x20); irq = ffz(~isr); if (irq == 2) { isr = inb(0xa0); irq = 8 + ffz(~isr); } if (irq < 0 || irq > 15) return -EINVAL; return I8259_IRQ_BASE + irq; }
static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned long pld; unsigned int i; unsigned long flags; save_flags(flags); cli(); /* read the interrupt summary registers */ pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16); #if 0 printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8)); #endif /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 4) { isa_device_interrupt(vector, regs); } else { device_interrupt(16 + i, 16 + i, regs); } } restore_flags(flags); }
static inline void mikasa_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned long pld; unsigned int i; unsigned long flags; save_flags(flags); cli(); /* read the interrupt summary registers */ pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) | (((unsigned long) inb(0xa0)) << 8) | ((unsigned long) inb(0x20)); #if 0 printk("[0x%08lx]", pld); #endif /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i < 16) { isa_device_interrupt(vector, regs); } else { device_interrupt(i, i, regs); } } restore_flags(flags); }
/* we have to conditionally compile this because of GRU_xxx symbols */ static inline void alcor_and_xlt_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned long pld; unsigned int i; unsigned long flags; save_flags(flags); cli(); /* read the interrupt summary register of the GRU */ pld = (*(unsigned int *)GRU_INT_REQ) & GRU_INT_REQ_BITS; #if 0 printk("[0x%08lx/0x%04x]", pld, inb(0x20) | (inb(0xA0) << 8)); #endif /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. */ while (pld) { i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 31) { isa_device_interrupt(vector, regs); } else { device_interrupt(16 + i, 16 + i, regs); } } restore_flags(flags); }
/* * Return the next free block in the map. */ static int get_next_free_block(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { unsigned long long min_bs = td->o.rw_min_bs, lastb; int i; lastb = last_block(td, f, ddir); if (!lastb) return 1; i = f->last_free_lookup; *b = (i * BLOCKS_PER_MAP); while ((*b) * min_bs < f->real_file_size && (*b) * min_bs < f->io_size) { if (f->file_map[i] != (unsigned int) -1) { *b += ffz(f->file_map[i]); if (*b > lastb) break; f->last_free_lookup = i; return 0; } *b += BLOCKS_PER_MAP; i++; } dprint(FD_IO, "failed finding a free block\n"); return 1; }
static GtkWidget *gopt_get_group_frame(struct gopt_job_view *gjv, GtkWidget *box, unsigned int groupmask) { unsigned int mask, group; struct opt_group *og; GtkWidget *frame, *hbox; struct gopt_frame_widget *gfw; if (!groupmask) return 0; mask = groupmask; og = opt_group_cat_from_mask(&mask); if (!og) return NULL; group = ffz(~groupmask); gfw = &gjv->g_widgets[group]; if (!gfw->vbox[0]) { frame = gtk_frame_new(og->name); gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 3); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame), hbox); gfw->vbox[0] = gtk_vbox_new(TRUE, 5); gfw->vbox[1] = gtk_vbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[0], TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[1], TRUE, TRUE, 5); } hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(gfw->vbox[gfw->nr++ & 1]), hbox, FALSE, FALSE, 5); return hbox; }
void handle_IPI (int irq, void *dev_id, struct pt_regs *regs) { int this_cpu = smp_processor_id(); unsigned long *pending_ipis = &local_cpu_data->ipi.operation; unsigned long ops; /* Count this now; we may make a call that never returns. */ local_cpu_data->ipi_count++; mb(); /* Order interrupt and bit testing. */ while ((ops = xchg(pending_ipis, 0)) != 0) { mb(); /* Order bit clearing and data access. */ do { unsigned long which; which = ffz(~ops); ops &= ~(1 << which); switch (which) { case IPI_CALL_FUNC: { struct call_data_struct *data; void (*func)(void *info); void *info; int wait; /* release the 'pointer lock' */ data = (struct call_data_struct *) call_data; func = data->func; info = data->info; wait = data->wait; mb(); atomic_inc(&data->started); /* At this point the structure may be gone unless wait is true. */ (*func)(info); /* Notify the sending CPU that the task is done. */ mb(); if (wait) atomic_inc(&data->finished); } break; case IPI_CPU_STOP: stop_this_cpu(); break; default: printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); break; } /* Switch */ } while (ops); mb(); /* Order data access and bit testing. */ } }
/* * return the map bit offset of the fragment frag_id in the zone dm. * Note that the loop is optimised for best asm code - look at the * output of: * gcc -D__KERNEL__ -O2 -I../../include -o - -S map.c */ static int lookup_zone(const struct adfs_discmap *dm, const unsigned int idlen, const unsigned int frag_id, unsigned int *offset) { const unsigned int mapsize = dm->dm_endbit; const u32 idmask = (1 << idlen) - 1; unsigned char *map = dm->dm_bh->b_data + 4; unsigned int start = dm->dm_startbit; unsigned int mapptr; u32 frag; do { frag = GET_FRAG_ID(map, start, idmask); mapptr = start + idlen; /* * find end of fragment */ { u32 v, *_map = (u32 *)map; v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31); while (v == 0) { mapptr = (mapptr & ~31) + 32; if (mapptr >= mapsize) goto error; v = le32_to_cpu(_map[mapptr >> 5]); } mapptr += 1 + ffz(~v); } if (frag == frag_id) goto found; again: start = mapptr; } while (mapptr < mapsize); return -1; error: printk(KERN_ERR "adfs: oversized fragment 0x%x at 0x%x-0x%x\n", frag, start, mapptr); return -1; found: { int length = mapptr - start; if (*offset >= length) { *offset -= length; goto again; } } return start + *offset; }
/* * Find the first cleared bit in a memory region. */ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) { unsigned long idx; for (idx = 0; idx * BITS_PER_LONG < size; idx++) { if (addr[idx] != ~0UL) return min(idx * BITS_PER_LONG + ffz(addr[idx]), size); } return size; }
int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { u32 idx = ffz(gd->used_laws); if (idx >= FSL_HW_NUM_LAWS) return -1; set_law(idx, addr, sz, id); return idx; }
// Reserves a free slot in ReserveBMap qitem* queue_get_item(queue *q) { int i; qitem *buf = (qitem*)(q->buf + q->mapbytes*2); atomic_llong *map = (atomic_llong*)q->buf; int zbit; qitem *r; while(1) { // Reserve space for (i = 0; i < q->map_elements; i++) { long long int mval = atomic_load(&map[i]); long long int nval; // if no zero bit go to next element if (!(zbit = ffz(mval))) { continue; } nval = mval | (((long long int)1) << (--zbit)); // update map val with bit set. // If successful we are done. if (atomic_compare_exchange_strong(&map[i], &mval, nval)) { // printf("ZBIT %d %lld %lld\n",zbit,mval, sizeof(mval)); atomic_fetch_add(&q->size, 1); break; } // Unable to exchange, go again for same index. else { atomic_fetch_add(&q->ct, 1); i--; } } if (i < q->map_elements) { r = &buf[i*64+zbit]; break; } else { usleep(100); } } return r; }
void LinuxMode::setCPU() { uval local; cpuControl->P(); do { local = availCPU; tassertMsg(local!=0, "All cpus used: %lx\n",local); cpu = ffz(~local); tassertMsg(cpu<NR_CPUS, "Bad cpu: %lx %ld\n",local,cpu); } while (!CompareAndStoreSynced(&availCPU, local, local & ~(1ULL<<cpu))); }
int wbuf_put(const int npages, char *buf1, char *data, int *tries) { int i,t = 0; char *buf = buf1+WBUF_MAPBYTES(npages); atomic_llong *map = (atomic_llong*)buf1; int zbit; while(1) { // Reserve space for (i = 0; i < WBUF_MAP_ELEMENTS(npages); i++) { long long int mval = atomic_load(&map[i]); long long int nval; // if no zero bit go to next element if (!(zbit = ffz(mval))) continue; nval = mval | (((long long int)1) << (--zbit)); // update map val with bit set. // If successful we are done. if (atomic_compare_exchange_strong(&map[i], &mval, nval)) break; // Unable to exchange, go again for same index. else { i--; t++; } } if (i < WBUF_MAP_ELEMENTS(npages)) { // Copy data memcpy(buf + i*64*PGSZ + zbit*PGSZ, data, PGSZ); break; } else { usleep(100); } } if (tries != NULL) *tries = t; return i*64 + zbit; }
/* * return the map bit offset of the fragment frag_id in * the zone dm. * Note that the loop is optimised for best asm code - * look at the output of: * gcc -D__KERNEL__ -O2 -I../../include -o - -S map.c */ static int lookup_zone(const struct adfs_discmap *dm, const unsigned int idlen, const unsigned int frag_id, unsigned int *offset) { const unsigned int mapsize = dm->dm_endbit; const unsigned int idmask = (1 << idlen) - 1; unsigned long *map = ((unsigned long *)dm->dm_bh->b_data) + 1; unsigned int start = dm->dm_startbit; unsigned int mapptr; do { unsigned long frag; frag = GET_FRAG_ID(map, start, idmask); mapptr = start + idlen; /* * find end of fragment */ { unsigned long v2; while ((v2 = map[mapptr >> 5] >> (mapptr & 31)) == 0) { mapptr = (mapptr & ~31) + 32; if (mapptr >= mapsize) goto error; } mapptr += 1 + ffz(~v2); } if (frag == frag_id) goto found; again: start = mapptr; } while (mapptr < mapsize); error: return -1; found: { int length = mapptr - start; if (*offset >= length) { *offset -= length; goto again; } } return start + *offset; }
int kgsl_g12_drawctxt_create(struct kgsl_device_private *dev_priv, uint32_t unused, unsigned int *drawctxt_id) { int cmd; int result; unsigned int ctx_id; struct kgsl_device *device = dev_priv->device; if (g_z1xx.numcontext == 0) { if (kgsl_sharedmem_alloc(0, KGSL_G12_RB_SIZE, &g_z1xx.cmdbufdesc) != 0) return -ENOMEM; cmd = (int)(((VGV3_NEXTCMD_JUMP) & VGV3_NEXTCMD_NEXTCMD_FMASK) << VGV3_NEXTCMD_NEXTCMD_FSHIFT); result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_MODE, 4); if (result != 0) return result; result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_NEXTADDR, g_z1xx.cmdbufdesc.physaddr); if (result != 0) return result; result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_NEXTCMD, cmd | 5); if (result != 0) return result; result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0); if (result != 0) return result; } ctx_id = ffz(dev_priv->ctxt_id_mask); g_z1xx.numcontext++; if (g_z1xx.numcontext > KGSL_G12_CONTEXT_MAX) { *drawctxt_id = 0; return KGSL_FAILURE; } *drawctxt_id = ctx_id; return KGSL_SUCCESS; }
/*** * rt_udp_socket - create a new UDP-Socket * @s: socket */ int rt_udp_socket(struct rtdm_dev_context *context, rtdm_user_info_t *user_info) { struct rtsocket *sock = (struct rtsocket *)&context->dev_private; int ret; int i; int index; unsigned long flags; if ((ret = rt_socket_init(context)) != 0) return ret; sock->protocol = IPPROTO_UDP; sock->prot.inet.saddr = INADDR_ANY; sock->prot.inet.state = TCP_CLOSE; #ifdef CONFIG_RTNET_RTDM_SELECT sock->wakeup_select = NULL; #endif /* CONFIG_RTNET_RTDM_SELECT */ rtos_spin_lock_irqsave(&udp_socket_base_lock, flags); /* enforce maximum number of UDP sockets */ if (free_ports == 0) { rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags); rt_socket_cleanup(context); return -EAGAIN; } free_ports--; /* find free auto-port in bitmap */ for (i = 0; i < sizeof(port_bitmap)/4; i++) if (port_bitmap[i] != 0xFFFFFFFF) break; index = ffz(port_bitmap[i]); set_bit(index, &port_bitmap[i]); index += i*32; sock->prot.inet.reg_index = index; sock->prot.inet.sport = index + auto_port_start; /* register UDP socket */ port_registry[index].sport = sock->prot.inet.sport; port_registry[index].saddr = INADDR_ANY; port_registry[index].sock = sock; rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags); return 0; }
/* * Get the result of the IRQ probe.. A negative result means that * we have several candidates (but we return the lowest-numbered * one). */ int probe_irq_off(unsigned long irqs) { int i; irqs &= irq_mask & ~1; /* always mask out irq 0---it's the unused timer */ #ifdef CONFIG_ALPHA_P2K irqs &= ~(1 << 8); /* mask out irq 8 since that's the unused RTC input to PIC */ #endif if (!irqs) return 0; i = ffz(~irqs); if (irqs != (1UL << i)) i = -i; return i; }
/* Yuck. the _demux API is ugly */ int ec3104_irq_demux(int irq) { if (irq == EC3104_IRQ) { unsigned int mask; mask = ctrl_readl(EC3104_IRR); if (mask == 0xffffffff) return EC3104_IRQ; else return EC3104_IRQBASE + ffz(mask); } return irq; }
/* this returns the number of consequative 1 bits starting * from the right, get_index128(00 00 00 00 00 00 ... 00 00 10 FB) = 2 */ static inline int get_index128(be128 *block) { int x; __be32 *p = (__be32 *) block; for (p += 3, x = 0; x < 128; p--, x += 32) { u32 val = be32_to_cpup(p); if (!~val) continue; return x + ffz(val); } return x; }