mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 13:16:41 +00:00
Allwinner: linux: add CIR PM patches
This commit is contained in:
parent
161a75a994
commit
d9ea55a79c
@ -0,0 +1,104 @@
|
||||
From 371443de3c991f7b025d5203754a3497b7ea7c32 Mon Sep 17 00:00:00 2001
|
||||
From: Sean Young <sean@mess.org>
|
||||
Date: Tue, 10 Nov 2020 09:30:38 +0100
|
||||
Subject: [PATCH] media: sunxi-cir: allow timeout to be set at runtime
|
||||
|
||||
This allows the timeout to be set with the LIRC_SET_REC_TIMEOUT ioctl.
|
||||
|
||||
The timeout was hardcoded at just over 20ms, but returned 120ms when
|
||||
queried with the LIRC_GET_REC_TIMEOUT ioctl.
|
||||
|
||||
This also ensures the idle threshold is set correctly with a base clock
|
||||
other than 8Mhz.
|
||||
|
||||
Acked-by: Maxime Ripard <mripard@kernel.org>
|
||||
Signed-off-by: Sean Young <sean@mess.org>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 48 ++++++++++++++++++++++++++++++------
|
||||
1 file changed, 40 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
|
||||
index 4afc5895bee7..8555c7798706 100644
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -73,10 +73,6 @@
|
||||
#define SUNXI_IR_BASE_CLK 8000000
|
||||
/* Noise threshold in samples */
|
||||
#define SUNXI_IR_RXNOISE 1
|
||||
-/* Idle Threshold in samples */
|
||||
-#define SUNXI_IR_RXIDLE 20
|
||||
-/* Time after which device stops sending data in ms */
|
||||
-#define SUNXI_IR_TIMEOUT 120
|
||||
|
||||
/**
|
||||
* struct sunxi_ir_quirks - Differences between SoC variants.
|
||||
@@ -146,6 +142,41 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+/* Convert idle threshold to usec */
|
||||
+static unsigned int sunxi_ithr_to_usec(unsigned int base_clk, unsigned int ithr)
|
||||
+{
|
||||
+ return DIV_ROUND_CLOSEST(USEC_PER_SEC * (ithr + 1),
|
||||
+ base_clk / (128 * 64));
|
||||
+}
|
||||
+
|
||||
+/* Convert usec to idle threshold */
|
||||
+static unsigned int sunxi_usec_to_ithr(unsigned int base_clk, unsigned int usec)
|
||||
+{
|
||||
+ /* make sure we don't end up with a timeout less than requested */
|
||||
+ return DIV_ROUND_UP((base_clk / (128 * 64)) * usec, USEC_PER_SEC) - 1;
|
||||
+}
|
||||
+
|
||||
+static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = rc_dev->priv;
|
||||
+ unsigned int base_clk = clk_get_rate(ir->clk);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
|
||||
+
|
||||
+ dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
|
||||
+
|
||||
+ spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
+ /* Set noise threshold and idle threshold */
|
||||
+ writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
|
||||
+ ir->base + SUNXI_IR_CIR_REG);
|
||||
+ spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
+
|
||||
+ rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -242,9 +273,11 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
|
||||
ir->rc->dev.parent = dev;
|
||||
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
||||
- /* Frequency after IR internal divider with sample period in ns */
|
||||
+ /* Frequency after IR internal divider with sample period in us */
|
||||
ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
|
||||
- ir->rc->timeout = MS_TO_US(SUNXI_IR_TIMEOUT);
|
||||
+ ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0);
|
||||
+ ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255);
|
||||
+ ir->rc->s_timeout = sunxi_ir_set_timeout;
|
||||
ir->rc->driver_name = SUNXI_IR_DEV;
|
||||
|
||||
ret = rc_register_device(ir->rc);
|
||||
@@ -272,8 +305,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
|
||||
|
||||
/* Set noise threshold and idle threshold */
|
||||
- writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
|
||||
- ir->base + SUNXI_IR_CIR_REG);
|
||||
+ sunxi_ir_set_timeout(ir->rc, IR_DEFAULT_TIMEOUT);
|
||||
|
||||
/* Invert Input Signal */
|
||||
writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 0d476c62bcc132f66dc69342c2a90bba6d7128fe Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:41:23 -0600
|
||||
Subject: [PATCH 1/4] media: sunxi-cir: Skip register writes during remove
|
||||
|
||||
These writes occur after the device is already put back in reset, so
|
||||
they never had any effect.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
|
||||
index 8555c7798706..0a7f7eab3cc3 100644
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -342,22 +342,12 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
|
||||
static int sunxi_ir_remove(struct platform_device *pdev)
|
||||
{
|
||||
- unsigned long flags;
|
||||
struct sunxi_ir *ir = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(ir->clk);
|
||||
clk_disable_unprepare(ir->apb_clk);
|
||||
reset_control_assert(ir->rst);
|
||||
|
||||
- spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
- /* disable IR IRQ */
|
||||
- writel(0, ir->base + SUNXI_IR_RXINT_REG);
|
||||
- /* clear All Rx Interrupt Status */
|
||||
- writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
- /* disable IR */
|
||||
- writel(0, ir->base + SUNXI_IR_CTL_REG);
|
||||
- spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
-
|
||||
rc_unregister_device(ir->rc);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,74 @@
|
||||
From c7bc741a2aec36d9f87a99ef098db88825d5ef79 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:43:19 -0600
|
||||
Subject: [PATCH 2/4] media: sunxi-cir: Remove unnecessary spinlock
|
||||
|
||||
Only one register, SUNXI_IR_CIR_REG, is written from outside the
|
||||
interrupt handler, and that register is not written from inside it.
|
||||
There is no overlap between different contexts, so no lock is needed.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
|
||||
index 0a7f7eab3cc3..48be400421cd 100644
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -86,7 +86,6 @@ struct sunxi_ir_quirks {
|
||||
};
|
||||
|
||||
struct sunxi_ir {
|
||||
- spinlock_t ir_lock;
|
||||
struct rc_dev *rc;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
@@ -105,8 +104,6 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
|
||||
struct sunxi_ir *ir = dev_id;
|
||||
struct ir_raw_event rawir = {};
|
||||
|
||||
- spin_lock(&ir->ir_lock);
|
||||
-
|
||||
status = readl(ir->base + SUNXI_IR_RXSTA_REG);
|
||||
|
||||
/* clean all pending statuses */
|
||||
@@ -137,8 +134,6 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
|
||||
ir_raw_event_handle(ir->rc);
|
||||
}
|
||||
|
||||
- spin_unlock(&ir->ir_lock);
|
||||
-
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -160,17 +155,14 @@ static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
|
||||
{
|
||||
struct sunxi_ir *ir = rc_dev->priv;
|
||||
unsigned int base_clk = clk_get_rate(ir->clk);
|
||||
- unsigned long flags;
|
||||
|
||||
unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
|
||||
|
||||
dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
|
||||
|
||||
- spin_lock_irqsave(&ir->ir_lock, flags);
|
||||
/* Set noise threshold and idle threshold */
|
||||
writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
|
||||
ir->base + SUNXI_IR_CIR_REG);
|
||||
- spin_unlock_irqrestore(&ir->ir_lock, flags);
|
||||
|
||||
rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
|
||||
|
||||
@@ -199,8 +191,6 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- spin_lock_init(&ir->ir_lock);
|
||||
-
|
||||
ir->fifo_size = quirks->fifo_size;
|
||||
|
||||
/* Clock */
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,228 @@
|
||||
From c0009aa415ef085c8f31ddd68b873f195a77f3c4 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:50:32 -0600
|
||||
Subject: [PATCH 3/4] media: sunxi-cir: Factor out hardware initialization
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 142 ++++++++++++++++++++---------------
|
||||
1 file changed, 82 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
|
||||
index 48be400421cd..1047654e601b 100644
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -90,6 +90,7 @@ struct sunxi_ir {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
int fifo_size;
|
||||
+ u32 base_clk_freq;
|
||||
struct clk *clk;
|
||||
struct clk *apb_clk;
|
||||
struct reset_control *rst;
|
||||
@@ -169,10 +170,81 @@ static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sunxi_ir_hw_init(struct device *dev)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = dev_get_drvdata(dev);
|
||||
+ unsigned long tmp;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = reset_control_deassert(ir->rst);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_set_rate(ir->clk, ir->base_clk_freq);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "set ir base clock failed!\n");
|
||||
+ goto exit_reset_assert;
|
||||
+ }
|
||||
+ dev_dbg(dev, "set base clock frequency to %d Hz.\n", ir->base_clk_freq);
|
||||
+
|
||||
+ if (clk_prepare_enable(ir->apb_clk)) {
|
||||
+ dev_err(dev, "try to enable apb_ir_clk failed\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit_reset_assert;
|
||||
+ }
|
||||
+
|
||||
+ if (clk_prepare_enable(ir->clk)) {
|
||||
+ dev_err(dev, "try to enable ir_clk failed\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit_apb_clk_disable;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable CIR Mode */
|
||||
+ writel(REG_CTL_MD, ir->base + SUNXI_IR_CTL_REG);
|
||||
+
|
||||
+ /* Set noise threshold and idle threshold */
|
||||
+ sunxi_ir_set_timeout(ir->rc, ir->rc->timeout);
|
||||
+
|
||||
+ /* Invert Input Signal */
|
||||
+ writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
||||
+
|
||||
+ /* Clear All Rx Interrupt Status */
|
||||
+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
+
|
||||
+ /*
|
||||
+ * Enable IRQ on overflow, packet end, FIFO available with trigger
|
||||
+ * level
|
||||
+ */
|
||||
+ writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
|
||||
+ REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
|
||||
+ ir->base + SUNXI_IR_RXINT_REG);
|
||||
+
|
||||
+ /* Enable IR Module */
|
||||
+ tmp = readl(ir->base + SUNXI_IR_CTL_REG);
|
||||
+ writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+exit_apb_clk_disable:
|
||||
+ clk_disable_unprepare(ir->apb_clk);
|
||||
+exit_reset_assert:
|
||||
+ reset_control_assert(ir->rst);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void sunxi_ir_hw_exit(struct device *dev)
|
||||
+{
|
||||
+ struct sunxi_ir *ir = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_disable_unprepare(ir->clk);
|
||||
+ clk_disable_unprepare(ir->apb_clk);
|
||||
+ reset_control_assert(ir->rst);
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
- unsigned long tmp = 0;
|
||||
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dn = dev->of_node;
|
||||
@@ -207,49 +279,26 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
|
||||
/* Base clock frequency (optional) */
|
||||
of_property_read_u32(dn, "clock-frequency", &b_clk_freq);
|
||||
+ ir->base_clk_freq = b_clk_freq;
|
||||
|
||||
/* Reset */
|
||||
if (quirks->has_reset) {
|
||||
ir->rst = devm_reset_control_get_exclusive(dev, NULL);
|
||||
if (IS_ERR(ir->rst))
|
||||
return PTR_ERR(ir->rst);
|
||||
- ret = reset_control_deassert(ir->rst);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- ret = clk_set_rate(ir->clk, b_clk_freq);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "set ir base clock failed!\n");
|
||||
- goto exit_reset_assert;
|
||||
- }
|
||||
- dev_dbg(dev, "set base clock frequency to %d Hz.\n", b_clk_freq);
|
||||
-
|
||||
- if (clk_prepare_enable(ir->apb_clk)) {
|
||||
- dev_err(dev, "try to enable apb_ir_clk failed\n");
|
||||
- ret = -EINVAL;
|
||||
- goto exit_reset_assert;
|
||||
- }
|
||||
-
|
||||
- if (clk_prepare_enable(ir->clk)) {
|
||||
- dev_err(dev, "try to enable ir_clk failed\n");
|
||||
- ret = -EINVAL;
|
||||
- goto exit_clkdisable_apb_clk;
|
||||
}
|
||||
|
||||
/* IO */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ir->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(ir->base)) {
|
||||
- ret = PTR_ERR(ir->base);
|
||||
- goto exit_clkdisable_clk;
|
||||
+ return PTR_ERR(ir->base);
|
||||
}
|
||||
|
||||
ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||||
if (!ir->rc) {
|
||||
dev_err(dev, "failed to allocate device\n");
|
||||
- ret = -ENOMEM;
|
||||
- goto exit_clkdisable_clk;
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
ir->rc->priv = ir;
|
||||
@@ -265,6 +314,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
||||
/* Frequency after IR internal divider with sample period in us */
|
||||
ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
|
||||
+ ir->rc->timeout = IR_DEFAULT_TIMEOUT;
|
||||
ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0);
|
||||
ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255);
|
||||
ir->rc->s_timeout = sunxi_ir_set_timeout;
|
||||
@@ -291,41 +341,15 @@ static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
goto exit_free_dev;
|
||||
}
|
||||
|
||||
- /* Enable CIR Mode */
|
||||
- writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
|
||||
-
|
||||
- /* Set noise threshold and idle threshold */
|
||||
- sunxi_ir_set_timeout(ir->rc, IR_DEFAULT_TIMEOUT);
|
||||
-
|
||||
- /* Invert Input Signal */
|
||||
- writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
|
||||
-
|
||||
- /* Clear All Rx Interrupt Status */
|
||||
- writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
|
||||
-
|
||||
- /*
|
||||
- * Enable IRQ on overflow, packet end, FIFO available with trigger
|
||||
- * level
|
||||
- */
|
||||
- writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
|
||||
- REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
|
||||
- ir->base + SUNXI_IR_RXINT_REG);
|
||||
-
|
||||
- /* Enable IR Module */
|
||||
- tmp = readl(ir->base + SUNXI_IR_CTL_REG);
|
||||
- writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);
|
||||
+ ret = sunxi_ir_hw_init(dev);
|
||||
+ if (ret)
|
||||
+ goto exit_free_dev;
|
||||
|
||||
dev_info(dev, "initialized sunXi IR driver\n");
|
||||
return 0;
|
||||
|
||||
exit_free_dev:
|
||||
rc_free_device(ir->rc);
|
||||
-exit_clkdisable_clk:
|
||||
- clk_disable_unprepare(ir->clk);
|
||||
-exit_clkdisable_apb_clk:
|
||||
- clk_disable_unprepare(ir->apb_clk);
|
||||
-exit_reset_assert:
|
||||
- reset_control_assert(ir->rst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -334,11 +358,9 @@ static int sunxi_ir_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sunxi_ir *ir = platform_get_drvdata(pdev);
|
||||
|
||||
- clk_disable_unprepare(ir->clk);
|
||||
- clk_disable_unprepare(ir->apb_clk);
|
||||
- reset_control_assert(ir->rst);
|
||||
-
|
||||
+ sunxi_ir_hw_exit(&pdev->dev);
|
||||
rc_unregister_device(ir->rc);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 2f76dd45fb1faf046aaaaddb6021312622002a3d Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Sun, 10 Jan 2021 00:51:31 -0600
|
||||
Subject: [PATCH 4/4] media: sunxi-cir: Implement suspend/resume/shutdown
|
||||
callbacks
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
---
|
||||
drivers/media/rc/sunxi-cir.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
|
||||
index 1047654e601b..4e025f3980f4 100644
|
||||
--- a/drivers/media/rc/sunxi-cir.c
|
||||
+++ b/drivers/media/rc/sunxi-cir.c
|
||||
@@ -242,6 +242,18 @@ static void sunxi_ir_hw_exit(struct device *dev)
|
||||
reset_control_assert(ir->rst);
|
||||
}
|
||||
|
||||
+static int __maybe_unused sunxi_ir_suspend(struct device *dev)
|
||||
+{
|
||||
+ sunxi_ir_hw_exit(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused sunxi_ir_resume(struct device *dev)
|
||||
+{
|
||||
+ return sunxi_ir_hw_init(dev);
|
||||
+}
|
||||
+
|
||||
static int sunxi_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -364,6 +376,11 @@ static int sunxi_ir_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sunxi_ir_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+ sunxi_ir_hw_exit(&pdev->dev);
|
||||
+}
|
||||
+
|
||||
static const struct sunxi_ir_quirks sun4i_a10_ir_quirks = {
|
||||
.has_reset = false,
|
||||
.fifo_size = 16,
|
||||
@@ -396,12 +413,16 @@ static const struct of_device_id sunxi_ir_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunxi_ir_match);
|
||||
|
||||
+static SIMPLE_DEV_PM_OPS(sunxi_ir_pm_ops, sunxi_ir_suspend, sunxi_ir_resume);
|
||||
+
|
||||
static struct platform_driver sunxi_ir_driver = {
|
||||
.probe = sunxi_ir_probe,
|
||||
.remove = sunxi_ir_remove,
|
||||
+ .shutdown = sunxi_ir_shutdown,
|
||||
.driver = {
|
||||
.name = SUNXI_IR_DEV,
|
||||
.of_match_table = sunxi_ir_match,
|
||||
+ .pm = &sunxi_ir_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
2.30.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user