Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
22a5db98
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看板
提交
22a5db98
编写于
9月 23, 2016
作者:
L
Linus Walleij
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'gpio-irq-validmask' of /home/linus/linux-pinctrl into devel
上级
9132ce45
79b804cb
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
75 addition
and
3 deletion
+75
-3
Documentation/gpio/driver.txt
Documentation/gpio/driver.txt
+6
-0
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.c
+63
-3
include/linux/gpio/driver.h
include/linux/gpio/driver.h
+6
-0
未找到文件。
Documentation/gpio/driver.txt
浏览文件 @
22a5db98
...
...
@@ -262,6 +262,12 @@ symbol:
to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
If there is a need to exclude certain GPIOs from the IRQ domain, one can
set .irq_need_valid_mask of the gpiochip before gpiochip_add_data() is
called. This allocates .irq_valid_mask with as many bits set as there are
GPIOs in the chip. Drivers can exclude GPIOs by clearing bits from this
mask. The mask must be filled in before gpiochip_irqchip_add() is called.
* gpiochip_set_chained_irqchip(): sets up a chained irq handler for a
gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler
data. (Notice handler data, since the irqchip data is likely used by the
...
...
drivers/gpio/gpiolib.c
浏览文件 @
22a5db98
...
...
@@ -71,6 +71,8 @@ LIST_HEAD(gpio_devices);
static
void
gpiochip_free_hogs
(
struct
gpio_chip
*
chip
);
static
void
gpiochip_irqchip_remove
(
struct
gpio_chip
*
gpiochip
);
static
int
gpiochip_irqchip_init_valid_mask
(
struct
gpio_chip
*
gpiochip
);
static
void
gpiochip_irqchip_free_valid_mask
(
struct
gpio_chip
*
gpiochip
);
static
bool
gpiolib_initialized
;
...
...
@@ -1167,6 +1169,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
if
(
status
)
goto
err_remove_from_list
;
status
=
gpiochip_irqchip_init_valid_mask
(
chip
);
if
(
status
)
goto
err_remove_from_list
;
status
=
of_gpiochip_add
(
chip
);
if
(
status
)
goto
err_remove_chip
;
...
...
@@ -1192,6 +1198,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
acpi_gpiochip_remove
(
chip
);
gpiochip_free_hogs
(
chip
);
of_gpiochip_remove
(
chip
);
gpiochip_irqchip_free_valid_mask
(
chip
);
err_remove_from_list:
spin_lock_irqsave
(
&
gpio_lock
,
flags
);
list_del
(
&
gdev
->
list
);
...
...
@@ -1397,6 +1404,40 @@ static struct gpio_chip *find_chip_by_name(const char *name)
* The following is irqchip helper code for gpiochips.
*/
static
int
gpiochip_irqchip_init_valid_mask
(
struct
gpio_chip
*
gpiochip
)
{
int
i
;
if
(
!
gpiochip
->
irq_need_valid_mask
)
return
0
;
gpiochip
->
irq_valid_mask
=
kcalloc
(
BITS_TO_LONGS
(
gpiochip
->
ngpio
),
sizeof
(
long
),
GFP_KERNEL
);
if
(
!
gpiochip
->
irq_valid_mask
)
return
-
ENOMEM
;
/* Assume by default all GPIOs are valid */
for
(
i
=
0
;
i
<
gpiochip
->
ngpio
;
i
++
)
set_bit
(
i
,
gpiochip
->
irq_valid_mask
);
return
0
;
}
static
void
gpiochip_irqchip_free_valid_mask
(
struct
gpio_chip
*
gpiochip
)
{
kfree
(
gpiochip
->
irq_valid_mask
);
gpiochip
->
irq_valid_mask
=
NULL
;
}
static
bool
gpiochip_irqchip_irq_valid
(
const
struct
gpio_chip
*
gpiochip
,
unsigned
int
offset
)
{
/* No mask means all valid */
if
(
likely
(
!
gpiochip
->
irq_valid_mask
))
return
true
;
return
test_bit
(
offset
,
gpiochip
->
irq_valid_mask
);
}
/**
* gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip
* @gpiochip: the gpiochip to set the irqchip chain to
...
...
@@ -1438,9 +1479,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
}
/* Set the parent IRQ for all affected IRQs */
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
{
if
(
!
gpiochip_irqchip_irq_valid
(
gpiochip
,
offset
))
continue
;
irq_set_parent
(
irq_find_mapping
(
gpiochip
->
irqdomain
,
offset
),
parent_irq
);
}
}
EXPORT_SYMBOL_GPL
(
gpiochip_set_chained_irqchip
);
...
...
@@ -1547,9 +1591,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
/* Remove all IRQ mappings and delete the domain */
if
(
gpiochip
->
irqdomain
)
{
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
{
if
(
!
gpiochip_irqchip_irq_valid
(
gpiochip
,
offset
))
continue
;
irq_dispose_mapping
(
irq_find_mapping
(
gpiochip
->
irqdomain
,
offset
));
}
irq_domain_remove
(
gpiochip
->
irqdomain
);
}
...
...
@@ -1558,6 +1605,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
gpiochip
->
irqchip
->
irq_release_resources
=
NULL
;
gpiochip
->
irqchip
=
NULL
;
}
gpiochip_irqchip_free_valid_mask
(
gpiochip
);
}
/**
...
...
@@ -1593,6 +1642,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct
lock_class_key
*
lock_key
)
{
struct
device_node
*
of_node
;
bool
irq_base_set
=
false
;
unsigned
int
offset
;
unsigned
irq_base
=
0
;
...
...
@@ -1656,13 +1706,17 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
* necessary to allocate descriptors for all IRQs.
*/
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
{
if
(
!
gpiochip_irqchip_irq_valid
(
gpiochip
,
offset
))
continue
;
irq_base
=
irq_create_mapping
(
gpiochip
->
irqdomain
,
offset
);
if
(
offset
==
0
)
if
(
!
irq_base_set
)
{
/*
* Store the base into the gpiochip to be used when
* unmapping the irqs.
*/
gpiochip
->
irq_base
=
irq_base
;
irq_base_set
=
true
;
}
}
acpi_gpiochip_request_interrupts
(
gpiochip
);
...
...
@@ -1674,6 +1728,12 @@ EXPORT_SYMBOL_GPL(_gpiochip_irqchip_add);
#else
/* CONFIG_GPIOLIB_IRQCHIP */
static
void
gpiochip_irqchip_remove
(
struct
gpio_chip
*
gpiochip
)
{}
static
inline
int
gpiochip_irqchip_init_valid_mask
(
struct
gpio_chip
*
gpiochip
)
{
return
0
;
}
static
inline
void
gpiochip_irqchip_free_valid_mask
(
struct
gpio_chip
*
gpiochip
)
{
}
#endif
/* CONFIG_GPIOLIB_IRQCHIP */
...
...
include/linux/gpio/driver.h
浏览文件 @
22a5db98
...
...
@@ -112,6 +112,10 @@ enum single_ended_mode {
* initialization, provided by GPIO driver
* @irq_parent: GPIO IRQ chip parent/bank linux irq number,
* provided by GPIO driver
* @irq_need_valid_mask: If set core allocates @irq_valid_mask with all
* bits set to one
* @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to
* be included in IRQ domain of the chip
* @lock_key: per GPIO IRQ chip lockdep class
*
* A gpio_chip can help platforms abstract various sources of GPIOs so
...
...
@@ -190,6 +194,8 @@ struct gpio_chip {
irq_flow_handler_t
irq_handler
;
unsigned
int
irq_default_type
;
int
irq_parent
;
bool
irq_need_valid_mask
;
unsigned
long
*
irq_valid_mask
;
struct
lock_class_key
*
lock_key
;
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录