diff options
author | Olof Johansson <olof@lixom.net> | 2019-06-17 04:53:32 -0700 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2019-06-17 04:53:32 -0700 |
commit | c3bd15a0786ef7e32482a7dced21d79286b6f36c (patch) | |
tree | 5b5e88af9fe3ca2bd34d24e2a547c7a8e3b1643d /arch/arm/mach-omap2 | |
parent | 426356392c2ce9c720852ec9181c66d9e57d7340 (diff) | |
parent | 4e23be473e3063a9d3bc06bb0aee89885fffab0e (diff) | |
download | talos-op-linux-c3bd15a0786ef7e32482a7dced21d79286b6f36c.tar.gz talos-op-linux-c3bd15a0786ef7e32482a7dced21d79286b6f36c.zip |
Merge tag 'omap-for-v5.3/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/drivers
ti-sysc interconnect target module driver changes for v5.3
This series of changes improves probing devices with ti-sysc to the
point where we can now probe most devices without the custom dts
property "ti,hwmods" and no legacy platform data :)
We add support for platform data callbacks for idling and unidling the
clockdomain the module belongs to. The rest of the series mostly adds
handling for the various quirks needed by old legacy modules such as
i2c and watchdog. Some quirk handling is still missing for few modules,
but those will be added as they get tested.
The related platform data and dts changes will be sent separately.
* tag 'omap-for-v5.3/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
bus: ti-sysc: Add support for module specific reset quirks
bus: ti-sysc: Detect uarts also on omap34xx
bus: ti-sysc: Do rstctrl reset handling in two phases
bus: ti-sysc: Add support for disabling module without legacy mode
bus: ti-sysc: Set ENAWAKEUP if available
bus: ti-sysc: Handle swsup idle mode quirks
bus: ti-sysc: Handle clockactivity for enable and disable
bus: ti-sysc: Enable interconnect target module autoidle bit on enable
bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set
bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset bits
bus: ti-sysc: Support 16-bit writes too
bus: ti-sysc: Add support for missing clockdomain handling
ARM: dts: dra71x: Disable usb4_tm target module
ARM: dts: dra71x: Disable rtc target module
ARM: dts: dra76x: Disable usb4_tm target module
ARM: dts: dra76x: Disable rtc target module
ARM: dts: dra76x: Update MMC2_HS200_MANUAL1 iodelay values
ARM: dts: am57xx-idk: Remove support for voltage switching for SD card
bus: ti-sysc: Handle devices with no control registers
ARM: dts: Configure osc clock for d_can on am335x
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pdata-quirks.c | 60 |
2 files changed, 65 insertions, 34 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 405ac24def05..932ba221e8e7 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3445,6 +3445,7 @@ static int omap_hwmod_check_module(struct device *dev, * @dev: struct device * @oh: module * @sysc_fields: sysc register bits + * @clockdomain: clockdomain * @rev_offs: revision register offset * @sysc_offs: sysconfig register offset * @syss_offs: sysstatus register offset @@ -3456,6 +3457,7 @@ static int omap_hwmod_check_module(struct device *dev, static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, const struct ti_sysc_module_data *data, struct sysc_regbits *sysc_fields, + struct clockdomain *clkdm, s32 rev_offs, s32 sysc_offs, s32 syss_offs, u32 sysc_flags, u32 idlemodes) @@ -3463,8 +3465,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, struct omap_hwmod_class_sysconfig *sysc; struct omap_hwmod_class *class = NULL; struct omap_hwmod_ocp_if *oi = NULL; - struct clockdomain *clkdm = NULL; - struct clk *clk = NULL; void __iomem *regs = NULL; unsigned long flags; @@ -3511,36 +3511,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, oi->user = OCP_USER_MPU | OCP_USER_SDMA; } - if (!oh->_clk) { - struct clk_hw_omap *hwclk; - - clk = of_clk_get_by_name(dev->of_node, "fck"); - if (!IS_ERR(clk)) - clk_prepare(clk); - else - clk = NULL; - - /* - * Populate clockdomain based on dts clock. It is needed for - * clkdm_deny_idle() and clkdm_allow_idle() until we have have - * interconnect driver and reset driver capable of blocking - * clockdomain idle during reset, enable and idle. - */ - if (clk) { - hwclk = to_clk_hw_omap(__clk_get_hw(clk)); - if (hwclk && hwclk->clkdm_name) - clkdm = clkdm_lookup(hwclk->clkdm_name); - } - - /* - * Note that we assume interconnect driver manages the clocks - * and do not need to populate oh->_clk for dynamically - * allocated modules. - */ - clk_unprepare(clk); - clk_put(clk); - } - spin_lock_irqsave(&oh->_lock, flags); if (regs) oh->_mpu_rt_va = regs; @@ -3626,7 +3596,7 @@ int omap_hwmod_init_module(struct device *dev, u32 sysc_flags, idlemodes; int error; - if (!dev || !data) + if (!dev || !data || !data->name || !cookie) return -EINVAL; oh = _lookup(data->name); @@ -3697,7 +3667,8 @@ int omap_hwmod_init_module(struct device *dev, return error; return omap_hwmod_allocate_module(dev, oh, data, sysc_fields, - rev_offs, sysc_offs, syss_offs, + cookie->clkdm, rev_offs, + sysc_offs, syss_offs, sysc_flags, idlemodes); } diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index a2ecc5e69abb..b09cc4e8d240 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -29,6 +29,7 @@ #include <linux/platform_data/wkup_m3.h> #include <linux/platform_data/asoc-ti-mcbsp.h> +#include "clockdomain.h" #include "common.h" #include "common-board-devices.h" #include "control.h" @@ -463,6 +464,62 @@ static void __init dra7x_evm_mmc_quirk(void) } #endif +static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk) +{ + struct clockdomain *clkdm = NULL; + struct clk_hw_omap *hwclk; + + hwclk = to_clk_hw_omap(__clk_get_hw(clk)); + if (hwclk && hwclk->clkdm_name) + clkdm = clkdm_lookup(hwclk->clkdm_name); + + return clkdm; +} + +/** + * ti_sysc_clkdm_init - find clockdomain based on clock + * @fck: device functional clock + * @ick: device interface clock + * @dev: struct device + * + * Populate clockdomain based on clock. It is needed for + * clkdm_deny_idle() and clkdm_allow_idle() for blocking clockdomain + * clockdomain idle during reset, enable and idle. + * + * Note that we assume interconnect driver manages the clocks + * and do not need to populate oh->_clk for dynamically + * allocated modules. + */ +static int ti_sysc_clkdm_init(struct device *dev, + struct clk *fck, struct clk *ick, + struct ti_sysc_cookie *cookie) +{ + if (fck) + cookie->clkdm = ti_sysc_find_one_clockdomain(fck); + if (cookie->clkdm) + return 0; + if (ick) + cookie->clkdm = ti_sysc_find_one_clockdomain(ick); + if (cookie->clkdm) + return 0; + + return -ENODEV; +} + +static void ti_sysc_clkdm_deny_idle(struct device *dev, + const struct ti_sysc_cookie *cookie) +{ + if (cookie->clkdm) + clkdm_deny_idle(cookie->clkdm); +} + +static void ti_sysc_clkdm_allow_idle(struct device *dev, + const struct ti_sysc_cookie *cookie) +{ + if (cookie->clkdm) + clkdm_allow_idle(cookie->clkdm); +} + static int ti_sysc_enable_module(struct device *dev, const struct ti_sysc_cookie *cookie) { @@ -494,6 +551,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[]; static struct ti_sysc_platform_data ti_sysc_pdata = { .auxdata = omap_auxdata_lookup, + .init_clockdomain = ti_sysc_clkdm_init, + .clkdm_deny_idle = ti_sysc_clkdm_deny_idle, + .clkdm_allow_idle = ti_sysc_clkdm_allow_idle, .init_module = omap_hwmod_init_module, .enable_module = ti_sysc_enable_module, .idle_module = ti_sysc_idle_module, |