19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2016 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef __ISR_H 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define __ISR_H 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 20c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos#include <stdbool.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 2257ceaaa0aa1fece02ff82cd903a26bdf65131c56Christopher Tate 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cpu.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <list.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <util.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <seos.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ChainedInterrupt { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project link_t isrs; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void (*const enable)(struct ChainedInterrupt *); 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void (*const disable)(struct ChainedInterrupt *); 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 34182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ChainedIsr { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project link_t node; 374870e9d5eba59fb257a87f97f1adf0b734cf48d3Dianne Hackborn 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t maxLatencyNs; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn bool (*func)(struct ChainedIsr *); 41c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate uint16_t tid; 42c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos}; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roosstatic inline void chainIsr(struct ChainedInterrupt *interrupt, struct ChainedIsr *isr) 453d658bf20e2d56e36941e7407deebeec1276fbcfDianne Hackborn{ 46c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos interrupt->disable(interrupt); 478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato isr->tid = osGetCurrentTid(); 483d658bf20e2d56e36941e7407deebeec1276fbcfDianne Hackborn list_add_tail(&interrupt->isrs, &isr->node); 49c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos interrupt->enable(interrupt); 50043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 524cb338de350d7afa8c2113a76d45c417c695be66Christopher Tatestatic inline void unchainIsr(struct ChainedInterrupt *interrupt, struct ChainedIsr *isr) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interrupt->disable(interrupt); 55043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn isr->tid = 0; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list_delete(&isr->node); 578103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (!list_is_empty(&interrupt->isrs)) 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interrupt->enable(interrupt); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 611f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwoodstatic inline bool dispatchIsr(struct ChainedInterrupt *interrupt) 621590f1ee7b7b7962f08e8cc29b9891b2ad124c9bChristopher Tate{ 6318a75f1123e7bb9c68d983ab266c1ad886b347a5Christopher Tate struct link_t *cur, *tmp; 64c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos bool handled = false; 654870e9d5eba59fb257a87f97f1adf0b734cf48d3Dianne Hackborn uint16_t oldTid = osGetCurrentTid(); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list_iterate(&interrupt->isrs, cur, tmp) { 68e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate struct ChainedIsr *curIsr = container_of(cur, struct ChainedIsr, node); 69e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate osSetCurrentTid(curIsr->tid); 70e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate handled = curIsr->func(curIsr); 71e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate if (handled) 72e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate break; 738103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 748103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn osSetCurrentTid(oldTid); 75182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return handled; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 79e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tatestatic inline int unchainIsrAll(struct ChainedInterrupt *interrupt, uint32_t tid) 80498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate{ 81498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate int count = 0; 82498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate struct link_t *cur, *tmp; 83498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate 84498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate list_iterate(&interrupt->isrs, cur, tmp) { 85498c6cbd78f42d4f6d2568ead6c2697fcfaa326eChristopher Tate struct ChainedIsr *curIsr = container_of(cur, struct ChainedIsr, node); 86e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate if (curIsr->tid == tid) { 87e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate unchainIsr(interrupt, curIsr); 88182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski count++; 89e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate } 90182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski } 91182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 92b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate return count; 93e0a22b324d0e3157e570ea5f71cc682fa9696e01Christopher Tate} 94182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 95182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinskistatic inline uint32_t maxLatencyIsr(struct ChainedInterrupt *interrupt) 96182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski{ 97182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski struct link_t *cur, *tmp; 98182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski uint32_t latency = 0; 99182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 100182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski list_iterate(&interrupt->isrs, cur, tmp) { 101c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos struct ChainedIsr *curIsr = container_of(cur, struct ChainedIsr, node); 1021e38382b542f5cef9957a89692b02c55a3dd351cDianne Hackborn if (!latency || (curIsr->maxLatencyNs && curIsr->maxLatencyNs < latency)) 103182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski latency = curIsr->maxLatencyNs; 104182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski } 105c42a1e1071937ae48b7aa5d6291a32c29078b74bAdrian Roos 106182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski return latency; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 108182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif /* __ISR_H */ 110182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski