Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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: Hans de Goede <hdegoede@redhat.com>
Acked-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Hans de Goede and committed by
Mauro Carvalho Chehab
44f8af68 2c794075

+25 -2
+2
Documentation/devicetree/bindings/media/sunxi-ir.txt
··· 10 10 11 11 Optional properties: 12 12 - linux,rc-map-name : Remote control map name. 13 + - resets : phandle + reset specifier pair 13 14 14 15 Example: 15 16 ··· 18 17 compatible = "allwinner,sun4i-a10-ir"; 19 18 clocks = <&apb0_gates 6>, <&ir0_clk>; 20 19 clock-names = "apb", "ir"; 20 + resets = <&apb0_rst 1>; 21 21 interrupts = <0 5 1>; 22 22 reg = <0x01C21800 0x40>; 23 23 linux,rc-map-name = "rc-rc6-mce";
+23 -2
drivers/media/rc/sunxi-cir.c
··· 23 23 #include <linux/interrupt.h> 24 24 #include <linux/module.h> 25 25 #include <linux/of_platform.h> 26 + #include <linux/reset.h> 26 27 #include <media/rc-core.h> 27 28 28 29 #define SUNXI_IR_DEV "sunxi-ir" ··· 96 95 int irq; 97 96 struct clk *clk; 98 97 struct clk *apb_clk; 98 + struct reset_control *rst; 99 99 const char *map_name; 100 100 }; 101 101 ··· 168 166 return PTR_ERR(ir->clk); 169 167 } 170 168 169 + /* Reset (optional) */ 170 + ir->rst = devm_reset_control_get_optional(dev, NULL); 171 + if (IS_ERR(ir->rst)) { 172 + ret = PTR_ERR(ir->rst); 173 + if (ret == -EPROBE_DEFER) 174 + return ret; 175 + ir->rst = NULL; 176 + } else { 177 + ret = reset_control_deassert(ir->rst); 178 + if (ret) 179 + return ret; 180 + } 181 + 171 182 ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); 172 183 if (ret) { 173 184 dev_err(dev, "set ir base clock failed!\n"); 174 - return ret; 185 + goto exit_reset_assert; 175 186 } 176 187 177 188 if (clk_prepare_enable(ir->apb_clk)) { 178 189 dev_err(dev, "try to enable apb_ir_clk failed\n"); 179 - return -EINVAL; 190 + ret = -EINVAL; 191 + goto exit_reset_assert; 180 192 } 181 193 182 194 if (clk_prepare_enable(ir->clk)) { ··· 287 271 clk_disable_unprepare(ir->clk); 288 272 exit_clkdisable_apb_clk: 289 273 clk_disable_unprepare(ir->apb_clk); 274 + exit_reset_assert: 275 + if (ir->rst) 276 + reset_control_assert(ir->rst); 290 277 291 278 return ret; 292 279 } ··· 301 282 302 283 clk_disable_unprepare(ir->clk); 303 284 clk_disable_unprepare(ir->apb_clk); 285 + if (ir->rst) 286 + reset_control_assert(ir->rst); 304 287 305 288 spin_lock_irqsave(&ir->ir_lock, flags); 306 289 /* disable IR IRQ */