cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

light.c (33667B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Greybus Lights protocol driver.
      4 *
      5 * Copyright 2015 Google Inc.
      6 * Copyright 2015 Linaro Ltd.
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/leds.h>
     11#include <linux/led-class-flash.h>
     12#include <linux/module.h>
     13#include <linux/slab.h>
     14#include <linux/greybus.h>
     15#include <media/v4l2-flash-led-class.h>
     16
     17#define NAMES_MAX	32
     18
     19struct gb_channel {
     20	u8				id;
     21	u32				flags;
     22	u32				color;
     23	char				*color_name;
     24	u8				fade_in;
     25	u8				fade_out;
     26	u32				mode;
     27	char				*mode_name;
     28	struct attribute		**attrs;
     29	struct attribute_group		*attr_group;
     30	const struct attribute_group	**attr_groups;
     31	struct led_classdev		*led;
     32#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
     33	struct led_classdev_flash	fled;
     34	struct led_flash_setting	intensity_uA;
     35	struct led_flash_setting	timeout_us;
     36#else
     37	struct led_classdev		cled;
     38#endif
     39	struct gb_light			*light;
     40	bool				is_registered;
     41	bool				releasing;
     42	bool				strobe_state;
     43	bool				active;
     44	struct mutex			lock;
     45};
     46
     47struct gb_light {
     48	u8			id;
     49	char			*name;
     50	struct gb_lights	*glights;
     51	u32			flags;
     52	u8			channels_count;
     53	struct gb_channel	*channels;
     54	bool			has_flash;
     55	bool			ready;
     56#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
     57	struct v4l2_flash	*v4l2_flash;
     58	struct v4l2_flash	*v4l2_flash_ind;
     59#endif
     60};
     61
     62struct gb_lights {
     63	struct gb_connection	*connection;
     64	u8			lights_count;
     65	struct gb_light		*lights;
     66	struct mutex		lights_lock;
     67};
     68
     69static void gb_lights_channel_free(struct gb_channel *channel);
     70
     71static struct gb_connection *get_conn_from_channel(struct gb_channel *channel)
     72{
     73	return channel->light->glights->connection;
     74}
     75
     76static struct gb_connection *get_conn_from_light(struct gb_light *light)
     77{
     78	return light->glights->connection;
     79}
     80
     81static bool is_channel_flash(struct gb_channel *channel)
     82{
     83	return !!(channel->mode & (GB_CHANNEL_MODE_FLASH | GB_CHANNEL_MODE_TORCH
     84				   | GB_CHANNEL_MODE_INDICATOR));
     85}
     86
     87#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
     88static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
     89{
     90	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
     91
     92	return container_of(fled_cdev, struct gb_channel, fled);
     93}
     94
     95static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
     96{
     97	return &channel->fled.led_cdev;
     98}
     99
    100static struct gb_channel *get_channel_from_mode(struct gb_light *light,
    101						u32 mode)
    102{
    103	struct gb_channel *channel = NULL;
    104	int i;
    105
    106	for (i = 0; i < light->channels_count; i++) {
    107		channel = &light->channels[i];
    108		if (channel && channel->mode == mode)
    109			break;
    110	}
    111	return channel;
    112}
    113
    114static int __gb_lights_flash_intensity_set(struct gb_channel *channel,
    115					   u32 intensity)
    116{
    117	struct gb_connection *connection = get_conn_from_channel(channel);
    118	struct gb_bundle *bundle = connection->bundle;
    119	struct gb_lights_set_flash_intensity_request req;
    120	int ret;
    121
    122	if (channel->releasing)
    123		return -ESHUTDOWN;
    124
    125	ret = gb_pm_runtime_get_sync(bundle);
    126	if (ret < 0)
    127		return ret;
    128
    129	req.light_id = channel->light->id;
    130	req.channel_id = channel->id;
    131	req.intensity_uA = cpu_to_le32(intensity);
    132
    133	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_INTENSITY,
    134				&req, sizeof(req), NULL, 0);
    135
    136	gb_pm_runtime_put_autosuspend(bundle);
    137
    138	return ret;
    139}
    140
    141static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
    142{
    143	u32 intensity;
    144
    145	/* If the channel is flash we need to get the attached torch channel */
    146	if (channel->mode & GB_CHANNEL_MODE_FLASH)
    147		channel = get_channel_from_mode(channel->light,
    148						GB_CHANNEL_MODE_TORCH);
    149
    150	/* For not flash we need to convert brightness to intensity */
    151	intensity = channel->intensity_uA.min +
    152			(channel->intensity_uA.step * channel->led->brightness);
    153
    154	return __gb_lights_flash_intensity_set(channel, intensity);
    155}
    156#else
    157static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
    158{
    159	return container_of(cdev, struct gb_channel, cled);
    160}
    161
    162static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
    163{
    164	return &channel->cled;
    165}
    166
    167static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
    168{
    169	return 0;
    170}
    171#endif
    172
    173static int gb_lights_color_set(struct gb_channel *channel, u32 color);
    174static int gb_lights_fade_set(struct gb_channel *channel);
    175
    176static void led_lock(struct led_classdev *cdev)
    177{
    178	mutex_lock(&cdev->led_access);
    179}
    180
    181static void led_unlock(struct led_classdev *cdev)
    182{
    183	mutex_unlock(&cdev->led_access);
    184}
    185
    186#define gb_lights_fade_attr(__dir)					\
    187static ssize_t fade_##__dir##_show(struct device *dev,			\
    188				   struct device_attribute *attr,	\
    189				   char *buf)				\
    190{									\
    191	struct led_classdev *cdev = dev_get_drvdata(dev);		\
    192	struct gb_channel *channel = get_channel_from_cdev(cdev);	\
    193									\
    194	return sprintf(buf, "%u\n", channel->fade_##__dir);		\
    195}									\
    196									\
    197static ssize_t fade_##__dir##_store(struct device *dev,			\
    198				    struct device_attribute *attr,	\
    199				    const char *buf, size_t size)	\
    200{									\
    201	struct led_classdev *cdev = dev_get_drvdata(dev);		\
    202	struct gb_channel *channel = get_channel_from_cdev(cdev);	\
    203	u8 fade;							\
    204	int ret;							\
    205									\
    206	led_lock(cdev);							\
    207	if (led_sysfs_is_disabled(cdev)) {				\
    208		ret = -EBUSY;						\
    209		goto unlock;						\
    210	}								\
    211									\
    212	ret = kstrtou8(buf, 0, &fade);					\
    213	if (ret < 0) {							\
    214		dev_err(dev, "could not parse fade value %d\n", ret);	\
    215		goto unlock;						\
    216	}								\
    217	if (channel->fade_##__dir == fade)				\
    218		goto unlock;						\
    219	channel->fade_##__dir = fade;					\
    220									\
    221	ret = gb_lights_fade_set(channel);				\
    222	if (ret < 0)							\
    223		goto unlock;						\
    224									\
    225	ret = size;							\
    226unlock:									\
    227	led_unlock(cdev);						\
    228	return ret;							\
    229}									\
    230static DEVICE_ATTR_RW(fade_##__dir)
    231
    232gb_lights_fade_attr(in);
    233gb_lights_fade_attr(out);
    234
    235static ssize_t color_show(struct device *dev, struct device_attribute *attr,
    236			  char *buf)
    237{
    238	struct led_classdev *cdev = dev_get_drvdata(dev);
    239	struct gb_channel *channel = get_channel_from_cdev(cdev);
    240
    241	return sprintf(buf, "0x%08x\n", channel->color);
    242}
    243
    244static ssize_t color_store(struct device *dev, struct device_attribute *attr,
    245			   const char *buf, size_t size)
    246{
    247	struct led_classdev *cdev = dev_get_drvdata(dev);
    248	struct gb_channel *channel = get_channel_from_cdev(cdev);
    249	u32 color;
    250	int ret;
    251
    252	led_lock(cdev);
    253	if (led_sysfs_is_disabled(cdev)) {
    254		ret = -EBUSY;
    255		goto unlock;
    256	}
    257	ret = kstrtou32(buf, 0, &color);
    258	if (ret < 0) {
    259		dev_err(dev, "could not parse color value %d\n", ret);
    260		goto unlock;
    261	}
    262
    263	ret = gb_lights_color_set(channel, color);
    264	if (ret < 0)
    265		goto unlock;
    266
    267	channel->color = color;
    268	ret = size;
    269unlock:
    270	led_unlock(cdev);
    271	return ret;
    272}
    273static DEVICE_ATTR_RW(color);
    274
    275static int channel_attr_groups_set(struct gb_channel *channel,
    276				   struct led_classdev *cdev)
    277{
    278	int attr = 0;
    279	int size = 0;
    280
    281	if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
    282		size++;
    283	if (channel->flags & GB_LIGHT_CHANNEL_FADER)
    284		size += 2;
    285
    286	if (!size)
    287		return 0;
    288
    289	/* Set attributes based in the channel flags */
    290	channel->attrs = kcalloc(size + 1, sizeof(*channel->attrs), GFP_KERNEL);
    291	if (!channel->attrs)
    292		return -ENOMEM;
    293	channel->attr_group = kzalloc(sizeof(*channel->attr_group), GFP_KERNEL);
    294	if (!channel->attr_group)
    295		return -ENOMEM;
    296	channel->attr_groups = kcalloc(2, sizeof(*channel->attr_groups),
    297				       GFP_KERNEL);
    298	if (!channel->attr_groups)
    299		return -ENOMEM;
    300
    301	if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
    302		channel->attrs[attr++] = &dev_attr_color.attr;
    303	if (channel->flags & GB_LIGHT_CHANNEL_FADER) {
    304		channel->attrs[attr++] = &dev_attr_fade_in.attr;
    305		channel->attrs[attr++] = &dev_attr_fade_out.attr;
    306	}
    307
    308	channel->attr_group->attrs = channel->attrs;
    309
    310	channel->attr_groups[0] = channel->attr_group;
    311
    312	cdev->groups = channel->attr_groups;
    313
    314	return 0;
    315}
    316
    317static int gb_lights_fade_set(struct gb_channel *channel)
    318{
    319	struct gb_connection *connection = get_conn_from_channel(channel);
    320	struct gb_bundle *bundle = connection->bundle;
    321	struct gb_lights_set_fade_request req;
    322	int ret;
    323
    324	if (channel->releasing)
    325		return -ESHUTDOWN;
    326
    327	ret = gb_pm_runtime_get_sync(bundle);
    328	if (ret < 0)
    329		return ret;
    330
    331	req.light_id = channel->light->id;
    332	req.channel_id = channel->id;
    333	req.fade_in = channel->fade_in;
    334	req.fade_out = channel->fade_out;
    335	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FADE,
    336				&req, sizeof(req), NULL, 0);
    337
    338	gb_pm_runtime_put_autosuspend(bundle);
    339
    340	return ret;
    341}
    342
    343static int gb_lights_color_set(struct gb_channel *channel, u32 color)
    344{
    345	struct gb_connection *connection = get_conn_from_channel(channel);
    346	struct gb_bundle *bundle = connection->bundle;
    347	struct gb_lights_set_color_request req;
    348	int ret;
    349
    350	if (channel->releasing)
    351		return -ESHUTDOWN;
    352
    353	ret = gb_pm_runtime_get_sync(bundle);
    354	if (ret < 0)
    355		return ret;
    356
    357	req.light_id = channel->light->id;
    358	req.channel_id = channel->id;
    359	req.color = cpu_to_le32(color);
    360	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_COLOR,
    361				&req, sizeof(req), NULL, 0);
    362
    363	gb_pm_runtime_put_autosuspend(bundle);
    364
    365	return ret;
    366}
    367
    368static int __gb_lights_led_brightness_set(struct gb_channel *channel)
    369{
    370	struct gb_lights_set_brightness_request req;
    371	struct gb_connection *connection = get_conn_from_channel(channel);
    372	struct gb_bundle *bundle = connection->bundle;
    373	bool old_active;
    374	int ret;
    375
    376	mutex_lock(&channel->lock);
    377	ret = gb_pm_runtime_get_sync(bundle);
    378	if (ret < 0)
    379		goto out_unlock;
    380
    381	old_active = channel->active;
    382
    383	req.light_id = channel->light->id;
    384	req.channel_id = channel->id;
    385	req.brightness = (u8)channel->led->brightness;
    386
    387	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BRIGHTNESS,
    388				&req, sizeof(req), NULL, 0);
    389	if (ret < 0)
    390		goto out_pm_put;
    391
    392	if (channel->led->brightness)
    393		channel->active = true;
    394	else
    395		channel->active = false;
    396
    397	/* we need to keep module alive when turning to active state */
    398	if (!old_active && channel->active)
    399		goto out_unlock;
    400
    401	/*
    402	 * on the other hand if going to inactive we still hold a reference and
    403	 * need to put it, so we could go to suspend.
    404	 */
    405	if (old_active && !channel->active)
    406		gb_pm_runtime_put_autosuspend(bundle);
    407
    408out_pm_put:
    409	gb_pm_runtime_put_autosuspend(bundle);
    410out_unlock:
    411	mutex_unlock(&channel->lock);
    412
    413	return ret;
    414}
    415
    416static int __gb_lights_brightness_set(struct gb_channel *channel)
    417{
    418	int ret;
    419
    420	if (channel->releasing)
    421		return 0;
    422
    423	if (is_channel_flash(channel))
    424		ret = __gb_lights_flash_brightness_set(channel);
    425	else
    426		ret = __gb_lights_led_brightness_set(channel);
    427
    428	return ret;
    429}
    430
    431static int gb_brightness_set(struct led_classdev *cdev,
    432			     enum led_brightness value)
    433{
    434	struct gb_channel *channel = get_channel_from_cdev(cdev);
    435
    436	channel->led->brightness = value;
    437
    438	return __gb_lights_brightness_set(channel);
    439}
    440
    441static enum led_brightness gb_brightness_get(struct led_classdev *cdev)
    442
    443{
    444	struct gb_channel *channel = get_channel_from_cdev(cdev);
    445
    446	return channel->led->brightness;
    447}
    448
    449static int gb_blink_set(struct led_classdev *cdev, unsigned long *delay_on,
    450			unsigned long *delay_off)
    451{
    452	struct gb_channel *channel = get_channel_from_cdev(cdev);
    453	struct gb_connection *connection = get_conn_from_channel(channel);
    454	struct gb_bundle *bundle = connection->bundle;
    455	struct gb_lights_blink_request req;
    456	bool old_active;
    457	int ret;
    458
    459	if (channel->releasing)
    460		return -ESHUTDOWN;
    461
    462	if (!delay_on || !delay_off)
    463		return -EINVAL;
    464
    465	mutex_lock(&channel->lock);
    466	ret = gb_pm_runtime_get_sync(bundle);
    467	if (ret < 0)
    468		goto out_unlock;
    469
    470	old_active = channel->active;
    471
    472	req.light_id = channel->light->id;
    473	req.channel_id = channel->id;
    474	req.time_on_ms = cpu_to_le16(*delay_on);
    475	req.time_off_ms = cpu_to_le16(*delay_off);
    476
    477	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BLINK, &req,
    478				sizeof(req), NULL, 0);
    479	if (ret < 0)
    480		goto out_pm_put;
    481
    482	if (*delay_on)
    483		channel->active = true;
    484	else
    485		channel->active = false;
    486
    487	/* we need to keep module alive when turning to active state */
    488	if (!old_active && channel->active)
    489		goto out_unlock;
    490
    491	/*
    492	 * on the other hand if going to inactive we still hold a reference and
    493	 * need to put it, so we could go to suspend.
    494	 */
    495	if (old_active && !channel->active)
    496		gb_pm_runtime_put_autosuspend(bundle);
    497
    498out_pm_put:
    499	gb_pm_runtime_put_autosuspend(bundle);
    500out_unlock:
    501	mutex_unlock(&channel->lock);
    502
    503	return ret;
    504}
    505
    506static void gb_lights_led_operations_set(struct gb_channel *channel,
    507					 struct led_classdev *cdev)
    508{
    509	cdev->brightness_get = gb_brightness_get;
    510	cdev->brightness_set_blocking = gb_brightness_set;
    511
    512	if (channel->flags & GB_LIGHT_CHANNEL_BLINK)
    513		cdev->blink_set = gb_blink_set;
    514}
    515
    516#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
    517/* V4L2 specific helpers */
    518static const struct v4l2_flash_ops v4l2_flash_ops;
    519
    520static void __gb_lights_channel_v4l2_config(struct led_flash_setting *channel_s,
    521					    struct led_flash_setting *v4l2_s)
    522{
    523	v4l2_s->min = channel_s->min;
    524	v4l2_s->max = channel_s->max;
    525	v4l2_s->step = channel_s->step;
    526	/* For v4l2 val is the default value */
    527	v4l2_s->val = channel_s->max;
    528}
    529
    530static int gb_lights_light_v4l2_register(struct gb_light *light)
    531{
    532	struct gb_connection *connection = get_conn_from_light(light);
    533	struct device *dev = &connection->bundle->dev;
    534	struct v4l2_flash_config sd_cfg = { {0} }, sd_cfg_ind = { {0} };
    535	struct led_classdev_flash *fled;
    536	struct led_classdev *iled = NULL;
    537	struct gb_channel *channel_torch, *channel_ind, *channel_flash;
    538
    539	channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH);
    540	if (channel_torch)
    541		__gb_lights_channel_v4l2_config(&channel_torch->intensity_uA,
    542						&sd_cfg.intensity);
    543
    544	channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR);
    545	if (channel_ind) {
    546		__gb_lights_channel_v4l2_config(&channel_ind->intensity_uA,
    547						&sd_cfg_ind.intensity);
    548		iled = &channel_ind->fled.led_cdev;
    549	}
    550
    551	channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH);
    552	WARN_ON(!channel_flash);
    553
    554	fled = &channel_flash->fled;
    555
    556	snprintf(sd_cfg.dev_name, sizeof(sd_cfg.dev_name), "%s", light->name);
    557	snprintf(sd_cfg_ind.dev_name, sizeof(sd_cfg_ind.dev_name),
    558		 "%s indicator", light->name);
    559
    560	/* Set the possible values to faults, in our case all faults */
    561	sd_cfg.flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT |
    562		LED_FAULT_OVER_TEMPERATURE | LED_FAULT_SHORT_CIRCUIT |
    563		LED_FAULT_OVER_CURRENT | LED_FAULT_INDICATOR |
    564		LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE |
    565		LED_FAULT_LED_OVER_TEMPERATURE;
    566
    567	light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, &v4l2_flash_ops,
    568					    &sd_cfg);
    569	if (IS_ERR(light->v4l2_flash))
    570		return PTR_ERR(light->v4l2_flash);
    571
    572	if (channel_ind) {
    573		light->v4l2_flash_ind =
    574			v4l2_flash_indicator_init(dev, NULL, iled, &sd_cfg_ind);
    575		if (IS_ERR(light->v4l2_flash_ind)) {
    576			v4l2_flash_release(light->v4l2_flash);
    577			return PTR_ERR(light->v4l2_flash_ind);
    578		}
    579	}
    580
    581	return 0;
    582}
    583
    584static void gb_lights_light_v4l2_unregister(struct gb_light *light)
    585{
    586	v4l2_flash_release(light->v4l2_flash_ind);
    587	v4l2_flash_release(light->v4l2_flash);
    588}
    589#else
    590static int gb_lights_light_v4l2_register(struct gb_light *light)
    591{
    592	struct gb_connection *connection = get_conn_from_light(light);
    593
    594	dev_err(&connection->bundle->dev, "no support for v4l2 subdevices\n");
    595	return 0;
    596}
    597
    598static void gb_lights_light_v4l2_unregister(struct gb_light *light)
    599{
    600}
    601#endif
    602
    603#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
    604/* Flash specific operations */
    605static int gb_lights_flash_intensity_set(struct led_classdev_flash *fcdev,
    606					 u32 brightness)
    607{
    608	struct gb_channel *channel = container_of(fcdev, struct gb_channel,
    609						  fled);
    610	int ret;
    611
    612	ret = __gb_lights_flash_intensity_set(channel, brightness);
    613	if (ret < 0)
    614		return ret;
    615
    616	fcdev->brightness.val = brightness;
    617
    618	return 0;
    619}
    620
    621static int gb_lights_flash_intensity_get(struct led_classdev_flash *fcdev,
    622					 u32 *brightness)
    623{
    624	*brightness = fcdev->brightness.val;
    625
    626	return 0;
    627}
    628
    629static int gb_lights_flash_strobe_set(struct led_classdev_flash *fcdev,
    630				      bool state)
    631{
    632	struct gb_channel *channel = container_of(fcdev, struct gb_channel,
    633						  fled);
    634	struct gb_connection *connection = get_conn_from_channel(channel);
    635	struct gb_bundle *bundle = connection->bundle;
    636	struct gb_lights_set_flash_strobe_request req;
    637	int ret;
    638
    639	if (channel->releasing)
    640		return -ESHUTDOWN;
    641
    642	ret = gb_pm_runtime_get_sync(bundle);
    643	if (ret < 0)
    644		return ret;
    645
    646	req.light_id = channel->light->id;
    647	req.channel_id = channel->id;
    648	req.state = state ? 1 : 0;
    649
    650	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_STROBE,
    651				&req, sizeof(req), NULL, 0);
    652	if (!ret)
    653		channel->strobe_state = state;
    654
    655	gb_pm_runtime_put_autosuspend(bundle);
    656
    657	return ret;
    658}
    659
    660static int gb_lights_flash_strobe_get(struct led_classdev_flash *fcdev,
    661				      bool *state)
    662{
    663	struct gb_channel *channel = container_of(fcdev, struct gb_channel,
    664						  fled);
    665
    666	*state = channel->strobe_state;
    667	return 0;
    668}
    669
    670static int gb_lights_flash_timeout_set(struct led_classdev_flash *fcdev,
    671				       u32 timeout)
    672{
    673	struct gb_channel *channel = container_of(fcdev, struct gb_channel,
    674						  fled);
    675	struct gb_connection *connection = get_conn_from_channel(channel);
    676	struct gb_bundle *bundle = connection->bundle;
    677	struct gb_lights_set_flash_timeout_request req;
    678	int ret;
    679
    680	if (channel->releasing)
    681		return -ESHUTDOWN;
    682
    683	ret = gb_pm_runtime_get_sync(bundle);
    684	if (ret < 0)
    685		return ret;
    686
    687	req.light_id = channel->light->id;
    688	req.channel_id = channel->id;
    689	req.timeout_us = cpu_to_le32(timeout);
    690
    691	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT,
    692				&req, sizeof(req), NULL, 0);
    693	if (!ret)
    694		fcdev->timeout.val = timeout;
    695
    696	gb_pm_runtime_put_autosuspend(bundle);
    697
    698	return ret;
    699}
    700
    701static int gb_lights_flash_fault_get(struct led_classdev_flash *fcdev,
    702				     u32 *fault)
    703{
    704	struct gb_channel *channel = container_of(fcdev, struct gb_channel,
    705						  fled);
    706	struct gb_connection *connection = get_conn_from_channel(channel);
    707	struct gb_bundle *bundle = connection->bundle;
    708	struct gb_lights_get_flash_fault_request req;
    709	struct gb_lights_get_flash_fault_response resp;
    710	int ret;
    711
    712	if (channel->releasing)
    713		return -ESHUTDOWN;
    714
    715	ret = gb_pm_runtime_get_sync(bundle);
    716	if (ret < 0)
    717		return ret;
    718
    719	req.light_id = channel->light->id;
    720	req.channel_id = channel->id;
    721
    722	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_FLASH_FAULT,
    723				&req, sizeof(req), &resp, sizeof(resp));
    724	if (!ret)
    725		*fault = le32_to_cpu(resp.fault);
    726
    727	gb_pm_runtime_put_autosuspend(bundle);
    728
    729	return ret;
    730}
    731
    732static const struct led_flash_ops gb_lights_flash_ops = {
    733	.flash_brightness_set	= gb_lights_flash_intensity_set,
    734	.flash_brightness_get	= gb_lights_flash_intensity_get,
    735	.strobe_set		= gb_lights_flash_strobe_set,
    736	.strobe_get		= gb_lights_flash_strobe_get,
    737	.timeout_set		= gb_lights_flash_timeout_set,
    738	.fault_get		= gb_lights_flash_fault_get,
    739};
    740
    741static int __gb_lights_channel_torch_attach(struct gb_channel *channel,
    742					    struct gb_channel *channel_torch)
    743{
    744	char *name;
    745
    746	/* we can only attach torch to a flash channel */
    747	if (!(channel->mode & GB_CHANNEL_MODE_FLASH))
    748		return 0;
    749
    750	/* Move torch brightness to the destination */
    751	channel->led->max_brightness = channel_torch->led->max_brightness;
    752
    753	/* append mode name to flash name */
    754	name = kasprintf(GFP_KERNEL, "%s_%s", channel->led->name,
    755			 channel_torch->mode_name);
    756	if (!name)
    757		return -ENOMEM;
    758	kfree(channel->led->name);
    759	channel->led->name = name;
    760
    761	channel_torch->led = channel->led;
    762
    763	return 0;
    764}
    765
    766static int __gb_lights_flash_led_register(struct gb_channel *channel)
    767{
    768	struct gb_connection *connection = get_conn_from_channel(channel);
    769	struct led_classdev_flash *fled = &channel->fled;
    770	struct led_flash_setting *fset;
    771	struct gb_channel *channel_torch;
    772	int ret;
    773
    774	fled->ops = &gb_lights_flash_ops;
    775
    776	fled->led_cdev.flags |= LED_DEV_CAP_FLASH;
    777
    778	fset = &fled->brightness;
    779	fset->min = channel->intensity_uA.min;
    780	fset->max = channel->intensity_uA.max;
    781	fset->step = channel->intensity_uA.step;
    782	fset->val = channel->intensity_uA.max;
    783
    784	/* Only the flash mode have the timeout constraints settings */
    785	if (channel->mode & GB_CHANNEL_MODE_FLASH) {
    786		fset = &fled->timeout;
    787		fset->min = channel->timeout_us.min;
    788		fset->max = channel->timeout_us.max;
    789		fset->step = channel->timeout_us.step;
    790		fset->val = channel->timeout_us.max;
    791	}
    792
    793	/*
    794	 * If light have torch mode channel, this channel will be the led
    795	 * classdev of the registered above flash classdev
    796	 */
    797	channel_torch = get_channel_from_mode(channel->light,
    798					      GB_CHANNEL_MODE_TORCH);
    799	if (channel_torch) {
    800		ret = __gb_lights_channel_torch_attach(channel, channel_torch);
    801		if (ret < 0)
    802			goto fail;
    803	}
    804
    805	ret = led_classdev_flash_register(&connection->bundle->dev, fled);
    806	if (ret < 0)
    807		goto fail;
    808
    809	channel->is_registered = true;
    810	return 0;
    811fail:
    812	channel->led = NULL;
    813	return ret;
    814}
    815
    816static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
    817{
    818	if (!channel->is_registered)
    819		return;
    820
    821	led_classdev_flash_unregister(&channel->fled);
    822}
    823
    824static int gb_lights_channel_flash_config(struct gb_channel *channel)
    825{
    826	struct gb_connection *connection = get_conn_from_channel(channel);
    827	struct gb_lights_get_channel_flash_config_request req;
    828	struct gb_lights_get_channel_flash_config_response conf;
    829	struct led_flash_setting *fset;
    830	int ret;
    831
    832	req.light_id = channel->light->id;
    833	req.channel_id = channel->id;
    834
    835	ret = gb_operation_sync(connection,
    836				GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG,
    837				&req, sizeof(req), &conf, sizeof(conf));
    838	if (ret < 0)
    839		return ret;
    840
    841	/*
    842	 * Intensity constraints for flash related modes: flash, torch,
    843	 * indicator.  They will be needed for v4l2 registration.
    844	 */
    845	fset = &channel->intensity_uA;
    846	fset->min = le32_to_cpu(conf.intensity_min_uA);
    847	fset->max = le32_to_cpu(conf.intensity_max_uA);
    848	fset->step = le32_to_cpu(conf.intensity_step_uA);
    849
    850	/*
    851	 * On flash type, max brightness is set as the number of intensity steps
    852	 * available.
    853	 */
    854	channel->led->max_brightness = (fset->max - fset->min) / fset->step;
    855
    856	/* Only the flash mode have the timeout constraints settings */
    857	if (channel->mode & GB_CHANNEL_MODE_FLASH) {
    858		fset = &channel->timeout_us;
    859		fset->min = le32_to_cpu(conf.timeout_min_us);
    860		fset->max = le32_to_cpu(conf.timeout_max_us);
    861		fset->step = le32_to_cpu(conf.timeout_step_us);
    862	}
    863
    864	return 0;
    865}
    866#else
    867static int gb_lights_channel_flash_config(struct gb_channel *channel)
    868{
    869	struct gb_connection *connection = get_conn_from_channel(channel);
    870
    871	dev_err(&connection->bundle->dev, "no support for flash devices\n");
    872	return 0;
    873}
    874
    875static int __gb_lights_flash_led_register(struct gb_channel *channel)
    876{
    877	return 0;
    878}
    879
    880static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
    881{
    882}
    883
    884#endif
    885
    886static int __gb_lights_led_register(struct gb_channel *channel)
    887{
    888	struct gb_connection *connection = get_conn_from_channel(channel);
    889	struct led_classdev *cdev = get_channel_cdev(channel);
    890	int ret;
    891
    892	ret = led_classdev_register(&connection->bundle->dev, cdev);
    893	if (ret < 0)
    894		channel->led = NULL;
    895	else
    896		channel->is_registered = true;
    897	return ret;
    898}
    899
    900static int gb_lights_channel_register(struct gb_channel *channel)
    901{
    902	/* Normal LED channel, just register in led classdev and we are done */
    903	if (!is_channel_flash(channel))
    904		return __gb_lights_led_register(channel);
    905
    906	/*
    907	 * Flash Type need more work, register flash classdev, indicator as
    908	 * flash classdev, torch will be led classdev of the flash classdev.
    909	 */
    910	if (!(channel->mode & GB_CHANNEL_MODE_TORCH))
    911		return __gb_lights_flash_led_register(channel);
    912
    913	return 0;
    914}
    915
    916static void __gb_lights_led_unregister(struct gb_channel *channel)
    917{
    918	struct led_classdev *cdev = get_channel_cdev(channel);
    919
    920	if (!channel->is_registered)
    921		return;
    922
    923	led_classdev_unregister(cdev);
    924	kfree(cdev->name);
    925	cdev->name = NULL;
    926	channel->led = NULL;
    927}
    928
    929static void gb_lights_channel_unregister(struct gb_channel *channel)
    930{
    931	/* The same as register, handle channels differently */
    932	if (!is_channel_flash(channel)) {
    933		__gb_lights_led_unregister(channel);
    934		return;
    935	}
    936
    937	if (channel->mode & GB_CHANNEL_MODE_TORCH)
    938		__gb_lights_led_unregister(channel);
    939	else
    940		__gb_lights_flash_led_unregister(channel);
    941}
    942
    943static int gb_lights_channel_config(struct gb_light *light,
    944				    struct gb_channel *channel)
    945{
    946	struct gb_lights_get_channel_config_response conf;
    947	struct gb_lights_get_channel_config_request req;
    948	struct gb_connection *connection = get_conn_from_light(light);
    949	struct led_classdev *cdev = get_channel_cdev(channel);
    950	char *name;
    951	int ret;
    952
    953	req.light_id = light->id;
    954	req.channel_id = channel->id;
    955
    956	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG,
    957				&req, sizeof(req), &conf, sizeof(conf));
    958	if (ret < 0)
    959		return ret;
    960
    961	channel->light = light;
    962	channel->mode = le32_to_cpu(conf.mode);
    963	channel->flags = le32_to_cpu(conf.flags);
    964	channel->color = le32_to_cpu(conf.color);
    965	channel->color_name = kstrndup(conf.color_name, NAMES_MAX, GFP_KERNEL);
    966	if (!channel->color_name)
    967		return -ENOMEM;
    968	channel->mode_name = kstrndup(conf.mode_name, NAMES_MAX, GFP_KERNEL);
    969	if (!channel->mode_name)
    970		return -ENOMEM;
    971
    972	channel->led = cdev;
    973
    974	name = kasprintf(GFP_KERNEL, "%s:%s:%s", light->name,
    975			 channel->color_name, channel->mode_name);
    976	if (!name)
    977		return -ENOMEM;
    978
    979	cdev->name = name;
    980
    981	cdev->max_brightness = conf.max_brightness;
    982
    983	ret = channel_attr_groups_set(channel, cdev);
    984	if (ret < 0)
    985		return ret;
    986
    987	gb_lights_led_operations_set(channel, cdev);
    988
    989	/*
    990	 * If it is not a flash related channel (flash, torch or indicator) we
    991	 * are done here. If not, continue and fetch flash related
    992	 * configurations.
    993	 */
    994	if (!is_channel_flash(channel))
    995		return ret;
    996
    997	light->has_flash = true;
    998
    999	return gb_lights_channel_flash_config(channel);
   1000}
   1001
   1002static int gb_lights_light_config(struct gb_lights *glights, u8 id)
   1003{
   1004	struct gb_light *light = &glights->lights[id];
   1005	struct gb_lights_get_light_config_request req;
   1006	struct gb_lights_get_light_config_response conf;
   1007	int ret;
   1008	int i;
   1009
   1010	light->glights = glights;
   1011	light->id = id;
   1012
   1013	req.id = id;
   1014
   1015	ret = gb_operation_sync(glights->connection,
   1016				GB_LIGHTS_TYPE_GET_LIGHT_CONFIG,
   1017				&req, sizeof(req), &conf, sizeof(conf));
   1018	if (ret < 0)
   1019		return ret;
   1020
   1021	if (!conf.channel_count)
   1022		return -EINVAL;
   1023	if (!strlen(conf.name))
   1024		return -EINVAL;
   1025
   1026	light->channels_count = conf.channel_count;
   1027	light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL);
   1028	if (!light->name)
   1029		return -ENOMEM;
   1030	light->channels = kcalloc(light->channels_count,
   1031				  sizeof(struct gb_channel), GFP_KERNEL);
   1032	if (!light->channels)
   1033		return -ENOMEM;
   1034
   1035	/* First we collect all the configurations for all channels */
   1036	for (i = 0; i < light->channels_count; i++) {
   1037		light->channels[i].id = i;
   1038		ret = gb_lights_channel_config(light, &light->channels[i]);
   1039		if (ret < 0)
   1040			return ret;
   1041	}
   1042
   1043	return 0;
   1044}
   1045
   1046static int gb_lights_light_register(struct gb_light *light)
   1047{
   1048	int ret;
   1049	int i;
   1050
   1051	/*
   1052	 * Then, if everything went ok in getting configurations, we register
   1053	 * the classdev, flash classdev and v4l2 subsystem, if a flash device is
   1054	 * found.
   1055	 */
   1056	for (i = 0; i < light->channels_count; i++) {
   1057		ret = gb_lights_channel_register(&light->channels[i]);
   1058		if (ret < 0)
   1059			return ret;
   1060
   1061		mutex_init(&light->channels[i].lock);
   1062	}
   1063
   1064	light->ready = true;
   1065
   1066	if (light->has_flash) {
   1067		ret = gb_lights_light_v4l2_register(light);
   1068		if (ret < 0) {
   1069			light->has_flash = false;
   1070			return ret;
   1071		}
   1072	}
   1073
   1074	return 0;
   1075}
   1076
   1077static void gb_lights_channel_free(struct gb_channel *channel)
   1078{
   1079	kfree(channel->attrs);
   1080	kfree(channel->attr_group);
   1081	kfree(channel->attr_groups);
   1082	kfree(channel->color_name);
   1083	kfree(channel->mode_name);
   1084	mutex_destroy(&channel->lock);
   1085}
   1086
   1087static void gb_lights_channel_release(struct gb_channel *channel)
   1088{
   1089	channel->releasing = true;
   1090
   1091	gb_lights_channel_unregister(channel);
   1092
   1093	gb_lights_channel_free(channel);
   1094}
   1095
   1096static void gb_lights_light_release(struct gb_light *light)
   1097{
   1098	int i;
   1099
   1100	light->ready = false;
   1101
   1102	if (light->has_flash)
   1103		gb_lights_light_v4l2_unregister(light);
   1104	light->has_flash = false;
   1105
   1106	for (i = 0; i < light->channels_count; i++)
   1107		gb_lights_channel_release(&light->channels[i]);
   1108	light->channels_count = 0;
   1109
   1110	kfree(light->channels);
   1111	light->channels = NULL;
   1112	kfree(light->name);
   1113	light->name = NULL;
   1114}
   1115
   1116static void gb_lights_release(struct gb_lights *glights)
   1117{
   1118	int i;
   1119
   1120	if (!glights)
   1121		return;
   1122
   1123	mutex_lock(&glights->lights_lock);
   1124	if (!glights->lights)
   1125		goto free_glights;
   1126
   1127	for (i = 0; i < glights->lights_count; i++)
   1128		gb_lights_light_release(&glights->lights[i]);
   1129
   1130	kfree(glights->lights);
   1131
   1132free_glights:
   1133	mutex_unlock(&glights->lights_lock);
   1134	mutex_destroy(&glights->lights_lock);
   1135	kfree(glights);
   1136}
   1137
   1138static int gb_lights_get_count(struct gb_lights *glights)
   1139{
   1140	struct gb_lights_get_lights_response resp;
   1141	int ret;
   1142
   1143	ret = gb_operation_sync(glights->connection, GB_LIGHTS_TYPE_GET_LIGHTS,
   1144				NULL, 0, &resp, sizeof(resp));
   1145	if (ret < 0)
   1146		return ret;
   1147
   1148	if (!resp.lights_count)
   1149		return -EINVAL;
   1150
   1151	glights->lights_count = resp.lights_count;
   1152
   1153	return 0;
   1154}
   1155
   1156static int gb_lights_create_all(struct gb_lights *glights)
   1157{
   1158	struct gb_connection *connection = glights->connection;
   1159	int ret;
   1160	int i;
   1161
   1162	mutex_lock(&glights->lights_lock);
   1163	ret = gb_lights_get_count(glights);
   1164	if (ret < 0)
   1165		goto out;
   1166
   1167	glights->lights = kcalloc(glights->lights_count,
   1168				  sizeof(struct gb_light), GFP_KERNEL);
   1169	if (!glights->lights) {
   1170		ret = -ENOMEM;
   1171		goto out;
   1172	}
   1173
   1174	for (i = 0; i < glights->lights_count; i++) {
   1175		ret = gb_lights_light_config(glights, i);
   1176		if (ret < 0) {
   1177			dev_err(&connection->bundle->dev,
   1178				"Fail to configure lights device\n");
   1179			goto out;
   1180		}
   1181	}
   1182
   1183out:
   1184	mutex_unlock(&glights->lights_lock);
   1185	return ret;
   1186}
   1187
   1188static int gb_lights_register_all(struct gb_lights *glights)
   1189{
   1190	struct gb_connection *connection = glights->connection;
   1191	int ret = 0;
   1192	int i;
   1193
   1194	mutex_lock(&glights->lights_lock);
   1195	for (i = 0; i < glights->lights_count; i++) {
   1196		ret = gb_lights_light_register(&glights->lights[i]);
   1197		if (ret < 0) {
   1198			dev_err(&connection->bundle->dev,
   1199				"Fail to enable lights device\n");
   1200			break;
   1201		}
   1202	}
   1203
   1204	mutex_unlock(&glights->lights_lock);
   1205	return ret;
   1206}
   1207
   1208static int gb_lights_request_handler(struct gb_operation *op)
   1209{
   1210	struct gb_connection *connection = op->connection;
   1211	struct device *dev = &connection->bundle->dev;
   1212	struct gb_lights *glights = gb_connection_get_data(connection);
   1213	struct gb_light *light;
   1214	struct gb_message *request;
   1215	struct gb_lights_event_request *payload;
   1216	int ret =  0;
   1217	u8 light_id;
   1218	u8 event;
   1219
   1220	if (op->type != GB_LIGHTS_TYPE_EVENT) {
   1221		dev_err(dev, "Unsupported unsolicited event: %u\n", op->type);
   1222		return -EINVAL;
   1223	}
   1224
   1225	request = op->request;
   1226
   1227	if (request->payload_size < sizeof(*payload)) {
   1228		dev_err(dev, "Wrong event size received (%zu < %zu)\n",
   1229			request->payload_size, sizeof(*payload));
   1230		return -EINVAL;
   1231	}
   1232
   1233	payload = request->payload;
   1234	light_id = payload->light_id;
   1235
   1236	if (light_id >= glights->lights_count ||
   1237	    !glights->lights[light_id].ready) {
   1238		dev_err(dev, "Event received for unconfigured light id: %d\n",
   1239			light_id);
   1240		return -EINVAL;
   1241	}
   1242
   1243	event = payload->event;
   1244
   1245	if (event & GB_LIGHTS_LIGHT_CONFIG) {
   1246		light = &glights->lights[light_id];
   1247
   1248		mutex_lock(&glights->lights_lock);
   1249		gb_lights_light_release(light);
   1250		ret = gb_lights_light_config(glights, light_id);
   1251		if (!ret)
   1252			ret = gb_lights_light_register(light);
   1253		if (ret < 0)
   1254			gb_lights_light_release(light);
   1255		mutex_unlock(&glights->lights_lock);
   1256	}
   1257
   1258	return ret;
   1259}
   1260
   1261static int gb_lights_probe(struct gb_bundle *bundle,
   1262			   const struct greybus_bundle_id *id)
   1263{
   1264	struct greybus_descriptor_cport *cport_desc;
   1265	struct gb_connection *connection;
   1266	struct gb_lights *glights;
   1267	int ret;
   1268
   1269	if (bundle->num_cports != 1)
   1270		return -ENODEV;
   1271
   1272	cport_desc = &bundle->cport_desc[0];
   1273	if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS)
   1274		return -ENODEV;
   1275
   1276	glights = kzalloc(sizeof(*glights), GFP_KERNEL);
   1277	if (!glights)
   1278		return -ENOMEM;
   1279
   1280	mutex_init(&glights->lights_lock);
   1281
   1282	connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
   1283					  gb_lights_request_handler);
   1284	if (IS_ERR(connection)) {
   1285		ret = PTR_ERR(connection);
   1286		goto out;
   1287	}
   1288
   1289	glights->connection = connection;
   1290	gb_connection_set_data(connection, glights);
   1291
   1292	greybus_set_drvdata(bundle, glights);
   1293
   1294	/* We aren't ready to receive an incoming request yet */
   1295	ret = gb_connection_enable_tx(connection);
   1296	if (ret)
   1297		goto error_connection_destroy;
   1298
   1299	/*
   1300	 * Setup all the lights devices over this connection, if anything goes
   1301	 * wrong tear down all lights
   1302	 */
   1303	ret = gb_lights_create_all(glights);
   1304	if (ret < 0)
   1305		goto error_connection_disable;
   1306
   1307	/* We are ready to receive an incoming request now, enable RX as well */
   1308	ret = gb_connection_enable(connection);
   1309	if (ret)
   1310		goto error_connection_disable;
   1311
   1312	/* Enable & register lights */
   1313	ret = gb_lights_register_all(glights);
   1314	if (ret < 0)
   1315		goto error_connection_disable;
   1316
   1317	gb_pm_runtime_put_autosuspend(bundle);
   1318
   1319	return 0;
   1320
   1321error_connection_disable:
   1322	gb_connection_disable(connection);
   1323error_connection_destroy:
   1324	gb_connection_destroy(connection);
   1325out:
   1326	gb_lights_release(glights);
   1327	return ret;
   1328}
   1329
   1330static void gb_lights_disconnect(struct gb_bundle *bundle)
   1331{
   1332	struct gb_lights *glights = greybus_get_drvdata(bundle);
   1333
   1334	if (gb_pm_runtime_get_sync(bundle))
   1335		gb_pm_runtime_get_noresume(bundle);
   1336
   1337	gb_connection_disable(glights->connection);
   1338	gb_connection_destroy(glights->connection);
   1339
   1340	gb_lights_release(glights);
   1341}
   1342
   1343static const struct greybus_bundle_id gb_lights_id_table[] = {
   1344	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) },
   1345	{ }
   1346};
   1347MODULE_DEVICE_TABLE(greybus, gb_lights_id_table);
   1348
   1349static struct greybus_driver gb_lights_driver = {
   1350	.name		= "lights",
   1351	.probe		= gb_lights_probe,
   1352	.disconnect	= gb_lights_disconnect,
   1353	.id_table	= gb_lights_id_table,
   1354};
   1355module_greybus_driver(gb_lights_driver);
   1356
   1357MODULE_LICENSE("GPL v2");