Re: [PATCH] staging: greybus: remove timesync protocol support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/05/2017 11:39 AM, Greg Kroah-Hartman wrote:
> From: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> 
> While the timesync protocol was a great idea, it never ended up getting
> implemented by any known hardware devices.  It's also a bit
> "interesting" in how it ties into the platform controller.
> 
> So, just remove it for now.  It's not needed, no one uses it, and it's a
> stumbling block in getting the greybus core code merged out of the
> staging tree.  If anyone wants it in the future, reverting this patch is
> a great place to start from.
> 
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

This consists entirely of deletions.  I haven't applied the
patch to test it, so I trust it compiles as it should.  And if
that is true, I'm sure it causes no harm, since as you said,
nobody uses the code right now.

Reviewed-by: Alex Elder <elder@xxxxxxxxxx>

> ---
> 
> Sorry Bryan, I know it was a lot of work, and it's a great protocol and
> implementation, but it never made it into a device :(
> 
> Note, there are some remants in the arche-platform driver, but that's
> probably next on the chopping block, so I didn't unwind it from there as
> it's a bit more complex, and it never gets built so no one will see
> it...
> 
>  drivers/staging/greybus/Makefile            |    4 +-
>  drivers/staging/greybus/arche_platform.h    |    2 -
>  drivers/staging/greybus/control.c           |   50 -
>  drivers/staging/greybus/control.h           |    7 -
>  drivers/staging/greybus/core.c              |   11 -
>  drivers/staging/greybus/es2.c               |  132 ---
>  drivers/staging/greybus/greybus.h           |    1 -
>  drivers/staging/greybus/greybus_protocols.h |   47 -
>  drivers/staging/greybus/greybus_trace.h     |   28 -
>  drivers/staging/greybus/hd.h                |    7 -
>  drivers/staging/greybus/interface.c         |   56 +-
>  drivers/staging/greybus/interface.h         |    5 -
>  drivers/staging/greybus/svc.c               |   87 --
>  drivers/staging/greybus/svc.h               |    7 -
>  drivers/staging/greybus/timesync.c          | 1357 ---------------------------
>  drivers/staging/greybus/timesync.h          |   45 -
>  drivers/staging/greybus/timesync_platform.c |   82 --
>  17 files changed, 3 insertions(+), 1925 deletions(-)
>  delete mode 100644 drivers/staging/greybus/timesync.c
>  delete mode 100644 drivers/staging/greybus/timesync.h
>  delete mode 100644 drivers/staging/greybus/timesync_platform.c
> 
> diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
> index f337b7b70782..b26b9a35bdd5 100644
> --- a/drivers/staging/greybus/Makefile
> +++ b/drivers/staging/greybus/Makefile
> @@ -10,9 +10,7 @@ greybus-y :=	core.o		\
>  		control.o	\
>  		svc.o		\
>  		svc_watchdog.o	\
> -		operation.o	\
> -		timesync.o	\
> -		timesync_platform.o
> +		operation.o
>  
>  obj-$(CONFIG_GREYBUS)		+= greybus.o
>  
> diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h
> index bd12345b82a2..c0591df9b9d6 100644
> --- a/drivers/staging/greybus/arche_platform.h
> +++ b/drivers/staging/greybus/arche_platform.h
> @@ -10,8 +10,6 @@
>  #ifndef __ARCHE_PLATFORM_H
>  #define __ARCHE_PLATFORM_H
>  
> -#include "timesync.h"
> -
>  enum arche_platform_state {
>  	ARCHE_PLATFORM_STATE_OFF,
>  	ARCHE_PLATFORM_STATE_ACTIVE,
> diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c
> index 4716190e740a..5b30be30a3a4 100644
> --- a/drivers/staging/greybus/control.c
> +++ b/drivers/staging/greybus/control.c
> @@ -198,56 +198,6 @@ int gb_control_mode_switch_operation(struct gb_control *control)
>  	return ret;
>  }
>  
> -int gb_control_timesync_enable(struct gb_control *control, u8 count,
> -			       u64 frame_time, u32 strobe_delay, u32 refclk)
> -{
> -	struct gb_control_timesync_enable_request request;
> -
> -	request.count = count;
> -	request.frame_time = cpu_to_le64(frame_time);
> -	request.strobe_delay = cpu_to_le32(strobe_delay);
> -	request.refclk = cpu_to_le32(refclk);
> -	return gb_operation_sync(control->connection,
> -				 GB_CONTROL_TYPE_TIMESYNC_ENABLE, &request,
> -				 sizeof(request), NULL, 0);
> -}
> -
> -int gb_control_timesync_disable(struct gb_control *control)
> -{
> -	return gb_operation_sync(control->connection,
> -				 GB_CONTROL_TYPE_TIMESYNC_DISABLE, NULL, 0,
> -				 NULL, 0);
> -}
> -
> -int gb_control_timesync_get_last_event(struct gb_control *control,
> -				       u64 *frame_time)
> -{
> -	struct gb_control_timesync_get_last_event_response response;
> -	int ret;
> -
> -	ret = gb_operation_sync(control->connection,
> -				GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT,
> -				NULL, 0, &response, sizeof(response));
> -	if (!ret)
> -		*frame_time = le64_to_cpu(response.frame_time);
> -	return ret;
> -}
> -
> -int gb_control_timesync_authoritative(struct gb_control *control,
> -				      u64 *frame_time)
> -{
> -	struct gb_control_timesync_authoritative_request request;
> -	int i;
> -
> -	for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
> -		request.frame_time[i] = cpu_to_le64(frame_time[i]);
> -
> -	return gb_operation_sync(control->connection,
> -				 GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE,
> -				 &request, sizeof(request),
> -				 NULL, 0);
> -}
> -
>  static int gb_control_bundle_pm_status_map(u8 status)
>  {
>  	switch (status) {
> diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h
> index f9a60daf9a72..4dcaec8b9cfe 100644
> --- a/drivers/staging/greybus/control.h
> +++ b/drivers/staging/greybus/control.h
> @@ -48,13 +48,6 @@ void gb_control_mode_switch_complete(struct gb_control *control);
>  int gb_control_get_manifest_size_operation(struct gb_interface *intf);
>  int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
>  				      size_t size);
> -int gb_control_timesync_enable(struct gb_control *control, u8 count,
> -			       u64 frame_time, u32 strobe_delay, u32 refclk);
> -int gb_control_timesync_disable(struct gb_control *control);
> -int gb_control_timesync_get_last_event(struct gb_control *control,
> -				       u64 *frame_time);
> -int gb_control_timesync_authoritative(struct gb_control *control,
> -				      u64 *frame_time);
>  int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id);
>  int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id);
>  int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id);
> diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
> index 1049e9c0edb0..ba761905b790 100644
> --- a/drivers/staging/greybus/core.c
> +++ b/drivers/staging/greybus/core.c
> @@ -218,8 +218,6 @@ static int greybus_probe(struct device *dev)
>  		return retval;
>  	}
>  
> -	gb_timesync_schedule_synchronous(bundle->intf);
> -
>  	pm_runtime_put(&bundle->intf->dev);
>  
>  	return 0;
> @@ -326,16 +324,8 @@ static int __init gb_init(void)
>  		pr_err("gb_operation_init failed (%d)\n", retval);
>  		goto error_operation;
>  	}
> -
> -	retval = gb_timesync_init();
> -	if (retval) {
> -		pr_err("gb_timesync_init failed\n");
> -		goto error_timesync;
> -	}
>  	return 0;	/* Success */
>  
> -error_timesync:
> -	gb_operation_exit();
>  error_operation:
>  	gb_hd_exit();
>  error_hd:
> @@ -349,7 +339,6 @@ module_init(gb_init);
>  
>  static void __exit gb_exit(void)
>  {
> -	gb_timesync_exit();
>  	gb_operation_exit();
>  	gb_hd_exit();
>  	bus_unregister(&greybus_bus_type);
> diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c
> index c1929dfa9b31..93afd9374f04 100644
> --- a/drivers/staging/greybus/es2.c
> +++ b/drivers/staging/greybus/es2.c
> @@ -127,29 +127,6 @@ struct es2_ap_dev {
>  	struct list_head arpcs;
>  };
>  
> -/**
> - * timesync_enable_request - Enable timesync in an APBridge
> - * @count: number of TimeSync Pulses to expect
> - * @frame_time: the initial FrameTime at the first TimeSync Pulse
> - * @strobe_delay: the expected delay in microseconds between each TimeSync Pulse
> - * @refclk: The AP mandated reference clock to run FrameTime at
> - */
> -struct timesync_enable_request {
> -	__u8	count;
> -	__le64	frame_time;
> -	__le32	strobe_delay;
> -	__le32	refclk;
> -} __packed;
> -
> -/**
> - * timesync_authoritative_request - Transmit authoritative FrameTime to APBridge
> - * @frame_time: An array of authoritative FrameTimes provided by the SVC
> - *              and relayed to the APBridge by the AP
> - */
> -struct timesync_authoritative_request {
> -	__le64	frame_time[GB_TIMESYNC_MAX_STROBES];
> -} __packed;
> -
>  struct arpc {
>  	struct list_head list;
>  	struct arpc_request_message *req;
> @@ -754,111 +731,6 @@ static int latency_tag_disable(struct gb_host_device *hd, u16 cport_id)
>  	return retval;
>  }
>  
> -static int timesync_enable(struct gb_host_device *hd, u8 count,
> -			   u64 frame_time, u32 strobe_delay, u32 refclk)
> -{
> -	int retval;
> -	struct es2_ap_dev *es2 = hd_to_es2(hd);
> -	struct usb_device *udev = es2->usb_dev;
> -	struct gb_control_timesync_enable_request *request;
> -
> -	request = kzalloc(sizeof(*request), GFP_KERNEL);
> -	if (!request)
> -		return -ENOMEM;
> -
> -	request->count = count;
> -	request->frame_time = cpu_to_le64(frame_time);
> -	request->strobe_delay = cpu_to_le32(strobe_delay);
> -	request->refclk = cpu_to_le32(refclk);
> -	retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
> -				 GB_APB_REQUEST_TIMESYNC_ENABLE,
> -				 USB_DIR_OUT | USB_TYPE_VENDOR |
> -				 USB_RECIP_INTERFACE, 0, 0, request,
> -				 sizeof(*request), ES2_USB_CTRL_TIMEOUT);
> -	if (retval < 0)
> -		dev_err(&udev->dev, "Cannot enable timesync %d\n", retval);
> -
> -	kfree(request);
> -	return retval;
> -}
> -
> -static int timesync_disable(struct gb_host_device *hd)
> -{
> -	int retval;
> -	struct es2_ap_dev *es2 = hd_to_es2(hd);
> -	struct usb_device *udev = es2->usb_dev;
> -
> -	retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
> -				 GB_APB_REQUEST_TIMESYNC_DISABLE,
> -				 USB_DIR_OUT | USB_TYPE_VENDOR |
> -				 USB_RECIP_INTERFACE, 0, 0, NULL,
> -				 0, ES2_USB_CTRL_TIMEOUT);
> -	if (retval < 0)
> -		dev_err(&udev->dev, "Cannot disable timesync %d\n", retval);
> -
> -	return retval;
> -}
> -
> -static int timesync_authoritative(struct gb_host_device *hd, u64 *frame_time)
> -{
> -	int retval, i;
> -	struct es2_ap_dev *es2 = hd_to_es2(hd);
> -	struct usb_device *udev = es2->usb_dev;
> -	struct timesync_authoritative_request *request;
> -
> -	request = kzalloc(sizeof(*request), GFP_KERNEL);
> -	if (!request)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
> -		request->frame_time[i] = cpu_to_le64(frame_time[i]);
> -
> -	retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
> -				 GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE,
> -				 USB_DIR_OUT | USB_TYPE_VENDOR |
> -				 USB_RECIP_INTERFACE, 0, 0, request,
> -				 sizeof(*request), ES2_USB_CTRL_TIMEOUT);
> -	if (retval < 0)
> -		dev_err(&udev->dev, "Cannot timesync authoritative out %d\n", retval);
> -
> -	kfree(request);
> -	return retval;
> -}
> -
> -static int timesync_get_last_event(struct gb_host_device *hd, u64 *frame_time)
> -{
> -	int retval;
> -	struct es2_ap_dev *es2 = hd_to_es2(hd);
> -	struct usb_device *udev = es2->usb_dev;
> -	__le64 *response_frame_time;
> -
> -	response_frame_time = kzalloc(sizeof(*response_frame_time), GFP_KERNEL);
> -	if (!response_frame_time)
> -		return -ENOMEM;
> -
> -	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
> -				 GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT,
> -				 USB_DIR_IN | USB_TYPE_VENDOR |
> -				 USB_RECIP_INTERFACE, 0, 0, response_frame_time,
> -				 sizeof(*response_frame_time),
> -				 ES2_USB_CTRL_TIMEOUT);
> -
> -	if (retval != sizeof(*response_frame_time)) {
> -		dev_err(&udev->dev, "Cannot get last TimeSync event: %d\n",
> -			retval);
> -
> -		if (retval >= 0)
> -			retval = -EIO;
> -
> -		goto out;
> -	}
> -	*frame_time = le64_to_cpu(*response_frame_time);
> -	retval = 0;
> -out:
> -	kfree(response_frame_time);
> -	return retval;
> -}
> -
>  static struct gb_hd_driver es2_driver = {
>  	.hd_priv_size			= sizeof(struct es2_ap_dev),
>  	.message_send			= message_send,
> @@ -874,10 +746,6 @@ static struct gb_hd_driver es2_driver = {
>  	.latency_tag_enable		= latency_tag_enable,
>  	.latency_tag_disable		= latency_tag_disable,
>  	.output				= output,
> -	.timesync_enable		= timesync_enable,
> -	.timesync_disable		= timesync_disable,
> -	.timesync_authoritative		= timesync_authoritative,
> -	.timesync_get_last_event	= timesync_get_last_event,
>  };
>  
>  /* Common function to report consistent warnings based on URB status */
> diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h
> index 12526887ae2e..c9bb93f23927 100644
> --- a/drivers/staging/greybus/greybus.h
> +++ b/drivers/staging/greybus/greybus.h
> @@ -33,7 +33,6 @@
>  #include "bundle.h"
>  #include "connection.h"
>  #include "operation.h"
> -#include "timesync.h"
>  
>  /* Matches up with the Greybus Protocol specification document */
>  #define GREYBUS_VERSION_MAJOR	0x00
> diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
> index 639578309c2a..b1be0b0af464 100644
> --- a/drivers/staging/greybus/greybus_protocols.h
> +++ b/drivers/staging/greybus/greybus_protocols.h
> @@ -173,26 +173,6 @@ struct gb_control_disconnected_request {
>  } __packed;
>  /* Control protocol [dis]connected response has no payload */
>  
> -#define GB_TIMESYNC_MAX_STROBES			0x04
> -
> -struct gb_control_timesync_enable_request {
> -	__u8	count;
> -	__le64	frame_time;
> -	__le32	strobe_delay;
> -	__le32	refclk;
> -} __packed;
> -/* timesync enable response has no payload */
> -
> -struct gb_control_timesync_authoritative_request {
> -	__le64	frame_time[GB_TIMESYNC_MAX_STROBES];
> -} __packed;
> -/* timesync authoritative response has no payload */
> -
> -/* timesync get_last_event_request has no payload */
> -struct gb_control_timesync_get_last_event_response {
> -	__le64	frame_time;
> -} __packed;
> -
>  /*
>   * All Bundle power management operations use the same request and response
>   * layout and status codes.
> @@ -1169,33 +1149,6 @@ struct gb_svc_intf_unipro_response {
>  #define GB_SVC_INTF_UNIPRO_NOT_OFF			0x03
>  } __packed;
>  
> -struct gb_svc_timesync_enable_request {
> -	__u8	count;
> -	__le64	frame_time;
> -	__le32	strobe_delay;
> -	__le32	refclk;
> -} __packed;
> -/* timesync enable response has no payload */
> -
> -/* timesync authoritative request has no payload */
> -struct gb_svc_timesync_authoritative_response {
> -	__le64	frame_time[GB_TIMESYNC_MAX_STROBES];
> -};
> -
> -struct gb_svc_timesync_wake_pins_acquire_request {
> -	__le32	strobe_mask;
> -};
> -
> -/* timesync wake pins acquire response has no payload */
> -
> -/* timesync wake pins release request has no payload */
> -/* timesync wake pins release response has no payload */
> -
> -/* timesync svc ping request has no payload */
> -struct gb_svc_timesync_ping_response {
> -	__le64	frame_time;
> -} __packed;
> -
>  #define GB_SVC_UNIPRO_FAST_MODE			0x01
>  #define GB_SVC_UNIPRO_SLOW_MODE			0x02
>  #define GB_SVC_UNIPRO_FAST_AUTO_MODE		0x04
> diff --git a/drivers/staging/greybus/greybus_trace.h b/drivers/staging/greybus/greybus_trace.h
> index 6f8692da9ec8..f8feae4dc3b5 100644
> --- a/drivers/staging/greybus/greybus_trace.h
> +++ b/drivers/staging/greybus/greybus_trace.h
> @@ -488,34 +488,6 @@ DEFINE_HD_EVENT(gb_hd_in);
>  
>  #undef DEFINE_HD_EVENT
>  
> -/*
> - * Occurs on a TimeSync synchronization event or a TimeSync ping event.
> - */
> -TRACE_EVENT(gb_timesync_irq,
> -
> -	TP_PROTO(u8 ping, u8 strobe, u8 count, u64 frame_time),
> -
> -	TP_ARGS(ping, strobe, count, frame_time),
> -
> -	TP_STRUCT__entry(
> -		__field(u8, ping)
> -		__field(u8, strobe)
> -		__field(u8, count)
> -		__field(u64, frame_time)
> -	),
> -
> -	TP_fast_assign(
> -		__entry->ping = ping;
> -		__entry->strobe = strobe;
> -		__entry->count = count;
> -		__entry->frame_time = frame_time;
> -	),
> -
> -	TP_printk("%s %d/%d frame-time %llu\n",
> -		  __entry->ping ? "ping" : "strobe", __entry->strobe,
> -		  __entry->count, __entry->frame_time)
> -);
> -
>  #endif /* _TRACE_GREYBUS_H */
>  
>  /* This part must be outside protection */
> diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h
> index c4250cfe595f..e7927bb1761c 100644
> --- a/drivers/staging/greybus/hd.h
> +++ b/drivers/staging/greybus/hd.h
> @@ -37,13 +37,6 @@ struct gb_hd_driver {
>  	int (*latency_tag_disable)(struct gb_host_device *hd, u16 cport_id);
>  	int (*output)(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
>  		      bool async);
> -	int (*timesync_enable)(struct gb_host_device *hd, u8 count,
> -			       u64 frame_time, u32 strobe_delay, u32 refclk);
> -	int (*timesync_disable)(struct gb_host_device *hd);
> -	int (*timesync_authoritative)(struct gb_host_device *hd,
> -				      u64 *frame_time);
> -	int (*timesync_get_last_event)(struct gb_host_device *hd,
> -				       u64 *frame_time);
>  };
>  
>  struct gb_host_device {
> diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
> index 546b090e2d51..a4fd51632232 100644
> --- a/drivers/staging/greybus/interface.c
> +++ b/drivers/staging/greybus/interface.c
> @@ -702,14 +702,12 @@ static void gb_interface_release(struct device *dev)
>  static int gb_interface_suspend(struct device *dev)
>  {
>  	struct gb_interface *intf = to_gb_interface(dev);
> -	int ret, timesync_ret;
> +	int ret;
>  
>  	ret = gb_control_interface_suspend_prepare(intf->control);
>  	if (ret)
>  		return ret;
>  
> -	gb_timesync_interface_remove(intf);
> -
>  	ret = gb_control_suspend(intf->control);
>  	if (ret)
>  		goto err_hibernate_abort;
> @@ -730,12 +728,6 @@ static int gb_interface_suspend(struct device *dev)
>  err_hibernate_abort:
>  	gb_control_interface_hibernate_abort(intf->control);
>  
> -	timesync_ret = gb_timesync_interface_add(intf);
> -	if (timesync_ret) {
> -		dev_err(dev, "failed to add to timesync: %d\n", timesync_ret);
> -		return timesync_ret;
> -	}
> -
>  	return ret;
>  }
>  
> @@ -757,18 +749,6 @@ static int gb_interface_resume(struct device *dev)
>  	if (ret)
>  		return ret;
>  
> -	ret = gb_timesync_interface_add(intf);
> -	if (ret) {
> -		dev_err(dev, "failed to add to timesync: %d\n", ret);
> -		return ret;
> -	}
> -
> -	ret = gb_timesync_schedule_synchronous(intf);
> -	if (ret) {
> -		dev_err(dev, "failed to synchronize FrameTime: %d\n", ret);
> -		return ret;
> -	}
> -
>  	return 0;
>  }
>  
> @@ -1152,16 +1132,10 @@ int gb_interface_enable(struct gb_interface *intf)
>  	if (ret)
>  		goto err_destroy_bundles;
>  
> -	ret = gb_timesync_interface_add(intf);
> -	if (ret) {
> -		dev_err(&intf->dev, "failed to add to timesync: %d\n", ret);
> -		goto err_destroy_bundles;
> -	}
> -
>  	/* Register the control device and any bundles */
>  	ret = gb_control_add(intf->control);
>  	if (ret)
> -		goto err_remove_timesync;
> +		goto err_destroy_bundles;
>  
>  	pm_runtime_use_autosuspend(&intf->dev);
>  	pm_runtime_get_noresume(&intf->dev);
> @@ -1186,8 +1160,6 @@ int gb_interface_enable(struct gb_interface *intf)
>  
>  	return 0;
>  
> -err_remove_timesync:
> -	gb_timesync_interface_remove(intf);
>  err_destroy_bundles:
>  	list_for_each_entry_safe(bundle, tmp, &intf->bundles, links)
>  		gb_bundle_destroy(bundle);
> @@ -1230,7 +1202,6 @@ void gb_interface_disable(struct gb_interface *intf)
>  		gb_control_interface_deactivate_prepare(intf->control);
>  
>  	gb_control_del(intf->control);
> -	gb_timesync_interface_remove(intf);
>  	gb_control_disable(intf->control);
>  	gb_control_put(intf->control);
>  	intf->control = NULL;
> @@ -1243,29 +1214,6 @@ void gb_interface_disable(struct gb_interface *intf)
>  	pm_runtime_put_noidle(&intf->dev);
>  }
>  
> -/* Enable TimeSync on an Interface control connection. */
> -int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
> -				 u64 frame_time, u32 strobe_delay, u32 refclk)
> -{
> -	return gb_control_timesync_enable(intf->control, count,
> -					  frame_time, strobe_delay,
> -					  refclk);
> -}
> -
> -/* Disable TimeSync on an Interface control connection. */
> -int gb_interface_timesync_disable(struct gb_interface *intf)
> -{
> -	return gb_control_timesync_disable(intf->control);
> -}
> -
> -/* Transmit the Authoritative FrameTime via an Interface control connection. */
> -int gb_interface_timesync_authoritative(struct gb_interface *intf,
> -					u64 *frame_time)
> -{
> -	return gb_control_timesync_authoritative(intf->control,
> -						frame_time);
> -}
> -
>  /* Register an interface. */
>  int gb_interface_add(struct gb_interface *intf)
>  {
> diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h
> index 03299d2a8be5..bd31b8c18d5b 100644
> --- a/drivers/staging/greybus/interface.h
> +++ b/drivers/staging/greybus/interface.h
> @@ -72,11 +72,6 @@ int gb_interface_activate(struct gb_interface *intf);
>  void gb_interface_deactivate(struct gb_interface *intf);
>  int gb_interface_enable(struct gb_interface *intf);
>  void gb_interface_disable(struct gb_interface *intf);
> -int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
> -				 u64 frame_time, u32 strobe_delay, u32 refclk);
> -int gb_interface_timesync_authoritative(struct gb_interface *intf,
> -					u64 *frame_time);
> -int gb_interface_timesync_disable(struct gb_interface *intf);
>  int gb_interface_add(struct gb_interface *intf);
>  void gb_interface_del(struct gb_interface *intf);
>  void gb_interface_put(struct gb_interface *intf);
> diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
> index 8779270cadc1..be151a64ea03 100644
> --- a/drivers/staging/greybus/svc.c
> +++ b/drivers/staging/greybus/svc.c
> @@ -518,85 +518,6 @@ void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
>  	}
>  }
>  
> -int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
> -			   u32 strobe_delay, u32 refclk)
> -{
> -	struct gb_connection *connection = svc->connection;
> -	struct gb_svc_timesync_enable_request request;
> -
> -	request.count = count;
> -	request.frame_time = cpu_to_le64(frame_time);
> -	request.strobe_delay = cpu_to_le32(strobe_delay);
> -	request.refclk = cpu_to_le32(refclk);
> -	return gb_operation_sync(connection,
> -				 GB_SVC_TYPE_TIMESYNC_ENABLE,
> -				 &request, sizeof(request), NULL, 0);
> -}
> -
> -int gb_svc_timesync_disable(struct gb_svc *svc)
> -{
> -	struct gb_connection *connection = svc->connection;
> -
> -	return gb_operation_sync(connection,
> -				 GB_SVC_TYPE_TIMESYNC_DISABLE,
> -				 NULL, 0, NULL, 0);
> -}
> -
> -int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time)
> -{
> -	struct gb_connection *connection = svc->connection;
> -	struct gb_svc_timesync_authoritative_response response;
> -	int ret, i;
> -
> -	ret = gb_operation_sync(connection,
> -				GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE, NULL, 0,
> -				&response, sizeof(response));
> -	if (ret < 0)
> -		return ret;
> -
> -	for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
> -		frame_time[i] = le64_to_cpu(response.frame_time[i]);
> -	return 0;
> -}
> -
> -int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time)
> -{
> -	struct gb_connection *connection = svc->connection;
> -	struct gb_svc_timesync_ping_response response;
> -	int ret;
> -
> -	ret = gb_operation_sync(connection,
> -				GB_SVC_TYPE_TIMESYNC_PING,
> -				NULL, 0,
> -				&response, sizeof(response));
> -	if (ret < 0)
> -		return ret;
> -
> -	*frame_time = le64_to_cpu(response.frame_time);
> -	return 0;
> -}
> -
> -int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask)
> -{
> -	struct gb_connection *connection = svc->connection;
> -	struct gb_svc_timesync_wake_pins_acquire_request request;
> -
> -	request.strobe_mask = cpu_to_le32(strobe_mask);
> -	return gb_operation_sync(connection,
> -				 GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE,
> -				 &request, sizeof(request),
> -				 NULL, 0);
> -}
> -
> -int gb_svc_timesync_wake_pins_release(struct gb_svc *svc)
> -{
> -	struct gb_connection *connection = svc->connection;
> -
> -	return gb_operation_sync(connection,
> -				 GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE,
> -				 NULL, 0, NULL, 0);
> -}
> -
>  /* Creates bi-directional routes between the devices */
>  int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
>  			       u8 intf2_id, u8 dev2_id)
> @@ -945,13 +866,6 @@ static int gb_svc_hello(struct gb_operation *op)
>  
>  	gb_svc_debugfs_init(svc);
>  
> -	ret = gb_timesync_svc_add(svc);
> -	if (ret) {
> -		dev_err(&svc->dev, "failed to add SVC to timesync: %d\n", ret);
> -		gb_svc_debugfs_exit(svc);
> -		goto err_unregister_device;
> -	}
> -
>  	return gb_svc_queue_deferred_request(op);
>  
>  err_unregister_device:
> @@ -1467,7 +1381,6 @@ void gb_svc_del(struct gb_svc *svc)
>  	 * The SVC device may have been registered from the request handler.
>  	 */
>  	if (device_is_registered(&svc->dev)) {
> -		gb_timesync_svc_remove(svc);
>  		gb_svc_debugfs_exit(svc);
>  		gb_svc_watchdog_destroy(svc);
>  		device_del(&svc->dev);
> diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h
> index d1d7ef967385..226c2a396fc8 100644
> --- a/drivers/staging/greybus/svc.h
> +++ b/drivers/staging/greybus/svc.h
> @@ -95,13 +95,6 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc);
>  bool gb_svc_watchdog_enabled(struct gb_svc *svc);
>  int gb_svc_watchdog_enable(struct gb_svc *svc);
>  int gb_svc_watchdog_disable(struct gb_svc *svc);
> -int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
> -			   u32 strobe_delay, u32 refclk);
> -int gb_svc_timesync_disable(struct gb_svc *svc);
> -int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time);
> -int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time);
> -int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask);
> -int gb_svc_timesync_wake_pins_release(struct gb_svc *svc);
>  
>  int gb_svc_protocol_init(void);
>  void gb_svc_protocol_exit(void);
> diff --git a/drivers/staging/greybus/timesync.c b/drivers/staging/greybus/timesync.c
> deleted file mode 100644
> index 29e6c1c12807..000000000000
> --- a/drivers/staging/greybus/timesync.c
> +++ /dev/null
> @@ -1,1357 +0,0 @@
> -/*
> - * TimeSync API driver.
> - *
> - * Copyright 2016 Google Inc.
> - * Copyright 2016 Linaro Ltd.
> - *
> - * Released under the GPLv2 only.
> - */
> -#include <linux/debugfs.h>
> -#include <linux/hrtimer.h>
> -#include "greybus.h"
> -#include "timesync.h"
> -#include "greybus_trace.h"
> -
> -/*
> - * Minimum inter-strobe value of one millisecond is chosen because it
> - * just-about fits the common definition of a jiffy.
> - *
> - * Maximum value OTOH is constrained by the number of bits the SVC can fit
> - * into a 16 bit up-counter. The SVC configures the timer in microseconds
> - * so the maximum allowable value is 65535 microseconds. We clip that value
> - * to 10000 microseconds for the sake of using nice round base 10 numbers
> - * and since right-now there's no imaginable use-case requiring anything
> - * other than a one millisecond inter-strobe time, let alone something
> - * higher than ten milliseconds.
> - */
> -#define GB_TIMESYNC_STROBE_DELAY_US		1000
> -#define GB_TIMESYNC_DEFAULT_OFFSET_US		1000
> -
> -/* Work queue timers long, short and SVC strobe timeout */
> -#define GB_TIMESYNC_DELAYED_WORK_LONG		msecs_to_jiffies(10)
> -#define GB_TIMESYNC_DELAYED_WORK_SHORT		msecs_to_jiffies(1)
> -#define GB_TIMESYNC_MAX_WAIT_SVC		msecs_to_jiffies(5000)
> -#define GB_TIMESYNC_KTIME_UPDATE		msecs_to_jiffies(1000)
> -#define GB_TIMESYNC_MAX_KTIME_CONVERSION	15
> -
> -/* Maximum number of times we'll retry a failed synchronous sync */
> -#define GB_TIMESYNC_MAX_RETRIES			5
> -
> -/* Reported nanoseconds/femtoseconds per clock */
> -static u64 gb_timesync_ns_per_clock;
> -static u64 gb_timesync_fs_per_clock;
> -
> -/* Maximum difference we will accept converting FrameTime to ktime */
> -static u32 gb_timesync_max_ktime_diff;
> -
> -/* Reported clock rate */
> -static unsigned long gb_timesync_clock_rate;
> -
> -/* Workqueue */
> -static void gb_timesync_worker(struct work_struct *work);
> -
> -/* List of SVCs with one FrameTime per SVC */
> -static LIST_HEAD(gb_timesync_svc_list);
> -
> -/* Synchronize parallel contexts accessing a valid timesync_svc pointer */
> -static DEFINE_MUTEX(gb_timesync_svc_list_mutex);
> -
> -/* Structure to convert from FrameTime to timespec/ktime */
> -struct gb_timesync_frame_time_data {
> -	u64 frame_time;
> -	struct timespec ts;
> -};
> -
> -struct gb_timesync_svc {
> -	struct list_head list;
> -	struct list_head interface_list;
> -	struct gb_svc *svc;
> -	struct gb_timesync_host_device *timesync_hd;
> -
> -	spinlock_t spinlock;	/* Per SVC spinlock to sync with ISR */
> -	struct mutex mutex;	/* Per SVC mutex for regular synchronization */
> -
> -	struct dentry *frame_time_dentry;
> -	struct dentry *frame_ktime_dentry;
> -	struct workqueue_struct *work_queue;
> -	wait_queue_head_t wait_queue;
> -	struct delayed_work delayed_work;
> -	struct timer_list ktime_timer;
> -
> -	/* The current local FrameTime */
> -	u64 frame_time_offset;
> -	struct gb_timesync_frame_time_data strobe_data[GB_TIMESYNC_MAX_STROBES];
> -	struct gb_timesync_frame_time_data ktime_data;
> -
> -	/* The SVC FrameTime and relative AP FrameTime @ last TIMESYNC_PING */
> -	u64 svc_ping_frame_time;
> -	u64 ap_ping_frame_time;
> -
> -	/* Transitory settings */
> -	u32 strobe_mask;
> -	bool offset_down;
> -	bool print_ping;
> -	bool capture_ping;
> -	int strobe;
> -
> -	/* Current state */
> -	int state;
> -};
> -
> -struct gb_timesync_host_device {
> -	struct list_head list;
> -	struct gb_host_device *hd;
> -	u64 ping_frame_time;
> -};
> -
> -struct gb_timesync_interface {
> -	struct list_head list;
> -	struct gb_interface *interface;
> -	u64 ping_frame_time;
> -};
> -
> -enum gb_timesync_state {
> -	GB_TIMESYNC_STATE_INVALID		= 0,
> -	GB_TIMESYNC_STATE_INACTIVE		= 1,
> -	GB_TIMESYNC_STATE_INIT			= 2,
> -	GB_TIMESYNC_STATE_WAIT_SVC		= 3,
> -	GB_TIMESYNC_STATE_AUTHORITATIVE		= 4,
> -	GB_TIMESYNC_STATE_PING			= 5,
> -	GB_TIMESYNC_STATE_ACTIVE		= 6,
> -};
> -
> -static void gb_timesync_ktime_timer_fn(unsigned long data);
> -
> -static u64 gb_timesync_adjust_count(struct gb_timesync_svc *timesync_svc,
> -				    u64 counts)
> -{
> -	if (timesync_svc->offset_down)
> -		return counts - timesync_svc->frame_time_offset;
> -	else
> -		return counts + timesync_svc->frame_time_offset;
> -}
> -
> -/*
> - * This function provides the authoritative FrameTime to a calling function. It
> - * is designed to be lockless and should remain that way the caller is assumed
> - * to be state-aware.
> - */
> -static u64 __gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
> -{
> -	u64 clocks = gb_timesync_platform_get_counter();
> -
> -	return gb_timesync_adjust_count(timesync_svc, clocks);
> -}
> -
> -static void gb_timesync_schedule_svc_timeout(struct gb_timesync_svc
> -					     *timesync_svc)
> -{
> -	queue_delayed_work(timesync_svc->work_queue,
> -			   &timesync_svc->delayed_work,
> -			   GB_TIMESYNC_MAX_WAIT_SVC);
> -}
> -
> -static void gb_timesync_set_state(struct gb_timesync_svc *timesync_svc,
> -				  int state)
> -{
> -	switch (state) {
> -	case GB_TIMESYNC_STATE_INVALID:
> -		timesync_svc->state = state;
> -		wake_up(&timesync_svc->wait_queue);
> -		break;
> -	case GB_TIMESYNC_STATE_INACTIVE:
> -		timesync_svc->state = state;
> -		wake_up(&timesync_svc->wait_queue);
> -		break;
> -	case GB_TIMESYNC_STATE_INIT:
> -		if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) {
> -			timesync_svc->strobe = 0;
> -			timesync_svc->frame_time_offset = 0;
> -			timesync_svc->state = state;
> -			cancel_delayed_work(&timesync_svc->delayed_work);
> -			queue_delayed_work(timesync_svc->work_queue,
> -					   &timesync_svc->delayed_work,
> -					   GB_TIMESYNC_DELAYED_WORK_LONG);
> -		}
> -		break;
> -	case GB_TIMESYNC_STATE_WAIT_SVC:
> -		if (timesync_svc->state == GB_TIMESYNC_STATE_INIT)
> -			timesync_svc->state = state;
> -		break;
> -	case GB_TIMESYNC_STATE_AUTHORITATIVE:
> -		if (timesync_svc->state == GB_TIMESYNC_STATE_WAIT_SVC) {
> -			timesync_svc->state = state;
> -			cancel_delayed_work(&timesync_svc->delayed_work);
> -			queue_delayed_work(timesync_svc->work_queue,
> -					   &timesync_svc->delayed_work, 0);
> -		}
> -		break;
> -	case GB_TIMESYNC_STATE_PING:
> -		if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE) {
> -			timesync_svc->state = state;
> -			queue_delayed_work(timesync_svc->work_queue,
> -					   &timesync_svc->delayed_work,
> -					   GB_TIMESYNC_DELAYED_WORK_SHORT);
> -		}
> -		break;
> -	case GB_TIMESYNC_STATE_ACTIVE:
> -		if (timesync_svc->state == GB_TIMESYNC_STATE_AUTHORITATIVE ||
> -		    timesync_svc->state == GB_TIMESYNC_STATE_PING) {
> -			timesync_svc->state = state;
> -			wake_up(&timesync_svc->wait_queue);
> -		}
> -		break;
> -	}
> -
> -	if (WARN_ON(timesync_svc->state != state)) {
> -		pr_err("Invalid state transition %d=>%d\n",
> -		       timesync_svc->state, state);
> -	}
> -}
> -
> -static void gb_timesync_set_state_atomic(struct gb_timesync_svc *timesync_svc,
> -					 int state)
> -{
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -	gb_timesync_set_state(timesync_svc, state);
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -}
> -
> -static u64 gb_timesync_diff(u64 x, u64 y)
> -{
> -	if (x > y)
> -		return x - y;
> -	else
> -		return y - x;
> -}
> -
> -static void gb_timesync_adjust_to_svc(struct gb_timesync_svc *svc,
> -				      u64 svc_frame_time, u64 ap_frame_time)
> -{
> -	if (svc_frame_time > ap_frame_time) {
> -		svc->frame_time_offset = svc_frame_time - ap_frame_time;
> -		svc->offset_down = false;
> -	} else {
> -		svc->frame_time_offset = ap_frame_time - svc_frame_time;
> -		svc->offset_down = true;
> -	}
> -}
> -
> -/*
> - * Associate a FrameTime with a ktime timestamp represented as struct timespec
> - * Requires the calling context to hold timesync_svc->mutex
> - */
> -static void gb_timesync_store_ktime(struct gb_timesync_svc *timesync_svc,
> -				    struct timespec ts, u64 frame_time)
> -{
> -	timesync_svc->ktime_data.ts = ts;
> -	timesync_svc->ktime_data.frame_time = frame_time;
> -}
> -
> -/*
> - * Find the two pulses that best-match our expected inter-strobe gap and
> - * then calculate the difference between the SVC time at the second pulse
> - * to the local time at the second pulse.
> - */
> -static void gb_timesync_collate_frame_time(struct gb_timesync_svc *timesync_svc,
> -					   u64 *frame_time)
> -{
> -	int i = 0;
> -	u64 delta, ap_frame_time;
> -	u64 strobe_delay_ns = GB_TIMESYNC_STROBE_DELAY_US * NSEC_PER_USEC;
> -	u64 least = 0;
> -
> -	for (i = 1; i < GB_TIMESYNC_MAX_STROBES; i++) {
> -		delta = timesync_svc->strobe_data[i].frame_time -
> -			timesync_svc->strobe_data[i - 1].frame_time;
> -		delta *= gb_timesync_ns_per_clock;
> -		delta = gb_timesync_diff(delta, strobe_delay_ns);
> -
> -		if (!least || delta < least) {
> -			least = delta;
> -			gb_timesync_adjust_to_svc(timesync_svc, frame_time[i],
> -						  timesync_svc->strobe_data[i].frame_time);
> -
> -			ap_frame_time = timesync_svc->strobe_data[i].frame_time;
> -			ap_frame_time = gb_timesync_adjust_count(timesync_svc,
> -								 ap_frame_time);
> -			gb_timesync_store_ktime(timesync_svc,
> -						timesync_svc->strobe_data[i].ts,
> -						ap_frame_time);
> -
> -			pr_debug("adjust %s local %llu svc %llu delta %llu\n",
> -				 timesync_svc->offset_down ? "down" : "up",
> -				 timesync_svc->strobe_data[i].frame_time,
> -				 frame_time[i], delta);
> -		}
> -	}
> -}
> -
> -static void gb_timesync_teardown(struct gb_timesync_svc *timesync_svc)
> -{
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_interface *interface;
> -	struct gb_host_device *hd;
> -	int ret;
> -
> -	list_for_each_entry(timesync_interface,
> -			    &timesync_svc->interface_list, list) {
> -		interface = timesync_interface->interface;
> -		ret = gb_interface_timesync_disable(interface);
> -		if (ret) {
> -			dev_err(&interface->dev,
> -				"interface timesync_disable %d\n", ret);
> -		}
> -	}
> -
> -	hd = timesync_svc->timesync_hd->hd;
> -	ret = hd->driver->timesync_disable(hd);
> -	if (ret < 0) {
> -		dev_err(&hd->dev, "host timesync_disable %d\n",
> -			ret);
> -	}
> -
> -	gb_svc_timesync_wake_pins_release(svc);
> -	gb_svc_timesync_disable(svc);
> -	gb_timesync_platform_unlock_bus();
> -
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
> -}
> -
> -static void gb_timesync_platform_lock_bus_fail(struct gb_timesync_svc
> -						*timesync_svc, int ret)
> -{
> -	if (ret == -EAGAIN) {
> -		gb_timesync_set_state(timesync_svc, timesync_svc->state);
> -	} else {
> -		pr_err("Failed to lock timesync bus %d\n", ret);
> -		gb_timesync_set_state(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
> -	}
> -}
> -
> -static void gb_timesync_enable(struct gb_timesync_svc *timesync_svc)
> -{
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_host_device *hd;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_interface *interface;
> -	u64 init_frame_time;
> -	unsigned long clock_rate = gb_timesync_clock_rate;
> -	int ret;
> -
> -	/*
> -	 * Get access to the wake pins in the AP and SVC
> -	 * Release these pins either in gb_timesync_teardown() or in
> -	 * gb_timesync_authoritative()
> -	 */
> -	ret = gb_timesync_platform_lock_bus(timesync_svc);
> -	if (ret < 0) {
> -		gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
> -		return;
> -	}
> -	ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
> -	if (ret) {
> -		dev_err(&svc->dev,
> -			"gb_svc_timesync_wake_pins_acquire %d\n", ret);
> -		gb_timesync_teardown(timesync_svc);
> -		return;
> -	}
> -
> -	/* Choose an initial time in the future */
> -	init_frame_time = __gb_timesync_get_frame_time(timesync_svc) + 100000UL;
> -
> -	/* Send enable command to all relevant participants */
> -	list_for_each_entry(timesync_interface, &timesync_svc->interface_list,
> -			    list) {
> -		interface = timesync_interface->interface;
> -		ret = gb_interface_timesync_enable(interface,
> -						   GB_TIMESYNC_MAX_STROBES,
> -						   init_frame_time,
> -						   GB_TIMESYNC_STROBE_DELAY_US,
> -						   clock_rate);
> -		if (ret) {
> -			dev_err(&interface->dev,
> -				"interface timesync_enable %d\n", ret);
> -		}
> -	}
> -
> -	hd = timesync_svc->timesync_hd->hd;
> -	ret = hd->driver->timesync_enable(hd, GB_TIMESYNC_MAX_STROBES,
> -					  init_frame_time,
> -					  GB_TIMESYNC_STROBE_DELAY_US,
> -					  clock_rate);
> -	if (ret < 0) {
> -		dev_err(&hd->dev, "host timesync_enable %d\n",
> -			ret);
> -	}
> -
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_WAIT_SVC);
> -	ret = gb_svc_timesync_enable(svc, GB_TIMESYNC_MAX_STROBES,
> -				     init_frame_time,
> -				     GB_TIMESYNC_STROBE_DELAY_US,
> -				     clock_rate);
> -	if (ret) {
> -		dev_err(&svc->dev,
> -			"gb_svc_timesync_enable %d\n", ret);
> -		gb_timesync_teardown(timesync_svc);
> -		return;
> -	}
> -
> -	/* Schedule a timeout waiting for SVC to complete strobing */
> -	gb_timesync_schedule_svc_timeout(timesync_svc);
> -}
> -
> -static void gb_timesync_authoritative(struct gb_timesync_svc *timesync_svc)
> -{
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_host_device *hd;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_interface *interface;
> -	u64 svc_frame_time[GB_TIMESYNC_MAX_STROBES];
> -	int ret;
> -
> -	/* Get authoritative time from SVC and adjust local clock */
> -	ret = gb_svc_timesync_authoritative(svc, svc_frame_time);
> -	if (ret) {
> -		dev_err(&svc->dev,
> -			"gb_svc_timesync_authoritative %d\n", ret);
> -		gb_timesync_teardown(timesync_svc);
> -		return;
> -	}
> -	gb_timesync_collate_frame_time(timesync_svc, svc_frame_time);
> -
> -	/* Transmit authoritative time to downstream slaves */
> -	hd = timesync_svc->timesync_hd->hd;
> -	ret = hd->driver->timesync_authoritative(hd, svc_frame_time);
> -	if (ret < 0)
> -		dev_err(&hd->dev, "host timesync_authoritative %d\n", ret);
> -
> -	list_for_each_entry(timesync_interface,
> -			    &timesync_svc->interface_list, list) {
> -		interface = timesync_interface->interface;
> -		ret = gb_interface_timesync_authoritative(
> -						interface,
> -						svc_frame_time);
> -		if (ret) {
> -			dev_err(&interface->dev,
> -				"interface timesync_authoritative %d\n", ret);
> -		}
> -	}
> -
> -	/* Release wake pins */
> -	gb_svc_timesync_wake_pins_release(svc);
> -	gb_timesync_platform_unlock_bus();
> -
> -	/* Transition to state ACTIVE */
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
> -
> -	/* Schedule a ping to verify the synchronized system time */
> -	timesync_svc->print_ping = true;
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_PING);
> -}
> -
> -static int __gb_timesync_get_status(struct gb_timesync_svc *timesync_svc)
> -{
> -	int ret = -EINVAL;
> -
> -	switch (timesync_svc->state) {
> -	case GB_TIMESYNC_STATE_INVALID:
> -	case GB_TIMESYNC_STATE_INACTIVE:
> -		ret = -ENODEV;
> -		break;
> -	case GB_TIMESYNC_STATE_INIT:
> -	case GB_TIMESYNC_STATE_WAIT_SVC:
> -	case GB_TIMESYNC_STATE_AUTHORITATIVE:
> -		ret = -EAGAIN;
> -		break;
> -	case GB_TIMESYNC_STATE_PING:
> -	case GB_TIMESYNC_STATE_ACTIVE:
> -		ret = 0;
> -		break;
> -	}
> -	return ret;
> -}
> -
> -/*
> - * This routine takes a FrameTime and derives the difference with-respect
> - * to a reference FrameTime/ktime pair. It then returns the calculated
> - * ktime based on the difference between the supplied FrameTime and
> - * the reference FrameTime.
> - *
> - * The time difference is calculated to six decimal places. Taking 19.2MHz
> - * as an example this means we have 52.083333~ nanoseconds per clock or
> - * 52083333~ femtoseconds per clock.
> - *
> - * Naively taking the count difference and converting to
> - * seconds/nanoseconds would quickly see the 0.0833 component produce
> - * noticeable errors. For example a time difference of one second would
> - * loose 19200000 * 0.08333x nanoseconds or 1.59 seconds.
> - *
> - * In contrast calculating in femtoseconds the same example of 19200000 *
> - * 0.000000083333x nanoseconds per count of error is just 1.59 nanoseconds!
> - *
> - * Continuing the example of 19.2 MHz we cap the maximum error difference
> - * at a worst-case 0.3 microseconds over a potential calculation window of
> - * abount 15 seconds, meaning you can convert a FrameTime that is <= 15
> - * seconds older/younger than the reference time with a maximum error of
> - * 0.2385 useconds. Note 19.2MHz is an example frequency not a requirement.
> - */
> -static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
> -				   u64 frame_time, struct timespec *ts)
> -{
> -	unsigned long flags;
> -	u64 delta_fs, counts, sec, nsec;
> -	bool add;
> -	int ret = 0;
> -
> -	memset(ts, 0x00, sizeof(*ts));
> -	mutex_lock(&timesync_svc->mutex);
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -
> -	ret = __gb_timesync_get_status(timesync_svc);
> -	if (ret)
> -		goto done;
> -
> -	/* Support calculating ktime upwards or downwards from the reference */
> -	if (frame_time < timesync_svc->ktime_data.frame_time) {
> -		add = false;
> -		counts = timesync_svc->ktime_data.frame_time - frame_time;
> -	} else {
> -		add = true;
> -		counts = frame_time - timesync_svc->ktime_data.frame_time;
> -	}
> -
> -	/* Enforce the .23 of a usecond boundary @ 19.2MHz */
> -	if (counts > gb_timesync_max_ktime_diff) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Determine the time difference in femtoseconds */
> -	delta_fs = counts * gb_timesync_fs_per_clock;
> -
> -	/* Convert to seconds */
> -	sec = delta_fs;
> -	do_div(sec, NSEC_PER_SEC);
> -	do_div(sec, 1000000UL);
> -
> -	/* Get the nanosecond remainder */
> -	nsec = do_div(delta_fs, sec);
> -	do_div(nsec, 1000000UL);
> -
> -	if (add) {
> -		/* Add the calculated offset - overflow nanoseconds upwards */
> -		ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec + sec;
> -		ts->tv_nsec = timesync_svc->ktime_data.ts.tv_nsec + nsec;
> -		if (ts->tv_nsec >= NSEC_PER_SEC) {
> -			ts->tv_sec++;
> -			ts->tv_nsec -= NSEC_PER_SEC;
> -		}
> -	} else {
> -		/* Subtract the difference over/underflow as necessary */
> -		if (nsec > timesync_svc->ktime_data.ts.tv_nsec) {
> -			sec++;
> -			nsec = nsec + timesync_svc->ktime_data.ts.tv_nsec;
> -			nsec = do_div(nsec, NSEC_PER_SEC);
> -		} else {
> -			nsec = timesync_svc->ktime_data.ts.tv_nsec - nsec;
> -		}
> -		/* Cannot return a negative second value */
> -		if (sec > timesync_svc->ktime_data.ts.tv_sec) {
> -			ret = -EINVAL;
> -			goto done;
> -		}
> -		ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec - sec;
> -		ts->tv_nsec = nsec;
> -	}
> -done:
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -	mutex_unlock(&timesync_svc->mutex);
> -	return ret;
> -}
> -
> -static size_t gb_timesync_log_frame_time(struct gb_timesync_svc *timesync_svc,
> -					 char *buf, size_t buflen)
> -{
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_host_device *hd;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_interface *interface;
> -	unsigned int len;
> -	size_t off;
> -
> -	/* AP/SVC */
> -	off = snprintf(buf, buflen, "%s frametime: ap=%llu %s=%llu ",
> -		       greybus_bus_type.name,
> -		       timesync_svc->ap_ping_frame_time, dev_name(&svc->dev),
> -		       timesync_svc->svc_ping_frame_time);
> -	len = buflen - off;
> -
> -	/* APB/GPB */
> -	if (len < buflen) {
> -		hd = timesync_svc->timesync_hd->hd;
> -		off += snprintf(&buf[off], len, "%s=%llu ", dev_name(&hd->dev),
> -				timesync_svc->timesync_hd->ping_frame_time);
> -		len = buflen - off;
> -	}
> -
> -	list_for_each_entry(timesync_interface,
> -			    &timesync_svc->interface_list, list) {
> -		if (len < buflen) {
> -			interface = timesync_interface->interface;
> -			off += snprintf(&buf[off], len, "%s=%llu ",
> -					dev_name(&interface->dev),
> -					timesync_interface->ping_frame_time);
> -			len = buflen - off;
> -		}
> -	}
> -	if (len < buflen)
> -		off += snprintf(&buf[off], len, "\n");
> -	return off;
> -}
> -
> -static size_t gb_timesync_log_frame_ktime(struct gb_timesync_svc *timesync_svc,
> -					  char *buf, size_t buflen)
> -{
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_host_device *hd;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_interface *interface;
> -	struct timespec ts;
> -	unsigned int len;
> -	size_t off;
> -
> -	/* AP */
> -	gb_timesync_to_timespec(timesync_svc, timesync_svc->ap_ping_frame_time,
> -				&ts);
> -	off = snprintf(buf, buflen, "%s frametime: ap=%lu.%lu ",
> -		       greybus_bus_type.name, ts.tv_sec, ts.tv_nsec);
> -	len = buflen - off;
> -	if (len >= buflen)
> -		goto done;
> -
> -	/* SVC */
> -	gb_timesync_to_timespec(timesync_svc, timesync_svc->svc_ping_frame_time,
> -				&ts);
> -	off += snprintf(&buf[off], len, "%s=%lu.%lu ", dev_name(&svc->dev),
> -			ts.tv_sec, ts.tv_nsec);
> -	len = buflen - off;
> -	if (len >= buflen)
> -		goto done;
> -
> -	/* APB/GPB */
> -	hd = timesync_svc->timesync_hd->hd;
> -	gb_timesync_to_timespec(timesync_svc,
> -				timesync_svc->timesync_hd->ping_frame_time,
> -				&ts);
> -	off += snprintf(&buf[off], len, "%s=%lu.%lu ",
> -			dev_name(&hd->dev),
> -			ts.tv_sec, ts.tv_nsec);
> -	len = buflen - off;
> -	if (len >= buflen)
> -		goto done;
> -
> -	list_for_each_entry(timesync_interface,
> -			    &timesync_svc->interface_list, list) {
> -		interface = timesync_interface->interface;
> -		gb_timesync_to_timespec(timesync_svc,
> -					timesync_interface->ping_frame_time,
> -					&ts);
> -		off += snprintf(&buf[off], len, "%s=%lu.%lu ",
> -				dev_name(&interface->dev),
> -				ts.tv_sec, ts.tv_nsec);
> -		len = buflen - off;
> -		if (len >= buflen)
> -			goto done;
> -	}
> -	off += snprintf(&buf[off], len, "\n");
> -done:
> -	return off;
> -}
> -
> -/*
> - * Send an SVC initiated wake 'ping' to each TimeSync participant.
> - * Get the FrameTime from each participant associated with the wake
> - * ping.
> - */
> -static void gb_timesync_ping(struct gb_timesync_svc *timesync_svc)
> -{
> -	struct gb_svc *svc = timesync_svc->svc;
> -	struct gb_host_device *hd;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_control *control;
> -	u64 *ping_frame_time;
> -	int ret;
> -
> -	/* Get access to the wake pins in the AP and SVC */
> -	ret = gb_timesync_platform_lock_bus(timesync_svc);
> -	if (ret < 0) {
> -		gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
> -		return;
> -	}
> -	ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
> -	if (ret) {
> -		dev_err(&svc->dev,
> -			"gb_svc_timesync_wake_pins_acquire %d\n", ret);
> -		gb_timesync_teardown(timesync_svc);
> -		return;
> -	}
> -
> -	/* Have SVC generate a timesync ping */
> -	timesync_svc->capture_ping = true;
> -	timesync_svc->svc_ping_frame_time = 0;
> -	ret = gb_svc_timesync_ping(svc, &timesync_svc->svc_ping_frame_time);
> -	timesync_svc->capture_ping = false;
> -	if (ret) {
> -		dev_err(&svc->dev,
> -			"gb_svc_timesync_ping %d\n", ret);
> -		gb_timesync_teardown(timesync_svc);
> -		return;
> -	}
> -
> -	/* Get the ping FrameTime from each APB/GPB */
> -	hd = timesync_svc->timesync_hd->hd;
> -	timesync_svc->timesync_hd->ping_frame_time = 0;
> -	ret = hd->driver->timesync_get_last_event(hd,
> -		&timesync_svc->timesync_hd->ping_frame_time);
> -	if (ret)
> -		dev_err(&hd->dev, "host timesync_get_last_event %d\n", ret);
> -
> -	list_for_each_entry(timesync_interface,
> -			    &timesync_svc->interface_list, list) {
> -		control = timesync_interface->interface->control;
> -		timesync_interface->ping_frame_time = 0;
> -		ping_frame_time = &timesync_interface->ping_frame_time;
> -		ret = gb_control_timesync_get_last_event(control,
> -							 ping_frame_time);
> -		if (ret) {
> -			dev_err(&timesync_interface->interface->dev,
> -				"gb_control_timesync_get_last_event %d\n", ret);
> -		}
> -	}
> -
> -	/* Ping success - move to timesync active */
> -	gb_svc_timesync_wake_pins_release(svc);
> -	gb_timesync_platform_unlock_bus();
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
> -}
> -
> -static void gb_timesync_log_ping_time(struct gb_timesync_svc *timesync_svc)
> -{
> -	char *buf;
> -
> -	if (!timesync_svc->print_ping)
> -		return;
> -
> -	buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -	if (buf) {
> -		gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
> -		dev_dbg(&timesync_svc->svc->dev, "%s", buf);
> -		kfree(buf);
> -	}
> -}
> -
> -/*
> - * Perform the actual work of scheduled TimeSync logic.
> - */
> -static void gb_timesync_worker(struct work_struct *work)
> -{
> -	struct delayed_work *delayed_work = to_delayed_work(work);
> -	struct gb_timesync_svc *timesync_svc =
> -		container_of(delayed_work, struct gb_timesync_svc, delayed_work);
> -
> -	mutex_lock(&timesync_svc->mutex);
> -
> -	switch (timesync_svc->state) {
> -	case GB_TIMESYNC_STATE_INIT:
> -		gb_timesync_enable(timesync_svc);
> -		break;
> -
> -	case GB_TIMESYNC_STATE_WAIT_SVC:
> -		dev_err(&timesync_svc->svc->dev,
> -			"timeout SVC strobe completion %d/%d\n",
> -			timesync_svc->strobe, GB_TIMESYNC_MAX_STROBES);
> -		gb_timesync_teardown(timesync_svc);
> -		break;
> -
> -	case GB_TIMESYNC_STATE_AUTHORITATIVE:
> -		gb_timesync_authoritative(timesync_svc);
> -		break;
> -
> -	case GB_TIMESYNC_STATE_PING:
> -		gb_timesync_ping(timesync_svc);
> -		gb_timesync_log_ping_time(timesync_svc);
> -		break;
> -
> -	default:
> -		pr_err("Invalid state %d for delayed work\n",
> -		       timesync_svc->state);
> -		break;
> -	}
> -
> -	mutex_unlock(&timesync_svc->mutex);
> -}
> -
> -/*
> - * Schedule a new TimeSync INIT or PING operation serialized w/r to
> - * gb_timesync_worker().
> - */
> -static int gb_timesync_schedule(struct gb_timesync_svc *timesync_svc, int state)
> -{
> -	int ret = 0;
> -
> -	if (state != GB_TIMESYNC_STATE_INIT && state != GB_TIMESYNC_STATE_PING)
> -		return -EINVAL;
> -
> -	mutex_lock(&timesync_svc->mutex);
> -	if (timesync_svc->state !=  GB_TIMESYNC_STATE_INVALID)
> -		gb_timesync_set_state_atomic(timesync_svc, state);
> -	else
> -		ret = -ENODEV;
> -
> -	mutex_unlock(&timesync_svc->mutex);
> -	return ret;
> -}
> -
> -static int __gb_timesync_schedule_synchronous(
> -	struct gb_timesync_svc *timesync_svc, int state)
> -{
> -	unsigned long flags;
> -	int ret;
> -
> -	ret = gb_timesync_schedule(timesync_svc, state);
> -	if (ret)
> -		return ret;
> -
> -	ret = wait_event_interruptible(timesync_svc->wait_queue,
> -			(timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE ||
> -			 timesync_svc->state == GB_TIMESYNC_STATE_INACTIVE ||
> -			 timesync_svc->state == GB_TIMESYNC_STATE_INVALID));
> -	if (ret)
> -		return ret;
> -
> -	mutex_lock(&timesync_svc->mutex);
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -
> -	ret = __gb_timesync_get_status(timesync_svc);
> -
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -	mutex_unlock(&timesync_svc->mutex);
> -
> -	return ret;
> -}
> -
> -static struct gb_timesync_svc *gb_timesync_find_timesync_svc(
> -	struct gb_host_device *hd)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -
> -	list_for_each_entry(timesync_svc, &gb_timesync_svc_list, list) {
> -		if (timesync_svc->svc == hd->svc)
> -			return timesync_svc;
> -	}
> -	return NULL;
> -}
> -
> -static struct gb_timesync_interface *gb_timesync_find_timesync_interface(
> -	struct gb_timesync_svc *timesync_svc,
> -	struct gb_interface *interface)
> -{
> -	struct gb_timesync_interface *timesync_interface;
> -
> -	list_for_each_entry(timesync_interface, &timesync_svc->interface_list, list) {
> -		if (timesync_interface->interface == interface)
> -			return timesync_interface;
> -	}
> -	return NULL;
> -}
> -
> -int gb_timesync_schedule_synchronous(struct gb_interface *interface)
> -{
> -	int ret;
> -	struct gb_timesync_svc *timesync_svc;
> -	int retries;
> -
> -	if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
> -		return 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	for (retries = 0; retries < GB_TIMESYNC_MAX_RETRIES; retries++) {
> -		timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -		if (!timesync_svc) {
> -			ret = -ENODEV;
> -			goto done;
> -		}
> -
> -		ret = __gb_timesync_schedule_synchronous(timesync_svc,
> -						 GB_TIMESYNC_STATE_INIT);
> -		if (!ret)
> -			break;
> -	}
> -	if (ret && retries == GB_TIMESYNC_MAX_RETRIES)
> -		ret = -ETIMEDOUT;
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_schedule_synchronous);
> -
> -void gb_timesync_schedule_asynchronous(struct gb_interface *interface)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -
> -	if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
> -		return;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -	if (!timesync_svc)
> -		goto done;
> -
> -	gb_timesync_schedule(timesync_svc, GB_TIMESYNC_STATE_INIT);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_schedule_asynchronous);
> -
> -static ssize_t gb_timesync_ping_read(struct file *file, char __user *ubuf,
> -				     size_t len, loff_t *offset, bool ktime)
> -{
> -	struct gb_timesync_svc *timesync_svc = file_inode(file)->i_private;
> -	char *buf;
> -	ssize_t ret = 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	mutex_lock(&timesync_svc->mutex);
> -	if (list_empty(&timesync_svc->interface_list))
> -		ret = -ENODEV;
> -	timesync_svc->print_ping = false;
> -	mutex_unlock(&timesync_svc->mutex);
> -	if (ret)
> -		goto done;
> -
> -	ret = __gb_timesync_schedule_synchronous(timesync_svc,
> -						 GB_TIMESYNC_STATE_PING);
> -	if (ret)
> -		goto done;
> -
> -	buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -	if (!buf) {
> -		ret = -ENOMEM;
> -		goto done;
> -	}
> -
> -	if (ktime)
> -		ret = gb_timesync_log_frame_ktime(timesync_svc, buf, PAGE_SIZE);
> -	else
> -		ret = gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
> -	if (ret > 0)
> -		ret = simple_read_from_buffer(ubuf, len, offset, buf, ret);
> -	kfree(buf);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -
> -static ssize_t gb_timesync_ping_read_frame_time(struct file *file,
> -						char __user *buf,
> -						size_t len, loff_t *offset)
> -{
> -	return gb_timesync_ping_read(file, buf, len, offset, false);
> -}
> -
> -static ssize_t gb_timesync_ping_read_frame_ktime(struct file *file,
> -						 char __user *buf,
> -						 size_t len, loff_t *offset)
> -{
> -	return gb_timesync_ping_read(file, buf, len, offset, true);
> -}
> -
> -static const struct file_operations gb_timesync_debugfs_frame_time_ops = {
> -	.read		= gb_timesync_ping_read_frame_time,
> -};
> -
> -static const struct file_operations gb_timesync_debugfs_frame_ktime_ops = {
> -	.read		= gb_timesync_ping_read_frame_ktime,
> -};
> -
> -static int gb_timesync_hd_add(struct gb_timesync_svc *timesync_svc,
> -			      struct gb_host_device *hd)
> -{
> -	struct gb_timesync_host_device *timesync_hd;
> -
> -	timesync_hd = kzalloc(sizeof(*timesync_hd), GFP_KERNEL);
> -	if (!timesync_hd)
> -		return -ENOMEM;
> -
> -	WARN_ON(timesync_svc->timesync_hd);
> -	timesync_hd->hd = hd;
> -	timesync_svc->timesync_hd = timesync_hd;
> -
> -	return 0;
> -}
> -
> -static void gb_timesync_hd_remove(struct gb_timesync_svc *timesync_svc,
> -				  struct gb_host_device *hd)
> -{
> -	if (timesync_svc->timesync_hd->hd == hd) {
> -		kfree(timesync_svc->timesync_hd);
> -		timesync_svc->timesync_hd = NULL;
> -		return;
> -	}
> -	WARN_ON(1);
> -}
> -
> -int gb_timesync_svc_add(struct gb_svc *svc)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	int ret;
> -
> -	timesync_svc = kzalloc(sizeof(*timesync_svc), GFP_KERNEL);
> -	if (!timesync_svc)
> -		return -ENOMEM;
> -
> -	timesync_svc->work_queue =
> -		create_singlethread_workqueue("gb-timesync-work_queue");
> -
> -	if (!timesync_svc->work_queue) {
> -		kfree(timesync_svc);
> -		return -ENOMEM;
> -	}
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	INIT_LIST_HEAD(&timesync_svc->interface_list);
> -	INIT_DELAYED_WORK(&timesync_svc->delayed_work, gb_timesync_worker);
> -	mutex_init(&timesync_svc->mutex);
> -	spin_lock_init(&timesync_svc->spinlock);
> -	init_waitqueue_head(&timesync_svc->wait_queue);
> -
> -	timesync_svc->svc = svc;
> -	timesync_svc->frame_time_offset = 0;
> -	timesync_svc->capture_ping = false;
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
> -
> -	timesync_svc->frame_time_dentry =
> -		debugfs_create_file("frame-time", S_IRUGO, svc->debugfs_dentry,
> -				    timesync_svc,
> -				    &gb_timesync_debugfs_frame_time_ops);
> -	timesync_svc->frame_ktime_dentry =
> -		debugfs_create_file("frame-ktime", S_IRUGO, svc->debugfs_dentry,
> -				    timesync_svc,
> -				    &gb_timesync_debugfs_frame_ktime_ops);
> -
> -	list_add(&timesync_svc->list, &gb_timesync_svc_list);
> -	ret = gb_timesync_hd_add(timesync_svc, svc->hd);
> -	if (ret) {
> -		list_del(&timesync_svc->list);
> -		debugfs_remove(timesync_svc->frame_ktime_dentry);
> -		debugfs_remove(timesync_svc->frame_time_dentry);
> -		destroy_workqueue(timesync_svc->work_queue);
> -		kfree(timesync_svc);
> -		goto done;
> -	}
> -
> -	init_timer(&timesync_svc->ktime_timer);
> -	timesync_svc->ktime_timer.function = gb_timesync_ktime_timer_fn;
> -	timesync_svc->ktime_timer.expires = jiffies + GB_TIMESYNC_KTIME_UPDATE;
> -	timesync_svc->ktime_timer.data = (unsigned long)timesync_svc;
> -	add_timer(&timesync_svc->ktime_timer);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_svc_add);
> -
> -void gb_timesync_svc_remove(struct gb_svc *svc)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	struct gb_timesync_interface *timesync_interface;
> -	struct gb_timesync_interface *next;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
> -	if (!timesync_svc)
> -		goto done;
> -
> -	cancel_delayed_work_sync(&timesync_svc->delayed_work);
> -
> -	mutex_lock(&timesync_svc->mutex);
> -
> -	gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INVALID);
> -	del_timer_sync(&timesync_svc->ktime_timer);
> -	gb_timesync_teardown(timesync_svc);
> -
> -	gb_timesync_hd_remove(timesync_svc, svc->hd);
> -	list_for_each_entry_safe(timesync_interface, next,
> -				 &timesync_svc->interface_list, list) {
> -		list_del(&timesync_interface->list);
> -		kfree(timesync_interface);
> -	}
> -	debugfs_remove(timesync_svc->frame_ktime_dentry);
> -	debugfs_remove(timesync_svc->frame_time_dentry);
> -	destroy_workqueue(timesync_svc->work_queue);
> -	list_del(&timesync_svc->list);
> -
> -	mutex_unlock(&timesync_svc->mutex);
> -
> -	kfree(timesync_svc);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_svc_remove);
> -
> -/*
> - * Add a Greybus Interface to the set of TimeSync Interfaces.
> - */
> -int gb_timesync_interface_add(struct gb_interface *interface)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	struct gb_timesync_interface *timesync_interface;
> -	int ret = 0;
> -
> -	if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
> -		return 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -	if (!timesync_svc) {
> -		ret = -ENODEV;
> -		goto done;
> -	}
> -
> -	timesync_interface = kzalloc(sizeof(*timesync_interface), GFP_KERNEL);
> -	if (!timesync_interface) {
> -		ret = -ENOMEM;
> -		goto done;
> -	}
> -
> -	mutex_lock(&timesync_svc->mutex);
> -	timesync_interface->interface = interface;
> -	list_add(&timesync_interface->list, &timesync_svc->interface_list);
> -	timesync_svc->strobe_mask |= 1 << interface->interface_id;
> -	mutex_unlock(&timesync_svc->mutex);
> -
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_interface_add);
> -
> -/*
> - * Remove a Greybus Interface from the set of TimeSync Interfaces.
> - */
> -void gb_timesync_interface_remove(struct gb_interface *interface)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	struct gb_timesync_interface *timesync_interface;
> -
> -	if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
> -		return;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -	if (!timesync_svc)
> -		goto done;
> -
> -	timesync_interface = gb_timesync_find_timesync_interface(timesync_svc,
> -								 interface);
> -	if (!timesync_interface)
> -		goto done;
> -
> -	mutex_lock(&timesync_svc->mutex);
> -	timesync_svc->strobe_mask &= ~(1 << interface->interface_id);
> -	list_del(&timesync_interface->list);
> -	kfree(timesync_interface);
> -	mutex_unlock(&timesync_svc->mutex);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_interface_remove);
> -
> -/*
> - * Give the authoritative FrameTime to the calling function. Returns zero if we
> - * are not in GB_TIMESYNC_STATE_ACTIVE.
> - */
> -static u64 gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
> -{
> -	unsigned long flags;
> -	u64 ret;
> -
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -	if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE)
> -		ret = __gb_timesync_get_frame_time(timesync_svc);
> -	else
> -		ret = 0;
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -	return ret;
> -}
> -
> -u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	u64 ret = 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -	if (!timesync_svc)
> -		goto done;
> -
> -	ret = gb_timesync_get_frame_time(timesync_svc);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_interface);
> -
> -u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	u64 ret = 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
> -	if (!timesync_svc)
> -		goto done;
> -
> -	ret = gb_timesync_get_frame_time(timesync_svc);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_svc);
> -
> -/* Incrementally updates the conversion base from FrameTime to ktime */
> -static void gb_timesync_ktime_timer_fn(unsigned long data)
> -{
> -	struct gb_timesync_svc *timesync_svc =
> -		(struct gb_timesync_svc *)data;
> -	unsigned long flags;
> -	u64 frame_time;
> -	struct timespec ts;
> -
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -
> -	if (timesync_svc->state != GB_TIMESYNC_STATE_ACTIVE)
> -		goto done;
> -
> -	ktime_get_ts(&ts);
> -	frame_time = __gb_timesync_get_frame_time(timesync_svc);
> -	gb_timesync_store_ktime(timesync_svc, ts, frame_time);
> -
> -done:
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -	mod_timer(&timesync_svc->ktime_timer,
> -		  jiffies + GB_TIMESYNC_KTIME_UPDATE);
> -}
> -
> -int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
> -				   struct timespec *ts)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	int ret = 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
> -	if (!timesync_svc) {
> -		ret = -ENODEV;
> -		goto done;
> -	}
> -	ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_svc);
> -
> -int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
> -					 u64 frame_time, struct timespec *ts)
> -{
> -	struct gb_timesync_svc *timesync_svc;
> -	int ret = 0;
> -
> -	mutex_lock(&gb_timesync_svc_list_mutex);
> -	timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
> -	if (!timesync_svc) {
> -		ret = -ENODEV;
> -		goto done;
> -	}
> -
> -	ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
> -done:
> -	mutex_unlock(&gb_timesync_svc_list_mutex);
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_interface);
> -
> -void gb_timesync_irq(struct gb_timesync_svc *timesync_svc)
> -{
> -	unsigned long flags;
> -	u64 strobe_time;
> -	bool strobe_is_ping = true;
> -	struct timespec ts;
> -
> -	ktime_get_ts(&ts);
> -	strobe_time = __gb_timesync_get_frame_time(timesync_svc);
> -
> -	spin_lock_irqsave(&timesync_svc->spinlock, flags);
> -
> -	if (timesync_svc->state == GB_TIMESYNC_STATE_PING) {
> -		if (!timesync_svc->capture_ping)
> -			goto done_nolog;
> -		timesync_svc->ap_ping_frame_time = strobe_time;
> -		goto done_log;
> -	} else if (timesync_svc->state != GB_TIMESYNC_STATE_WAIT_SVC) {
> -		goto done_nolog;
> -	}
> -
> -	timesync_svc->strobe_data[timesync_svc->strobe].frame_time = strobe_time;
> -	timesync_svc->strobe_data[timesync_svc->strobe].ts = ts;
> -
> -	if (++timesync_svc->strobe == GB_TIMESYNC_MAX_STROBES) {
> -		gb_timesync_set_state(timesync_svc,
> -				      GB_TIMESYNC_STATE_AUTHORITATIVE);
> -	}
> -	strobe_is_ping = false;
> -done_log:
> -	trace_gb_timesync_irq(strobe_is_ping, timesync_svc->strobe,
> -			      GB_TIMESYNC_MAX_STROBES, strobe_time);
> -done_nolog:
> -	spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
> -}
> -EXPORT_SYMBOL(gb_timesync_irq);
> -
> -int __init gb_timesync_init(void)
> -{
> -	int ret = 0;
> -
> -	ret = gb_timesync_platform_init();
> -	if (ret) {
> -		pr_err("timesync platform init fail!\n");
> -		return ret;
> -	}
> -
> -	gb_timesync_clock_rate = gb_timesync_platform_get_clock_rate();
> -
> -	/* Calculate nanoseconds and femtoseconds per clock */
> -	gb_timesync_fs_per_clock = FSEC_PER_SEC;
> -	do_div(gb_timesync_fs_per_clock, gb_timesync_clock_rate);
> -	gb_timesync_ns_per_clock = NSEC_PER_SEC;
> -	do_div(gb_timesync_ns_per_clock, gb_timesync_clock_rate);
> -
> -	/* Calculate the maximum number of clocks we will convert to ktime */
> -	gb_timesync_max_ktime_diff =
> -		GB_TIMESYNC_MAX_KTIME_CONVERSION * gb_timesync_clock_rate;
> -
> -	pr_info("Time-Sync @ %lu Hz max ktime conversion +/- %d seconds\n",
> -		gb_timesync_clock_rate, GB_TIMESYNC_MAX_KTIME_CONVERSION);
> -	return 0;
> -}
> -
> -void gb_timesync_exit(void)
> -{
> -	gb_timesync_platform_exit();
> -}
> diff --git a/drivers/staging/greybus/timesync.h b/drivers/staging/greybus/timesync.h
> deleted file mode 100644
> index 72fc9a35a002..000000000000
> --- a/drivers/staging/greybus/timesync.h
> +++ /dev/null
> @@ -1,45 +0,0 @@
> -/*
> - * TimeSync API driver.
> - *
> - * Copyright 2016 Google Inc.
> - * Copyright 2016 Linaro Ltd.
> - *
> - * Released under the GPLv2 only.
> - */
> -
> -#ifndef __TIMESYNC_H
> -#define __TIMESYNC_H
> -
> -struct gb_svc;
> -struct gb_interface;
> -struct gb_timesync_svc;
> -
> -/* Platform */
> -u64 gb_timesync_platform_get_counter(void);
> -u32 gb_timesync_platform_get_clock_rate(void);
> -int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata);
> -void gb_timesync_platform_unlock_bus(void);
> -
> -int gb_timesync_platform_init(void);
> -void gb_timesync_platform_exit(void);
> -
> -/* Core API */
> -int gb_timesync_interface_add(struct gb_interface *interface);
> -void gb_timesync_interface_remove(struct gb_interface *interface);
> -int gb_timesync_svc_add(struct gb_svc *svc);
> -void gb_timesync_svc_remove(struct gb_svc *svc);
> -
> -u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface);
> -u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc);
> -int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
> -				   struct timespec *ts);
> -int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
> -					 u64 frame_time, struct timespec *ts);
> -
> -int gb_timesync_schedule_synchronous(struct gb_interface *intf);
> -void gb_timesync_schedule_asynchronous(struct gb_interface *intf);
> -void gb_timesync_irq(struct gb_timesync_svc *timesync_svc);
> -int gb_timesync_init(void);
> -void gb_timesync_exit(void);
> -
> -#endif /* __TIMESYNC_H */
> diff --git a/drivers/staging/greybus/timesync_platform.c b/drivers/staging/greybus/timesync_platform.c
> deleted file mode 100644
> index 113f3d6c4b3a..000000000000
> --- a/drivers/staging/greybus/timesync_platform.c
> +++ /dev/null
> @@ -1,82 +0,0 @@
> -/*
> - * TimeSync API driver.
> - *
> - * Copyright 2016 Google Inc.
> - * Copyright 2016 Linaro Ltd.
> - *
> - * Released under the GPLv2 only.
> - *
> - * This code reads directly from an ARMv7 memory-mapped timer that lives in
> - * MMIO space. Since this counter lives inside of MMIO space its shared between
> - * cores and that means we don't have to worry about issues like TSC on x86
> - * where each time-stamp-counter (TSC) is local to a particular core.
> - *
> - * Register-level access code is based on
> - * drivers/clocksource/arm_arch_timer.c
> - */
> -#include <linux/cpufreq.h>
> -#include <linux/of_platform.h>
> -
> -#include "greybus.h"
> -#include "arche_platform.h"
> -
> -#define DEFAULT_FRAMETIME_CLOCK_HZ 19200000
> -
> -static u32 gb_timesync_clock_frequency;
> -int (*arche_platform_change_state_cb)(enum arche_platform_state state,
> -				      struct gb_timesync_svc *pdata);
> -EXPORT_SYMBOL_GPL(arche_platform_change_state_cb);
> -
> -u64 gb_timesync_platform_get_counter(void)
> -{
> -	return (u64)get_cycles();
> -}
> -
> -u32 gb_timesync_platform_get_clock_rate(void)
> -{
> -	if (unlikely(!gb_timesync_clock_frequency)) {
> -		gb_timesync_clock_frequency = cpufreq_get(0);
> -		if (!gb_timesync_clock_frequency)
> -			gb_timesync_clock_frequency = DEFAULT_FRAMETIME_CLOCK_HZ;
> -	}
> -
> -	return gb_timesync_clock_frequency;
> -}
> -
> -int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata)
> -{
> -	return arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_TIME_SYNC,
> -					      pdata);
> -}
> -
> -void gb_timesync_platform_unlock_bus(void)
> -{
> -	arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_ACTIVE, NULL);
> -}
> -
> -static const struct of_device_id arch_timer_of_match[] = {
> -	{ .compatible   = "google,greybus-frame-time-counter", },
> -	{},
> -};
> -
> -int __init gb_timesync_platform_init(void)
> -{
> -	struct device_node *np;
> -
> -	np = of_find_matching_node(NULL, arch_timer_of_match);
> -	if (!np) {
> -		/* Tolerate not finding to allow BBB etc to continue */
> -		pr_warn("Unable to find a compatible ARMv7 timer\n");
> -		return 0;
> -	}
> -
> -	if (of_property_read_u32(np, "clock-frequency",
> -				 &gb_timesync_clock_frequency)) {
> -		pr_err("Unable to find timer clock-frequency\n");
> -		return -ENODEV;
> -	}
> -
> -	return 0;
> -}
> -
> -void gb_timesync_platform_exit(void) {}
> 

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux