Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
22a5db98
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
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:
...
@@ -262,6 +262,12 @@ symbol:
to the container using container_of().
to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
(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
* 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
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
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);
...
@@ -71,6 +71,8 @@ LIST_HEAD(gpio_devices);
static
void
gpiochip_free_hogs
(
struct
gpio_chip
*
chip
);
static
void
gpiochip_free_hogs
(
struct
gpio_chip
*
chip
);
static
void
gpiochip_irqchip_remove
(
struct
gpio_chip
*
gpiochip
);
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
;
static
bool
gpiolib_initialized
;
...
@@ -1167,6 +1169,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
...
@@ -1167,6 +1169,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
if
(
status
)
if
(
status
)
goto
err_remove_from_list
;
goto
err_remove_from_list
;
status
=
gpiochip_irqchip_init_valid_mask
(
chip
);
if
(
status
)
goto
err_remove_from_list
;
status
=
of_gpiochip_add
(
chip
);
status
=
of_gpiochip_add
(
chip
);
if
(
status
)
if
(
status
)
goto
err_remove_chip
;
goto
err_remove_chip
;
...
@@ -1192,6 +1198,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
...
@@ -1192,6 +1198,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
acpi_gpiochip_remove
(
chip
);
acpi_gpiochip_remove
(
chip
);
gpiochip_free_hogs
(
chip
);
gpiochip_free_hogs
(
chip
);
of_gpiochip_remove
(
chip
);
of_gpiochip_remove
(
chip
);
gpiochip_irqchip_free_valid_mask
(
chip
);
err_remove_from_list:
err_remove_from_list:
spin_lock_irqsave
(
&
gpio_lock
,
flags
);
spin_lock_irqsave
(
&
gpio_lock
,
flags
);
list_del
(
&
gdev
->
list
);
list_del
(
&
gdev
->
list
);
...
@@ -1397,6 +1404,40 @@ static struct gpio_chip *find_chip_by_name(const char *name)
...
@@ -1397,6 +1404,40 @@ static struct gpio_chip *find_chip_by_name(const char *name)
* The following is irqchip helper code for gpiochips.
* 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_set_chained_irqchip() - sets a chained irqchip to a gpiochip
* @gpiochip: the gpiochip to set the irqchip chain to
* @gpiochip: the gpiochip to set the irqchip chain to
...
@@ -1438,9 +1479,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
...
@@ -1438,9 +1479,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
}
}
/* Set the parent IRQ for all affected IRQs */
/* 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
),
irq_set_parent
(
irq_find_mapping
(
gpiochip
->
irqdomain
,
offset
),
parent_irq
);
parent_irq
);
}
}
}
EXPORT_SYMBOL_GPL
(
gpiochip_set_chained_irqchip
);
EXPORT_SYMBOL_GPL
(
gpiochip_set_chained_irqchip
);
...
@@ -1547,9 +1591,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
...
@@ -1547,9 +1591,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
/* Remove all IRQ mappings and delete the domain */
/* Remove all IRQ mappings and delete the domain */
if
(
gpiochip
->
irqdomain
)
{
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_dispose_mapping
(
irq_find_mapping
(
gpiochip
->
irqdomain
,
offset
));
irq_find_mapping
(
gpiochip
->
irqdomain
,
offset
));
}
irq_domain_remove
(
gpiochip
->
irqdomain
);
irq_domain_remove
(
gpiochip
->
irqdomain
);
}
}
...
@@ -1558,6 +1605,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
...
@@ -1558,6 +1605,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
gpiochip
->
irqchip
->
irq_release_resources
=
NULL
;
gpiochip
->
irqchip
->
irq_release_resources
=
NULL
;
gpiochip
->
irqchip
=
NULL
;
gpiochip
->
irqchip
=
NULL
;
}
}
gpiochip_irqchip_free_valid_mask
(
gpiochip
);
}
}
/**
/**
...
@@ -1593,6 +1642,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
...
@@ -1593,6 +1642,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct
lock_class_key
*
lock_key
)
struct
lock_class_key
*
lock_key
)
{
{
struct
device_node
*
of_node
;
struct
device_node
*
of_node
;
bool
irq_base_set
=
false
;
unsigned
int
offset
;
unsigned
int
offset
;
unsigned
irq_base
=
0
;
unsigned
irq_base
=
0
;
...
@@ -1656,13 +1706,17 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
...
@@ -1656,13 +1706,17 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
* necessary to allocate descriptors for all IRQs.
* necessary to allocate descriptors for all IRQs.
*/
*/
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
{
for
(
offset
=
0
;
offset
<
gpiochip
->
ngpio
;
offset
++
)
{
if
(
!
gpiochip_irqchip_irq_valid
(
gpiochip
,
offset
))
continue
;
irq_base
=
irq_create_mapping
(
gpiochip
->
irqdomain
,
offset
);
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
* Store the base into the gpiochip to be used when
* unmapping the irqs.
* unmapping the irqs.
*/
*/
gpiochip
->
irq_base
=
irq_base
;
gpiochip
->
irq_base
=
irq_base
;
irq_base_set
=
true
;
}
}
}
acpi_gpiochip_request_interrupts
(
gpiochip
);
acpi_gpiochip_request_interrupts
(
gpiochip
);
...
@@ -1674,6 +1728,12 @@ EXPORT_SYMBOL_GPL(_gpiochip_irqchip_add);
...
@@ -1674,6 +1728,12 @@ EXPORT_SYMBOL_GPL(_gpiochip_irqchip_add);
#else
/* CONFIG_GPIOLIB_IRQCHIP */
#else
/* CONFIG_GPIOLIB_IRQCHIP */
static
void
gpiochip_irqchip_remove
(
struct
gpio_chip
*
gpiochip
)
{}
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 */
#endif
/* CONFIG_GPIOLIB_IRQCHIP */
...
...
include/linux/gpio/driver.h
浏览文件 @
22a5db98
...
@@ -112,6 +112,10 @@ enum single_ended_mode {
...
@@ -112,6 +112,10 @@ enum single_ended_mode {
* initialization, provided by GPIO driver
* initialization, provided by GPIO driver
* @irq_parent: GPIO IRQ chip parent/bank linux irq number,
* @irq_parent: GPIO IRQ chip parent/bank linux irq number,
* provided by GPIO driver
* 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
* @lock_key: per GPIO IRQ chip lockdep class
*
*
* A gpio_chip can help platforms abstract various sources of GPIOs so
* A gpio_chip can help platforms abstract various sources of GPIOs so
...
@@ -190,6 +194,8 @@ struct gpio_chip {
...
@@ -190,6 +194,8 @@ struct gpio_chip {
irq_flow_handler_t
irq_handler
;
irq_flow_handler_t
irq_handler
;
unsigned
int
irq_default_type
;
unsigned
int
irq_default_type
;
int
irq_parent
;
int
irq_parent
;
bool
irq_need_valid_mask
;
unsigned
long
*
irq_valid_mask
;
struct
lock_class_key
*
lock_key
;
struct
lock_class_key
*
lock_key
;
#endif
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录