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

overlay-sysfs.c (9224B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2009 Nokia Corporation
      4 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
      5 *
      6 * Some code and ideas taken from drivers/video/omap/ driver
      7 * by Imre Deak.
      8 */
      9
     10#define DSS_SUBSYS_NAME "OVERLAY"
     11
     12#include <linux/module.h>
     13#include <linux/err.h>
     14#include <linux/sysfs.h>
     15#include <linux/kobject.h>
     16#include <linux/platform_device.h>
     17
     18#include <video/omapfb_dss.h>
     19
     20#include "dss.h"
     21#include "dss_features.h"
     22
     23static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
     24{
     25	return sysfs_emit(buf, "%s\n", ovl->name);
     26}
     27
     28static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
     29{
     30	return sysfs_emit(buf, "%s\n",
     31			ovl->manager ? ovl->manager->name : "<none>");
     32}
     33
     34static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
     35		size_t size)
     36{
     37	int i, r;
     38	struct omap_overlay_manager *mgr = NULL;
     39	struct omap_overlay_manager *old_mgr;
     40	int len = size;
     41
     42	if (buf[size-1] == '\n')
     43		--len;
     44
     45	if (len > 0) {
     46		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
     47			mgr = omap_dss_get_overlay_manager(i);
     48
     49			if (sysfs_streq(buf, mgr->name))
     50				break;
     51
     52			mgr = NULL;
     53		}
     54	}
     55
     56	if (len > 0 && mgr == NULL)
     57		return -EINVAL;
     58
     59	if (mgr)
     60		DSSDBG("manager %s found\n", mgr->name);
     61
     62	if (mgr == ovl->manager)
     63		return size;
     64
     65	old_mgr = ovl->manager;
     66
     67	r = dispc_runtime_get();
     68	if (r)
     69		return r;
     70
     71	/* detach old manager */
     72	if (old_mgr) {
     73		r = ovl->unset_manager(ovl);
     74		if (r) {
     75			DSSERR("detach failed\n");
     76			goto err;
     77		}
     78
     79		r = old_mgr->apply(old_mgr);
     80		if (r)
     81			goto err;
     82	}
     83
     84	if (mgr) {
     85		r = ovl->set_manager(ovl, mgr);
     86		if (r) {
     87			DSSERR("Failed to attach overlay\n");
     88			goto err;
     89		}
     90
     91		r = mgr->apply(mgr);
     92		if (r)
     93			goto err;
     94	}
     95
     96	dispc_runtime_put();
     97
     98	return size;
     99
    100err:
    101	dispc_runtime_put();
    102	return r;
    103}
    104
    105static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
    106{
    107	struct omap_overlay_info info;
    108
    109	ovl->get_overlay_info(ovl, &info);
    110
    111	return sysfs_emit(buf, "%d,%d\n",
    112			info.width, info.height);
    113}
    114
    115static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
    116{
    117	struct omap_overlay_info info;
    118
    119	ovl->get_overlay_info(ovl, &info);
    120
    121	return sysfs_emit(buf, "%d\n", info.screen_width);
    122}
    123
    124static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
    125{
    126	struct omap_overlay_info info;
    127
    128	ovl->get_overlay_info(ovl, &info);
    129
    130	return sysfs_emit(buf, "%d,%d\n",
    131			info.pos_x, info.pos_y);
    132}
    133
    134static ssize_t overlay_position_store(struct omap_overlay *ovl,
    135		const char *buf, size_t size)
    136{
    137	int r;
    138	char *last;
    139	struct omap_overlay_info info;
    140
    141	ovl->get_overlay_info(ovl, &info);
    142
    143	info.pos_x = simple_strtoul(buf, &last, 10);
    144	++last;
    145	if (last - buf >= size)
    146		return -EINVAL;
    147
    148	info.pos_y = simple_strtoul(last, &last, 10);
    149
    150	r = ovl->set_overlay_info(ovl, &info);
    151	if (r)
    152		return r;
    153
    154	if (ovl->manager) {
    155		r = ovl->manager->apply(ovl->manager);
    156		if (r)
    157			return r;
    158	}
    159
    160	return size;
    161}
    162
    163static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
    164{
    165	struct omap_overlay_info info;
    166
    167	ovl->get_overlay_info(ovl, &info);
    168
    169	return sysfs_emit(buf, "%d,%d\n",
    170			info.out_width, info.out_height);
    171}
    172
    173static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
    174		const char *buf, size_t size)
    175{
    176	int r;
    177	char *last;
    178	struct omap_overlay_info info;
    179
    180	ovl->get_overlay_info(ovl, &info);
    181
    182	info.out_width = simple_strtoul(buf, &last, 10);
    183	++last;
    184	if (last - buf >= size)
    185		return -EINVAL;
    186
    187	info.out_height = simple_strtoul(last, &last, 10);
    188
    189	r = ovl->set_overlay_info(ovl, &info);
    190	if (r)
    191		return r;
    192
    193	if (ovl->manager) {
    194		r = ovl->manager->apply(ovl->manager);
    195		if (r)
    196			return r;
    197	}
    198
    199	return size;
    200}
    201
    202static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
    203{
    204	return sysfs_emit(buf, "%d\n", ovl->is_enabled(ovl));
    205}
    206
    207static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
    208		size_t size)
    209{
    210	int r;
    211	bool enable;
    212
    213	r = strtobool(buf, &enable);
    214	if (r)
    215		return r;
    216
    217	if (enable)
    218		r = ovl->enable(ovl);
    219	else
    220		r = ovl->disable(ovl);
    221
    222	if (r)
    223		return r;
    224
    225	return size;
    226}
    227
    228static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
    229{
    230	struct omap_overlay_info info;
    231
    232	ovl->get_overlay_info(ovl, &info);
    233
    234	return sysfs_emit(buf, "%d\n",
    235			info.global_alpha);
    236}
    237
    238static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
    239		const char *buf, size_t size)
    240{
    241	int r;
    242	u8 alpha;
    243	struct omap_overlay_info info;
    244
    245	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
    246		return -ENODEV;
    247
    248	r = kstrtou8(buf, 0, &alpha);
    249	if (r)
    250		return r;
    251
    252	ovl->get_overlay_info(ovl, &info);
    253
    254	info.global_alpha = alpha;
    255
    256	r = ovl->set_overlay_info(ovl, &info);
    257	if (r)
    258		return r;
    259
    260	if (ovl->manager) {
    261		r = ovl->manager->apply(ovl->manager);
    262		if (r)
    263			return r;
    264	}
    265
    266	return size;
    267}
    268
    269static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
    270		char *buf)
    271{
    272	struct omap_overlay_info info;
    273
    274	ovl->get_overlay_info(ovl, &info);
    275
    276	return sysfs_emit(buf, "%d\n",
    277			info.pre_mult_alpha);
    278}
    279
    280static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
    281		const char *buf, size_t size)
    282{
    283	int r;
    284	u8 alpha;
    285	struct omap_overlay_info info;
    286
    287	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
    288		return -ENODEV;
    289
    290	r = kstrtou8(buf, 0, &alpha);
    291	if (r)
    292		return r;
    293
    294	ovl->get_overlay_info(ovl, &info);
    295
    296	info.pre_mult_alpha = alpha;
    297
    298	r = ovl->set_overlay_info(ovl, &info);
    299	if (r)
    300		return r;
    301
    302	if (ovl->manager) {
    303		r = ovl->manager->apply(ovl->manager);
    304		if (r)
    305			return r;
    306	}
    307
    308	return size;
    309}
    310
    311static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
    312{
    313	struct omap_overlay_info info;
    314
    315	ovl->get_overlay_info(ovl, &info);
    316
    317	return sysfs_emit(buf, "%d\n", info.zorder);
    318}
    319
    320static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
    321		const char *buf, size_t size)
    322{
    323	int r;
    324	u8 zorder;
    325	struct omap_overlay_info info;
    326
    327	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
    328		return -ENODEV;
    329
    330	r = kstrtou8(buf, 0, &zorder);
    331	if (r)
    332		return r;
    333
    334	ovl->get_overlay_info(ovl, &info);
    335
    336	info.zorder = zorder;
    337
    338	r = ovl->set_overlay_info(ovl, &info);
    339	if (r)
    340		return r;
    341
    342	if (ovl->manager) {
    343		r = ovl->manager->apply(ovl->manager);
    344		if (r)
    345			return r;
    346	}
    347
    348	return size;
    349}
    350
    351struct overlay_attribute {
    352	struct attribute attr;
    353	ssize_t (*show)(struct omap_overlay *, char *);
    354	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
    355};
    356
    357#define OVERLAY_ATTR(_name, _mode, _show, _store) \
    358	struct overlay_attribute overlay_attr_##_name = \
    359	__ATTR(_name, _mode, _show, _store)
    360
    361static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
    362static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
    363		overlay_manager_show, overlay_manager_store);
    364static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
    365static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
    366static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
    367		overlay_position_show, overlay_position_store);
    368static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
    369		overlay_output_size_show, overlay_output_size_store);
    370static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
    371		overlay_enabled_show, overlay_enabled_store);
    372static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
    373		overlay_global_alpha_show, overlay_global_alpha_store);
    374static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
    375		overlay_pre_mult_alpha_show,
    376		overlay_pre_mult_alpha_store);
    377static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
    378		overlay_zorder_show, overlay_zorder_store);
    379
    380static struct attribute *overlay_sysfs_attrs[] = {
    381	&overlay_attr_name.attr,
    382	&overlay_attr_manager.attr,
    383	&overlay_attr_input_size.attr,
    384	&overlay_attr_screen_width.attr,
    385	&overlay_attr_position.attr,
    386	&overlay_attr_output_size.attr,
    387	&overlay_attr_enabled.attr,
    388	&overlay_attr_global_alpha.attr,
    389	&overlay_attr_pre_mult_alpha.attr,
    390	&overlay_attr_zorder.attr,
    391	NULL
    392};
    393ATTRIBUTE_GROUPS(overlay_sysfs);
    394
    395static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
    396		char *buf)
    397{
    398	struct omap_overlay *overlay;
    399	struct overlay_attribute *overlay_attr;
    400
    401	overlay = container_of(kobj, struct omap_overlay, kobj);
    402	overlay_attr = container_of(attr, struct overlay_attribute, attr);
    403
    404	if (!overlay_attr->show)
    405		return -ENOENT;
    406
    407	return overlay_attr->show(overlay, buf);
    408}
    409
    410static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
    411		const char *buf, size_t size)
    412{
    413	struct omap_overlay *overlay;
    414	struct overlay_attribute *overlay_attr;
    415
    416	overlay = container_of(kobj, struct omap_overlay, kobj);
    417	overlay_attr = container_of(attr, struct overlay_attribute, attr);
    418
    419	if (!overlay_attr->store)
    420		return -ENOENT;
    421
    422	return overlay_attr->store(overlay, buf, size);
    423}
    424
    425static const struct sysfs_ops overlay_sysfs_ops = {
    426	.show = overlay_attr_show,
    427	.store = overlay_attr_store,
    428};
    429
    430static struct kobj_type overlay_ktype = {
    431	.sysfs_ops = &overlay_sysfs_ops,
    432	.default_groups = overlay_sysfs_groups,
    433};
    434
    435int dss_overlay_kobj_init(struct omap_overlay *ovl,
    436		struct platform_device *pdev)
    437{
    438	return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
    439			&pdev->dev.kobj, "overlay%d", ovl->id);
    440}
    441
    442void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
    443{
    444	kobject_del(&ovl->kobj);
    445	kobject_put(&ovl->kobj);
    446}