Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c5455f70
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c5455f70
编写于
3月 30, 2015
作者:
S
Shawn Guo
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'jcooper/irqchip/vybrid' into imx/dt
上级
40cb1981
4a073175
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
261 addition
and
0 deletion
+261
-0
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt
...vicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt
+14
-0
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt
...n/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt
+33
-0
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Kconfig
+1
-0
drivers/irqchip/Makefile
drivers/irqchip/Makefile
+1
-0
drivers/irqchip/irq-vf610-mscm-ir.c
drivers/irqchip/irq-vf610-mscm-ir.c
+212
-0
未找到文件。
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt
0 → 100644
浏览文件 @
c5455f70
Freescale Vybrid Miscellaneous System Control - CPU Configuration
The MSCM IP contains multiple sub modules, this binding describes the first
block of registers which contains CPU configuration information.
Required properties:
- compatible: "fsl,vf610-mscm-cpucfg", "syscon"
- reg: the register range of the MSCM CPU configuration registers
Example:
mscm_cpucfg: cpucfg@40001000 {
compatible = "fsl,vf610-mscm-cpucfg", "syscon";
reg = <0x40001000 0x800>;
}
Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt
0 → 100644
浏览文件 @
c5455f70
Freescale Vybrid Miscellaneous System Control - Interrupt Router
The MSCM IP contains multiple sub modules, this binding describes the second
block of registers which control the interrupt router. The interrupt router
allows to configure the recipient of each peripheral interrupt. Furthermore
it controls the directed processor interrupts. The module is available in all
Vybrid SoC's but is only really useful in dual core configurations (VF6xx
which comes with a Cortex-A5/Cortex-M4 combination).
Required properties:
- compatible: "fsl,vf610-mscm-ir"
- reg: the register range of the MSCM Interrupt Router
- fsl,cpucfg: The handle to the MSCM CPU configuration node, required
to get the current CPU ID
- interrupt-controller: Identifies the node as an interrupt controller
- #interrupt-cells: Two cells, interrupt number and cells.
The hardware interrupt number according to interrupt
assignment of the interrupt router is required.
Flags get passed only when using GIC as parent. Flags
encoding as documented by the GIC bindings.
- interrupt-parent: Should be the phandle for the interrupt controller of
the CPU the device tree is intended to be used on. This
is either the node of the GIC or NVIC controller.
Example:
mscm_ir: interrupt-controller@40001800 {
compatible = "fsl,vf610-mscm-ir";
reg = <0x40001800 0x400>;
fsl,cpucfg = <&mscm_cpucfg>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
}
arch/arm/mach-imx/Kconfig
浏览文件 @
c5455f70
...
...
@@ -584,6 +584,7 @@ config SOC_IMX6SX
config SOC_VF610
bool "Vybrid Family VF610 support"
select IRQ_DOMAIN_HIERARCHY
select ARM_GIC
select PINCTRL_VF610
select PL310_ERRATA_769419 if CACHE_L2X0
...
...
drivers/irqchip/Makefile
浏览文件 @
c5455f70
...
...
@@ -37,6 +37,7 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
obj-$(CONFIG_XTENSA)
+=
irq-xtensa-pic.o
obj-$(CONFIG_XTENSA_MX)
+=
irq-xtensa-mx.o
obj-$(CONFIG_IRQ_CROSSBAR)
+=
irq-crossbar.o
obj-$(CONFIG_SOC_VF610)
+=
irq-vf610-mscm-ir.o
obj-$(CONFIG_BCM7120_L2_IRQ)
+=
irq-bcm7120-l2.o
obj-$(CONFIG_BRCMSTB_L2_IRQ)
+=
irq-brcmstb-l2.o
obj-$(CONFIG_KEYSTONE_IRQ)
+=
irq-keystone.o
...
...
drivers/irqchip/irq-vf610-mscm-ir.c
0 → 100644
浏览文件 @
c5455f70
/*
* Copyright (C) 2014-2015 Toradex AG
* Author: Stefan Agner <stefan@agner.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*
* IRQ chip driver for MSCM interrupt router available on Vybrid SoC's.
* The interrupt router is between the CPU's interrupt controller and the
* peripheral. The router allows to route the peripheral interrupts to
* one of the two available CPU's on Vybrid VF6xx SoC's (Cortex-A5 or
* Cortex-M4). The router will be configured transparently on a IRQ
* request.
*
* o All peripheral interrupts of the Vybrid SoC can be routed to
* CPU 0, CPU 1 or both. The routing is useful for dual-core
* variants of Vybrid SoC such as VF6xx. This driver routes the
* requested interrupt to the CPU currently running on.
*
* o It is required to setup the interrupt router even on single-core
* variants of Vybrid.
*/
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/mfd/syscon.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include "irqchip.h"
#define MSCM_CPxNUM 0x4
#define MSCM_IRSPRC(n) (0x80 + 2 * (n))
#define MSCM_IRSPRC_CPEN_MASK 0x3
#define MSCM_IRSPRC_NUM 112
struct
vf610_mscm_ir_chip_data
{
void
__iomem
*
mscm_ir_base
;
u16
cpu_mask
;
u16
saved_irsprc
[
MSCM_IRSPRC_NUM
];
};
static
struct
vf610_mscm_ir_chip_data
*
mscm_ir_data
;
static
inline
void
vf610_mscm_ir_save
(
struct
vf610_mscm_ir_chip_data
*
data
)
{
int
i
;
for
(
i
=
0
;
i
<
MSCM_IRSPRC_NUM
;
i
++
)
data
->
saved_irsprc
[
i
]
=
readw_relaxed
(
data
->
mscm_ir_base
+
MSCM_IRSPRC
(
i
));
}
static
inline
void
vf610_mscm_ir_restore
(
struct
vf610_mscm_ir_chip_data
*
data
)
{
int
i
;
for
(
i
=
0
;
i
<
MSCM_IRSPRC_NUM
;
i
++
)
writew_relaxed
(
data
->
saved_irsprc
[
i
],
data
->
mscm_ir_base
+
MSCM_IRSPRC
(
i
));
}
static
int
vf610_mscm_ir_notifier
(
struct
notifier_block
*
self
,
unsigned
long
cmd
,
void
*
v
)
{
switch
(
cmd
)
{
case
CPU_CLUSTER_PM_ENTER
:
vf610_mscm_ir_save
(
mscm_ir_data
);
break
;
case
CPU_CLUSTER_PM_ENTER_FAILED
:
case
CPU_CLUSTER_PM_EXIT
:
vf610_mscm_ir_restore
(
mscm_ir_data
);
break
;
}
return
NOTIFY_OK
;
}
static
struct
notifier_block
mscm_ir_notifier_block
=
{
.
notifier_call
=
vf610_mscm_ir_notifier
,
};
static
void
vf610_mscm_ir_enable
(
struct
irq_data
*
data
)
{
irq_hw_number_t
hwirq
=
data
->
hwirq
;
struct
vf610_mscm_ir_chip_data
*
chip_data
=
data
->
chip_data
;
u16
irsprc
;
irsprc
=
readw_relaxed
(
chip_data
->
mscm_ir_base
+
MSCM_IRSPRC
(
hwirq
));
irsprc
&=
MSCM_IRSPRC_CPEN_MASK
;
WARN_ON
(
irsprc
&
~
chip_data
->
cpu_mask
);
writew_relaxed
(
chip_data
->
cpu_mask
,
chip_data
->
mscm_ir_base
+
MSCM_IRSPRC
(
hwirq
));
irq_chip_unmask_parent
(
data
);
}
static
void
vf610_mscm_ir_disable
(
struct
irq_data
*
data
)
{
irq_hw_number_t
hwirq
=
data
->
hwirq
;
struct
vf610_mscm_ir_chip_data
*
chip_data
=
data
->
chip_data
;
writew_relaxed
(
0x0
,
chip_data
->
mscm_ir_base
+
MSCM_IRSPRC
(
hwirq
));
irq_chip_mask_parent
(
data
);
}
static
struct
irq_chip
vf610_mscm_ir_irq_chip
=
{
.
name
=
"mscm-ir"
,
.
irq_mask
=
irq_chip_mask_parent
,
.
irq_unmask
=
irq_chip_unmask_parent
,
.
irq_eoi
=
irq_chip_eoi_parent
,
.
irq_enable
=
vf610_mscm_ir_enable
,
.
irq_disable
=
vf610_mscm_ir_disable
,
.
irq_retrigger
=
irq_chip_retrigger_hierarchy
,
.
irq_set_affinity
=
irq_chip_set_affinity_parent
,
};
static
int
vf610_mscm_ir_domain_alloc
(
struct
irq_domain
*
domain
,
unsigned
int
virq
,
unsigned
int
nr_irqs
,
void
*
arg
)
{
int
i
;
irq_hw_number_t
hwirq
;
struct
of_phandle_args
*
irq_data
=
arg
;
struct
of_phandle_args
gic_data
;
if
(
irq_data
->
args_count
!=
2
)
return
-
EINVAL
;
hwirq
=
irq_data
->
args
[
0
];
for
(
i
=
0
;
i
<
nr_irqs
;
i
++
)
irq_domain_set_hwirq_and_chip
(
domain
,
virq
+
i
,
hwirq
+
i
,
&
vf610_mscm_ir_irq_chip
,
domain
->
host_data
);
gic_data
.
np
=
domain
->
parent
->
of_node
;
gic_data
.
args_count
=
3
;
gic_data
.
args
[
0
]
=
GIC_SPI
;
gic_data
.
args
[
1
]
=
irq_data
->
args
[
0
];
gic_data
.
args
[
2
]
=
irq_data
->
args
[
1
];
return
irq_domain_alloc_irqs_parent
(
domain
,
virq
,
nr_irqs
,
&
gic_data
);
}
static
const
struct
irq_domain_ops
mscm_irq_domain_ops
=
{
.
xlate
=
irq_domain_xlate_twocell
,
.
alloc
=
vf610_mscm_ir_domain_alloc
,
.
free
=
irq_domain_free_irqs_common
,
};
static
int
__init
vf610_mscm_ir_of_init
(
struct
device_node
*
node
,
struct
device_node
*
parent
)
{
struct
irq_domain
*
domain
,
*
domain_parent
;
struct
regmap
*
mscm_cp_regmap
;
int
ret
,
cpuid
;
domain_parent
=
irq_find_host
(
parent
);
if
(
!
domain_parent
)
{
pr_err
(
"vf610_mscm_ir: interrupt-parent not found
\n
"
);
return
-
EINVAL
;
}
mscm_ir_data
=
kzalloc
(
sizeof
(
*
mscm_ir_data
),
GFP_KERNEL
);
if
(
!
mscm_ir_data
)
return
-
ENOMEM
;
mscm_ir_data
->
mscm_ir_base
=
of_io_request_and_map
(
node
,
0
,
"mscm-ir"
);
if
(
!
mscm_ir_data
->
mscm_ir_base
)
{
pr_err
(
"vf610_mscm_ir: unable to map mscm register
\n
"
);
ret
=
-
ENOMEM
;
goto
out_free
;
}
mscm_cp_regmap
=
syscon_regmap_lookup_by_phandle
(
node
,
"fsl,cpucfg"
);
if
(
IS_ERR
(
mscm_cp_regmap
))
{
ret
=
PTR_ERR
(
mscm_cp_regmap
);
pr_err
(
"vf610_mscm_ir: regmap lookup for cpucfg failed
\n
"
);
goto
out_unmap
;
}
regmap_read
(
mscm_cp_regmap
,
MSCM_CPxNUM
,
&
cpuid
);
mscm_ir_data
->
cpu_mask
=
0x1
<<
cpuid
;
domain
=
irq_domain_add_hierarchy
(
domain_parent
,
0
,
MSCM_IRSPRC_NUM
,
node
,
&
mscm_irq_domain_ops
,
mscm_ir_data
);
if
(
!
domain
)
{
ret
=
-
ENOMEM
;
goto
out_unmap
;
}
cpu_pm_register_notifier
(
&
mscm_ir_notifier_block
);
return
0
;
out_unmap:
iounmap
(
mscm_ir_data
->
mscm_ir_base
);
out_free:
kfree
(
mscm_ir_data
);
return
ret
;
}
IRQCHIP_DECLARE
(
vf610_mscm_ir
,
"fsl,vf610-mscm-ir"
,
vf610_mscm_ir_of_init
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录