cregit-Linux how code gets into the kernel

Release 4.7 drivers/clk/clk-divider.c

Directory: drivers/clk
/*
 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
 * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Adjustable divider clock implementation
 */

#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/log2.h>

/*
 * DOC: basic adjustable divider clock that cannot gate
 *
 * Traits of this clock:
 * prepare - clk_prepare only ensures that parents are prepared
 * enable - clk_enable only ensures that parents are enabled
 * rate - rate is adjustable.  clk->rate = ceiling(parent->rate / divisor)
 * parent - fixed parent.  No clk_set_parent support
 */


#define div_mask(width)	((1 << (width)) - 1)


static unsigned int _get_table_maxdiv(const struct clk_div_table *table, u8 width) { unsigned int maxdiv = 0, mask = div_mask(width); const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) if (clkt->div > maxdiv && clkt->val <= mask) maxdiv = clkt->div; return maxdiv; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak5577.46%150.00%
stephen boydstephen boyd1622.54%150.00%
Total71100.00%2100.00%


static unsigned int _get_table_mindiv(const struct clk_div_table *table) { unsigned int mindiv = UINT_MAX; const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) if (clkt->div < mindiv) mindiv = clkt->div; return mindiv; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin55100.00%1100.00%
Total55100.00%1100.00%


static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width, unsigned long flags) { if (flags & CLK_DIVIDER_ONE_BASED) return div_mask(width); if (flags & CLK_DIVIDER_POWER_OF_TWO) return 1 << div_mask(width); if (table) return _get_table_maxdiv(table, width); return div_mask(width) + 1; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak5177.27%250.00%
stephen boydstephen boyd1522.73%250.00%
Total66100.00%4100.00%


static unsigned int _get_table_div(const struct clk_div_table *table, unsigned int val) { const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) if (clkt->val == val) return clkt->div; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak52100.00%1100.00%
Total52100.00%1100.00%


static unsigned int _get_div(const struct clk_div_table *table, unsigned int val, unsigned long flags, u8 width) { if (flags & CLK_DIVIDER_ONE_BASED) return val; if (flags & CLK_DIVIDER_POWER_OF_TWO) return 1 << val; if (flags & CLK_DIVIDER_MAX_AT_ZERO) return val ? val : div_mask(width) + 1; if (table) return _get_table_div(table, val); return val + 1; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak5164.56%250.00%
jim quinlanjim quinlan2126.58%125.00%
stephen boydstephen boyd78.86%125.00%
Total79100.00%4100.00%


static unsigned int _get_table_val(const struct clk_div_table *table, unsigned int div) { const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) if (clkt->div == div) return clkt->val; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak52100.00%1100.00%
Total52100.00%1100.00%


static unsigned int _get_val(const struct clk_div_table *table, unsigned int div, unsigned long flags, u8 width) { if (flags & CLK_DIVIDER_ONE_BASED) return div; if (flags & CLK_DIVIDER_POWER_OF_TWO) return __ffs(div); if (flags & CLK_DIVIDER_MAX_AT_ZERO) return (div == div_mask(width) + 1) ? 0 : div; if (table) return _get_table_val(table, div); return div - 1; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak5059.52%240.00%
jim quinlanjim quinlan2529.76%120.00%
stephen boydstephen boyd78.33%120.00%
james hoganjames hogan22.38%120.00%
Total84100.00%5100.00%


unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, unsigned int val, const struct clk_div_table *table, unsigned long flags) { struct clk_divider *divider = to_clk_divider(hw); unsigned int div; div = _get_div(table, val, flags, divider->width); if (!div) { WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO), "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", clk_hw_get_name(hw)); return parent_rate; } return DIV_ROUND_UP_ULL((u64)parent_rate, div); }

Contributors

PersonTokensPropCommitsCommitProp
michael turquettemichael turquette2728.12%112.50%
rajendra nayakrajendra nayak2222.92%112.50%
stephen boydstephen boyd1919.79%225.00%
jim quinlanjim quinlan1414.58%112.50%
soren brinkmannsoren brinkmann77.29%112.50%
brian norrisbrian norris44.17%112.50%
tomi valkeinentomi valkeinen33.12%112.50%
Total96100.00%8100.00%

EXPORT_SYMBOL_GPL(divider_recalc_rate);
static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_divider *divider = to_clk_divider(hw); unsigned int val; val = clk_readl(divider->reg) >> divider->shift; val &= div_mask(divider->width); return divider_recalc_rate(hw, parent_rate, val, divider->table, divider->flags); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd70100.00%1100.00%
Total70100.00%1100.00%


static bool _is_valid_table_div(const struct clk_div_table *table, unsigned int div) { const struct clk_div_table *clkt; for (clkt = table; clkt->div; clkt++) if (clkt->div == div) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak49100.00%1100.00%
Total49100.00%1100.00%


static bool _is_valid_div(const struct clk_div_table *table, unsigned int div, unsigned long flags) { if (flags & CLK_DIVIDER_POWER_OF_TWO) return is_power_of_2(div); if (table) return _is_valid_table_div(table, div); return true; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak3982.98%133.33%
stephen boydstephen boyd714.89%133.33%
james hoganjames hogan12.13%133.33%
Total47100.00%3100.00%


static int _round_up_table(const struct clk_div_table *table, int div) { const struct clk_div_table *clkt; int up = INT_MAX; for (clkt = table; clkt->div; clkt++) { if (clkt->div == div) return clkt->div; else if (clkt->div < div) continue; if ((clkt->div - div) < (up - div)) up = clkt->div; } return up; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin89100.00%2100.00%
Total89100.00%2100.00%


static int _round_down_table(const struct clk_div_table *table, int div) { const struct clk_div_table *clkt; int down = _get_table_mindiv(table); for (clkt = table; clkt->div; clkt++) { if (clkt->div == div) return clkt->div; else if (clkt->div > div) continue; if ((div - clkt->div) < (div - down)) down = clkt->div; } return down; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin92100.00%1100.00%
Total92100.00%1100.00%


static int _div_round_up(const struct clk_div_table *table, unsigned long parent_rate, unsigned long rate, unsigned long flags) { int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); if (flags & CLK_DIVIDER_POWER_OF_TWO) div = __roundup_pow_of_two(div); if (table) div = _round_up_table(table, div); return div; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin5583.33%133.33%
stephen boydstephen boyd710.61%133.33%
brian norrisbrian norris46.06%133.33%
Total66100.00%3100.00%


static int _div_round_closest(const struct clk_div_table *table, unsigned long parent_rate, unsigned long rate, unsigned long flags) { int up, down; unsigned long up_rate, down_rate; up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); down = parent_rate / rate; if (flags & CLK_DIVIDER_POWER_OF_TWO) { up = __roundup_pow_of_two(up); down = __rounddown_pow_of_two(down); } else if (table) { up = _round_up_table(table, up); down = _round_down_table(table, down); } up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up); down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down); return (rate - up_rate) <= (down_rate - rate) ? up : down; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin8660.99%120.00%
uwe kleine-koeniguwe kleine-koenig3625.53%240.00%
brian norrisbrian norris128.51%120.00%
stephen boydstephen boyd74.96%120.00%
Total141100.00%5100.00%


static int _div_round(const struct clk_div_table *table, unsigned long parent_rate, unsigned long rate, unsigned long flags) { if (flags & CLK_DIVIDER_ROUND_CLOSEST) return _div_round_closest(table, parent_rate, rate, flags); return _div_round_up(table, parent_rate, rate, flags); }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin4175.93%150.00%
stephen boydstephen boyd1324.07%150.00%
Total54100.00%2100.00%


static bool _is_best_div(unsigned long rate, unsigned long now, unsigned long best, unsigned long flags) { if (flags & CLK_DIVIDER_ROUND_CLOSEST) return abs(rate - now) < abs(rate - best); return now <= rate && now > best; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin4178.85%133.33%
tomasz figatomasz figa611.54%133.33%
stephen boydstephen boyd59.62%133.33%
Total52100.00%3100.00%


static int _next_div(const struct clk_div_table *table, int div, unsigned long flags) { div++; if (flags & CLK_DIVIDER_POWER_OF_TWO) return __roundup_pow_of_two(div); if (table) return _round_up_table(table, div); return div; }

Contributors

PersonTokensPropCommitsCommitProp
maxime coquelinmaxime coquelin4285.71%150.00%
stephen boydstephen boyd714.29%150.00%
Total49100.00%2100.00%


static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags) { int i, bestdiv = 0; unsigned long parent_rate, best = 0, now, maxdiv; unsigned long parent_rate_saved = *best_parent_rate; if (!rate) rate = 1; maxdiv = _get_maxdiv(table, width, flags); if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { parent_rate = *best_parent_rate; bestdiv = _div_round(table, parent_rate, rate, flags); bestdiv = bestdiv == 0 ? 1 : bestdiv; bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; return bestdiv; } /* * The maximum divider we can use without overflowing * unsigned long in rate * i below */ maxdiv = min(ULONG_MAX / rate, maxdiv); for (i = _next_div(table, 0, flags); i <= maxdiv; i = _next_div(table, i, flags)) { if (rate * i == parent_rate_saved) { /* * It's the most ideal case if the requested rate can be * divided from parent clock without needing to change * parent rate, so return the divider immediately. */ *best_parent_rate = parent_rate_saved; return i; } parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * i); now = DIV_ROUND_UP_ULL((u64)parent_rate, i); if (_is_best_div(rate, now, best, flags)) { bestdiv = i; best = now; *best_parent_rate = parent_rate; } } if (!bestdiv) { bestdiv = _get_maxdiv(table, width, flags); *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); } return bestdiv; }

Contributors

PersonTokensPropCommitsCommitProp
michael turquettemichael turquette17662.19%17.14%
stephen boydstephen boyd3612.72%321.43%
shawn guoshawn guo3412.01%214.29%
maxime coquelinmaxime coquelin134.59%321.43%
masahiro yamadamasahiro yamada82.83%17.14%
rajendra nayakrajendra nayak82.83%17.14%
brian norrisbrian norris41.41%17.14%
tomi valkeinentomi valkeinen31.06%17.14%
uwe kleine-koeniguwe kleine-koenig10.35%17.14%
Total283100.00%14100.00%


long divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate, const struct clk_div_table *table, u8 width, unsigned long flags) { int div; div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); return DIV_ROUND_UP_ULL((u64)*prate, div); }

Contributors

PersonTokensPropCommitsCommitProp
michael turquettemichael turquette3757.81%125.00%
stephen boydstephen boyd2031.25%125.00%
brian norrisbrian norris46.25%125.00%
tomi valkeinentomi valkeinen34.69%125.00%
Total64100.00%4100.00%

EXPORT_SYMBOL_GPL(divider_round_rate);
static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { struct clk_divider *divider = to_clk_divider(hw); int bestdiv; /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { bestdiv = readl(divider->reg) >> divider->shift; bestdiv &= div_mask(divider->width); bestdiv = _get_div(divider->table, bestdiv, divider->flags, divider->width); return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); } return divider_round_rate(hw, rate, prate, divider->table, divider->width, divider->flags); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd7966.39%116.67%
michael turquettemichael turquette2420.17%116.67%
heiko stuebnerheiko stuebner54.20%116.67%
brian norrisbrian norris43.36%116.67%
jim quinlanjim quinlan43.36%116.67%
shawn guoshawn guo32.52%116.67%
Total119100.00%6100.00%


int divider_get_val(unsigned long rate, unsigned long parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags) { unsigned int div, value; div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); if (!_is_valid_div(table, div, flags)) return -EINVAL; value = _get_val(table, div, flags, width); return min_t(unsigned int, value, div_mask(width)); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd4351.81%112.50%
maxime coquelinmaxime coquelin1315.66%112.50%
michael turquettemichael turquette1113.25%112.50%
rajendra nayakrajendra nayak67.23%112.50%
brian norrisbrian norris44.82%112.50%
tomi valkeinentomi valkeinen33.61%112.50%
jim quinlanjim quinlan22.41%112.50%
shawn guoshawn guo11.20%112.50%
Total83100.00%8100.00%

EXPORT_SYMBOL_GPL(divider_get_val);
static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_divider *divider = to_clk_divider(hw); unsigned int value; unsigned long flags = 0; u32 val; value = divider_get_val(rate, parent_rate, divider->table, divider->width, divider->flags); if (divider->lock) spin_lock_irqsave(divider->lock, flags); else __acquire(divider->lock); if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { val = div_mask(divider->width) << (divider->shift + 16); } else { val = clk_readl(divider->reg); val &= ~(div_mask(divider->width) << divider->shift); } val |= value << divider->shift; clk_writel(val, divider->reg); if (divider->lock) spin_unlock_irqrestore(divider->lock, flags); else __release(divider->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael turquettemichael turquette7842.39%116.67%
stephen boydstephen boyd7440.22%233.33%
haojian zhuanghaojian zhuang2815.22%116.67%
gerhard sittiggerhard sittig21.09%116.67%
rajendra nayakrajendra nayak21.09%116.67%
Total184100.00%6100.00%

const struct clk_ops clk_divider_ops = { .recalc_rate = clk_divider_recalc_rate, .round_rate = clk_divider_round_rate, .set_rate = clk_divider_set_rate, }; EXPORT_SYMBOL_GPL(clk_divider_ops); const struct clk_ops clk_divider_ro_ops = { .recalc_rate = clk_divider_recalc_rate, .round_rate = clk_divider_round_rate, }; EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
static struct clk_hw *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { struct clk_divider *div; struct clk_hw *hw; struct clk_init_data init; int ret; if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { if (width + shift > 16) { pr_warn("divider value exceeds LOWORD field\n"); return ERR_PTR(-EINVAL); } } /* allocate the divider */ div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) return ERR_PTR(-ENOMEM); init.name = name; if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) init.ops = &clk_divider_ro_ops; else init.ops = &clk_divider_ops; init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); /* struct clk_divider assignments */ div->reg = reg; div->shift = shift; div->width = width; div->flags = clk_divider_flags; div->lock = lock; div->hw.init = &init; div->table = table; /* register the clock */ hw = &div->hw; ret = clk_hw_register(dev, hw); if (ret) { kfree(div); hw = ERR_PTR(ret); } return hw; }

Contributors

PersonTokensPropCommitsCommitProp
michael turquettemichael turquette12345.90%222.22%
saravana kannansaravana kannan5721.27%111.11%
haojian zhuanghaojian zhuang3011.19%111.11%
stephen boydstephen boyd2810.45%222.22%
rajendra nayakrajendra nayak165.97%222.22%
heiko stuebnerheiko stuebner145.22%111.11%
Total268100.00%9100.00%

/** * clk_register_divider - register a divider clock with the clock framework * @dev: device registering this clock * @name: name of this clock * @parent_name: name of clock's parent * @flags: framework-specific flags * @reg: register address to adjust divider * @shift: number of bits to shift the bitfield * @width: width of the bitfield * @clk_divider_flags: divider-specific flags for this clock * @lock: shared register lock for this clock */
struct clk *clk_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, spinlock_t *lock) { struct clk_hw *hw; hw = _register_divider(dev, name, parent_name, flags, reg, shift, width, clk_divider_flags, NULL, lock); if (IS_ERR(hw)) return ERR_CAST(hw); return hw->clk; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak6772.83%150.00%
stephen boydstephen boyd2527.17%150.00%
Total92100.00%2100.00%

EXPORT_SYMBOL_GPL(clk_register_divider); /** * clk_hw_register_divider - register a divider clock with the clock framework * @dev: device registering this clock * @name: name of this clock * @parent_name: name of clock's parent * @flags: framework-specific flags * @reg: register address to adjust divider * @shift: number of bits to shift the bitfield * @width: width of the bitfield * @clk_divider_flags: divider-specific flags for this clock * @lock: shared register lock for this clock */
struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, spinlock_t *lock) { return _register_divider(dev, name, parent_name, flags, reg, shift, width, clk_divider_flags, NULL, lock); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd68100.00%1100.00%
Total68100.00%1100.00%

EXPORT_SYMBOL_GPL(clk_hw_register_divider); /** * clk_register_divider_table - register a table based divider clock with * the clock framework * @dev: device registering this clock * @name: name of this clock * @parent_name: name of clock's parent * @flags: framework-specific flags * @reg: register address to adjust divider * @shift: number of bits to shift the bitfield * @width: width of the bitfield * @clk_divider_flags: divider-specific flags for this clock * @table: array of divider/value pairs ending with a div set to 0 * @lock: shared register lock for this clock */
struct clk *clk_register_divider_table(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { struct clk_hw *hw; hw = _register_divider(dev, name, parent_name, flags, reg, shift, width, clk_divider_flags, table, lock); if (IS_ERR(hw)) return ERR_CAST(hw); return hw->clk; }

Contributors

PersonTokensPropCommitsCommitProp
rajendra nayakrajendra nayak7374.49%150.00%
stephen boydstephen boyd2525.51%150.00%
Total98100.00%2100.00%

EXPORT_SYMBOL_GPL(clk_register_divider_table); /** * clk_hw_register_divider_table - register a table based divider clock with * the clock framework * @dev: device registering this clock * @name: name of this clock * @parent_name: name of clock's parent * @flags: framework-specific flags * @reg: register address to adjust divider * @shift: number of bits to shift the bitfield * @width: width of the bitfield * @clk_divider_flags: divider-specific flags for this clock * @table: array of divider/value pairs ending with a div set to 0 * @lock: shared register lock for this clock */
struct clk_hw *clk_hw_register_divider_table(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { return _register_divider(dev, name, parent_name, flags, reg, shift, width, clk_divider_flags, table, lock); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd74100.00%1100.00%
Total74100.00%1100.00%

EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
void clk_unregister_divider(struct clk *clk) { struct clk_divider *div; struct clk_hw *hw; hw = __clk_get_hw(clk); if (!hw) return; div = to_clk_divider(hw); clk_unregister(clk); kfree(div); }

Contributors

PersonTokensPropCommitsCommitProp
krzysztof kozlowskikrzysztof kozlowski50100.00%1100.00%
Total50100.00%1100.00%

EXPORT_SYMBOL_GPL(clk_unregister_divider); /** * clk_hw_unregister_divider - unregister a clk divider * @hw: hardware-specific clock data to unregister */
void clk_hw_unregister_divider(struct clk_hw *hw) { struct clk_divider *div; div = to_clk_divider(hw); clk_hw_unregister(hw); kfree(div); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd32100.00%1100.00%
Total32100.00%1100.00%

EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);

Overall Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd71925.61%718.42%
rajendra nayakrajendra nayak59521.19%37.89%
maxime coquelinmaxime coquelin52718.77%410.53%
michael turquettemichael turquette52618.73%25.26%
jim quinlanjim quinlan662.35%12.63%
haojian zhuanghaojian zhuang582.07%12.63%
saravana kannansaravana kannan572.03%12.63%
krzysztof kozlowskikrzysztof kozlowski551.96%12.63%
heiko stuebnerheiko stuebner411.46%25.26%
shawn guoshawn guo391.39%410.53%
uwe kleine-koeniguwe kleine-koenig371.32%37.89%
brian norrisbrian norris371.32%12.63%
tomi valkeinentomi valkeinen120.43%12.63%
fabio estevamfabio estevam100.36%12.63%
masahiro yamadamasahiro yamada80.28%12.63%
soren brinkmannsoren brinkmann70.25%12.63%
james hoganjames hogan60.21%25.26%
tomasz figatomasz figa60.21%12.63%
gerhard sittiggerhard sittig20.07%12.63%
Total2808100.00%38100.00%
Directory: drivers/clk
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}