Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * driver.c - device id matching, driver model, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "base.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) static int compare_func(const char *ida, const char *idb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	/* we only need to compare the last 4 chars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	for (i = 3; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		if (ida[i] != 'X' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		    idb[i] != 'X' && toupper(ida[i]) != toupper(idb[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) int compare_pnp_id(struct pnp_id *pos, const char *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (!pos || !id || (strlen(id) != 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	if (memcmp(id, "ANYDEVS", 7) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	while (pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		if (memcmp(pos->id, id, 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 			if (compare_func(pos->id, id) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		pos = pos->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static const struct pnp_device_id *match_device(struct pnp_driver *drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 						struct pnp_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	const struct pnp_device_id *drv_id = drv->id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (!drv_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	while (*drv_id->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		if (compare_pnp_id(dev->id, drv_id->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			return drv_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		drv_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) int pnp_device_attach(struct pnp_dev *pnp_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	mutex_lock(&pnp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (pnp_dev->status != PNP_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		mutex_unlock(&pnp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	pnp_dev->status = PNP_ATTACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	mutex_unlock(&pnp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) void pnp_device_detach(struct pnp_dev *pnp_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	mutex_lock(&pnp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (pnp_dev->status == PNP_ATTACHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		pnp_dev->status = PNP_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	mutex_unlock(&pnp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static int pnp_device_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct pnp_driver *pnp_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct pnp_dev *pnp_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	const struct pnp_device_id *dev_id = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	pnp_drv = to_pnp_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	error = pnp_device_attach(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (pnp_dev->active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			error = pnp_activate_dev(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	} else if ((pnp_drv->flags & PNP_DRIVER_RES_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		   == PNP_DRIVER_RES_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		error = pnp_disable_dev(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (pnp_drv->probe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		dev_id = match_device(pnp_drv, pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		if (dev_id != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			error = pnp_drv->probe(pnp_dev, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (error >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		pnp_dev->driver = pnp_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	pnp_device_detach(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int pnp_device_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct pnp_dev *pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct pnp_driver *drv = pnp_dev->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (drv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		if (drv->remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			drv->remove(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		pnp_dev->driver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (pnp_dev->active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	    (!drv || !(drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		pnp_disable_dev(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	pnp_device_detach(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void pnp_device_shutdown(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct pnp_dev *pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct pnp_driver *drv = pnp_dev->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (drv && drv->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		drv->shutdown(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int pnp_bus_match(struct device *dev, struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct pnp_dev *pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct pnp_driver *pnp_drv = to_pnp_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (match_device(pnp_drv, pnp_dev) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int __pnp_bus_suspend(struct device *dev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct pnp_dev *pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct pnp_driver *pnp_drv = pnp_dev->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (!pnp_drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (pnp_drv->driver.pm && pnp_drv->driver.pm->suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		error = pnp_drv->driver.pm->suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		suspend_report_result(pnp_drv->driver.pm->suspend, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (pnp_drv->suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		error = pnp_drv->suspend(pnp_dev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (pnp_can_disable(pnp_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		error = pnp_stop_dev(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (pnp_can_suspend(pnp_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		pnp_dev->protocol->suspend(pnp_dev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int pnp_bus_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return __pnp_bus_suspend(dev, PMSG_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int pnp_bus_freeze(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return __pnp_bus_suspend(dev, PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int pnp_bus_poweroff(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return __pnp_bus_suspend(dev, PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int pnp_bus_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct pnp_dev *pnp_dev = to_pnp_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct pnp_driver *pnp_drv = pnp_dev->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (!pnp_drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (pnp_dev->protocol->resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		error = pnp_dev->protocol->resume(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (pnp_can_write(pnp_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		error = pnp_start_dev(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (pnp_drv->driver.pm && pnp_drv->driver.pm->resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		error = pnp_drv->driver.pm->resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if (pnp_drv->resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		error = pnp_drv->resume(pnp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static const struct dev_pm_ops pnp_bus_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	/* Suspend callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	.suspend = pnp_bus_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	.resume = pnp_bus_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	/* Hibernate callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	.freeze = pnp_bus_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	.thaw = pnp_bus_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	.poweroff = pnp_bus_poweroff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	.restore = pnp_bus_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct bus_type pnp_bus_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	.name    = "pnp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	.match   = pnp_bus_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	.probe   = pnp_device_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	.remove  = pnp_device_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	.shutdown = pnp_device_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	.pm	 = &pnp_bus_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	.dev_groups = pnp_dev_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int pnp_register_driver(struct pnp_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	drv->driver.name = drv->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	drv->driver.bus = &pnp_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return driver_register(&drv->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) void pnp_unregister_driver(struct pnp_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	driver_unregister(&drv->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * pnp_add_id - adds an EISA id to the specified device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * @dev: pointer to the desired device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * @id: pointer to an EISA id string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct pnp_id *dev_id, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	if (!dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	dev_id->id[0] = id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	dev_id->id[1] = id[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	dev_id->id[2] = id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	dev_id->id[3] = tolower(id[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	dev_id->id[4] = tolower(id[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	dev_id->id[5] = tolower(id[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	dev_id->id[6] = tolower(id[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	dev_id->id[7] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	dev_id->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	ptr = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	while (ptr && ptr->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		ptr = ptr->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		ptr->next = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		dev->id = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	return dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) EXPORT_SYMBOL(pnp_register_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) EXPORT_SYMBOL(pnp_unregister_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) EXPORT_SYMBOL(pnp_device_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) EXPORT_SYMBOL(pnp_device_detach);