xref: /openbmc/linux/include/linux/surface_aggregator/device.h (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1eb0e90a8SMaximilian Luz /* SPDX-License-Identifier: GPL-2.0+ */
2eb0e90a8SMaximilian Luz /*
3eb0e90a8SMaximilian Luz  * Surface System Aggregator Module (SSAM) bus and client-device subsystem.
4eb0e90a8SMaximilian Luz  *
5eb0e90a8SMaximilian Luz  * Main interface for the surface-aggregator bus, surface-aggregator client
6eb0e90a8SMaximilian Luz  * devices, and respective drivers building on top of the SSAM controller.
7eb0e90a8SMaximilian Luz  * Provides support for non-platform/non-ACPI SSAM clients via dedicated
8eb0e90a8SMaximilian Luz  * subsystem.
9eb0e90a8SMaximilian Luz  *
10b2763358SMaximilian Luz  * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
11eb0e90a8SMaximilian Luz  */
12eb0e90a8SMaximilian Luz 
13eb0e90a8SMaximilian Luz #ifndef _LINUX_SURFACE_AGGREGATOR_DEVICE_H
14eb0e90a8SMaximilian Luz #define _LINUX_SURFACE_AGGREGATOR_DEVICE_H
15eb0e90a8SMaximilian Luz 
16eb0e90a8SMaximilian Luz #include <linux/device.h>
17eb0e90a8SMaximilian Luz #include <linux/mod_devicetable.h>
184a4ab610SMaximilian Luz #include <linux/property.h>
19eb0e90a8SMaximilian Luz #include <linux/types.h>
20eb0e90a8SMaximilian Luz 
21eb0e90a8SMaximilian Luz #include <linux/surface_aggregator/controller.h>
22eb0e90a8SMaximilian Luz 
23eb0e90a8SMaximilian Luz 
24eb0e90a8SMaximilian Luz /* -- Surface System Aggregator Module bus. --------------------------------- */
25eb0e90a8SMaximilian Luz 
26eb0e90a8SMaximilian Luz /**
27eb0e90a8SMaximilian Luz  * enum ssam_device_domain - SAM device domain.
28eb0e90a8SMaximilian Luz  * @SSAM_DOMAIN_VIRTUAL:   Virtual device.
29eb0e90a8SMaximilian Luz  * @SSAM_DOMAIN_SERIALHUB: Physical device connected via Surface Serial Hub.
30eb0e90a8SMaximilian Luz  */
31eb0e90a8SMaximilian Luz enum ssam_device_domain {
32eb0e90a8SMaximilian Luz 	SSAM_DOMAIN_VIRTUAL   = 0x00,
33eb0e90a8SMaximilian Luz 	SSAM_DOMAIN_SERIALHUB = 0x01,
34eb0e90a8SMaximilian Luz };
35eb0e90a8SMaximilian Luz 
36eb0e90a8SMaximilian Luz /**
37eb0e90a8SMaximilian Luz  * enum ssam_virtual_tc - Target categories for the virtual SAM domain.
38eb0e90a8SMaximilian Luz  * @SSAM_VIRTUAL_TC_HUB: Device hub category.
39eb0e90a8SMaximilian Luz  */
40eb0e90a8SMaximilian Luz enum ssam_virtual_tc {
41eb0e90a8SMaximilian Luz 	SSAM_VIRTUAL_TC_HUB = 0x00,
42eb0e90a8SMaximilian Luz };
43eb0e90a8SMaximilian Luz 
44eb0e90a8SMaximilian Luz /**
45eb0e90a8SMaximilian Luz  * struct ssam_device_uid - Unique identifier for SSAM device.
46eb0e90a8SMaximilian Luz  * @domain:   Domain of the device.
47eb0e90a8SMaximilian Luz  * @category: Target category of the device.
48eb0e90a8SMaximilian Luz  * @target:   Target ID of the device.
49eb0e90a8SMaximilian Luz  * @instance: Instance ID of the device.
50eb0e90a8SMaximilian Luz  * @function: Sub-function of the device. This field can be used to split a
51eb0e90a8SMaximilian Luz  *            single SAM device into multiple virtual subdevices to separate
52eb0e90a8SMaximilian Luz  *            different functionality of that device and allow one driver per
53eb0e90a8SMaximilian Luz  *            such functionality.
54eb0e90a8SMaximilian Luz  */
55eb0e90a8SMaximilian Luz struct ssam_device_uid {
56eb0e90a8SMaximilian Luz 	u8 domain;
57eb0e90a8SMaximilian Luz 	u8 category;
58eb0e90a8SMaximilian Luz 	u8 target;
59eb0e90a8SMaximilian Luz 	u8 instance;
60eb0e90a8SMaximilian Luz 	u8 function;
61eb0e90a8SMaximilian Luz };
62eb0e90a8SMaximilian Luz 
63eb0e90a8SMaximilian Luz /*
64eb0e90a8SMaximilian Luz  * Special values for device matching.
65eb0e90a8SMaximilian Luz  *
66eb0e90a8SMaximilian Luz  * These values are intended to be used with SSAM_DEVICE(), SSAM_VDEV(), and
67eb0e90a8SMaximilian Luz  * SSAM_SDEV() exclusively. Specifically, they are used to initialize the
68eb0e90a8SMaximilian Luz  * match_flags member of the device ID structure. Do not use them directly
69eb0e90a8SMaximilian Luz  * with struct ssam_device_id or struct ssam_device_uid.
70eb0e90a8SMaximilian Luz  */
7178abf1b5SMaximilian Luz #define SSAM_SSH_TID_ANY	0xffff
7278abf1b5SMaximilian Luz #define SSAM_SSH_IID_ANY	0xffff
7378abf1b5SMaximilian Luz #define SSAM_SSH_FUN_ANY	0xffff
74eb0e90a8SMaximilian Luz 
75eb0e90a8SMaximilian Luz /**
76eb0e90a8SMaximilian Luz  * SSAM_DEVICE() - Initialize a &struct ssam_device_id with the given
77eb0e90a8SMaximilian Luz  * parameters.
78eb0e90a8SMaximilian Luz  * @d:   Domain of the device.
79eb0e90a8SMaximilian Luz  * @cat: Target category of the device.
80eb0e90a8SMaximilian Luz  * @tid: Target ID of the device.
81eb0e90a8SMaximilian Luz  * @iid: Instance ID of the device.
82eb0e90a8SMaximilian Luz  * @fun: Sub-function of the device.
83eb0e90a8SMaximilian Luz  *
84eb0e90a8SMaximilian Luz  * Initializes a &struct ssam_device_id with the given parameters. See &struct
85eb0e90a8SMaximilian Luz  * ssam_device_uid for details regarding the parameters. The special values
8678abf1b5SMaximilian Luz  * %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and %SSAM_SSH_FUN_ANY can be used to specify that
87eb0e90a8SMaximilian Luz  * matching should ignore target ID, instance ID, and/or sub-function,
88eb0e90a8SMaximilian Luz  * respectively. This macro initializes the ``match_flags`` field based on the
89eb0e90a8SMaximilian Luz  * given parameters.
90eb0e90a8SMaximilian Luz  *
91eb0e90a8SMaximilian Luz  * Note: The parameters @d and @cat must be valid &u8 values, the parameters
9278abf1b5SMaximilian Luz  * @tid, @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
9378abf1b5SMaximilian Luz  * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values are not
94eb0e90a8SMaximilian Luz  * allowed.
95eb0e90a8SMaximilian Luz  */
96eb0e90a8SMaximilian Luz #define SSAM_DEVICE(d, cat, tid, iid, fun)					\
9778abf1b5SMaximilian Luz 	.match_flags = (((tid) != SSAM_SSH_TID_ANY) ? SSAM_MATCH_TARGET : 0)	\
9878abf1b5SMaximilian Luz 		     | (((iid) != SSAM_SSH_IID_ANY) ? SSAM_MATCH_INSTANCE : 0)	\
9978abf1b5SMaximilian Luz 		     | (((fun) != SSAM_SSH_FUN_ANY) ? SSAM_MATCH_FUNCTION : 0),	\
100eb0e90a8SMaximilian Luz 	.domain   = d,								\
101eb0e90a8SMaximilian Luz 	.category = cat,							\
10278abf1b5SMaximilian Luz 	.target   = __builtin_choose_expr((tid) != SSAM_SSH_TID_ANY, (tid), 0),	\
10378abf1b5SMaximilian Luz 	.instance = __builtin_choose_expr((iid) != SSAM_SSH_IID_ANY, (iid), 0),	\
10478abf1b5SMaximilian Luz 	.function = __builtin_choose_expr((fun) != SSAM_SSH_FUN_ANY, (fun), 0)
105eb0e90a8SMaximilian Luz 
106eb0e90a8SMaximilian Luz /**
107eb0e90a8SMaximilian Luz  * SSAM_VDEV() - Initialize a &struct ssam_device_id as virtual device with
108eb0e90a8SMaximilian Luz  * the given parameters.
109eb0e90a8SMaximilian Luz  * @cat: Target category of the device.
110eb0e90a8SMaximilian Luz  * @tid: Target ID of the device.
111eb0e90a8SMaximilian Luz  * @iid: Instance ID of the device.
112eb0e90a8SMaximilian Luz  * @fun: Sub-function of the device.
113eb0e90a8SMaximilian Luz  *
114eb0e90a8SMaximilian Luz  * Initializes a &struct ssam_device_id with the given parameters in the
115eb0e90a8SMaximilian Luz  * virtual domain. See &struct ssam_device_uid for details regarding the
11678abf1b5SMaximilian Luz  * parameters. The special values %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and
11778abf1b5SMaximilian Luz  * %SSAM_SSH_FUN_ANY can be used to specify that matching should ignore target ID,
118eb0e90a8SMaximilian Luz  * instance ID, and/or sub-function, respectively. This macro initializes the
119eb0e90a8SMaximilian Luz  * ``match_flags`` field based on the given parameters.
120eb0e90a8SMaximilian Luz  *
121eb0e90a8SMaximilian Luz  * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
12278abf1b5SMaximilian Luz  * @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
12378abf1b5SMaximilian Luz  * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values are not
124eb0e90a8SMaximilian Luz  * allowed.
125eb0e90a8SMaximilian Luz  */
126eb0e90a8SMaximilian Luz #define SSAM_VDEV(cat, tid, iid, fun) \
12778abf1b5SMaximilian Luz 	SSAM_DEVICE(SSAM_DOMAIN_VIRTUAL, SSAM_VIRTUAL_TC_##cat, SSAM_SSH_TID_##tid, iid, fun)
128eb0e90a8SMaximilian Luz 
129eb0e90a8SMaximilian Luz /**
130eb0e90a8SMaximilian Luz  * SSAM_SDEV() - Initialize a &struct ssam_device_id as physical SSH device
131eb0e90a8SMaximilian Luz  * with the given parameters.
132eb0e90a8SMaximilian Luz  * @cat: Target category of the device.
133eb0e90a8SMaximilian Luz  * @tid: Target ID of the device.
134eb0e90a8SMaximilian Luz  * @iid: Instance ID of the device.
135eb0e90a8SMaximilian Luz  * @fun: Sub-function of the device.
136eb0e90a8SMaximilian Luz  *
137eb0e90a8SMaximilian Luz  * Initializes a &struct ssam_device_id with the given parameters in the SSH
138eb0e90a8SMaximilian Luz  * domain. See &struct ssam_device_uid for details regarding the parameters.
13978abf1b5SMaximilian Luz  * The special values %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and
14078abf1b5SMaximilian Luz  * %SSAM_SSH_FUN_ANY can be used to specify that matching should ignore target
14178abf1b5SMaximilian Luz  * ID, instance ID, and/or sub-function, respectively. This macro initializes
14278abf1b5SMaximilian Luz  * the ``match_flags`` field based on the given parameters.
143eb0e90a8SMaximilian Luz  *
144eb0e90a8SMaximilian Luz  * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
14578abf1b5SMaximilian Luz  * @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
14678abf1b5SMaximilian Luz  * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values
14778abf1b5SMaximilian Luz  * are not allowed.
148eb0e90a8SMaximilian Luz  */
149eb0e90a8SMaximilian Luz #define SSAM_SDEV(cat, tid, iid, fun) \
15078abf1b5SMaximilian Luz 	SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, SSAM_SSH_TID_##tid, iid, fun)
151eb0e90a8SMaximilian Luz 
152dc0393c7SMaximilian Luz /*
153dc0393c7SMaximilian Luz  * enum ssam_device_flags - Flags for SSAM client devices.
154dc0393c7SMaximilian Luz  * @SSAM_DEVICE_HOT_REMOVED_BIT:
155dc0393c7SMaximilian Luz  *	The device has been hot-removed. Further communication with it may time
156dc0393c7SMaximilian Luz  *	out and should be avoided.
157dc0393c7SMaximilian Luz  */
158dc0393c7SMaximilian Luz enum ssam_device_flags {
159dc0393c7SMaximilian Luz 	SSAM_DEVICE_HOT_REMOVED_BIT = 0,
160dc0393c7SMaximilian Luz };
161dc0393c7SMaximilian Luz 
162eb0e90a8SMaximilian Luz /**
163eb0e90a8SMaximilian Luz  * struct ssam_device - SSAM client device.
164eb0e90a8SMaximilian Luz  * @dev:   Driver model representation of the device.
165eb0e90a8SMaximilian Luz  * @ctrl:  SSAM controller managing this device.
166eb0e90a8SMaximilian Luz  * @uid:   UID identifying the device.
167dc0393c7SMaximilian Luz  * @flags: Device state flags, see &enum ssam_device_flags.
168eb0e90a8SMaximilian Luz  */
169eb0e90a8SMaximilian Luz struct ssam_device {
170eb0e90a8SMaximilian Luz 	struct device dev;
171eb0e90a8SMaximilian Luz 	struct ssam_controller *ctrl;
172eb0e90a8SMaximilian Luz 
173eb0e90a8SMaximilian Luz 	struct ssam_device_uid uid;
174dc0393c7SMaximilian Luz 
175dc0393c7SMaximilian Luz 	unsigned long flags;
176eb0e90a8SMaximilian Luz };
177eb0e90a8SMaximilian Luz 
178eb0e90a8SMaximilian Luz /**
179eb0e90a8SMaximilian Luz  * struct ssam_device_driver - SSAM client device driver.
180eb0e90a8SMaximilian Luz  * @driver:      Base driver model structure.
181eb0e90a8SMaximilian Luz  * @match_table: Match table specifying which devices the driver should bind to.
182eb0e90a8SMaximilian Luz  * @probe:       Called when the driver is being bound to a device.
183eb0e90a8SMaximilian Luz  * @remove:      Called when the driver is being unbound from the device.
184eb0e90a8SMaximilian Luz  */
185eb0e90a8SMaximilian Luz struct ssam_device_driver {
186eb0e90a8SMaximilian Luz 	struct device_driver driver;
187eb0e90a8SMaximilian Luz 
188eb0e90a8SMaximilian Luz 	const struct ssam_device_id *match_table;
189eb0e90a8SMaximilian Luz 
190eb0e90a8SMaximilian Luz 	int  (*probe)(struct ssam_device *sdev);
191eb0e90a8SMaximilian Luz 	void (*remove)(struct ssam_device *sdev);
192eb0e90a8SMaximilian Luz };
193eb0e90a8SMaximilian Luz 
1940eb65840SMaximilian Luz #ifdef CONFIG_SURFACE_AGGREGATOR_BUS
1950eb65840SMaximilian Luz 
196eb0e90a8SMaximilian Luz extern struct bus_type ssam_bus_type;
197eb0e90a8SMaximilian Luz extern const struct device_type ssam_device_type;
198eb0e90a8SMaximilian Luz 
199eb0e90a8SMaximilian Luz /**
200eb0e90a8SMaximilian Luz  * is_ssam_device() - Check if the given device is a SSAM client device.
201eb0e90a8SMaximilian Luz  * @d: The device to test the type of.
202eb0e90a8SMaximilian Luz  *
203eb0e90a8SMaximilian Luz  * Return: Returns %true if the specified device is of type &struct
204eb0e90a8SMaximilian Luz  * ssam_device, i.e. the device type points to %ssam_device_type, and %false
205eb0e90a8SMaximilian Luz  * otherwise.
206eb0e90a8SMaximilian Luz  */
is_ssam_device(struct device * d)207eb0e90a8SMaximilian Luz static inline bool is_ssam_device(struct device *d)
208eb0e90a8SMaximilian Luz {
209eb0e90a8SMaximilian Luz 	return d->type == &ssam_device_type;
210eb0e90a8SMaximilian Luz }
211eb0e90a8SMaximilian Luz 
2120eb65840SMaximilian Luz #else /* CONFIG_SURFACE_AGGREGATOR_BUS */
2130eb65840SMaximilian Luz 
is_ssam_device(struct device * d)2140eb65840SMaximilian Luz static inline bool is_ssam_device(struct device *d)
2150eb65840SMaximilian Luz {
2160eb65840SMaximilian Luz 	return false;
2170eb65840SMaximilian Luz }
2180eb65840SMaximilian Luz 
2190eb65840SMaximilian Luz #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */
2200eb65840SMaximilian Luz 
221eb0e90a8SMaximilian Luz /**
222eb0e90a8SMaximilian Luz  * to_ssam_device() - Casts the given device to a SSAM client device.
223eb0e90a8SMaximilian Luz  * @d: The device to cast.
224eb0e90a8SMaximilian Luz  *
225eb0e90a8SMaximilian Luz  * Casts the given &struct device to a &struct ssam_device. The caller has to
226eb0e90a8SMaximilian Luz  * ensure that the given device is actually enclosed in a &struct ssam_device,
227eb0e90a8SMaximilian Luz  * e.g. by calling is_ssam_device().
228eb0e90a8SMaximilian Luz  *
229eb0e90a8SMaximilian Luz  * Return: Returns a pointer to the &struct ssam_device wrapping the given
230eb0e90a8SMaximilian Luz  * device @d.
231eb0e90a8SMaximilian Luz  */
23234be683aSGreg Kroah-Hartman #define to_ssam_device(d)	container_of_const(d, struct ssam_device, dev)
233eb0e90a8SMaximilian Luz 
234eb0e90a8SMaximilian Luz /**
235eb0e90a8SMaximilian Luz  * to_ssam_device_driver() - Casts the given device driver to a SSAM client
236eb0e90a8SMaximilian Luz  * device driver.
237eb0e90a8SMaximilian Luz  * @d: The driver to cast.
238eb0e90a8SMaximilian Luz  *
239eb0e90a8SMaximilian Luz  * Casts the given &struct device_driver to a &struct ssam_device_driver. The
240eb0e90a8SMaximilian Luz  * caller has to ensure that the given driver is actually enclosed in a
241eb0e90a8SMaximilian Luz  * &struct ssam_device_driver.
242eb0e90a8SMaximilian Luz  *
243eb0e90a8SMaximilian Luz  * Return: Returns the pointer to the &struct ssam_device_driver wrapping the
244eb0e90a8SMaximilian Luz  * given device driver @d.
245eb0e90a8SMaximilian Luz  */
246*ed08d937SMaximilian Luz #define to_ssam_device_driver(d)	container_of_const(d, struct ssam_device_driver, driver)
247eb0e90a8SMaximilian Luz 
248eb0e90a8SMaximilian Luz const struct ssam_device_id *ssam_device_id_match(const struct ssam_device_id *table,
249eb0e90a8SMaximilian Luz 						  const struct ssam_device_uid uid);
250eb0e90a8SMaximilian Luz 
251eb0e90a8SMaximilian Luz const struct ssam_device_id *ssam_device_get_match(const struct ssam_device *dev);
252eb0e90a8SMaximilian Luz 
253eb0e90a8SMaximilian Luz const void *ssam_device_get_match_data(const struct ssam_device *dev);
254eb0e90a8SMaximilian Luz 
255eb0e90a8SMaximilian Luz struct ssam_device *ssam_device_alloc(struct ssam_controller *ctrl,
256eb0e90a8SMaximilian Luz 				      struct ssam_device_uid uid);
257eb0e90a8SMaximilian Luz 
258eb0e90a8SMaximilian Luz int ssam_device_add(struct ssam_device *sdev);
259eb0e90a8SMaximilian Luz void ssam_device_remove(struct ssam_device *sdev);
260eb0e90a8SMaximilian Luz 
261eb0e90a8SMaximilian Luz /**
262dc0393c7SMaximilian Luz  * ssam_device_mark_hot_removed() - Mark the given device as hot-removed.
263dc0393c7SMaximilian Luz  * @sdev: The device to mark as hot-removed.
264dc0393c7SMaximilian Luz  *
265dc0393c7SMaximilian Luz  * Mark the device as having been hot-removed. This signals drivers using the
266dc0393c7SMaximilian Luz  * device that communication with the device should be avoided and may lead to
267dc0393c7SMaximilian Luz  * timeouts.
268dc0393c7SMaximilian Luz  */
ssam_device_mark_hot_removed(struct ssam_device * sdev)269dc0393c7SMaximilian Luz static inline void ssam_device_mark_hot_removed(struct ssam_device *sdev)
270dc0393c7SMaximilian Luz {
271dc0393c7SMaximilian Luz 	dev_dbg(&sdev->dev, "marking device as hot-removed\n");
272dc0393c7SMaximilian Luz 	set_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags);
273dc0393c7SMaximilian Luz }
274dc0393c7SMaximilian Luz 
275dc0393c7SMaximilian Luz /**
276dc0393c7SMaximilian Luz  * ssam_device_is_hot_removed() - Check if the given device has been
277dc0393c7SMaximilian Luz  * hot-removed.
278dc0393c7SMaximilian Luz  * @sdev: The device to check.
279dc0393c7SMaximilian Luz  *
280dc0393c7SMaximilian Luz  * Checks if the given device has been marked as hot-removed. See
281dc0393c7SMaximilian Luz  * ssam_device_mark_hot_removed() for more details.
282dc0393c7SMaximilian Luz  *
283dc0393c7SMaximilian Luz  * Return: Returns ``true`` if the device has been marked as hot-removed.
284dc0393c7SMaximilian Luz  */
ssam_device_is_hot_removed(struct ssam_device * sdev)285dc0393c7SMaximilian Luz static inline bool ssam_device_is_hot_removed(struct ssam_device *sdev)
286dc0393c7SMaximilian Luz {
287dc0393c7SMaximilian Luz 	return test_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags);
288dc0393c7SMaximilian Luz }
289dc0393c7SMaximilian Luz 
290dc0393c7SMaximilian Luz /**
291eb0e90a8SMaximilian Luz  * ssam_device_get() - Increment reference count of SSAM client device.
292eb0e90a8SMaximilian Luz  * @sdev: The device to increment the reference count of.
293eb0e90a8SMaximilian Luz  *
294eb0e90a8SMaximilian Luz  * Increments the reference count of the given SSAM client device by
295eb0e90a8SMaximilian Luz  * incrementing the reference count of the enclosed &struct device via
296eb0e90a8SMaximilian Luz  * get_device().
297eb0e90a8SMaximilian Luz  *
298eb0e90a8SMaximilian Luz  * See ssam_device_put() for the counter-part of this function.
299eb0e90a8SMaximilian Luz  *
300eb0e90a8SMaximilian Luz  * Return: Returns the device provided as input.
301eb0e90a8SMaximilian Luz  */
ssam_device_get(struct ssam_device * sdev)302eb0e90a8SMaximilian Luz static inline struct ssam_device *ssam_device_get(struct ssam_device *sdev)
303eb0e90a8SMaximilian Luz {
304eb0e90a8SMaximilian Luz 	return sdev ? to_ssam_device(get_device(&sdev->dev)) : NULL;
305eb0e90a8SMaximilian Luz }
306eb0e90a8SMaximilian Luz 
307eb0e90a8SMaximilian Luz /**
308eb0e90a8SMaximilian Luz  * ssam_device_put() - Decrement reference count of SSAM client device.
309eb0e90a8SMaximilian Luz  * @sdev: The device to decrement the reference count of.
310eb0e90a8SMaximilian Luz  *
311eb0e90a8SMaximilian Luz  * Decrements the reference count of the given SSAM client device by
312eb0e90a8SMaximilian Luz  * decrementing the reference count of the enclosed &struct device via
313eb0e90a8SMaximilian Luz  * put_device().
314eb0e90a8SMaximilian Luz  *
315eb0e90a8SMaximilian Luz  * See ssam_device_get() for the counter-part of this function.
316eb0e90a8SMaximilian Luz  */
ssam_device_put(struct ssam_device * sdev)317eb0e90a8SMaximilian Luz static inline void ssam_device_put(struct ssam_device *sdev)
318eb0e90a8SMaximilian Luz {
319eb0e90a8SMaximilian Luz 	if (sdev)
320eb0e90a8SMaximilian Luz 		put_device(&sdev->dev);
321eb0e90a8SMaximilian Luz }
322eb0e90a8SMaximilian Luz 
323eb0e90a8SMaximilian Luz /**
324eb0e90a8SMaximilian Luz  * ssam_device_get_drvdata() - Get driver-data of SSAM client device.
325eb0e90a8SMaximilian Luz  * @sdev: The device to get the driver-data from.
326eb0e90a8SMaximilian Luz  *
327eb0e90a8SMaximilian Luz  * Return: Returns the driver-data of the given device, previously set via
328eb0e90a8SMaximilian Luz  * ssam_device_set_drvdata().
329eb0e90a8SMaximilian Luz  */
ssam_device_get_drvdata(struct ssam_device * sdev)330eb0e90a8SMaximilian Luz static inline void *ssam_device_get_drvdata(struct ssam_device *sdev)
331eb0e90a8SMaximilian Luz {
332eb0e90a8SMaximilian Luz 	return dev_get_drvdata(&sdev->dev);
333eb0e90a8SMaximilian Luz }
334eb0e90a8SMaximilian Luz 
335eb0e90a8SMaximilian Luz /**
336eb0e90a8SMaximilian Luz  * ssam_device_set_drvdata() - Set driver-data of SSAM client device.
337eb0e90a8SMaximilian Luz  * @sdev: The device to set the driver-data of.
338eb0e90a8SMaximilian Luz  * @data: The data to set the device's driver-data pointer to.
339eb0e90a8SMaximilian Luz  */
ssam_device_set_drvdata(struct ssam_device * sdev,void * data)340eb0e90a8SMaximilian Luz static inline void ssam_device_set_drvdata(struct ssam_device *sdev, void *data)
341eb0e90a8SMaximilian Luz {
342eb0e90a8SMaximilian Luz 	dev_set_drvdata(&sdev->dev, data);
343eb0e90a8SMaximilian Luz }
344eb0e90a8SMaximilian Luz 
345eb0e90a8SMaximilian Luz int __ssam_device_driver_register(struct ssam_device_driver *d, struct module *o);
346eb0e90a8SMaximilian Luz void ssam_device_driver_unregister(struct ssam_device_driver *d);
347eb0e90a8SMaximilian Luz 
348eb0e90a8SMaximilian Luz /**
349eb0e90a8SMaximilian Luz  * ssam_device_driver_register() - Register a SSAM client device driver.
350eb0e90a8SMaximilian Luz  * @drv: The driver to register.
351eb0e90a8SMaximilian Luz  */
352eb0e90a8SMaximilian Luz #define ssam_device_driver_register(drv) \
353eb0e90a8SMaximilian Luz 	__ssam_device_driver_register(drv, THIS_MODULE)
354eb0e90a8SMaximilian Luz 
355eb0e90a8SMaximilian Luz /**
356eb0e90a8SMaximilian Luz  * module_ssam_device_driver() - Helper macro for SSAM device driver
357eb0e90a8SMaximilian Luz  * registration.
358eb0e90a8SMaximilian Luz  * @drv: The driver managed by this module.
359eb0e90a8SMaximilian Luz  *
360eb0e90a8SMaximilian Luz  * Helper macro to register a SSAM device driver via module_init() and
361eb0e90a8SMaximilian Luz  * module_exit(). This macro may only be used once per module and replaces the
362eb0e90a8SMaximilian Luz  * aforementioned definitions.
363eb0e90a8SMaximilian Luz  */
364eb0e90a8SMaximilian Luz #define module_ssam_device_driver(drv)			\
365eb0e90a8SMaximilian Luz 	module_driver(drv, ssam_device_driver_register,	\
366eb0e90a8SMaximilian Luz 		      ssam_device_driver_unregister)
367eb0e90a8SMaximilian Luz 
368eb0e90a8SMaximilian Luz 
36938543b72SMaximilian Luz /* -- Helpers for controller and hub devices. ------------------------------- */
37038543b72SMaximilian Luz 
37138543b72SMaximilian Luz #ifdef CONFIG_SURFACE_AGGREGATOR_BUS
3724a4ab610SMaximilian Luz 
3734a4ab610SMaximilian Luz int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl,
3744a4ab610SMaximilian Luz 			    struct fwnode_handle *node);
37538543b72SMaximilian Luz void ssam_remove_clients(struct device *dev);
3764a4ab610SMaximilian Luz 
37738543b72SMaximilian Luz #else /* CONFIG_SURFACE_AGGREGATOR_BUS */
3784a4ab610SMaximilian Luz 
__ssam_register_clients(struct device * parent,struct ssam_controller * ctrl,struct fwnode_handle * node)3794a4ab610SMaximilian Luz static inline int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl,
3804a4ab610SMaximilian Luz 					  struct fwnode_handle *node)
3814a4ab610SMaximilian Luz {
3824a4ab610SMaximilian Luz 	return 0;
3834a4ab610SMaximilian Luz }
3844a4ab610SMaximilian Luz 
ssam_remove_clients(struct device * dev)38538543b72SMaximilian Luz static inline void ssam_remove_clients(struct device *dev) {}
3864a4ab610SMaximilian Luz 
38738543b72SMaximilian Luz #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */
38838543b72SMaximilian Luz 
3894a4ab610SMaximilian Luz /**
3904a4ab610SMaximilian Luz  * ssam_register_clients() - Register all client devices defined under the
3914a4ab610SMaximilian Luz  * given parent device.
3924a4ab610SMaximilian Luz  * @dev: The parent device under which clients should be registered.
3934a4ab610SMaximilian Luz  * @ctrl: The controller with which client should be registered.
3944a4ab610SMaximilian Luz  *
3954a4ab610SMaximilian Luz  * Register all clients that have via firmware nodes been defined as children
3964a4ab610SMaximilian Luz  * of the given (parent) device. The respective child firmware nodes will be
3974a4ab610SMaximilian Luz  * associated with the correspondingly created child devices.
3984a4ab610SMaximilian Luz  *
3994a4ab610SMaximilian Luz  * The given controller will be used to instantiate the new devices. See
4004a4ab610SMaximilian Luz  * ssam_device_add() for details.
4014a4ab610SMaximilian Luz  *
4024a4ab610SMaximilian Luz  * Return: Returns zero on success, nonzero on failure.
4034a4ab610SMaximilian Luz  */
ssam_register_clients(struct device * dev,struct ssam_controller * ctrl)4044a4ab610SMaximilian Luz static inline int ssam_register_clients(struct device *dev, struct ssam_controller *ctrl)
4054a4ab610SMaximilian Luz {
4064a4ab610SMaximilian Luz 	return __ssam_register_clients(dev, ctrl, dev_fwnode(dev));
4074a4ab610SMaximilian Luz }
4084a4ab610SMaximilian Luz 
4094a4ab610SMaximilian Luz /**
4104a4ab610SMaximilian Luz  * ssam_device_register_clients() - Register all client devices defined under
4114a4ab610SMaximilian Luz  * the given SSAM parent device.
4124a4ab610SMaximilian Luz  * @sdev: The parent device under which clients should be registered.
4134a4ab610SMaximilian Luz  *
4144a4ab610SMaximilian Luz  * Register all clients that have via firmware nodes been defined as children
4154a4ab610SMaximilian Luz  * of the given (parent) device. The respective child firmware nodes will be
4164a4ab610SMaximilian Luz  * associated with the correspondingly created child devices.
4174a4ab610SMaximilian Luz  *
4184a4ab610SMaximilian Luz  * The controller used by the parent device will be used to instantiate the new
4194a4ab610SMaximilian Luz  * devices. See ssam_device_add() for details.
4204a4ab610SMaximilian Luz  *
4214a4ab610SMaximilian Luz  * Return: Returns zero on success, nonzero on failure.
4224a4ab610SMaximilian Luz  */
ssam_device_register_clients(struct ssam_device * sdev)4234a4ab610SMaximilian Luz static inline int ssam_device_register_clients(struct ssam_device *sdev)
4244a4ab610SMaximilian Luz {
4254a4ab610SMaximilian Luz 	return ssam_register_clients(&sdev->dev, sdev->ctrl);
4264a4ab610SMaximilian Luz }
4274a4ab610SMaximilian Luz 
42838543b72SMaximilian Luz 
429eb0e90a8SMaximilian Luz /* -- Helpers for client-device requests. ----------------------------------- */
430eb0e90a8SMaximilian Luz 
431eb0e90a8SMaximilian Luz /**
432eb0e90a8SMaximilian Luz  * SSAM_DEFINE_SYNC_REQUEST_CL_N() - Define synchronous client-device SAM
433eb0e90a8SMaximilian Luz  * request function with neither argument nor return value.
434eb0e90a8SMaximilian Luz  * @name: Name of the generated function.
435eb0e90a8SMaximilian Luz  * @spec: Specification (&struct ssam_request_spec_md) defining the request.
436eb0e90a8SMaximilian Luz  *
437eb0e90a8SMaximilian Luz  * Defines a function executing the synchronous SAM request specified by
438eb0e90a8SMaximilian Luz  * @spec, with the request having neither argument nor return value. Device
439eb0e90a8SMaximilian Luz  * specifying parameters are not hard-coded, but instead are provided via the
440eb0e90a8SMaximilian Luz  * client device, specifically its UID, supplied when calling this function.
441eb0e90a8SMaximilian Luz  * The generated function takes care of setting up the request struct, buffer
442eb0e90a8SMaximilian Luz  * allocation, as well as execution of the request itself, returning once the
443eb0e90a8SMaximilian Luz  * request has been fully completed. The required transport buffer will be
444eb0e90a8SMaximilian Luz  * allocated on the stack.
445eb0e90a8SMaximilian Luz  *
44603ee3183SMaximilian Luz  * The generated function is defined as ``static int name(struct ssam_device
44703ee3183SMaximilian Luz  * *sdev)``, returning the status of the request, which is zero on success and
44803ee3183SMaximilian Luz  * negative on failure. The ``sdev`` parameter specifies both the target
44903ee3183SMaximilian Luz  * device of the request and by association the controller via which the
45003ee3183SMaximilian Luz  * request is sent.
451eb0e90a8SMaximilian Luz  *
452b09ee1cdSMaximilian Luz  * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
453eb0e90a8SMaximilian Luz  * the generated function.
454eb0e90a8SMaximilian Luz  */
455eb0e90a8SMaximilian Luz #define SSAM_DEFINE_SYNC_REQUEST_CL_N(name, spec...)			\
456eb0e90a8SMaximilian Luz 	SSAM_DEFINE_SYNC_REQUEST_MD_N(__raw_##name, spec)		\
45703ee3183SMaximilian Luz 	static int name(struct ssam_device *sdev)			\
458eb0e90a8SMaximilian Luz 	{								\
459eb0e90a8SMaximilian Luz 		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
460eb0e90a8SMaximilian Luz 				    sdev->uid.instance);		\
461eb0e90a8SMaximilian Luz 	}
462eb0e90a8SMaximilian Luz 
463eb0e90a8SMaximilian Luz /**
464eb0e90a8SMaximilian Luz  * SSAM_DEFINE_SYNC_REQUEST_CL_W() - Define synchronous client-device SAM
465eb0e90a8SMaximilian Luz  * request function with argument.
466eb0e90a8SMaximilian Luz  * @name:  Name of the generated function.
467eb0e90a8SMaximilian Luz  * @atype: Type of the request's argument.
468eb0e90a8SMaximilian Luz  * @spec:  Specification (&struct ssam_request_spec_md) defining the request.
469eb0e90a8SMaximilian Luz  *
470eb0e90a8SMaximilian Luz  * Defines a function executing the synchronous SAM request specified by
471eb0e90a8SMaximilian Luz  * @spec, with the request taking an argument of type @atype and having no
472eb0e90a8SMaximilian Luz  * return value. Device specifying parameters are not hard-coded, but instead
473eb0e90a8SMaximilian Luz  * are provided via the client device, specifically its UID, supplied when
474eb0e90a8SMaximilian Luz  * calling this function. The generated function takes care of setting up the
475eb0e90a8SMaximilian Luz  * request struct, buffer allocation, as well as execution of the request
476eb0e90a8SMaximilian Luz  * itself, returning once the request has been fully completed. The required
477eb0e90a8SMaximilian Luz  * transport buffer will be allocated on the stack.
478eb0e90a8SMaximilian Luz  *
47903ee3183SMaximilian Luz  * The generated function is defined as ``static int name(struct ssam_device
48003ee3183SMaximilian Luz  * *sdev, const atype *arg)``, returning the status of the request, which is
48103ee3183SMaximilian Luz  * zero on success and negative on failure. The ``sdev`` parameter specifies
48203ee3183SMaximilian Luz  * both the target device of the request and by association the controller via
48303ee3183SMaximilian Luz  * which the request is sent. The request's argument is specified via the
48403ee3183SMaximilian Luz  * ``arg`` pointer.
485eb0e90a8SMaximilian Luz  *
486b09ee1cdSMaximilian Luz  * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
487eb0e90a8SMaximilian Luz  * the generated function.
488eb0e90a8SMaximilian Luz  */
489eb0e90a8SMaximilian Luz #define SSAM_DEFINE_SYNC_REQUEST_CL_W(name, atype, spec...)		\
490eb0e90a8SMaximilian Luz 	SSAM_DEFINE_SYNC_REQUEST_MD_W(__raw_##name, atype, spec)	\
49103ee3183SMaximilian Luz 	static int name(struct ssam_device *sdev, const atype *arg)	\
492eb0e90a8SMaximilian Luz 	{								\
493eb0e90a8SMaximilian Luz 		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
494eb0e90a8SMaximilian Luz 				    sdev->uid.instance, arg);		\
495eb0e90a8SMaximilian Luz 	}
496eb0e90a8SMaximilian Luz 
497eb0e90a8SMaximilian Luz /**
498eb0e90a8SMaximilian Luz  * SSAM_DEFINE_SYNC_REQUEST_CL_R() - Define synchronous client-device SAM
499eb0e90a8SMaximilian Luz  * request function with return value.
500eb0e90a8SMaximilian Luz  * @name:  Name of the generated function.
501eb0e90a8SMaximilian Luz  * @rtype: Type of the request's return value.
502eb0e90a8SMaximilian Luz  * @spec:  Specification (&struct ssam_request_spec_md) defining the request.
503eb0e90a8SMaximilian Luz  *
504eb0e90a8SMaximilian Luz  * Defines a function executing the synchronous SAM request specified by
505eb0e90a8SMaximilian Luz  * @spec, with the request taking no argument but having a return value of
506eb0e90a8SMaximilian Luz  * type @rtype. Device specifying parameters are not hard-coded, but instead
507eb0e90a8SMaximilian Luz  * are provided via the client device, specifically its UID, supplied when
508eb0e90a8SMaximilian Luz  * calling this function. The generated function takes care of setting up the
509eb0e90a8SMaximilian Luz  * request struct, buffer allocation, as well as execution of the request
510eb0e90a8SMaximilian Luz  * itself, returning once the request has been fully completed. The required
511eb0e90a8SMaximilian Luz  * transport buffer will be allocated on the stack.
512eb0e90a8SMaximilian Luz  *
51303ee3183SMaximilian Luz  * The generated function is defined as ``static int name(struct ssam_device
51403ee3183SMaximilian Luz  * *sdev, rtype *ret)``, returning the status of the request, which is zero on
515eb0e90a8SMaximilian Luz  * success and negative on failure. The ``sdev`` parameter specifies both the
516eb0e90a8SMaximilian Luz  * target device of the request and by association the controller via which
517eb0e90a8SMaximilian Luz  * the request is sent. The request's return value is written to the memory
518eb0e90a8SMaximilian Luz  * pointed to by the ``ret`` parameter.
519eb0e90a8SMaximilian Luz  *
520b09ee1cdSMaximilian Luz  * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
521eb0e90a8SMaximilian Luz  * the generated function.
522eb0e90a8SMaximilian Luz  */
523eb0e90a8SMaximilian Luz #define SSAM_DEFINE_SYNC_REQUEST_CL_R(name, rtype, spec...)		\
524eb0e90a8SMaximilian Luz 	SSAM_DEFINE_SYNC_REQUEST_MD_R(__raw_##name, rtype, spec)	\
52503ee3183SMaximilian Luz 	static int name(struct ssam_device *sdev, rtype *ret)		\
526eb0e90a8SMaximilian Luz 	{								\
527eb0e90a8SMaximilian Luz 		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
528eb0e90a8SMaximilian Luz 				    sdev->uid.instance, ret);		\
529eb0e90a8SMaximilian Luz 	}
530eb0e90a8SMaximilian Luz 
531eb003bf3SMaximilian Luz /**
532eb003bf3SMaximilian Luz  * SSAM_DEFINE_SYNC_REQUEST_CL_WR() - Define synchronous client-device SAM
533eb003bf3SMaximilian Luz  * request function with argument and return value.
534eb003bf3SMaximilian Luz  * @name:  Name of the generated function.
535eb003bf3SMaximilian Luz  * @atype: Type of the request's argument.
536eb003bf3SMaximilian Luz  * @rtype: Type of the request's return value.
537eb003bf3SMaximilian Luz  * @spec:  Specification (&struct ssam_request_spec_md) defining the request.
538eb003bf3SMaximilian Luz  *
539eb003bf3SMaximilian Luz  * Defines a function executing the synchronous SAM request specified by @spec,
540eb003bf3SMaximilian Luz  * with the request taking an argument of type @atype and having a return value
541eb003bf3SMaximilian Luz  * of type @rtype. Device specifying parameters are not hard-coded, but instead
542eb003bf3SMaximilian Luz  * are provided via the client device, specifically its UID, supplied when
543eb003bf3SMaximilian Luz  * calling this function. The generated function takes care of setting up the
544eb003bf3SMaximilian Luz  * request struct, buffer allocation, as well as execution of the request
545eb003bf3SMaximilian Luz  * itself, returning once the request has been fully completed. The required
546eb003bf3SMaximilian Luz  * transport buffer will be allocated on the stack.
547eb003bf3SMaximilian Luz  *
548eb003bf3SMaximilian Luz  * The generated function is defined as ``static int name(struct ssam_device
549eb003bf3SMaximilian Luz  * *sdev, const atype *arg, rtype *ret)``, returning the status of the request,
550eb003bf3SMaximilian Luz  * which is zero on success and negative on failure. The ``sdev`` parameter
551eb003bf3SMaximilian Luz  * specifies both the target device of the request and by association the
552eb003bf3SMaximilian Luz  * controller via which the request is sent. The request's argument is
553eb003bf3SMaximilian Luz  * specified via the ``arg`` pointer. The request's return value is written to
554eb003bf3SMaximilian Luz  * the memory pointed to by the ``ret`` parameter.
555eb003bf3SMaximilian Luz  *
556b09ee1cdSMaximilian Luz  * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
557eb003bf3SMaximilian Luz  * the generated function.
558eb003bf3SMaximilian Luz  */
559eb003bf3SMaximilian Luz #define SSAM_DEFINE_SYNC_REQUEST_CL_WR(name, atype, rtype, spec...)		\
560eb003bf3SMaximilian Luz 	SSAM_DEFINE_SYNC_REQUEST_MD_WR(__raw_##name, atype, rtype, spec)	\
561eb003bf3SMaximilian Luz 	static int name(struct ssam_device *sdev, const atype *arg, rtype *ret)	\
562eb003bf3SMaximilian Luz 	{									\
563eb003bf3SMaximilian Luz 		return __raw_##name(sdev->ctrl, sdev->uid.target,		\
564eb003bf3SMaximilian Luz 				    sdev->uid.instance, arg, ret);		\
565eb003bf3SMaximilian Luz 	}
566eb003bf3SMaximilian Luz 
5675c1e88b9SMaximilian Luz 
5685c1e88b9SMaximilian Luz /* -- Helpers for client-device notifiers. ---------------------------------- */
5695c1e88b9SMaximilian Luz 
5705c1e88b9SMaximilian Luz /**
5715c1e88b9SMaximilian Luz  * ssam_device_notifier_register() - Register an event notifier for the
5725c1e88b9SMaximilian Luz  * specified client device.
5735c1e88b9SMaximilian Luz  * @sdev: The device the notifier should be registered on.
5745c1e88b9SMaximilian Luz  * @n:    The event notifier to register.
5755c1e88b9SMaximilian Luz  *
5765c1e88b9SMaximilian Luz  * Register an event notifier. Increment the usage counter of the associated
5775c1e88b9SMaximilian Luz  * SAM event if the notifier is not marked as an observer. If the event is not
5785c1e88b9SMaximilian Luz  * marked as an observer and is currently not enabled, it will be enabled
5795c1e88b9SMaximilian Luz  * during this call. If the notifier is marked as an observer, no attempt will
5805c1e88b9SMaximilian Luz  * be made at enabling any event and no reference count will be modified.
5815c1e88b9SMaximilian Luz  *
5825c1e88b9SMaximilian Luz  * Notifiers marked as observers do not need to be associated with one specific
5835c1e88b9SMaximilian Luz  * event, i.e. as long as no event matching is performed, only the event target
5845c1e88b9SMaximilian Luz  * category needs to be set.
5855c1e88b9SMaximilian Luz  *
5865c1e88b9SMaximilian Luz  * Return: Returns zero on success, %-ENOSPC if there have already been
5875c1e88b9SMaximilian Luz  * %INT_MAX notifiers for the event ID/type associated with the notifier block
5885c1e88b9SMaximilian Luz  * registered, %-ENOMEM if the corresponding event entry could not be
5895c1e88b9SMaximilian Luz  * allocated, %-ENODEV if the device is marked as hot-removed. If this is the
5905c1e88b9SMaximilian Luz  * first time that a notifier block is registered for the specific associated
5915c1e88b9SMaximilian Luz  * event, returns the status of the event-enable EC-command.
5925c1e88b9SMaximilian Luz  */
ssam_device_notifier_register(struct ssam_device * sdev,struct ssam_event_notifier * n)5935c1e88b9SMaximilian Luz static inline int ssam_device_notifier_register(struct ssam_device *sdev,
5945c1e88b9SMaximilian Luz 						struct ssam_event_notifier *n)
5955c1e88b9SMaximilian Luz {
5965c1e88b9SMaximilian Luz 	/*
5975c1e88b9SMaximilian Luz 	 * Note that this check does not provide any guarantees whatsoever as
5985c1e88b9SMaximilian Luz 	 * hot-removal could happen at any point and we can't protect against
5995c1e88b9SMaximilian Luz 	 * it. Nevertheless, if we can detect hot-removal, bail early to avoid
6005c1e88b9SMaximilian Luz 	 * communication timeouts.
6015c1e88b9SMaximilian Luz 	 */
6025c1e88b9SMaximilian Luz 	if (ssam_device_is_hot_removed(sdev))
6035c1e88b9SMaximilian Luz 		return -ENODEV;
6045c1e88b9SMaximilian Luz 
6055c1e88b9SMaximilian Luz 	return ssam_notifier_register(sdev->ctrl, n);
6065c1e88b9SMaximilian Luz }
6075c1e88b9SMaximilian Luz 
6085c1e88b9SMaximilian Luz /**
6095c1e88b9SMaximilian Luz  * ssam_device_notifier_unregister() - Unregister an event notifier for the
6105c1e88b9SMaximilian Luz  * specified client device.
6115c1e88b9SMaximilian Luz  * @sdev: The device the notifier has been registered on.
6125c1e88b9SMaximilian Luz  * @n:    The event notifier to unregister.
6135c1e88b9SMaximilian Luz  *
6145c1e88b9SMaximilian Luz  * Unregister an event notifier. Decrement the usage counter of the associated
6155c1e88b9SMaximilian Luz  * SAM event if the notifier is not marked as an observer. If the usage counter
6165c1e88b9SMaximilian Luz  * reaches zero, the event will be disabled.
6175c1e88b9SMaximilian Luz  *
6185c1e88b9SMaximilian Luz  * In case the device has been marked as hot-removed, the event will not be
6195c1e88b9SMaximilian Luz  * disabled on the EC, as in those cases any attempt at doing so may time out.
6205c1e88b9SMaximilian Luz  *
6215c1e88b9SMaximilian Luz  * Return: Returns zero on success, %-ENOENT if the given notifier block has
6225c1e88b9SMaximilian Luz  * not been registered on the controller. If the given notifier block was the
6235c1e88b9SMaximilian Luz  * last one associated with its specific event, returns the status of the
6245c1e88b9SMaximilian Luz  * event-disable EC-command.
6255c1e88b9SMaximilian Luz  */
ssam_device_notifier_unregister(struct ssam_device * sdev,struct ssam_event_notifier * n)6265c1e88b9SMaximilian Luz static inline int ssam_device_notifier_unregister(struct ssam_device *sdev,
6275c1e88b9SMaximilian Luz 						  struct ssam_event_notifier *n)
6285c1e88b9SMaximilian Luz {
6295c1e88b9SMaximilian Luz 	return __ssam_notifier_unregister(sdev->ctrl, n,
6305c1e88b9SMaximilian Luz 					  !ssam_device_is_hot_removed(sdev));
6315c1e88b9SMaximilian Luz }
6325c1e88b9SMaximilian Luz 
633eb0e90a8SMaximilian Luz #endif /* _LINUX_SURFACE_AGGREGATOR_DEVICE_H */
634