1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2017
4  * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  */
6 
7 #define LOG_CATEGORY UCLASS_SYSINFO
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <sysinfo.h>
12 
13 struct sysinfo_priv {
14 	bool detected;
15 };
16 
sysinfo_get(struct udevice ** devp)17 int sysinfo_get(struct udevice **devp)
18 {
19 	int ret = uclass_first_device_err(UCLASS_SYSINFO, devp);
20 
21 	/*
22 	 * There is some very dodgy error handling in gazerbeam,
23 	 * do not return a device on error.
24 	 */
25 	if (ret)
26 		*devp = NULL;
27 	return ret;
28 }
29 
sysinfo_detect(struct udevice * dev)30 int sysinfo_detect(struct udevice *dev)
31 {
32 	int ret;
33 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
34 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
35 
36 	if (!ops->detect)
37 		return -ENOSYS;
38 
39 	ret = ops->detect(dev);
40 	if (!ret)
41 		priv->detected = true;
42 
43 	return ret;
44 }
45 
sysinfo_get_fit_loadable(struct udevice * dev,int index,const char * type,const char ** strp)46 int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
47 			     const char **strp)
48 {
49 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
50 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
51 
52 	if (!priv->detected)
53 		return -EPERM;
54 
55 	if (!ops->get_fit_loadable)
56 		return -ENOSYS;
57 
58 	return ops->get_fit_loadable(dev, index, type, strp);
59 }
60 
sysinfo_get_bool(struct udevice * dev,int id,bool * val)61 int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
62 {
63 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
64 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
65 
66 	if (!priv->detected)
67 		return -EPERM;
68 
69 	if (!ops->get_bool)
70 		return -ENOSYS;
71 
72 	return ops->get_bool(dev, id, val);
73 }
74 
sysinfo_get_int(struct udevice * dev,int id,int * val)75 int sysinfo_get_int(struct udevice *dev, int id, int *val)
76 {
77 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
78 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
79 
80 	if (!priv->detected)
81 		return -EPERM;
82 
83 	if (!ops->get_int)
84 		return -ENOSYS;
85 
86 	return ops->get_int(dev, id, val);
87 }
88 
sysinfo_get_str(struct udevice * dev,int id,size_t size,char * val)89 int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val)
90 {
91 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
92 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
93 
94 	if (!priv->detected)
95 		return -EPERM;
96 
97 	if (!ops->get_str)
98 		return -ENOSYS;
99 
100 	return ops->get_str(dev, id, size, val);
101 }
102 
103 UCLASS_DRIVER(sysinfo) = {
104 	.id		= UCLASS_SYSINFO,
105 	.name		= "sysinfo",
106 	.post_bind	= dm_scan_fdt_dev,
107 	.per_device_auto	= sizeof(bool),
108 };
109