diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 21:50:54 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 21:50:54 +0200 |
commit | bfaf245022b4b8661af2e35f467cf0e91943c24c (patch) | |
tree | b5a6ee49a047557a791eb897c8c9545a155e36b7 /drivers/clk/pistachio/clk.c | |
parent | Merge tag 'xtensa-20150416' of git://github.com/czankel/xtensa-linux (diff) | |
parent | Merge branch '4.0-fixes' into mips-for-linux-next (diff) | |
download | linux-bfaf245022b4b8661af2e35f467cf0e91943c24c.tar.xz linux-bfaf245022b4b8661af2e35f467cf0e91943c24c.zip |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for MIPS for Linux 4.1. Most
noteworthy:
- Add more Octeon-optimized crypto functions
- Octeon crypto preemption and locking fixes
- Little endian support for Octeon
- Use correct CSR to soft reset Octeons
- Support LEDs on the Octeon-based DSR-1000N
- Fix PCI interrupt mapping for the Octeon-based DSR-1000N
- Mark prom_free_prom_memory() as __init for a number of systems
- Support for Imagination's Pistachio SOC. This includes arch and
CLK bits. I'd like to merge pinctrl bits later
- Improve parallelism of csum_partial for certain pipelines
- Organize DTB files in subdirs like other architectures
- Implement read_sched_clock for all MIPS platforms other than
Octeon
- Massive series of 38 fixes and cleanups for the FPU emulator /
kernel
- Further FPU remulator work to support new features. This sits on a
separate branch which also has been pulled into the 4.1 KVM branch
- Clean up and fixes for the SEAD3 eval board; remove unused file
- Various updates for Netlogic platforms
- A number of small updates for Loongson 3 platforms
- Increase the memory limit for ATH79 platforms to 256MB
- A fair number of fixes and updates for BCM47xx platforms
- Finish the implementation of XPA support
- MIPS FDC support. No, not floppy controller but Fast Debug Channel :)
- Detect the R16000 used in SGI legacy platforms
- Fix Kconfig dependencies for the SSB bus support"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (265 commits)
MIPS: Makefile: Fix MIPS ASE detection code
MIPS: asm: elf: Set O32 default FPU flags
MIPS: BCM47XX: Fix detecting Microsoft MN-700 & Asus WL500G
MIPS: Kconfig: Disable SMP/CPS for 64-bit
MIPS: Hibernate: flush TLB entries earlier
MIPS: smp-cps: cpu_set FPU mask if FPU present
MIPS: lose_fpu(): Disable FPU when MSA enabled
MIPS: ralink: add missing symbol for RALINK_ILL_ACC
MIPS: ralink: Fix bad config symbol in PCI makefile.
SSB: fix Kconfig dependencies
MIPS: Malta: Detect and fix bad memsize values
Revert "MIPS: Avoid pipeline stalls on some MIPS32R2 cores."
MIPS: Octeon: Delete override of cpu_has_mips_r2_exec_hazard.
MIPS: Fix cpu_has_mips_r2_exec_hazard.
MIPS: kernel: entry.S: Set correct ISA level for mips_ihb
MIPS: asm: spinlock: Fix addiu instruction for R10000_LLSC_WAR case
MIPS: r4kcache: Use correct base register for MIPS R6 cache flushes
MIPS: Kconfig: Fix typo for the r2-to-r6 emulator kernel parameter
MIPS: unaligned: Fix regular load/store instruction emulation for EVA
MIPS: unaligned: Surround load/store macros in do {} while statements
...
Diffstat (limited to 'drivers/clk/pistachio/clk.c')
-rw-r--r-- | drivers/clk/pistachio/clk.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/drivers/clk/pistachio/clk.c b/drivers/clk/pistachio/clk.c new file mode 100644 index 000000000000..85faa83e1bd7 --- /dev/null +++ b/drivers/clk/pistachio/clk.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2014 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include <linux/clk-provider.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> + +#include "clk.h" + +struct pistachio_clk_provider * +pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks) +{ + struct pistachio_clk_provider *p; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return p; + + p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL); + if (!p->clk_data.clks) + goto free_provider; + p->clk_data.clk_num = num_clks; + p->node = node; + p->base = of_iomap(node, 0); + if (!p->base) { + pr_err("Failed to map clock provider registers\n"); + goto free_clks; + } + + return p; + +free_clks: + kfree(p->clk_data.clks); +free_provider: + kfree(p); + return NULL; +} + +void pistachio_clk_register_provider(struct pistachio_clk_provider *p) +{ + unsigned int i; + + for (i = 0; i < p->clk_data.clk_num; i++) { + if (IS_ERR(p->clk_data.clks[i])) + pr_warn("Failed to register clock %d: %ld\n", i, + PTR_ERR(p->clk_data.clks[i])); + } + + of_clk_add_provider(p->node, of_clk_src_onecell_get, &p->clk_data); +} + +void pistachio_clk_register_gate(struct pistachio_clk_provider *p, + struct pistachio_gate *gate, + unsigned int num) +{ + struct clk *clk; + unsigned int i; + + for (i = 0; i < num; i++) { + clk = clk_register_gate(NULL, gate[i].name, gate[i].parent, + CLK_SET_RATE_PARENT, + p->base + gate[i].reg, gate[i].shift, + 0, NULL); + p->clk_data.clks[gate[i].id] = clk; + } +} + +void pistachio_clk_register_mux(struct pistachio_clk_provider *p, + struct pistachio_mux *mux, + unsigned int num) +{ + struct clk *clk; + unsigned int i; + + for (i = 0; i < num; i++) { + clk = clk_register_mux(NULL, mux[i].name, mux[i].parents, + mux[i].num_parents, + CLK_SET_RATE_NO_REPARENT, + p->base + mux[i].reg, mux[i].shift, + get_count_order(mux[i].num_parents), + 0, NULL); + p->clk_data.clks[mux[i].id] = clk; + } +} + +void pistachio_clk_register_div(struct pistachio_clk_provider *p, + struct pistachio_div *div, + unsigned int num) +{ + struct clk *clk; + unsigned int i; + + for (i = 0; i < num; i++) { + clk = clk_register_divider(NULL, div[i].name, div[i].parent, + 0, p->base + div[i].reg, 0, + div[i].width, div[i].div_flags, + NULL); + p->clk_data.clks[div[i].id] = clk; + } +} + +void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p, + struct pistachio_fixed_factor *ff, + unsigned int num) +{ + struct clk *clk; + unsigned int i; + + for (i = 0; i < num; i++) { + clk = clk_register_fixed_factor(NULL, ff[i].name, ff[i].parent, + 0, 1, ff[i].div); + p->clk_data.clks[ff[i].id] = clk; + } +} + +void pistachio_clk_force_enable(struct pistachio_clk_provider *p, + unsigned int *clk_ids, unsigned int num) +{ + unsigned int i; + int err; + + for (i = 0; i < num; i++) { + struct clk *clk = p->clk_data.clks[clk_ids[i]]; + + if (IS_ERR(clk)) + continue; + + err = clk_prepare_enable(clk); + if (err) + pr_err("Failed to enable clock %s: %d\n", + __clk_get_name(clk), err); + } +} |