1
0
Fork 0

staging: greybus: remove timesync protocol support

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@linuxfoundation.org>
Reviewed-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Alex Elder <elder@kernel.org>
Acked-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
hifive-unleashed-5.1
Greg Kroah-Hartman 2017-01-05 18:39:12 +01:00
parent 02bbd9802d
commit bdfb95c4ba
17 changed files with 3 additions and 1925 deletions

View File

@ -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

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 {

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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) {}