summaryrefslogtreecommitdiff
path: root/drivers/clk/ti/clkctrl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-02 03:07:54 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-02 03:07:54 +0300
commit537433b6241e067de2d9da3bed5f4fed9c9eac58 (patch)
treea42c12eb76b5b35aa04edc409425ca2c01ceb2e3 /drivers/clk/ti/clkctrl.c
parentab486bc9a591689f3ac2b6ebc072309371f8f451 (diff)
parent9a288ba7d1dd088c10697905ff42d48830a7c549 (diff)
downloadlinux-537433b6241e067de2d9da3bed5f4fed9c9eac58.tar.xz
Merge tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC device tree updates from Arnd Bergmann: "We get a moderate number of new machines this time, and only one new SoC variant (Actions S700): Actions: - S700 Soc and CubieBoard7 development board - Allo.com Sparky Single-board-computer Allwinner: - Orange Pi R1 development board - Libre Computer Board ALL-H3-CC H3 single-board computer ASpeed ast2x00: - Witherspoon: OpenPower Power9 server manufactured by IBM that uses the ASPEED ast2500 - Zaius: OpenPower Power9 server manufactured by Invatech that uses the ASPEED ast2500 - Q71L: Intel Xeon server manufactured by Qanta that uses the ASPEED ast2400 AT91: - Axentia Nattis/Natte digital signage - sama5d2 PTC-ek Evaluation board Freescale/NXP i.MX: - SolidRun Humminboard2 development board - Variscite DART-MX6 SoM and Carrier-board - Technologic TS-4600 and TS-7970 development board - Toradex Colibri iMX7D SoM board - v1.5 variant of Solidrun Cubox-i and Hummingboard Freescale/NXP Layerscape: - Moxa UC-8410A Series industrial computer Gemini: - D-Link DNS-313 NAS enclosure OMAP: - LogicPD OMAP35xx SOM-LV devkit - LogicPD OMAP35xx Torpedo devkit Renesas: - r8a77970 (V3M) Starter Kit board - r8a7795 (M3-W) Salvator-XS board We finally managed to get the dtc warnings under control, with no more build-time warnings for bad device tree files. This includes fixes for the majority of platforms, including nomadik, samsung, lpc32xx, STi, spear, mediatek, freescale, qcom, realview, keystone, omap, kirkwood, renesas, hisilicon, and broadcom. Files get rearranged on a few platforms, in particular the Marvell Armada 7K/8K device tree files are changed in preparation for future SoC support, based on more than two of the same chips in one package, and some boards get renamed for oxnas for consistency. Finally, many existing SoCs gain descriptions for additional on-chip devices that we can now support with kernel drivers: - Allwinner A83t (drm, ethernet, i2c, ...), H3/H5 (USB-OTG) - Amlogic AXG family (clk, pinctrl, pwm, ...), and others (vpu, hdmi) - Aspeed clk controller support - Freescale LS1088A, LS1021A device support - Gemini Ethernet, PCI, TVE, panel - Keystone gpio, qspi, more uarts - Mediatek cpufreq, regulator, clock, reset - Marvell thermal, cpufreq, nand - Renesas SMP, thermal, timer, PWM, sound, phy, ipmmu - Rockchip Mipi, GPU, display - Samsung Exynos5433 PMU, power domain, nfc - Spreadtrum: sc9860 clocks - Tegra TX2 PSDI, HDMI, I2C,SMMU, display, fuse, ..." * tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (690 commits) arm64: dts: stratix10: fix SPI settings ARM: dts: socfpga: add i2c reset signals arm64: dts: stratix10: add USB ECC reset bit arm64: dts: stratix10: enable USB on the devkit ARM: dts: socfpga: disable over-current for Arria10 USB devkit ARM: dts: Nokia N9: add support for up/down keys in the dts ARM: dts: nomadik: add interrupt-parent for clcd ARM: dts: Add ethernet to a bunch of platforms ARM: dts: Add ethernet to the Gemini SoC ARM: dts: rename oxnas dts files ARM: dts: s5pv210: add interrupt-parent for ohci ARM: lpc3250: fix uda1380 gpio numbers ARM: dts: STi: Add gpio polarity for "hdmi,hpd-gpio" property ARM: dts: dra7: Reduce shut down temperature of non-cpu thermal zones ARM: dts: n900: Add aliases for lcd and tvout displays ARM: dts: Update ti-sysc data for existing users ARM: dts: Fix smartreflex compatible for omap3 shared mpu-iva instance arm64: dts: marvell: armada-80x0: Fix pinctrl compatible string arm: spear13xx: Fix spics gpio controller's warning arm: spear13xx: Fix dmas cells ...
Diffstat (limited to 'drivers/clk/ti/clkctrl.c')
-rw-r--r--drivers/clk/ti/clkctrl.c91
1 files changed, 84 insertions, 7 deletions
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index 53e71d0503ec..afa0d6bfc5c1 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -21,6 +21,7 @@
#include <linux/of_address.h>
#include <linux/clk/ti.h>
#include <linux/delay.h>
+#include <linux/timekeeping.h>
#include "clock.h"
#define NO_IDLEST 0x1
@@ -46,6 +47,7 @@ static bool _early_timeout = true;
struct omap_clkctrl_provider {
void __iomem *base;
struct list_head clocks;
+ char *clkdm_name;
};
struct omap_clkctrl_clk {
@@ -89,7 +91,18 @@ static bool _omap4_is_ready(u32 val)
static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
{
- if (unlikely(_early_timeout)) {
+ /*
+ * There are two special cases where ktime_to_ns() can't be
+ * used to track the timeouts. First one is during early boot
+ * when the timers haven't been initialized yet. The second
+ * one is during suspend-resume cycle while timekeeping is
+ * being suspended / resumed. Clocksource for the system
+ * can be from a timer that requires pm_runtime access, which
+ * will eventually bring us here with timekeeping_suspended,
+ * during both suspend entry and resume paths. This happens
+ * at least on am43xx platform.
+ */
+ if (unlikely(_early_timeout || timekeeping_suspended)) {
if (time->cycles++ < timeout) {
udelay(1);
return false;
@@ -208,6 +221,7 @@ static const struct clk_ops omap4_clkctrl_clk_ops = {
.enable = _omap4_clkctrl_clk_enable,
.disable = _omap4_clkctrl_clk_disable,
.is_enabled = _omap4_clkctrl_clk_is_enabled,
+ .init = omap2_init_clk_clkdm,
};
static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec,
@@ -321,6 +335,9 @@ _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider,
}
mux->mask = num_parents;
+ if (!(mux->flags & CLK_MUX_INDEX_ONE))
+ mux->mask--;
+
mux->mask = (1 << fls(mux->mask)) - 1;
mux->shift = data->bit;
@@ -340,6 +357,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
{
struct clk_omap_divider *div;
const struct omap_clkctrl_div_data *div_data = data->data;
+ u8 div_flags = 0;
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
@@ -347,12 +365,16 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
div->reg.ptr = reg;
div->shift = data->bit;
+ div->flags = div_data->flags;
+
+ if (div->flags & CLK_DIVIDER_POWER_OF_TWO)
+ div_flags |= CLKF_INDEX_POWER_OF_TWO;
- if (ti_clk_parse_divider_data((int *)div_data->dividers,
- div_data->max_div, 0, 0,
+ if (ti_clk_parse_divider_data((int *)div_data->dividers, 0,
+ div_data->max_div, div_flags,
&div->width, &div->table)) {
- pr_err("%s: Data parsing for %s:%04x:%d failed\n", __func__,
- node->name, offset, data->bit);
+ pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__,
+ node, offset, data->bit);
kfree(div);
return;
}
@@ -400,6 +422,12 @@ _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider,
}
}
+static void __init _clkctrl_add_provider(void *data,
+ struct device_node *np)
+{
+ of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data);
+}
+
static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
{
struct omap_clkctrl_provider *provider;
@@ -411,6 +439,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
struct omap_clkctrl_clk *clkctrl_clk;
const __be32 *addrp;
u32 addr;
+ int ret;
addrp = of_get_address(node, 0, NULL, NULL);
addr = (u32)of_translate_address(node, addrp);
@@ -419,6 +448,31 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
if (of_machine_is_compatible("ti,omap4"))
data = omap4_clkctrl_data;
#endif
+#ifdef CONFIG_SOC_OMAP5
+ if (of_machine_is_compatible("ti,omap5"))
+ data = omap5_clkctrl_data;
+#endif
+#ifdef CONFIG_SOC_DRA7XX
+ if (of_machine_is_compatible("ti,dra7"))
+ data = dra7_clkctrl_data;
+#endif
+#ifdef CONFIG_SOC_AM33XX
+ if (of_machine_is_compatible("ti,am33xx"))
+ data = am3_clkctrl_data;
+#endif
+#ifdef CONFIG_SOC_AM43XX
+ if (of_machine_is_compatible("ti,am4372"))
+ data = am4_clkctrl_data;
+ if (of_machine_is_compatible("ti,am438x"))
+ data = am438x_clkctrl_data;
+#endif
+#ifdef CONFIG_SOC_TI81XX
+ if (of_machine_is_compatible("ti,dm814"))
+ data = dm814_clkctrl_data;
+
+ if (of_machine_is_compatible("ti,dm816"))
+ data = dm816_clkctrl_data;
+#endif
while (data->addr) {
if (addr == data->addr)
@@ -428,7 +482,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
}
if (!data->addr) {
- pr_err("%s not found from clkctrl data.\n", node->name);
+ pr_err("%pOF not found from clkctrl data.\n", node);
return;
}
@@ -438,6 +492,21 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
provider->base = of_iomap(node, 0);
+ provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3,
+ GFP_KERNEL);
+ if (!provider->clkdm_name) {
+ kfree(provider);
+ return;
+ }
+
+ /*
+ * Create default clkdm name, replace _cm from end of parent node
+ * name with _clkdm
+ */
+ strcpy(provider->clkdm_name, node->parent->name);
+ provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0;
+ strcat(provider->clkdm_name, "clkdm");
+
INIT_LIST_HEAD(&provider->clocks);
/* Generate clocks */
@@ -460,6 +529,11 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
if (reg_data->flags & CLKF_NO_IDLEST)
hw->flags |= NO_IDLEST;
+ if (reg_data->clkdm_name)
+ hw->clkdm_name = reg_data->clkdm_name;
+ else
+ hw->clkdm_name = provider->clkdm_name;
+
init.parent_names = &reg_data->parent;
init.num_parents = 1;
init.flags = 0;
@@ -485,7 +559,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
reg_data++;
}
- of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider);
+ ret = of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider);
+ if (ret == -EPROBE_DEFER)
+ ti_clk_retry_init(node, provider, _clkctrl_add_provider);
+
return;
cleanup: