Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

i2c: designware: Combine some of the common functions

The adapter can be registered just in the core instead of
separately in the master and slave drivers. The same applies
to the interrupt.

The dedicated "target only" (slave only) configuration
for this controller will be removed so that host mode
(master mode) will always be supported together with the
target mode. Therefore the descrption for the "target only"
configuration that appears in the "name" sysfs attribute
file is also dropped while at it.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260120130729.1679560-2-heikki.krogerus@linux.intel.com

authored by

Heikki Krogerus and committed by
Andi Shyti
6062443a 2c7aa268

+126 -143
+101 -7
drivers/i2c/busses/i2c-designware-common.c
··· 136 136 * 137 137 * Return: 0 on success, or negative errno otherwise. 138 138 */ 139 - int i2c_dw_init_regmap(struct dw_i2c_dev *dev) 139 + static int i2c_dw_init_regmap(struct dw_i2c_dev *dev) 140 140 { 141 141 struct regmap_config map_cfg = { 142 142 .reg_bits = 32, ··· 458 458 return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) - 1 + offset; 459 459 } 460 460 461 - int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) 461 + static int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) 462 462 { 463 463 unsigned int reg; 464 464 int ret; ··· 675 675 return -EIO; 676 676 } 677 677 678 - int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) 678 + static int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) 679 679 { 680 680 u32 tx_fifo_depth, rx_fifo_depth; 681 681 unsigned int param; ··· 744 744 } 745 745 EXPORT_SYMBOL_GPL(i2c_dw_disable); 746 746 747 + static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) 748 + { 749 + struct dw_i2c_dev *dev = dev_id; 750 + 751 + if (dev->mode == DW_IC_SLAVE) 752 + return i2c_dw_isr_slave(dev); 753 + 754 + return i2c_dw_isr_master(dev); 755 + } 756 + 757 + static const struct i2c_algorithm i2c_dw_algo = { 758 + .xfer = i2c_dw_xfer, 759 + .functionality = i2c_dw_func, 760 + #if IS_ENABLED(CONFIG_I2C_SLAVE) 761 + .reg_slave = i2c_dw_reg_slave, 762 + .unreg_slave = i2c_dw_unreg_slave, 763 + #endif 764 + }; 765 + 766 + static const struct i2c_adapter_quirks i2c_dw_quirks = { 767 + .flags = I2C_AQ_NO_ZERO_LEN, 768 + }; 769 + 747 770 int i2c_dw_probe(struct dw_i2c_dev *dev) 748 771 { 772 + struct i2c_adapter *adap = &dev->adapter; 773 + unsigned long irq_flags; 774 + int ret; 775 + 749 776 device_set_node(&dev->adapter.dev, dev_fwnode(dev->dev)); 777 + 778 + ret = i2c_dw_init_regmap(dev); 779 + if (ret) 780 + return ret; 781 + 782 + ret = i2c_dw_set_sda_hold(dev); 783 + if (ret) 784 + return ret; 785 + 786 + ret = i2c_dw_set_fifo_size(dev); 787 + if (ret) 788 + return ret; 750 789 751 790 switch (dev->mode) { 752 791 case DW_IC_SLAVE: 753 - return i2c_dw_probe_slave(dev); 792 + ret = i2c_dw_probe_slave(dev); 793 + break; 754 794 case DW_IC_MASTER: 755 - return i2c_dw_probe_master(dev); 795 + ret = i2c_dw_probe_master(dev); 796 + break; 756 797 default: 757 - dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); 758 - return -EINVAL; 798 + ret = -EINVAL; 799 + break; 759 800 } 801 + if (ret) 802 + return ret; 803 + 804 + ret = dev->init(dev); 805 + if (ret) 806 + return ret; 807 + 808 + if (!adap->name[0]) 809 + strscpy(adap->name, "Synopsys DesignWare I2C adapter"); 810 + 811 + adap->retries = 3; 812 + adap->algo = &i2c_dw_algo; 813 + adap->quirks = &i2c_dw_quirks; 814 + adap->dev.parent = dev->dev; 815 + i2c_set_adapdata(adap, dev); 816 + 817 + /* 818 + * REVISIT: The mode check may not be necessary. 819 + * For now keeping the flags as they were originally. 820 + */ 821 + if (dev->mode == DW_IC_SLAVE) 822 + irq_flags = IRQF_SHARED; 823 + else if (dev->flags & ACCESS_NO_IRQ_SUSPEND) 824 + irq_flags = IRQF_NO_SUSPEND; 825 + else 826 + irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; 827 + 828 + ret = i2c_dw_acquire_lock(dev); 829 + if (ret) 830 + return ret; 831 + 832 + __i2c_dw_write_intr_mask(dev, 0); 833 + i2c_dw_release_lock(dev); 834 + 835 + if (!(dev->flags & ACCESS_POLLING)) { 836 + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, 837 + irq_flags, dev_name(dev->dev), dev); 838 + if (ret) 839 + return ret; 840 + } 841 + 842 + /* 843 + * Increment PM usage count during adapter registration in order to 844 + * avoid possible spurious runtime suspend when adapter device is 845 + * registered to the device core and immediate resume in case bus has 846 + * registered I2C slaves that do I2C transfers in their probe. 847 + */ 848 + ACQUIRE(pm_runtime_noresume, pm)(dev->dev); 849 + ret = ACQUIRE_ERR(pm_runtime_noresume, &pm); 850 + if (ret) 851 + return ret; 852 + 853 + return i2c_add_numbered_adapter(adap); 760 854 } 761 855 EXPORT_SYMBOL_GPL(i2c_dw_probe); 762 856
+8 -3
drivers/i2c/busses/i2c-designware-core.h
··· 13 13 #include <linux/completion.h> 14 14 #include <linux/errno.h> 15 15 #include <linux/i2c.h> 16 + #include <linux/irqreturn.h> 16 17 #include <linux/pm.h> 17 18 #include <linux/regmap.h> 18 19 #include <linux/types.h> ··· 345 344 int (*probe)(struct dw_i2c_dev *dev); 346 345 }; 347 346 348 - int i2c_dw_init_regmap(struct dw_i2c_dev *dev); 349 347 u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, 350 348 u32 tSYMBOL, u32 tf, int offset); 351 349 u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, 352 350 u32 tLOW, u32 tf, int offset); 353 - int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev); 354 351 u32 i2c_dw_clk_rate(struct dw_i2c_dev *dev); 355 352 int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); 356 353 int i2c_dw_acquire_lock(struct dw_i2c_dev *dev); 357 354 void i2c_dw_release_lock(struct dw_i2c_dev *dev); 358 355 int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); 359 356 int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); 360 - int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); 361 357 u32 i2c_dw_func(struct i2c_adapter *adap); 358 + irqreturn_t i2c_dw_isr_master(struct dw_i2c_dev *dev); 362 359 363 360 extern const struct dev_pm_ops i2c_dw_dev_pm_ops; 364 361 ··· 396 397 extern void i2c_dw_configure_master(struct dw_i2c_dev *dev); 397 398 extern int i2c_dw_probe_master(struct dw_i2c_dev *dev); 398 399 400 + int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); 401 + 399 402 #if IS_ENABLED(CONFIG_I2C_SLAVE) 400 403 extern void i2c_dw_configure_slave(struct dw_i2c_dev *dev); 401 404 extern int i2c_dw_probe_slave(struct dw_i2c_dev *dev); 405 + irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev); 406 + int i2c_dw_reg_slave(struct i2c_client *client); 407 + int i2c_dw_unreg_slave(struct i2c_client *client); 402 408 #else 403 409 static inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { } 404 410 static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; } 411 + static inline irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev) { return IRQ_NONE; } 405 412 #endif 406 413 407 414 static inline void i2c_dw_configure(struct dw_i2c_dev *dev)
+11 -86
drivers/i2c/busses/i2c-designware-master.c
··· 191 191 dev->hs_hcnt, dev->hs_lcnt); 192 192 } 193 193 194 - ret = i2c_dw_set_sda_hold(dev); 195 - if (ret) 196 - return ret; 197 - 198 194 dev_dbg(dev->dev, "Bus speed: %s\n", i2c_freq_mode_string(t->bus_freq_hz)); 199 195 return 0; 200 196 } ··· 349 353 * Initiate and continue master read/write transaction with polling 350 354 * based transfer routine afterward write messages into the Tx buffer. 351 355 */ 352 - static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, int num_msgs) 356 + static int amd_i2c_dw_xfer_quirk(struct dw_i2c_dev *dev, struct i2c_msg *msgs, int num_msgs) 353 357 { 354 - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 355 358 int msg_wrt_idx, msg_itr_lmt, buf_len, data_idx; 356 359 int cmd = 0, status; 357 360 u8 *tx_buf; ··· 747 752 * Interrupt service routine. This gets called whenever an I2C master interrupt 748 753 * occurs. 749 754 */ 750 - static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) 755 + irqreturn_t i2c_dw_isr_master(struct dw_i2c_dev *dev) 751 756 { 752 - struct dw_i2c_dev *dev = dev_id; 753 757 unsigned int stat, enabled; 754 758 755 759 regmap_read(dev->map, DW_IC_ENABLE, &enabled); ··· 809 815 * Prepare controller for a transaction and call i2c_dw_xfer_msg. 810 816 */ 811 817 static int 812 - i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 818 + i2c_dw_xfer_common(struct dw_i2c_dev *dev, struct i2c_msg msgs[], int num) 813 819 { 814 - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 815 820 int ret; 816 821 817 822 dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); ··· 901 908 return ret; 902 909 } 903 910 904 - static const struct i2c_algorithm i2c_dw_algo = { 905 - .xfer = i2c_dw_xfer, 906 - .functionality = i2c_dw_func, 907 - }; 911 + int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 912 + { 913 + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 908 914 909 - static const struct i2c_algorithm amd_i2c_dw_algo = { 910 - .xfer = amd_i2c_dw_xfer_quirk, 911 - .functionality = i2c_dw_func, 912 - }; 915 + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) 916 + return amd_i2c_dw_xfer_quirk(dev, msgs, num); 913 917 914 - static const struct i2c_adapter_quirks i2c_dw_quirks = { 915 - .flags = I2C_AQ_NO_ZERO_LEN, 916 - }; 918 + return i2c_dw_xfer_common(dev, msgs, num); 919 + } 917 920 918 921 void i2c_dw_configure_master(struct dw_i2c_dev *dev) 919 922 { ··· 994 1005 995 1006 int i2c_dw_probe_master(struct dw_i2c_dev *dev) 996 1007 { 997 - struct i2c_adapter *adap = &dev->adapter; 998 - unsigned long irq_flags; 999 1008 unsigned int ic_con; 1000 1009 int ret; 1001 1010 ··· 1001 1014 1002 1015 dev->init = i2c_dw_init_master; 1003 1016 1004 - ret = i2c_dw_init_regmap(dev); 1005 - if (ret) 1006 - return ret; 1007 - 1008 1017 ret = i2c_dw_set_timings_master(dev); 1009 - if (ret) 1010 - return ret; 1011 - 1012 - ret = i2c_dw_set_fifo_size(dev); 1013 1018 if (ret) 1014 1019 return ret; 1015 1020 ··· 1024 1045 if (ic_con & DW_IC_CON_BUS_CLEAR_CTRL) 1025 1046 dev->master_cfg |= DW_IC_CON_BUS_CLEAR_CTRL; 1026 1047 1027 - ret = dev->init(dev); 1028 - if (ret) 1029 - return ret; 1030 - 1031 - if (!adap->name[0]) 1032 - scnprintf(adap->name, sizeof(adap->name), 1033 - "Synopsys DesignWare I2C adapter"); 1034 - adap->retries = 3; 1035 - if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) 1036 - adap->algo = &amd_i2c_dw_algo; 1037 - else 1038 - adap->algo = &i2c_dw_algo; 1039 - adap->quirks = &i2c_dw_quirks; 1040 - adap->dev.parent = dev->dev; 1041 - i2c_set_adapdata(adap, dev); 1042 - 1043 - if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { 1044 - irq_flags = IRQF_NO_SUSPEND; 1045 - } else { 1046 - irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; 1047 - } 1048 - 1049 - ret = i2c_dw_acquire_lock(dev); 1050 - if (ret) 1051 - return ret; 1052 - 1053 - __i2c_dw_write_intr_mask(dev, 0); 1054 - i2c_dw_release_lock(dev); 1055 - 1056 - if (!(dev->flags & ACCESS_POLLING)) { 1057 - ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, 1058 - irq_flags, dev_name(dev->dev), dev); 1059 - if (ret) 1060 - return dev_err_probe(dev->dev, ret, 1061 - "failure requesting irq %i: %d\n", 1062 - dev->irq, ret); 1063 - } 1064 - 1065 - ret = i2c_dw_init_recovery_info(dev); 1066 - if (ret) 1067 - return ret; 1068 - 1069 - /* 1070 - * Increment PM usage count during adapter registration in order to 1071 - * avoid possible spurious runtime suspend when adapter device is 1072 - * registered to the device core and immediate resume in case bus has 1073 - * registered I2C slaves that do I2C transfers in their probe. 1074 - */ 1075 - pm_runtime_get_noresume(dev->dev); 1076 - ret = i2c_add_numbered_adapter(adap); 1077 - if (ret) 1078 - dev_err(dev->dev, "failure adding adapter: %d\n", ret); 1079 - pm_runtime_put_noidle(dev->dev); 1080 - 1081 - return ret; 1048 + return i2c_dw_init_recovery_info(dev); 1082 1049 } 1083 1050 1084 1051 MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter");
+6 -47
drivers/i2c/busses/i2c-designware-slave.c
··· 63 63 return 0; 64 64 } 65 65 66 - static int i2c_dw_reg_slave(struct i2c_client *slave) 66 + int i2c_dw_reg_slave(struct i2c_client *slave) 67 67 { 68 68 struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); 69 69 ··· 88 88 return 0; 89 89 } 90 90 91 - static int i2c_dw_unreg_slave(struct i2c_client *slave) 91 + int i2c_dw_unreg_slave(struct i2c_client *slave) 92 92 { 93 93 struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); 94 94 ··· 152 152 * Interrupt service routine. This gets called whenever an I2C slave interrupt 153 153 * occurs. 154 154 */ 155 - static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) 155 + irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev) 156 156 { 157 - struct dw_i2c_dev *dev = dev_id; 158 157 unsigned int raw_stat, stat, enabled, tmp; 159 158 u8 val = 0, slave_activity; 160 159 ··· 216 217 return IRQ_HANDLED; 217 218 } 218 219 219 - static const struct i2c_algorithm i2c_dw_algo = { 220 - .functionality = i2c_dw_func, 221 - .reg_slave = i2c_dw_reg_slave, 222 - .unreg_slave = i2c_dw_unreg_slave, 223 - }; 224 - 225 220 void i2c_dw_configure_slave(struct dw_i2c_dev *dev) 226 221 { 227 222 dev->functionality = I2C_FUNC_SLAVE; ··· 229 236 230 237 int i2c_dw_probe_slave(struct dw_i2c_dev *dev) 231 238 { 232 - struct i2c_adapter *adap = &dev->adapter; 233 - int ret; 239 + if (dev->flags & ACCESS_POLLING) 240 + return -EOPNOTSUPP; 234 241 235 242 dev->init = i2c_dw_init_slave; 236 243 237 - ret = i2c_dw_init_regmap(dev); 238 - if (ret) 239 - return ret; 240 - 241 - ret = i2c_dw_set_sda_hold(dev); 242 - if (ret) 243 - return ret; 244 - 245 - ret = i2c_dw_set_fifo_size(dev); 246 - if (ret) 247 - return ret; 248 - 249 - ret = dev->init(dev); 250 - if (ret) 251 - return ret; 252 - 253 - snprintf(adap->name, sizeof(adap->name), 254 - "Synopsys DesignWare I2C Slave adapter"); 255 - adap->retries = 3; 256 - adap->algo = &i2c_dw_algo; 257 - adap->dev.parent = dev->dev; 258 - i2c_set_adapdata(adap, dev); 259 - 260 - ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr_slave, 261 - IRQF_SHARED, dev_name(dev->dev), dev); 262 - if (ret) 263 - return dev_err_probe(dev->dev, ret, 264 - "failure requesting IRQ %i: %d\n", 265 - dev->irq, ret); 266 - 267 - ret = i2c_add_numbered_adapter(adap); 268 - if (ret) 269 - dev_err(dev->dev, "failure adding adapter: %d\n", ret); 270 - 271 - return ret; 244 + return 0; 272 245 } 273 246 274 247 MODULE_AUTHOR("Luis Oliveira <lolivei@synopsys.com>");