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