Message ID | 20231121-dev-iio-backend-v1-12-6a3d542eba35@analog.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | iio: add new backend framework | expand |
Hi Nuno, kernel test robot noticed the following build warnings: [auto build test WARNING on jic23-iio/togreg] [also build test WARNING on driver-core/driver-core-testing driver-core/driver-core-next driver-core/driver-core-linus robh/for-next linus/master v6.7-rc2 next-20231121] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Nuno-Sa-via-B4-Relay/driver-core-allow-modifying-device_links-flags/20231121-182010 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/20231121-dev-iio-backend-v1-12-6a3d542eba35%40analog.com patch subject: [PATCH 12/12] iio: adc: adi-axi-adc: move to backend framework config: i386-randconfig-141-20231122 (https://download.01.org/0day-ci/archive/20231122/202311220748.T1FnZwoy-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231122/202311220748.T1FnZwoy-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202311220748.T1FnZwoy-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/iio/industrialio-backend.c:123: warning: expecting prototype for iio_backend_chan_enable(). Prototype was for iio_backend_enable() instead >> drivers/iio/industrialio-backend.c:242: warning: Function parameter or member 'back' not described in 'iio_backend_get_priv' >> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'dev' not described in 'devm_iio_backend_register' >> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'ops' not described in 'devm_iio_backend_register' >> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'priv' not described in 'devm_iio_backend_register' vim +242 drivers/iio/industrialio-backend.c 67915cd5ae2cc11 Nuno Sa 2023-11-21 114 67915cd5ae2cc11 Nuno Sa 2023-11-21 115 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 116 * iio_backend_chan_enable - Enable the backend. 67915cd5ae2cc11 Nuno Sa 2023-11-21 117 * @back: Backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 118 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 119 * RETURNS: 67915cd5ae2cc11 Nuno Sa 2023-11-21 120 * 0 on success, negative error number on failure. 67915cd5ae2cc11 Nuno Sa 2023-11-21 121 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 122 int iio_backend_enable(struct iio_backend *back) 67915cd5ae2cc11 Nuno Sa 2023-11-21 @123 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 124 return iio_backend_op_call(back, enable); 67915cd5ae2cc11 Nuno Sa 2023-11-21 125 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 126 EXPORT_SYMBOL_GPL(iio_backend_enable); 67915cd5ae2cc11 Nuno Sa 2023-11-21 127 67915cd5ae2cc11 Nuno Sa 2023-11-21 128 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 129 * iio_backend_disable - Disable the backend. 67915cd5ae2cc11 Nuno Sa 2023-11-21 130 * @back: Backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 131 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 132 void iio_backend_disable(struct iio_backend *back) 67915cd5ae2cc11 Nuno Sa 2023-11-21 133 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 134 iio_backend_void_op_call(back, disable); 67915cd5ae2cc11 Nuno Sa 2023-11-21 135 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 136 EXPORT_SYMBOL_GPL(iio_backend_disable); 67915cd5ae2cc11 Nuno Sa 2023-11-21 137 67915cd5ae2cc11 Nuno Sa 2023-11-21 138 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 139 * iio_backend_data_format_set - Configure the channel data format 67915cd5ae2cc11 Nuno Sa 2023-11-21 140 * @back: Backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 141 * @chan: Channel number. 67915cd5ae2cc11 Nuno Sa 2023-11-21 142 * @data: Data format. 67915cd5ae2cc11 Nuno Sa 2023-11-21 143 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 144 * Properly configure a channel with respect to the expected data format. A 67915cd5ae2cc11 Nuno Sa 2023-11-21 145 * @struct iio_backend_data_fmt must be passed with the settings. 67915cd5ae2cc11 Nuno Sa 2023-11-21 146 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 147 * RETURNS: 67915cd5ae2cc11 Nuno Sa 2023-11-21 148 * 0 on success, negative error number on failure 67915cd5ae2cc11 Nuno Sa 2023-11-21 149 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 150 int iio_backend_data_format_set(struct iio_backend *back, unsigned int chan, 67915cd5ae2cc11 Nuno Sa 2023-11-21 151 const struct iio_backend_data_fmt *data) 67915cd5ae2cc11 Nuno Sa 2023-11-21 152 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 153 if (!data || data->type >= IIO_BACKEND_DATA_TYPE_MAX) 67915cd5ae2cc11 Nuno Sa 2023-11-21 154 return -EINVAL; 67915cd5ae2cc11 Nuno Sa 2023-11-21 155 67915cd5ae2cc11 Nuno Sa 2023-11-21 156 return iio_backend_op_call(back, data_format_set, chan, data); 67915cd5ae2cc11 Nuno Sa 2023-11-21 157 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 158 EXPORT_SYMBOL_GPL(iio_backend_data_format_set); 67915cd5ae2cc11 Nuno Sa 2023-11-21 159 67915cd5ae2cc11 Nuno Sa 2023-11-21 160 static void iio_backend_free(struct kref *ref) 67915cd5ae2cc11 Nuno Sa 2023-11-21 161 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 162 struct iio_backend *back = container_of(ref, struct iio_backend, ref); 67915cd5ae2cc11 Nuno Sa 2023-11-21 163 67915cd5ae2cc11 Nuno Sa 2023-11-21 164 kfree(back); 67915cd5ae2cc11 Nuno Sa 2023-11-21 165 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 166 67915cd5ae2cc11 Nuno Sa 2023-11-21 167 static void iio_backend_release(void *arg) 67915cd5ae2cc11 Nuno Sa 2023-11-21 168 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 169 struct iio_backend *back = arg; 67915cd5ae2cc11 Nuno Sa 2023-11-21 170 67915cd5ae2cc11 Nuno Sa 2023-11-21 171 module_put(back->owner); 67915cd5ae2cc11 Nuno Sa 2023-11-21 172 kref_put(&back->ref, iio_backend_free); 67915cd5ae2cc11 Nuno Sa 2023-11-21 173 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 174 67915cd5ae2cc11 Nuno Sa 2023-11-21 175 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 176 * devm_iio_backend_get - Get a backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 177 * @dev: Device where to look for the backend. 67915cd5ae2cc11 Nuno Sa 2023-11-21 178 * @name: Backend name. 67915cd5ae2cc11 Nuno Sa 2023-11-21 179 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 180 * Get's the backend associated with @dev. 67915cd5ae2cc11 Nuno Sa 2023-11-21 181 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 182 * RETURNS: 67915cd5ae2cc11 Nuno Sa 2023-11-21 183 * A backend pointer, negative error pointer otherwise. 67915cd5ae2cc11 Nuno Sa 2023-11-21 184 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 185 struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name) 67915cd5ae2cc11 Nuno Sa 2023-11-21 186 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 187 struct fwnode_handle *fwnode; 67915cd5ae2cc11 Nuno Sa 2023-11-21 188 struct iio_backend *back; 67915cd5ae2cc11 Nuno Sa 2023-11-21 189 int index = 0, ret; 67915cd5ae2cc11 Nuno Sa 2023-11-21 190 67915cd5ae2cc11 Nuno Sa 2023-11-21 191 if (name) { 67915cd5ae2cc11 Nuno Sa 2023-11-21 192 index = device_property_match_string(dev, "io-backends-names", 67915cd5ae2cc11 Nuno Sa 2023-11-21 193 name); 67915cd5ae2cc11 Nuno Sa 2023-11-21 194 if (index < 0) 67915cd5ae2cc11 Nuno Sa 2023-11-21 195 return ERR_PTR(index); 67915cd5ae2cc11 Nuno Sa 2023-11-21 196 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 197 67915cd5ae2cc11 Nuno Sa 2023-11-21 198 fwnode = fwnode_find_reference(dev_fwnode(dev), "io-backends", index); 67915cd5ae2cc11 Nuno Sa 2023-11-21 199 if (IS_ERR(fwnode)) { 67915cd5ae2cc11 Nuno Sa 2023-11-21 200 dev_err(dev, "Cannot get Firmware reference\n"); 67915cd5ae2cc11 Nuno Sa 2023-11-21 201 return ERR_CAST(fwnode); 67915cd5ae2cc11 Nuno Sa 2023-11-21 202 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 203 67915cd5ae2cc11 Nuno Sa 2023-11-21 204 guard(mutex)(&iio_back_lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 205 list_for_each_entry(back, &iio_back_list, entry) { 67915cd5ae2cc11 Nuno Sa 2023-11-21 206 struct device_link *link; 67915cd5ae2cc11 Nuno Sa 2023-11-21 207 67915cd5ae2cc11 Nuno Sa 2023-11-21 208 if (!device_match_fwnode(back->dev, fwnode)) 67915cd5ae2cc11 Nuno Sa 2023-11-21 209 continue; 67915cd5ae2cc11 Nuno Sa 2023-11-21 210 67915cd5ae2cc11 Nuno Sa 2023-11-21 211 fwnode_handle_put(fwnode); 67915cd5ae2cc11 Nuno Sa 2023-11-21 212 kref_get(&back->ref); 67915cd5ae2cc11 Nuno Sa 2023-11-21 213 if (!try_module_get(back->owner)) { 67915cd5ae2cc11 Nuno Sa 2023-11-21 214 dev_err(dev, "Cannot get module reference\n"); 67915cd5ae2cc11 Nuno Sa 2023-11-21 215 return ERR_PTR(-ENODEV); 67915cd5ae2cc11 Nuno Sa 2023-11-21 216 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 217 67915cd5ae2cc11 Nuno Sa 2023-11-21 218 ret = devm_add_action_or_reset(dev, iio_backend_release, back); 67915cd5ae2cc11 Nuno Sa 2023-11-21 219 if (ret) 67915cd5ae2cc11 Nuno Sa 2023-11-21 220 return ERR_PTR(ret); 67915cd5ae2cc11 Nuno Sa 2023-11-21 221 67915cd5ae2cc11 Nuno Sa 2023-11-21 222 link = device_link_add(dev, back->dev, 67915cd5ae2cc11 Nuno Sa 2023-11-21 223 DL_FLAG_AUTOREMOVE_CONSUMER); 67915cd5ae2cc11 Nuno Sa 2023-11-21 224 if (!link) 67915cd5ae2cc11 Nuno Sa 2023-11-21 225 dev_warn(dev, "Could not link to supplier(%s)\n", 67915cd5ae2cc11 Nuno Sa 2023-11-21 226 dev_name(back->dev)); 67915cd5ae2cc11 Nuno Sa 2023-11-21 227 67915cd5ae2cc11 Nuno Sa 2023-11-21 228 dev_dbg(dev, "Found backend(%s) device\n", dev_name(back->dev)); 67915cd5ae2cc11 Nuno Sa 2023-11-21 229 return back; 67915cd5ae2cc11 Nuno Sa 2023-11-21 230 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 231 67915cd5ae2cc11 Nuno Sa 2023-11-21 232 fwnode_handle_put(fwnode); 67915cd5ae2cc11 Nuno Sa 2023-11-21 233 return ERR_PTR(-EPROBE_DEFER); 67915cd5ae2cc11 Nuno Sa 2023-11-21 234 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 235 EXPORT_SYMBOL_GPL(devm_iio_backend_get); 67915cd5ae2cc11 Nuno Sa 2023-11-21 236 67915cd5ae2cc11 Nuno Sa 2023-11-21 237 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 238 * iio_backend_get_priv - Get driver private data 67915cd5ae2cc11 Nuno Sa 2023-11-21 239 * @back Backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 240 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 241 void *iio_backend_get_priv(const struct iio_backend *back) 67915cd5ae2cc11 Nuno Sa 2023-11-21 @242 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 243 return back->priv; 67915cd5ae2cc11 Nuno Sa 2023-11-21 244 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 245 EXPORT_SYMBOL_GPL(iio_backend_get_priv); 67915cd5ae2cc11 Nuno Sa 2023-11-21 246 67915cd5ae2cc11 Nuno Sa 2023-11-21 247 static void iio_backend_unregister(void *arg) 67915cd5ae2cc11 Nuno Sa 2023-11-21 248 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 249 struct iio_backend *back = arg; 67915cd5ae2cc11 Nuno Sa 2023-11-21 250 67915cd5ae2cc11 Nuno Sa 2023-11-21 251 mutex_lock(&iio_back_lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 252 list_del(&back->entry); 67915cd5ae2cc11 Nuno Sa 2023-11-21 253 mutex_unlock(&iio_back_lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 254 67915cd5ae2cc11 Nuno Sa 2023-11-21 255 mutex_lock(&back->lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 256 back->ops = NULL; 67915cd5ae2cc11 Nuno Sa 2023-11-21 257 mutex_unlock(&back->lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 258 kref_put(&back->ref, iio_backend_free); 67915cd5ae2cc11 Nuno Sa 2023-11-21 259 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 260 67915cd5ae2cc11 Nuno Sa 2023-11-21 261 /** 67915cd5ae2cc11 Nuno Sa 2023-11-21 262 * devm_iio_backend_register - Register a new backend device 67915cd5ae2cc11 Nuno Sa 2023-11-21 263 * @dev Backend device being registered. 67915cd5ae2cc11 Nuno Sa 2023-11-21 264 * @ops Backend ops 67915cd5ae2cc11 Nuno Sa 2023-11-21 265 * @priv Device private data. 67915cd5ae2cc11 Nuno Sa 2023-11-21 266 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 267 * @ops and @priv are both mandatory. Not providing them results in -EINVAL. 67915cd5ae2cc11 Nuno Sa 2023-11-21 268 * 67915cd5ae2cc11 Nuno Sa 2023-11-21 269 * RETURNS: 67915cd5ae2cc11 Nuno Sa 2023-11-21 270 * 0 on success, negative error number on failure. 67915cd5ae2cc11 Nuno Sa 2023-11-21 271 */ 67915cd5ae2cc11 Nuno Sa 2023-11-21 272 int devm_iio_backend_register(struct device *dev, 67915cd5ae2cc11 Nuno Sa 2023-11-21 273 const struct iio_backend_ops *ops, void *priv) 67915cd5ae2cc11 Nuno Sa 2023-11-21 @274 { 67915cd5ae2cc11 Nuno Sa 2023-11-21 275 struct iio_backend *back; 67915cd5ae2cc11 Nuno Sa 2023-11-21 276 67915cd5ae2cc11 Nuno Sa 2023-11-21 277 if (!ops || !priv) { 67915cd5ae2cc11 Nuno Sa 2023-11-21 278 dev_err(dev, "No backend ops or private data given\n"); 67915cd5ae2cc11 Nuno Sa 2023-11-21 279 return -EINVAL; 67915cd5ae2cc11 Nuno Sa 2023-11-21 280 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 281 67915cd5ae2cc11 Nuno Sa 2023-11-21 282 back = kzalloc(sizeof(*back), GFP_KERNEL); 67915cd5ae2cc11 Nuno Sa 2023-11-21 283 if (!back) 67915cd5ae2cc11 Nuno Sa 2023-11-21 284 return -ENOMEM; 67915cd5ae2cc11 Nuno Sa 2023-11-21 285 67915cd5ae2cc11 Nuno Sa 2023-11-21 286 kref_init(&back->ref); 67915cd5ae2cc11 Nuno Sa 2023-11-21 287 mutex_init(&back->lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 288 back->ops = ops; 67915cd5ae2cc11 Nuno Sa 2023-11-21 289 back->owner = dev->driver->owner; 67915cd5ae2cc11 Nuno Sa 2023-11-21 290 back->dev = dev; 67915cd5ae2cc11 Nuno Sa 2023-11-21 291 back->priv = priv; 67915cd5ae2cc11 Nuno Sa 2023-11-21 292 mutex_lock(&iio_back_lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 293 list_add(&back->entry, &iio_back_list); 67915cd5ae2cc11 Nuno Sa 2023-11-21 294 mutex_unlock(&iio_back_lock); 67915cd5ae2cc11 Nuno Sa 2023-11-21 295 67915cd5ae2cc11 Nuno Sa 2023-11-21 296 return devm_add_action_or_reset(dev, iio_backend_unregister, back); 67915cd5ae2cc11 Nuno Sa 2023-11-21 297 } 67915cd5ae2cc11 Nuno Sa 2023-11-21 298 EXPORT_SYMBOL_GPL(devm_iio_backend_register); 67915cd5ae2cc11 Nuno Sa 2023-11-21 299
Hi Nuno,
kernel test robot noticed the following build warnings:
[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on driver-core/driver-core-testing driver-core/driver-core-next driver-core/driver-core-linus robh/for-next linus/master v6.7-rc2 next-20231124]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Nuno-Sa-via-B4-Relay/driver-core-allow-modifying-device_links-flags/20231121-182010
base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link: https://lore.kernel.org/r/20231121-dev-iio-backend-v1-12-6a3d542eba35%40analog.com
patch subject: [PATCH 12/12] iio: adc: adi-axi-adc: move to backend framework
config: arm-randconfig-r081-20231123 (https://download.01.org/0day-ci/archive/20231125/202311251430.QfOfg5Ws-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20231125/202311251430.QfOfg5Ws-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311251430.QfOfg5Ws-lkp@intel.com/
smatch warnings:
drivers/iio/adc/adi-axi-adc.c:64 axi_adc_enable() warn: inconsistent indenting
vim +64 drivers/iio/adc/adi-axi-adc.c
58
59 static int axi_adc_enable(struct iio_backend *back)
60 {
61 struct adi_axi_adc_state *st = iio_backend_get_priv(back);
62 int ret;
63
> 64 ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
65 ADI_AXI_REG_RSTN_MMCM_RSTN);
66 if (ret)
67 return ret;
68
69 fsleep(10);
70 return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
71 ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
72 }
73
On Tue, Nov 21, 2023 at 4:17 AM Nuno Sa via B4 Relay <devnull+nuno.sa.analog.com@kernel.org> wrote: > > From: Nuno Sa <nuno.sa@analog.com> > > Move to the IIO backend framework. Devices supported by adi-axi-adc now > register themselves as backend devices. > > Signed-off-by: Nuno Sa <nuno.sa@analog.com> > --- > drivers/iio/adc/Kconfig | 1 + > drivers/iio/adc/adi-axi-adc.c | 364 ++++++++---------------------------------- > 2 files changed, 65 insertions(+), 300 deletions(-) > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index af56df63beff..cc42a3399c63 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -292,6 +292,7 @@ config ADI_AXI_ADC > select IIO_BUFFER > select IIO_BUFFER_HW_CONSUMER > select IIO_BUFFER_DMAENGINE > + select IIO_BACKEND > depends on HAS_IOMEM > depends on OF > help > diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c > index c247ff1541d2..b2ab2c119efa 100644 > --- a/drivers/iio/adc/adi-axi-adc.c > +++ b/drivers/iio/adc/adi-axi-adc.c <snip> > @@ -390,37 +166,23 @@ static int adi_axi_adc_probe(struct platform_device *pdev) > if (ret) > return ret; > > - if (cl->info->version > ver) { > + if (*expected_ver > ver) { > dev_err(&pdev->dev, > "IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", > - ADI_AXI_PCORE_VER_MAJOR(cl->info->version), > - ADI_AXI_PCORE_VER_MINOR(cl->info->version), > - ADI_AXI_PCORE_VER_PATCH(cl->info->version), > + ADI_AXI_PCORE_VER_MAJOR(*expected_ver), > + ADI_AXI_PCORE_VER_MINOR(*expected_ver), > + ADI_AXI_PCORE_VER_PATCH(*expected_ver), > ADI_AXI_PCORE_VER_MAJOR(ver), > ADI_AXI_PCORE_VER_MINOR(ver), > ADI_AXI_PCORE_VER_PATCH(ver)); > return -ENODEV; > } > > - indio_dev->info = &adi_axi_adc_info; > - indio_dev->name = "adi-axi-adc"; > - indio_dev->modes = INDIO_DIRECT_MODE; > - indio_dev->num_channels = conv->chip_info->num_channels; > - indio_dev->channels = conv->chip_info->channels; > - > - ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev); > + ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st); > if (ret) > return ret; > > - ret = adi_axi_adc_setup_channels(&pdev->dev, st); > - if (ret) > - return ret; > - > - ret = devm_iio_device_register(&pdev->dev, indio_dev); > - if (ret) > - return ret; > - > - dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n", > + dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n", Was this format change intentional? There are other places above where %c is still used. > ADI_AXI_PCORE_VER_MAJOR(ver), > ADI_AXI_PCORE_VER_MINOR(ver), > ADI_AXI_PCORE_VER_PATCH(ver)); > @@ -428,6 +190,8 @@ static int adi_axi_adc_probe(struct platform_device *pdev) > return 0; > } > > +static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a'); > + > /* Match table for of_platform binding */ > static const struct of_device_id adi_axi_adc_of_match[] = { > { .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info }, > > -- > 2.42.1 > >
On Thu, 2023-11-30 at 17:33 -0600, David Lechner wrote: > On Tue, Nov 21, 2023 at 4:17 AM Nuno Sa via B4 Relay > <devnull+nuno.sa.analog.com@kernel.org> wrote: > > > > From: Nuno Sa <nuno.sa@analog.com> > > > > Move to the IIO backend framework. Devices supported by adi-axi-adc now > > register themselves as backend devices. > > > > Signed-off-by: Nuno Sa <nuno.sa@analog.com> > > --- > > drivers/iio/adc/Kconfig | 1 + > > drivers/iio/adc/adi-axi-adc.c | 364 ++++++++---------------------------------- > > 2 files changed, 65 insertions(+), 300 deletions(-) > > > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > > index af56df63beff..cc42a3399c63 100644 > > --- a/drivers/iio/adc/Kconfig > > +++ b/drivers/iio/adc/Kconfig > > @@ -292,6 +292,7 @@ config ADI_AXI_ADC > > select IIO_BUFFER > > select IIO_BUFFER_HW_CONSUMER > > select IIO_BUFFER_DMAENGINE > > + select IIO_BACKEND > > depends on HAS_IOMEM > > depends on OF > > help > > diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c > > index c247ff1541d2..b2ab2c119efa 100644 > > --- a/drivers/iio/adc/adi-axi-adc.c > > +++ b/drivers/iio/adc/adi-axi-adc.c > > <snip> > > > @@ -390,37 +166,23 @@ static int adi_axi_adc_probe(struct platform_device *pdev) > > if (ret) > > return ret; > > > > - if (cl->info->version > ver) { > > + if (*expected_ver > ver) { > > dev_err(&pdev->dev, > > "IP core version is too old. Expected %d.%.2d.%c, > > Reported %d.%.2d.%c\n", > > - ADI_AXI_PCORE_VER_MAJOR(cl->info->version), > > - ADI_AXI_PCORE_VER_MINOR(cl->info->version), > > - ADI_AXI_PCORE_VER_PATCH(cl->info->version), > > + ADI_AXI_PCORE_VER_MAJOR(*expected_ver), > > + ADI_AXI_PCORE_VER_MINOR(*expected_ver), > > + ADI_AXI_PCORE_VER_PATCH(*expected_ver), > > ADI_AXI_PCORE_VER_MAJOR(ver), > > ADI_AXI_PCORE_VER_MINOR(ver), > > ADI_AXI_PCORE_VER_PATCH(ver)); > > return -ENODEV; > > } > > > > - indio_dev->info = &adi_axi_adc_info; > > - indio_dev->name = "adi-axi-adc"; > > - indio_dev->modes = INDIO_DIRECT_MODE; > > - indio_dev->num_channels = conv->chip_info->num_channels; > > - indio_dev->channels = conv->chip_info->channels; > > - > > - ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev); > > + ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st); > > if (ret) > > return ret; > > > > - ret = adi_axi_adc_setup_channels(&pdev->dev, st); > > - if (ret) > > - return ret; > > - > > - ret = devm_iio_device_register(&pdev->dev, indio_dev); > > - if (ret) > > - return ret; > > - > > - dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n", > > + dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n", > > Was this format change intentional? There are other places above where > %c is still used. > Yes, the output was weird with %c. I guess something changed... Hmm need to look at the other places. - Nuno Sá >
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index af56df63beff..cc42a3399c63 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -292,6 +292,7 @@ config ADI_AXI_ADC select IIO_BUFFER select IIO_BUFFER_HW_CONSUMER select IIO_BUFFER_DMAENGINE + select IIO_BACKEND depends on HAS_IOMEM depends on OF help diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index c247ff1541d2..b2ab2c119efa 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -17,13 +17,9 @@ #include <linux/regmap.h> #include <linux/slab.h> -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> -#include <linux/iio/buffer.h> -#include <linux/iio/buffer-dmaengine.h> - #include <linux/fpga/adi-axi-common.h> -#include <linux/iio/adc/adi-axi-adc.h> +#include <linux/iio/backend.h> + /* * Register definitions: @@ -44,6 +40,7 @@ #define ADI_AXI_REG_CHAN_CTRL_PN_SEL_OWR BIT(10) #define ADI_AXI_REG_CHAN_CTRL_IQCOR_EN BIT(9) #define ADI_AXI_REG_CHAN_CTRL_DCFILT_EN BIT(8) +#define ADI_AXI_REG_CHAN_CTRL_FMT_MASK GENMASK(6, 4) #define ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT BIT(6) #define ADI_AXI_REG_CHAN_CTRL_FMT_TYPE BIT(5) #define ADI_AXI_REG_CHAN_CTRL_FMT_EN BIT(4) @@ -55,286 +52,67 @@ ADI_AXI_REG_CHAN_CTRL_FMT_EN | \ ADI_AXI_REG_CHAN_CTRL_ENABLE) -struct adi_axi_adc_core_info { - unsigned int version; -}; - struct adi_axi_adc_state { - struct mutex lock; - - struct adi_axi_adc_client *client; struct regmap *regmap; }; -struct adi_axi_adc_client { - struct list_head entry; - struct adi_axi_adc_conv conv; - struct adi_axi_adc_state *state; - struct device *dev; - const struct adi_axi_adc_core_info *info; -}; - -static LIST_HEAD(registered_clients); -static DEFINE_MUTEX(registered_clients_lock); - -static struct adi_axi_adc_client *conv_to_client(struct adi_axi_adc_conv *conv) -{ - return container_of(conv, struct adi_axi_adc_client, conv); -} - -void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv) -{ - struct adi_axi_adc_client *cl = conv_to_client(conv); - - return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client), - IIO_DMA_MINALIGN); -} -EXPORT_SYMBOL_NS_GPL(adi_axi_adc_conv_priv, IIO_ADI_AXI); - -static int adi_axi_adc_config_dma_buffer(struct device *dev, - struct iio_dev *indio_dev) -{ - const char *dma_name; - - if (!device_property_present(dev, "dmas")) - return 0; - - if (device_property_read_string(dev, "dma-names", &dma_name)) - dma_name = "rx"; - - return devm_iio_dmaengine_buffer_setup(indio_dev->dev.parent, - indio_dev, dma_name); -} - -static int adi_axi_adc_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, long mask) -{ - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - - if (!conv->read_raw) - return -EOPNOTSUPP; - - return conv->read_raw(conv, chan, val, val2, mask); -} - -static int adi_axi_adc_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, int val2, long mask) -{ - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - - if (!conv->write_raw) - return -EOPNOTSUPP; - - return conv->write_raw(conv, chan, val, val2, mask); -} - -static int adi_axi_adc_read_avail(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - const int **vals, int *type, int *length, - long mask) -{ - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - - if (!conv->read_avail) - return -EOPNOTSUPP; - - return conv->read_avail(conv, chan, vals, type, length, mask); -} - -static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) -{ - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - unsigned int i; - int ret; - - for (i = 0; i < conv->chip_info->num_channels; i++) { - if (test_bit(i, scan_mask)) - ret = regmap_set_bits(st->regmap, - ADI_AXI_REG_CHAN_CTRL(i), - ADI_AXI_REG_CHAN_CTRL_ENABLE); - else - ret = regmap_clear_bits(st->regmap, - ADI_AXI_REG_CHAN_CTRL(i), - ADI_AXI_REG_CHAN_CTRL_ENABLE); - if (ret) - return ret; - } - - return 0; -} - -static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev, - size_t sizeof_priv) -{ - struct adi_axi_adc_client *cl; - size_t alloc_size; - - alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_DMA_MINALIGN); - if (sizeof_priv) - alloc_size += ALIGN(sizeof_priv, IIO_DMA_MINALIGN); - - cl = kzalloc(alloc_size, GFP_KERNEL); - if (!cl) - return ERR_PTR(-ENOMEM); - - mutex_lock(®istered_clients_lock); - - cl->dev = get_device(dev); - - list_add_tail(&cl->entry, ®istered_clients); - - mutex_unlock(®istered_clients_lock); - - return &cl->conv; -} - -static void adi_axi_adc_conv_unregister(struct adi_axi_adc_conv *conv) -{ - struct adi_axi_adc_client *cl = conv_to_client(conv); - - mutex_lock(®istered_clients_lock); - - list_del(&cl->entry); - put_device(cl->dev); - - mutex_unlock(®istered_clients_lock); - - kfree(cl); -} - -static void devm_adi_axi_adc_conv_release(void *conv) -{ - adi_axi_adc_conv_unregister(conv); -} - -struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev, - size_t sizeof_priv) +static int axi_adc_enable(struct iio_backend *back) { - struct adi_axi_adc_conv *conv; + struct adi_axi_adc_state *st = iio_backend_get_priv(back); int ret; - conv = adi_axi_adc_conv_register(dev, sizeof_priv); - if (IS_ERR(conv)) - return conv; - - ret = devm_add_action_or_reset(dev, devm_adi_axi_adc_conv_release, - conv); + ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN, + ADI_AXI_REG_RSTN_MMCM_RSTN); if (ret) - return ERR_PTR(ret); + return ret; - return conv; + fsleep(10); + return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN, + ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN); } -EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI); -static const struct iio_info adi_axi_adc_info = { - .read_raw = &adi_axi_adc_read_raw, - .write_raw = &adi_axi_adc_write_raw, - .update_scan_mode = &adi_axi_adc_update_scan_mode, - .read_avail = &adi_axi_adc_read_avail, -}; - -static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = { - .version = ADI_AXI_PCORE_VER(10, 0, 'a'), -}; - -static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev) +static void axi_adc_disable(struct iio_backend *back) { - const struct adi_axi_adc_core_info *info; - struct adi_axi_adc_client *cl; - struct device_node *cln; - - info = of_device_get_match_data(dev); - if (!info) - return ERR_PTR(-ENODEV); - - cln = of_parse_phandle(dev->of_node, "adi,adc-dev", 0); - if (!cln) { - dev_err(dev, "No 'adi,adc-dev' node defined\n"); - return ERR_PTR(-ENODEV); - } - - mutex_lock(®istered_clients_lock); - - list_for_each_entry(cl, ®istered_clients, entry) { - if (!cl->dev) - continue; - - if (cl->dev->of_node != cln) - continue; + struct adi_axi_adc_state *st = iio_backend_get_priv(back); - if (!try_module_get(cl->dev->driver->owner)) { - mutex_unlock(®istered_clients_lock); - of_node_put(cln); - return ERR_PTR(-ENODEV); - } - - get_device(cl->dev); - cl->info = info; - mutex_unlock(®istered_clients_lock); - of_node_put(cln); - return cl; - } - - mutex_unlock(®istered_clients_lock); - of_node_put(cln); - - return ERR_PTR(-EPROBE_DEFER); + regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0); } -static int adi_axi_adc_setup_channels(struct device *dev, - struct adi_axi_adc_state *st) +static int axi_adc_data_format_set(struct iio_backend *back, unsigned int chan, + const struct iio_backend_data_fmt *data) { - struct adi_axi_adc_conv *conv = &st->client->conv; - int i, ret; + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + u32 val; - if (conv->preenable_setup) { - ret = conv->preenable_setup(conv); - if (ret) - return ret; - } + if (!data->enable) + return regmap_clear_bits(st->regmap, + ADI_AXI_REG_CHAN_CTRL(chan), + ADI_AXI_REG_CHAN_CTRL_FMT_EN); - for (i = 0; i < conv->chip_info->num_channels; i++) { - ret = regmap_write(st->regmap, ADI_AXI_REG_CHAN_CTRL(i), - ADI_AXI_REG_CHAN_CTRL_DEFAULTS); - if (ret) - return ret; - } + val = FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_EN, true); + if (data->sign_extend) + val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT, true); + if (data->type == IIO_BACKEND_OFFSET_BINARY) + val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_TYPE, true); - return 0; + return regmap_update_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan), + ADI_AXI_REG_CHAN_CTRL_FMT_MASK, val); } -static int axi_adc_reset(struct adi_axi_adc_state *st) +static int axi_adc_chan_enable(struct iio_backend *back, unsigned int chan) { - int ret; + struct adi_axi_adc_state *st = iio_backend_get_priv(back); - ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0); - if (ret) - return ret; - - mdelay(10); - ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, - ADI_AXI_REG_RSTN_MMCM_RSTN); - if (ret) - return ret; - - mdelay(10); - return regmap_write(st->regmap, ADI_AXI_REG_RSTN, - ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN); + return regmap_set_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan), + ADI_AXI_REG_CHAN_CTRL_ENABLE); } -static void adi_axi_adc_cleanup(void *data) +static int axi_adc_chan_disable(struct iio_backend *back, unsigned int chan) { - struct adi_axi_adc_client *cl = data; + struct adi_axi_adc_state *st = iio_backend_get_priv(back); - put_device(cl->dev); - module_put(cl->dev->driver->owner); + return regmap_clear_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan), + ADI_AXI_REG_CHAN_CTRL_ENABLE); } static const struct regmap_config axi_adc_regmap_config = { @@ -344,33 +122,25 @@ static const struct regmap_config axi_adc_regmap_config = { .max_register = 0x0800, }; +static const struct iio_backend_ops adi_axi_adc_generic = { + .enable = axi_adc_enable, + .disable = axi_adc_disable, + .data_format_set = axi_adc_data_format_set, + .chan_enable = axi_adc_chan_enable, + .chan_disable = axi_adc_chan_disable, +}; + static int adi_axi_adc_probe(struct platform_device *pdev) { - struct adi_axi_adc_conv *conv; - struct iio_dev *indio_dev; - struct adi_axi_adc_client *cl; struct adi_axi_adc_state *st; void __iomem *base; - unsigned int ver; + unsigned int ver, *expected_ver; int ret; - cl = adi_axi_adc_attach_client(&pdev->dev); - if (IS_ERR(cl)) - return PTR_ERR(cl); - - ret = devm_add_action_or_reset(&pdev->dev, adi_axi_adc_cleanup, cl); - if (ret) - return ret; - - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); - if (indio_dev == NULL) + st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); + if (!st) return -ENOMEM; - st = iio_priv(indio_dev); - st->client = cl; - cl->state = st; - mutex_init(&st->lock); - base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -380,9 +150,15 @@ static int adi_axi_adc_probe(struct platform_device *pdev) if (IS_ERR(st->regmap)) return PTR_ERR(st->regmap); - conv = &st->client->conv; + expected_ver = (unsigned int *)device_get_match_data(&pdev->dev); + if (!expected_ver) + return -ENODEV; - ret = axi_adc_reset(st); + /* + * Force disable the core. Up to the frontend to enable us. And we can + * still read/write registers... + */ + ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0); if (ret) return ret; @@ -390,37 +166,23 @@ static int adi_axi_adc_probe(struct platform_device *pdev) if (ret) return ret; - if (cl->info->version > ver) { + if (*expected_ver > ver) { dev_err(&pdev->dev, "IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", - ADI_AXI_PCORE_VER_MAJOR(cl->info->version), - ADI_AXI_PCORE_VER_MINOR(cl->info->version), - ADI_AXI_PCORE_VER_PATCH(cl->info->version), + ADI_AXI_PCORE_VER_MAJOR(*expected_ver), + ADI_AXI_PCORE_VER_MINOR(*expected_ver), + ADI_AXI_PCORE_VER_PATCH(*expected_ver), ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); return -ENODEV; } - indio_dev->info = &adi_axi_adc_info; - indio_dev->name = "adi-axi-adc"; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->num_channels = conv->chip_info->num_channels; - indio_dev->channels = conv->chip_info->channels; - - ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev); + ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st); if (ret) return ret; - ret = adi_axi_adc_setup_channels(&pdev->dev, st); - if (ret) - return ret; - - ret = devm_iio_device_register(&pdev->dev, indio_dev); - if (ret) - return ret; - - dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n", + dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n", ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); @@ -428,6 +190,8 @@ static int adi_axi_adc_probe(struct platform_device *pdev) return 0; } +static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a'); + /* Match table for of_platform binding */ static const struct of_device_id adi_axi_adc_of_match[] = { { .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },