Commit 78223354 authored by Jason Cooper's avatar Jason Cooper

Merge branch 'irqchip/renesas' into irqchip/core

parents 2a6c0f0a 6f46aedb
...@@ -4,7 +4,7 @@ Required properties: ...@@ -4,7 +4,7 @@ Required properties:
- compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. - compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback.
Examples with soctypes are: Examples with soctypes are:
- "renesas,irqc-r8a73a4" (R-Mobile AP6) - "renesas,irqc-r8a73a4" (R-Mobile APE6)
- "renesas,irqc-r8a7790" (R-Car H2) - "renesas,irqc-r8a7790" (R-Car H2)
- "renesas,irqc-r8a7791" (R-Car M2-W) - "renesas,irqc-r8a7791" (R-Car M2-W)
- "renesas,irqc-r8a7792" (R-Car V2H) - "renesas,irqc-r8a7792" (R-Car V2H)
...@@ -12,6 +12,7 @@ Required properties: ...@@ -12,6 +12,7 @@ Required properties:
- "renesas,irqc-r8a7794" (R-Car E2) - "renesas,irqc-r8a7794" (R-Car E2)
- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
interrupts.txt in this directory interrupts.txt in this directory
- clocks: Must contain a reference to the functional clock.
Optional properties: Optional properties:
...@@ -29,4 +30,5 @@ Example: ...@@ -29,4 +30,5 @@ Example:
<0 1 IRQ_TYPE_LEVEL_HIGH>, <0 1 IRQ_TYPE_LEVEL_HIGH>,
<0 2 IRQ_TYPE_LEVEL_HIGH>, <0 2 IRQ_TYPE_LEVEL_HIGH>,
<0 3 IRQ_TYPE_LEVEL_HIGH>; <0 3 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp4_clks R8A7790_CLK_IRQC>;
}; };
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/clk.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -29,15 +30,26 @@ ...@@ -29,15 +30,26 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/irq-renesas-irqc.h> #include <linux/platform_data/irq-renesas-irqc.h>
#include <linux/pm_runtime.h>
#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */
#define IRQC_REQ_STS 0x00 #define IRQC_REQ_STS 0x00 /* Interrupt Request Status Register */
#define IRQC_EN_STS 0x04 #define IRQC_EN_STS 0x04 /* Interrupt Enable Status Register */
#define IRQC_EN_SET 0x08 #define IRQC_EN_SET 0x08 /* Interrupt Enable Set Register */
#define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) #define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10))
#define DETECT_STATUS 0x100 /* SYS-CPU vs. RT-CPU */
#define DETECT_STATUS 0x100 /* IRQn Detect Status Register */
#define MONITOR 0x104 /* IRQn Signal Level Monitor Register */
#define HLVL_STS 0x108 /* IRQn High Level Detect Status Register */
#define LLVL_STS 0x10c /* IRQn Low Level Detect Status Register */
#define S_R_EDGE_STS 0x110 /* IRQn Sync Rising Edge Detect Status Reg. */
#define S_F_EDGE_STS 0x114 /* IRQn Sync Falling Edge Detect Status Reg. */
#define A_R_EDGE_STS 0x118 /* IRQn Async Rising Edge Detect Status Reg. */
#define A_F_EDGE_STS 0x11c /* IRQn Async Falling Edge Detect Status Reg. */
#define CHTEN_STS 0x120 /* Chattering Reduction Status Register */
#define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) #define IRQC_CONFIG(n) (0x180 + ((n) * 0x04))
/* IRQn Configuration Register */
struct irqc_irq { struct irqc_irq {
int hw_irq; int hw_irq;
...@@ -55,6 +67,7 @@ struct irqc_priv { ...@@ -55,6 +67,7 @@ struct irqc_priv {
struct platform_device *pdev; struct platform_device *pdev;
struct irq_chip irq_chip; struct irq_chip irq_chip;
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct clk *clk;
}; };
static void irqc_dbg(struct irqc_irq *i, char *str) static void irqc_dbg(struct irqc_irq *i, char *str)
...@@ -108,6 +121,21 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -108,6 +121,21 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type)
return 0; return 0;
} }
static int irqc_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct irqc_priv *p = irq_data_get_irq_chip_data(d);
if (!p->clk)
return 0;
if (on)
clk_enable(p->clk);
else
clk_disable(p->clk);
return 0;
}
static irqreturn_t irqc_irq_handler(int irq, void *dev_id) static irqreturn_t irqc_irq_handler(int irq, void *dev_id)
{ {
struct irqc_irq *i = dev_id; struct irqc_irq *i = dev_id;
...@@ -170,6 +198,15 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -170,6 +198,15 @@ static int irqc_probe(struct platform_device *pdev)
p->pdev = pdev; p->pdev = pdev;
platform_set_drvdata(pdev, p); platform_set_drvdata(pdev, p);
p->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(p->clk)) {
dev_warn(&pdev->dev, "unable to get clock\n");
p->clk = NULL;
}
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
/* get hold of manadatory IOMEM */ /* get hold of manadatory IOMEM */
io = platform_get_resource(pdev, IORESOURCE_MEM, 0); io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!io) { if (!io) {
...@@ -210,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -210,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev)
irq_chip->irq_mask = irqc_irq_disable; irq_chip->irq_mask = irqc_irq_disable;
irq_chip->irq_unmask = irqc_irq_enable; irq_chip->irq_unmask = irqc_irq_enable;
irq_chip->irq_set_type = irqc_irq_set_type; irq_chip->irq_set_type = irqc_irq_set_type;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; irq_chip->irq_set_wake = irqc_irq_set_wake;
irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
p->number_of_irqs, p->number_of_irqs,
...@@ -250,6 +288,8 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -250,6 +288,8 @@ static int irqc_probe(struct platform_device *pdev)
err2: err2:
iounmap(p->iomem); iounmap(p->iomem);
err1: err1:
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
kfree(p); kfree(p);
err0: err0:
return ret; return ret;
...@@ -265,6 +305,8 @@ static int irqc_remove(struct platform_device *pdev) ...@@ -265,6 +305,8 @@ static int irqc_remove(struct platform_device *pdev)
irq_domain_remove(p->irq_domain); irq_domain_remove(p->irq_domain);
iounmap(p->iomem); iounmap(p->iomem);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
kfree(p); kfree(p);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment