Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
5c008d70
Commit
5c008d70
authored
Oct 01, 2012
by
Olof Johansson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next/soc2' into HEAD
parents
5d3a0a95
36246a82
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
112 additions
and
137 deletions
+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
No files found.
arch/arm/Kconfig
View file @
5c008d70
...
@@ -485,7 +485,9 @@ config ARCH_MXS
...
@@ -485,7 +485,9 @@ config ARCH_MXS
select CLKSRC_MMIO
select CLKSRC_MMIO
select COMMON_CLK
select COMMON_CLK
select HAVE_CLK_PREPARE
select HAVE_CLK_PREPARE
select MULTI_IRQ_HANDLER
select PINCTRL
select PINCTRL
select SPARSE_IRQ
select USE_OF
select USE_OF
help
help
Support for Freescale MXS-based family of processors
Support for Freescale MXS-based family of processors
...
...
arch/arm/boot/dts/imx23.dtsi
View file @
5c008d70
...
@@ -43,7 +43,7 @@ apbh@80000000 {
...
@@ -43,7 +43,7 @@ apbh@80000000 {
ranges;
ranges;
icoll: interrupt-controller@80000000 {
icoll: interrupt-controller@80000000 {
compatible = "fsl,imx23-icoll", "fsl,
mxs-
icoll";
compatible = "fsl,imx23-icoll", "fsl,icoll";
interrupt-controller;
interrupt-controller;
#interrupt-cells = <1>;
#interrupt-cells = <1>;
reg = <0x80000000 0x2000>;
reg = <0x80000000 0x2000>;
...
@@ -407,8 +407,9 @@ pwm: pwm@80064000 {
...
@@ -407,8 +407,9 @@ pwm: pwm@80064000 {
};
};
timrot@80068000 {
timrot@80068000 {
compatible = "fsl,imx23-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
reg = <0x80068000 0x2000>;
status = "disabled"
;
interrupts = <28 29 30 31>
;
};
};
auart0: serial@8006c000 {
auart0: serial@8006c000 {
...
...
arch/arm/boot/dts/imx28.dtsi
View file @
5c008d70
...
@@ -52,7 +52,7 @@ apbh@80000000 {
...
@@ -52,7 +52,7 @@ apbh@80000000 {
ranges;
ranges;
icoll: interrupt-controller@80000000 {
icoll: interrupt-controller@80000000 {
compatible = "fsl,imx28-icoll", "fsl,
mxs-
icoll";
compatible = "fsl,imx28-icoll", "fsl,icoll";
interrupt-controller;
interrupt-controller;
#interrupt-cells = <1>;
#interrupt-cells = <1>;
reg = <0x80000000 0x2000>;
reg = <0x80000000 0x2000>;
...
@@ -787,8 +787,9 @@ pwm: pwm@80064000 {
...
@@ -787,8 +787,9 @@ pwm: pwm@80064000 {
};
};
timrot@80068000 {
timrot@80068000 {
compatible = "fsl,imx28-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
reg = <0x80068000 0x2000>;
status = "disabled"
;
interrupts = <48 49 50 51>
;
};
};
auart0: serial@8006a000 {
auart0: serial@8006a000 {
...
...
arch/arm/mach-mxs/icoll.c
View file @
5c008d70
...
@@ -19,20 +19,27 @@
...
@@ -19,20 +19,27 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <asm/exception.h>
#include <mach/mxs.h>
#include <mach/mxs.h>
#include <mach/common.h>
#include <mach/common.h>
#define HW_ICOLL_VECTOR 0x0000
#define HW_ICOLL_VECTOR 0x0000
#define HW_ICOLL_LEVELACK 0x0010
#define HW_ICOLL_LEVELACK 0x0010
#define HW_ICOLL_CTRL 0x0020
#define HW_ICOLL_CTRL 0x0020
#define HW_ICOLL_STAT_OFFSET 0x0070
#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
#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
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
)
static
void
icoll_ack_irq
(
struct
irq_data
*
d
)
{
{
...
@@ -48,13 +55,13 @@ 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
)
static
void
icoll_mask_irq
(
struct
irq_data
*
d
)
{
{
__raw_writel
(
BM_ICOLL_INTERRUPTn_ENABLE
,
__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
)
static
void
icoll_unmask_irq
(
struct
irq_data
*
d
)
{
{
__raw_writel
(
BM_ICOLL_INTERRUPTn_ENABLE
,
__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
=
{
static
struct
irq_chip
mxs_icoll_chip
=
{
...
@@ -63,18 +70,56 @@ static struct irq_chip mxs_icoll_chip = {
...
@@ -63,18 +70,56 @@ static struct irq_chip mxs_icoll_chip = {
.
irq_unmask
=
icoll_unmask_irq
,
.
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
* Interrupt Collector reset, which initializes the priority
* for each irq to level 0.
* for each irq to level 0.
*/
*/
mxs_reset_block
(
icoll_base
+
HW_ICOLL_CTRL
);
mxs_reset_block
(
icoll_base
+
HW_ICOLL_CTRL
);
for
(
i
=
0
;
i
<
MXS_INTERNAL_IRQS
;
i
++
)
{
icoll_domain
=
irq_domain_add_linear
(
np
,
ICOLL_NUM_IRQS
,
irq_set_chip_and_handler
(
i
,
&
mxs_icoll_chip
,
handle_level_irq
);
&
icoll_irq_domain_ops
,
NULL
);
set_irq_flags
(
i
,
IRQF_VALID
);
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
View file @
5c008d70
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
extern
const
u32
*
mxs_get_ocotp
(
void
);
extern
const
u32
*
mxs_get_ocotp
(
void
);
extern
int
mxs_reset_block
(
void
__iomem
*
);
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
void
mxs_restart
(
char
,
const
char
*
);
extern
int
mxs_saif_clkmux_select
(
unsigned
int
clkmux
);
extern
int
mxs_saif_clkmux_select
(
unsigned
int
clkmux
);
...
@@ -24,5 +24,6 @@ extern int mx28_clocks_init(void);
...
@@ -24,5 +24,6 @@ extern int mx28_clocks_init(void);
extern
void
mx28_map_io
(
void
);
extern
void
mx28_map_io
(
void
);
extern
void
icoll_init_irq
(
void
);
extern
void
icoll_init_irq
(
void
);
extern
void
icoll_handle_irq
(
struct
pt_regs
*
);
#endif
/* __MACH_MXS_COMMON_H__ */
#endif
/* __MACH_MXS_COMMON_H__ */
arch/arm/mach-mxs/include/mach/entry-macro.S
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
View file @
5c008d70
...
@@ -17,10 +17,8 @@
...
@@ -17,10 +17,8 @@
#include <linux/err.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/irqdomain.h>
#include <linux/micrel_phy.h>
#include <linux/micrel_phy.h>
#include <linux/mxsfb.h>
#include <linux/mxsfb.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/phy.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/consumer.h>
...
@@ -141,37 +139,6 @@ static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
...
@@ -141,37 +139,6 @@ static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
{
/* sentinel */
}
{
/* 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
)
static
void
__init
imx23_timer_init
(
void
)
{
{
mx23_clocks_init
();
mx23_clocks_init
();
...
@@ -421,7 +388,8 @@ static const char *imx28_dt_compat[] __initdata = {
...
@@ -421,7 +388,8 @@ static const char *imx28_dt_compat[] __initdata = {
DT_MACHINE_START
(
IMX23
,
"Freescale i.MX23 (Device Tree)"
)
DT_MACHINE_START
(
IMX23
,
"Freescale i.MX23 (Device Tree)"
)
.
map_io
=
mx23_map_io
,
.
map_io
=
mx23_map_io
,
.
init_irq
=
mxs_dt_init_irq
,
.
init_irq
=
icoll_init_irq
,
.
handle_irq
=
icoll_handle_irq
,
.
timer
=
&
imx23_timer
,
.
timer
=
&
imx23_timer
,
.
init_machine
=
mxs_machine_init
,
.
init_machine
=
mxs_machine_init
,
.
dt_compat
=
imx23_dt_compat
,
.
dt_compat
=
imx23_dt_compat
,
...
@@ -430,7 +398,8 @@ MACHINE_END
...
@@ -430,7 +398,8 @@ MACHINE_END
DT_MACHINE_START
(
IMX28
,
"Freescale i.MX28 (Device Tree)"
)
DT_MACHINE_START
(
IMX28
,
"Freescale i.MX28 (Device Tree)"
)
.
map_io
=
mx28_map_io
,
.
map_io
=
mx28_map_io
,
.
init_irq
=
mxs_dt_init_irq
,
.
init_irq
=
icoll_init_irq
,
.
handle_irq
=
icoll_handle_irq
,
.
timer
=
&
imx28_timer
,
.
timer
=
&
imx28_timer
,
.
init_machine
=
mxs_machine_init
,
.
init_machine
=
mxs_machine_init
,
.
dt_compat
=
imx28_dt_compat
,
.
dt_compat
=
imx28_dt_compat
,
...
...
arch/arm/mach-mxs/timer.c
View file @
5c008d70
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <asm/mach/time.h>
#include <asm/mach/time.h>
#include <mach/mxs.h>
#include <mach/mxs.h>
...
@@ -244,9 +246,17 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
...
@@ -244,9 +246,17 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
return
0
;
return
0
;
}
}
void
__init
mxs_timer_init
(
int
irq
)
void
__init
mxs_timer_init
(
void
)
{
{
struct
device_node
*
np
;
struct
clk
*
timer_clk
;
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
);
timer_clk
=
clk_get_sys
(
"timrot"
,
NULL
);
if
(
IS_ERR
(
timer_clk
))
{
if
(
IS_ERR
(
timer_clk
))
{
...
@@ -295,5 +305,6 @@ void __init mxs_timer_init(int irq)
...
@@ -295,5 +305,6 @@ void __init mxs_timer_init(int irq)
mxs_clockevent_init
(
timer_clk
);
mxs_clockevent_init
(
timer_clk
);
/* Make irqs happen */
/* Make irqs happen */
irq
=
irq_of_parse_and_map
(
np
,
0
);
setup_irq
(
irq
,
&
mxs_timer_irq
);
setup_irq
(
irq
,
&
mxs_timer_irq
);
}
}
drivers/clk/mxs/clk-imx23.c
View file @
5c008d70
...
@@ -165,7 +165,7 @@ int __init mx23_clocks_init(void)
...
@@ -165,7 +165,7 @@ int __init mx23_clocks_init(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
mxs_timer_init
(
MX23_INT_TIMER0
);
mxs_timer_init
();
return
0
;
return
0
;
}
}
drivers/clk/mxs/clk-imx28.c
View file @
5c008d70
...
@@ -244,7 +244,7 @@ int __init mx28_clocks_init(void)
...
@@ -244,7 +244,7 @@ int __init mx28_clocks_init(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clks_init_on
);
i
++
)
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
clk_prepare_enable
(
clks
[
clks_init_on
[
i
]]);
mxs_timer_init
(
MX28_INT_TIMER0
);
mxs_timer_init
();
return
0
;
return
0
;
}
}
drivers/gpio/gpio-mxs.c
View file @
5c008d70
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_address.h>
...
@@ -52,8 +53,6 @@
...
@@ -52,8 +53,6 @@
#define GPIO_INT_LEV_MASK (1 << 0)
#define GPIO_INT_LEV_MASK (1 << 0)
#define GPIO_INT_POL_MASK (1 << 1)
#define GPIO_INT_POL_MASK (1 << 1)
#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
enum
mxs_gpio_id
{
enum
mxs_gpio_id
{
IMX23_GPIO
,
IMX23_GPIO
,
IMX28_GPIO
,
IMX28_GPIO
,
...
@@ -63,7 +62,7 @@ struct mxs_gpio_port {
...
@@ -63,7 +62,7 @@ struct mxs_gpio_port {
void
__iomem
*
base
;
void
__iomem
*
base
;
int
id
;
int
id
;
int
irq
;
int
irq
;
int
virtual_irq_start
;
struct
irq_domain
*
domain
;
struct
bgpio_chip
bgc
;
struct
bgpio_chip
bgc
;
enum
mxs_gpio_id
devid
;
enum
mxs_gpio_id
devid
;
};
};
...
@@ -82,8 +81,7 @@ static inline int is_imx28_gpio(struct mxs_gpio_port *port)
...
@@ -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
)
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
<<
d
->
hwirq
;
u32
pin_mask
=
1
<<
(
gpio
&
31
);
struct
irq_chip_generic
*
gc
=
irq_data_get_irq_chip_data
(
d
);
struct
irq_chip_generic
*
gc
=
irq_data_get_irq_chip_data
(
d
);
struct
mxs_gpio_port
*
port
=
gc
->
private
;
struct
mxs_gpio_port
*
port
=
gc
->
private
;
void
__iomem
*
pin_addr
;
void
__iomem
*
pin_addr
;
...
@@ -120,7 +118,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
...
@@ -120,7 +118,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
else
else
writel
(
pin_mask
,
pin_addr
+
MXS_CLR
);
writel
(
pin_mask
,
pin_addr
+
MXS_CLR
);
writel
(
1
<<
(
gpio
&
0x1f
)
,
writel
(
pin_mask
,
port
->
base
+
PINCTRL_IRQSTAT
(
port
)
+
MXS_CLR
);
port
->
base
+
PINCTRL_IRQSTAT
(
port
)
+
MXS_CLR
);
return
0
;
return
0
;
...
@@ -131,7 +129,6 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
...
@@ -131,7 +129,6 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
{
u32
irq_stat
;
u32
irq_stat
;
struct
mxs_gpio_port
*
port
=
irq_get_handler_data
(
irq
);
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
);
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)
...
@@ -140,7 +137,7 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
while
(
irq_stat
!=
0
)
{
while
(
irq_stat
!=
0
)
{
int
irqoffset
=
fls
(
irq_stat
)
-
1
;
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
);
irq_stat
&=
~
(
1
<<
irqoffset
);
}
}
}
}
...
@@ -167,12 +164,12 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
...
@@ -167,12 +164,12 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
return
0
;
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_generic
*
gc
;
struct
irq_chip_type
*
ct
;
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
);
port
->
base
,
handle_level_irq
);
gc
->
private
=
port
;
gc
->
private
=
port
;
...
@@ -194,7 +191,7 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
...
@@ -194,7 +191,7 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
struct
mxs_gpio_port
*
port
=
struct
mxs_gpio_port
*
port
=
container_of
(
bgc
,
struct
mxs_gpio_port
,
bgc
);
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
[]
=
{
static
struct
platform_device_id
mxs_gpio_ids
[]
=
{
...
@@ -226,6 +223,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
...
@@ -226,6 +223,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
static
void
__iomem
*
base
;
static
void
__iomem
*
base
;
struct
mxs_gpio_port
*
port
;
struct
mxs_gpio_port
*
port
;
struct
resource
*
iores
=
NULL
;
struct
resource
*
iores
=
NULL
;
int
irq_base
;
int
err
;
int
err
;
port
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
port
),
GFP_KERNEL
);
port
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
port
),
GFP_KERNEL
);
...
@@ -241,7 +239,6 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
...
@@ -241,7 +239,6 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
port
->
id
=
pdev
->
id
;
port
->
id
=
pdev
->
id
;
port
->
devid
=
pdev
->
id_entry
->
driver_data
;
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
);
port
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
port
->
irq
<
0
)
if
(
port
->
irq
<
0
)
...
@@ -275,8 +272,19 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
...
@@ -275,8 +272,19 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
/* clear address has to be used to clear IRQSTAT bits */
/* clear address has to be used to clear IRQSTAT bits */
writel
(
~
0U
,
port
->
base
+
PINCTRL_IRQSTAT
(
port
)
+
MXS_CLR
);
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 */
/* 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 */
/* setup one handler for each entry */
irq_set_chained_handler
(
port
->
irq
,
mxs_gpio_irq_handler
);
irq_set_chained_handler
(
port
->
irq
,
mxs_gpio_irq_handler
);
...
@@ -287,18 +295,22 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
...
@@ -287,18 +295,22 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
port
->
base
+
PINCTRL_DOUT
(
port
),
NULL
,
port
->
base
+
PINCTRL_DOUT
(
port
),
NULL
,
port
->
base
+
PINCTRL_DOE
(
port
),
NULL
,
0
);
port
->
base
+
PINCTRL_DOE
(
port
),
NULL
,
0
);
if
(
err
)
if
(
err
)
return
err
;
goto
out_irqdesc_free
;
port
->
bgc
.
gc
.
to_irq
=
mxs_gpio_to_irq
;
port
->
bgc
.
gc
.
to_irq
=
mxs_gpio_to_irq
;
port
->
bgc
.
gc
.
base
=
port
->
id
*
32
;
port
->
bgc
.
gc
.
base
=
port
->
id
*
32
;
err
=
gpiochip_add
(
&
port
->
bgc
.
gc
);
err
=
gpiochip_add
(
&
port
->
bgc
.
gc
);
if
(
err
)
{
if
(
err
)
bgpio_remove
(
&
port
->
bgc
);
goto
out_bgpio_remove
;
return
err
;
}
return
0
;
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
=
{
static
struct
platform_driver
mxs_gpio_driver
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment