0001
0002
0003
0004
0005
0006
0007 #include <linux/mii_timestamper.h>
0008
0009 static LIST_HEAD(mii_timestamping_devices);
0010 static DEFINE_MUTEX(tstamping_devices_lock);
0011
0012 struct mii_timestamping_desc {
0013 struct list_head list;
0014 struct mii_timestamping_ctrl *ctrl;
0015 struct device *device;
0016 };
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 int register_mii_tstamp_controller(struct device *device,
0027 struct mii_timestamping_ctrl *ctrl)
0028 {
0029 struct mii_timestamping_desc *desc;
0030
0031 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
0032 if (!desc)
0033 return -ENOMEM;
0034
0035 INIT_LIST_HEAD(&desc->list);
0036 desc->ctrl = ctrl;
0037 desc->device = device;
0038
0039 mutex_lock(&tstamping_devices_lock);
0040 list_add_tail(&mii_timestamping_devices, &desc->list);
0041 mutex_unlock(&tstamping_devices_lock);
0042
0043 return 0;
0044 }
0045 EXPORT_SYMBOL(register_mii_tstamp_controller);
0046
0047
0048
0049
0050
0051
0052 void unregister_mii_tstamp_controller(struct device *device)
0053 {
0054 struct mii_timestamping_desc *desc;
0055 struct list_head *this, *next;
0056
0057 mutex_lock(&tstamping_devices_lock);
0058 list_for_each_safe(this, next, &mii_timestamping_devices) {
0059 desc = list_entry(this, struct mii_timestamping_desc, list);
0060 if (desc->device == device) {
0061 list_del_init(&desc->list);
0062 kfree(desc);
0063 break;
0064 }
0065 }
0066 mutex_unlock(&tstamping_devices_lock);
0067 }
0068 EXPORT_SYMBOL(unregister_mii_tstamp_controller);
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 struct mii_timestamper *register_mii_timestamper(struct device_node *node,
0079 unsigned int port)
0080 {
0081 struct mii_timestamper *mii_ts = NULL;
0082 struct mii_timestamping_desc *desc;
0083 struct list_head *this;
0084
0085 mutex_lock(&tstamping_devices_lock);
0086 list_for_each(this, &mii_timestamping_devices) {
0087 desc = list_entry(this, struct mii_timestamping_desc, list);
0088 if (desc->device->of_node == node) {
0089 mii_ts = desc->ctrl->probe_channel(desc->device, port);
0090 if (!IS_ERR(mii_ts)) {
0091 mii_ts->device = desc->device;
0092 get_device(desc->device);
0093 }
0094 break;
0095 }
0096 }
0097 mutex_unlock(&tstamping_devices_lock);
0098
0099 return mii_ts ? mii_ts : ERR_PTR(-EPROBE_DEFER);
0100 }
0101 EXPORT_SYMBOL(register_mii_timestamper);
0102
0103
0104
0105
0106
0107
0108
0109 void unregister_mii_timestamper(struct mii_timestamper *mii_ts)
0110 {
0111 struct mii_timestamping_desc *desc;
0112 struct list_head *this;
0113
0114 if (!mii_ts)
0115 return;
0116
0117
0118
0119
0120
0121 if (!mii_ts->device)
0122 return;
0123
0124 mutex_lock(&tstamping_devices_lock);
0125 list_for_each(this, &mii_timestamping_devices) {
0126 desc = list_entry(this, struct mii_timestamping_desc, list);
0127 if (desc->device == mii_ts->device) {
0128 desc->ctrl->release_channel(desc->device, mii_ts);
0129 put_device(desc->device);
0130 break;
0131 }
0132 }
0133 mutex_unlock(&tstamping_devices_lock);
0134 }
0135 EXPORT_SYMBOL(unregister_mii_timestamper);