diff options
Diffstat (limited to 'include/linux/i3c/master.h')
| -rw-r--r-- | include/linux/i3c/master.h | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index 592b646f6134..f7ceec2b4477 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -174,10 +174,19 @@ struct i3c_device_ibi_info { * assigned a dynamic address by the master. Will be used during * bus initialization to assign it a specific dynamic address * before starting DAA (Dynamic Address Assignment) + * @static_addr_method: Bitmap describing which methods of Dynamic Address + * Assignment from a Static Address are supported by this I3C Target. + * A value of 1 in a bit position indicates that the I3C target + * supports that method, and a value of 0 indicates that the I3C + * target does not support that method. + * Bit 0: SETDASA + * Bit 1: SETAASA + * All other bits are reserved. * @pid: I3C Provisioned ID exposed by the device. This is a unique identifier * that may be used to attach boardinfo to i3c_dev_desc when the device * does not have a static address - * @of_node: optional DT node in case the device has been described in the DT + * @fwnode: Firmware node (DT or ACPI) in case the device has been + * described in firmware * * This structure is used to attach board-level information to an I3C device. * Not all I3C devices connected on the bus will have a boardinfo. It's only @@ -188,8 +197,9 @@ struct i3c_dev_boardinfo { struct list_head node; u8 init_dyn_addr; u8 static_addr; + u8 static_addr_method; u64 pid; - struct device_node *of_node; + struct fwnode_handle *fwnode; }; /** @@ -228,6 +238,8 @@ struct i3c_dev_desc { * every time the I3C device is rediscovered with a different dynamic * address assigned * @bus: I3C bus this device is attached to + * @node: unregistered device list node, only for use by + * i3c_master_register_new_i3c_devs(), it is not protected by a lock * * I3C device object exposed to I3C device drivers. The takes care of linking * this object to the relevant &struct_i3c_dev_desc one. @@ -238,6 +250,7 @@ struct i3c_device { struct device dev; struct i3c_dev_desc *desc; struct i3c_bus *bus; + struct list_head node; }; /* @@ -259,6 +272,7 @@ struct i3c_device { #define I3C_BUS_THIGH_MIXED_MAX_NS 41 #define I3C_BUS_TIDLE_MIN_NS 200000 #define I3C_BUS_TLOW_OD_MIN_NS 200 +#define I3C_BUS_THIGH_INIT_OD_MIN_NS 200 /** * enum i3c_bus_mode - I3C bus mode @@ -494,7 +508,7 @@ struct i3c_master_controller_ops { int (*disable_hotjoin)(struct i3c_master_controller *master); int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed); int (*set_dev_nack_retry)(struct i3c_master_controller *master, - unsigned long dev_nack_retry_cnt); + unsigned int dev_nack_retry_cnt); }; /** @@ -511,15 +525,29 @@ struct i3c_master_controller_ops { * @hotjoin: true if the master support hotjoin * @rpm_allowed: true if Runtime PM allowed * @rpm_ibi_allowed: true if IBI and Hot-Join allowed while runtime suspended + * @ibi_wakeup: IBI can wakeup the system + * @shutting_down: set to true when master begins shutdown or unregister * @boardinfo.i3c: list of I3C boardinfo objects * @boardinfo.i2c: list of I2C boardinfo objects * @boardinfo: board-level information attached to devices connected on the bus * @bus: I3C bus exposed by this master - * @wq: workqueue which can be used by master + * @addr_method: Bitmap describing which methods of Address Assignment required + * to be run for discovering all the devices on the bus. + * Bit 0: SETDASA + * Bit 1: SETAASA + * All other bits are reserved. + * @wq: freezable workqueue which can be used by master * drivers if they need to postpone operations that need to take place * in a thread context. Typical examples are Hot Join processing which * requires taking the bus lock in maintenance, which in turn, can only * be done from a sleep-able context + * @hj_work: work item used to run DAA after a Hot-Join event is detected. + * Queued to @wq by i3c_master_queue_hotjoin() + * @reg_work: work item used to register newly discovered I3C devices with + * the driver model. Queued to @wq by i3c_master_do_daa_ext() so + * that device registration is deferred out of the DAA caller's + * context (notably the resume path), and is skipped if the + * controller is shutting down * @dev_nack_retry_count: retry count when slave device nack * * A &struct i3c_master_controller has to be registered to the I3C subsystem @@ -537,12 +565,17 @@ struct i3c_master_controller { unsigned int hotjoin: 1; unsigned int rpm_allowed: 1; unsigned int rpm_ibi_allowed: 1; + unsigned int ibi_wakeup: 1; + bool shutting_down; struct { struct list_head i3c; struct list_head i2c; } boardinfo; struct i3c_bus bus; + u8 addr_method; struct workqueue_struct *wq; + struct work_struct hj_work; + struct work_struct reg_work; unsigned int dev_nack_retry_count; }; @@ -596,14 +629,15 @@ int i3c_master_disec_locked(struct i3c_master_controller *master, u8 addr, u8 evts); int i3c_master_enec_locked(struct i3c_master_controller *master, u8 addr, u8 evts); +int i3c_master_enec_disec_locked(struct i3c_master_controller *master, u8 addr, + bool enable, u8 evts, bool suppress_m2); int i3c_master_entdaa_locked(struct i3c_master_controller *master); int i3c_master_defslvs_locked(struct i3c_master_controller *master); int i3c_master_get_free_addr(struct i3c_master_controller *master, u8 start_addr); -int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, - u8 addr); +void i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, u8 addr); int i3c_master_do_daa(struct i3c_master_controller *master); int i3c_master_do_daa_ext(struct i3c_master_controller *master, bool rstdaa); struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *ptr, @@ -613,6 +647,8 @@ void i3c_master_dma_unmap_single(struct i3c_dma *dma_xfer); DEFINE_FREE(i3c_master_dma_unmap_single, void *, if (_T) i3c_master_dma_unmap_single(_T)) +int i3c_master_reattach_i3c_dev_locked(struct i3c_dev_desc *dev, + u8 old_dyn_addr); int i3c_master_set_info(struct i3c_master_controller *master, const struct i3c_device_info *info); @@ -623,6 +659,7 @@ int i3c_master_register(struct i3c_master_controller *master, void i3c_master_unregister(struct i3c_master_controller *master); int i3c_master_enable_hotjoin(struct i3c_master_controller *master); int i3c_master_disable_hotjoin(struct i3c_master_controller *master); +void i3c_master_queue_hotjoin(struct i3c_master_controller *master); /** * i3c_dev_get_master_data() - get master private data attached to an I3C @@ -729,6 +766,7 @@ void i3c_generic_ibi_recycle_slot(struct i3c_generic_ibi_pool *pool, struct i3c_ibi_slot *slot); void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot); +bool i3c_master_has_wakeup_enabled_devs(struct i3c_master_controller *master); struct i3c_ibi_slot *i3c_master_get_free_ibi_slot(struct i3c_dev_desc *dev); |
