diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/sa1110/devpower.c | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/sa1110/devpower.c')
| -rw-r--r-- | os/sa1110/devpower.c | 377 |
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, -}; |
