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

Commit 44f8af68 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab
Browse files

[media] rc: sunxi-cir: Add support for an optional reset controller



On sun6i the cir block is attached to the reset controller, add support
for de-asserting the reset if a reset controller is specified in dt.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
Acked-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 2c794075
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ Required properties:

Optional properties:
- linux,rc-map-name : Remote control map name.
- resets : phandle + reset specifier pair

Example:

@@ -17,6 +18,7 @@ ir0: ir@01c21800 {
	compatible = "allwinner,sun4i-a10-ir";
	clocks = <&apb0_gates 6>, <&ir0_clk>;
	clock-names = "apb", "ir";
	resets = <&apb0_rst 1>;
	interrupts = <0 5 1>;
	reg = <0x01C21800 0x40>;
	linux,rc-map-name = "rc-rc6-mce";
+23 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/reset.h>
#include <media/rc-core.h>

#define SUNXI_IR_DEV "sunxi-ir"
@@ -95,6 +96,7 @@ struct sunxi_ir {
	int             irq;
	struct clk      *clk;
	struct clk      *apb_clk;
	struct reset_control *rst;
	const char      *map_name;
};

@@ -166,15 +168,29 @@ static int sunxi_ir_probe(struct platform_device *pdev)
		return PTR_ERR(ir->clk);
	}

	/* Reset (optional) */
	ir->rst = devm_reset_control_get_optional(dev, NULL);
	if (IS_ERR(ir->rst)) {
		ret = PTR_ERR(ir->rst);
		if (ret == -EPROBE_DEFER)
			return ret;
		ir->rst = NULL;
	} else {
		ret = reset_control_deassert(ir->rst);
		if (ret)
			return ret;
	}

	ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK);
	if (ret) {
		dev_err(dev, "set ir base clock failed!\n");
		return ret;
		goto exit_reset_assert;
	}

	if (clk_prepare_enable(ir->apb_clk)) {
		dev_err(dev, "try to enable apb_ir_clk failed\n");
		return -EINVAL;
		ret = -EINVAL;
		goto exit_reset_assert;
	}

	if (clk_prepare_enable(ir->clk)) {
@@ -271,6 +287,9 @@ static int sunxi_ir_probe(struct platform_device *pdev)
	clk_disable_unprepare(ir->clk);
exit_clkdisable_apb_clk:
	clk_disable_unprepare(ir->apb_clk);
exit_reset_assert:
	if (ir->rst)
		reset_control_assert(ir->rst);

	return ret;
}
@@ -282,6 +301,8 @@ static int sunxi_ir_remove(struct platform_device *pdev)

	clk_disable_unprepare(ir->clk);
	clk_disable_unprepare(ir->apb_clk);
	if (ir->rst)
		reset_control_assert(ir->rst);

	spin_lock_irqsave(&ir->ir_lock, flags);
	/* disable IR IRQ */