notifier: add notifier to core_context

Adds notifier to core_context, which is the first step
of multicore notifier implementation.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2018-10-08 12:06:29 +02:00
parent aeb18eefd9
commit bebfad8028
9 changed files with 147 additions and 30 deletions

View File

@ -54,6 +54,7 @@ sof_SOURCES += \
smp/xtos/_vectors.S \
smp/cpu.c \
smp/init.c \
smp/notifier.c \
smp/schedule.c \
smp/task.c \
smp/work.c
@ -63,6 +64,7 @@ sof_SOURCES += \
up/xtos/_vectors.S \
up/cpu.c \
up/init.c \
up/notifier.c \
up/schedule.c \
up/task.c \
up/work.c

View File

@ -107,6 +107,8 @@ void cpu_power_down_core(void)
free_system_workq();
free_system_notify();
/* free entire sys heap, an instance dedicated for this core */
free_heap(RZONE_SYS);

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Intel Corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author: Tomasz Lauda <tomasz.lauda@linux.intel.com>
*
*/
/**
* \file arch/xtensa/smp/notifier.c
* \brief Xtensa SMP notifier implementation file
* \authors Tomasz Lauda <tomasz.lauda@linux.intel.com>
*/
#include <xtos-structs.h>
#include <arch/cpu.h>
#include <sof/notifier.h>
struct notify **arch_notify_get(void)
{
struct core_context *ctx = (struct core_context *)cpu_read_threadptr();
return &ctx->notify;
}

View File

@ -35,6 +35,7 @@
struct idc;
struct irq_task;
struct notify;
struct schedule_data;
struct work_queue;
@ -59,6 +60,7 @@ struct core_context {
struct irq_task *irq_high_task;
struct schedule_data *sch;
struct work_queue *queue;
struct notify *notify;
struct idc *idc;
};

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Intel Corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author: Tomasz Lauda <tomasz.lauda@linux.intel.com>
*
*/
/**
* \file arch/xtensa/up/notifier.c
* \brief Xtensa UP notifier implementation file
* \authors Tomasz Lauda <tomasz.lauda@linux.intel.com>
*/
#include <sof/notifier.h>
/** \brief Notify data pointer. */
static struct notify *notify;
struct notify **arch_notify_get(void)
{
return &notify;
}

View File

@ -33,6 +33,7 @@
#include <stdint.h>
#include <sof/list.h>
#include <sof/lock.h>
struct sof;
@ -40,6 +41,11 @@ struct sof;
#define NOTIFIER_ID_CPU_FREQ 0
#define NOTIFIER_ID_SSP_FREQ 1
struct notify {
spinlock_t lock; /* notifier lock */
struct list_item list; /* list of notifiers */
};
struct notifier {
uint32_t id;
struct list_item list;
@ -47,6 +53,8 @@ struct notifier {
void (*cb)(int message, void *cb_data, void *event_data);
};
struct notify **arch_notify_get(void);
void notifier_register(struct notifier *notifier);
void notifier_unregister(struct notifier *notifier);
@ -54,4 +62,6 @@ void notifier_event(int id, int message, void *event_data);
void init_system_notify(struct sof *sof);
void free_system_notify(void);
#endif

View File

@ -100,6 +100,9 @@ int slave_core_init(struct sof *sof)
if (err < 0)
panic(SOF_IPC_PANIC_ARCH);
trace_point(TRACE_BOOT_SYS_NOTE);
init_system_notify(sof);
trace_point(TRACE_BOOT_SYS_SCHED);
scheduler_init(sof);

View File

@ -30,44 +30,40 @@
#include <sof/notifier.h>
#include <sof/sof.h>
#include <sof/lock.h>
#include <sof/list.h>
/* General purpose notifiers */
struct notify {
spinlock_t lock;
struct list_item list; /* list of notifiers */
};
static struct notify _notify;
#include <sof/alloc.h>
void notifier_register(struct notifier *notifier)
{
spin_lock(&_notify.lock);
list_item_prepend(&notifier->list, &_notify.list);
spin_unlock(&_notify.lock);
struct notify *notify = *arch_notify_get();
spin_lock(&notify->lock);
list_item_prepend(&notifier->list, &notify->list);
spin_unlock(&notify->lock);
}
void notifier_unregister(struct notifier *notifier)
{
spin_lock(&_notify.lock);
struct notify *notify = *arch_notify_get();
spin_lock(&notify->lock);
list_item_del(&notifier->list);
spin_unlock(&_notify.lock);
spin_unlock(&notify->lock);
}
void notifier_event(int id, int message, void *event_data)
{
struct notify *notify = *arch_notify_get();
struct list_item *wlist;
struct notifier *n;
spin_lock(&_notify.lock);
spin_lock(&notify->lock);
if (list_is_empty(&_notify.list))
if (list_is_empty(&notify->list))
goto out;
/* iterate through notifiers and send event to interested clients */
list_for_item(wlist, &_notify.list) {
list_for_item(wlist, &notify->list) {
n = container_of(wlist, struct notifier, list);
if (n->id == id)
@ -75,11 +71,23 @@ void notifier_event(int id, int message, void *event_data)
}
out:
spin_unlock(&_notify.lock);
spin_unlock(&notify->lock);
}
void init_system_notify(struct sof *sof)
{
list_init(&_notify.list);
spinlock_init(&_notify.lock);
struct notify **notify = arch_notify_get();
*notify = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, sizeof(**notify));
list_init(&(*notify)->list);
spinlock_init(&(*notify)->lock);
}
void free_system_notify(void)
{
struct notify *notify = *arch_notify_get();
spin_lock(&notify->lock);
list_item_del(&notify->list);
spin_unlock(&notify->lock);
}

View File

@ -501,13 +501,11 @@ struct work_queue *work_new_queue(struct work_queue_timesource *ts)
/* TODO: configurable through IPC */
queue->timeout = PLATFORM_WORKQ_DEFAULT_TIMEOUT;
if (cpu_get_id() == PLATFORM_MASTER_CORE_ID) {
/* notification of clk changes */
queue->notifier.cb = work_notify;
queue->notifier.cb_data = queue;
queue->notifier.id = ts->notifier;
notifier_register(&queue->notifier);
}
/* notification of clk changes */
queue->notifier.cb = work_notify;
queue->notifier.cb_data = queue;
queue->notifier.id = ts->notifier;
notifier_register(&queue->notifier);
/* register system timer */
timer_register(&queue->ts->timer, queue_run, queue);
@ -539,8 +537,7 @@ void free_system_workq(void)
timer_unregister(&(*queue)->ts->timer);
if (cpu_get_id() == PLATFORM_MASTER_CORE_ID)
notifier_unregister(&(*queue)->notifier);
notifier_unregister(&(*queue)->notifier);
list_item_del(&(*queue)->work);