Chápu to tak, že kernel musí obsahovat obecné GPIO API a specifický ovladač nebo nějaký definiční soubor (v rámci device tree?) pro RPi, takže ví, jak IRQ nakonfigurovat a když přijde, tak ho umí taky třeba ACKnout, což bych z user space dělal asi dost těžko...
Tak nejak.. delat polling interrupt flagu a acknout ho z userspace jde, pokud mate privilegia na pristup na dane adresy (mmio) nebo io porty, ale v ramci moderniho OS nemate sanci nastavit vektor preruseni, i kdyz vite kam ho zapsat, tohle musi resit kernel - protoze ten jedinej ma persistentni virtualni adresy (v x86 cs selektor).
Pred GPIO interruptem existoval navrh na IRQ API, kde v kernelu je kratky handler a jinak to funguje znova skrze poll():
https://lwn.net/Articles/127698/ (stejny zpusob pouziti, skrze poll)
Díky za ten odkaz... moc hezké čtení, v podstatě to shrnuje všechny moje námitky :-)
User space chápu jako prostor, který je od hardwaru naschvál poněkud izolován, běží nad nějakou abstrakcí stroje s jednotným softwarovým rozhraním. User space je prostředí relativně lenivé, pokud se týče doby odezvy a její garance, ale na druhou stranu nijak děsivé pro programátora - a v zájmu stability systému toho user space zas tak moc nesmí.
ACKování IRQ je věc, kterou se patří dělat v "IRQ kontextu", což je z hlediska plánování procesů/tasků atd. poměrně vyjímečné místo s výsadními právy, zejména vysokou prioritou běhu, např. tam může být zakázáno další přerušení (nebo lze znovu rekurzivně přerušit jen IRQ linkou o vyšší prioritě). Pointa je v tom, že kromě ACKnutí interruptu standardním způsobem hostitelovu řadiči přerušení (tzn. charakteristicky pro danou platformu počítače) mívají jednotlivé periferie svá vlastní pravidla, jak je třeba v dané periferii HW-specificky zašťourat, aby (v kontextu naší debaty) dočasně zmlkla, tzn. aby po návratu obsluhy přerušení (ISR) nebyla obsluha volána okamžitě znovu toutéž periferií. Viz level-triggered IRQ na PCI, tam se snad ani nic "genericky" neACKuje. Druhá varianta je, že pokud IRQ řádně neACKnete HW-specifickým způsobem, periferie už nikdy další interrupt nepošle (toho bych se bál u edge-triggered IRQ) - ale tato varianta je obecně snad méně časově kritická, a zrovna tenhle druh ACKu by se dal odložit do nějaké té "obsluhy druhé úrovně" (ACK je proveden nějakým relativně standardním = řádně plánovaným taskem, v kernelu nebo i v user space).
Chci říct, že ISR kontext a user space jsou dost protichůdná prostředí. ISR kontext má přednost i před kernelovými tasky. Naopak mít v user space zakázané interrupty? Z toho mám trochu husí kůži... Plánovač procesů potřebuje povolené interrupty ke svému provozu. Nemám teď úplně jasno, jak "drahý" je odskok do normální kernelové obsluhy IRQ, vs. co by znamenalo, mít obsluhu navíc v adresním režimu user space (jestli by ten context switch byl nutně těžkotonážnější).
V tom historickém kontextu na LWN se správně píše, že se věc komplikuje u sdílených IRQ linek, a že ohledně zmíněného HW-specifického ACKování v samotné periferii byl i nějaký návrh, toto pro jednodušší případy popsat nějakým structem, který by se dal předat při inicializaci user-mode driveru z user space do kernelu, a generická obsluha (ISR) v první linii v kernelu by podle tohoto "receptu" provedla základní držhubný ACK, aby se interrupt mohl odblokovat (například pro další periferie sdílející tutéž linku). Pokud mohu soudit, neujalo se to...
Tzn. request_irq(IRQ,*obsluha) podle mého patří právem do kernelu, v user space bych se tohoto nedožadoval :-) Mimochodem v kernelu request_irq() nezapisuje přímo do tabulky vektorů, se kterou pracuje CPU LAPIC - kernel má jednotnou super-obsluhu, která se zavěsí na všechna IRQ obsluhovaná LAPICem, a teprve tahle superobsluha volá obslužné rutiny (callbacky) registrované jednotlivými drivery (kernelovými moduly). Je to pravda už hodně dávno, co jsem to ve zdrojákách našel - snad se na tom moc nezměnilo :-) Dovedu si představit, že tahle superobsluha umí čítat počty interruptů (pokud to nedělá hardware LAPICu) a mám pocit, že přímo tahle superobsluha umí po ukončení "užitečné" obsluhy taky zavolat plánovač, tzn. v tom případě není pravda, že je plánovač probouzen pouze konkrétním časovačem (a procesy, které se procesoru dobrovolně vzdají tím, že usnou/zablokují se).
Hergot to jsem zase ujel...