mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.5 KiB
132 lines
3.5 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
// |
|
// Support for generic time stamping devices on MII buses. |
|
// Copyright (C) 2018 Richard Cochran <[email protected]> |
|
// |
|
|
|
#include <linux/mii_timestamper.h> |
|
|
|
static LIST_HEAD(mii_timestamping_devices); |
|
static DEFINE_MUTEX(tstamping_devices_lock); |
|
|
|
struct mii_timestamping_desc { |
|
struct list_head list; |
|
struct mii_timestamping_ctrl *ctrl; |
|
struct device *device; |
|
}; |
|
|
|
/** |
|
* register_mii_tstamp_controller() - registers an MII time stamping device. |
|
* |
|
* @device: The device to be registered. |
|
* @ctrl: Pointer to device's control interface. |
|
* |
|
* Returns zero on success or non-zero on failure. |
|
*/ |
|
int register_mii_tstamp_controller(struct device *device, |
|
struct mii_timestamping_ctrl *ctrl) |
|
{ |
|
struct mii_timestamping_desc *desc; |
|
|
|
desc = kzalloc(sizeof(*desc), GFP_KERNEL); |
|
if (!desc) |
|
return -ENOMEM; |
|
|
|
INIT_LIST_HEAD(&desc->list); |
|
desc->ctrl = ctrl; |
|
desc->device = device; |
|
|
|
mutex_lock(&tstamping_devices_lock); |
|
list_add_tail(&mii_timestamping_devices, &desc->list); |
|
mutex_unlock(&tstamping_devices_lock); |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL(register_mii_tstamp_controller); |
|
|
|
/** |
|
* unregister_mii_tstamp_controller() - unregisters an MII time stamping device. |
|
* |
|
* @device: A device previously passed to register_mii_tstamp_controller(). |
|
*/ |
|
void unregister_mii_tstamp_controller(struct device *device) |
|
{ |
|
struct mii_timestamping_desc *desc; |
|
struct list_head *this, *next; |
|
|
|
mutex_lock(&tstamping_devices_lock); |
|
list_for_each_safe(this, next, &mii_timestamping_devices) { |
|
desc = list_entry(this, struct mii_timestamping_desc, list); |
|
if (desc->device == device) { |
|
list_del_init(&desc->list); |
|
kfree(desc); |
|
break; |
|
} |
|
} |
|
mutex_unlock(&tstamping_devices_lock); |
|
} |
|
EXPORT_SYMBOL(unregister_mii_tstamp_controller); |
|
|
|
/** |
|
* register_mii_timestamper - Enables a given port of an MII time stamper. |
|
* |
|
* @node: The device tree node of the MII time stamp controller. |
|
* @port: The index of the port to be enabled. |
|
* |
|
* Returns a valid interface on success or ERR_PTR otherwise. |
|
*/ |
|
struct mii_timestamper *register_mii_timestamper(struct device_node *node, |
|
unsigned int port) |
|
{ |
|
struct mii_timestamper *mii_ts = NULL; |
|
struct mii_timestamping_desc *desc; |
|
struct list_head *this; |
|
|
|
mutex_lock(&tstamping_devices_lock); |
|
list_for_each(this, &mii_timestamping_devices) { |
|
desc = list_entry(this, struct mii_timestamping_desc, list); |
|
if (desc->device->of_node == node) { |
|
mii_ts = desc->ctrl->probe_channel(desc->device, port); |
|
if (!IS_ERR(mii_ts)) { |
|
mii_ts->device = desc->device; |
|
get_device(desc->device); |
|
} |
|
break; |
|
} |
|
} |
|
mutex_unlock(&tstamping_devices_lock); |
|
|
|
return mii_ts ? mii_ts : ERR_PTR(-EPROBE_DEFER); |
|
} |
|
EXPORT_SYMBOL(register_mii_timestamper); |
|
|
|
/** |
|
* unregister_mii_timestamper - Disables a given MII time stamper. |
|
* |
|
* @mii_ts: An interface obtained via register_mii_timestamper(). |
|
* |
|
*/ |
|
void unregister_mii_timestamper(struct mii_timestamper *mii_ts) |
|
{ |
|
struct mii_timestamping_desc *desc; |
|
struct list_head *this; |
|
|
|
/* mii_timestamper statically registered by the PHY driver won't use the |
|
* register_mii_timestamper() and thus don't have ->device set. Don't |
|
* try to unregister these. |
|
*/ |
|
if (!mii_ts->device) |
|
return; |
|
|
|
mutex_lock(&tstamping_devices_lock); |
|
list_for_each(this, &mii_timestamping_devices) { |
|
desc = list_entry(this, struct mii_timestamping_desc, list); |
|
if (desc->device == mii_ts->device) { |
|
desc->ctrl->release_channel(desc->device, mii_ts); |
|
put_device(desc->device); |
|
break; |
|
} |
|
} |
|
mutex_unlock(&tstamping_devices_lock); |
|
} |
|
EXPORT_SYMBOL(unregister_mii_timestamper);
|
|
|