diff options
Diffstat (limited to 'drivers/media/rc/st_rc.c')
| -rw-r--r-- | drivers/media/rc/st_rc.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 15de3ae166a2..6b70bac5f45d 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -1,15 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2013 STMicroelectronics Limited * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -115,7 +112,7 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) int_status = readl(dev->rx_base + IRB_RX_INT_STATUS); if (unlikely(int_status & IRB_RX_OVERRUN_INT)) { /* discard the entire collection in case of errors! */ - ir_raw_event_reset(dev->rdev); + ir_raw_event_overflow(dev->rdev); dev_info(dev->dev, "IR RX overrun\n"); writel(IRB_RX_OVERRUN_INT, dev->rx_base + IRB_RX_INT_CLEAR); @@ -138,12 +135,12 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) mark /= dev->sample_div; } - ev.duration = US_TO_NS(mark); + ev.duration = mark; ev.pulse = true; ir_raw_event_store(dev->rdev, &ev); if (!last_symbol) { - ev.duration = US_TO_NS(symbol); + ev.duration = symbol; ev.pulse = false; ir_raw_event_store(dev->rdev, &ev); } else { @@ -161,8 +158,9 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) return IRQ_HANDLED; } -static void st_rc_hardware_init(struct st_rc_device *dev) +static int st_rc_hardware_init(struct st_rc_device *dev) { + int ret; int baseclock, freqdiff; unsigned int rx_max_symbol_per = MAX_SYMB_TIME; unsigned int rx_sampling_freq_div; @@ -170,7 +168,12 @@ static void st_rc_hardware_init(struct st_rc_device *dev) /* Enable the IP */ reset_control_deassert(dev->rstc); - clk_prepare_enable(dev->sys_clock); + ret = clk_prepare_enable(dev->sys_clock); + if (ret) { + dev_err(dev->dev, "Failed to prepare/enable system clock\n"); + return ret; + } + baseclock = clk_get_rate(dev->sys_clock); /* IRB input pins are inverted internally from high to low. */ @@ -188,9 +191,11 @@ static void st_rc_hardware_init(struct st_rc_device *dev) } writel(rx_max_symbol_per, dev->rx_base + IRB_MAX_SYM_PERIOD); + + return 0; } -static int st_rc_remove(struct platform_device *pdev) +static void st_rc_remove(struct platform_device *pdev) { struct st_rc_device *rc_dev = platform_get_drvdata(pdev); @@ -198,7 +203,6 @@ static int st_rc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, false); clk_disable_unprepare(rc_dev->sys_clock); rc_unregister_device(rc_dev->rdev); - return 0; } static int st_rc_open(struct rc_dev *rdev) @@ -227,7 +231,6 @@ static int st_rc_probe(struct platform_device *pdev) int ret = -EINVAL; struct rc_dev *rdev; struct device *dev = &pdev->dev; - struct resource *res; struct st_rc_device *rc_dev; struct device_node *np = pdev->dev.of_node; const char *rx_mode; @@ -270,9 +273,7 @@ static int st_rc_probe(struct platform_device *pdev) goto err; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - rc_dev->base = devm_ioremap_resource(dev, res); + rc_dev->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rc_dev->base)) { ret = PTR_ERR(rc_dev->base); goto err; @@ -283,7 +284,7 @@ static int st_rc_probe(struct platform_device *pdev) else rc_dev->rx_base = rc_dev->base; - rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); + rc_dev->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(rc_dev->rstc)) { ret = PTR_ERR(rc_dev->rstc); goto err; @@ -291,12 +292,14 @@ static int st_rc_probe(struct platform_device *pdev) rc_dev->dev = dev; platform_set_drvdata(pdev, rc_dev); - st_rc_hardware_init(rc_dev); + ret = st_rc_hardware_init(rc_dev); + if (ret) + goto err; rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* rx sampling rate is 10Mhz */ rdev->rx_resolution = 100; - rdev->timeout = US_TO_NS(MAX_SYMB_TIME); + rdev->timeout = MAX_SYMB_TIME; rdev->priv = rc_dev; rdev->open = st_rc_open; rdev->close = st_rc_close; @@ -363,6 +366,7 @@ static int st_rc_suspend(struct device *dev) static int st_rc_resume(struct device *dev) { + int ret; struct st_rc_device *rc_dev = dev_get_drvdata(dev); struct rc_dev *rdev = rc_dev->rdev; @@ -371,7 +375,10 @@ static int st_rc_resume(struct device *dev) rc_dev->irq_wake = 0; } else { pinctrl_pm_select_default_state(dev); - st_rc_hardware_init(rc_dev); + ret = st_rc_hardware_init(rc_dev); + if (ret) + return ret; + if (rdev->users) { writel(IRB_RX_INTS, rc_dev->rx_base + IRB_RX_INT_EN); writel(0x01, rc_dev->rx_base + IRB_RX_EN); |
