^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) #ifndef S390_CCWGROUP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define S390_CCWGROUP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) struct ccw_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) struct ccw_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * struct ccwgroup_device - ccw group device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * @state: online/offline state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * @count: number of attached slave devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * @dev: embedded device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * @cdev: variable number of slave devices, allocated as needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * @ungroup_work: work to be done when a ccwgroup notifier has action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * type %BUS_NOTIFY_UNBIND_DRIVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct ccwgroup_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) CCWGROUP_OFFLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) CCWGROUP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) } state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* private: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) atomic_t onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct mutex reg_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* public: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct work_struct ungroup_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct ccw_device *cdev[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * struct ccwgroup_driver - driver for ccw group devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @setup: function called during device creation to setup the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @remove: function called on remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @set_online: function called when device is set online
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @set_offline: function called when device is set offline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @shutdown: function called when device is shut down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @driver: embedded driver structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @ccw_driver: supported ccw_driver (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct ccwgroup_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int (*setup) (struct ccwgroup_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void (*remove) (struct ccwgroup_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int (*set_online) (struct ccwgroup_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int (*set_offline) (struct ccwgroup_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void (*shutdown)(struct ccwgroup_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct device_driver driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct ccw_driver *ccw_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int num_devices, const char *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) char *bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) extern int ccwgroup_set_online(struct ccwgroup_device *gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) extern int ccwgroup_set_offline(struct ccwgroup_device *gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #if IS_ENABLED(CONFIG_CCWGROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool dev_is_ccwgroup(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #else /* CONFIG_CCWGROUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static inline bool dev_is_ccwgroup(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #endif /* CONFIG_CCWGROUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif