Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 : : /* 3 : : * i2c-core.h - interfaces internal to the I2C framework 4 : : */ 5 : : 6 : : #include <linux/rwsem.h> 7 : : 8 : : struct i2c_devinfo { 9 : : struct list_head list; 10 : : int busnum; 11 : : struct i2c_board_info board_info; 12 : : }; 13 : : 14 : : /* board_lock protects board_list and first_dynamic_bus_num. 15 : : * only i2c core components are allowed to use these symbols. 16 : : */ 17 : : extern struct rw_semaphore __i2c_board_lock; 18 : : extern struct list_head __i2c_board_list; 19 : : extern int __i2c_first_dynamic_bus_num; 20 : : 21 : : int i2c_check_7bit_addr_validity_strict(unsigned short addr); 22 : : int i2c_dev_irq_from_resources(const struct resource *resources, 23 : : unsigned int num_resources); 24 : : 25 : : /* 26 : : * We only allow atomic transfers for very late communication, e.g. to send 27 : : * the powerdown command to a PMIC. Atomic transfers are a corner case and not 28 : : * for generic use! 29 : : */ 30 : 0 : static inline bool i2c_in_atomic_xfer_mode(void) 31 : : { 32 [ # # # # : 0 : return system_state > SYSTEM_RUNNING && irqs_disabled(); # # # # ] 33 : : } 34 : : 35 : 0 : static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) 36 : : { 37 : 0 : int ret = 0; 38 : : 39 [ # # # # ]: 0 : if (i2c_in_atomic_xfer_mode()) { 40 [ # # # # : 0 : WARN(!adap->algo->master_xfer_atomic && !adap->algo->smbus_xfer_atomic, # # # # ] 41 : : "No atomic I2C transfer handler for '%s'\n", dev_name(&adap->dev)); 42 [ # # ]: 0 : ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT) ? 0 : -EAGAIN; 43 : : } else { 44 : 0 : i2c_lock_bus(adap, I2C_LOCK_SEGMENT); 45 : : } 46 : : 47 : 0 : return ret; 48 : : } 49 : : 50 : 0 : static inline int __i2c_check_suspended(struct i2c_adapter *adap) 51 : : { 52 [ # # ]: 0 : if (test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags)) { 53 [ # # ]: 0 : if (!test_and_set_bit(I2C_ALF_SUSPEND_REPORTED, &adap->locked_flags)) 54 [ # # ]: 0 : dev_WARN(&adap->dev, "Transfer while suspended\n"); 55 : 0 : return -ESHUTDOWN; 56 : : } 57 : : 58 : : return 0; 59 : : } 60 : : 61 : : #ifdef CONFIG_ACPI 62 : : const struct acpi_device_id * 63 : : i2c_acpi_match_device(const struct acpi_device_id *matches, 64 : : struct i2c_client *client); 65 : : void i2c_acpi_register_devices(struct i2c_adapter *adap); 66 : : 67 : : int i2c_acpi_get_irq(struct i2c_client *client); 68 : : #else /* CONFIG_ACPI */ 69 : : static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } 70 : : static inline const struct acpi_device_id * 71 : : i2c_acpi_match_device(const struct acpi_device_id *matches, 72 : : struct i2c_client *client) 73 : : { 74 : : return NULL; 75 : : } 76 : : 77 : : static inline int i2c_acpi_get_irq(struct i2c_client *client) 78 : : { 79 : : return 0; 80 : : } 81 : : #endif /* CONFIG_ACPI */ 82 : : extern struct notifier_block i2c_acpi_notifier; 83 : : 84 : : #ifdef CONFIG_ACPI_I2C_OPREGION 85 : : int i2c_acpi_install_space_handler(struct i2c_adapter *adapter); 86 : : void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter); 87 : : #else /* CONFIG_ACPI_I2C_OPREGION */ 88 : : static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter) { return 0; } 89 : : static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter) { } 90 : : #endif /* CONFIG_ACPI_I2C_OPREGION */ 91 : : 92 : : #ifdef CONFIG_OF 93 : : void of_i2c_register_devices(struct i2c_adapter *adap); 94 : : #else 95 : 0 : static inline void of_i2c_register_devices(struct i2c_adapter *adap) { } 96 : : #endif 97 : : extern struct notifier_block i2c_of_notifier;