![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0+ */ 0002 /* 0003 * Surface System Aggregator Module (SSAM) bus and client-device subsystem. 0004 * 0005 * Main interface for the surface-aggregator bus, surface-aggregator client 0006 * devices, and respective drivers building on top of the SSAM controller. 0007 * Provides support for non-platform/non-ACPI SSAM clients via dedicated 0008 * subsystem. 0009 * 0010 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> 0011 */ 0012 0013 #ifndef _LINUX_SURFACE_AGGREGATOR_DEVICE_H 0014 #define _LINUX_SURFACE_AGGREGATOR_DEVICE_H 0015 0016 #include <linux/device.h> 0017 #include <linux/mod_devicetable.h> 0018 #include <linux/property.h> 0019 #include <linux/types.h> 0020 0021 #include <linux/surface_aggregator/controller.h> 0022 0023 0024 /* -- Surface System Aggregator Module bus. --------------------------------- */ 0025 0026 /** 0027 * enum ssam_device_domain - SAM device domain. 0028 * @SSAM_DOMAIN_VIRTUAL: Virtual device. 0029 * @SSAM_DOMAIN_SERIALHUB: Physical device connected via Surface Serial Hub. 0030 */ 0031 enum ssam_device_domain { 0032 SSAM_DOMAIN_VIRTUAL = 0x00, 0033 SSAM_DOMAIN_SERIALHUB = 0x01, 0034 }; 0035 0036 /** 0037 * enum ssam_virtual_tc - Target categories for the virtual SAM domain. 0038 * @SSAM_VIRTUAL_TC_HUB: Device hub category. 0039 */ 0040 enum ssam_virtual_tc { 0041 SSAM_VIRTUAL_TC_HUB = 0x00, 0042 }; 0043 0044 /** 0045 * struct ssam_device_uid - Unique identifier for SSAM device. 0046 * @domain: Domain of the device. 0047 * @category: Target category of the device. 0048 * @target: Target ID of the device. 0049 * @instance: Instance ID of the device. 0050 * @function: Sub-function of the device. This field can be used to split a 0051 * single SAM device into multiple virtual subdevices to separate 0052 * different functionality of that device and allow one driver per 0053 * such functionality. 0054 */ 0055 struct ssam_device_uid { 0056 u8 domain; 0057 u8 category; 0058 u8 target; 0059 u8 instance; 0060 u8 function; 0061 }; 0062 0063 /* 0064 * Special values for device matching. 0065 * 0066 * These values are intended to be used with SSAM_DEVICE(), SSAM_VDEV(), and 0067 * SSAM_SDEV() exclusively. Specifically, they are used to initialize the 0068 * match_flags member of the device ID structure. Do not use them directly 0069 * with struct ssam_device_id or struct ssam_device_uid. 0070 */ 0071 #define SSAM_ANY_TID 0xffff 0072 #define SSAM_ANY_IID 0xffff 0073 #define SSAM_ANY_FUN 0xffff 0074 0075 /** 0076 * SSAM_DEVICE() - Initialize a &struct ssam_device_id with the given 0077 * parameters. 0078 * @d: Domain of the device. 0079 * @cat: Target category of the device. 0080 * @tid: Target ID of the device. 0081 * @iid: Instance ID of the device. 0082 * @fun: Sub-function of the device. 0083 * 0084 * Initializes a &struct ssam_device_id with the given parameters. See &struct 0085 * ssam_device_uid for details regarding the parameters. The special values 0086 * %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be used to specify that 0087 * matching should ignore target ID, instance ID, and/or sub-function, 0088 * respectively. This macro initializes the ``match_flags`` field based on the 0089 * given parameters. 0090 * 0091 * Note: The parameters @d and @cat must be valid &u8 values, the parameters 0092 * @tid, @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID, 0093 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not 0094 * allowed. 0095 */ 0096 #define SSAM_DEVICE(d, cat, tid, iid, fun) \ 0097 .match_flags = (((tid) != SSAM_ANY_TID) ? SSAM_MATCH_TARGET : 0) \ 0098 | (((iid) != SSAM_ANY_IID) ? SSAM_MATCH_INSTANCE : 0) \ 0099 | (((fun) != SSAM_ANY_FUN) ? SSAM_MATCH_FUNCTION : 0), \ 0100 .domain = d, \ 0101 .category = cat, \ 0102 .target = __builtin_choose_expr((tid) != SSAM_ANY_TID, (tid), 0), \ 0103 .instance = __builtin_choose_expr((iid) != SSAM_ANY_IID, (iid), 0), \ 0104 .function = __builtin_choose_expr((fun) != SSAM_ANY_FUN, (fun), 0) 0105 0106 /** 0107 * SSAM_VDEV() - Initialize a &struct ssam_device_id as virtual device with 0108 * the given parameters. 0109 * @cat: Target category of the device. 0110 * @tid: Target ID of the device. 0111 * @iid: Instance ID of the device. 0112 * @fun: Sub-function of the device. 0113 * 0114 * Initializes a &struct ssam_device_id with the given parameters in the 0115 * virtual domain. See &struct ssam_device_uid for details regarding the 0116 * parameters. The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and 0117 * %SSAM_ANY_FUN can be used to specify that matching should ignore target ID, 0118 * instance ID, and/or sub-function, respectively. This macro initializes the 0119 * ``match_flags`` field based on the given parameters. 0120 * 0121 * Note: The parameter @cat must be a valid &u8 value, the parameters @tid, 0122 * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID, 0123 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not 0124 * allowed. 0125 */ 0126 #define SSAM_VDEV(cat, tid, iid, fun) \ 0127 SSAM_DEVICE(SSAM_DOMAIN_VIRTUAL, SSAM_VIRTUAL_TC_##cat, tid, iid, fun) 0128 0129 /** 0130 * SSAM_SDEV() - Initialize a &struct ssam_device_id as physical SSH device 0131 * with the given parameters. 0132 * @cat: Target category of the device. 0133 * @tid: Target ID of the device. 0134 * @iid: Instance ID of the device. 0135 * @fun: Sub-function of the device. 0136 * 0137 * Initializes a &struct ssam_device_id with the given parameters in the SSH 0138 * domain. See &struct ssam_device_uid for details regarding the parameters. 0139 * The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be 0140 * used to specify that matching should ignore target ID, instance ID, and/or 0141 * sub-function, respectively. This macro initializes the ``match_flags`` 0142 * field based on the given parameters. 0143 * 0144 * Note: The parameter @cat must be a valid &u8 value, the parameters @tid, 0145 * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID, 0146 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not 0147 * allowed. 0148 */ 0149 #define SSAM_SDEV(cat, tid, iid, fun) \ 0150 SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, tid, iid, fun) 0151 0152 /* 0153 * enum ssam_device_flags - Flags for SSAM client devices. 0154 * @SSAM_DEVICE_HOT_REMOVED_BIT: 0155 * The device has been hot-removed. Further communication with it may time 0156 * out and should be avoided. 0157 */ 0158 enum ssam_device_flags { 0159 SSAM_DEVICE_HOT_REMOVED_BIT = 0, 0160 }; 0161 0162 /** 0163 * struct ssam_device - SSAM client device. 0164 * @dev: Driver model representation of the device. 0165 * @ctrl: SSAM controller managing this device. 0166 * @uid: UID identifying the device. 0167 * @flags: Device state flags, see &enum ssam_device_flags. 0168 */ 0169 struct ssam_device { 0170 struct device dev; 0171 struct ssam_controller *ctrl; 0172 0173 struct ssam_device_uid uid; 0174 0175 unsigned long flags; 0176 }; 0177 0178 /** 0179 * struct ssam_device_driver - SSAM client device driver. 0180 * @driver: Base driver model structure. 0181 * @match_table: Match table specifying which devices the driver should bind to. 0182 * @probe: Called when the driver is being bound to a device. 0183 * @remove: Called when the driver is being unbound from the device. 0184 */ 0185 struct ssam_device_driver { 0186 struct device_driver driver; 0187 0188 const struct ssam_device_id *match_table; 0189 0190 int (*probe)(struct ssam_device *sdev); 0191 void (*remove)(struct ssam_device *sdev); 0192 }; 0193 0194 #ifdef CONFIG_SURFACE_AGGREGATOR_BUS 0195 0196 extern struct bus_type ssam_bus_type; 0197 extern const struct device_type ssam_device_type; 0198 0199 /** 0200 * is_ssam_device() - Check if the given device is a SSAM client device. 0201 * @d: The device to test the type of. 0202 * 0203 * Return: Returns %true if the specified device is of type &struct 0204 * ssam_device, i.e. the device type points to %ssam_device_type, and %false 0205 * otherwise. 0206 */ 0207 static inline bool is_ssam_device(struct device *d) 0208 { 0209 return d->type == &ssam_device_type; 0210 } 0211 0212 #else /* CONFIG_SURFACE_AGGREGATOR_BUS */ 0213 0214 static inline bool is_ssam_device(struct device *d) 0215 { 0216 return false; 0217 } 0218 0219 #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */ 0220 0221 /** 0222 * to_ssam_device() - Casts the given device to a SSAM client device. 0223 * @d: The device to cast. 0224 * 0225 * Casts the given &struct device to a &struct ssam_device. The caller has to 0226 * ensure that the given device is actually enclosed in a &struct ssam_device, 0227 * e.g. by calling is_ssam_device(). 0228 * 0229 * Return: Returns a pointer to the &struct ssam_device wrapping the given 0230 * device @d. 0231 */ 0232 static inline struct ssam_device *to_ssam_device(struct device *d) 0233 { 0234 return container_of(d, struct ssam_device, dev); 0235 } 0236 0237 /** 0238 * to_ssam_device_driver() - Casts the given device driver to a SSAM client 0239 * device driver. 0240 * @d: The driver to cast. 0241 * 0242 * Casts the given &struct device_driver to a &struct ssam_device_driver. The 0243 * caller has to ensure that the given driver is actually enclosed in a 0244 * &struct ssam_device_driver. 0245 * 0246 * Return: Returns the pointer to the &struct ssam_device_driver wrapping the 0247 * given device driver @d. 0248 */ 0249 static inline 0250 struct ssam_device_driver *to_ssam_device_driver(struct device_driver *d) 0251 { 0252 return container_of(d, struct ssam_device_driver, driver); 0253 } 0254 0255 const struct ssam_device_id *ssam_device_id_match(const struct ssam_device_id *table, 0256 const struct ssam_device_uid uid); 0257 0258 const struct ssam_device_id *ssam_device_get_match(const struct ssam_device *dev); 0259 0260 const void *ssam_device_get_match_data(const struct ssam_device *dev); 0261 0262 struct ssam_device *ssam_device_alloc(struct ssam_controller *ctrl, 0263 struct ssam_device_uid uid); 0264 0265 int ssam_device_add(struct ssam_device *sdev); 0266 void ssam_device_remove(struct ssam_device *sdev); 0267 0268 /** 0269 * ssam_device_mark_hot_removed() - Mark the given device as hot-removed. 0270 * @sdev: The device to mark as hot-removed. 0271 * 0272 * Mark the device as having been hot-removed. This signals drivers using the 0273 * device that communication with the device should be avoided and may lead to 0274 * timeouts. 0275 */ 0276 static inline void ssam_device_mark_hot_removed(struct ssam_device *sdev) 0277 { 0278 dev_dbg(&sdev->dev, "marking device as hot-removed\n"); 0279 set_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags); 0280 } 0281 0282 /** 0283 * ssam_device_is_hot_removed() - Check if the given device has been 0284 * hot-removed. 0285 * @sdev: The device to check. 0286 * 0287 * Checks if the given device has been marked as hot-removed. See 0288 * ssam_device_mark_hot_removed() for more details. 0289 * 0290 * Return: Returns ``true`` if the device has been marked as hot-removed. 0291 */ 0292 static inline bool ssam_device_is_hot_removed(struct ssam_device *sdev) 0293 { 0294 return test_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags); 0295 } 0296 0297 /** 0298 * ssam_device_get() - Increment reference count of SSAM client device. 0299 * @sdev: The device to increment the reference count of. 0300 * 0301 * Increments the reference count of the given SSAM client device by 0302 * incrementing the reference count of the enclosed &struct device via 0303 * get_device(). 0304 * 0305 * See ssam_device_put() for the counter-part of this function. 0306 * 0307 * Return: Returns the device provided as input. 0308 */ 0309 static inline struct ssam_device *ssam_device_get(struct ssam_device *sdev) 0310 { 0311 return sdev ? to_ssam_device(get_device(&sdev->dev)) : NULL; 0312 } 0313 0314 /** 0315 * ssam_device_put() - Decrement reference count of SSAM client device. 0316 * @sdev: The device to decrement the reference count of. 0317 * 0318 * Decrements the reference count of the given SSAM client device by 0319 * decrementing the reference count of the enclosed &struct device via 0320 * put_device(). 0321 * 0322 * See ssam_device_get() for the counter-part of this function. 0323 */ 0324 static inline void ssam_device_put(struct ssam_device *sdev) 0325 { 0326 if (sdev) 0327 put_device(&sdev->dev); 0328 } 0329 0330 /** 0331 * ssam_device_get_drvdata() - Get driver-data of SSAM client device. 0332 * @sdev: The device to get the driver-data from. 0333 * 0334 * Return: Returns the driver-data of the given device, previously set via 0335 * ssam_device_set_drvdata(). 0336 */ 0337 static inline void *ssam_device_get_drvdata(struct ssam_device *sdev) 0338 { 0339 return dev_get_drvdata(&sdev->dev); 0340 } 0341 0342 /** 0343 * ssam_device_set_drvdata() - Set driver-data of SSAM client device. 0344 * @sdev: The device to set the driver-data of. 0345 * @data: The data to set the device's driver-data pointer to. 0346 */ 0347 static inline void ssam_device_set_drvdata(struct ssam_device *sdev, void *data) 0348 { 0349 dev_set_drvdata(&sdev->dev, data); 0350 } 0351 0352 int __ssam_device_driver_register(struct ssam_device_driver *d, struct module *o); 0353 void ssam_device_driver_unregister(struct ssam_device_driver *d); 0354 0355 /** 0356 * ssam_device_driver_register() - Register a SSAM client device driver. 0357 * @drv: The driver to register. 0358 */ 0359 #define ssam_device_driver_register(drv) \ 0360 __ssam_device_driver_register(drv, THIS_MODULE) 0361 0362 /** 0363 * module_ssam_device_driver() - Helper macro for SSAM device driver 0364 * registration. 0365 * @drv: The driver managed by this module. 0366 * 0367 * Helper macro to register a SSAM device driver via module_init() and 0368 * module_exit(). This macro may only be used once per module and replaces the 0369 * aforementioned definitions. 0370 */ 0371 #define module_ssam_device_driver(drv) \ 0372 module_driver(drv, ssam_device_driver_register, \ 0373 ssam_device_driver_unregister) 0374 0375 0376 /* -- Helpers for controller and hub devices. ------------------------------- */ 0377 0378 #ifdef CONFIG_SURFACE_AGGREGATOR_BUS 0379 0380 int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, 0381 struct fwnode_handle *node); 0382 void ssam_remove_clients(struct device *dev); 0383 0384 #else /* CONFIG_SURFACE_AGGREGATOR_BUS */ 0385 0386 static inline int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, 0387 struct fwnode_handle *node) 0388 { 0389 return 0; 0390 } 0391 0392 static inline void ssam_remove_clients(struct device *dev) {} 0393 0394 #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */ 0395 0396 /** 0397 * ssam_register_clients() - Register all client devices defined under the 0398 * given parent device. 0399 * @dev: The parent device under which clients should be registered. 0400 * @ctrl: The controller with which client should be registered. 0401 * 0402 * Register all clients that have via firmware nodes been defined as children 0403 * of the given (parent) device. The respective child firmware nodes will be 0404 * associated with the correspondingly created child devices. 0405 * 0406 * The given controller will be used to instantiate the new devices. See 0407 * ssam_device_add() for details. 0408 * 0409 * Return: Returns zero on success, nonzero on failure. 0410 */ 0411 static inline int ssam_register_clients(struct device *dev, struct ssam_controller *ctrl) 0412 { 0413 return __ssam_register_clients(dev, ctrl, dev_fwnode(dev)); 0414 } 0415 0416 /** 0417 * ssam_device_register_clients() - Register all client devices defined under 0418 * the given SSAM parent device. 0419 * @sdev: The parent device under which clients should be registered. 0420 * 0421 * Register all clients that have via firmware nodes been defined as children 0422 * of the given (parent) device. The respective child firmware nodes will be 0423 * associated with the correspondingly created child devices. 0424 * 0425 * The controller used by the parent device will be used to instantiate the new 0426 * devices. See ssam_device_add() for details. 0427 * 0428 * Return: Returns zero on success, nonzero on failure. 0429 */ 0430 static inline int ssam_device_register_clients(struct ssam_device *sdev) 0431 { 0432 return ssam_register_clients(&sdev->dev, sdev->ctrl); 0433 } 0434 0435 0436 /* -- Helpers for client-device requests. ----------------------------------- */ 0437 0438 /** 0439 * SSAM_DEFINE_SYNC_REQUEST_CL_N() - Define synchronous client-device SAM 0440 * request function with neither argument nor return value. 0441 * @name: Name of the generated function. 0442 * @spec: Specification (&struct ssam_request_spec_md) defining the request. 0443 * 0444 * Defines a function executing the synchronous SAM request specified by 0445 * @spec, with the request having neither argument nor return value. Device 0446 * specifying parameters are not hard-coded, but instead are provided via the 0447 * client device, specifically its UID, supplied when calling this function. 0448 * The generated function takes care of setting up the request struct, buffer 0449 * allocation, as well as execution of the request itself, returning once the 0450 * request has been fully completed. The required transport buffer will be 0451 * allocated on the stack. 0452 * 0453 * The generated function is defined as ``static int name(struct ssam_device 0454 * *sdev)``, returning the status of the request, which is zero on success and 0455 * negative on failure. The ``sdev`` parameter specifies both the target 0456 * device of the request and by association the controller via which the 0457 * request is sent. 0458 * 0459 * Refer to ssam_request_sync_onstack() for more details on the behavior of 0460 * the generated function. 0461 */ 0462 #define SSAM_DEFINE_SYNC_REQUEST_CL_N(name, spec...) \ 0463 SSAM_DEFINE_SYNC_REQUEST_MD_N(__raw_##name, spec) \ 0464 static int name(struct ssam_device *sdev) \ 0465 { \ 0466 return __raw_##name(sdev->ctrl, sdev->uid.target, \ 0467 sdev->uid.instance); \ 0468 } 0469 0470 /** 0471 * SSAM_DEFINE_SYNC_REQUEST_CL_W() - Define synchronous client-device SAM 0472 * request function with argument. 0473 * @name: Name of the generated function. 0474 * @atype: Type of the request's argument. 0475 * @spec: Specification (&struct ssam_request_spec_md) defining the request. 0476 * 0477 * Defines a function executing the synchronous SAM request specified by 0478 * @spec, with the request taking an argument of type @atype and having no 0479 * return value. Device specifying parameters are not hard-coded, but instead 0480 * are provided via the client device, specifically its UID, supplied when 0481 * calling this function. The generated function takes care of setting up the 0482 * request struct, buffer allocation, as well as execution of the request 0483 * itself, returning once the request has been fully completed. The required 0484 * transport buffer will be allocated on the stack. 0485 * 0486 * The generated function is defined as ``static int name(struct ssam_device 0487 * *sdev, const atype *arg)``, returning the status of the request, which is 0488 * zero on success and negative on failure. The ``sdev`` parameter specifies 0489 * both the target device of the request and by association the controller via 0490 * which the request is sent. The request's argument is specified via the 0491 * ``arg`` pointer. 0492 * 0493 * Refer to ssam_request_sync_onstack() for more details on the behavior of 0494 * the generated function. 0495 */ 0496 #define SSAM_DEFINE_SYNC_REQUEST_CL_W(name, atype, spec...) \ 0497 SSAM_DEFINE_SYNC_REQUEST_MD_W(__raw_##name, atype, spec) \ 0498 static int name(struct ssam_device *sdev, const atype *arg) \ 0499 { \ 0500 return __raw_##name(sdev->ctrl, sdev->uid.target, \ 0501 sdev->uid.instance, arg); \ 0502 } 0503 0504 /** 0505 * SSAM_DEFINE_SYNC_REQUEST_CL_R() - Define synchronous client-device SAM 0506 * request function with return value. 0507 * @name: Name of the generated function. 0508 * @rtype: Type of the request's return value. 0509 * @spec: Specification (&struct ssam_request_spec_md) defining the request. 0510 * 0511 * Defines a function executing the synchronous SAM request specified by 0512 * @spec, with the request taking no argument but having a return value of 0513 * type @rtype. Device specifying parameters are not hard-coded, but instead 0514 * are provided via the client device, specifically its UID, supplied when 0515 * calling this function. The generated function takes care of setting up the 0516 * request struct, buffer allocation, as well as execution of the request 0517 * itself, returning once the request has been fully completed. The required 0518 * transport buffer will be allocated on the stack. 0519 * 0520 * The generated function is defined as ``static int name(struct ssam_device 0521 * *sdev, rtype *ret)``, returning the status of the request, which is zero on 0522 * success and negative on failure. The ``sdev`` parameter specifies both the 0523 * target device of the request and by association the controller via which 0524 * the request is sent. The request's return value is written to the memory 0525 * pointed to by the ``ret`` parameter. 0526 * 0527 * Refer to ssam_request_sync_onstack() for more details on the behavior of 0528 * the generated function. 0529 */ 0530 #define SSAM_DEFINE_SYNC_REQUEST_CL_R(name, rtype, spec...) \ 0531 SSAM_DEFINE_SYNC_REQUEST_MD_R(__raw_##name, rtype, spec) \ 0532 static int name(struct ssam_device *sdev, rtype *ret) \ 0533 { \ 0534 return __raw_##name(sdev->ctrl, sdev->uid.target, \ 0535 sdev->uid.instance, ret); \ 0536 } 0537 0538 /** 0539 * SSAM_DEFINE_SYNC_REQUEST_CL_WR() - Define synchronous client-device SAM 0540 * request function with argument and return value. 0541 * @name: Name of the generated function. 0542 * @atype: Type of the request's argument. 0543 * @rtype: Type of the request's return value. 0544 * @spec: Specification (&struct ssam_request_spec_md) defining the request. 0545 * 0546 * Defines a function executing the synchronous SAM request specified by @spec, 0547 * with the request taking an argument of type @atype and having a return value 0548 * of type @rtype. Device specifying parameters are not hard-coded, but instead 0549 * are provided via the client device, specifically its UID, supplied when 0550 * calling this function. The generated function takes care of setting up the 0551 * request struct, buffer allocation, as well as execution of the request 0552 * itself, returning once the request has been fully completed. The required 0553 * transport buffer will be allocated on the stack. 0554 * 0555 * The generated function is defined as ``static int name(struct ssam_device 0556 * *sdev, const atype *arg, rtype *ret)``, returning the status of the request, 0557 * which is zero on success and negative on failure. The ``sdev`` parameter 0558 * specifies both the target device of the request and by association the 0559 * controller via which the request is sent. The request's argument is 0560 * specified via the ``arg`` pointer. The request's return value is written to 0561 * the memory pointed to by the ``ret`` parameter. 0562 * 0563 * Refer to ssam_request_sync_onstack() for more details on the behavior of 0564 * the generated function. 0565 */ 0566 #define SSAM_DEFINE_SYNC_REQUEST_CL_WR(name, atype, rtype, spec...) \ 0567 SSAM_DEFINE_SYNC_REQUEST_MD_WR(__raw_##name, atype, rtype, spec) \ 0568 static int name(struct ssam_device *sdev, const atype *arg, rtype *ret) \ 0569 { \ 0570 return __raw_##name(sdev->ctrl, sdev->uid.target, \ 0571 sdev->uid.instance, arg, ret); \ 0572 } 0573 0574 0575 /* -- Helpers for client-device notifiers. ---------------------------------- */ 0576 0577 /** 0578 * ssam_device_notifier_register() - Register an event notifier for the 0579 * specified client device. 0580 * @sdev: The device the notifier should be registered on. 0581 * @n: The event notifier to register. 0582 * 0583 * Register an event notifier. Increment the usage counter of the associated 0584 * SAM event if the notifier is not marked as an observer. If the event is not 0585 * marked as an observer and is currently not enabled, it will be enabled 0586 * during this call. If the notifier is marked as an observer, no attempt will 0587 * be made at enabling any event and no reference count will be modified. 0588 * 0589 * Notifiers marked as observers do not need to be associated with one specific 0590 * event, i.e. as long as no event matching is performed, only the event target 0591 * category needs to be set. 0592 * 0593 * Return: Returns zero on success, %-ENOSPC if there have already been 0594 * %INT_MAX notifiers for the event ID/type associated with the notifier block 0595 * registered, %-ENOMEM if the corresponding event entry could not be 0596 * allocated, %-ENODEV if the device is marked as hot-removed. If this is the 0597 * first time that a notifier block is registered for the specific associated 0598 * event, returns the status of the event-enable EC-command. 0599 */ 0600 static inline int ssam_device_notifier_register(struct ssam_device *sdev, 0601 struct ssam_event_notifier *n) 0602 { 0603 /* 0604 * Note that this check does not provide any guarantees whatsoever as 0605 * hot-removal could happen at any point and we can't protect against 0606 * it. Nevertheless, if we can detect hot-removal, bail early to avoid 0607 * communication timeouts. 0608 */ 0609 if (ssam_device_is_hot_removed(sdev)) 0610 return -ENODEV; 0611 0612 return ssam_notifier_register(sdev->ctrl, n); 0613 } 0614 0615 /** 0616 * ssam_device_notifier_unregister() - Unregister an event notifier for the 0617 * specified client device. 0618 * @sdev: The device the notifier has been registered on. 0619 * @n: The event notifier to unregister. 0620 * 0621 * Unregister an event notifier. Decrement the usage counter of the associated 0622 * SAM event if the notifier is not marked as an observer. If the usage counter 0623 * reaches zero, the event will be disabled. 0624 * 0625 * In case the device has been marked as hot-removed, the event will not be 0626 * disabled on the EC, as in those cases any attempt at doing so may time out. 0627 * 0628 * Return: Returns zero on success, %-ENOENT if the given notifier block has 0629 * not been registered on the controller. If the given notifier block was the 0630 * last one associated with its specific event, returns the status of the 0631 * event-disable EC-command. 0632 */ 0633 static inline int ssam_device_notifier_unregister(struct ssam_device *sdev, 0634 struct ssam_event_notifier *n) 0635 { 0636 return __ssam_notifier_unregister(sdev->ctrl, n, 0637 !ssam_device_is_hot_removed(sdev)); 0638 } 0639 0640 #endif /* _LINUX_SURFACE_AGGREGATOR_DEVICE_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |