drivers/clk: support using clk function at interrupt and idle

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1 2023-05-29 11:07:10 +08:00 committed by Xiang Xiao
parent 9ef19af5bb
commit afec562fbb

View File

@ -56,8 +56,8 @@ static struct list_node g_clk_orphan_list
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static void clk_list_lock(void); static irqstate_t clk_list_lock(void);
static void clk_list_unlock(void); static void clk_list_unlock(irqstate_t flags);
static int clk_fetch_parent_index(FAR struct clk_s *clk, static int clk_fetch_parent_index(FAR struct clk_s *clk,
FAR struct clk_s *parent); FAR struct clk_s *parent);
@ -176,9 +176,9 @@ static size_t clk_procfs_printf(FAR char *buffer, size_t buflen,
return procfs_memcpy(tmp, tmplen, buffer, buflen, pos); return procfs_memcpy(tmp, tmplen, buffer, buflen, pos);
} }
static size_t clk_procfs_show_subtree(FAR FAR struct clk_s *clk, int level, static size_t clk_procfs_show_subtree(FAR struct clk_s *clk, int level,
FAR char *buffer, size_t buflen, FAR char *buffer, size_t buflen,
off_t *pos) off_t *pos, FAR irqstate_t *flags)
{ {
FAR struct clk_s *child; FAR struct clk_s *child;
size_t oldlen = buflen; size_t oldlen = buflen;
@ -186,7 +186,7 @@ static size_t clk_procfs_show_subtree(FAR FAR struct clk_s *clk, int level,
if (strchr(clk_get_name(clk), '/')) if (strchr(clk_get_name(clk), '/'))
{ {
clk_list_unlock(); clk_list_unlock(*flags);
} }
ret = clk_procfs_printf(buffer, buflen, pos, "%*s%-*s %11d %11u %11d\n", ret = clk_procfs_printf(buffer, buflen, pos, "%*s%-*s %11d %11u %11d\n",
@ -198,7 +198,7 @@ static size_t clk_procfs_show_subtree(FAR FAR struct clk_s *clk, int level,
if (strchr(clk_get_name(clk), '/')) if (strchr(clk_get_name(clk), '/'))
{ {
clk_list_lock(); *flags = clk_list_lock();
} }
if (buflen > 0) if (buflen > 0)
@ -206,7 +206,7 @@ static size_t clk_procfs_show_subtree(FAR FAR struct clk_s *clk, int level,
list_for_every_entry(&clk->children, child, struct clk_s, node) list_for_every_entry(&clk->children, child, struct clk_s, node)
{ {
ret = clk_procfs_show_subtree(child, level + 1, ret = clk_procfs_show_subtree(child, level + 1,
buffer, buflen, pos); buffer, buflen, pos, flags);
buffer += ret; buffer += ret;
buflen -= ret; buflen -= ret;
@ -225,13 +225,14 @@ static size_t clk_procfs_showtree(FAR char *buffer,
{ {
FAR struct clk_s *clk; FAR struct clk_s *clk;
size_t oldlen = buflen; size_t oldlen = buflen;
irqstate_t flags;
size_t ret; size_t ret;
clk_list_lock(); flags = clk_list_lock();
list_for_every_entry(&g_clk_root_list, clk, struct clk_s, node) list_for_every_entry(&g_clk_root_list, clk, struct clk_s, node)
{ {
ret = clk_procfs_show_subtree(clk, 0, buffer, buflen, pos); ret = clk_procfs_show_subtree(clk, 0, buffer, buflen, pos, &flags);
buffer += ret; buffer += ret;
buflen -= ret; buflen -= ret;
@ -243,7 +244,7 @@ static size_t clk_procfs_showtree(FAR char *buffer,
list_for_every_entry(&g_clk_orphan_list, clk, struct clk_s, node) list_for_every_entry(&g_clk_orphan_list, clk, struct clk_s, node)
{ {
ret = clk_procfs_show_subtree(clk, 0, buffer, buflen, pos); ret = clk_procfs_show_subtree(clk, 0, buffer, buflen, pos, &flags);
buffer += ret; buffer += ret;
buflen -= ret; buflen -= ret;
@ -254,7 +255,7 @@ static size_t clk_procfs_showtree(FAR char *buffer,
} }
out: out:
clk_list_unlock(); clk_list_unlock(flags);
return oldlen - buflen; return oldlen - buflen;
} }
@ -315,14 +316,24 @@ static int clk_procfs_stat(const char *relpath, struct stat *buf)
#endif /* !defined(CONFIG_FS_PROCFS_EXCLUDE_CLK) && defined(CONFIG_FS_PROCFS) */ #endif /* !defined(CONFIG_FS_PROCFS_EXCLUDE_CLK) && defined(CONFIG_FS_PROCFS) */
static void clk_list_lock(void) static irqstate_t clk_list_lock(void)
{ {
nxmutex_lock(&g_clk_list_lock); if (!up_interrupt_context() && !sched_idletask())
{
nxmutex_lock(&g_clk_list_lock);
}
return enter_critical_section();
} }
static void clk_list_unlock(void) static void clk_list_unlock(irqstate_t flags)
{ {
nxmutex_unlock(&g_clk_list_lock); leave_critical_section(flags);
if (!up_interrupt_context() && !sched_idletask())
{
nxmutex_unlock(&g_clk_list_lock);
}
} }
static int clk_fetch_parent_index(FAR struct clk_s *clk, static int clk_fetch_parent_index(FAR struct clk_s *clk,
@ -710,6 +721,7 @@ static int __clk_register(FAR struct clk_s *clk)
{ {
FAR struct clk_s *orphan; FAR struct clk_s *orphan;
FAR struct clk_s *temp; FAR struct clk_s *temp;
irqstate_t flags;
uint8_t i; uint8_t i;
if (!clk) if (!clk)
@ -737,7 +749,7 @@ static int __clk_register(FAR struct clk_s *clk)
clk_init_parent(clk); clk_init_parent(clk);
clk_list_lock(); flags = clk_list_lock();
if (clk->parent) if (clk->parent)
{ {
@ -776,7 +788,7 @@ static int __clk_register(FAR struct clk_s *clk)
} }
} }
clk_list_unlock(); clk_list_unlock(flags);
return 0; return 0;
} }
@ -814,8 +826,9 @@ static void clk_disable_unused_subtree(FAR struct clk_s *clk)
void clk_disable_unused(void) void clk_disable_unused(void)
{ {
FAR struct clk_s *root_clk = NULL; FAR struct clk_s *root_clk = NULL;
irqstate_t flags;
clk_list_lock(); flags = clk_list_lock();
list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node) list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node)
{ {
@ -827,7 +840,7 @@ void clk_disable_unused(void)
clk_disable_unused_subtree(root_clk); clk_disable_unused_subtree(root_clk);
} }
clk_list_unlock(); clk_list_unlock(flags);
} }
int clk_disable(FAR struct clk_s *clk) int clk_disable(FAR struct clk_s *clk)
@ -982,13 +995,14 @@ FAR struct clk_s *clk_get(FAR const char *name)
{ {
FAR struct clk_s *root_clk = NULL; FAR struct clk_s *root_clk = NULL;
FAR struct clk_s *ret = NULL; FAR struct clk_s *ret = NULL;
irqstate_t flags;
if (!name) if (!name)
{ {
return NULL; return NULL;
} }
clk_list_lock(); flags = clk_list_lock();
list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node) list_for_every_entry(&g_clk_root_list, root_clk, struct clk_s, node)
{ {
@ -1009,7 +1023,7 @@ FAR struct clk_s *clk_get(FAR const char *name)
} }
out: out:
clk_list_unlock(); clk_list_unlock(flags);
#ifdef CONFIG_CLK_RPMSG #ifdef CONFIG_CLK_RPMSG
if (ret == NULL) if (ret == NULL)