Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b403721f authored by Archana Sathyakumar's avatar Archana Sathyakumar Committed by Mahesh Sivasubramanian
Browse files

msm-core: Add uio extension for memory mapping



With /dev/mem node no longer available for userspace IO memory access,
each driver needs to provide the range of memory it needs access to and
the type of memory it is accessing.

Add this interface to the driver and create a device that allows
userspace to access IO memory mapped region. Since userspace access is
simple IO memory read, use the generic UIO ops function for mmap and
open calls.

Change-Id: I34ffd2873ed7998244bded7f88f6663dd95c6ad4
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 6c644c0f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ scheduling decision.
The required nodes for the Energy-aware driver are:

- compatible:    "qcom,apss-core-ea"
- reg:           Physical address mapped to this device

Required properties:
- qcom,core-mapping: Parent node that lists characteristics of
@@ -44,8 +45,9 @@ Optional properties to define per core characteristics:

Example

qcom,msm-core {
qcom,msm-core@0xfc4b0000 {
	compatible = "qcom,apss-core-ea";
	reg = <0xfc4b0000 0x1000>;
	qcom,low-hyst-temp = <10>;
	qcom,high-hyst-temp = <5>;
	qcom,polling-interval = <50>;
+2 −1
Original line number Diff line number Diff line
@@ -3191,8 +3191,9 @@
		linux,contiguous-region = <&adsp_mem>;
	};

	qcom,msm-core {
	qcom,msm-core@fc4b8000 {
		compatible = "qcom,apss-core-ea";
		reg = <0xfc4b8000 0x1000>;
		qcom,low-hyst-temp = <10>;
		qcom,high-hyst-temp = <5>;
		qcom,polling-interval = <50>;
+51 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/thermal.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/uio_driver.h>
#include <asm/smp_plat.h>
#include <stdbool.h>
#define CREATE_TRACE_POINTS
@@ -907,6 +908,49 @@ static void free_dyn_memory(void)
	}
}

static int uio_init(struct platform_device *pdev)
{
	int ret = 0;
	struct uio_info *info = NULL;
	struct resource *clnt_res = NULL;
	u32 ea_mem_size = 0;
	phys_addr_t ea_mem_pyhsical = 0;

	clnt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!clnt_res) {
		pr_err("resource not found\n");
		return -ENODEV;
	}

	info = devm_kzalloc(&pdev->dev, sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	ea_mem_size = resource_size(clnt_res);
	ea_mem_pyhsical = clnt_res->start;

	if (ea_mem_size == 0) {
		pr_err("msm-core: memory size is zero");
		return -EINVAL;
	}

	/* Setup device */
	info->name = clnt_res->name;
	info->version = "1.0";
	info->mem[0].addr = ea_mem_pyhsical;
	info->mem[0].size = ea_mem_size;
	info->mem[0].memtype = UIO_MEM_PHYS;

	ret = uio_register_device(&pdev->dev, info);
	if (ret) {
		pr_err("uio register failed ret=%d", ret);
		return ret;
	}
	dev_set_drvdata(&pdev->dev, info);

	return 0;
}

static int msm_core_dev_probe(struct platform_device *pdev)
{
	int ret = 0;
@@ -940,6 +984,10 @@ static int msm_core_dev_probe(struct platform_device *pdev)
	key = "qcom,throttling-temp";
	ret = of_property_read_u32(node, key, &max_throttling_temp);

	ret = uio_init(pdev);
	if (ret)
		return ret;

	ret = msm_core_freq_init();
	if (ret)
		return ret;
@@ -974,6 +1022,9 @@ failed:
static int msm_core_remove(struct platform_device *pdev)
{
	int cpu;
	struct uio_info *info = dev_get_drvdata(&pdev->dev);

	uio_unregister_device(info);

	for_each_possible_cpu(cpu) {
		if (activity[cpu].sensor_id < 0)