void bonito_irqdispatch(void) { u32 int_status; int i; /* */ int_status = LOONGSON_INTISR; while (int_status & (1 << 10)) { udelay(1); int_status = LOONGSON_INTISR; } /* */ int_status = LOONGSON_INTISR & LOONGSON_INTEN; if (int_status) { i = __ffs(int_status); do_IRQ(LOONGSON_IRQ_BASE + i); } }
/* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev) { unsigned long irr; struct gsc_asic *gsc_asic = dev; irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR); if (irr == 0) return IRQ_NONE; DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr); do { int local_irq = __ffs(irr); unsigned int irq = gsc_asic->global_irq[local_irq]; __do_IRQ(irq); irr &= ~(1 << local_irq); } while (irr); return IRQ_HANDLED; }
/** * omap3_dpll_allow_idle - enable DPLL autoidle bits * @clk: struct clk * of the DPLL to operate on * * Enable DPLL automatic idle control. This automatic idle mode * switching takes effect only when the DPLL is locked, at least on * OMAP3430. The DPLL will enter low-power stop when its downstream * clocks are gated. No return value. */ static void omap3_dpll_allow_idle(struct clk *clk) { const struct dpll_data *dd; u32 v; if (!clk || !clk->dpll_data) return; dd = clk->dpll_data; /* * REVISIT: CORE DPLL can optionally enter low-power bypass * by writing 0x5 instead of 0x1. Add some mechanism to * optionally enter this mode. */ v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg); v &= ~dd->autoidle_mask; v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); cm_write_mod_reg(v, clk->prcm_mod, dd->autoidle_reg); }
/** * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not * @v: bitfield value of the DPLL enable * * Checks given DPLL enable bitfield to see whether the DPLL is in bypass * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise. */ static int _omap2_dpll_is_in_bypass(u32 v) { u8 mask, val; mask = ti_clk_features.dpll_bypass_vals; /* * Each set bit in the mask corresponds to a bypass value equal * to the bitshift. Go through each set-bit in the mask and * compare against the given register value. */ while (mask) { val = __ffs(mask); mask ^= (1 << val); if (v == val) return 1; } return 0; }
/* Public functions */ u8 omap2_init_dpll_parent(struct clk_hw *hw) { struct clk_hw_omap *clk = to_clk_hw_omap(hw); u32 v; struct dpll_data *dd; dd = clk->dpll_data; if (!dd) return -EINVAL; v = omap2_clk_readl(clk, dd->control_reg); v &= dd->enable_mask; v >>= __ffs(dd->enable_mask); /* Reparent the struct clk in case the dpll is in bypass */ if (_omap2_dpll_is_in_bypass(v)) return 1; return 0; }
static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip = irq_get_chip(irq); unsigned int first_irq; chained_irq_enter(host_chip, desc); nmk_chip = irq_get_handler_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while (status) { int bit = __ffs(status); generic_handle_irq(first_irq + bit); status &= ~BIT(bit); } chained_irq_exit(host_chip, desc); }
static void ath79_misc_irq_handler(struct irq_desc *desc) { void __iomem *base = ath79_reset_base; u32 pending; pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); if (!pending) { spurious_interrupt(); return; } while (pending) { int bit = __ffs(pending); generic_handle_irq(ATH79_MISC_IRQ(bit)); pending &= ~BIT(bit); } }
static irqreturn_t pca953x_irq_handler(int irq, void *devid) { struct pca953x_chip *chip = devid; uint16_t pending; uint16_t level; pending = pca953x_irq_pending(chip); if (!pending) return IRQ_HANDLED; do { level = __ffs(pending); generic_handle_irq(level + chip->irq_base); pending &= ~(1 << level); } while (pending); return IRQ_HANDLED; }
void ti816x_init_fapll_parent(struct clk *clk) { u32 v; struct fapll_data *fd; fd = clk->fapll_data; if (!fd) return; /* Return bypass rate if FAPLL is bypassed */ v = __raw_readl(fd->control_reg); v &= fd->bypass_mask; v >>= __ffs(fd->bypass_mask); /* Reparent in case the fapll is in bypass */ if (v == fd->bypass_en) clk_reparent(clk, fd->clk_bypass); return; }
_WCRTLINK int ffs( int value ) { #if defined(__386__) && defined(__WATCOMC__) return( __ffs( value ) ); #else int index; if( value == 0 ) { return( 0 ); } index = 1; /* We know this loop will exit because at least one bit is non-zero */ while( (value & 1) == 0 ) { ++index; value >>= 1; } return( index ); #endif }
bool ux500_pm_prcmu_pending_interrupt(u32 *pending_irq) { u32 it; u32 im; int i; for (i = 0; i < GIC_NUMBER_SPI_REGS; i++) { /* There are 4 registers */ it = prcmu_read(PRCM_ARMITVAL31TO0 + i * 4); im = prcmu_read(PRCM_ARMITMSK31TO0 + i * 4); if (it & im) { /* Return first pending interrupt */ if (pending_irq) *pending_irq = i * 32 + __ffs(it & im); return true; } } return false; }
static irqreturn_t max732x_irq_handler(int irq, void *devid) { struct max732x_chip *chip = devid; uint8_t pending; uint8_t level; pending = max732x_irq_pending(chip); if (!pending) return IRQ_HANDLED; do { level = __ffs(pending); handle_nested_irq(level + chip->irq_base); pending &= ~(1 << level); } while (pending); return IRQ_HANDLED; }
static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip = irq_get_chip(irq); unsigned int first_irq; chained_irq_enter(host_chip, desc); nmk_chip = irq_get_handler_data(irq); first_irq = nmk_chip->domain->revmap_data.legacy.first_irq; while (status) { int bit = __ffs(status); generic_handle_irq(first_irq + bit); status &= ~BIT(bit); } chained_irq_exit(host_chip, desc); }
/* * the first level int-handler will jump here if it is a bonito irq */ void bonito_irqdispatch(void) { u32 int_status; int i; /* workaround the IO dma problem: let cpu looping to allow DMA finish */ int_status = LOONGSON_INTISR; while (int_status & (1 << 10)) { udelay(1); int_status = LOONGSON_INTISR; } /* Get pending sources, masked by current enables */ int_status = LOONGSON_INTISR & LOONGSON_INTEN; if (int_status) { i = __ffs(int_status); do_IRQ(LOONGSON_IRQ_BASE + i); } }
static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { int id = rdev_get_id(rdev); struct lp87565 *lp87565 = rdev_get_drvdata(rdev); unsigned int reg; int ret; if (ramp_delay <= 470) reg = 7; else if (ramp_delay <= 940) reg = 6; else if (ramp_delay <= 1900) reg = 5; else if (ramp_delay <= 3800) reg = 4; else if (ramp_delay <= 7500) reg = 3; else if (ramp_delay <= 10000) reg = 2; else if (ramp_delay <= 15000) reg = 1; else reg = 0; ret = regmap_update_bits(lp87565->regmap, regulators[id].ctrl2_reg, LP87565_BUCK_CTRL_2_SLEW_RATE, reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE)); if (ret) { dev_err(lp87565->dev, "SLEW RATE write failed: %d\n", ret); return ret; } rdev->constraints->ramp_delay = lp87565_buck_ramp_delay[reg]; /* Conservatively give a 15% margin */ rdev->constraints->ramp_delay = rdev->constraints->ramp_delay * 85 / 100; return 0; }
/** * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr * @clk: OMAP clock struct ptr to use * * Given a pointer @clk to a source-selectable struct clk, read the * hardware register and determine what its parent is currently set * to. Update @clk's .parent field with the appropriate clk ptr. No * return value. */ void omap2_init_clksel_parent(struct clk *clk) { const struct clksel *clks; const struct clksel_rate *clkr; u32 r, found = 0; if (!clk->clksel || !clk->clksel_mask) return; //printk("omap2_init_clksel_parent: %s clksel_reg=%x\n", clk->name, clk->clksel_reg); r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; //printk("omap2_init_clksel_parent: __raw_readl %x\n", r); r >>= __ffs(clk->clksel_mask); //printk("omap2_init_clksel_parent: __ffs(%x) %x\n", clk->clksel_mask, r); for (clks = clk->clksel; clks->parent && !found; clks++) { for (clkr = clks->rates; clkr->div && !found; clkr++) { if (!(clkr->flags & cpu_mask)) continue; if (clkr->val == r) { if (clk->parent != clks->parent) { pr_debug("clock: inited %s parent " "to %s (was %s)\n", clk->name, clks->parent->name, ((clk->parent) ? clk->parent->name : "NULL")); clk_reparent(clk, clks->parent); }; found = 1; } } } /* This indicates a data error */ WARN(!found, "clock: %s: init parent: could not find regval %0x\n", clk->name, r); return; }
static void vp_latch_vsel(struct voltagedomain *voltdm) { struct omap_vp_instance *vp = voltdm->vp; struct omap_volt_data *v = omap_voltage_get_curr_vdata(voltdm); u32 vpconfig; unsigned long uvdc; char vsel; if (IS_ERR_OR_NULL(v)) { pr_warning("%s: unable to get voltage for vdd_%s\n", __func__, voltdm->name); return; } uvdc = omap_get_operation_voltage(v); if (!uvdc) { pr_warning("%s: unable to find current voltage for vdd_%s\n", __func__, voltdm->name); return; } if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { pr_warning("%s: PMIC function to convert voltage in uV to" " vsel not registered\n", __func__); return; } vsel = voltdm->pmic->uv_to_vsel(uvdc); vpconfig = voltdm->read(vp->vpconfig); vpconfig &= ~(vp->common->vpconfig_initvoltage_mask | vp->common->vpconfig_initvdd); vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask); voltdm->write(vpconfig, vp->vpconfig); /* Trigger initVDD value copy to voltage processor */ voltdm->write((vpconfig | vp->common->vpconfig_initvdd), vp->vpconfig); /* Clear initVDD copy trigger bit */ voltdm->write(vpconfig, vp->vpconfig); }
static int __init __gic_clocksource_init(void) { unsigned int count_width; int ret; /* Set clocksource mask. */ count_width = read_gic_config() & GIC_CONFIG_COUNTBITS; count_width >>= __ffs(GIC_CONFIG_COUNTBITS); count_width *= 4; count_width += 32; gic_clocksource.mask = CLOCKSOURCE_MASK(count_width); /* Calculate a somewhat reasonable rating value. */ gic_clocksource.rating = 200 + gic_frequency / 10000000; ret = clocksource_register_hz(&gic_clocksource, gic_frequency); if (ret < 0) pr_warn("Unable to register clocksource\n"); return ret; }
static void rps_handle_cascade_irq(struct irq_desc *desc) #endif { struct rps_chip_data *chip_data = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int cascade_irq, rps_irq; u32 status; chained_irq_enter(chip, desc); status = ioread32(chip_data->base + RPS_STATUS); rps_irq = __ffs(status); cascade_irq = irq_find_mapping(chip_data->domain, rps_irq); if (unlikely(rps_irq >= RPS_IRQ_COUNT)) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) handle_bad_irq(cascade_irq, desc); #else handle_bad_irq(desc); #endif else
/* Must be called with smi lock held */ static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int port; u32 mask; int ret; mask = ds->phys_port_mask; while (mask) { port = __ffs(mask); mask &= ~(1 << port); if (ps->fid[port] != fid) continue; ret = _mv88e6xxx_update_port_config(ds, port); if (ret) return ret; } return _mv88e6xxx_flush_fid(ds, fid); }
void SpiFrequency( Spi_t *obj, uint32_t hz ) { uint32_t divisor; divisor = SystemCoreClock / hz; // Find the nearest power-of-2 divisor = divisor > 0 ? divisor-1 : 0; divisor |= divisor >> 1; divisor |= divisor >> 2; divisor |= divisor >> 4; divisor |= divisor >> 8; divisor |= divisor >> 16; divisor++; divisor = __ffs( divisor ) - 1; divisor = ( divisor > 0x07 ) ? 0x07 : divisor; obj->Spi.Init.BaudRatePrescaler = divisor << 3; }
static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) { u32 pending = ar5312_rst_reg_read(AR5312_ISR) & ar5312_rst_reg_read(AR5312_IMR); unsigned nr, misc_irq = 0; if (pending) { struct irq_domain *domain = irq_get_handler_data(irq); nr = __ffs(pending); misc_irq = irq_find_mapping(domain, nr); } if (misc_irq) { generic_handle_irq(misc_irq); if (nr == AR5312_MISC_IRQ_TIMER) ar5312_rst_reg_read(AR5312_TIMER); } else { spurious_interrupt(); } }
int omap_vp_update_errorgain(struct voltagedomain *voltdm, unsigned long target_volt) { struct omap_volt_data *volt_data; if (!voltdm->vp) return -EINVAL; /* Get volt_data corresponding to target_volt */ volt_data = omap_voltage_get_voltdata(voltdm, target_volt); if (IS_ERR(volt_data)) return -EINVAL; /* Setting vp errorgain based on the voltage */ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask, volt_data->vp_errgain << __ffs(voltdm->vp->common->vpconfig_errorgain_mask), voltdm->vp->vpconfig); return 0; }
static void ske_keypad_read_data(struct ske_keypad *keypad) { struct input_dev *input = keypad->input; u16 status; int col = 0, row = 0, code; int ske_asr, ske_ris, key_pressed, i; /* * Read the auto scan registers * * Each SKE_ASRx (x=0 to x=3) contains two row values. * lower byte contains row value for column 2*x, * upper byte contains row value for column 2*x + 1 */ for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) { ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i)); if (!ske_asr) continue; /* now that ASRx is zero, find out the column x and row y*/ if (ske_asr & 0xff) { col = i * 2; status = ske_asr & 0xff; } else { col = (i * 2) + 1; status = (ske_asr & 0xff00) >> 8; } /* find out the row */ row = __ffs(status); code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); ske_ris = readl(keypad->reg_base + SKE_RIS); key_pressed = ske_ris & SKE_KPRISA; input_event(input, EV_MSC, MSC_SCAN, code); input_report_key(input, keypad->keymap[code], key_pressed); input_sync(input); } }
void print_hard_irq_inloop(int ret) { unsigned int i, j, val; unsigned int gpio_irq[GPIO_GROUP_NUM]; if(!((sprd_irqs_sts[0]&IRQ_DSP0) || (sprd_irqs_sts[0]&IRQ_DSP1) || (sprd_irqs_sts[0]&IRQ_TIMER0) || (sprd_irqs_sts[0]&IRQ_SIM0) || (sprd_irqs_sts[0]&IRQ_SIM1) ) ){ if(sprd_irqs_sts[0] != 0) printk("%c#:INTC0: %08x\n", ret?'S':'F', sprd_irqs_sts[0]); if(sprd_irqs_sts[1] != 0) printk("%c#:INTC0 FIQ: %08x\n", ret?'S':'F', sprd_irqs_sts[1]); } if(sprd_irqs_sts[0] & IRQ_GPIO){ for(i=0; i<(GPIO_GROUP_NUM/2); i++){ j = 2*i; gpio_irq[j]= __raw_readl(SPRD_GPIO_BASE + 0x100*i + REG_GPIO_MIS); gpio_irq[j+1]= __raw_readl(SPRD_GPIO_BASE + 0x100*i + 0x80 + REG_GPIO_MIS); printk("gpio_irq[%d]:0x%x, gpio_irq[%d]:0x%x \n", j, gpio_irq[j], j+1, gpio_irq[j+1]); } for(i=0; i<GPIO_GROUP_NUM; i++){ if(gpio_irq[i] != 0){ val = gpio_irq[i]; while(val){ j = __ffs(val); printk("gpio irq number : %d \n", (j+16*(i+1)) ); val &= ~(1<<j); } } } } if(sprd_irqs_sts[0] & IRQ_ADIE){ printk("adie, irq status:0x%x \n", sci_adi_read(ANA_REG_INT_MASK_STATUS)); } }
static int phylink_phy_write(struct phylink *pl, unsigned int phy_id, unsigned int reg, unsigned int val) { struct phy_device *phydev = pl->phydev; int prtad, devad; if (mdio_phy_id_is_c45(phy_id)) { prtad = mdio_phy_id_prtad(phy_id); devad = mdio_phy_id_devad(phy_id); devad = MII_ADDR_C45 | devad << 16 | reg; } else if (phydev->is_c45) { switch (reg) { case MII_BMCR: case MII_BMSR: case MII_PHYSID1: case MII_PHYSID2: devad = __ffs(phydev->c45_ids.devices_in_package); break; case MII_ADVERTISE: case MII_LPA: if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN)) return -EINVAL; devad = MDIO_MMD_AN; if (reg == MII_ADVERTISE) reg = MDIO_AN_ADVERTISE; else reg = MDIO_AN_LPA; break; default: return -EINVAL; } prtad = phy_id; devad = MII_ADDR_C45 | devad << 16 | reg; } else { prtad = phy_id; devad = reg; } return mdiobus_write(phydev->mdio.bus, prtad, devad, val); }
static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) { struct omap3_l3 *l3 = _l3; u64 status, clear; u64 error; u64 error_addr; u64 err_source = 0; void __iomem *base; int int_type; irqreturn_t ret = IRQ_NONE; int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; if (!int_type) { status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_0); BUG_ON(status & L3_STATUS_0_TIMEOUT_MASK); } else { status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_1); } err_source = __ffs(status); base = l3->rt + omap3_l3_bases[int_type][err_source]; error = omap3_l3_readll(base, L3_ERROR_LOG); if (error) { error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR); ret |= omap3_l3_block_irq(l3, error, error_addr); } clear = (L3_AGENT_STATUS_CLEAR_IA << int_type) | L3_AGENT_STATUS_CLEAR_TA; omap3_l3_writell(base, L3_AGENT_STATUS, clear); omap3_l3_writell(base, L3_ERROR_LOG, error); return ret; }
static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending = __raw_readl(BALLOON3_INT_CONTROL_REG) & balloon3_irq_enabled; do { /* clear useless edge notification */ if (desc->irq_data.chip->irq_ack) { struct irq_data *d; d = irq_get_irq_data(BALLOON3_AUX_NIRQ); desc->irq_data.chip->irq_ack(d); } while (pending) { irq = BALLOON3_IRQ(0) + __ffs(pending); generic_handle_irq(irq); pending &= pending - 1; } pending = __raw_readl(BALLOON3_INT_CONTROL_REG) & balloon3_irq_enabled; } while (pending); }
static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) { struct temp_sensor_registers *tsr; int i; u32 ctrl; if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH)) return 0; for (i = 0; i < bg_ptr->conf->sensor_count; i++) { tsr = bg_ptr->conf->sensors[i].registers; ctrl = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); ctrl &= ~tsr->bgap_tempsoff_mask; /* active on 0 */ ctrl |= !on << __ffs(tsr->bgap_tempsoff_mask); /* write BGAP_TEMPSOFF should be reset to 0 */ omap_bandgap_writel(bg_ptr, ctrl, tsr->temp_sensor_ctrl); } return 0; }
static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc) { struct megamod_cascade_data *cascade; struct megamod_pic *pic; u32 events; int n, idx; cascade = irq_desc_get_handler_data(desc); pic = cascade->pic; idx = cascade->index; while ((events = soc_readl(&pic->regs->mevtflag[idx])) != 0) { n = __ffs(events); irq = irq_linear_revmap(pic->irqhost, idx * 32 + n); soc_writel(1 << n, &pic->regs->evtclr[idx]); generic_handle_irq(irq); } }