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

ptp: track available ptp vclocks information

Track available ptp vclocks information. Record index values
of available ptp vclocks during registering and unregistering.

This is preparation for supporting ptp vclocks info query
through ethtool.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yangbo Lu and committed by
David S. Miller
44c494c8 73f37068

+40 -4
+14 -1
drivers/ptp/ptp_clock.c
··· 196 196 { 197 197 struct ptp_clock *ptp; 198 198 int err = 0, index, major = MAJOR(ptp_devt); 199 + size_t size; 199 200 200 201 if (info->n_alarm > PTP_MAX_ALARMS) 201 202 return ERR_PTR(-EINVAL); ··· 239 238 strcmp(parent->class->name, "ptp") == 0) 240 239 ptp->is_virtual_clock = true; 241 240 242 - if (!ptp->is_virtual_clock) 241 + if (!ptp->is_virtual_clock) { 243 242 ptp->max_vclocks = PTP_DEFAULT_MAX_VCLOCKS; 243 + 244 + size = sizeof(int) * ptp->max_vclocks; 245 + ptp->vclock_index = kzalloc(size, GFP_KERNEL); 246 + if (!ptp->vclock_index) { 247 + err = -ENOMEM; 248 + goto no_mem_for_vclocks; 249 + } 250 + } 244 251 245 252 err = ptp_populate_pin_groups(ptp); 246 253 if (err) ··· 294 285 no_pps: 295 286 ptp_cleanup_pin_groups(ptp); 296 287 no_pin_groups: 288 + kfree(ptp->vclock_index); 289 + no_mem_for_vclocks: 297 290 if (ptp->kworker) 298 291 kthread_destroy_worker(ptp->kworker); 299 292 kworker_err: ··· 319 308 320 309 ptp->defunct = 1; 321 310 wake_up_interruptible(&ptp->tsev_wq); 311 + 312 + kfree(ptp->vclock_index); 322 313 323 314 if (ptp->kworker) { 324 315 kthread_cancel_delayed_work_sync(&ptp->aux_work);
+1
drivers/ptp/ptp_private.h
··· 49 49 struct kthread_delayed_work aux_work; 50 50 unsigned int max_vclocks; 51 51 unsigned int n_vclocks; 52 + int *vclock_index; 52 53 struct mutex n_vclocks_mux; /* protect concurrent n_vclocks access */ 53 54 bool is_virtual_clock; 54 55 };
+25 -3
drivers/ptp/ptp_sysfs.c
··· 213 213 if (!vclock) 214 214 goto out; 215 215 216 + *(ptp->vclock_index + ptp->n_vclocks + i) = 217 + vclock->clock->index; 218 + 216 219 dev_info(dev, "new virtual clock ptp%d\n", 217 220 vclock->clock->index); 218 221 } ··· 226 223 i = ptp->n_vclocks - num; 227 224 device_for_each_child_reverse(dev, &i, 228 225 unregister_vclock); 226 + 227 + for (i = 1; i <= ptp->n_vclocks - num; i++) 228 + *(ptp->vclock_index + ptp->n_vclocks - i) = -1; 229 229 } 230 230 231 231 if (num == 0) ··· 262 256 const char *buf, size_t count) 263 257 { 264 258 struct ptp_clock *ptp = dev_get_drvdata(dev); 259 + unsigned int *vclock_index; 260 + int err = -EINVAL; 261 + size_t size; 265 262 u32 max; 266 263 267 264 if (kstrtou32(buf, 0, &max) || max == 0) ··· 276 267 if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) 277 268 return -ERESTARTSYS; 278 269 279 - if (max < ptp->n_vclocks) { 280 - mutex_unlock(&ptp->n_vclocks_mux); 281 - return -EINVAL; 270 + if (max < ptp->n_vclocks) 271 + goto out; 272 + 273 + size = sizeof(int) * max; 274 + vclock_index = kzalloc(size, GFP_KERNEL); 275 + if (!vclock_index) { 276 + err = -ENOMEM; 277 + goto out; 282 278 } 283 279 280 + size = sizeof(int) * ptp->n_vclocks; 281 + memcpy(vclock_index, ptp->vclock_index, size); 282 + 283 + kfree(ptp->vclock_index); 284 + ptp->vclock_index = vclock_index; 284 285 ptp->max_vclocks = max; 285 286 286 287 mutex_unlock(&ptp->n_vclocks_mux); 287 288 288 289 return count; 290 + out: 291 + mutex_unlock(&ptp->n_vclocks_mux); 292 + return err; 289 293 } 290 294 static DEVICE_ATTR_RW(max_vclocks); 291 295