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:
Arnd Bergmann 2024-04-29 22:25:14 +02:00
commit 75e4eadcf9
2 changed files with 34 additions and 132 deletions

View File

@ -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,
};
/*

View File

@ -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)