summaryrefslogtreecommitdiff
path: root/os/sa1110/devpower.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/sa1110/devpower.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/sa1110/devpower.c')
-rw-r--r--os/sa1110/devpower.c377
1 files changed, 0 insertions, 377 deletions
diff --git a/os/sa1110/devpower.c b/os/sa1110/devpower.c
deleted file mode 100644
index c7cd5095..00000000
--- a/os/sa1110/devpower.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * power management
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-typedef struct Power Power;
-typedef struct Puser Puser;
-
-enum{
- Qdir,
- Qctl,
- Qdata
-};
-
-static
-Dirtab powertab[]={
- ".", {Qdir, 0, QTDIR}, 0, 0500,
- "powerctl", {Qctl, 0}, 0, 0600,
- "powerdata", {Qdata, 0}, 0, 0666,
-};
-
-struct Puser {
- Ref;
- ulong alarm; /* real time clock alarm time, if non-zero */
- QLock rl; /* mutual exclusion to protect r */
- Rendez r; /* wait for event of interest */
- int state; /* shutdown state of this process */
- Puser* next;
-};
-
-enum{
- Pwridle,
- Pwroff,
- Pwrack
-};
-
-static struct {
- QLock;
- Puser *list;
- Lock l; /* protect shutdown, nwaiting */
- int shutdown; /* non-zero if currently shutting down */
- int nwaiting; /* waiting for this many processes */
- Rendez ackr; /* wait here for all acks */
-} pwrusers;
-
-
-static Chan*
-powerattach(char* spec)
-{
- return devattach(L'↓', spec);
-}
-
-static int
-powerwalk(Chan* c, char* name)
-{
- return devwalk(c, name, powertab, nelem(powertab), devgen);
-}
-
-static void
-powerstat(Chan* c, char* db)
-{
- devstat(c, db, powertab, nelem(powertab), devgen);
-}
-
-static Chan*
-poweropen(Chan* c, int omode)
-{
- Puser *p;
-
- if(c->qid.type & QTDIR)
- return devopen(c, omode, powertab, nelem(powertab), devgen);
- switch(c->qid.path){
- case Qdata:
- p = mallocz(sizeof(Puser), 1);
- if(p == nil)
- error(Enovmem);
- p->state = Pwridle;
- p->ref = 1;
- if(waserror()){
- free(p);
- nexterror();
- }
- c = devopen(c, omode, powertab, nelem(powertab), devgen);
- c->aux = p;
- qlock(&pwrusers);
- p->next = pwrusers.list;
- pwrusers.list = p; /* note: must place on front of list for correct shutdown ordering */
- qunlock(&pwrusers);
- poperror();
- break;
- case Qctl:
- c = devopen(c, omode, powertab, nelem(powertab), devgen);
- break;
- }
- return c;
-}
-
-static Chan *
-powerclone(Chan *c, Chan *nc)
-{
- Puser *p;
-
- nc = devclone(c, nc);
- if((p = nc->aux) != nil)
- incref(p);
- return nc;
-}
-
-static void
-powerclose(Chan* c)
-{
- Puser *p, **l;
-
- if(c->qid.type & QTDIR || (c->flag & COPEN) == 0)
- return;
- p = c->aux;
- if(p != nil && decref(p) == 0){
- /* TO DO: cancel alarm */
- qlock(&pwrusers);
- for(l = &pwrusers.list; *l != nil; l = &(*l)->next)
- if(*l == p){
- *l = p->next;
- break;
- }
- qunlock(&pwrusers);
- free(p);
- }
-}
-
-static int
-isshutdown(void *a)
-{
- return ((Puser*)a)->state == Pwroff;
-}
-
-static long
-powerread(Chan* c, void* a, long n, vlong offset)
-{
- Puser *p;
- char *msg;
-
- switch(c->qid.path & ~CHDIR){
- case Qdir:
- return devdirread(c, a, n, powertab, nelem(powertab), devgen);
- case Qdata:
- p = c->aux;
- for(;;){
- if(!canqlock(&p->rl))
- error(Einuse); /* only one reader at a time */
- if(waserror()){
- qunlock(&p->rl);
- nexterror();
- }
- sleep(&p->r, isshutdown, p);
- poperror();
- qunlock(&p->rl);
- msg = nil;
- lock(p);
- if(p->state == Pwroff){
- msg = "power off";
- p->state = Pwrack;
- }
- unlock(p);
- if(msg != nil)
- return readstr(offset, a, n, msg);
- }
- break;
- case Qctl:
- default:
- n=0;
- break;
- }
- return n;
-}
-
-static int
-alldown(void*)
-{
- return pwrusers.nwaiting == 0;
-}
-
-static long
-powerwrite(Chan* c, void *a, long n, vlong)
-{
- Cmdbuf *cmd;
- Puser *p;
-
- if(c->qid.type & QTDIR)
- error(Ebadusefd);
- cmd = parsecmd(a, n);
- if(waserror()){
- free(cmd);
- nexterror();
- }
- switch(c->qid.path & ~CHDIR){
- case Qdata:
- p = c->aux;
- if(cmd->nf < 2)
- error(Ebadarg);
- if(strcmp(cmd->f[0], "ack") == 0){
- if(strcmp(cmd->f[1], "power") == 0){
- lock(p);
- if(p->state == Pwrack){
- lock(&pwrusers.l);
- if(pwrusers.shutdown && pwrusers.nwaiting > 0)
- pwrusers.nwaiting--;
- unlock(&pwrusers.l);
- wakeup(&pwrusers.ackr);
- p->state = Pwridle;
- }
- unlock(p);
- }else
- error(Ebadarg);
- }else if(strcmp(cmd->f[0], "alarm") == 0){
- /* set alarm */
- }else
- error(Ebadarg);
- break;
- case Qctl:
- if(cmd->nf < 1)
- error(Ebadarg);
- if(strcmp(cmd->f[0], "suspend") == 0){
- /* start the suspend action */
- qlock(&pwrusers);
- //powersuspend(0); /* calls poweringdown, then archsuspend() */
- qunlock(&pwrusers);
- }else if(strcmp(cmd->f[0], "shutdown") == 0){
- /* go to it */
- qlock(&pwrusers);
- if(waserror()){
- lock(&pwrusers.l);
- pwrusers.shutdown = 0; /* hard luck for those already notified */
- unlock(&pwrusers.l);
- qunlock(&pwrusers);
- nexterror();
- }
- lock(&pwrusers.l);
- pwrusers.shutdown = 1;
- pwrusers.nwaiting = 0;
- unlock(&pwrusers.l);
- for(p = pwrusers.list; p != nil; p = p->next){
- lock(p);
- if(p->state == Pwridle){
- p->state = Pwroff;
- lock(&pwrusers.l);
- pwrusers.nwaiting++;
- unlock(&pwrusers.l);
- }
- unlock(p);
- wakeup(&p->r);
- /* putting the tsleep here does each in turn; move out of loop to multicast */
- tsleep(&pwrusers.ackr, alldown, nil, 1000);
- }
- poperror();
- qunlock(&pwrusers);
- //powersuspend(1);
- }else
- error(Ebadarg);
- free(cmd);
- break;
- default:
- error(Ebadusefd);
- }
- poperror();
- return n;
-}
-
-/*
- * device-level power management: suspend/resume/shutdown
- */
-
-struct Power {
- void (*f)(int);
- Power* prev;
- Power* next;
-};
-
-static struct {
- Lock;
- Power list;
-} power;
-
-void
-powerenablereset(void)
-{
- power.list.next = power.list.prev = &power.list;
- power.list.f = (void*)-1; /* something not nil */
-}
-
-void
-powerenable(void (*f)(int))
-{
- Power *p, *l;
-
- p = malloc(sizeof(*p));
- p->f = f;
- p->prev = nil;
- p->next = nil;
- ilock(&power);
- for(l = power.list.next; l != &power.list; l = l->next)
- if(l->f == f){
- iunlock(&power);
- free(p);
- return;
- }
- l = &power.list;
- p->prev = l->prev;
- l->prev = p;
- p->next = l;
- p->prev->next = p;
- iunlock(&power);
-}
-
-void
-powerdisable(void (*f)(int))
-{
- Power *l;
-
- ilock(&power);
- for(l = power.list.next; l != &power.list; l = l->next)
- if(l->f == f){
- l->prev->next = l->next;
- l->next->prev = l->prev;
- free(l);
- break;
- }
- iunlock(&power);
-}
-
-/*
- * interrupts are assumed off so there's no need to lock
- */
-void
-poweringup(void)
-{
- Power *l;
-
- for(l = power.list.next; l != &power.list; l = l->next)
- (*l->f)(1);
-}
-
-void
-poweringdown(void)
-{
- Power *l;
-
- for(l = power.list.prev; l != &power.list; l = l->prev)
- (*l->f)(0);
-}
-
-Dev powerdevtab = {
- L'↓',
- "power",
-
- devreset,
- devinit,
- powerattach,
- devdetach,
- powerclone,
- powerwalk,
- powerstat,
- poweropen,
- devcreate,
- powerclose,
- powerread,
- devbread,
- powerwrite,
- devbwrite,
- devremove,
- devwstat,
-};