drivers/clk: support using clk function at interrupt and idle
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
9ef19af5bb
commit
afec562fbb
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user