mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 14:32:23 +00:00
Driver updates for ti-sysc
A change to update the handling of no-reset-on-init quirk to make it init time only like it should be. And a change to add the missing copyrights. Also a series of changes to simplify the driver by dropping the old unused handling for interconnect targets tagged pm_runtime_irq_safe(). These are all non-urgent changes and can be queued whenever suitable. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEkgNvrZJU/QSQYIcQG9Q+yVyrpXMFAmYt4joRHHRvbnlAYXRv bWlkZS5jb20ACgkQG9Q+yVyrpXNO+g/7BTsnrnPSCOgebdI5UWrPQ316ANM0C9OR ENm1FiOGvkBLY25g3wlLlswsKm2Of/4yOsw+KIN53MjOtJm5+1eBome6Dro4RIKE nEuZNFIr7w9MGHX/ugB7hoOsqwvlOWUYJsEywfaVyRMjD296mVM/L1L6Xh7GUgDd A4ChKAhwSMuAV72ZCofL9a1mRYbUlCgm+vT5b6VP4JoCN9FoAl33eoGZXxRlV96d y1lkmVn0ZuiURTZFzqfcsV0AJxpIuHJAYgt2/yMOPvUBtSvl/b7+GeLy1cO/zDEU m0WKKTwPyRzFlfZmEITuRGYBtmzg7N3XskqIhTWMPY3W2o2bDlGK4pg39nRZDBmN 4vpCJoP946Ac2SR1NMfyYkn5aVpSPAb1A59aEZ1Hn3ti9IqIeCqaHsGOLG8/DzPp XXWZHCxJS2TQZU+VXzQrJL62j3J1c4wXF4+xTb2LgKXxnX1TzGM5klD2RkkEApU8 Cio+Z3kq3FNQGT2eQCktu7ifhwfNGFNTmTktZ1P9Li/p6eroBkJc2xljiixXzxqo WeLRghaQ85ZekhyprneSUgyUphm9/0FNUn0BaEqedB84yM1rdFEPJVU0duFEqNfS i6YTRYLWvzp8lv2iCHrlzhqEA1HgArBJn0cj61pvA5uf7aRRYOEn2Nk6+/GQWRII fbZWeOIdeLY= =DXcf -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmYwAioACgkQYKtH/8kJ Uiecaw/8CXl1oNCA26w8mgNsmG0D4HgexEgrh5eL9ili9Qy/NhwAV1D5dL01gcHr BppEPxyRJjwx8492Vo4yF0RwcFxND7Voqsd9nO1nnyRb4cN9ZNaPeDo2nJUy0eWs MoNcbQ2aNQs94LUsIezWvTXj1MZlBgET0vxAWOEYHHTGtXnpm6K7arjLIGgjUKVO GG7pQ209/FgiReYOYPH4lIIY5tuov5LNJWY2RYmczf63QYEnV8lsOhVPEbb9xJgJ DJM0YsnWDEDV7Guq7eRvJjSRLPaSVOmKoMcQpMBdhS0D+p5r6MKuQjw8ubdcb7fZ hXJ3SqOMobks4dwZkZ9ZK+vWON2litlkZixgVVT6QRTGXtEUjsisKJeVrzEvjILO ZsNmEbJJ9rcVxsWRfduNeAtXZ96ek/pHupYyzHQSu4IhrDDObRAcXEhhcrU8vyr+ 7dXUupwMUa/Kl9HT0kjvh3AqcK/mxMA8rtADgcpQzwqzVJdZTXvxjY3hRPRMuV6M c5T245cw4Cq2nOY3hjuz6qB46Ngp7i4+FbvhYfP6YCmQjkk+XG3JIwIOnLJDBWAg R+94yvMkA1hj+DH4eXkn8oUaJ9Esd7GngPbuQJ9jSZIjC+i5gooPjCLWNmNWfzzA hWyG7ouj0Hi+NvLgKjjhxaeBRFw9HvVCJQMz6Sggww0C1yhHw6c= =iLZx -----END PGP SIGNATURE----- Merge tag 'drivers-ti-sysc-for-v6.10-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into soc/drivers Driver updates for ti-sysc A change to update the handling of no-reset-on-init quirk to make it init time only like it should be. And a change to add the missing copyrights. Also a series of changes to simplify the driver by dropping the old unused handling for interconnect targets tagged pm_runtime_irq_safe(). These are all non-urgent changes and can be queued whenever suitable. * tag 'drivers-ti-sysc-for-v6.10-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: bus: ti-sysc: Drop legacy idle quirk handling bus: ti-sysc: Drop legacy quirk handling for smartreflex bus: ti-sysc: Drop legacy quirk handling for uarts bus: ti-sysc: Add a description and copyrights bus: ti-sysc: Move check for no-reset-on-init Link: https://lore.kernel.org/r/pull-1714283210-549557@atomide.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
75e4eadcf9
@ -1,6 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ti-sysc.c - Texas Instruments sysc interconnect target driver
|
||||
*
|
||||
* TI SoCs have an interconnect target wrapper IP for many devices. The wrapper
|
||||
* IP manages clock gating, resets, and PM capabilities for the connected devices.
|
||||
*
|
||||
* Copyright (C) 2017-2024 Texas Instruments Incorporated - https://www.ti.com/
|
||||
*
|
||||
* Many features are based on the earlier omap_hwmod arch code with thanks to all
|
||||
* the people who developed and debugged the code over the years:
|
||||
*
|
||||
* Copyright (C) 2009-2011 Nokia Corporation
|
||||
* Copyright (C) 2011-2021 Texas Instruments Incorporated - https://www.ti.com/
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
@ -1458,8 +1469,7 @@ static int __maybe_unused sysc_noirq_suspend(struct device *dev)
|
||||
|
||||
ddata = dev_get_drvdata(dev);
|
||||
|
||||
if (ddata->cfg.quirks &
|
||||
(SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
|
||||
if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
|
||||
return 0;
|
||||
|
||||
if (!ddata->enabled)
|
||||
@ -1477,8 +1487,7 @@ static int __maybe_unused sysc_noirq_resume(struct device *dev)
|
||||
|
||||
ddata = dev_get_drvdata(dev);
|
||||
|
||||
if (ddata->cfg.quirks &
|
||||
(SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
|
||||
if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
|
||||
return 0;
|
||||
|
||||
if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_RESUME) {
|
||||
@ -1529,19 +1538,6 @@ struct sysc_revision_quirk {
|
||||
}
|
||||
|
||||
static const struct sysc_revision_quirk sysc_revision_quirks[] = {
|
||||
/* These drivers need to be fixed to not use pm_runtime_irq_safe() */
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
|
||||
/* Uarts on omap4 and later */
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
|
||||
|
||||
/* Quirks that need to be set based on the module address */
|
||||
SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,
|
||||
SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT |
|
||||
@ -1599,6 +1595,17 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
|
||||
SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
|
||||
SYSC_QUIRK("sata", 0, 0xfc, 0x1100, -ENODEV, 0x5e412000, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT),
|
||||
/* Uarts on omap4 and later */
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT),
|
||||
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE_ACT),
|
||||
SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff,
|
||||
SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
|
||||
SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff,
|
||||
@ -2145,8 +2152,7 @@ static int sysc_reset(struct sysc *ddata)
|
||||
sysc_offset = ddata->offsets[SYSC_SYSCONFIG];
|
||||
|
||||
if (ddata->legacy_mode ||
|
||||
ddata->cap->regbits->srst_shift < 0 ||
|
||||
ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
|
||||
ddata->cap->regbits->srst_shift < 0)
|
||||
return 0;
|
||||
|
||||
sysc_mask = BIT(ddata->cap->regbits->srst_shift);
|
||||
@ -2240,12 +2246,14 @@ static int sysc_init_module(struct sysc *ddata)
|
||||
goto err_main_clocks;
|
||||
}
|
||||
|
||||
error = sysc_reset(ddata);
|
||||
if (error)
|
||||
dev_err(ddata->dev, "Reset failed with %d\n", error);
|
||||
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
|
||||
error = sysc_reset(ddata);
|
||||
if (error)
|
||||
dev_err(ddata->dev, "Reset failed with %d\n", error);
|
||||
|
||||
if (error && !ddata->legacy_mode)
|
||||
sysc_disable_module(ddata->dev);
|
||||
if (error && !ddata->legacy_mode)
|
||||
sysc_disable_module(ddata->dev);
|
||||
}
|
||||
|
||||
err_main_clocks:
|
||||
if (error)
|
||||
@ -2447,89 +2455,6 @@ static int __maybe_unused sysc_child_runtime_resume(struct device *dev)
|
||||
return pm_generic_runtime_resume(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int sysc_child_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct sysc *ddata;
|
||||
int error;
|
||||
|
||||
ddata = sysc_child_to_parent(dev);
|
||||
|
||||
dev_dbg(ddata->dev, "%s %s\n", __func__,
|
||||
ddata->name ? ddata->name : "");
|
||||
|
||||
error = pm_generic_suspend_noirq(dev);
|
||||
if (error) {
|
||||
dev_err(dev, "%s error at %i: %i\n",
|
||||
__func__, __LINE__, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!pm_runtime_status_suspended(dev)) {
|
||||
error = pm_generic_runtime_suspend(dev);
|
||||
if (error) {
|
||||
dev_dbg(dev, "%s busy at %i: %i\n",
|
||||
__func__, __LINE__, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = sysc_runtime_suspend(ddata->dev);
|
||||
if (error) {
|
||||
dev_err(dev, "%s error at %i: %i\n",
|
||||
__func__, __LINE__, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ddata->child_needs_resume = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sysc_child_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct sysc *ddata;
|
||||
int error;
|
||||
|
||||
ddata = sysc_child_to_parent(dev);
|
||||
|
||||
dev_dbg(ddata->dev, "%s %s\n", __func__,
|
||||
ddata->name ? ddata->name : "");
|
||||
|
||||
if (ddata->child_needs_resume) {
|
||||
ddata->child_needs_resume = false;
|
||||
|
||||
error = sysc_runtime_resume(ddata->dev);
|
||||
if (error)
|
||||
dev_err(ddata->dev,
|
||||
"%s runtime resume error: %i\n",
|
||||
__func__, error);
|
||||
|
||||
error = pm_generic_runtime_resume(dev);
|
||||
if (error)
|
||||
dev_err(ddata->dev,
|
||||
"%s generic runtime resume: %i\n",
|
||||
__func__, error);
|
||||
}
|
||||
|
||||
return pm_generic_resume_noirq(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct dev_pm_domain sysc_child_pm_domain = {
|
||||
.ops = {
|
||||
SET_RUNTIME_PM_OPS(sysc_child_runtime_suspend,
|
||||
sysc_child_runtime_resume,
|
||||
NULL)
|
||||
USE_PLATFORM_PM_SLEEP_OPS
|
||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_child_suspend_noirq,
|
||||
sysc_child_resume_noirq)
|
||||
}
|
||||
};
|
||||
|
||||
/* Caller needs to take list_lock if ever used outside of cpu_pm */
|
||||
static void sysc_reinit_modules(struct sysc_soc_info *soc)
|
||||
{
|
||||
@ -2600,25 +2525,6 @@ static void sysc_add_restored(struct sysc *ddata)
|
||||
mutex_unlock(&sysc_soc->list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysc_legacy_idle_quirk - handle children in omap_device compatible way
|
||||
* @ddata: device driver data
|
||||
* @child: child device driver
|
||||
*
|
||||
* Allow idle for child devices as done with _od_runtime_suspend().
|
||||
* Otherwise many child devices will not idle because of the permanent
|
||||
* parent usecount set in pm_runtime_irq_safe().
|
||||
*
|
||||
* Note that the long term solution is to just modify the child device
|
||||
* drivers to not set pm_runtime_irq_safe() and then this can be just
|
||||
* dropped.
|
||||
*/
|
||||
static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child)
|
||||
{
|
||||
if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
|
||||
dev_pm_domain_set(child, &sysc_child_pm_domain);
|
||||
}
|
||||
|
||||
static int sysc_notifier_call(struct notifier_block *nb,
|
||||
unsigned long event, void *device)
|
||||
{
|
||||
@ -2635,7 +2541,6 @@ static int sysc_notifier_call(struct notifier_block *nb,
|
||||
error = sysc_child_add_clocks(ddata, dev);
|
||||
if (error)
|
||||
return error;
|
||||
sysc_legacy_idle_quirk(ddata, dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2859,8 +2764,7 @@ static const struct sysc_capabilities sysc_34xx_sr = {
|
||||
.type = TI_SYSC_OMAP34XX_SR,
|
||||
.sysc_mask = SYSC_OMAP2_CLOCKACTIVITY,
|
||||
.regbits = &sysc_regbits_omap34xx_sr,
|
||||
.mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED |
|
||||
SYSC_QUIRK_LEGACY_IDLE,
|
||||
.mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2881,13 +2785,12 @@ static const struct sysc_capabilities sysc_36xx_sr = {
|
||||
.type = TI_SYSC_OMAP36XX_SR,
|
||||
.sysc_mask = SYSC_OMAP3_SR_ENAWAKEUP,
|
||||
.regbits = &sysc_regbits_omap36xx_sr,
|
||||
.mod_quirks = SYSC_QUIRK_UNCACHED | SYSC_QUIRK_LEGACY_IDLE,
|
||||
.mod_quirks = SYSC_QUIRK_UNCACHED,
|
||||
};
|
||||
|
||||
static const struct sysc_capabilities sysc_omap4_sr = {
|
||||
.type = TI_SYSC_OMAP4_SR,
|
||||
.regbits = &sysc_regbits_omap36xx_sr,
|
||||
.mod_quirks = SYSC_QUIRK_LEGACY_IDLE,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -71,7 +71,6 @@ struct sysc_regbits {
|
||||
#define SYSC_QUIRK_SWSUP_SIDLE_ACT BIT(12)
|
||||
#define SYSC_QUIRK_SWSUP_SIDLE BIT(11)
|
||||
#define SYSC_QUIRK_EXT_OPT_CLOCK BIT(10)
|
||||
#define SYSC_QUIRK_LEGACY_IDLE BIT(9)
|
||||
#define SYSC_QUIRK_RESET_STATUS BIT(8)
|
||||
#define SYSC_QUIRK_NO_IDLE BIT(7)
|
||||
#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6)
|
||||
|
Loading…
Reference in New Issue
Block a user