]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
nvpmodel: add nvpmodel_emc_cap driver and sysfs
authorTerry Wang <terwang@nvidia.com>
Mon, 16 Jan 2017 16:52:32 +0000 (00:52 +0800)
committermobile promotions <svcmobile_promotions@nvidia.com>
Tue, 24 Jan 2017 11:19:49 +0000 (03:19 -0800)
Add nvpmodel_emc_cap driver
Add /sys/kernel/nvpmodel_emc_cap/emc_iso_cap sysfs

bug 1843348

Change-Id: Ifc0091ebbd4ecf5950a80083c01196e24ac93472
Signed-off-by: Terry Wang <terwang@nvidia.com>
Reviewed-on: http://git-master/r/1282877
(cherry picked from commit a294f9adc5c3043bcf7855bfbfa500471e5822f4)
Signed-off-by: Terry Wang <terwang@nvidia.com>
Reviewed-on: http://git-master/r/1287944
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
drivers/Kconfig
drivers/Makefile
drivers/nvpmodel/Kconfig [new file with mode: 0644]
drivers/nvpmodel/Makefile [new file with mode: 0644]
drivers/nvpmodel/nvpmodel_emc_cap.c [new file with mode: 0644]
drivers/platform/tegra/mc/emc_bwmgr.c
include/linux/platform/tegra/emc_bwmgr.h

index 33fd2bf5e4173badfcb7387c933c3f83b9782b35..065f25a115f5e067005c1536e4c1aa297ce7233c 100644 (file)
@@ -110,6 +110,8 @@ source "drivers/leds/Kconfig"
 
 source "drivers/switch/Kconfig"
 
+source "drivers/nvpmodel/Kconfig"
+
 source "drivers/accessibility/Kconfig"
 
 source "drivers/infiniband/Kconfig"
index 0abfbbccacc05dda949ffd62e28c7c396b10d2fd..016c4699dfbef4814670b0237381c12d88e1a8b5 100644 (file)
@@ -176,6 +176,7 @@ obj-$(CONFIG_STM)           += hwtracing/stm/
 obj-$(CONFIG_ANDROID)          += android/
 obj-$(CONFIG_NVMEM)            += nvmem/
 obj-$(CONFIG_FPGA)             += fpga/
+obj-$(CONFIG_NVPMODEL_EMC)     += nvpmodel/
 
 # The wildcard hack is necessary for kernel's make clean.
 ifneq ($(wildcard $(srctree)/../t18x/drivers/Makefile.*),)
diff --git a/drivers/nvpmodel/Kconfig b/drivers/nvpmodel/Kconfig
new file mode 100644 (file)
index 0000000..9a559af
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Nvpmodel EMC CAP Configuration
+#
+
+menuconfig NVPMODEL_EMC
+       tristate "NVPMODEL_EMC_CAP driver"
+       default n
+       help
+           This driver add an EMC bwmgr client and expose related cap Sysfs to
+           user space, this make the Nvpmodel to cap EMC BW through Sysfs
+           possible. The cap value is based on different Nvpmodel usecase.
+           The BW cap will effect on not only bwmgr client and also iso client.
+
+           If in doubt, say N.
diff --git a/drivers/nvpmodel/Makefile b/drivers/nvpmodel/Makefile
new file mode 100644 (file)
index 0000000..7c5b284
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Nvpmodel EMC Client driver.
+#
+obj-$(CONFIG_NVPMODEL_EMC) := nvpmodel_emc_cap.o
diff --git a/drivers/nvpmodel/nvpmodel_emc_cap.c b/drivers/nvpmodel/nvpmodel_emc_cap.c
new file mode 100644 (file)
index 0000000..19d0227
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * drivers/nvpmodel/nvpmodel_emc_cap.c
+ *
+ * NVIDIA Tegra Nvpmodel driver for Tegra chips
+ *
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/platform/tegra/emc_bwmgr.h>
+#include <linux/platform/tegra/bwmgr_mc.h>
+
+#define AUTHOR "Terry Wang <terwang@nvidia.com>"
+#define DESCRIPTION "Nvpmodel EMC cap driver"
+#define MODULE_NAME "Nvpmodel_EMC_cap"
+#define VERSION "1.0"
+
+/* Module information */
+MODULE_AUTHOR(AUTHOR);
+MODULE_DESCRIPTION(DESCRIPTION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
+
+static struct kobject *emc_iso_cap_kobject;
+static unsigned long emc_iso_cap;
+
+/* bandwidth manager handle */
+struct tegra_bwmgr_client *bwmgr_handle;
+
+static ssize_t emc_iso_cap_show(struct kobject *kobj,
+                               struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", emc_iso_cap);
+}
+
+static ssize_t emc_iso_cap_store(struct kobject *kobj,
+                               struct kobj_attribute *attr, char *buf,
+                               size_t count)
+{
+       int error = 0;
+       sscanf(buf, "%du", &emc_iso_cap);
+       error = tegra_bwmgr_set_emc(bwmgr_handle, emc_iso_cap,
+                               TEGRA_BWMGR_SET_EMC_ISO_CAP);
+       if (error)
+               pr_warn("Nvpmodel failed to set EMC hz=%lu errno=%d\n",
+                       emc_iso_cap, error);
+
+       return count;
+}
+
+static struct kobj_attribute emc_iso_cap_attribute =
+       __ATTR(emc_iso_cap, 0660, emc_iso_cap_show, emc_iso_cap_store);
+
+static int __init nvpmodel_emc_cap_init(void)
+{
+       int error = 0;
+
+       emc_iso_cap_kobject = kobject_create_and_add("nvpmodel_emc_cap",
+                                                kernel_kobj);
+       if (!emc_iso_cap_kobject)
+               return -ENOMEM;
+       error = sysfs_create_file(emc_iso_cap_kobject,
+                               &emc_iso_cap_attribute.attr);
+       if (error) {
+               pr_err("failed to create emc_iso_cap sysfs: error %d\n", error);
+               kobject_put(emc_iso_cap_kobject);
+               return error;
+       }
+
+       bwmgr_handle = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_NVPMODEL);
+       if (IS_ERR_OR_NULL(bwmgr_handle)) {
+               error = IS_ERR(bwmgr_handle) ?
+                       PTR_ERR(bwmgr_handle) : -ENODEV;
+               pr_warn("Nvpmodel can't register EMC bwmgr (%d)\n", error);
+               kobject_put(emc_iso_cap_kobject);
+               return error;
+       }
+
+       pr_info("Module initialized successfully \n");
+       return error;
+}
+
+static void __exit nvpmodel_emc_cap_exit(void)
+{
+       tegra_bwmgr_unregister(bwmgr_handle);
+       kobject_put(emc_iso_cap_kobject);
+       pr_info("Module exit successfully \n");
+}
+
+module_init(nvpmodel_emc_cap_init);
+module_exit(nvpmodel_emc_cap_exit);
index fcf5385dd340c8c0550ea62185fd832f8c2208ee..bc65cd9fa64bcd479d488c4d75849182c0247527 100644 (file)
@@ -500,6 +500,7 @@ static const char * const tegra_bwmgr_client_names[] = {
        "se3",
        "se4",
        "pmqos",
+       "nvpmodel",
        "debug",
        "null",
 };
index 532c0e8e18d467f04267daeaf3b747b0c7a010cd..2b9f7e57aaf231f7489477f1c584c323149f2a87 100644 (file)
@@ -56,6 +56,7 @@ enum tegra_bwmgr_client_id {
        TEGRA_BWMGR_CLIENT_SE3,
        TEGRA_BWMGR_CLIENT_SE4,
        TEGRA_BWMGR_CLIENT_PMQOS,
+       TEGRA_BWMGR_CLIENT_NVPMODEL,
        TEGRA_BWMGR_CLIENT_DEBUG,
        TEGRA_BWMGR_CLIENT_COUNT /* Should always be last */
 };