History

Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk fixes from Stephen Boyd: "A handful of critical fixes for changes introduce this merge window. - The TI sci_clk_get() API was pretty broken and nobody noticed. - There were some CPUfreq crashes on C.H.I.P devices because we failed to propagate rates up the clk tree. - Also, the Intel Atom PMC clk driver needs to mark a clk critical if the firmware has it enabled already so that audio doesn't get killed on Baytrail. - Gemini devices have a dead serial console because the reset control usage in the serial driver assume one method of reset that gemini doesn't support (this will be fixed in the next version in the reset framework so this is the small fix for -rc series). - Finally we have two rate calculation fixes, one for Exynos and one for Meson SoCs, that fix rate inconsistencies" * tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: clk: keystone: sci-clk: Fix sci_clk_get clk: meson: mpll: fix mpll0 fractional part ignored clk: samsung: exynos5420: The EPLL rate table corrections clk: sunxi-ng: sun5i: Add clk_set_rate_parent to the CPU clock clk: x86: Do not gate clocks enabled by the firmware clk: gemini: Fix reset regression

Linus Torvalds committed 9 years ago

Commit ef9ca022 parents 6999507 f54d2cd9 files · +90 −33Browse files

Unified · Split

9 files
  1. drivers/clk/clk-gemini.c +14 −0
  2. drivers/clk/keystone/sci-clk.c +42 −24
  3. drivers/clk/meson/clk-mpll.c +7 −0
  4. drivers/clk/meson/clkc.h +1 −0
  5. drivers/clk/meson/gxbb.c +5 −0
  6. drivers/clk/meson/meson8b.c +5 −0
  7. drivers/clk/samsung/clk-exynos5420.c +8 −8
  8. drivers/clk/sunxi-ng/ccu-sun5i.c +1 −1
  9. drivers/clk/x86/clk-pmc-atom.c +7 −0
drivers/clk/clk-gemini.c+14−0
@@ -237,6 +237,18 @@ static int gemini_reset(struct reset_controller_dev *rcdev, · 236 unmodified lines
237 BIT(GEMINI_RESET_CPU1) | BIT(id));237 BIT(GEMINI_RESET_CPU1) | BIT(id));
238}238}
239 239
240static int gemini_reset_assert(struct reset_controller_dev *rcdev,
241 unsigned long id)
242{
243 return 0;
244}
245
246static int gemini_reset_deassert(struct reset_controller_dev *rcdev,
247 unsigned long id)
248{
249 return 0;
250}
251
240static int gemini_reset_status(struct reset_controller_dev *rcdev,252static int gemini_reset_status(struct reset_controller_dev *rcdev,
241 unsigned long id)253 unsigned long id)
242{254{
@@ -253,6 +265,8 @@ static int gemini_reset_status(struct reset_controller_dev *rcdev, · 10 unmodified lines
253 265
254static const struct reset_control_ops gemini_reset_ops = {266static const struct reset_control_ops gemini_reset_ops = {
255 .reset = gemini_reset,267 .reset = gemini_reset,
268 .assert = gemini_reset_assert,
269 .deassert = gemini_reset_deassert,
256 .status = gemini_reset_status,270 .status = gemini_reset_status,
257};271};
258 272
drivers/clk/keystone/sci-clk.c+42−24
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#include <linux/platform_device.h>22#include <linux/platform_device.h>
23#include <linux/slab.h>23#include <linux/slab.h>
24#include <linux/soc/ti/ti_sci_protocol.h>24#include <linux/soc/ti/ti_sci_protocol.h>
25#include <linux/bsearch.h>
25 26
26#define SCI_CLK_SSC_ENABLE BIT(0)27#define SCI_CLK_SSC_ENABLE BIT(0)
27#define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1)28#define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1)
@@ -44,6 +45,7 @@ struct sci_clk_data { · 16 unmodified lines
44 * @dev: Device pointer for the clock provider45 * @dev: Device pointer for the clock provider
45 * @clk_data: Clock data46 * @clk_data: Clock data
46 * @clocks: Clocks array for this device47 * @clocks: Clocks array for this device
48 * @num_clocks: Total number of clocks for this provider
47 */49 */
48struct sci_clk_provider {50struct sci_clk_provider {
49 const struct ti_sci_handle *sci;51 const struct ti_sci_handle *sci;
@@ -51,6 +53,7 @@ struct sci_clk_provider { · 1 unmodified line
51 struct device *dev;53 struct device *dev;
52 const struct sci_clk_data *clk_data;54 const struct sci_clk_data *clk_data;
53 struct clk_hw **clocks;55 struct clk_hw **clocks;
56 int num_clocks;
54};57};
55 58
56/**59/**
@@ -58,7 +61,6 @@ struct sci_clk_provider { · 1 unmodified line
58 * @hw: Hardware clock cookie for common clock framework61 * @hw: Hardware clock cookie for common clock framework
59 * @dev_id: Device index62 * @dev_id: Device index
60 * @clk_id: Clock index63 * @clk_id: Clock index
61 * @node: Clocks list link
62 * @provider: Master clock provider64 * @provider: Master clock provider
63 * @flags: Flags for the clock65 * @flags: Flags for the clock
64 */66 */
@@ -66,7 +68,6 @@ struct sci_clk { · 1 unmodified line
66 struct clk_hw hw;68 struct clk_hw hw;
67 u16 dev_id;69 u16 dev_id;
68 u8 clk_id;70 u8 clk_id;
69 struct list_head node;
70 struct sci_clk_provider *provider;71 struct sci_clk_provider *provider;
71 u8 flags;72 u8 flags;
72};73};
@@ -367,6 +368,19 @@ err: · 294 unmodified lines
367 return &sci_clk->hw;368 return &sci_clk->hw;
368}369}
369 370
371static int _cmp_sci_clk(const void *a, const void *b)
372{
373 const struct sci_clk *ca = a;
374 const struct sci_clk *cb = *(struct sci_clk **)b;
375
376 if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id)
377 return 0;
378 if (ca->dev_id > cb->dev_id ||
379 (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id))
380 return 1;
381 return -1;
382}
383
370/**384/**
371 * sci_clk_get - Xlate function for getting clock handles385 * sci_clk_get - Xlate function for getting clock handles
372 * @clkspec: device tree clock specifier386 * @clkspec: device tree clock specifier
@@ -380,29 +394,22 @@ err: · 7 unmodified lines
380static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)394static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
381{395{
382 struct sci_clk_provider *provider = data;396 struct sci_clk_provider *provider = data;
383 u16 dev_id;397 struct sci_clk **clk;
384 u8 clk_id;398 struct sci_clk key;
385 const struct sci_clk_data *clks = provider->clk_data;
386 struct clk_hw **clocks = provider->clocks;
387 399
388 if (clkspec->args_count != 2)400 if (clkspec->args_count != 2)
389 return ERR_PTR(-EINVAL);401 return ERR_PTR(-EINVAL);
390 402
391 dev_id = clkspec->args[0];403 key.dev_id = clkspec->args[0];
392 clk_id = clkspec->args[1];404 key.clk_id = clkspec->args[1];
393 405
394 while (clks->num_clks) {406 clk = bsearch(&key, provider->clocks, provider->num_clocks,
395 if (clks->dev == dev_id) {407 sizeof(clk), _cmp_sci_clk);
396 if (clk_id >= clks->num_clks)
397 return ERR_PTR(-EINVAL);
398
399 return clocks[clk_id];
400 }
401 408
402 clks++;409 if (!clk)
403 }410 return ERR_PTR(-ENODEV);
404 411
405 return ERR_PTR(-ENODEV);412 return &(*clk)->hw;
406}413}
407 414
408static int ti_sci_init_clocks(struct sci_clk_provider *p)415static int ti_sci_init_clocks(struct sci_clk_provider *p)
@@ -410,18 +417,29 @@ static int ti_sci_init_clocks(struct sci_clk_provider *p) · 1 unmodified line
410 const struct sci_clk_data *data = p->clk_data;417 const struct sci_clk_data *data = p->clk_data;
411 struct clk_hw *hw;418 struct clk_hw *hw;
412 int i;419 int i;
420 int num_clks = 0;
413 421
414 while (data->num_clks) {422 while (data->num_clks) {
415 p->clocks = devm_kcalloc(p->dev, data->num_clks,423 num_clks += data->num_clks;
416 sizeof(struct sci_clk),424 data++;
417 GFP_KERNEL);425 }
418 if (!p->clocks)
419 return -ENOMEM;
420 426
427 p->num_clocks = num_clks;
428
429 p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk),
430 GFP_KERNEL);
431 if (!p->clocks)
432 return -ENOMEM;
433
434 num_clks = 0;
435
436 data = p->clk_data;
437
438 while (data->num_clks) {
421 for (i = 0; i < data->num_clks; i++) {439 for (i = 0; i < data->num_clks; i++) {
422 hw = _sci_clk_build(p, data->dev, i);440 hw = _sci_clk_build(p, data->dev, i);
423 if (!IS_ERR(hw)) {441 if (!IS_ERR(hw)) {
424 p->clocks[i] = hw;442 p->clocks[num_clks++] = hw;
425 continue;443 continue;
426 }444 }
427 445
drivers/clk/meson/clk-mpll.c+7−0
@@ -161,6 +161,13 @@ static int mpll_set_rate(struct clk_hw *hw, · 160 unmodified lines
161 reg = PARM_SET(p->width, p->shift, reg, 1);161 reg = PARM_SET(p->width, p->shift, reg, 1);
162 writel(reg, mpll->base + p->reg_off);162 writel(reg, mpll->base + p->reg_off);
163 163
164 p = &mpll->ssen;
165 if (p->width != 0) {
166 reg = readl(mpll->base + p->reg_off);
167 reg = PARM_SET(p->width, p->shift, reg, 1);
168 writel(reg, mpll->base + p->reg_off);
169 }
170
164 p = &mpll->n2;171 p = &mpll->n2;
165 reg = readl(mpll->base + p->reg_off);172 reg = readl(mpll->base + p->reg_off);
166 reg = PARM_SET(p->width, p->shift, reg, n2);173 reg = PARM_SET(p->width, p->shift, reg, n2);
drivers/clk/meson/clkc.h+1−0
@@ -118,6 +118,7 @@ struct meson_clk_mpll { · 117 unmodified lines
118 struct parm sdm_en;118 struct parm sdm_en;
119 struct parm n2;119 struct parm n2;
120 struct parm en;120 struct parm en;
121 struct parm ssen;
121 spinlock_t *lock;122 spinlock_t *lock;
122};123};
123 124
drivers/clk/meson/gxbb.c+5−0
@@ -528,6 +528,11 @@ static struct meson_clk_mpll gxbb_mpll0 = { · 527 unmodified lines
528 .shift = 14,528 .shift = 14,
529 .width = 1,529 .width = 1,
530 },530 },
531 .ssen = {
532 .reg_off = HHI_MPLL_CNTL,
533 .shift = 25,
534 .width = 1,
535 },
531 .lock = &clk_lock,536 .lock = &clk_lock,
532 .hw.init = &(struct clk_init_data){537 .hw.init = &(struct clk_init_data){
533 .name = "mpll0",538 .name = "mpll0",
drivers/clk/meson/meson8b.c+5−0
@@ -267,6 +267,11 @@ static struct meson_clk_mpll meson8b_mpll0 = { · 266 unmodified lines
267 .shift = 14,267 .shift = 14,
268 .width = 1,268 .width = 1,
269 },269 },
270 .ssen = {
271 .reg_off = HHI_MPLL_CNTL,
272 .shift = 25,
273 .width = 1,
274 },
270 .lock = &clk_lock,275 .lock = &clk_lock,
271 .hw.init = &(struct clk_init_data){276 .hw.init = &(struct clk_init_data){
272 .name = "mpll0",277 .name = "mpll0",
drivers/clk/samsung/clk-exynos5420.c+8−8
@@ -1283,16 +1283,16 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini · 1282 unmodified lines
1283static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {1283static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
1284 PLL_36XX_RATE(600000000U, 100, 2, 1, 0),1284 PLL_36XX_RATE(600000000U, 100, 2, 1, 0),
1285 PLL_36XX_RATE(400000000U, 200, 3, 2, 0),1285 PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
1286 PLL_36XX_RATE(393216000U, 197, 3, 2, 25690),1286 PLL_36XX_RATE(393216003U, 197, 3, 2, -25690),
1287 PLL_36XX_RATE(361267200U, 301, 5, 2, 3671),1287 PLL_36XX_RATE(361267218U, 301, 5, 2, 3671),
1288 PLL_36XX_RATE(200000000U, 200, 3, 3, 0),1288 PLL_36XX_RATE(200000000U, 200, 3, 3, 0),
1289 PLL_36XX_RATE(196608000U, 197, 3, 3, -25690),1289 PLL_36XX_RATE(196608001U, 197, 3, 3, -25690),
1290 PLL_36XX_RATE(180633600U, 301, 5, 3, 3671),1290 PLL_36XX_RATE(180633609U, 301, 5, 3, 3671),
1291 PLL_36XX_RATE(131072000U, 131, 3, 3, 4719),1291 PLL_36XX_RATE(131072006U, 131, 3, 3, 4719),
1292 PLL_36XX_RATE(100000000U, 200, 3, 4, 0),1292 PLL_36XX_RATE(100000000U, 200, 3, 4, 0),
1293 PLL_36XX_RATE(65536000U, 131, 3, 4, 4719),1293 PLL_36XX_RATE( 65536003U, 131, 3, 4, 4719),
1294 PLL_36XX_RATE(49152000U, 197, 3, 5, 25690),1294 PLL_36XX_RATE( 49152000U, 197, 3, 5, -25690),
1295 PLL_36XX_RATE(32768000U, 131, 3, 5, 4719),1295 PLL_36XX_RATE( 32768001U, 131, 3, 5, 4719),
1296};1296};
1297 1297
1298static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {1298static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
drivers/clk/sunxi-ng/ccu-sun5i.c+1−1
@@ -184,7 +184,7 @@ static struct ccu_mux cpu_clk = { · 183 unmodified lines
184 .hw.init = CLK_HW_INIT_PARENTS("cpu",184 .hw.init = CLK_HW_INIT_PARENTS("cpu",
185 cpu_parents,185 cpu_parents,
186 &ccu_mux_ops,186 &ccu_mux_ops,
187 CLK_IS_CRITICAL),187 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
188 }188 }
189};189};
190 190
drivers/clk/x86/clk-pmc-atom.c+7−0
@@ -186,6 +186,13 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, · 185 unmodified lines
186 pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;186 pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
187 spin_lock_init(&pclk->lock);187 spin_lock_init(&pclk->lock);
188 188
189 /*
190 * If the clock was already enabled by the firmware mark it as critical
191 * to avoid it being gated by the clock framework if no driver owns it.
192 */
193 if (plt_clk_is_enabled(&pclk->hw))
194 init.flags |= CLK_IS_CRITICAL;
195
189 ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);196 ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
190 if (ret) {197 if (ret) {
191 pclk = ERR_PTR(ret);198 pclk = ERR_PTR(ret);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t