From cc64770782e6bb01b2d8b76c1731a28d5d06d135 Mon Sep 17 00:00:00 2001
From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
Date: Fri, 7 Jul 2017 20:42:36 +0300
Subject: [PATCH] MOST: dim2: add device tree support
Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
---
drivers/staging/most/hdm-dim2/dim2_hdm.c | 72 ++++++++++++++++++++++----------
1 file changed, 50 insertions(+), 22 deletions(-)
diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
index a36449551513..f28f169180fe 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
+#include <linux/of_platform.h>
#include <linux/printk.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -21,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/sched.h>
#include <linux/kthread.h>
@@ -101,6 +103,7 @@ struct dim2_hdm {
struct most_interface most_iface;
char name[16 + sizeof "dim2-"];
void __iomem *io_base;
+ struct clk *clk;
int clk_speed;
struct task_struct *netinfo_task;
wait_queue_head_t netinfo_waitq;
@@ -165,6 +168,27 @@ void dimcb_on_error(u8 error_id, const char *error_message)
error_message);
}
+static int dim_parce_speed(const char *clock_speed)
+{
+ if (!strcmp(clock_speed, "256fs"))
+ return CLK_256FS;
+ else if (!strcmp(clock_speed, "512fs"))
+ return CLK_512FS;
+ else if (!strcmp(clock_speed, "1024fs"))
+ return CLK_1024FS;
+ else if (!strcmp(clock_speed, "2048fs"))
+ return CLK_2048FS;
+ else if (!strcmp(clock_speed, "3072fs"))
+ return CLK_3072FS;
+ else if (!strcmp(clock_speed, "4096fs"))
+ return CLK_4096FS;
+ else if (!strcmp(clock_speed, "6144fs"))
+ return CLK_6144FS;
+ else if (!strcmp(clock_speed, "8192fs"))
+ return CLK_8192FS;
+ return -1;
+}
+
/**
* startup_dim - initialize the dim2 interface
* @pdev: platform device
@@ -178,32 +202,12 @@ static int startup_dim(struct platform_device *pdev)
struct dim2_platform_data *pdata = pdev->dev.platform_data;
u8 hal_ret;
- dev->clk_speed = -1;
-
- if (clock_speed) {
- if (!strcmp(clock_speed, "256fs"))
- dev->clk_speed = CLK_256FS;
- else if (!strcmp(clock_speed, "512fs"))
- dev->clk_speed = CLK_512FS;
- else if (!strcmp(clock_speed, "1024fs"))
- dev->clk_speed = CLK_1024FS;
- else if (!strcmp(clock_speed, "2048fs"))
- dev->clk_speed = CLK_2048FS;
- else if (!strcmp(clock_speed, "3072fs"))
- dev->clk_speed = CLK_3072FS;
- else if (!strcmp(clock_speed, "4096fs"))
- dev->clk_speed = CLK_4096FS;
- else if (!strcmp(clock_speed, "6144fs"))
- dev->clk_speed = CLK_6144FS;
- else if (!strcmp(clock_speed, "8192fs"))
- dev->clk_speed = CLK_8192FS;
- }
+ if (clock_speed)
+ dev->clk_speed = dim_parce_speed(clock_speed);
if (dev->clk_speed == -1) {
pr_info("Bad or missing clock speed parameter, using default value: 3072fs\n");
dev->clk_speed = CLK_3072FS;
- } else {
- pr_info("Selected clock speed: %s\n", clock_speed);
}
if (pdata && pdata->init) {
int ret = pdata->init(pdata, dev->io_base, dev->clk_speed);
@@ -735,6 +739,7 @@ static int dim2_probe(struct platform_device *pdev)
int ret, i;
struct kobject *kobj;
int irq;
+ struct device_node *np = pdev->dev.of_node;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -765,6 +770,14 @@ static int dim2_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq);
return ret;
}
+
+ dev->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(dev->clk)) {
+ dev_err(&pdev->dev, "cannot get clock\n");
+ ret = PTR_ERR(dev->clk);
+ return ret;
+ }
+ clk_prepare_enable(dev->clk);
init_waitqueue_head(&dev->netinfo_waitq);
dev->deliver_netinfo = 0;
@@ -814,6 +827,12 @@ static int dim2_probe(struct platform_device *pdev)
dev->most_iface.poison_channel = poison_channel;
dev->most_iface.request_netinfo = request_netinfo;
+ if (np) {
+ const char *tmp;
+ if (!of_property_read_string(np, "clock-speed", &tmp))
+ dev->clk_speed = dim_parce_speed(tmp);
+ }
+
kobj = most_register_interface(&dev->most_iface);
if (IS_ERR(kobj)) {
ret = PTR_ERR(kobj);
@@ -866,6 +885,8 @@ static int dim2_remove(struct platform_device *pdev)
most_deregister_interface(&dev->most_iface);
kthread_stop(dev->netinfo_task);
+ clk_disable_unprepare(dev->clk);
+
/*
* break link to local platform_device_id struct
* to prevent crash by unload platform device module
@@ -882,12 +903,19 @@ static struct platform_device_id dim2_id[] = {
MODULE_DEVICE_TABLE(platform, dim2_id);
+static const struct of_device_id dim2_of_match[] = {
+ { .compatible = "rcar,medialb-dim2", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dim2_of_match);
+
static struct platform_driver dim2_driver = {
.probe = dim2_probe,
.remove = dim2_remove,
.id_table = dim2_id,
.driver = {
.name = "hdm_dim2",
+ .of_match_table = dim2_of_match,
},
};
--
2.13.0