diff options
Diffstat (limited to 'drivers/staging/greybus')
41 files changed, 254 insertions, 2174 deletions
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-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index 3fda0cd6bb42..02243b4fd898 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -168,7 +168,10 @@ static int standby_boot_seq(struct platform_device *pdev) if (apb->init_disabled) return 0; - /* Even if it is in OFF state, then we do not want to change the state */ + /* + * Even if it is in OFF state, + * then we do not want to change the state + */ if (apb->state == ARCHE_PLATFORM_STATE_STANDBY || apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; @@ -461,7 +464,7 @@ static int arche_apb_ctrl_remove(struct platform_device *pdev) return 0; } -static int arche_apb_ctrl_suspend(struct device *dev) +static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev) { /* * If timing profile permits, we may shutdown bridge @@ -475,7 +478,7 @@ static int arche_apb_ctrl_suspend(struct device *dev) return 0; } -static int arche_apb_ctrl_resume(struct device *dev) +static int __maybe_unused arche_apb_ctrl_resume(struct device *dev) { /* * Atleast for ES2 we have to meet the delay requirement between diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 338c2d3ee842..aac1145f1983 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -312,9 +312,11 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) if (arche_pdata->wake_detect_state == WD_STATE_IDLE) { arche_pdata->wake_detect_start = jiffies; /* - * In the begining, when wake/detect goes low (first time), we assume - * it is meant for coldboot and set the flag. If wake/detect line stays low - * beyond 30msec, then it is coldboot else fallback to standby boot. + * In the begining, when wake/detect goes low + * (first time), we assume it is meant for coldboot + * and set the flag. If wake/detect line stays low + * beyond 30msec, then it is coldboot else fallback + * to standby boot. */ arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_BOOT_INIT); @@ -330,7 +332,8 @@ exit: /* * Requires arche_pdata->platform_state_mutex to be held */ -static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) +static int +arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) { int ret; @@ -364,7 +367,8 @@ static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdat /* * Requires arche_pdata->platform_state_mutex to be held */ -static int arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) +static int +arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) { int ret; @@ -398,7 +402,8 @@ static int arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_p /* * Requires arche_pdata->platform_state_mutex to be held */ -static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) +static void +arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) { unsigned long flags; @@ -561,14 +566,17 @@ static int arche_platform_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; int ret; - arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), GFP_KERNEL); + arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), + GFP_KERNEL); if (!arche_pdata) return -ENOMEM; /* setup svc reset gpio */ arche_pdata->is_reset_act_hi = of_property_read_bool(np, "svc,reset-active-high"); - arche_pdata->svc_reset_gpio = of_get_named_gpio(np, "svc,reset-gpio", 0); + arche_pdata->svc_reset_gpio = of_get_named_gpio(np, + "svc,reset-gpio", + 0); if (arche_pdata->svc_reset_gpio < 0) { dev_err(dev, "failed to get reset-gpio\n"); return arche_pdata->svc_reset_gpio; @@ -610,7 +618,8 @@ static int arche_platform_probe(struct platform_device *pdev) dev_err(dev, "failed to get svc clock-req gpio\n"); return arche_pdata->svc_refclk_req; } - ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, "svc-clk-req"); + ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, + "svc-clk-req"); if (ret) { dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret); return ret; @@ -634,13 +643,16 @@ static int arche_platform_probe(struct platform_device *pdev) arche_pdata->num_apbs = of_get_child_count(np); dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); - arche_pdata->wake_detect_gpio = of_get_named_gpio(np, "svc,wake-detect-gpio", 0); + arche_pdata->wake_detect_gpio = of_get_named_gpio(np, + "svc,wake-detect-gpio", + 0); if (arche_pdata->wake_detect_gpio < 0) { dev_err(dev, "failed to get wake detect gpio\n"); return arche_pdata->wake_detect_gpio; } - ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, "wake detect"); + ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, + "wake detect"); if (ret) { dev_err(dev, "Failed requesting wake_detect gpio %d\n", arche_pdata->wake_detect_gpio); @@ -658,10 +670,11 @@ static int arche_platform_probe(struct platform_device *pdev) gpio_to_irq(arche_pdata->wake_detect_gpio); ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, - arche_platform_wd_irq, - arche_platform_wd_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - dev_name(dev), arche_pdata); + arche_platform_wd_irq, + arche_platform_wd_irq_thread, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + dev_name(dev), arche_pdata); if (ret) { dev_err(dev, "failed to request wake detect IRQ %d\n", ret); return ret; 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/arpc.h b/drivers/staging/greybus/arpc.h index 7fbddfc40d83..c0b63c0130c5 100644 --- a/drivers/staging/greybus/arpc.h +++ b/drivers/staging/greybus/arpc.h @@ -74,7 +74,6 @@ struct arpc_response_message { __u8 result; /* Result of RPC */ } __packed; - /* ARPC requests */ #define ARPC_TYPE_CPORT_CONNECTED 0x01 #define ARPC_TYPE_CPORT_QUIESCE 0x02 diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index f8862c6d7102..25c8bb4cb0de 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -496,6 +496,11 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream, gb_pm_runtime_put_noidle(bundle); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sig_bits = dai->driver->playback.sig_bits; + else + sig_bits = dai->driver->capture.sig_bits; + params->state = GBAUDIO_CODEC_HWPARAMS; params->format = format; params->rate = rate; @@ -689,6 +694,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .rate_min = 48000, .channels_min = 1, .channels_max = 2, + .sig_bits = 16, }, .capture = { .stream_name = "I2S 0 Capture", @@ -698,6 +704,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .rate_min = 48000, .channels_min = 1, .channels_max = 2, + .sig_bits = 16, }, .ops = &gbcodec_dai_ops, }, @@ -831,7 +838,10 @@ int gbaudio_register_module(struct gbaudio_module_info *module) snd_soc_dapm_link_component_dai_widgets(codec->card, &codec->dapm); #ifdef CONFIG_SND_JACK - /* register jack devices for this module from codec->jack_list */ + /* + * register jack devices for this module + * from codec->jack_list + */ list_for_each_entry(jack, &codec->jack_list, list) { if ((jack == &module->headset_jack) || (jack == &module->button_jack)) @@ -1019,47 +1029,16 @@ static int gbcodec_remove(struct snd_soc_codec *codec) return 0; } -static u8 gbcodec_reg[GBCODEC_REG_COUNT] = { - [GBCODEC_CTL_REG] = GBCODEC_CTL_REG_DEFAULT, - [GBCODEC_MUTE_REG] = GBCODEC_MUTE_REG_DEFAULT, - [GBCODEC_PB_LVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT, - [GBCODEC_PB_RVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT, - [GBCODEC_CAP_LVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT, - [GBCODEC_CAP_RVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT, - [GBCODEC_APB1_MUX_REG] = GBCODEC_APB1_MUX_REG_DEFAULT, - [GBCODEC_APB2_MUX_REG] = GBCODEC_APB2_MUX_REG_DEFAULT, -}; - static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - int ret = 0; - - if (reg == SND_SOC_NOPM) - return 0; - - BUG_ON(reg >= GBCODEC_REG_COUNT); - - gbcodec_reg[reg] = value; - dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, value); - - return ret; + return 0; } static unsigned int gbcodec_read(struct snd_soc_codec *codec, unsigned int reg) { - unsigned int val = 0; - - if (reg == SND_SOC_NOPM) - return 0; - - BUG_ON(reg >= GBCODEC_REG_COUNT); - - val = gbcodec_reg[reg]; - dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, val); - - return val; + return 0; } static struct snd_soc_codec_driver soc_codec_dev_gbaudio = { @@ -1069,10 +1048,6 @@ static struct snd_soc_codec_driver soc_codec_dev_gbaudio = { .read = gbcodec_read, .write = gbcodec_write, - .reg_cache_size = GBCODEC_REG_COUNT, - .reg_cache_default = gbcodec_reg_defaults, - .reg_word_size = 1, - .idle_bias_off = true, .ignore_pmdown_time = 1, }; diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h index 62fd93939a1f..6fb064c69a36 100644 --- a/drivers/staging/greybus/audio_codec.h +++ b/drivers/staging/greybus/audio_codec.h @@ -24,18 +24,6 @@ enum { NUM_CODEC_DAIS, }; -enum gbcodec_reg_index { - GBCODEC_CTL_REG, - GBCODEC_MUTE_REG, - GBCODEC_PB_LVOL_REG, - GBCODEC_PB_RVOL_REG, - GBCODEC_CAP_LVOL_REG, - GBCODEC_CAP_RVOL_REG, - GBCODEC_APB1_MUX_REG, - GBCODEC_APB2_MUX_REG, - GBCODEC_REG_COUNT -}; - /* device_type should be same as defined in audio.h (Android media layer) */ enum { GBAUDIO_DEVICE_NONE = 0x0, @@ -51,42 +39,9 @@ enum { GBAUDIO_DEVICE_IN_WIRED_HEADSET = GBAUDIO_DEVICE_BIT_IN | 0x10, }; -/* bit 0-SPK, 1-HP, 2-DAC, - * 4-MIC, 5-HSMIC, 6-MIC2 - */ -#define GBCODEC_CTL_REG_DEFAULT 0x00 - -/* bit 0,1 - APB1-PB-L/R - * bit 2,3 - APB2-PB-L/R - * bit 4,5 - APB1-Cap-L/R - * bit 6,7 - APB2-Cap-L/R - */ -#define GBCODEC_MUTE_REG_DEFAULT 0x00 - -/* 0-127 steps */ -#define GBCODEC_PB_VOL_REG_DEFAULT 0x00 -#define GBCODEC_CAP_VOL_REG_DEFAULT 0x00 - -/* bit 0,1,2 - PB stereo, left, right - * bit 8,9,10 - Cap stereo, left, right - */ -#define GBCODEC_APB1_MUX_REG_DEFAULT 0x00 -#define GBCODEC_APB2_MUX_REG_DEFAULT 0x00 - #define GBCODEC_JACK_MASK 0x0000FFFF #define GBCODEC_JACK_BUTTON_MASK 0xFFFF0000 -static const u8 gbcodec_reg_defaults[GBCODEC_REG_COUNT] = { - GBCODEC_CTL_REG_DEFAULT, - GBCODEC_MUTE_REG_DEFAULT, - GBCODEC_PB_VOL_REG_DEFAULT, - GBCODEC_PB_VOL_REG_DEFAULT, - GBCODEC_CAP_VOL_REG_DEFAULT, - GBCODEC_CAP_VOL_REG_DEFAULT, - GBCODEC_APB1_MUX_REG_DEFAULT, - GBCODEC_APB2_MUX_REG_DEFAULT, -}; - enum gbaudio_codec_state { GBAUDIO_CODEC_SHUTDOWN = 0, GBAUDIO_CODEC_STARTUP, @@ -116,7 +71,6 @@ struct gbaudio_codec_info { /* to maintain runtime stream params for each DAI */ struct list_head dai_list; struct mutex lock; - u8 reg[GBCODEC_REG_COUNT]; }; struct gbaudio_widget { diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c index 42f287dd7b84..7884d8482dc0 100644 --- a/drivers/staging/greybus/audio_gb.c +++ b/drivers/staging/greybus/audio_gb.c @@ -108,7 +108,7 @@ int gb_audio_gb_disable_widget(struct gb_connection *connection, EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget); int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport, - uint32_t *format, uint32_t *rate, u8 *channels, + u32 *format, u32 *rate, u8 *channels, u8 *sig_bits) { struct gb_audio_get_pcm_request req; @@ -132,7 +132,7 @@ int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport, EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm); int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport, - uint32_t format, uint32_t rate, u8 channels, + u32 format, u32 rate, u8 channels, u8 sig_bits) { struct gb_audio_set_pcm_request req; diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 17a9948b1ba1..094c3be79b33 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module, struct gb_audio_streaming_event_request *req) { dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n", - req->data_cport, req->event); + le16_to_cpu(req->data_cport), req->event); return 0; } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 8b216ca99cf9..07fac3948f3a 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, { const char **strings; int i; + unsigned int items; __u8 *data; - strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items, - GFP_KERNEL); + items = le32_to_cpu(gbenum->items); + strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL); data = gbenum->names; - for (i = 0; i < gbenum->items; i++) { + for (i = 0; i < items; i++) { strings[i] = (const char *)data; while (*data != '\0') data++; @@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: - uinfo->value.integer.min = info->value.integer.min; - uinfo->value.integer.max = info->value.integer.max; + uinfo->value.integer.min = le32_to_cpu(info->value.integer.min); + uinfo->value.integer.max = le32_to_cpu(info->value.integer.max); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: - max = info->value.enumerated.items; + max = le32_to_cpu(info->value.enumerated.items); uinfo->value.enumerated.items = max; if (uinfo->value.enumerated.item > max - 1) uinfo->value.enumerated.item = max - 1; @@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: ucontrol->value.integer.value[0] = - gbvalue.value.integer_value[0]; + le32_to_cpu(gbvalue.value.integer_value[0]); if (data->vcount == 2) ucontrol->value.integer.value[1] = - gbvalue.value.integer_value[1]; + le32_to_cpu(gbvalue.value.integer_value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: ucontrol->value.enumerated.item[0] = - gbvalue.value.enumerated_item[0]; + le32_to_cpu(gbvalue.value.enumerated_item[0]); if (data->vcount == 2) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); break; default: dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", @@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: gbvalue.value.integer_value[0] = - ucontrol->value.integer.value[0]; + cpu_to_le32(ucontrol->value.integer.value[0]); if (data->vcount == 2) gbvalue.value.integer_value[1] = - ucontrol->value.integer.value[1]; + cpu_to_le32(ucontrol->value.integer.value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: gbvalue.value.enumerated_item[0] = - ucontrol->value.enumerated.item[0]; + cpu_to_le32(ucontrol->value.enumerated.item[0]); if (data->vcount == 2) gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); break; default: dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", @@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol, info = (struct gb_audio_ctl_elem_info *)data->info; /* update uinfo */ - platform_max = info->value.integer.max; - platform_min = info->value.integer.min; + platform_max = le32_to_cpu(info->value.integer.max); + platform_min = le32_to_cpu(info->value.integer.min); if (platform_max == 1 && !strnstr(kcontrol->id.name, " Volume", NAME_SIZE)) @@ -371,12 +372,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = data->vcount; - uinfo->value.integer.min = 0; - if (info->value.integer.min < 0 && - (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER)) - uinfo->value.integer.max = platform_max - platform_min; - else - uinfo->value.integer.max = platform_max; + uinfo->value.integer.min = platform_min; + uinfo->value.integer.max = platform_max; return 0; } @@ -424,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, return ret; } /* update ucontrol */ - ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0]; + ucontrol->value.integer.value[0] = + le32_to_cpu(gbvalue.value.integer_value[0]); return ret; } @@ -458,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, "GB: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); - max = info->value.integer.max; + max = le32_to_cpu(info->value.integer.max); mask = (1 << fls(max)) - 1; val = ucontrol->value.integer.value[0] & mask; connect = !!val; @@ -474,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, connect); } gbvalue.value.integer_value[0] = - ucontrol->value.integer.value[0]; + cpu_to_le32(ucontrol->value.integer.value[0]); ret = gb_pm_runtime_get_sync(bundle); if (ret) @@ -588,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol, return ret; } - ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; + ucontrol->value.enumerated.item[0] = + le32_to_cpu(gbvalue.value.enumerated_item[0]); if (e->shift_l != e->shift_r) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); return 0; } @@ -617,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; - gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0]; + gbvalue.value.enumerated_item[0] = + cpu_to_le32(ucontrol->value.enumerated.item[0]); if (e->shift_l != e->shift_r) { if (ucontrol->value.enumerated.item[1] > e->max - 1) return -EINVAL; gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); } bundle = to_gb_bundle(module->dev); @@ -660,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated; /* since count=1, and reg is dummy */ - gbe->max = gb_enum->items; + gbe->max = le32_to_cpu(gb_enum->items); gbe->texts = gb_generate_enum_strings(gb, gb_enum); /* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); *kctl = (struct snd_kcontrol_new) @@ -695,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; ctldata->ctl_id = ctl->id; - ctldata->data_cport = ctl->data_cport; + ctldata->data_cport = le16_to_cpu(ctl->data_cport); ctldata->access = ctl->access; ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -869,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated; /* since count=1, and reg is dummy */ - gbe->max = gb_enum->items; + gbe->max = le32_to_cpu(gb_enum->items); gbe->texts = gb_generate_enum_strings(gb, gb_enum); /* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); *kctl = (struct snd_kcontrol_new) @@ -895,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; ctldata->ctl_id = ctl->id; - ctldata->data_cport = ctl->data_cport; + ctldata->data_cport = le16_to_cpu(ctl->data_cport); ctldata->access = ctl->access; ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -1041,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module, csize = offsetof(struct gb_audio_control, info); csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -1189,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module, csize = offsetof(struct gb_audio_control, info); csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -1312,7 +1312,7 @@ static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module, goto error; } dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink, - (dapm_routes->control) ? dapm_routes->control:"NULL", + (dapm_routes->control) ? dapm_routes->control : "NULL", dapm_routes->source); dapm_routes++; curr++; @@ -1335,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module, /* update block offset */ module->dai_offset = (unsigned long)&tplg_data->data; - module->control_offset = module->dai_offset + tplg_data->size_dais; + module->control_offset = module->dai_offset + + le32_to_cpu(tplg_data->size_dais); module->widget_offset = module->control_offset + - tplg_data->size_controls; + le32_to_cpu(tplg_data->size_controls); module->route_offset = module->widget_offset + - tplg_data->size_widgets; + le32_to_cpu(tplg_data->size_widgets); dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset); dev_dbg(module->dev, "control offset is %lx\n", @@ -1357,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, struct gb_audio_control *controls; struct gb_audio_widget *widgets; struct gb_audio_route *routes; + unsigned int jack_type; if (!tplg_data) return -EINVAL; @@ -1399,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, dev_dbg(module->dev, "Route parsing finished\n"); /* parse jack capabilities */ - if (tplg_data->jack_type) { - module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK; - module->button_mask = tplg_data->jack_type & - GBCODEC_JACK_BUTTON_MASK; + jack_type = le32_to_cpu(tplg_data->jack_type); + if (jack_type) { + module->jack_mask = jack_type & GBCODEC_JACK_MASK; + module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK; } return ret; diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index 168626ba0c03..6c5dcb1c226b 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -16,7 +16,6 @@ #include "greybus_authentication.h" #include "firmware.h" -#include "greybus.h" #define CAP_TIMEOUT_MS 1000 diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index 5f90721bcc51..06df0ce03150 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -53,7 +53,8 @@ static void free_firmware(struct gb_bootrom *bootrom) static void gb_bootrom_timedout(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork); + struct gb_bootrom *bootrom = container_of(dwork, + struct gb_bootrom, dwork); struct device *dev = &bootrom->connection->bundle->dev; const char *reason; @@ -187,7 +188,8 @@ static int find_firmware(struct gb_bootrom *bootrom, u8 stage) static int gb_bootrom_firmware_size_request(struct gb_operation *op) { struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); - struct gb_bootrom_firmware_size_request *size_request = op->request->payload; + struct gb_bootrom_firmware_size_request *size_request = + op->request->payload; struct gb_bootrom_firmware_size_response *size_response; struct device *dev = &op->connection->bundle->dev; int ret; @@ -220,7 +222,8 @@ static int gb_bootrom_firmware_size_request(struct gb_operation *op) size_response = op->response->payload; size_response->size = cpu_to_le32(bootrom->fw->size); - dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size); + dev_dbg(dev, "%s: firmware size %d bytes\n", + __func__, size_response->size); unlock: mutex_unlock(&bootrom->mutex); @@ -287,8 +290,8 @@ static int gb_bootrom_get_firmware(struct gb_operation *op) firmware_response = op->response->payload; memcpy(firmware_response->data, fw->data + offset, size); - dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset, - size); + dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", + offset, size); unlock: mutex_unlock(&bootrom->mutex); diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 0ee291ca2c72..a64517eabff4 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -1067,22 +1067,22 @@ struct gb_camera_debugfs_entry { static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = { { .name = "capabilities", - .mask = S_IFREG | S_IRUGO, + .mask = S_IFREG | 0444, .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES, .execute = gb_camera_debugfs_capabilities, }, { .name = "configure_streams", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS, .execute = gb_camera_debugfs_configure_streams, }, { .name = "capture", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE, .execute = gb_camera_debugfs_capture, }, { .name = "flush", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH, .execute = gb_camera_debugfs_flush, }, @@ -1097,7 +1097,7 @@ static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf, ssize_t ret; /* For read-only entries the operation is triggered by a read. */ - if (!(op->mask & S_IWUGO)) { + if (!(op->mask & 0222)) { ret = op->execute(gcam, NULL, 0); if (ret < 0) return ret; diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 557075147f2d..1bf0ee403106 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -357,6 +357,9 @@ static int gb_connection_hd_cport_quiesce(struct gb_connection *connection) size_t peer_space; int ret; + if (!hd->driver->cport_quiesce) + return 0; + peer_space = sizeof(struct gb_operation_msg_hdr) + sizeof(struct gb_cport_shutdown_request); @@ -380,6 +383,9 @@ static int gb_connection_hd_cport_clear(struct gb_connection *connection) struct gb_host_device *hd = connection->hd; int ret; + if (!hd->driver->cport_clear) + return 0; + ret = hd->driver->cport_clear(hd, connection->hd_cport_id); if (ret) { dev_err(&hd->dev, "%s: failed to clear host cport: %d\n", 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..f7b24e0eaa6f 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 */ @@ -1217,7 +1085,8 @@ static void apb_log_get(struct es2_ap_dev *es2, char *buf) retval = usb_control_msg(es2->usb_dev, usb_rcvctrlpipe(es2->usb_dev, 0), GB_APB_REQUEST_LOG, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_INTERFACE, 0x00, 0x00, buf, APB1_LOG_MSG_SIZE, @@ -1283,7 +1152,7 @@ static void usb_log_enable(struct es2_ap_dev *es2) if (IS_ERR(es2->apb_log_task)) return; /* XXX We will need to rename this per APB */ - es2->apb_log_dentry = debugfs_create_file("apb_log", S_IRUGO, + es2->apb_log_dentry = debugfs_create_file("apb_log", 0444, gb_debugfs_get(), es2, &apb_log_fops); } @@ -1540,7 +1409,7 @@ static int ap_probe(struct usb_interface *interface, /* XXX We will need to rename this per APB */ es2->apb_log_enable_dentry = debugfs_create_file("apb_log_enable", - (S_IWUSR | S_IRUGO), + 0644, gb_debugfs_get(), es2, &apb_log_enable_fops); diff --git a/drivers/staging/greybus/fw-download.c b/drivers/staging/greybus/fw-download.c index 2d7246887547..8a1a413c6cb3 100644 --- a/drivers/staging/greybus/fw-download.c +++ b/drivers/staging/greybus/fw-download.c @@ -130,7 +130,8 @@ static void free_firmware(struct fw_download *fw_download, static void fw_request_timedout(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct fw_request *fw_req = container_of(dwork, struct fw_request, dwork); + struct fw_request *fw_req = container_of(dwork, + struct fw_request, dwork); struct fw_download *fw_download = fw_req->fw_download; dev_err(fw_download->parent, @@ -239,7 +240,8 @@ static int fw_download_find_firmware(struct gb_operation *op) tag = (const char *)request->firmware_tag; /* firmware_tag must be null-terminated */ - if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) == GB_FIRMWARE_TAG_MAX_SIZE) { + if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) == + GB_FIRMWARE_TAG_MAX_SIZE) { dev_err(fw_download->parent, "firmware-tag is not null-terminated\n"); return -EINVAL; diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index bcde7c9a0f17..64a1eb93ec96 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -104,7 +104,8 @@ static int gbphy_dev_uevent(struct device *dev, struct kobj_uevent_env *env) } static const struct gbphy_device_id * -gbphy_dev_match_id(struct gbphy_device *gbphy_dev, struct gbphy_driver *gbphy_drv) +gbphy_dev_match_id(struct gbphy_device *gbphy_dev, + struct gbphy_driver *gbphy_drv) { const struct gbphy_device_id *id = gbphy_drv->id_table; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index 250caa00de5e..ee5f998b174f 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -410,21 +410,21 @@ static int gb_gpio_request_handler(struct gb_operation *op) return 0; } -static int gb_gpio_request(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_activate_operation(ggc, (u8)offset); } -static void gb_gpio_free(struct gpio_chip *chip, unsigned offset) +static void gb_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_deactivate_operation(ggc, (u8)offset); } -static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; @@ -438,22 +438,22 @@ static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset) return ggc->lines[which].direction ? 1 : 0; } -static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_in_operation(ggc, (u8)offset); } -static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value); } -static int gb_gpio_get(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; @@ -467,24 +467,27 @@ static int gb_gpio_get(struct gpio_chip *chip, unsigned offset) return ggc->lines[which].value; } -static void gb_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_set_value_operation(ggc, (u8)offset, !!value); } -static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, - unsigned debounce) +static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset, + unsigned long config) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); - u16 usec; + u32 debounce; + if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; + + debounce = pinconf_to_config_argument(config); if (debounce > U16_MAX) return -EINVAL; - usec = (u16)debounce; - return gb_gpio_set_debounce_operation(ggc, (u8)offset, usec); + return gb_gpio_set_debounce_operation(ggc, (u8)offset, (u16)debounce); } static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc) @@ -557,7 +560,8 @@ static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc) /* Remove all IRQ mappings and delete the domain */ if (ggc->irqdomain) { for (offset = 0; offset < (ggc->line_max + 1); offset++) - irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, offset)); + irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, + offset)); irq_domain_remove(ggc->irqdomain); } @@ -593,7 +597,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip, { struct gb_gpio_controller *ggc; unsigned int offset; - unsigned irq_base; + unsigned int irq_base; if (!chip || !irqchip) return -EINVAL; @@ -625,7 +629,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip, return 0; } -static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); @@ -689,7 +693,7 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, gpio->direction_output = gb_gpio_direction_output; gpio->get = gb_gpio_get; gpio->set = gb_gpio_set; - gpio->set_debounce = gb_gpio_set_debounce; + gpio->set_config = gb_gpio_set_config; gpio->to_irq = gb_gpio_to_irq; gpio->base = -1; /* Allocate base dynamically */ gpio->ngpio = ggc->line_max + 1; 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/log.c b/drivers/staging/greybus/log.c index 1a18ab1ff8aa..5c5bedaf69a6 100644 --- a/drivers/staging/greybus/log.c +++ b/drivers/staging/greybus/log.c @@ -37,9 +37,9 @@ static int gb_log_request_handler(struct gb_operation *op) } receive = op->request->payload; len = le16_to_cpu(receive->len); - if (len != (int)(op->request->payload_size - sizeof(*receive))) { - dev_err(dev, "log request wrong size %d vs %d\n", len, - (int)(op->request->payload_size - sizeof(*receive))); + if (len != (op->request->payload_size - sizeof(*receive))) { + dev_err(dev, "log request wrong size %d vs %zu\n", len, + (op->request->payload_size - sizeof(*receive))); return -EINVAL; } if (len == 0) { diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 7882306adeca..aaf29a5fac83 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -124,7 +124,7 @@ static DEFINE_IDA(loopback_ida); #define GB_LOOPBACK_FIFO_DEFAULT 8192 -static unsigned kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT; +static unsigned int kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT; module_param(kfifo_depth, uint, 0444); /* Maximum size of any one send data buffer we support */ @@ -629,6 +629,7 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type, mutex_lock(&gb->mutex); ret = gb_operation_request_send(operation, gb_loopback_async_operation_callback, + 0, GFP_KERNEL); if (ret) goto error; @@ -1008,11 +1009,22 @@ static int gb_loopback_fn(void *data) /* Optionally terminate */ if (gb->send_count == gb->iteration_max) { + mutex_unlock(&gb->mutex); + + /* Wait for synchronous and asynchronus completion */ + gb_loopback_async_wait_all(gb); + + /* Mark complete unless user-space has poked us */ + mutex_lock(&gb->mutex); if (gb->iteration_count == gb->iteration_max) { gb->type = 0; gb->send_count = 0; sysfs_notify(&gb->dev->kobj, NULL, "iteration_count"); + dev_dbg(&bundle->dev, "load test complete\n"); + } else { + dev_dbg(&bundle->dev, + "continuing on with new test set\n"); } mutex_unlock(&gb->mutex); continue; @@ -1026,13 +1038,12 @@ static int gb_loopback_fn(void *data) /* Else operations to perform */ if (gb->async) { - if (type == GB_LOOPBACK_TYPE_PING) { + if (type == GB_LOOPBACK_TYPE_PING) error = gb_loopback_async_ping(gb); - } else if (type == GB_LOOPBACK_TYPE_TRANSFER) { + else if (type == GB_LOOPBACK_TYPE_TRANSFER) error = gb_loopback_async_transfer(gb, size); - } else if (type == GB_LOOPBACK_TYPE_SINK) { + else if (type == GB_LOOPBACK_TYPE_SINK) error = gb_loopback_async_sink(gb, size); - } if (error) gb->error++; @@ -1051,8 +1062,13 @@ static int gb_loopback_fn(void *data) gb_loopback_calculate_stats(gb, !!error); } gb->send_count++; - if (us_wait) - udelay(us_wait); + + if (us_wait) { + if (us_wait < 20000) + usleep_range(us_wait, us_wait + 100); + else + msleep(us_wait / 1000); + } } gb_pm_runtime_put_autosuspend(bundle); @@ -1199,7 +1215,7 @@ static int gb_loopback_probe(struct gb_bundle *bundle, /* Create per-connection sysfs and debugfs data-points */ snprintf(name, sizeof(name), "raw_latency_%s", dev_name(&connection->bundle->dev)); - gb->file = debugfs_create_file(name, S_IFREG | S_IRUGO, gb_dev.root, gb, + gb->file = debugfs_create_file(name, S_IFREG | 0444, gb_dev.root, gb, &gb_loopback_debugfs_latency_ops); gb->id = ida_simple_get(&loopback_ida, 0, 0, GFP_KERNEL); diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 0123109a1070..3023012808d9 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -273,18 +273,40 @@ static void gb_operation_request_handle(struct gb_operation *operation) static void gb_operation_work(struct work_struct *work) { struct gb_operation *operation; + int ret; operation = container_of(work, struct gb_operation, work); - if (gb_operation_is_incoming(operation)) + if (gb_operation_is_incoming(operation)) { gb_operation_request_handle(operation); - else + } else { + ret = del_timer_sync(&operation->timer); + if (!ret) { + /* Cancel request message if scheduled by timeout. */ + if (gb_operation_result(operation) == -ETIMEDOUT) + gb_message_cancel(operation->request); + } + operation->callback(operation); + } gb_operation_put_active(operation); gb_operation_put(operation); } +static void gb_operation_timeout(unsigned long arg) +{ + struct gb_operation *operation = (void *)arg; + + if (gb_operation_result_set(operation, -ETIMEDOUT)) { + /* + * A stuck request message will be cancelled from the + * workqueue. + */ + queue_work(gb_operation_completion_wq, &operation->work); + } +} + static void gb_operation_message_init(struct gb_host_device *hd, struct gb_message *message, u16 operation_id, size_t payload_size, u8 type) @@ -518,6 +540,9 @@ gb_operation_create_common(struct gb_connection *connection, u8 type, gfp_flags)) { goto err_request; } + + setup_timer(&operation->timer, gb_operation_timeout, + (unsigned long)operation); } operation->flags = op_flags; @@ -679,6 +704,7 @@ static void gb_operation_sync_callback(struct gb_operation *operation) * gb_operation_request_send() - send an operation request message * @operation: the operation to initiate * @callback: the operation completion callback + * @timeout: operation timeout in milliseconds, or zero for no timeout * @gfp: the memory flags to use for any allocations * * The caller has filled in any payload so the request message is ready to go. @@ -693,6 +719,7 @@ static void gb_operation_sync_callback(struct gb_operation *operation) */ int gb_operation_request_send(struct gb_operation *operation, gb_operation_callback callback, + unsigned int timeout, gfp_t gfp) { struct gb_connection *connection = operation->connection; @@ -742,6 +769,11 @@ int gb_operation_request_send(struct gb_operation *operation, if (ret) goto err_put_active; + if (timeout) { + operation->timer.expires = jiffies + msecs_to_jiffies(timeout); + add_timer(&operation->timer); + } + return 0; err_put_active: @@ -763,26 +795,16 @@ int gb_operation_request_send_sync_timeout(struct gb_operation *operation, unsigned int timeout) { int ret; - unsigned long timeout_jiffies; ret = gb_operation_request_send(operation, gb_operation_sync_callback, - GFP_KERNEL); + timeout, GFP_KERNEL); if (ret) return ret; - if (timeout) - timeout_jiffies = msecs_to_jiffies(timeout); - else - timeout_jiffies = MAX_SCHEDULE_TIMEOUT; - - ret = wait_for_completion_interruptible_timeout(&operation->completion, - timeout_jiffies); + ret = wait_for_completion_interruptible(&operation->completion); if (ret < 0) { /* Cancel the operation if interrupted */ gb_operation_cancel(operation, -ECANCELED); - } else if (ret == 0) { - /* Cancel the operation if op timed out */ - gb_operation_cancel(operation, -ETIMEDOUT); } return gb_operation_result(operation); diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index de09a2c7de54..7529f01b2529 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -98,6 +98,7 @@ struct gb_operation { struct work_struct work; gb_operation_callback callback; struct completion completion; + struct timer_list timer; struct kref kref; atomic_t waiters; @@ -164,6 +165,7 @@ bool gb_operation_response_alloc(struct gb_operation *operation, int gb_operation_request_send(struct gb_operation *operation, gb_operation_callback callback, + unsigned int timeout, gfp_t gfp); int gb_operation_request_send_sync_timeout(struct gb_operation *operation, unsigned int timeout); diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index 66b37ea29ef0..101ca5097fc9 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c @@ -52,7 +52,7 @@ struct gb_sdio_host { static inline bool single_op(struct mmc_command *cmd) { - uint32_t opcode = cmd->opcode; + u32 opcode = cmd->opcode; return opcode == MMC_WRITE_BLOCK || opcode == MMC_READ_SINGLE_BLOCK; diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index 8779270cadc1..516f827e5ed9 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) @@ -757,7 +678,8 @@ static int gb_svc_version_request(struct gb_operation *op) static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -780,7 +702,8 @@ static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf, static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -803,7 +726,8 @@ static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf, static ssize_t pwr_debugfs_power_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -879,11 +803,11 @@ static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc) rail->svc = svc; dir = debugfs_create_dir(fname, dent); - debugfs_create_file("voltage_now", S_IRUGO, dir, rail, + debugfs_create_file("voltage_now", 0444, dir, rail, &pwrmon_debugfs_voltage_fops); - debugfs_create_file("current_now", S_IRUGO, dir, rail, + debugfs_create_file("current_now", 0444, dir, rail, &pwrmon_debugfs_current_fops); - debugfs_create_file("power_now", S_IRUGO, dir, rail, + debugfs_create_file("power_now", 0444, dir, rail, &pwrmon_debugfs_power_fops); } @@ -945,13 +869,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: @@ -1010,14 +927,15 @@ static void gb_svc_process_hello_deferred(struct gb_operation *operation) * Power Mode Changes is resolved. */ ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - GB_SVC_SMALL_AMPLITUDE, GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - 0, 0, - NULL, NULL); + GB_SVC_UNIPRO_HS_SERIES_A, + GB_SVC_UNIPRO_SLOW_AUTO_MODE, + 2, 1, + GB_SVC_SMALL_AMPLITUDE, + GB_SVC_NO_DE_EMPHASIS, + GB_SVC_UNIPRO_SLOW_AUTO_MODE, + 2, 1, + 0, 0, + NULL, NULL); if (ret) dev_warn(&svc->dev, @@ -1467,7 +1385,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/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c index 3729460fb954..779fbea5d4ba 100644 --- a/drivers/staging/greybus/svc_watchdog.c +++ b/drivers/staging/greybus/svc_watchdog.c @@ -11,7 +11,7 @@ #include <linux/workqueue.h> #include "greybus.h" -#define SVC_WATCHDOG_PERIOD (2*HZ) +#define SVC_WATCHDOG_PERIOD (2 * HZ) struct gb_svc_watchdog { struct delayed_work work; @@ -44,19 +44,19 @@ static int svc_watchdog_pm_notifier(struct notifier_block *notifier, static void greybus_reset(struct work_struct *work) { - static char start_path[256] = "/system/bin/start"; + static char const start_path[] = "/system/bin/start"; static char *envp[] = { "HOME=/", "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin", NULL, }; static char *argv[] = { - start_path, + (char *)start_path, "unipro_reset", NULL, }; - printk(KERN_ERR "svc_watchdog: calling \"%s %s\" to reset greybus network!\n", + pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n", argv[0], argv[1]); call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC); } 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, - ×ync_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(×ync_svc->wait_queue); - break; - case GB_TIMESYNC_STATE_INACTIVE: - timesync_svc->state = state; - wake_up(×ync_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(×ync_svc->delayed_work); - queue_delayed_work(timesync_svc->work_queue, - ×ync_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(×ync_svc->delayed_work); - queue_delayed_work(timesync_svc->work_queue, - ×ync_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, - ×ync_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(×ync_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(×ync_svc->spinlock, flags); - gb_timesync_set_state(timesync_svc, state); - spin_unlock_irqrestore(×ync_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, - ×ync_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, ×ync_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, - ×ync_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(×ync_svc->mutex); - spin_lock_irqsave(×ync_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(×ync_svc->spinlock, flags); - mutex_unlock(×ync_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, - ×ync_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, - ×ync_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, ×ync_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, - ×ync_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, - ×ync_svc->interface_list, list) { - control = timesync_interface->interface->control; - timesync_interface->ping_frame_time = 0; - ping_frame_time = ×ync_interface->ping_frame_time; - ret = gb_control_timesync_get_last_event(control, - ping_frame_time); - if (ret) { - dev_err(×ync_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(×ync_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(×ync_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(×ync_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(×ync_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(×ync_svc->mutex); - if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) - gb_timesync_set_state_atomic(timesync_svc, state); - else - ret = -ENODEV; - - mutex_unlock(×ync_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(×ync_svc->mutex); - spin_lock_irqsave(×ync_svc->spinlock, flags); - - ret = __gb_timesync_get_status(timesync_svc); - - spin_unlock_irqrestore(×ync_svc->spinlock, flags); - mutex_unlock(×ync_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, ×ync_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(×ync_svc->mutex); - if (list_empty(×ync_svc->interface_list)) - ret = -ENODEV; - timesync_svc->print_ping = false; - mutex_unlock(×ync_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(×ync_svc->interface_list); - INIT_DELAYED_WORK(×ync_svc->delayed_work, gb_timesync_worker); - mutex_init(×ync_svc->mutex); - spin_lock_init(×ync_svc->spinlock); - init_waitqueue_head(×ync_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(×ync_svc->list, &gb_timesync_svc_list); - ret = gb_timesync_hd_add(timesync_svc, svc->hd); - if (ret) { - list_del(×ync_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(×ync_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(×ync_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(×ync_svc->delayed_work); - - mutex_lock(×ync_svc->mutex); - - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INVALID); - del_timer_sync(×ync_svc->ktime_timer); - gb_timesync_teardown(timesync_svc); - - gb_timesync_hd_remove(timesync_svc, svc->hd); - list_for_each_entry_safe(timesync_interface, next, - ×ync_svc->interface_list, list) { - list_del(×ync_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(×ync_svc->list); - - mutex_unlock(×ync_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(×ync_svc->mutex); - timesync_interface->interface = interface; - list_add(×ync_interface->list, ×ync_svc->interface_list); - timesync_svc->strobe_mask |= 1 << interface->interface_id; - mutex_unlock(×ync_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(×ync_svc->mutex); - timesync_svc->strobe_mask &= ~(1 << interface->interface_id); - list_del(×ync_interface->list); - kfree(timesync_interface); - mutex_unlock(×ync_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(×ync_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(×ync_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(×ync_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(×ync_svc->spinlock, flags); - mod_timer(×ync_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(×ync_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(×ync_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 27f75b17679b..000000000000 --- a/drivers/staging/greybus/timesync_platform.c +++ /dev/null @@ -1,88 +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) -{ - if (!arche_platform_change_state_cb) - return 0; - - return arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_TIME_SYNC, - pdata); -} - -void gb_timesync_platform_unlock_bus(void) -{ - if (!arche_platform_change_state_cb) - return; - - 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) {} diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index f7f4cd6fb55b..18d7a3d1f3c7 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -168,7 +168,7 @@ GET_AVG(latency_avg); GET_AVG(apbridge_unipro_latency_avg); GET_AVG(gbphy_firmware_latency_avg); -void abort() +void abort(void) { _exit(1); } @@ -521,7 +521,6 @@ static int log_results(struct loopback_test *t) int fd, i, len, ret; struct tm tm; time_t local_time; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; char file_name[MAX_SYSFS_PATH]; char data[CSV_MAX_LINE]; @@ -538,7 +537,7 @@ static int log_results(struct loopback_test *t) snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv", t->test_name, t->size, t->iteration_max); - fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode); + fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd < 0) { fprintf(stderr, "unable to open %s for appendation\n", file_name); abort(); diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 6d39f4a04754..ab0dbf5cab5a 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -624,14 +624,14 @@ static int get_serial_info(struct gb_tty *gb_tty, struct serial_struct tmp; memset(&tmp, 0, sizeof(tmp)); - tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST; tmp.type = PORT_16550A; tmp.line = gb_tty->minor; tmp.xmit_fifo_size = 16; tmp.baud_base = 9600; tmp.close_delay = gb_tty->port.close_delay / 10; - tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; + tmp.closing_wait = + gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; if (copy_to_user(info, &tmp, sizeof(tmp))) return -EFAULT; @@ -1000,7 +1000,8 @@ static int gb_tty_init(void) gb_tty_driver->subtype = SERIAL_TYPE_NORMAL; gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; gb_tty_driver->init_termios = tty_std_termios; - gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | + CREAD | HUPCL | CLOCAL; tty_set_operations(gb_tty_driver, &gb_ops); retval = tty_register_driver(gb_tty_driver); diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index 4ba0e168930f..77a2365a55e6 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -70,7 +70,9 @@ static void gb_vibrator_worker(struct work_struct *work) { struct delayed_work *delayed_work = to_delayed_work(work); struct gb_vibrator_device *vib = - container_of(delayed_work, struct gb_vibrator_device, delayed_work); + container_of(delayed_work, + struct gb_vibrator_device, + delayed_work); turn_off(vib); } |