提交 33c1f638 编写于 作者: L Linus Torvalds

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

Pull clk updates from Stephen Boyd:
 "The clk changes for this release cycle are mostly dominated by new
  device support in terms of LoC, but there has been some cleanup in the
  core as well as the usual minor clk additions to various drivers.

  Core:
   - parent tracking has been simplified
   - CLK_IS_ROOT is now a no-op flag, cleaning up drivers has started
   - of_clk_init() doesn't consider disabled DT nodes anymore
   - clk_unregister() had an error path bug squashed
   - of_clk_get_parent_count() has been fixed to only return unsigned ints
   - HAVE_MACH_CLKDEV is removed now that the last arch user (ARM) is gone

  New Drivers:
   - NXP LPC18xx creg
   - QCOM IPQ4019 GCC
   - TI dm814x ADPLL
   - i.MX6QP

  Updates:
   - Cyngus audio clks found on Broadcom iProc devices
   - Non-critical fixes for BCM2385 PLLs
   - Samsung exynos5433 updates for clk id errors, HDMI support,
     suspend/resume simplifications
   - USB, CAN, LVDS, and FCP clks on shmobile devices
   - sunxi got support for more clks on new SoCs and went through a
     minor refactoring/rewrite to use a simpler factor clk construct
   - rockchip added some more clk ids and added suport for fraction
     dividers
   - QCOM GDSCs in msm8996
   - A new devm helper to make adding custom actions simpler (acked by Greg)"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (197 commits)
  clk: bcm2835: fix check of error code returned by devm_ioremap_resource()
  clk: renesas: div6: use RENESAS for #define
  clk: renesas: Rename header file renesas.h
  clk: max77{686,802}: Remove CLK_IS_ROOT
  clk: versatile: Remove CLK_IS_ROOT
  clk: sunxi: Remove use of variable length array
  clk: fixed-rate: Remove CLK_IS_ROOT
  clk: qcom: Remove CLK_IS_ROOT
  doc: dt: add documentation for lpc1850-creg-clk driver
  clk: add lpc18xx creg clk driver
  clk: lpc32xx: fix compilation warning
  clk: xgene: Add missing parenthesis when clearing divider value
  clk: mb86s7x: Remove CLK_IS_ROOT
  clk: x86: Remove clkdev.h and clk.h includes
  clk: x86: Remove CLK_IS_ROOT
  clk: mvebu: Remove CLK_IS_ROOT
  clk: renesas: move drivers to renesas directory
  clk: si5{14,351,70}: Remove CLK_IS_ROOT
  clk: scpi: Remove CLK_IS_ROOT
  clk: s2mps11: Remove CLK_IS_ROOT
  ...
......@@ -8,7 +8,10 @@ Required properties:
- compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a".
- #clock-cells : from common clock binding; Should always be set to 0.
- reg : Address and length of the axi-clkgen register set.
- clocks : Phandle and clock specifier for the parent clock.
- clocks : Phandle and clock specifier for the parent clock(s). This must
either reference one clock if only the first clock input is connected or two
if both clock inputs are connected. For the later case the clock connected
to the first input must be specified first.
Optional properties:
- clock-output-names : From common clock binding.
......
......@@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are:
"brcm,cygnus-lcpll0"
"brcm,cygnus-mipipll"
"brcm,cygnus-asiu-clk"
"brcm,cygnus-audiopll"
The following table defines the set of PLL/clock index and ID for Cygnus.
These clock IDs are defined in:
......@@ -131,6 +132,11 @@ These clock IDs are defined in:
ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED
ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED
audiopll crystal 0 BCM_CYGNUS_AUDIOPLL
ch0_audio audiopll 1 BCM_CYGNUS_AUDIOPLL_CH0
ch1_audio audiopll 2 BCM_CYGNUS_AUDIOPLL_CH1
ch2_audio audiopll 3 BCM_CYGNUS_AUDIOPLL_CH2
Northstar and Northstar Plus
------
PLL and leaf clock compatible strings for Northstar and Northstar Plus are:
......
* NXP LPC1850 CREG clocks
The NXP LPC18xx/43xx CREG (Configuration Registers) block contains
control registers for two low speed clocks. One of the clocks is a
32 kHz oscillator driver with power up/down and clock gating. Next
is a fixed divider that creates a 1 kHz clock from the 32 kHz osc.
These clocks are used by the RTC and the Event Router peripherials.
The 32 kHz can also be routed to other peripherials to enable low
power modes.
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible:
Should be "nxp,lpc1850-creg-clk"
- #clock-cells:
Shall have value <1>.
- clocks:
Shall contain a phandle to the fixed 32 kHz crystal.
The creg-clk node must be a child of the creg syscon node.
The following clocks are available from the clock node.
Clock ID Name
0 1 kHz clock
1 32 kHz Oscillator
Example:
soc {
creg: syscon@40043000 {
compatible = "nxp,lpc1850-creg", "syscon", "simple-mfd";
reg = <0x40043000 0x1000>;
creg_clk: clock-controller {
compatible = "nxp,lpc1850-creg-clk";
clocks = <&xtal32>;
#clock-cells = <1>;
};
...
};
rtc: rtc@40046000 {
...
clocks = <&creg_clk 0>, <&ccu1 CLK_CPU_BUS>;
clock-names = "rtc", "reg";
...
};
};
......@@ -7,6 +7,7 @@ Required properties :
"qcom,gcc-apq8064"
"qcom,gcc-apq8084"
"qcom,gcc-ipq8064"
"qcom,gcc-ipq4019"
"qcom,gcc-msm8660"
"qcom,gcc-msm8916"
"qcom,gcc-msm8960"
......
......@@ -61,7 +61,7 @@ Examples
reg = <0 0xe6e88000 0 64>;
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 310>;
clock-names = "sci_ick";
clock-names = "fck";
dmas = <&dmac1 0x13>, <&dmac1 0x12>;
dma-names = "tx", "rx";
power-domains = <&cpg>;
......
......@@ -18,6 +18,7 @@ Required properties:
"allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock
"allwinner,sun4i-a10-axi-clk" - for the AXI clock
"allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23
"allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs
"allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
"allwinner,sun4i-a10-ahb-clk" - for the AHB clock
"allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
......@@ -39,12 +40,14 @@ Required properties:
"allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31
"allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23
"allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80
"allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T
"allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10
"allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13
"allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
"allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31
"allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
"allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23
"allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3
"allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80
"allwinner,sun4i-a10-apb1-clk" - for the APB1 clock
"allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80
......@@ -57,6 +60,7 @@ Required properties:
"allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
"allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T
"allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3
"allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80
"allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10
......
Binding for Texas Instruments ADPLL clock.
Binding status: Unstable - ABI compatibility may be broken in the future
This binding uses the common clock binding[1]. It assumes a
register-mapped ADPLL with two to three selectable input clocks
and three to four children.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be one of "ti,dm814-adpll-s-clock" or
"ti,dm814-adpll-lj-clock" depending on the type of the ADPLL
- #clock-cells : from common clock binding; shall be set to 1.
- clocks : link phandles of parent clocks clkinp and clkinpulow, note
that the adpll-s-clock also has an optional clkinphif
- reg : address and length of the register set for controlling the ADPLL.
Examples:
adpll_mpu_ck: adpll@40 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-s-clock";
reg = <0x40 0x40>;
clocks = <&devosc_ck &devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow", "clkinphif";
clock-output-names = "481c5040.adpll.dcoclkldo",
"481c5040.adpll.clkout",
"481c5040.adpll.clkoutx2",
"481c5040.adpll.clkouthif";
};
adpll_dsp_ck: adpll@80 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-lj-clock";
reg = <0x80 0x30>;
clocks = <&devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow";
clock-output-names = "481c5080.adpll.dcoclkldo",
"481c5080.adpll.clkout",
"481c5080.adpll.clkoutldo";
};
......@@ -416,7 +416,7 @@
status = "okay";
assigned-clocks = <&cru SCLK_USBPHY480M_SRC>;
assigned-clock-parents = <&cru SCLK_OTGPHY0>;
assigned-clock-parents = <&usbphy0>;
dr_mode = "host";
};
......
......@@ -32,6 +32,7 @@ config MACH_ARMADA_370
select CPU_PJ4B
select MACH_MVEBU_V7
select PINCTRL_ARMADA_370
select MVEBU_CLK_COREDIV
help
Say 'Y' here if you want your kernel to support boards based
on the Marvell Armada 370 SoC with device tree.
......@@ -49,6 +50,7 @@ config MACH_ARMADA_375
select HAVE_SMP
select MACH_MVEBU_V7
select PINCTRL_ARMADA_375
select MVEBU_CLK_COREDIV
help
Say 'Y' here if you want your kernel to support boards based
on the Marvell Armada 375 SoC with device tree.
......@@ -66,6 +68,7 @@ config MACH_ARMADA_38X
select HAVE_SMP
select MACH_MVEBU_V7
select PINCTRL_ARMADA_38X
select MVEBU_CLK_COREDIV
help
Say 'Y' here if you want your kernel to support boards based
on the Marvell Armada 380/385 SoC with device tree.
......
......@@ -12,7 +12,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/clk/shmobile.h>
#include <linux/clk/renesas.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/of.h>
......
......@@ -15,7 +15,7 @@
* GNU General Public License for more details.
*/
#include <linux/clk/shmobile.h>
#include <linux/clk/renesas.h>
#include <linux/io.h>
#include <linux/irqchip.h>
......
......@@ -14,7 +14,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/clk/shmobile.h>
#include <linux/clk/renesas.h>
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/irq.h>
......
......@@ -15,7 +15,7 @@
* GNU General Public License for more details.
*/
#include <linux/clk/shmobile.h>
#include <linux/clk/renesas.h>
#include <linux/clocksource.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
......
......@@ -328,7 +328,6 @@ config LANTIQ
select ARCH_REQUIRE_GPIOLIB
select SWAP_IO_SPACE
select BOOT_RAW
select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP
select USE_OF
select PINCTRL
......@@ -590,7 +589,6 @@ config RALINK
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MIPS16
select SYS_HAS_EARLY_PRINTK
select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP
select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER
......
......@@ -15,7 +15,6 @@ config PIC32MZDA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select ARCH_REQUIRE_GPIOLIB
select HAVE_MACH_CLKDEV
select COMMON_CLK
select CLKDEV_LOOKUP
select LIBFDT
......
......@@ -6,9 +6,6 @@ config CLKDEV_LOOKUP
config HAVE_CLK_PREPARE
bool
config HAVE_MACH_CLKDEV
bool
config COMMON_CLK
bool
select HAVE_CLK_PREPARE
......@@ -99,6 +96,14 @@ config COMMON_CLK_SI570
This driver supports Silicon Labs 570/571/598/599 programmable
clock generators.
config COMMON_CLK_CDCE706
tristate "Clock driver for TI CDCE706 clock synthesizer"
depends on I2C
select REGMAP_I2C
select RATIONAL
---help---
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
config COMMON_CLK_CDCE925
tristate "Clock driver for TI CDCE925 devices"
depends on I2C
......@@ -190,15 +195,7 @@ config COMMON_CLK_PWM
config COMMON_CLK_PXA
def_bool COMMON_CLK && ARCH_PXA
---help---
Sypport for the Marvell PXA SoC.
config COMMON_CLK_CDCE706
tristate "Clock driver for TI CDCE706 clock synthesizer"
depends on I2C
select REGMAP_I2C
select RATIONAL
---help---
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
Support for the Marvell PXA SoC.
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
......@@ -206,5 +203,6 @@ source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/samsung/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
endmenu
......@@ -70,15 +70,14 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/
obj-$(CONFIG_ARCH_RENESAS) += shmobile/
obj-$(CONFIG_ARCH_RENESAS) += renesas/
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_STI) += st/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
obj-y += ti/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_X86) += x86/
......
......@@ -273,14 +273,14 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np)
u32 id;
const char *name;
struct clk *clk;
int num_parents;
unsigned int num_parents;
const char *parent_names[GENERATED_SOURCE_MAX];
struct device_node *gcknp;
struct clk_range range = CLK_RANGE(0, 0);
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -291,7 +291,7 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
init.ops = &main_rc_osc_ops;
init.parent_names = NULL;
init.num_parents = 0;
init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
init.flags = CLK_IGNORE_UNUSED;
osc->hw.init = &init;
osc->regmap = regmap;
......@@ -572,12 +572,12 @@ static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
{
struct clk *clk;
const char *parent_names[2];
int num_parents;
unsigned int num_parents;
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > 2)
if (num_parents == 0 || num_parents > 2)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -199,14 +199,14 @@ of_at91_clk_master_setup(struct device_node *np,
const struct clk_master_layout *layout)
{
struct clk *clk;
int num_parents;
unsigned int num_parents;
const char *parent_names[MASTER_SOURCE_MAX];
const char *name = np->name;
struct clk_master_characteristics *characteristics;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -230,14 +230,14 @@ of_at91_clk_prog_setup(struct device_node *np,
int num;
u32 id;
struct clk *clk;
int num_parents;
unsigned int num_parents;
const char *parent_names[PROG_SOURCE_MAX];
const char *name;
struct device_node *progclknp;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -245,7 +245,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
init.ops = &slow_rc_osc_ops;
init.parent_names = NULL;
init.num_parents = 0;
init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
init.flags = CLK_IGNORE_UNUSED;
osc->hw.init = &init;
osc->sckcr = sckcr;
......@@ -360,11 +360,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
{
struct clk *clk;
const char *parent_names[2];
int num_parents;
unsigned int num_parents;
const char *name = np->name;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > 2)
if (num_parents == 0 || num_parents > 2)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......@@ -433,7 +433,7 @@ static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
{
struct clk *clk;
const char *parent_names[2];
int num_parents;
unsigned int num_parents;
const char *name = np->name;
struct regmap *regmap;
......
......@@ -142,13 +142,13 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
{
struct clk *clk;
int num_parents;
unsigned int num_parents;
const char *parent_names[SMD_SOURCE_MAX];
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX)
if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -366,13 +366,13 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
{
struct clk *clk;
int num_parents;
unsigned int num_parents;
const char *parent_names[USB_SOURCE_MAX];
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
......
......@@ -38,8 +38,8 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(dev, res);
if (!reg)
return -ENODEV;
if (IS_ERR(reg))
return PTR_ERR(reg);
onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
if (!onecell)
......
......@@ -88,10 +88,23 @@
#define CM_HSMDIV 0x08c
#define CM_OTPCTL 0x090
#define CM_OTPDIV 0x094
#define CM_PCMCTL 0x098
#define CM_PCMDIV 0x09c
#define CM_PWMCTL 0x0a0
#define CM_PWMDIV 0x0a4
#define CM_SLIMCTL 0x0a8
#define CM_SLIMDIV 0x0ac
#define CM_SMICTL 0x0b0
#define CM_SMIDIV 0x0b4
/* no definition for 0x0b8 and 0x0bc */
#define CM_TCNTCTL 0x0c0
#define CM_TCNTDIV 0x0c4
#define CM_TECCTL 0x0c8
#define CM_TECDIV 0x0cc
#define CM_TD0CTL 0x0d0
#define CM_TD0DIV 0x0d4
#define CM_TD1CTL 0x0d8
#define CM_TD1DIV 0x0dc
#define CM_TSENSCTL 0x0e0
#define CM_TSENSDIV 0x0e4
#define CM_TIMERCTL 0x0e8
......@@ -311,21 +324,18 @@ void __init bcm2835_init_clocks(void)
struct clk *clk;
int ret;
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
126000000);
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
if (IS_ERR(clk))
pr_err("apb_pclk not registered\n");
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
3000000);
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
if (IS_ERR(clk))
pr_err("uart0_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
if (ret)
pr_err("uart0_pclk alias not registered\n");
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
125000000);
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
if (IS_ERR(clk))
pr_err("uart1_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
......@@ -1060,16 +1070,7 @@ static long bcm2835_pll_divider_round_rate(struct clk_hw *hw,
static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
struct bcm2835_cprman *cprman = divider->cprman;
const struct bcm2835_pll_divider_data *data = divider->data;
u32 div = cprman_read(cprman, data->a2w_reg);
div &= (1 << A2W_PLL_DIV_BITS) - 1;
if (div == 0)
div = 256;
return parent_rate / div;
return clk_divider_ops.recalc_rate(hw, parent_rate);
}
static void bcm2835_pll_divider_off(struct clk_hw *hw)
......@@ -1107,13 +1108,15 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
struct bcm2835_cprman *cprman = divider->cprman;
const struct bcm2835_pll_divider_data *data = divider->data;
u32 cm;
int ret;
u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS;
ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
if (ret)
return ret;
div = DIV_ROUND_UP_ULL(parent_rate, rate);
div = min(div, max_div);
if (div == max_div)
div = 0;
cprman_write(cprman, data->a2w_reg, div);
cm = cprman_read(cprman, data->cm_reg);
cprman_write(cprman, data->cm_reg, cm | data->load_mask);
cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
......@@ -1428,7 +1431,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
divider->div.reg = cprman->regs + data->a2w_reg;
divider->div.shift = A2W_PLL_DIV_SHIFT;
divider->div.width = A2W_PLL_DIV_BITS;
divider->div.flags = 0;
divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO;
divider->div.lock = &cprman->regs_lock;
divider->div.hw.init = &init;
divider->div.table = NULL;
......
......@@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node)
iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div));
}
CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init);
/*
* AUDIO PLL VCO frequency parameter table
*
* PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) *
* (parent clock rate / pdiv)
*
* On Cygnus, parent is the 25MHz oscillator
*/
static const struct iproc_pll_vco_param audiopll_vco_params[] = {
/* rate (Hz) ndiv_int ndiv_frac pdiv */
{ 1354750204UL, 54, 199238, 1 },
{ 1769470191UL, 70, 816639, 1 },
};
static const struct iproc_pll_ctrl audiopll = {
.flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC |
IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW,
.reset = RESET_VAL(0x5c, 0, 1),
.dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3),
.sw_ctrl = SW_CTRL_VAL(0x4, 0),
.ndiv_int = REG_VAL(0x8, 0, 10),
.ndiv_frac = REG_VAL(0x8, 10, 20),
.pdiv = REG_VAL(0x44, 0, 4),
.vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10),
.status = REG_VAL(0x54, 0, 1),
.macro_mode = REG_VAL(0x0, 0, 3),
};
static const struct iproc_clk_ctrl audiopll_clk[] = {
[BCM_CYGNUS_AUDIOPLL_CH0] = {
.channel = BCM_CYGNUS_AUDIOPLL_CH0,
.flags = IPROC_CLK_AON |
IPROC_CLK_MCLK_DIV_BY_2,
.enable = ENABLE_VAL(0x14, 8, 10, 9),
.mdiv = REG_VAL(0x14, 0, 8),
},
[BCM_CYGNUS_AUDIOPLL_CH1] = {
.channel = BCM_CYGNUS_AUDIOPLL_CH1,
.flags = IPROC_CLK_AON,
.enable = ENABLE_VAL(0x18, 8, 10, 9),
.mdiv = REG_VAL(0x18, 0, 8),
},
[BCM_CYGNUS_AUDIOPLL_CH2] = {
.channel = BCM_CYGNUS_AUDIOPLL_CH2,
.flags = IPROC_CLK_AON,
.enable = ENABLE_VAL(0x1c, 8, 10, 9),
.mdiv = REG_VAL(0x1c, 0, 8),
},
};
static void __init cygnus_audiopll_clk_init(struct device_node *node)
{
iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params,
ARRAY_SIZE(audiopll_vco_params), audiopll_clk,
ARRAY_SIZE(audiopll_clk));
}
CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll",
cygnus_audiopll_clk_init);
......@@ -25,6 +25,12 @@
#define PLL_VCO_HIGH_SHIFT 19
#define PLL_VCO_LOW_SHIFT 30
/*
* PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies
* from a look-up table. Mode 7 allows user to manipulate PLL clock dividers
*/
#define PLL_USER_MODE 7
/* number of delay loops waiting for PLL to lock */
#define LOCK_DELAY 100
......@@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll)
const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
val = readl(pll->control_base + reset->offset);
val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift);
if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
else
val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
iproc_pll_write(pll, pll->control_base, reset->offset, val);
}
......@@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
val = readl(pll->control_base + reset->offset);
val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift;
if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
else
val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
iproc_pll_write(pll, pll->control_base, reset->offset, val);
}
......@@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
/* put PLL in reset */
__pll_put_in_reset(pll);
/* set PLL in user mode before modifying PLL controls */
if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) {
val = readl(pll->control_base + ctrl->macro_mode.offset);
val &= ~(bit_mask(ctrl->macro_mode.width) <<
ctrl->macro_mode.shift);
val |= PLL_USER_MODE << ctrl->macro_mode.shift;
iproc_pll_write(pll, pll->control_base,
ctrl->macro_mode.offset, val);
}
iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
......@@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
if (mdiv == 0)
mdiv = 256;
clk->rate = parent_rate / mdiv;
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
clk->rate = parent_rate / (mdiv * 2);
else
clk->rate = parent_rate / mdiv;
return clk->rate;
}
......@@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
if (rate == 0 || parent_rate == 0)
return -EINVAL;
div = DIV_ROUND_UP(parent_rate, rate);
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
div = DIV_ROUND_UP(parent_rate, rate * 2);
else
div = DIV_ROUND_UP(parent_rate, rate);
if (div > 256)
return -EINVAL;
......@@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
val |= div << ctrl->mdiv.shift;
}
iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
clk->rate = parent_rate / div;
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
clk->rate = parent_rate / (div * 2);
else
clk->rate = parent_rate / div;
return 0;
}
......
......@@ -60,6 +60,26 @@
*/
#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
/*
* Some PLLs have an additional divide by 2 in master clock calculation;
* MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
* of modified calculations
*/
#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
/*
* Some PLLs provide a look up table for the leaf clock frequencies and
* auto calculates VCO frequency parameters based on the provided leaf
* clock frequencies. They have a user mode that allows the divider
* controls to be determined by the user
*/
#define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
/*
* Some PLLs have an active low reset
*/
#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
/*
* Parameters for VCO frequency configuration
*
......@@ -149,6 +169,7 @@ struct iproc_pll_ctrl {
struct iproc_clk_reg_op pdiv;
struct iproc_pll_vco_ctrl vco_ctrl;
struct iproc_clk_reg_op status;
struct iproc_clk_reg_op macro_mode;
};
/*
......@@ -183,16 +204,16 @@ struct iproc_asiu_div {
unsigned int low_width;
};
void __init iproc_armpll_setup(struct device_node *node);
void __init iproc_pll_clk_setup(struct device_node *node,
const struct iproc_pll_ctrl *pll_ctrl,
const struct iproc_pll_vco_param *vco,
unsigned int num_vco_entries,
const struct iproc_clk_ctrl *clk_ctrl,
unsigned int num_clks);
void __init iproc_asiu_setup(struct device_node *node,
const struct iproc_asiu_div *div,
const struct iproc_asiu_gate *gate,
unsigned int num_clks);
void iproc_armpll_setup(struct device_node *node);
void iproc_pll_clk_setup(struct device_node *node,
const struct iproc_pll_ctrl *pll_ctrl,
const struct iproc_pll_vco_param *vco,
unsigned int num_vco_entries,
const struct iproc_clk_ctrl *clk_ctrl,
unsigned int num_clks);
void iproc_asiu_setup(struct device_node *node,
const struct iproc_asiu_div *div,
const struct iproc_asiu_gate *gate,
unsigned int num_clks);
#endif /* _CLK_IPROC_H */
......@@ -16,19 +16,8 @@
#include <linux/module.h>
#include <linux/err.h>
#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04
#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08
#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c
#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10
#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14
#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18
#define AXI_CLKGEN_V1_REG_LOCK1 0x1c
#define AXI_CLKGEN_V1_REG_LOCK2 0x20
#define AXI_CLKGEN_V1_REG_LOCK3 0x24
#define AXI_CLKGEN_V1_REG_FILTER1 0x28
#define AXI_CLKGEN_V1_REG_FILTER2 0x2c
#define AXI_CLKGEN_V2_REG_RESET 0x40
#define AXI_CLKGEN_V2_REG_CLKSEL 0x44
#define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70
#define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74
......@@ -51,40 +40,11 @@
#define MMCM_REG_FILTER1 0x4e
#define MMCM_REG_FILTER2 0x4f
struct axi_clkgen;
struct axi_clkgen_mmcm_ops {
void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
unsigned int val, unsigned int mask);
int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
unsigned int *val);
};
struct axi_clkgen {
void __iomem *base;
const struct axi_clkgen_mmcm_ops *mmcm_ops;
struct clk_hw clk_hw;
};
static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
bool enable)
{
axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
}
static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int val, unsigned int mask)
{
return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
}
static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int *val)
{
return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
}
static uint32_t axi_clkgen_lookup_filter(unsigned int m)
{
switch (m) {
......@@ -207,70 +167,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
*val = readl(axi_clkgen->base + reg);
}
static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
{
switch (reg) {
case MMCM_REG_CLKOUT0_1:
return AXI_CLKGEN_V1_REG_CLK_OUT1;
case MMCM_REG_CLKOUT0_2:
return AXI_CLKGEN_V1_REG_CLK_OUT2;
case MMCM_REG_CLK_FB1:
return AXI_CLKGEN_V1_REG_CLK_FB1;
case MMCM_REG_CLK_FB2:
return AXI_CLKGEN_V1_REG_CLK_FB2;
case MMCM_REG_CLK_DIV:
return AXI_CLKGEN_V1_REG_CLK_DIV;
case MMCM_REG_LOCK1:
return AXI_CLKGEN_V1_REG_LOCK1;
case MMCM_REG_LOCK2:
return AXI_CLKGEN_V1_REG_LOCK2;
case MMCM_REG_LOCK3:
return AXI_CLKGEN_V1_REG_LOCK3;
case MMCM_REG_FILTER1:
return AXI_CLKGEN_V1_REG_FILTER1;
case MMCM_REG_FILTER2:
return AXI_CLKGEN_V1_REG_FILTER2;
default:
return 0;
}
}
static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int val, unsigned int mask)
{
reg = axi_clkgen_v1_map_mmcm_reg(reg);
if (reg == 0)
return -EINVAL;
axi_clkgen_write(axi_clkgen, reg, val);
return 0;
}
static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int *val)
{
reg = axi_clkgen_v1_map_mmcm_reg(reg);
if (reg == 0)
return -EINVAL;
axi_clkgen_read(axi_clkgen, reg, val);
return 0;
}
static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
bool enable)
{
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
}
static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
.write = axi_clkgen_v1_mmcm_write,
.read = axi_clkgen_v1_mmcm_read,
.enable = axi_clkgen_v1_mmcm_enable,
};
static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
{
unsigned int timeout = 10000;
......@@ -286,7 +182,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
return val & 0xffff;
}
static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int *val)
{
unsigned int reg_val;
......@@ -310,7 +206,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
return 0;
}
static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
unsigned int reg, unsigned int val, unsigned int mask)
{
unsigned int reg_val = 0;
......@@ -321,7 +217,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
return ret;
if (mask != 0xffff) {
axi_clkgen_v2_mmcm_read(axi_clkgen, reg, &reg_val);
axi_clkgen_mmcm_read(axi_clkgen, reg, &reg_val);
reg_val &= ~mask;
}
......@@ -332,7 +228,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
return 0;
}
static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
bool enable)
{
unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
......@@ -343,12 +239,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
}
static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
.write = axi_clkgen_v2_mmcm_write,
.read = axi_clkgen_v2_mmcm_read,
.enable = axi_clkgen_v2_mmcm_enable,
};
static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
{
return container_of(clk_hw, struct axi_clkgen, clk_hw);
......@@ -438,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
tmp = (unsigned long long)(parent_rate / d) * m;
do_div(tmp, dout);
if (tmp > ULONG_MAX)
return ULONG_MAX;
return tmp;
return min_t(unsigned long long, tmp, ULONG_MAX);
}
static int axi_clkgen_enable(struct clk_hw *clk_hw)
......@@ -460,21 +347,38 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw)
axi_clkgen_mmcm_enable(axi_clkgen, false);
}
static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index)
{
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index);
return 0;
}
static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw)
{
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
unsigned int parent;
axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent);
return parent;
}
static const struct clk_ops axi_clkgen_ops = {
.recalc_rate = axi_clkgen_recalc_rate,
.round_rate = axi_clkgen_round_rate,
.set_rate = axi_clkgen_set_rate,
.enable = axi_clkgen_enable,
.disable = axi_clkgen_disable,
.set_parent = axi_clkgen_set_parent,
.get_parent = axi_clkgen_get_parent,
};
static const struct of_device_id axi_clkgen_ids[] = {
{
.compatible = "adi,axi-clkgen-1.00.a",
.data = &axi_clkgen_v1_mmcm_ops
}, {
.compatible = "adi,axi-clkgen-2.00.a",
.data = &axi_clkgen_v2_mmcm_ops,
},
{ },
};
......@@ -485,10 +389,11 @@ static int axi_clkgen_probe(struct platform_device *pdev)
const struct of_device_id *id;
struct axi_clkgen *axi_clkgen;
struct clk_init_data init;
const char *parent_name;
const char *parent_names[2];
const char *clk_name;
struct resource *mem;
struct clk *clk;
unsigned int i;
if (!pdev->dev.of_node)
return -ENODEV;
......@@ -501,26 +406,29 @@ static int axi_clkgen_probe(struct platform_device *pdev)
if (!axi_clkgen)
return -ENOMEM;
axi_clkgen->mmcm_ops = id->data;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(axi_clkgen->base))
return PTR_ERR(axi_clkgen->base);
parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
if (!parent_name)
init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
if (init.num_parents < 1 || init.num_parents > 2)
return -EINVAL;
for (i = 0; i < init.num_parents; i++) {
parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
if (!parent_names[i])
return -EINVAL;
}
clk_name = pdev->dev.of_node->name;
of_property_read_string(pdev->dev.of_node, "clock-output-names",
&clk_name);
init.name = clk_name;
init.ops = &axi_clkgen_ops;
init.flags = CLK_SET_RATE_GATE;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
init.parent_names = parent_names;
axi_clkgen_mmcm_enable(axi_clkgen, false);
......
......@@ -303,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
*/
maxdiv = min(ULONG_MAX / rate, maxdiv);
for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) {
if (!_is_valid_div(table, i, flags))
continue;
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
......
......@@ -36,7 +36,7 @@ static void __init efm32gg_cmu_init(struct device_node *np)
}
clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL,
CLK_IS_ROOT, 48000000);
0, 48000000);
clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0",
"HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
......
......@@ -100,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
}
EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
void clk_unregister_fixed_factor(struct clk *clk)
{
struct clk_hw *hw;
hw = __clk_get_hw(clk);
if (!hw)
return;
clk_unregister(clk);
kfree(to_clk_fixed_factor(hw));
}
EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
#ifdef CONFIG_OF
/**
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
......
......@@ -104,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
}
EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
void clk_unregister_fixed_rate(struct clk *clk)
{
struct clk_hw *hw;
hw = __clk_get_hw(clk);
if (!hw)
return;
clk_unregister(clk);
kfree(to_clk_fixed_rate(hw));
}
EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate);
#ifdef CONFIG_OF
/**
* of_fixed_clk_setup() - Setup function for simple fixed rate clock
......@@ -123,8 +136,7 @@ void of_fixed_clk_setup(struct device_node *node)
of_property_read_string(node, "clock-output-names", &clk_name);
clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
CLK_IS_ROOT, rate,
accuracy);
0, rate, accuracy);
if (!IS_ERR(clk))
of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
......
......@@ -20,6 +20,8 @@
#include <linux/of_gpio.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
/**
* DOC: basic gpio gated clock which can be enabled and disabled
......@@ -199,134 +201,69 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
}
EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
#ifdef CONFIG_OF
/**
* clk_register_get() has to be delayed, because -EPROBE_DEFER
* can not be handled properly at of_clk_init() call time.
*/
struct clk_gpio_delayed_register_data {
const char *gpio_name;
int num_parents;
const char **parent_names;
struct device_node *node;
struct mutex lock;
struct clk *clk;
struct clk *(*clk_register_get)(const char *name,
const char * const *parent_names, u8 num_parents,
unsigned gpio, bool active_low);
};
static struct clk *of_clk_gpio_delayed_register_get(
struct of_phandle_args *clkspec, void *_data)
static int gpio_clk_driver_probe(struct platform_device *pdev)
{
struct clk_gpio_delayed_register_data *data = _data;
struct clk *clk;
struct device_node *node = pdev->dev.of_node;
const char **parent_names, *gpio_name;
unsigned int num_parents;
int gpio;
enum of_gpio_flags of_flags;
struct clk *clk;
bool active_low, is_mux;
mutex_lock(&data->lock);
num_parents = of_clk_get_parent_count(node);
if (num_parents) {
parent_names = devm_kcalloc(&pdev->dev, num_parents,
sizeof(char *), GFP_KERNEL);
if (!parent_names)
return -ENOMEM;
if (data->clk) {
mutex_unlock(&data->lock);
return data->clk;
of_clk_parent_fill(node, parent_names, num_parents);
} else {
parent_names = NULL;
}
gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0,
&of_flags);
is_mux = of_device_is_compatible(node, "gpio-mux-clock");
gpio_name = is_mux ? "select-gpios" : "enable-gpios";
gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags);
if (gpio < 0) {
mutex_unlock(&data->lock);
if (gpio == -EPROBE_DEFER)
pr_debug("%s: %s: GPIOs not yet available, retry later\n",
data->node->name, __func__);
node->name, __func__);
else
pr_err("%s: %s: Can't get '%s' DT property\n",
data->node->name, __func__,
data->gpio_name);
return ERR_PTR(gpio);
node->name, __func__,
gpio_name);
return gpio;
}
clk = data->clk_register_get(data->node->name, data->parent_names,
data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
if (IS_ERR(clk))
goto out;
data->clk = clk;
out:
mutex_unlock(&data->lock);
active_low = of_flags & OF_GPIO_ACTIVE_LOW;
return clk;
}
static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name,
const char * const *parent_names, u8 num_parents,
unsigned gpio, bool active_low)
{
return clk_register_gpio_gate(NULL, name, parent_names ?
parent_names[0] : NULL, gpio, active_low, 0);
}
static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low)
{
return clk_register_gpio_mux(NULL, name, parent_names, num_parents,
gpio, active_low, 0);
}
static void __init of_gpio_clk_setup(struct device_node *node,
const char *gpio_name,
struct clk *(*clk_register_get)(const char *name,
const char * const *parent_names,
u8 num_parents,
unsigned gpio, bool active_low))
{
struct clk_gpio_delayed_register_data *data;
const char **parent_names;
int i, num_parents;
num_parents = of_clk_get_parent_count(node);
if (num_parents < 0)
num_parents = 0;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return;
if (num_parents) {
parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
if (!parent_names) {
kfree(data);
return;
}
for (i = 0; i < num_parents; i++)
parent_names[i] = of_clk_get_parent_name(node, i);
} else {
parent_names = NULL;
}
data->num_parents = num_parents;
data->parent_names = parent_names;
data->node = node;
data->gpio_name = gpio_name;
data->clk_register_get = clk_register_get;
mutex_init(&data->lock);
if (is_mux)
clk = clk_register_gpio_mux(&pdev->dev, node->name,
parent_names, num_parents, gpio, active_low, 0);
else
clk = clk_register_gpio_gate(&pdev->dev, node->name,
parent_names ? parent_names[0] : NULL, gpio,
active_low, 0);
if (IS_ERR(clk))
return PTR_ERR(clk);
of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data);
return of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
static void __init of_gpio_gate_clk_setup(struct device_node *node)
{
of_gpio_clk_setup(node, "enable-gpios",
of_clk_gpio_gate_delayed_register_get);
}
CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup);
static const struct of_device_id gpio_clk_match_table[] = {
{ .compatible = "gpio-mux-clock" },
{ .compatible = "gpio-gate-clock" },
{ }
};
void __init of_gpio_mux_clk_setup(struct device_node *node)
{
of_gpio_clk_setup(node, "select-gpios",
of_clk_gpio_mux_delayed_register_get);
}
CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup);
#endif
static struct platform_driver gpio_clk_driver = {
.probe = gpio_clk_driver_probe,
.driver = {
.name = "gpio-clk",
.of_match_table = gpio_clk_match_table,
},
};
builtin_platform_driver(gpio_clk_driver);
......@@ -38,17 +38,14 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
[MAX77686_CLK_AP] = {
.name = "32khz_ap",
.ops = &max_gen_clk_ops,
.flags = CLK_IS_ROOT,
},
[MAX77686_CLK_CP] = {
.name = "32khz_cp",
.ops = &max_gen_clk_ops,
.flags = CLK_IS_ROOT,
},
[MAX77686_CLK_PMIC] = {
.name = "32khz_pmic",
.ops = &max_gen_clk_ops,
.flags = CLK_IS_ROOT,
},
};
......
......@@ -39,12 +39,10 @@ static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = {
[MAX77802_CLK_32K_AP] = {
.name = "32khz_ap",
.ops = &max_gen_clk_ops,
.flags = CLK_IS_ROOT,
},
[MAX77802_CLK_32K_CP] = {
.name = "32khz_cp",
.ops = &max_gen_clk_ops,
.flags = CLK_IS_ROOT,
},
};
......
......@@ -217,7 +217,7 @@ static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
init.name = clkp;
init.num_parents = 0;
init.ops = &crg_port_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
crgclk->hw.init = &init;
crgclk->cntrlr = cntrlr;
crgclk->domain = domain;
......@@ -341,7 +341,7 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
init.name = dev_name(cpu_dev);
init.ops = &clk_clc_ops;
init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
init.flags = CLK_GET_RATE_NOCACHE;
init.num_parents = 0;
return devm_clk_register(cpu_dev, &clc->hw);
......
......@@ -44,7 +44,7 @@ struct palmas_clock_info {
struct clk *clk;
struct clk_hw hw;
struct palmas *palmas;
struct palmas_clk32k_desc *clk_desc;
const struct palmas_clk32k_desc *clk_desc;
int ext_control_pin;
};
......@@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = {
struct palmas_clks_of_match_data {
struct clk_init_data init;
struct palmas_clk32k_desc desc;
const struct palmas_clk32k_desc desc;
};
static struct palmas_clks_of_match_data palmas_of_clk32kg = {
static const struct palmas_clks_of_match_data palmas_of_clk32kg = {
.init = {
.name = "clk32kg",
.ops = &palmas_clks_ops,
......@@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = {
},
};
static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
.init = {
.name = "clk32kgaudio",
.ops = &palmas_clks_ops,
......@@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev)
{
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
struct device_node *node = pdev->dev.of_node;
struct palmas_clks_of_match_data *match_data;
const struct of_device_id *match;
const struct palmas_clks_of_match_data *match_data;
struct palmas_clock_info *cinfo;
struct clk *clk;
int ret;
match = of_match_device(palmas_clks_of_match, &pdev->dev);
match_data = (struct palmas_clks_of_match_data *)match->data;
match_data = of_device_get_match_data(&pdev->dev);
if (!match_data)
return 1;
cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL);
if (!cinfo)
......
......@@ -95,7 +95,7 @@ static int clk_pwm_probe(struct platform_device *pdev)
init.name = clk_name;
init.ops = &clk_pwm_ops;
init.flags = CLK_IS_BASIC | CLK_IS_ROOT;
init.flags = CLK_IS_BASIC;
init.num_parents = 0;
clk_pwm->pwm = pwm;
......
......@@ -99,17 +99,14 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
[S2MPS11_CLK_AP] = {
.name = "s2mps11_ap",
.ops = &s2mps11_clk_ops,
.flags = CLK_IS_ROOT,
},
[S2MPS11_CLK_CP] = {
.name = "s2mps11_cp",
.ops = &s2mps11_clk_ops,
.flags = CLK_IS_ROOT,
},
[S2MPS11_CLK_BT] = {
.name = "s2mps11_bt",
.ops = &s2mps11_clk_ops,
.flags = CLK_IS_ROOT,
},
};
......
......@@ -155,7 +155,7 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
unsigned long min = 0, max = 0;
init.name = name;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.num_parents = 0;
init.ops = match->data;
sclk->hw.init = &init;
......
......@@ -313,7 +313,7 @@ static int si514_probe(struct i2c_client *client,
return -ENOMEM;
init.ops = &si514_clk_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.num_parents = 0;
data->hw.init = &init;
data->i2c_client = client;
......
......@@ -1495,7 +1495,7 @@ static int si5351_i2c_probe(struct i2c_client *client,
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.parent_names = NULL;
init.num_parents = 0;
} else {
......
......@@ -418,7 +418,7 @@ static int si570_probe(struct i2c_client *client,
return -ENOMEM;
init.ops = &si570_clk_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.num_parents = 0;
data->hw.init = &init;
data->i2c_client = client;
......
......@@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
#define WM8850_BITS_TO_VAL(m, d1, d2) \
((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)
static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
u32 *multiplier, u32 *prediv)
{
unsigned long tclk;
......@@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
pr_err("%s: requested rate out of range\n", __func__);
*multiplier = 0;
*prediv = 1;
return;
return -EINVAL;
}
if (rate <= parent_rate * 31)
/* use the prediv to double the resolution */
......@@ -379,12 +379,15 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
if (tclk != rate)
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__,
rate, tclk);
return 0;
}
static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
u32 *multiplier, u32 *divisor1, u32 *divisor2)
{
u32 mul, div1, div2;
u32 mul, div1;
int div2;
u32 best_mul, best_div1, best_div2;
unsigned long tclk, rate_err, best_err;
......@@ -403,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*multiplier = mul;
*divisor1 = div1;
*divisor2 = div2;
return;
return 0;
}
if (rate_err < best_err) {
......@@ -414,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
}
}
if (best_err == (unsigned long)-1) {
pr_warn("%s: impossible rate %lu\n", __func__, rate);
return -EINVAL;
}
/* if we got here, it wasn't an exact match */
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
rate - best_err);
*multiplier = best_mul;
*divisor1 = best_div1;
*divisor2 = best_div2;
return 0;
}
static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
......@@ -449,10 +459,11 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
return 0;
}
static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2)
{
u32 mul, div1, div2;
u32 mul;
int div1, div2;
u32 best_mul, best_div1, best_div2;
unsigned long tclk, rate_err, best_err;
......@@ -472,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*multiplier = mul;
*divisor1 = div1;
*divisor2 = div2;
return;
return 0;
}
if (rate_err < best_err) {
......@@ -483,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
}
}
if (best_err == (unsigned long)-1) {
pr_warn("%s: impossible rate %lu\n", __func__, rate);
return -EINVAL;
}
/* if we got here, it wasn't an exact match */
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
rate - best_err);
......@@ -491,12 +507,15 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*multiplier = best_mul;
*divisor1 = best_div1;
*divisor2 = best_div2;
return 0;
}
static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
u32 *multiplier, u32 *divisor1, u32 *divisor2)
{
u32 mul, div1, div2;
u32 mul;
int div1, div2;
u32 best_mul, best_div1, best_div2;
unsigned long tclk, rate_err, best_err;
......@@ -516,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*multiplier = mul;
*divisor1 = div1;
*divisor2 = div2;
return;
return 0;
}
if (rate_err < best_err) {
......@@ -527,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
}
}
if (best_err == (unsigned long)-1) {
pr_warn("%s: impossible rate %lu\n", __func__, rate);
return -EINVAL;
}
/* if we got here, it wasn't an exact match */
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
rate - best_err);
......@@ -534,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*multiplier = best_mul;
*divisor1 = best_div1;
*divisor2 = best_div2;
return 0;
}
static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
......@@ -543,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
u32 filter, mul, div1, div2;
u32 pll_val;
unsigned long flags = 0;
int ret;
/* sanity check */
switch (pll->type) {
case PLL_TYPE_VT8500:
vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
pll_val = VT8500_BITS_TO_VAL(mul, div1);
ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
if (!ret)
pll_val = VT8500_BITS_TO_VAL(mul, div1);
break;
case PLL_TYPE_WM8650:
wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
if (!ret)
pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
break;
case PLL_TYPE_WM8750:
wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
if (!ret)
pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
break;
case PLL_TYPE_WM8850:
wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
if (!ret)
pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
break;
default:
pr_err("%s: invalid pll type\n", __func__);
return 0;
ret = -EINVAL;
}
if (ret)
return ret;
spin_lock_irqsave(pll->lock, flags);
vt8500_pmc_wait_busy();
......@@ -585,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
struct clk_pll *pll = to_clk_pll(hw);
u32 filter, mul, div1, div2;
long round_rate;
int ret;
switch (pll->type) {
case PLL_TYPE_VT8500:
vt8500_find_pll_bits(rate, *prate, &mul, &div1);
round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1);
if (!ret)
round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
break;
case PLL_TYPE_WM8650:
wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
if (!ret)
round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
case PLL_TYPE_WM8750:
wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
if (!ret)
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
case PLL_TYPE_WM8850:
wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
if (!ret)
round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
default:
round_rate = 0;
ret = -EINVAL;
}
if (ret)
return ret;
return round_rate;
}
......
......@@ -376,8 +376,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
/* Set new divider */
data = xgene_clk_read(pclk->param.divider_reg +
pclk->param.reg_divider_offset);
data &= ~((1 << pclk->param.reg_divider_width) - 1)
<< pclk->param.reg_divider_shift;
data &= ~(((1 << pclk->param.reg_divider_width) - 1)
<< pclk->param.reg_divider_shift);
data |= divider;
xgene_clk_write(data, pclk->param.divider_reg +
pclk->param.reg_divider_offset);
......
......@@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
{
if (!core || index >= core->num_parents)
return NULL;
else if (!core->parents)
return clk_core_lookup(core->parent_names[index]);
else if (!core->parents[index])
return core->parents[index] =
clk_core_lookup(core->parent_names[index]);
else
return core->parents[index];
if (!core->parents[index])
core->parents[index] =
clk_core_lookup(core->parent_names[index]);
return core->parents[index];
}
struct clk_hw *
......@@ -386,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
ret = core->rate;
if (core->flags & CLK_IS_ROOT)
if (!core->num_parents)
goto out;
if (!core->parent)
......@@ -1067,30 +1066,12 @@ static int clk_fetch_parent_index(struct clk_core *core,
{
int i;
if (!core->parents) {
core->parents = kcalloc(core->num_parents,
sizeof(struct clk *), GFP_KERNEL);
if (!core->parents)
return -ENOMEM;
}
/*
* find index of new parent clock using cached parent ptrs,
* or if not yet cached, use string name comparison and cache
* them now to avoid future calls to clk_core_lookup.
*/
for (i = 0; i < core->num_parents; i++) {
if (core->parents[i] == parent)
return i;
if (core->parents[i])
continue;
if (!parent)
return -EINVAL;
if (!strcmp(core->parent_names[i], parent->name)) {
core->parents[i] = clk_core_lookup(parent->name);
for (i = 0; i < core->num_parents; i++)
if (clk_core_get_parent_by_index(core, i) == parent)
return i;
}
}
return -EINVAL;
}
......@@ -1677,56 +1658,14 @@ struct clk *clk_get_parent(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_get_parent);
/*
* .get_parent is mandatory for clocks with multiple possible parents. It is
* optional for single-parent clocks. Always call .get_parent if it is
* available and WARN if it is missing for multi-parent clocks.
*
* For single-parent clocks without .get_parent, first check to see if the
* .parents array exists, and if so use it to avoid an expensive tree
* traversal. If .parents does not exist then walk the tree.
*/
static struct clk_core *__clk_init_parent(struct clk_core *core)
{
struct clk_core *ret = NULL;
u8 index;
u8 index = 0;
/* handle the trivial cases */
if (core->num_parents > 1 && core->ops->get_parent)
index = core->ops->get_parent(core->hw);
if (!core->num_parents)
goto out;
if (core->num_parents == 1) {
if (IS_ERR_OR_NULL(core->parent))
core->parent = clk_core_lookup(core->parent_names[0]);
ret = core->parent;
goto out;
}
if (!core->ops->get_parent) {
WARN(!core->ops->get_parent,
"%s: multi-parent clocks must implement .get_parent\n",
__func__);
goto out;
}
/*
* Do our best to cache parent clocks in core->parents. This prevents
* unnecessary and expensive lookups. We don't set core->parent here;
* that is done by the calling function.
*/
index = core->ops->get_parent(core->hw);
if (!core->parents)
core->parents =
kcalloc(core->num_parents, sizeof(struct clk *),
GFP_KERNEL);
ret = clk_core_get_parent_by_index(core, index);
out:
return ret;
return clk_core_get_parent_by_index(core, index);
}
static void clk_core_reparent(struct clk_core *core,
......@@ -1809,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
/* try finding the new parent index */
if (parent) {
p_index = clk_fetch_parent_index(core, parent);
p_rate = parent->rate;
if (p_index < 0) {
pr_debug("%s: clk %s can not be parent of clk %s\n",
__func__, parent->name, core->name);
ret = p_index;
goto out;
}
p_rate = parent->rate;
}
/* propagate PRE_RATE_CHANGE notifications */
......@@ -1902,6 +1841,10 @@ int clk_set_phase(struct clk *clk, int degrees)
clk_prepare_lock();
/* bail early if nothing to do */
if (degrees == clk->core->phase)
goto out;
trace_clk_set_phase(clk->core, degrees);
if (clk->core->ops->set_phase)
......@@ -1912,6 +1855,7 @@ int clk_set_phase(struct clk *clk, int degrees)
if (!ret)
clk->core->phase = degrees;
out:
clk_prepare_unlock();
return ret;
......@@ -2218,7 +2162,7 @@ static int clk_debug_register(struct clk_core *core)
*
* Dynamically removes a clk and all its child nodes from the
* debugfs clk directory if clk->dentry points to debugfs created by
* clk_debug_register in __clk_init.
* clk_debug_register in __clk_core_init.
*/
static void clk_debug_unregister(struct clk_core *core)
{
......@@ -2303,26 +2247,22 @@ static inline void clk_debug_unregister(struct clk_core *core)
#endif
/**
* __clk_init - initialize the data structures in a struct clk
* @dev: device initializing this clk, placeholder for now
* @clk: clk being initialized
* __clk_core_init - initialize the data structures in a struct clk_core
* @core: clk_core being initialized
*
* Initializes the lists in struct clk_core, queries the hardware for the
* parent and rate and sets them both.
*/
static int __clk_init(struct device *dev, struct clk *clk_user)
static int __clk_core_init(struct clk_core *core)
{
int i, ret = 0;
struct clk_core *orphan;
struct hlist_node *tmp2;
struct clk_core *core;
unsigned long rate;
if (!clk_user)
if (!core)
return -EINVAL;
core = clk_user->core;
clk_prepare_lock();
/* check to see if a clock with this name is already registered */
......@@ -2337,22 +2277,29 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
if (core->ops->set_rate &&
!((core->ops->round_rate || core->ops->determine_rate) &&
core->ops->recalc_rate)) {
pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
__func__, core->name);
pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
__func__, core->name);
ret = -EINVAL;
goto out;
}
if (core->ops->set_parent && !core->ops->get_parent) {
pr_warning("%s: %s must implement .get_parent & .set_parent\n",
__func__, core->name);
pr_err("%s: %s must implement .get_parent & .set_parent\n",
__func__, core->name);
ret = -EINVAL;
goto out;
}
if (core->num_parents > 1 && !core->ops->get_parent) {
pr_err("%s: %s must implement .get_parent as it has multi parents\n",
__func__, core->name);
ret = -EINVAL;
goto out;
}
if (core->ops->set_rate_and_parent &&
!(core->ops->set_parent && core->ops->set_rate)) {
pr_warn("%s: %s must implement .set_parent & .set_rate\n",
pr_err("%s: %s must implement .set_parent & .set_rate\n",
__func__, core->name);
ret = -EINVAL;
goto out;
......@@ -2364,37 +2311,12 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
"%s: invalid NULL in %s's .parent_names\n",
__func__, core->name);
/*
* Allocate an array of struct clk *'s to avoid unnecessary string
* look-ups of clk's possible parents. This can fail for clocks passed
* in to clk_init during early boot; thus any access to core->parents[]
* must always check for a NULL pointer and try to populate it if
* necessary.
*
* If core->parents is not NULL we skip this entire block. This allows
* for clock drivers to statically initialize core->parents.
*/
if (core->num_parents > 1 && !core->parents) {
core->parents = kcalloc(core->num_parents, sizeof(struct clk *),
GFP_KERNEL);
/*
* clk_core_lookup returns NULL for parents that have not been
* clk_init'd; thus any access to clk->parents[] must check
* for a NULL pointer. We can always perform lazy lookups for
* missing parents later on.
*/
if (core->parents)
for (i = 0; i < core->num_parents; i++)
core->parents[i] =
clk_core_lookup(core->parent_names[i]);
}
core->parent = __clk_init_parent(core);
/*
* Populate core->parent if parent has already been __clk_init'd. If
* parent has not yet been __clk_init'd then place clk in the orphan
* list. If clk has set the CLK_IS_ROOT flag then place it in the root
* Populate core->parent if parent has already been clk_core_init'd. If
* parent has not yet been clk_core_init'd then place clk in the orphan
* list. If clk doesn't have any parents then place it in the root
* clk list.
*
* Every time a new clk is clk_init'd then we walk the list of orphan
......@@ -2405,7 +2327,7 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
hlist_add_head(&core->child_node,
&core->parent->children);
core->orphan = core->parent->orphan;
} else if (core->flags & CLK_IS_ROOT) {
} else if (!core->num_parents) {
hlist_add_head(&core->child_node, &clk_root_list);
core->orphan = false;
} else {
......@@ -2454,24 +2376,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
core->rate = core->req_rate = rate;
/*
* walk the list of orphan clocks and reparent any that are children of
* this clock
* walk the list of orphan clocks and reparent any that newly finds a
* parent.
*/
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
if (orphan->num_parents && orphan->ops->get_parent) {
i = orphan->ops->get_parent(orphan->hw);
if (i >= 0 && i < orphan->num_parents &&
!strcmp(core->name, orphan->parent_names[i]))
clk_core_reparent(orphan, core);
continue;
}
struct clk_core *parent = __clk_init_parent(orphan);
for (i = 0; i < orphan->num_parents; i++)
if (!strcmp(core->name, orphan->parent_names[i])) {
clk_core_reparent(orphan, core);
break;
}
}
if (parent)
clk_core_reparent(orphan, parent);
}
/*
* optional platform-specific magic
......@@ -2585,21 +2498,31 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
}
}
/* avoid unnecessary string look-ups of clk_core's possible parents. */
core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
GFP_KERNEL);
if (!core->parents) {
ret = -ENOMEM;
goto fail_parents;
};
INIT_HLIST_HEAD(&core->clks);
hw->clk = __clk_create_clk(hw, NULL, NULL);
if (IS_ERR(hw->clk)) {
ret = PTR_ERR(hw->clk);
goto fail_parent_names_copy;
goto fail_parents;
}
ret = __clk_init(dev, hw->clk);
ret = __clk_core_init(core);
if (!ret)
return hw->clk;
__clk_free_clk(hw->clk);
hw->clk = NULL;
fail_parents:
kfree(core->parents);
fail_parent_names_copy:
while (--i >= 0)
kfree_const(core->parent_names[i]);
......@@ -2683,7 +2606,7 @@ void clk_unregister(struct clk *clk)
if (clk->core->ops == &clk_nodrv_ops) {
pr_err("%s: unregistered clock: %s\n", __func__,
clk->core->name);
return;
goto unlock;
}
/*
* Assign empty clock ops for consumers that might still hold
......@@ -2709,7 +2632,7 @@ void clk_unregister(struct clk *clk)
pr_warn("%s: unregistering prepared clock: %s\n",
__func__, clk->core->name);
kref_put(&clk->core->ref, __clk_release);
unlock:
clk_prepare_unlock();
}
EXPORT_SYMBOL_GPL(clk_unregister);
......@@ -3061,10 +2984,23 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
return __of_clk_get_from_provider(clkspec, NULL, __func__);
}
EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
int of_clk_get_parent_count(struct device_node *np)
/**
* of_clk_get_parent_count() - Count the number of clocks a device node has
* @np: device node to count
*
* Returns: The number of clocks that are possible parents of this node
*/
unsigned int of_clk_get_parent_count(struct device_node *np)
{
return of_count_phandle_with_args(np, "clocks", "#clock-cells");
int count;
count = of_count_phandle_with_args(np, "clocks", "#clock-cells");
if (count < 0)
return 0;
return count;
}
EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
......@@ -3214,6 +3150,9 @@ void __init of_clk_init(const struct of_device_id *matches)
for_each_matching_node_and_match(np, matches, &match) {
struct clock_provider *parent;
if (!of_device_is_available(np))
continue;
parent = kzalloc(sizeof(*parent), GFP_KERNEL);
if (!parent) {
list_for_each_entry_safe(clk_provider, next,
......
......@@ -13,7 +13,7 @@ static DEFINE_SPINLOCK(clklock);
static void __init h8300_div_clk_setup(struct device_node *node)
{
int num_parents;
unsigned int num_parents;
struct clk *clk;
const char *clk_name = node->name;
const char *parent_name;
......@@ -22,7 +22,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
int offset;
num_parents = of_clk_get_parent_count(node);
if (num_parents < 1) {
if (!num_parents) {
pr_err("%s: no parent found", clk_name);
return;
}
......@@ -34,7 +34,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
}
offset = (unsigned long)divcr & 3;
offset = (3 - offset) * 8;
divcr = (void *)((unsigned long)divcr & ~3);
divcr = (void __iomem *)((unsigned long)divcr & ~3);
parent_name = of_clk_get_parent_name(node, 0);
of_property_read_u32(node, "renesas,width", &width);
......
......@@ -83,7 +83,7 @@ static const struct clk_ops pll_ops = {
static void __init h8s2678_pll_clk_setup(struct device_node *node)
{
int num_parents;
unsigned int num_parents;
struct clk *clk;
const char *clk_name = node->name;
const char *parent_name;
......@@ -91,7 +91,7 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node)
struct clk_init_data init;
num_parents = of_clk_get_parent_count(node);
if (num_parents < 1) {
if (!num_parents) {
pr_err("%s: no parent found", clk_name);
return;
}
......
......@@ -78,15 +78,15 @@ static const char *const mmc3_mux_p[] __initconst = { "armpll2", "armpll3", };
/* fixed rate clocks */
static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = {
{ HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, },
{ HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, },
{ HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, },
{ HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, },
{ HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, },
{ HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, },
{ HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, },
{ HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, },
{ HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, },
{ HI3620_OSC32K, "osc32k", NULL, 0, 32768, },
{ HI3620_OSC26M, "osc26m", NULL, 0, 26000000, },
{ HI3620_PCLK, "pclk", NULL, 0, 26000000, },
{ HI3620_PLL_ARM0, "armpll0", NULL, 0, 1600000000, },
{ HI3620_PLL_ARM1, "armpll1", NULL, 0, 1600000000, },
{ HI3620_PLL_PERI, "armpll2", NULL, 0, 1440000000, },
{ HI3620_PLL_USB, "armpll3", NULL, 0, 1440000000, },
{ HI3620_PLL_HDMI, "armpll4", NULL, 0, 1188000000, },
{ HI3620_PLL_GPU, "armpll5", NULL, 0, 1300000000, },
};
/* fixed factor clocks */
......
......@@ -235,7 +235,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev)
init.name = "acpu0";
init.ops = &hi6220_stub_clk_ops;
init.num_parents = 0;
init.flags = CLK_IS_ROOT;
init.flags = 0;
clk = devm_clk_register(dev, &stub_clk->hw);
if (IS_ERR(clk))
......
......@@ -26,19 +26,19 @@
/* clocks in AO (always on) controller */
static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = {
{ HI6220_REF32K, "ref32k", NULL, CLK_IS_ROOT, 32764, },
{ HI6220_CLK_TCXO, "clk_tcxo", NULL, CLK_IS_ROOT, 19200000, },
{ HI6220_MMC1_PAD, "mmc1_pad", NULL, CLK_IS_ROOT, 100000000, },
{ HI6220_MMC2_PAD, "mmc2_pad", NULL, CLK_IS_ROOT, 100000000, },
{ HI6220_MMC0_PAD, "mmc0_pad", NULL, CLK_IS_ROOT, 200000000, },
{ HI6220_PLL_BBP, "bbppll0", NULL, CLK_IS_ROOT, 245760000, },
{ HI6220_PLL_GPU, "gpupll", NULL, CLK_IS_ROOT, 1000000000,},
{ HI6220_PLL1_DDR, "ddrpll1", NULL, CLK_IS_ROOT, 1066000000,},
{ HI6220_PLL_SYS, "syspll", NULL, CLK_IS_ROOT, 1200000000,},
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, CLK_IS_ROOT, 1200000000,},
{ HI6220_DDR_SRC, "ddr_sel_src", NULL, CLK_IS_ROOT, 1200000000,},
{ HI6220_PLL_MEDIA, "media_pll", NULL, CLK_IS_ROOT, 1440000000,},
{ HI6220_PLL_DDR, "ddrpll0", NULL, CLK_IS_ROOT, 1600000000,},
{ HI6220_REF32K, "ref32k", NULL, 0, 32764, },
{ HI6220_CLK_TCXO, "clk_tcxo", NULL, 0, 19200000, },
{ HI6220_MMC1_PAD, "mmc1_pad", NULL, 0, 100000000, },
{ HI6220_MMC2_PAD, "mmc2_pad", NULL, 0, 100000000, },
{ HI6220_MMC0_PAD, "mmc0_pad", NULL, 0, 200000000, },
{ HI6220_PLL_BBP, "bbppll0", NULL, 0, 245760000, },
{ HI6220_PLL_GPU, "gpupll", NULL, 0, 1000000000,},
{ HI6220_PLL1_DDR, "ddrpll1", NULL, 0, 1066000000,},
{ HI6220_PLL_SYS, "syspll", NULL, 0, 1200000000,},
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1200000000,},
{ HI6220_DDR_SRC, "ddr_sel_src", NULL, 0, 1200000000,},
{ HI6220_PLL_MEDIA, "media_pll", NULL, 0, 1440000000,},
{ HI6220_PLL_DDR, "ddrpll0", NULL, 0, 1600000000,},
};
static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = {
......
......@@ -36,9 +36,9 @@
/* fixed rate clocks */
static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = {
{ HIP04_OSC50M, "osc50m", NULL, CLK_IS_ROOT, 50000000, },
{ HIP04_CLK_50M, "clk50m", NULL, CLK_IS_ROOT, 50000000, },
{ HIP04_CLK_168M, "clk168m", NULL, CLK_IS_ROOT, 168750000, },
{ HIP04_OSC50M, "osc50m", NULL, 0, 50000000, },
{ HIP04_CLK_50M, "clk50m", NULL, 0, 50000000, },
{ HIP04_CLK_168M, "clk168m", NULL, 0, 168750000, },
};
static void __init hip04_clk_init(struct device_node *np)
......
......@@ -14,36 +14,36 @@
#include "clk.h"
static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = {
{ HIX5HD2_FIXED_1200M, "1200m", NULL, CLK_IS_ROOT, 1200000000, },
{ HIX5HD2_FIXED_400M, "400m", NULL, CLK_IS_ROOT, 400000000, },
{ HIX5HD2_FIXED_48M, "48m", NULL, CLK_IS_ROOT, 48000000, },
{ HIX5HD2_FIXED_24M, "24m", NULL, CLK_IS_ROOT, 24000000, },
{ HIX5HD2_FIXED_600M, "600m", NULL, CLK_IS_ROOT, 600000000, },
{ HIX5HD2_FIXED_300M, "300m", NULL, CLK_IS_ROOT, 300000000, },
{ HIX5HD2_FIXED_75M, "75m", NULL, CLK_IS_ROOT, 75000000, },
{ HIX5HD2_FIXED_200M, "200m", NULL, CLK_IS_ROOT, 200000000, },
{ HIX5HD2_FIXED_100M, "100m", NULL, CLK_IS_ROOT, 100000000, },
{ HIX5HD2_FIXED_40M, "40m", NULL, CLK_IS_ROOT, 40000000, },
{ HIX5HD2_FIXED_150M, "150m", NULL, CLK_IS_ROOT, 150000000, },
{ HIX5HD2_FIXED_1728M, "1728m", NULL, CLK_IS_ROOT, 1728000000, },
{ HIX5HD2_FIXED_28P8M, "28p8m", NULL, CLK_IS_ROOT, 28000000, },
{ HIX5HD2_FIXED_432M, "432m", NULL, CLK_IS_ROOT, 432000000, },
{ HIX5HD2_FIXED_345P6M, "345p6m", NULL, CLK_IS_ROOT, 345000000, },
{ HIX5HD2_FIXED_288M, "288m", NULL, CLK_IS_ROOT, 288000000, },
{ HIX5HD2_FIXED_60M, "60m", NULL, CLK_IS_ROOT, 60000000, },
{ HIX5HD2_FIXED_750M, "750m", NULL, CLK_IS_ROOT, 750000000, },
{ HIX5HD2_FIXED_500M, "500m", NULL, CLK_IS_ROOT, 500000000, },
{ HIX5HD2_FIXED_54M, "54m", NULL, CLK_IS_ROOT, 54000000, },
{ HIX5HD2_FIXED_27M, "27m", NULL, CLK_IS_ROOT, 27000000, },
{ HIX5HD2_FIXED_1500M, "1500m", NULL, CLK_IS_ROOT, 1500000000, },
{ HIX5HD2_FIXED_375M, "375m", NULL, CLK_IS_ROOT, 375000000, },
{ HIX5HD2_FIXED_187M, "187m", NULL, CLK_IS_ROOT, 187000000, },
{ HIX5HD2_FIXED_250M, "250m", NULL, CLK_IS_ROOT, 250000000, },
{ HIX5HD2_FIXED_125M, "125m", NULL, CLK_IS_ROOT, 125000000, },
{ HIX5HD2_FIXED_2P02M, "2m", NULL, CLK_IS_ROOT, 2000000, },
{ HIX5HD2_FIXED_50M, "50m", NULL, CLK_IS_ROOT, 50000000, },
{ HIX5HD2_FIXED_25M, "25m", NULL, CLK_IS_ROOT, 25000000, },
{ HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, },
{ HIX5HD2_FIXED_1200M, "1200m", NULL, 0, 1200000000, },
{ HIX5HD2_FIXED_400M, "400m", NULL, 0, 400000000, },
{ HIX5HD2_FIXED_48M, "48m", NULL, 0, 48000000, },
{ HIX5HD2_FIXED_24M, "24m", NULL, 0, 24000000, },
{ HIX5HD2_FIXED_600M, "600m", NULL, 0, 600000000, },
{ HIX5HD2_FIXED_300M, "300m", NULL, 0, 300000000, },
{ HIX5HD2_FIXED_75M, "75m", NULL, 0, 75000000, },
{ HIX5HD2_FIXED_200M, "200m", NULL, 0, 200000000, },
{ HIX5HD2_FIXED_100M, "100m", NULL, 0, 100000000, },
{ HIX5HD2_FIXED_40M, "40m", NULL, 0, 40000000, },
{ HIX5HD2_FIXED_150M, "150m", NULL, 0, 150000000, },
{ HIX5HD2_FIXED_1728M, "1728m", NULL, 0, 1728000000, },
{ HIX5HD2_FIXED_28P8M, "28p8m", NULL, 0, 28000000, },
{ HIX5HD2_FIXED_432M, "432m", NULL, 0, 432000000, },
{ HIX5HD2_FIXED_345P6M, "345p6m", NULL, 0, 345000000, },
{ HIX5HD2_FIXED_288M, "288m", NULL, 0, 288000000, },
{ HIX5HD2_FIXED_60M, "60m", NULL, 0, 60000000, },
{ HIX5HD2_FIXED_750M, "750m", NULL, 0, 750000000, },
{ HIX5HD2_FIXED_500M, "500m", NULL, 0, 500000000, },
{ HIX5HD2_FIXED_54M, "54m", NULL, 0, 54000000, },
{ HIX5HD2_FIXED_27M, "27m", NULL, 0, 27000000, },
{ HIX5HD2_FIXED_1500M, "1500m", NULL, 0, 1500000000, },
{ HIX5HD2_FIXED_375M, "375m", NULL, 0, 375000000, },
{ HIX5HD2_FIXED_187M, "187m", NULL, 0, 187000000, },
{ HIX5HD2_FIXED_250M, "250m", NULL, 0, 250000000, },
{ HIX5HD2_FIXED_125M, "125m", NULL, 0, 125000000, },
{ HIX5HD2_FIXED_2P02M, "2m", NULL, 0, 2000000, },
{ HIX5HD2_FIXED_50M, "50m", NULL, 0, 50000000, },
{ HIX5HD2_FIXED_25M, "25m", NULL, 0, 25000000, },
{ HIX5HD2_FIXED_83M, "83m", NULL, 0, 83333333, },
};
static const char *const sfc_mux_p[] __initconst = {
......
此差异已折叠。
......@@ -157,9 +157,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]);
clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
......@@ -196,8 +196,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20);
clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
clks[IMX6UL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
......@@ -210,8 +210,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
/* name parent_name mult div */
clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
np = ccm_node;
......@@ -219,34 +219,34 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
WARN_ON(!base);
clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels));
clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels));
clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels));
clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels));
clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels));
clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels));
clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels));
clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels));
clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels));
clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels));
clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels));
clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels));
clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
......@@ -259,11 +259,11 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3);
clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6);
......@@ -287,14 +287,14 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
/* CCGR0 */
clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4);
clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
......@@ -302,7 +302,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x68, 24);
......@@ -331,7 +331,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14);
clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
......@@ -365,6 +365,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
/* CCGR5 */
clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8);
clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10);
clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
clks[IMX6UL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
......@@ -391,10 +392,10 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14);
clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14);
clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20);
clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("Pwm7", "perclk", base + 0x80, 30);
clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
/* mask handshake of mmdc */
writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
......
......@@ -87,7 +87,7 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
static inline struct clk *imx_clk_fixed(const char *name, int rate)
{
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
}
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
......
......@@ -58,8 +58,8 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
for (i = 0; i < num; i++) {
const struct mtk_fixed_clk *rc = &clks[i];
clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
rc->rate);
if (IS_ERR(clk)) {
pr_err("Failed to register clk %s: %ld\n",
......
......@@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
}
void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
size_t nr_confs,
unsigned int nr_confs,
void __iomem *clk_base)
{
unsigned int i;
......
......@@ -11,7 +11,6 @@ config ARMADA_370_CLK
bool
select MVEBU_CLK_COMMON
select MVEBU_CLK_CPU
select MVEBU_CLK_COREDIV
config ARMADA_375_CLK
bool
......@@ -29,7 +28,6 @@ config ARMADA_XP_CLK
bool
select MVEBU_CLK_COMMON
select MVEBU_CLK_CPU
select MVEBU_CLK_COREDIV
config DOVE_CLK
bool
......
......@@ -137,8 +137,8 @@ void __init mvebu_coreclk_setup(struct device_node *np,
of_property_read_string_index(np, "clock-output-names", 0,
&tclk_name);
rate = desc->get_tclk_freq(base);
clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
CLK_IS_ROOT, rate);
clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, 0,
rate);
WARN_ON(IS_ERR(clk_data.clks[0]));
/* Register CPU clock */
......@@ -150,8 +150,8 @@ void __init mvebu_coreclk_setup(struct device_node *np,
&& desc->is_sscg_enabled(base))
rate = desc->fix_sscg_deviation(rate);
clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
CLK_IS_ROOT, rate);
clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, 0,
rate);
WARN_ON(IS_ERR(clk_data.clks[1]));
/* Register fixed-factor clocks derived from CPU clock */
......@@ -174,8 +174,7 @@ void __init mvebu_coreclk_setup(struct device_node *np,
2 + desc->num_ratios, &name);
rate = desc->get_refclk_freq(base);
clk_data.clks[2 + desc->num_ratios] =
clk_register_fixed_rate(NULL, name, NULL,
CLK_IS_ROOT, rate);
clk_register_fixed_rate(NULL, name, NULL, 0, rate);
WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios]));
}
......
......@@ -225,8 +225,7 @@ static int dove_divider_init(struct device *dev, void __iomem *base,
* Create the core PLL clock. We treat this as a fixed rate
* clock as we don't know any better, and documentation is sparse.
*/
clk = clk_register_fixed_rate(dev, core_pll[0], NULL, CLK_IS_ROOT,
2000000000UL);
clk = clk_register_fixed_rate(dev, core_pll[0], NULL, 0, 2000000000UL);
if (IS_ERR(clk))
return PTR_ERR(clk);
......
......@@ -38,7 +38,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name,
static inline struct clk *mxs_clk_fixed(const char *name, int rate)
{
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
}
static inline struct clk *mxs_clk_gate(const char *name,
......
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-creg.o
obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o
......@@ -605,7 +605,7 @@ static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,
/* Register the internal 12 MHz RC oscillator (IRC) */
clk = clk_register_fixed_rate(NULL, clk_src_names[CLK_SRC_IRC],
NULL, CLK_IS_ROOT, 12000000);
NULL, 0, 12000000);
if (IS_ERR(clk))
pr_warn("%s: failed to register irc clk\n", __func__);
......
/*
* Clk driver for NXP LPC18xx/43xx Configuration Registers (CREG)
*
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define LPC18XX_CREG_CREG0 0x004
#define LPC18XX_CREG_CREG0_EN1KHZ BIT(0)
#define LPC18XX_CREG_CREG0_EN32KHZ BIT(1)
#define LPC18XX_CREG_CREG0_RESET32KHZ BIT(2)
#define LPC18XX_CREG_CREG0_PD32KHZ BIT(3)
#define to_clk_creg(_hw) container_of(_hw, struct clk_creg_data, hw)
enum {
CREG_CLK_1KHZ,
CREG_CLK_32KHZ,
CREG_CLK_MAX,
};
struct clk_creg_data {
struct clk_hw hw;
const char *name;
struct regmap *reg;
unsigned int en_mask;
const struct clk_ops *ops;
};
#define CREG_CLK(_name, _emask, _ops) \
{ \
.name = _name, \
.en_mask = LPC18XX_CREG_CREG0_##_emask, \
.ops = &_ops, \
}
static int clk_creg_32k_prepare(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
int ret;
ret = regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
LPC18XX_CREG_CREG0_PD32KHZ |
LPC18XX_CREG_CREG0_RESET32KHZ, 0);
/*
* Powering up the 32k oscillator takes a long while
* and sadly there aren't any status bit to poll.
*/
msleep(2500);
return ret;
}
static void clk_creg_32k_unprepare(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
LPC18XX_CREG_CREG0_PD32KHZ,
LPC18XX_CREG_CREG0_PD32KHZ);
}
static int clk_creg_32k_is_prepared(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
u32 reg;
regmap_read(creg->reg, LPC18XX_CREG_CREG0, &reg);
return !(reg & LPC18XX_CREG_CREG0_PD32KHZ) &&
!(reg & LPC18XX_CREG_CREG0_RESET32KHZ);
}
static unsigned long clk_creg_1k_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return parent_rate / 32;
}
static int clk_creg_enable(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
return regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
creg->en_mask, creg->en_mask);
}
static void clk_creg_disable(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
creg->en_mask, 0);
}
static int clk_creg_is_enabled(struct clk_hw *hw)
{
struct clk_creg_data *creg = to_clk_creg(hw);
u32 reg;
regmap_read(creg->reg, LPC18XX_CREG_CREG0, &reg);
return !!(reg & creg->en_mask);
}
static const struct clk_ops clk_creg_32k = {
.enable = clk_creg_enable,
.disable = clk_creg_disable,
.is_enabled = clk_creg_is_enabled,
.prepare = clk_creg_32k_prepare,
.unprepare = clk_creg_32k_unprepare,
.is_prepared = clk_creg_32k_is_prepared,
};
static const struct clk_ops clk_creg_1k = {
.enable = clk_creg_enable,
.disable = clk_creg_disable,
.is_enabled = clk_creg_is_enabled,
.recalc_rate = clk_creg_1k_recalc_rate,
};
static struct clk_creg_data clk_creg_clocks[] = {
[CREG_CLK_1KHZ] = CREG_CLK("1khz_clk", EN1KHZ, clk_creg_1k),
[CREG_CLK_32KHZ] = CREG_CLK("32khz_clk", EN32KHZ, clk_creg_32k),
};
static struct clk *clk_register_creg_clk(struct device *dev,
struct clk_creg_data *creg_clk,
const char **parent_name,
struct regmap *syscon)
{
struct clk_init_data init;
init.ops = creg_clk->ops;
init.name = creg_clk->name;
init.parent_names = parent_name;
init.num_parents = 1;
creg_clk->reg = syscon;
creg_clk->hw.init = &init;
if (dev)
return devm_clk_register(dev, &creg_clk->hw);
return clk_register(NULL, &creg_clk->hw);
}
static struct clk *clk_creg_early[CREG_CLK_MAX];
static struct clk_onecell_data clk_creg_early_data = {
.clks = clk_creg_early,
.clk_num = CREG_CLK_MAX,
};
static void __init lpc18xx_creg_clk_init(struct device_node *np)
{
const char *clk_32khz_parent;
struct regmap *syscon;
syscon = syscon_node_to_regmap(np->parent);
if (IS_ERR(syscon)) {
pr_err("%s: syscon lookup failed\n", __func__);
return;
}
clk_32khz_parent = of_clk_get_parent_name(np, 0);
clk_creg_early[CREG_CLK_32KHZ] =
clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_32KHZ],
&clk_32khz_parent, syscon);
clk_creg_early[CREG_CLK_1KHZ] = ERR_PTR(-EPROBE_DEFER);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data);
}
CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);
static struct clk *clk_creg[CREG_CLK_MAX];
static struct clk_onecell_data clk_creg_data = {
.clks = clk_creg,
.clk_num = CREG_CLK_MAX,
};
static int lpc18xx_creg_clk_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct regmap *syscon;
syscon = syscon_node_to_regmap(np->parent);
if (IS_ERR(syscon)) {
dev_err(&pdev->dev, "syscon lookup failed\n");
return PTR_ERR(syscon);
}
clk_creg[CREG_CLK_32KHZ] = clk_creg_early[CREG_CLK_32KHZ];
clk_creg[CREG_CLK_1KHZ] =
clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_1KHZ],
&clk_creg_clocks[CREG_CLK_32KHZ].name,
syscon);
return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_data);
}
static const struct of_device_id lpc18xx_creg_clk_of_match[] = {
{ .compatible = "nxp,lpc1850-creg-clk" },
{},
};
static struct platform_driver lpc18xx_creg_clk_driver = {
.probe = lpc18xx_creg_clk_probe,
.driver = {
.name = "lpc18xx-creg-clk",
.of_match_table = lpc18xx_creg_clk_of_match,
},
};
builtin_platform_driver(lpc18xx_creg_clk_driver);
......@@ -87,7 +87,7 @@ enum {
enum {
/* Start from the last defined clock in dt bindings */
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1,
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1,
LPC32XX_CLK_ADC_RTC,
LPC32XX_CLK_TEST1,
LPC32XX_CLK_TEST2,
......@@ -96,7 +96,6 @@ enum {
LPC32XX_CLK_OSC,
LPC32XX_CLK_SYS,
LPC32XX_CLK_PLL397X,
LPC32XX_CLK_HCLK_PLL,
LPC32XX_CLK_HCLK_DIV_PERIPH,
LPC32XX_CLK_HCLK_DIV,
LPC32XX_CLK_HCLK,
......@@ -589,7 +588,8 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6;
u64 m_i, o = rate, i = *parent_rate, d = (u64)rate << 6;
u64 m = 0, n = 0, p = 0;
int p_i, n_i;
pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
......@@ -1429,6 +1429,8 @@ static struct clk * __init lpc32xx_clk_register(u32 id)
hw = &clk_hw->hw0.div.hw;
else if (clk_hw->type == CLK_GATE)
hw = &clk_hw->hw0.gate.hw;
else
return ERR_PTR(-EINVAL);
hw->init = &clk_init;
clk = clk_register(NULL, hw);
......@@ -1515,7 +1517,7 @@ static void __init lpc32xx_clk_init(struct device_node *np)
return;
}
for (i = 0; i < LPC32XX_CLK_MAX; i++) {
for (i = 1; i < LPC32XX_CLK_MAX; i++) {
clk[i] = lpc32xx_clk_register(i);
if (IS_ERR(clk[i])) {
pr_err("failed to register %s clock: %ld\n",
......@@ -1526,9 +1528,6 @@ static void __init lpc32xx_clk_init(struct device_node *np)
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
/* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */
clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000);
/* Set 48MHz rate of USB PLL clock */
clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000);
......@@ -1555,7 +1554,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np)
return;
}
for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) {
for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) {
usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET);
if (IS_ERR(usb_clk[i])) {
pr_err("failed to register %s clock: %ld\n",
......
......@@ -200,12 +200,10 @@ static void __init pxa25x_register_core(void)
static void __init pxa25x_register_plls(void)
{
clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
3686400);
CLK_GET_RATE_NOCACHE, 3686400);
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
32768);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
CLK_GET_RATE_NOCACHE, 32768);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz",
0, 26, 1);
clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz",
......
......@@ -208,12 +208,12 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base");
static void __init pxa27x_register_plls(void)
{
clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
CLK_GET_RATE_NOCACHE,
13 * MHz);
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
CLK_GET_RATE_NOCACHE,
32768 * KHz);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1);
}
......
......@@ -284,15 +284,15 @@ static void __init pxa3xx_register_core(void)
static void __init pxa3xx_register_plls(void)
{
clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
CLK_GET_RATE_NOCACHE,
13 * MHz);
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
CLK_GET_RATE_NOCACHE,
32768);
clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
CLK_GET_RATE_NOCACHE,
120 * MHz);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
clk_register_fixed_factor(NULL, "spll_624mhz", "osc_13mhz", 0, 48, 1);
clk_register_fixed_factor(NULL, "ring_osc_60mhz", "ring_osc_120mhz",
0, 1, 2);
......
......@@ -28,6 +28,14 @@ config APQ_MMCC_8084
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
config IPQ_GCC_4019
tristate "IPQ4019 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on ipq4019 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, etc.
config IPQ_GCC_806X
tristate "IPQ806x Global Clock Controller"
depends on COMMON_CLK_QCOM
......
......@@ -14,6 +14,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
......
......@@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
return ret;
src = ns_to_src(&rcg->s, ns);
f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
for (i = 0; i < num_parents; i++) {
if (src == rcg->s.parent_map[i].cfg) {
......@@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
}
}
/* bypass the pre divider */
f.pre_div = 1;
/* let us find appropriate m/n values for this */
for (; frac->num; frac++) {
request = (rate * frac->den) / frac->num;
......
......@@ -119,7 +119,6 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
fixed->hw.init = &init_data;
init_data.name = path;
init_data.flags = CLK_IS_ROOT;
init_data.ops = &clk_fixed_rate_ops;
clk = devm_clk_register(dev, &fixed->hw);
......@@ -185,6 +184,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
struct clk **clks;
struct qcom_reset_controller *reset;
struct qcom_cc *cc;
struct gdsc_desc *scd;
size_t num_clks = desc->num_clks;
struct clk_regmap **rclks = desc->clks;
......@@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev,
if (ret)
return ret;
devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node);
ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider,
pdev->dev.of_node);
if (ret)
return ret;
reset = &cc->reset;
reset->rcdev.of_node = dev->of_node;
......@@ -227,18 +231,28 @@ int qcom_cc_really_probe(struct platform_device *pdev,
if (ret)
return ret;
devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev);
ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister,
&reset->rcdev);
if (ret)
return ret;
if (desc->gdscs && desc->num_gdscs) {
ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
&reset->rcdev, regmap);
scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL);
if (!scd)
return -ENOMEM;
scd->dev = dev;
scd->scs = desc->gdscs;
scd->num = desc->num_gdscs;
ret = gdsc_register(scd, &reset->rcdev, regmap);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister,
scd);
if (ret)
return ret;
}
devm_add_action(dev, qcom_cc_gdsc_unregister, dev);
return 0;
}
EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
......
此差异已折叠。
......@@ -890,7 +890,6 @@ static struct clk_branch gsbi1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -906,7 +905,6 @@ static struct clk_branch gsbi2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -922,7 +920,6 @@ static struct clk_branch gsbi4_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi4_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -938,7 +935,6 @@ static struct clk_branch gsbi5_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi5_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -954,7 +950,6 @@ static struct clk_branch gsbi6_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi6_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -970,7 +965,6 @@ static struct clk_branch gsbi7_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi7_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1144,7 +1138,6 @@ static struct clk_branch pmem_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmem_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1308,7 +1301,6 @@ static struct clk_branch sdc1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1324,7 +1316,6 @@ static struct clk_branch sdc3_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc3_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1394,7 +1385,6 @@ static struct clk_branch tsif_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "tsif_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1410,7 +1400,6 @@ static struct clk_branch dma_bam_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "dma_bam_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1425,7 +1414,6 @@ static struct clk_branch adm0_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm0_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1442,7 +1430,6 @@ static struct clk_branch adm0_pbus_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm0_pbus_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1457,7 +1444,6 @@ static struct clk_branch pmic_arb0_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_arb0_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1472,7 +1458,6 @@ static struct clk_branch pmic_arb1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_arb1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1487,7 +1472,6 @@ static struct clk_branch pmic_ssbi2_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_ssbi2_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1504,7 +1488,6 @@ static struct clk_branch rpm_msg_ram_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "rpm_msg_ram_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1563,7 +1546,6 @@ static struct clk_branch pcie_a_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie_a_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1577,7 +1559,6 @@ static struct clk_branch pcie_aux_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie_aux_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1591,7 +1572,6 @@ static struct clk_branch pcie_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1605,7 +1585,6 @@ static struct clk_branch pcie_phy_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie_phy_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1659,7 +1638,6 @@ static struct clk_branch pcie1_a_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie1_a_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1673,7 +1651,6 @@ static struct clk_branch pcie1_aux_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie1_aux_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1687,7 +1664,6 @@ static struct clk_branch pcie1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1701,7 +1677,6 @@ static struct clk_branch pcie1_phy_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie1_phy_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1755,7 +1730,6 @@ static struct clk_branch pcie2_a_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie2_a_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1769,7 +1743,6 @@ static struct clk_branch pcie2_aux_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie2_aux_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1783,7 +1756,6 @@ static struct clk_branch pcie2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1797,7 +1769,6 @@ static struct clk_branch pcie2_phy_clk = {
.hw.init = &(struct clk_init_data){
.name = "pcie2_phy_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1887,7 +1858,6 @@ static struct clk_branch sata_a_clk = {
.hw.init = &(struct clk_init_data){
.name = "sata_a_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1901,7 +1871,6 @@ static struct clk_branch sata_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sata_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1915,7 +1884,6 @@ static struct clk_branch sfab_sata_s_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sfab_sata_s_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -1929,7 +1897,6 @@ static struct clk_branch sata_phy_cfg_clk = {
.hw.init = &(struct clk_init_data){
.name = "sata_phy_cfg_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2139,7 +2106,6 @@ static struct clk_branch usb_hs1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "usb_hs1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2218,7 +2184,6 @@ static struct clk_branch usb_fs1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "usb_fs1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2234,7 +2199,6 @@ static struct clk_branch ebi2_clk = {
.hw.init = &(struct clk_init_data){
.name = "ebi2_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2248,7 +2212,6 @@ static struct clk_branch ebi2_aon_clk = {
.hw.init = &(struct clk_init_data){
.name = "ebi2_always_on_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......
......@@ -1479,7 +1479,6 @@ static struct clk_branch pmem_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmem_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2027,7 +2026,6 @@ static struct clk_branch gsbi1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2041,7 +2039,6 @@ static struct clk_branch gsbi2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2055,7 +2052,6 @@ static struct clk_branch gsbi3_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi3_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2069,7 +2065,6 @@ static struct clk_branch gsbi4_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi4_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2083,7 +2078,6 @@ static struct clk_branch gsbi5_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi5_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2097,7 +2091,6 @@ static struct clk_branch gsbi6_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi6_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2111,7 +2104,6 @@ static struct clk_branch gsbi7_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi7_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2125,7 +2117,6 @@ static struct clk_branch gsbi8_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi8_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2139,7 +2130,6 @@ static struct clk_branch gsbi9_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi9_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2153,7 +2143,6 @@ static struct clk_branch gsbi10_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi10_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2167,7 +2156,6 @@ static struct clk_branch gsbi11_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi11_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2181,7 +2169,6 @@ static struct clk_branch gsbi12_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi12_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2195,7 +2182,6 @@ static struct clk_branch tsif_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "tsif_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2209,7 +2195,6 @@ static struct clk_branch usb_fs1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "usb_fs1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2223,7 +2208,6 @@ static struct clk_branch usb_fs2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "usb_fs2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2237,7 +2221,6 @@ static struct clk_branch usb_hs1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "usb_hs1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2251,7 +2234,6 @@ static struct clk_branch sdc1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2265,7 +2247,6 @@ static struct clk_branch sdc2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2279,7 +2260,6 @@ static struct clk_branch sdc3_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc3_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2293,7 +2273,6 @@ static struct clk_branch sdc4_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc4_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2307,7 +2286,6 @@ static struct clk_branch sdc5_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "sdc5_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2322,7 +2300,6 @@ static struct clk_branch adm0_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm0_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2337,7 +2314,6 @@ static struct clk_branch adm0_pbus_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm0_pbus_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2352,7 +2328,6 @@ static struct clk_branch adm1_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm1_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2367,7 +2342,6 @@ static struct clk_branch adm1_pbus_clk = {
.hw.init = &(struct clk_init_data){
.name = "adm1_pbus_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2382,7 +2356,6 @@ static struct clk_branch modem_ahb1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "modem_ahb1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2397,7 +2370,6 @@ static struct clk_branch modem_ahb2_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "modem_ahb2_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2412,7 +2384,6 @@ static struct clk_branch pmic_arb0_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_arb0_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2427,7 +2398,6 @@ static struct clk_branch pmic_arb1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_arb1_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2442,7 +2412,6 @@ static struct clk_branch pmic_ssbi2_clk = {
.hw.init = &(struct clk_init_data){
.name = "pmic_ssbi2_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......@@ -2459,7 +2428,6 @@ static struct clk_branch rpm_msg_ram_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "rpm_msg_ram_h_clk",
.ops = &clk_branch_ops,
.flags = CLK_IS_ROOT,
},
},
};
......
此差异已折叠。
此差异已折叠。
......@@ -1965,7 +1965,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_q6_bimc_axi_clk",
.flags = CLK_IS_ROOT,
.ops = &clk_branch2_ops,
},
},
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -82,9 +82,8 @@ static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct div6_clock *clock = to_div6_clock(hw);
unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
return parent_rate / div;
return parent_rate / clock->div;
}
static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
......
#ifndef __SHMOBILE_CLK_DIV6_H__
#define __SHMOBILE_CLK_DIV6_H__
#ifndef __RENESAS_CLK_DIV6_H__
#define __RENESAS_CLK_DIV6_H__
struct clk *cpg_div6_register(const char *name, unsigned int num_parents,
const char **parent_names, void __iomem *reg);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册