/* * Copyright (c) 2012 Corey Tabaka * * Use of this source code is governed by a MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT */ #include #include #include #include /* static list of devices constructed with DEVICE_INSTANCE macros */ extern struct device __start_devices[] __WEAK; extern struct device __stop_devices[] __WEAK; status_t device_init_all(void) { status_t res = NO_ERROR; for (struct device *dev = __start_devices; dev != __stop_devices; dev++) { if (dev->flags & DEVICE_FLAG_AUTOINIT) { status_t code = device_init(dev); if (code < 0) { TRACEF("Driver init failed for driver \"%s\", device \"%s\", reason %d\n", dev->driver->type, dev->name, code); res = code; } } } return res; } status_t device_fini_all(void) { status_t res = NO_ERROR; for (struct device *dev = __start_devices; dev != __stop_devices; dev++) { status_t code = device_fini(dev); if (code < 0) { TRACEF("Driver fini failed for driver \"%s\", device \"%s\", reason %d\n", dev->driver->type, dev->name, code); res = code; } } return res; } status_t device_init(struct device *dev) { if (!dev) return ERR_INVALID_ARGS; DEBUG_ASSERT(dev->driver); const struct driver_ops *ops = dev->driver->ops; if (ops && ops->init) { dprintf(INFO, "dev: initializing device %s:%s\n", dev->driver->type, dev->name); status_t err = ops->init(dev); if (err < 0) { dev->device_state = DEVICE_INITIALIZED_FAILED; } else { dev->device_state = DEVICE_INITIALIZED; } return err; } else { return ERR_NOT_SUPPORTED; } } status_t device_fini(struct device *dev) { if (!dev) return ERR_INVALID_ARGS; DEBUG_ASSERT(dev->driver); const struct driver_ops *ops = dev->driver->ops; if (ops && ops->fini) return ops->fini(dev); else return ERR_NOT_SUPPORTED; } status_t device_suspend(struct device *dev) { if (!dev) return ERR_NOT_SUPPORTED; DEBUG_ASSERT(dev->driver); const struct driver_ops *ops = dev->driver->ops; if (ops && ops->suspend) return ops->suspend(dev); else return ERR_NOT_SUPPORTED; } status_t device_resume(struct device *dev) { if (!dev) return ERR_NOT_SUPPORTED; DEBUG_ASSERT(dev->driver); const struct driver_ops *ops = dev->driver->ops; if (ops && ops->resume) return ops->resume(dev); else return ERR_NOT_SUPPORTED; }