1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2bbecb07fSUwe Kleine-König /*
3bbecb07fSUwe Kleine-König * Copyright (C) 2015 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
4bbecb07fSUwe Kleine-König */
5bbecb07fSUwe Kleine-König
6bbecb07fSUwe Kleine-König #include <linux/device.h>
7bbecb07fSUwe Kleine-König
8bbecb07fSUwe Kleine-König #define to_siox_device(_dev) container_of((_dev), struct siox_device, dev)
9bbecb07fSUwe Kleine-König struct siox_device {
10bbecb07fSUwe Kleine-König struct list_head node; /* node in smaster->devices */
11bbecb07fSUwe Kleine-König struct siox_master *smaster;
12bbecb07fSUwe Kleine-König struct device dev;
13bbecb07fSUwe Kleine-König
14bbecb07fSUwe Kleine-König const char *type;
15bbecb07fSUwe Kleine-König size_t inbytes;
16bbecb07fSUwe Kleine-König size_t outbytes;
17bbecb07fSUwe Kleine-König u8 statustype;
18bbecb07fSUwe Kleine-König
19bbecb07fSUwe Kleine-König u8 status_read_clean;
20bbecb07fSUwe Kleine-König u8 status_written;
21bbecb07fSUwe Kleine-König u8 status_written_lastcycle;
22bbecb07fSUwe Kleine-König bool connected;
23bbecb07fSUwe Kleine-König
24bbecb07fSUwe Kleine-König /* statistics */
25bbecb07fSUwe Kleine-König unsigned int watchdog_errors;
26bbecb07fSUwe Kleine-König unsigned int status_errors;
27bbecb07fSUwe Kleine-König
28bbecb07fSUwe Kleine-König struct kernfs_node *status_errors_kn;
29bbecb07fSUwe Kleine-König struct kernfs_node *watchdog_kn;
30bbecb07fSUwe Kleine-König struct kernfs_node *watchdog_errors_kn;
31bbecb07fSUwe Kleine-König struct kernfs_node *connected_kn;
32bbecb07fSUwe Kleine-König };
33bbecb07fSUwe Kleine-König
34bbecb07fSUwe Kleine-König bool siox_device_synced(struct siox_device *sdevice);
35bbecb07fSUwe Kleine-König bool siox_device_connected(struct siox_device *sdevice);
36bbecb07fSUwe Kleine-König
37bbecb07fSUwe Kleine-König struct siox_driver {
38bbecb07fSUwe Kleine-König int (*probe)(struct siox_device *sdevice);
39*1c12c270SUwe Kleine-König void (*remove)(struct siox_device *sdevice);
40bbecb07fSUwe Kleine-König void (*shutdown)(struct siox_device *sdevice);
41bbecb07fSUwe Kleine-König
42bbecb07fSUwe Kleine-König /*
43bbecb07fSUwe Kleine-König * buf is big enough to hold sdev->inbytes - 1 bytes, the status byte
44bbecb07fSUwe Kleine-König * is in the scope of the framework.
45bbecb07fSUwe Kleine-König */
46bbecb07fSUwe Kleine-König int (*set_data)(struct siox_device *sdevice, u8 status, u8 buf[]);
47bbecb07fSUwe Kleine-König /*
48bbecb07fSUwe Kleine-König * buf is big enough to hold sdev->outbytes - 1 bytes, the status byte
49bbecb07fSUwe Kleine-König * is in the scope of the framework
50bbecb07fSUwe Kleine-König */
51bbecb07fSUwe Kleine-König int (*get_data)(struct siox_device *sdevice, const u8 buf[]);
52bbecb07fSUwe Kleine-König
53bbecb07fSUwe Kleine-König struct device_driver driver;
54bbecb07fSUwe Kleine-König };
55bbecb07fSUwe Kleine-König
to_siox_driver(struct device_driver * driver)56bbecb07fSUwe Kleine-König static inline struct siox_driver *to_siox_driver(struct device_driver *driver)
57bbecb07fSUwe Kleine-König {
58bbecb07fSUwe Kleine-König if (driver)
59bbecb07fSUwe Kleine-König return container_of(driver, struct siox_driver, driver);
60bbecb07fSUwe Kleine-König else
61bbecb07fSUwe Kleine-König return NULL;
62bbecb07fSUwe Kleine-König }
63bbecb07fSUwe Kleine-König
64bbecb07fSUwe Kleine-König int __siox_driver_register(struct siox_driver *sdriver, struct module *owner);
65bbecb07fSUwe Kleine-König
siox_driver_register(struct siox_driver * sdriver)66bbecb07fSUwe Kleine-König static inline int siox_driver_register(struct siox_driver *sdriver)
67bbecb07fSUwe Kleine-König {
68bbecb07fSUwe Kleine-König return __siox_driver_register(sdriver, THIS_MODULE);
69bbecb07fSUwe Kleine-König }
70bbecb07fSUwe Kleine-König
siox_driver_unregister(struct siox_driver * sdriver)71bbecb07fSUwe Kleine-König static inline void siox_driver_unregister(struct siox_driver *sdriver)
72bbecb07fSUwe Kleine-König {
73bbecb07fSUwe Kleine-König return driver_unregister(&sdriver->driver);
74bbecb07fSUwe Kleine-König }
758f3fd895SEnrico Weigelt
768f3fd895SEnrico Weigelt /*
778f3fd895SEnrico Weigelt * module_siox_driver() - Helper macro for drivers that don't do
788f3fd895SEnrico Weigelt * anything special in module init/exit. This eliminates a lot of
798f3fd895SEnrico Weigelt * boilerplate. Each module may only use this macro once, and
808f3fd895SEnrico Weigelt * calling it replaces module_init() and module_exit()
818f3fd895SEnrico Weigelt */
828f3fd895SEnrico Weigelt #define module_siox_driver(__siox_driver) \
838f3fd895SEnrico Weigelt module_driver(__siox_driver, siox_driver_register, \
848f3fd895SEnrico Weigelt siox_driver_unregister)
85