Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
5c008d70
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5c008d70
编写于
10月 01, 2012
作者:
O
Olof Johansson
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next/soc2' into HEAD
上级
5d3a0a95
36246a82
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
112 addition
and
137 deletion
+112
-137
arch/arm/Kconfig
arch/arm/Kconfig
+2
-0
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx23.dtsi
+3
-2
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx28.dtsi
+3
-2
arch/arm/mach-mxs/icoll.c
arch/arm/mach-mxs/icoll.c
+54
-9
arch/arm/mach-mxs/include/mach/common.h
arch/arm/mach-mxs/include/mach/common.h
+2
-1
arch/arm/mach-mxs/include/mach/entry-macro.S
arch/arm/mach-mxs/include/mach/entry-macro.S
+0
-35
arch/arm/mach-mxs/include/mach/irqs.h
arch/arm/mach-mxs/include/mach/irqs.h
+0
-32
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-mxs/mach-mxs.c
+4
-35
arch/arm/mach-mxs/timer.c
arch/arm/mach-mxs/timer.c
+12
-1
drivers/clk/mxs/clk-imx23.c
drivers/clk/mxs/clk-imx23.c
+1
-1
drivers/clk/mxs/clk-imx28.c
drivers/clk/mxs/clk-imx28.c
+1
-1
drivers/gpio/gpio-mxs.c
drivers/gpio/gpio-mxs.c
+30
-18
未找到文件。
arch/arm/Kconfig
浏览文件 @
5c008d70
...
...
@@ -485,7 +485,9 @@ config ARCH_MXS
select CLKSRC_MMIO
select COMMON_CLK
select HAVE_CLK_PREPARE
select MULTI_IRQ_HANDLER
select PINCTRL
select SPARSE_IRQ
select USE_OF
help
Support for Freescale MXS-based family of processors
...
...
arch/arm/boot/dts/imx23.dtsi
浏览文件 @
5c008d70
...
...
@@ -43,7 +43,7 @@
ranges;
icoll: interrupt-controller@80000000 {
compatible = "fsl,imx23-icoll", "fsl,
mxs-
icoll";
compatible = "fsl,imx23-icoll", "fsl,icoll";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x80000000 0x2000>;
...
...
@@ -407,8 +407,9 @@
};
timrot@80068000 {
compatible = "fsl,imx23-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
status = "disabled"
;
interrupts = <28 29 30 31>
;
};
auart0: serial@8006c000 {
...
...
arch/arm/boot/dts/imx28.dtsi
浏览文件 @
5c008d70
...
...
@@ -52,7 +52,7 @@
ranges;
icoll: interrupt-controller@80000000 {
compatible = "fsl,imx28-icoll", "fsl,
mxs-
icoll";
compatible = "fsl,imx28-icoll", "fsl,icoll";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x80000000 0x2000>;
...
...
@@ -787,8 +787,9 @@
};
timrot@80068000 {
compatible = "fsl,imx28-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
status = "disabled"
;
interrupts = <48 49 50 51>
;
};
auart0: serial@8006a000 {
...
...
arch/arm/mach-mxs/icoll.c
浏览文件 @
5c008d70
...
...
@@ -19,20 +19,27 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <asm/exception.h>
#include <mach/mxs.h>
#include <mach/common.h>
#define HW_ICOLL_VECTOR 0x0000
#define HW_ICOLL_LEVELACK 0x0010
#define HW_ICOLL_CTRL 0x0020
#define HW_ICOLL_STAT_OFFSET 0x0070
#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
#define ICOLL_NUM_IRQS 128
static
void
__iomem
*
icoll_base
=
MXS_IO_ADDRESS
(
MXS_ICOLL_BASE_ADDR
);
static
struct
irq_domain
*
icoll_domain
;
static
void
icoll_ack_irq
(
struct
irq_data
*
d
)
{
...
...
@@ -48,13 +55,13 @@ static void icoll_ack_irq(struct irq_data *d)
static
void
icoll_mask_irq
(
struct
irq_data
*
d
)
{
__raw_writel
(
BM_ICOLL_INTERRUPTn_ENABLE
,
icoll_base
+
HW_ICOLL_INTERRUPTn_CLR
(
d
->
irq
));
icoll_base
+
HW_ICOLL_INTERRUPTn_CLR
(
d
->
hw
irq
));
}
static
void
icoll_unmask_irq
(
struct
irq_data
*
d
)
{
__raw_writel
(
BM_ICOLL_INTERRUPTn_ENABLE
,
icoll_base
+
HW_ICOLL_INTERRUPTn_SET
(
d
->
irq
));
icoll_base
+
HW_ICOLL_INTERRUPTn_SET
(
d
->
hw
irq
));
}
static
struct
irq_chip
mxs_icoll_chip
=
{
...
...
@@ -63,18 +70,56 @@ static struct irq_chip mxs_icoll_chip = {
.
irq_unmask
=
icoll_unmask_irq
,
};
void
__init
icoll_init_irq
(
void
)
asmlinkage
void
__exception_irq_entry
icoll_handle_irq
(
struct
pt_regs
*
regs
)
{
int
i
;
u32
irqnr
;
do
{
irqnr
=
__raw_readl
(
icoll_base
+
HW_ICOLL_STAT_OFFSET
);
if
(
irqnr
!=
0x7f
)
{
__raw_writel
(
irqnr
,
icoll_base
+
HW_ICOLL_VECTOR
);
irqnr
=
irq_find_mapping
(
icoll_domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
continue
;
}
break
;
}
while
(
1
);
}
static
int
icoll_irq_domain_map
(
struct
irq_domain
*
d
,
unsigned
int
virq
,
irq_hw_number_t
hw
)
{
irq_set_chip_and_handler
(
virq
,
&
mxs_icoll_chip
,
handle_level_irq
);
set_irq_flags
(
virq
,
IRQF_VALID
);
return
0
;
}
static
struct
irq_domain_ops
icoll_irq_domain_ops
=
{
.
map
=
icoll_irq_domain_map
,
.
xlate
=
irq_domain_xlate_onecell
,
};
void
__init
icoll_of_init
(
struct
device_node
*
np
,
struct
device_node
*
interrupt_parent
)
{
/*
* Interrupt Collector reset, which initializes the priority
* for each irq to level 0.
*/
mxs_reset_block
(
icoll_base
+
HW_ICOLL_CTRL
);
for
(
i
=
0
;
i
<
MXS_INTERNAL_IRQS
;
i
++
)
{
irq_set_chip_and_handler
(
i
,
&
mxs_icoll_chip
,
handle_level_irq
);
set_irq_flags
(
i
,
IRQF_VALID
);
}
icoll_domain
=
irq_domain_add_linear
(
np
,
ICOLL_NUM_IRQS
,
&
icoll_irq_domain_ops
,
NULL
);
WARN_ON
(
!
icoll_domain
);
}
static
const
struct
of_device_id
icoll_of_match
[]
__initconst
=
{
{.
compatible
=
"fsl,icoll"
,
.
data
=
icoll_of_init
},
{
/* sentinel */
}
};
void
__init
icoll_init_irq
(
void
)
{
of_irq_init
(
icoll_of_match
);
}
arch/arm/mach-mxs/include/mach/common.h
浏览文件 @
5c008d70
...
...
@@ -13,7 +13,7 @@
extern
const
u32
*
mxs_get_ocotp
(
void
);
extern
int
mxs_reset_block
(
void
__iomem
*
);
extern
void
mxs_timer_init
(
int
);
extern
void
mxs_timer_init
(
void
);
extern
void
mxs_restart
(
char
,
const
char
*
);
extern
int
mxs_saif_clkmux_select
(
unsigned
int
clkmux
);
...
...
@@ -24,5 +24,6 @@ extern int mx28_clocks_init(void);
extern
void
mx28_map_io
(
void
);
extern
void
icoll_init_irq
(
void
);
extern
void
icoll_handle_irq
(
struct
pt_regs
*
);
#endif
/* __MACH_MXS_COMMON_H__ */
arch/arm/mach-mxs/include/mach/entry-macro.S
已删除
100644 → 0
浏览文件 @
5d3a0a95
/*
*
Low
-
level
IRQ
helper
macros
for
Freescale
MXS
-
based
*
*
Copyright
(
C
)
2009
-
2010
Freescale
Semiconductor
,
Inc
.
All
Rights
Reserved
.
*
*
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
.
*
*
This
program
is
distributed
in
the
hope
that
it
will
be
useful
,
*
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
*
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
*
GNU
General
Public
License
for
more
details
.
*
*
You
should
have
received
a
copy
of
the
GNU
General
Public
License
along
*
with
this
program
; if not, write to the Free Software Foundation, Inc.,
*
51
Franklin
Street
,
Fifth
Floor
,
Boston
,
MA
02110
-
1301
USA
.
*/
#include <mach/mxs.h>
#define MXS_ICOLL_VBASE MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR)
#define HW_ICOLL_STAT_OFFSET 0x70
.
macro
get_irqnr_and_base
,
irqnr
,
irqstat
,
base
,
tmp
ldr
\
irqnr
,
[
\
base
,
#
HW_ICOLL_STAT_OFFSET
]
cmp
\
irqnr
,
#
0x7F
strne
\
irqnr
,
[
\
base
]
moveqs
\
irqnr
,
#
0
.
endm
.
macro
get_irqnr_preamble
,
base
,
tmp
ldr
\
base
,
=
MXS_ICOLL_VBASE
.
endm
arch/arm/mach-mxs/include/mach/irqs.h
已删除
100644 → 0
浏览文件 @
5d3a0a95
/*
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
* 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.
*/
#ifndef __MACH_MXS_IRQS_H__
#define __MACH_MXS_IRQS_H__
#define MXS_INTERNAL_IRQS 128
#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
/* the maximum for MXS-based */
#define MXS_GPIO_IRQS (32 * 5)
/*
* The next 16 interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
* these. If you need more, increase MXS_BOARD_IRQS, but keep it
* within sensible limits.
*/
#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
#define MXS_BOARD_IRQS 16
#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
#endif
/* __MACH_MXS_IRQS_H__ */
arch/arm/mach-mxs/mach-mxs.c
浏览文件 @
5c008d70
...
...
@@ -17,10 +17,8 @@
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/irqdomain.h>
#include <linux/micrel_phy.h>
#include <linux/mxsfb.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/pinctrl/consumer.h>
...
...
@@ -141,37 +139,6 @@ static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
{
/* sentinel */
}
};
static
int
__init
mxs_icoll_add_irq_domain
(
struct
device_node
*
np
,
struct
device_node
*
interrupt_parent
)
{
irq_domain_add_legacy
(
np
,
128
,
0
,
0
,
&
irq_domain_simple_ops
,
NULL
);
return
0
;
}
static
int
__init
mxs_gpio_add_irq_domain
(
struct
device_node
*
np
,
struct
device_node
*
interrupt_parent
)
{
static
int
gpio_irq_base
=
MXS_GPIO_IRQ_START
;
irq_domain_add_legacy
(
np
,
32
,
gpio_irq_base
,
0
,
&
irq_domain_simple_ops
,
NULL
);
gpio_irq_base
+=
32
;
return
0
;
}
static
const
struct
of_device_id
mxs_irq_match
[]
__initconst
=
{
{
.
compatible
=
"fsl,mxs-icoll"
,
.
data
=
mxs_icoll_add_irq_domain
,
},
{
.
compatible
=
"fsl,mxs-gpio"
,
.
data
=
mxs_gpio_add_irq_domain
,
},
{
/* sentinel */
}
};
static
void
__init
mxs_dt_init_irq
(
void
)
{
icoll_init_irq
();
of_irq_init
(
mxs_irq_match
);
}
static
void
__init
imx23_timer_init
(
void
)
{
mx23_clocks_init
();
...
...
@@ -421,7 +388,8 @@ static const char *imx28_dt_compat[] __initdata = {
DT_MACHINE_START
(
IMX23
,
"Freescale i.MX23 (Device Tree)"
)
.
map_io
=
mx23_map_io
,
.
init_irq
=
mxs_dt_init_irq
,
.
init_irq
=
icoll_init_irq
,
.
handle_irq
=
icoll_handle_irq
,
.
timer
=
&
imx23_timer
,
.
init_machine
=
mxs_machine_init
,
.
dt_compat
=
imx23_dt_compat
,
...
...
@@ -430,7 +398,8 @@ MACHINE_END
DT_MACHINE_START
(
IMX28
,
"Freescale i.MX28 (Device Tree)"
)
.
map_io
=
mx28_map_io
,
.
init_irq
=
mxs_dt_init_irq
,
.
init_irq
=
icoll_init_irq
,
.
handle_irq
=
icoll_handle_irq
,
.
timer
=
&
imx28_timer
,
.
init_machine
=
mxs_machine_init
,
.
dt_compat
=
imx28_dt_compat
,
...
...
arch/arm/mach-mxs/timer.c
浏览文件 @
5c008d70
...
...
@@ -25,6 +25,8 @@
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <asm/mach/time.h>
#include <mach/mxs.h>
...
...
@@ -244,9 +246,17 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
return
0
;
}
void
__init
mxs_timer_init
(
int
irq
)
void
__init
mxs_timer_init
(
void
)
{
struct
device_node
*
np
;
struct
clk
*
timer_clk
;
int
irq
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"fsl,timrot"
);
if
(
!
np
)
{
pr_err
(
"%s: failed find timrot node
\n
"
,
__func__
);
return
;
}
timer_clk
=
clk_get_sys
(
"timrot"
,
NULL
);
if
(
IS_ERR
(
timer_clk
))
{
...
...
@@ -295,5 +305,6 @@ void __init mxs_timer_init(int irq)
mxs_clockevent_init
(
timer_clk
);
/* Make irqs happen */
irq
=
irq_of_parse_and_map
(
np
,
0
);
setup_irq
(
irq
,
&
mxs_timer_irq
);
}
drivers/clk/mxs/clk-imx23.c
浏览文件 @
5c008d70
...
...
@@ -165,7 +165,7 @@ int __init mx23_clocks_init(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
mxs_timer_init
(
MX23_INT_TIMER0
);
mxs_timer_init
();
return
0
;
}
drivers/clk/mxs/clk-imx28.c
浏览文件 @
5c008d70
...
...
@@ -244,7 +244,7 @@ int __init mx28_clocks_init(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
mxs_timer_init
(
MX28_INT_TIMER0
);
mxs_timer_init
();
return
0
;
}
drivers/gpio/gpio-mxs.c
浏览文件 @
5c008d70
...
...
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_address.h>
...
...
@@ -52,8 +53,6 @@
#define GPIO_INT_LEV_MASK (1 << 0)
#define GPIO_INT_POL_MASK (1 << 1)
#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
enum
mxs_gpio_id
{
IMX23_GPIO
,
IMX28_GPIO
,
...
...
@@ -63,7 +62,7 @@ struct mxs_gpio_port {
void
__iomem
*
base
;
int
id
;
int
irq
;
int
virtual_irq_start
;
struct
irq_domain
*
domain
;
struct
bgpio_chip
bgc
;
enum
mxs_gpio_id
devid
;
};
...
...
@@ -82,8 +81,7 @@ static inline int is_imx28_gpio(struct mxs_gpio_port *port)
static
int
mxs_gpio_set_irq_type
(
struct
irq_data
*
d
,
unsigned
int
type
)
{
u32
gpio
=
irq_to_gpio
(
d
->
irq
);
u32
pin_mask
=
1
<<
(
gpio
&
31
);
u32
pin_mask
=
1
<<
d
->
hwirq
;
struct
irq_chip_generic
*
gc
=
irq_data_get_irq_chip_data
(
d
);
struct
mxs_gpio_port
*
port
=
gc
->
private
;
void
__iomem
*
pin_addr
;
...
...
@@ -120,7 +118,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
else
writel
(
pin_mask
,
pin_addr
+
MXS_CLR
);
writel
(
1
<<
(
gpio
&
0x1f
)
,
writel
(
pin_mask
,
port
->
base
+
PINCTRL_IRQSTAT
(
port
)
+
MXS_CLR
);
return
0
;
...
...
@@ -131,7 +129,6 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
u32
irq_stat
;
struct
mxs_gpio_port
*
port
=
irq_get_handler_data
(
irq
);
u32
gpio_irq_no_base
=
port
->
virtual_irq_start
;
desc
->
irq_data
.
chip
->
irq_ack
(
&
desc
->
irq_data
);
...
...
@@ -140,7 +137,7 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
while
(
irq_stat
!=
0
)
{
int
irqoffset
=
fls
(
irq_stat
)
-
1
;
generic_handle_irq
(
gpio_irq_no_base
+
irqoffset
);
generic_handle_irq
(
irq_find_mapping
(
port
->
domain
,
irqoffset
)
);
irq_stat
&=
~
(
1
<<
irqoffset
);
}
}
...
...
@@ -167,12 +164,12 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
return
0
;
}
static
void
__init
mxs_gpio_init_gc
(
struct
mxs_gpio_port
*
port
)
static
void
__init
mxs_gpio_init_gc
(
struct
mxs_gpio_port
*
port
,
int
irq_base
)
{
struct
irq_chip_generic
*
gc
;
struct
irq_chip_type
*
ct
;
gc
=
irq_alloc_generic_chip
(
"gpio-mxs"
,
1
,
port
->
virtual_irq_start
,
gc
=
irq_alloc_generic_chip
(
"gpio-mxs"
,
1
,
irq_base
,
port
->
base
,
handle_level_irq
);
gc
->
private
=
port
;
...
...
@@ -194,7 +191,7 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
struct
mxs_gpio_port
*
port
=
container_of
(
bgc
,
struct
mxs_gpio_port
,
bgc
);
return
port
->
virtual_irq_start
+
offset
;
return
irq_find_mapping
(
port
->
domain
,
offset
)
;
}
static
struct
platform_device_id
mxs_gpio_ids
[]
=
{
...
...
@@ -226,6 +223,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
static
void
__iomem
*
base
;
struct
mxs_gpio_port
*
port
;
struct
resource
*
iores
=
NULL
;
int
irq_base
;
int
err
;
port
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
port
),
GFP_KERNEL
);
...
...
@@ -241,7 +239,6 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
port
->
id
=
pdev
->
id
;
port
->
devid
=
pdev
->
id_entry
->
driver_data
;
}
port
->
virtual_irq_start
=
MXS_GPIO_IRQ_START
+
port
->
id
*
32
;
port
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
port
->
irq
<
0
)
...
...
@@ -275,8 +272,19 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
/* clear address has to be used to clear IRQSTAT bits */
writel
(
~
0U
,
port
->
base
+
PINCTRL_IRQSTAT
(
port
)
+
MXS_CLR
);
irq_base
=
irq_alloc_descs
(
-
1
,
0
,
32
,
numa_node_id
());
if
(
irq_base
<
0
)
return
irq_base
;
port
->
domain
=
irq_domain_add_legacy
(
np
,
32
,
irq_base
,
0
,
&
irq_domain_simple_ops
,
NULL
);
if
(
!
port
->
domain
)
{
err
=
-
ENODEV
;
goto
out_irqdesc_free
;
}
/* gpio-mxs can be a generic irq chip */
mxs_gpio_init_gc
(
port
);
mxs_gpio_init_gc
(
port
,
irq_base
);
/* setup one handler for each entry */
irq_set_chained_handler
(
port
->
irq
,
mxs_gpio_irq_handler
);
...
...
@@ -287,18 +295,22 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
port
->
base
+
PINCTRL_DOUT
(
port
),
NULL
,
port
->
base
+
PINCTRL_DOE
(
port
),
NULL
,
0
);
if
(
err
)
return
err
;
goto
out_irqdesc_free
;
port
->
bgc
.
gc
.
to_irq
=
mxs_gpio_to_irq
;
port
->
bgc
.
gc
.
base
=
port
->
id
*
32
;
err
=
gpiochip_add
(
&
port
->
bgc
.
gc
);
if
(
err
)
{
bgpio_remove
(
&
port
->
bgc
);
return
err
;
}
if
(
err
)
goto
out_bgpio_remove
;
return
0
;
out_bgpio_remove:
bgpio_remove
(
&
port
->
bgc
);
out_irqdesc_free:
irq_free_descs
(
irq_base
,
32
);
return
err
;
}
static
struct
platform_driver
mxs_gpio_driver
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录