Merge "defconfig: enable spss-utils driver for msmcobalt"

This commit is contained in:
Linux Build Service Account 2016-09-15 07:33:01 -07:00 committed by Gerrit - the friendly Code Review server
commit 7ad50395d8
8 changed files with 350 additions and 0 deletions

View file

@ -0,0 +1,27 @@
Qualcomm Technologies, Inc. Secure Processor SubSystem Utilities (spss_utils)
The Secure Processor SubSystem (SPSS) is a dedicated subsystem for security.
It has its own CPU, memories, and cryptographic engine.
It shall provide cryptographic services to other subsystems.
The SPSS firmware is loaded by PIL driver.
The communication with SPSS is done via spcom driver, using glink.
The spss_utils driver selects the SPSS firmware file,
according to a dedicated fuse and the platform HW version.
Required properties:
-compatible : should be "qcom,spss_utils"
-qcom,spss-fuse-addr: fuse register physical address
-qcom,spss-fuse-bit: fuse relevant bit
-qcom,spss-test-firmware-name: test firmware file name
-qcom,spss-prod-firmware-name: production firmware file name
Example:
qcom,spss_utils {
compatible = "qcom,spss-utils";
qcom,spss-fuse-addr = <0x007841c4 0x4>; /* spss test fuse physical address */
qcom,spss-fuse-bit = <27>;
qcom,spss-test-firmware-name = "spss1t"; /* 8 chars max */
qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */
};

View file

@ -746,6 +746,11 @@
};
};
&spss_utils {
qcom,spss-test-firmware-name = "spss2t"; /* 8 chars max */
qcom,spss-prod-firmware-name = "spss2p"; /* 8 chars max */
};
&ufs1 {
clock-names =
"core_clk",

View file

@ -1635,6 +1635,16 @@
status = "ok";
};
spss_utils: qcom,spss_utils {
compatible = "qcom,spss-utils";
/* spss test fuse physical address */
qcom,spss-fuse-addr = <0x007841c4 0x4>;
qcom,spss-fuse-bit = <27>;
qcom,spss-test-firmware-name = "spss"; /* default name */
qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */
status = "ok";
};
sdhc_2: sdhci@c0a4900 {
compatible = "qcom,sdhci-msm";
reg = <0xc0a4900 0x314>, <0xc0a4000 0x800>;

View file

@ -494,6 +494,7 @@ CONFIG_MSM_GLINK_SMD_XPRT=y
CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
CONFIG_MSM_GLINK_SPI_XPRT=y
CONFIG_MSM_SPCOM=y
CONFIG_MSM_SPSS_UTILS=y
CONFIG_MSM_SMEM_LOGGING=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_SMP2P_TEST=y

View file

@ -506,6 +506,7 @@ CONFIG_MSM_GLINK_SMD_XPRT=y
CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
CONFIG_MSM_GLINK_SPI_XPRT=y
CONFIG_MSM_SPCOM=y
CONFIG_MSM_SPSS_UTILS=y
CONFIG_MSM_SMEM_LOGGING=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_SMP2P_TEST=y

View file

@ -127,6 +127,17 @@ config MSM_SPCOM
spcom provides clients/server API, although currently only one client
or server is allowed per logical channel.
config MSM_SPSS_UTILS
depends on MSM_PIL
bool "Secure Processor Utilities"
help
spss-utils driver selects Secure Processor firmware file name.
The firmware file name for test or production is selected based
on a test fuse.
Different file name is used for differnt SPSS HW versions,
because the SPSS firmware size is too small to support multiple
HW versions.
config MSM_SMEM_LOGGING
depends on MSM_SMEM
bool "MSM Shared Memory Logger"

View file

@ -28,6 +28,7 @@ obj-$(CONFIG_MSM_IPC_ROUTER_HSIC_XPRT) += ipc_router_hsic_xprt.o
obj-$(CONFIG_MSM_IPC_ROUTER_MHI_XPRT) += ipc_router_mhi_xprt.o
obj-$(CONFIG_MSM_IPC_ROUTER_GLINK_XPRT) += ipc_router_glink_xprt.o
obj-$(CONFIG_MSM_SPCOM) += spcom.o
obj-$(CONFIG_MSM_SPSS_UTILS) += spss_utils.o
obj-y += qdsp6v2/
obj-$(CONFIG_MSM_SYSTEM_HEALTH_MONITOR) += system_health_monitor_v01.o
obj-$(CONFIG_MSM_SYSTEM_HEALTH_MONITOR) += system_health_monitor.o

View file

@ -0,0 +1,294 @@
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only 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.
*/
/*
* Secure-Processor-SubSystem (SPSS) utilities.
*
* This driver provides utilities for the Secure Processor (SP).
*
* The SP daemon needs to load different SPSS images based on:
*
* 1. Test/Production key used to sign the SPSS image (read fuse).
* 2. SPSS HW version (selected via Device Tree).
*
*/
#define pr_fmt(fmt) "spss_utils [%s]: " fmt, __func__
#include <linux/kernel.h> /* min() */
#include <linux/module.h> /* MODULE_LICENSE */
#include <linux/device.h> /* class_create() */
#include <linux/slab.h> /* kzalloc() */
#include <linux/fs.h> /* file_operations */
#include <linux/cdev.h> /* cdev_add() */
#include <linux/errno.h> /* EINVAL, ETIMEDOUT */
#include <linux/printk.h> /* pr_err() */
#include <linux/bitops.h> /* BIT(x) */
#include <linux/platform_device.h> /* platform_driver_register() */
#include <linux/of.h> /* of_property_count_strings() */
#include <linux/io.h> /* ioremap_nocache() */
#include <soc/qcom/subsystem_restart.h>
/* driver name */
#define DEVICE_NAME "spss-utils"
static bool is_test_fuse_set;
static const char *test_firmware_name;
static const char *prod_firmware_name;
static const char *firmware_name;
static struct device *spss_dev;
/*==========================================================================*/
/* Device Sysfs */
/*==========================================================================*/
static ssize_t firmware_name_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int ret;
if (!dev || !attr || !buf) {
pr_err("invalid param.\n");
return -EINVAL;
}
if (firmware_name == NULL)
ret = snprintf(buf, PAGE_SIZE, "%s\n", "unknown");
else
ret = snprintf(buf, PAGE_SIZE, "%s\n", firmware_name);
return ret;
}
static ssize_t firmware_name_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t size)
{
pr_err("set firmware name is not allowed.\n");
return -EINVAL;
}
static DEVICE_ATTR(firmware_name, 0444,
firmware_name_show, firmware_name_store);
static ssize_t test_fuse_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int ret;
if (!dev || !attr || !buf) {
pr_err("invalid param.\n");
return -EINVAL;
}
if (is_test_fuse_set)
ret = snprintf(buf, PAGE_SIZE, "%s\n", "test");
else
ret = snprintf(buf, PAGE_SIZE, "%s\n", "prod");
return ret;
}
static ssize_t test_fuse_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t size)
{
pr_err("set test fuse state is not allowed.\n");
return -EINVAL;
}
static DEVICE_ATTR(test_fuse_state, 0444,
test_fuse_state_show, test_fuse_state_store);
static int spss_create_sysfs(struct device *dev)
{
int ret;
ret = device_create_file(dev, &dev_attr_firmware_name);
if (ret < 0) {
pr_err("failed to create sysfs file for firmware_name.\n");
return ret;
}
ret = device_create_file(dev, &dev_attr_test_fuse_state);
if (ret < 0) {
pr_err("failed to create sysfs file for test_fuse_state.\n");
return ret;
}
return 0;
}
/*==========================================================================*/
/* Device Tree */
/*==========================================================================*/
/**
* spss_parse_dt() - Parse Device Tree info.
*/
static int spss_parse_dt(struct device_node *node)
{
int ret;
u32 spss_fuse_addr = 0;
u32 spss_fuse_bit = 0;
u32 spss_fuse_mask = 0;
void __iomem *spss_fuse_reg = NULL;
u32 val = 0;
ret = of_property_read_string(node, "qcom,spss-test-firmware-name",
&test_firmware_name);
if (ret < 0) {
pr_err("can't get test fw name.\n");
return -EFAULT;
}
ret = of_property_read_string(node, "qcom,spss-prod-firmware-name",
&prod_firmware_name);
if (ret < 0) {
pr_err("can't get prod fw name.\n");
return -EFAULT;
}
ret = of_property_read_u32(node, "qcom,spss-fuse-addr",
&spss_fuse_addr);
if (ret < 0) {
pr_err("can't get fuse addr.\n");
return -EFAULT;
}
ret = of_property_read_u32(node, "qcom,spss-fuse-bit",
&spss_fuse_bit);
if (ret < 0) {
pr_err("can't get fuse bit.\n");
return -EFAULT;
}
spss_fuse_mask = BIT(spss_fuse_bit);
pr_debug("spss_fuse_addr [0x%x] , spss_fuse_bit [%d] .\n",
(int) spss_fuse_addr, (int) spss_fuse_bit);
spss_fuse_reg = ioremap_nocache(spss_fuse_addr, sizeof(u32));
if (!spss_fuse_reg) {
pr_err("can't map fuse addr.\n");
return -EFAULT;
}
val = readl_relaxed(spss_fuse_reg);
pr_debug("spss fuse register value [0x%x].\n", (int) val);
if (val & spss_fuse_mask)
is_test_fuse_set = true;
iounmap(spss_fuse_reg);
return 0;
}
/**
* spss_probe() - initialization sequence
*/
static int spss_probe(struct platform_device *pdev)
{
int ret = 0;
struct device_node *np = NULL;
struct device *dev = NULL;
if (!pdev) {
pr_err("invalid pdev.\n");
return -ENODEV;
}
np = pdev->dev.of_node;
if (!np) {
pr_err("invalid DT node.\n");
return -EINVAL;
}
dev = &pdev->dev;
spss_dev = dev;
if (dev == NULL) {
pr_err("invalid dev.\n");
return -EINVAL;
}
platform_set_drvdata(pdev, dev);
ret = spss_parse_dt(np);
if (ret < 0) {
pr_err("fail to parse device tree.\n");
return -EFAULT;
}
if (is_test_fuse_set)
firmware_name = test_firmware_name;
else
firmware_name = prod_firmware_name;
ret = subsystem_set_fwname("spss", firmware_name);
if (ret < 0) {
pr_err("fail to set fw name.\n");
return -EFAULT;
}
spss_create_sysfs(dev);
pr_info("Initialization completed ok, firmware_name [%s].\n",
firmware_name);
return 0;
}
static const struct of_device_id spss_match_table[] = {
{ .compatible = "qcom,spss-utils", },
{ },
};
static struct platform_driver spss_driver = {
.probe = spss_probe,
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spss_match_table),
},
};
/*==========================================================================*/
/* Driver Init/Exit */
/*==========================================================================*/
static int __init spss_init(void)
{
int ret = 0;
pr_info("spss-utils driver Ver 1.0 12-Sep-2016.\n");
ret = platform_driver_register(&spss_driver);
if (ret)
pr_err("register platform driver failed, ret [%d]\n", ret);
return 0;
}
late_initcall(spss_init); /* start after PIL driver */
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Secure Processor Utilities");