* [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks.
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
@ 2011-02-17 7:25 ` Marek Szyprowski
2011-02-23 6:57 ` Kukjin Kim
2011-02-17 7:25 ` [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code Marek Szyprowski
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-17 7:25 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds missing GPYx gpio banks on Samsung S5PC210 platform.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-s5pv310/gpiolib.c | 49 +++++++++++++++++++++++++++++
arch/arm/mach-s5pv310/include/mach/gpio.h | 23 +++++++++++++-
2 files changed, 71 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
index 55217b8..f417ecd 100644
--- a/arch/arm/mach-s5pv310/gpiolib.c
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -199,6 +199,55 @@ static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
.label = "GPL2",
},
}, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY0(0),
+ .ngpio = S5PV310_GPIO_Y0_NR,
+ .label = "GPY0",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY1(0),
+ .ngpio = S5PV310_GPIO_Y1_NR,
+ .label = "GPY1",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY2(0),
+ .ngpio = S5PV310_GPIO_Y2_NR,
+ .label = "GPY2",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY3(0),
+ .ngpio = S5PV310_GPIO_Y3_NR,
+ .label = "GPY3",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY4(0),
+ .ngpio = S5PV310_GPIO_Y4_NR,
+ .label = "GPY4",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY5(0),
+ .ngpio = S5PV310_GPIO_Y5_NR,
+ .label = "GPY5",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV310_GPY6(0),
+ .ngpio = S5PV310_GPIO_Y6_NR,
+ .label = "GPY6",
+ },
+ }, {
.base = (S5P_VA_GPIO2 + 0xC00),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
diff --git a/arch/arm/mach-s5pv310/include/mach/gpio.h b/arch/arm/mach-s5pv310/include/mach/gpio.h
index 20cb80c..4b44463 100644
--- a/arch/arm/mach-s5pv310/include/mach/gpio.h
+++ b/arch/arm/mach-s5pv310/include/mach/gpio.h
@@ -50,6 +50,13 @@
#define S5PV310_GPIO_X1_NR (8)
#define S5PV310_GPIO_X2_NR (8)
#define S5PV310_GPIO_X3_NR (8)
+#define S5PV310_GPIO_Y0_NR (6)
+#define S5PV310_GPIO_Y1_NR (4)
+#define S5PV310_GPIO_Y2_NR (6)
+#define S5PV310_GPIO_Y3_NR (8)
+#define S5PV310_GPIO_Y4_NR (8)
+#define S5PV310_GPIO_Y5_NR (8)
+#define S5PV310_GPIO_Y6_NR (8)
#define S5PV310_GPIO_Z_NR (7)
/* GPIO bank numbers */
@@ -87,7 +94,14 @@ enum s5p_gpio_number {
S5PV310_GPIO_X1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X0),
S5PV310_GPIO_X2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X1),
S5PV310_GPIO_X3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X2),
- S5PV310_GPIO_Z_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
+ S5PV310_GPIO_Y0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
+ S5PV310_GPIO_Y1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y0),
+ S5PV310_GPIO_Y2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y1),
+ S5PV310_GPIO_Y3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y2),
+ S5PV310_GPIO_Y4_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y3),
+ S5PV310_GPIO_Y5_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y4),
+ S5PV310_GPIO_Y6_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y5),
+ S5PV310_GPIO_Z_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y6),
};
/* S5PV310 GPIO number definitions */
@@ -120,6 +134,13 @@ enum s5p_gpio_number {
#define S5PV310_GPX1(_nr) (S5PV310_GPIO_X1_START + (_nr))
#define S5PV310_GPX2(_nr) (S5PV310_GPIO_X2_START + (_nr))
#define S5PV310_GPX3(_nr) (S5PV310_GPIO_X3_START + (_nr))
+#define S5PV310_GPY0(_nr) (S5PV310_GPIO_Y0_START + (_nr))
+#define S5PV310_GPY1(_nr) (S5PV310_GPIO_Y1_START + (_nr))
+#define S5PV310_GPY2(_nr) (S5PV310_GPIO_Y2_START + (_nr))
+#define S5PV310_GPY3(_nr) (S5PV310_GPIO_Y3_START + (_nr))
+#define S5PV310_GPY4(_nr) (S5PV310_GPIO_Y4_START + (_nr))
+#define S5PV310_GPY5(_nr) (S5PV310_GPIO_Y5_START + (_nr))
+#define S5PV310_GPY6(_nr) (S5PV310_GPIO_Y6_START + (_nr))
#define S5PV310_GPZ(_nr) (S5PV310_GPIO_Z_START + (_nr))
/* the end of the S5PV310 specific gpios */
--
1.7.1.569.g6f426
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks.
2011-02-17 7:25 ` [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks Marek Szyprowski
@ 2011-02-23 6:57 ` Kukjin Kim
0 siblings, 0 replies; 10+ messages in thread
From: Kukjin Kim @ 2011-02-23 6:57 UTC (permalink / raw)
To: linux-arm-kernel
Marek Szyrowski wrote:
>
> This patch adds missing GPYx gpio banks on Samsung S5PC210 platform.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
> arch/arm/mach-s5pv310/gpiolib.c | 49
> +++++++++++++++++++++++++++++
> arch/arm/mach-s5pv310/include/mach/gpio.h | 23 +++++++++++++-
> 2 files changed, 71 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-
> s5pv310/gpiolib.c
> index 55217b8..f417ecd 100644
> --- a/arch/arm/mach-s5pv310/gpiolib.c
> +++ b/arch/arm/mach-s5pv310/gpiolib.c
> @@ -199,6 +199,55 @@ static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[]
=
> {
> .label = "GPL2",
> },
> }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY0(0),
> + .ngpio = S5PV310_GPIO_Y0_NR,
> + .label = "GPY0",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY1(0),
> + .ngpio = S5PV310_GPIO_Y1_NR,
> + .label = "GPY1",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY2(0),
> + .ngpio = S5PV310_GPIO_Y2_NR,
> + .label = "GPY2",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY3(0),
> + .ngpio = S5PV310_GPIO_Y3_NR,
> + .label = "GPY3",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY4(0),
> + .ngpio = S5PV310_GPIO_Y4_NR,
> + .label = "GPY4",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY5(0),
> + .ngpio = S5PV310_GPIO_Y5_NR,
> + .label = "GPY5",
> + },
> + }, {
> + .config = &gpio_cfg_noint,
> + .chip = {
> + .base = S5PV310_GPY6(0),
> + .ngpio = S5PV310_GPIO_Y6_NR,
> + .label = "GPY6",
> + },
> + }, {
> .base = (S5P_VA_GPIO2 + 0xC00),
> .config = &gpio_cfg_noint,
> .irq_base = IRQ_EINT(0),
> diff --git a/arch/arm/mach-s5pv310/include/mach/gpio.h b/arch/arm/mach-
> s5pv310/include/mach/gpio.h
> index 20cb80c..4b44463 100644
> --- a/arch/arm/mach-s5pv310/include/mach/gpio.h
> +++ b/arch/arm/mach-s5pv310/include/mach/gpio.h
> @@ -50,6 +50,13 @@
> #define S5PV310_GPIO_X1_NR (8)
> #define S5PV310_GPIO_X2_NR (8)
> #define S5PV310_GPIO_X3_NR (8)
> +#define S5PV310_GPIO_Y0_NR (6)
> +#define S5PV310_GPIO_Y1_NR (4)
> +#define S5PV310_GPIO_Y2_NR (6)
> +#define S5PV310_GPIO_Y3_NR (8)
> +#define S5PV310_GPIO_Y4_NR (8)
> +#define S5PV310_GPIO_Y5_NR (8)
> +#define S5PV310_GPIO_Y6_NR (8)
> #define S5PV310_GPIO_Z_NR (7)
>
> /* GPIO bank numbers */
> @@ -87,7 +94,14 @@ enum s5p_gpio_number {
> S5PV310_GPIO_X1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X0),
> S5PV310_GPIO_X2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X1),
> S5PV310_GPIO_X3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X2),
> - S5PV310_GPIO_Z_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
> + S5PV310_GPIO_Y0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
> + S5PV310_GPIO_Y1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y0),
> + S5PV310_GPIO_Y2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y1),
> + S5PV310_GPIO_Y3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y2),
> + S5PV310_GPIO_Y4_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y3),
> + S5PV310_GPIO_Y5_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y4),
> + S5PV310_GPIO_Y6_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y5),
> + S5PV310_GPIO_Z_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_Y6),
> };
>
> /* S5PV310 GPIO number definitions */
> @@ -120,6 +134,13 @@ enum s5p_gpio_number {
> #define S5PV310_GPX1(_nr) (S5PV310_GPIO_X1_START + (_nr))
> #define S5PV310_GPX2(_nr) (S5PV310_GPIO_X2_START + (_nr))
> #define S5PV310_GPX3(_nr) (S5PV310_GPIO_X3_START + (_nr))
> +#define S5PV310_GPY0(_nr) (S5PV310_GPIO_Y0_START + (_nr))
> +#define S5PV310_GPY1(_nr) (S5PV310_GPIO_Y1_START + (_nr))
> +#define S5PV310_GPY2(_nr) (S5PV310_GPIO_Y2_START + (_nr))
> +#define S5PV310_GPY3(_nr) (S5PV310_GPIO_Y3_START + (_nr))
> +#define S5PV310_GPY4(_nr) (S5PV310_GPIO_Y4_START + (_nr))
> +#define S5PV310_GPY5(_nr) (S5PV310_GPIO_Y5_START + (_nr))
> +#define S5PV310_GPY6(_nr) (S5PV310_GPIO_Y6_START + (_nr))
> #define S5PV310_GPZ(_nr) (S5PV310_GPIO_Z_START + (_nr))
>
> /* the end of the S5PV310 specific gpios */
> --
Ok...but as you know, need to re-work based on latest.
Could you re-submit this based on my for-next which includes Exynos4?
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
2011-02-17 7:25 ` [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks Marek Szyprowski
@ 2011-02-17 7:25 ` Marek Szyprowski
2011-02-23 10:15 ` Kukjin Kim
2011-02-17 7:25 ` [PATCH 3/5] ARM: Samsung: add function to register gpio interrupt bank data Marek Szyprowski
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-17 7:25 UTC (permalink / raw)
To: linux-arm-kernel
This patch performs a global cleanup in s5p gpio interrupt support code.
The code is prepared for upcoming support for gpio interrupts on S5PC210
platform, which has 2 gpio banks (regions) instead of one (like on
S5PC110 and S5PC100).
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/plat-s5p/irq-gpioint.c | 106 +++++++++++++++++----------------------
1 files changed, 46 insertions(+), 60 deletions(-)
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 3b6bf89..af10328 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -22,77 +22,64 @@
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
-#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
+#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & ~(SZ_4K - 1))
-#define GPIOINT_CON_OFFSET 0x700
-#define GPIOINT_MASK_OFFSET 0x900
-#define GPIOINT_PEND_OFFSET 0xA00
+#define CON_OFFSET 0x700
+#define MASK_OFFSET 0x900
+#define PEND_OFFSET 0xA00
+#define REG_OFFSET(x) ((x) << 2)
static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
-static int s5p_gpioint_get_group(struct irq_data *data)
-{
- struct gpio_chip *chip = irq_data_get_irq_data(data);
- struct s3c_gpio_chip *s3c_chip = container_of(chip,
- struct s3c_gpio_chip, chip);
- int group;
-
- for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
- if (s3c_chip == irq_chips[group])
- break;
-
- return group;
-}
-
static int s5p_gpioint_get_offset(struct irq_data *data)
{
- struct gpio_chip *chip = irq_data_get_irq_data(data);
- struct s3c_gpio_chip *s3c_chip = container_of(chip,
- struct s3c_gpio_chip, chip);
-
- return data->irq - s3c_chip->irq_base;
+ struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ return data->irq - chip->irq_base;
}
static void s5p_gpioint_ack(struct irq_data *data)
{
+ struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
int group, offset, pend_offset;
unsigned int value;
- group = s5p_gpioint_get_group(data);
+ group = chip->group;
offset = s5p_gpioint_get_offset(data);
- pend_offset = group << 2;
+ pend_offset = REG_OFFSET(group);
- value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
- value |= 1 << offset;
- __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+ value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
+ value |= BIT(offset);
+ __raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
}
static void s5p_gpioint_mask(struct irq_data *data)
{
+ struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
int group, offset, mask_offset;
unsigned int value;
- group = s5p_gpioint_get_group(data);
+ group = chip->group;
offset = s5p_gpioint_get_offset(data);
- mask_offset = group << 2;
+ mask_offset = REG_OFFSET(group);
- value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
- value |= 1 << offset;
- __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+ value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ value |= BIT(offset);
+ __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
}
static void s5p_gpioint_unmask(struct irq_data *data)
{
+ struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
int group, offset, mask_offset;
unsigned int value;
- group = s5p_gpioint_get_group(data);
+ group = chip->group;
offset = s5p_gpioint_get_offset(data);
- mask_offset = group << 2;
+ mask_offset = REG_OFFSET(group);
- value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
- value &= ~(1 << offset);
- __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+ value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ value &= ~BIT(offset);
+ __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
}
static void s5p_gpioint_mask_ack(struct irq_data *data)
@@ -103,12 +90,13 @@ static void s5p_gpioint_mask_ack(struct irq_data *data)
static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
{
+ struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
int group, offset, con_offset;
unsigned int value;
- group = s5p_gpioint_get_group(data);
+ group = chip->group;
offset = s5p_gpioint_get_offset(data);
- con_offset = group << 2;
+ con_offset = REG_OFFSET(group);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -132,15 +120,15 @@ static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
return -EINVAL;
}
- value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+ value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
value &= ~(0x7 << (offset * 0x4));
value |= (type << (offset * 0x4));
- __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+ __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
return 0;
}
-struct irq_chip s5p_gpioint = {
+static struct irq_chip s5p_gpioint = {
.name = "s5p_gpioint",
.irq_ack = s5p_gpioint_ack,
.irq_mask = s5p_gpioint_mask,
@@ -151,30 +139,28 @@ struct irq_chip s5p_gpioint = {
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
- int group, offset, pend_offset, mask_offset;
- int real_irq;
+ int group, pend_offset, mask_offset;
unsigned int pend, mask;
for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
- pend_offset = group << 2;
- pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
- pend_offset);
+ struct s3c_gpio_chip *chip = irq_chips[group];
+ if (!chip)
+ continue;
+
+ pend_offset = REG_OFFSET(group);
+ pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
if (!pend)
continue;
- mask_offset = group << 2;
- mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
- mask_offset);
+ mask_offset = REG_OFFSET(group);
+ mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
pend &= ~mask;
- for (offset = 0; offset < 8; offset++) {
- if (pend & (1 << offset)) {
- struct s3c_gpio_chip *chip = irq_chips[group];
- if (chip) {
- real_irq = chip->irq_base + offset;
- generic_handle_irq(real_irq);
- }
- }
+ while (pend) {
+ int offset = fls(pend) - 1;
+ int real_irq = chip->irq_base + offset;
+ generic_handle_irq(real_irq);
+ pend &= ~BIT(offset);
}
}
}
@@ -202,7 +188,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
for (i = 0; i < chip->chip.ngpio; i++) {
irq = chip->irq_base + i;
set_irq_chip(irq, &s5p_gpioint);
- set_irq_data(irq, &chip->chip);
+ set_irq_data(irq, chip);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
--
1.7.1.569.g6f426
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code
2011-02-17 7:25 ` [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code Marek Szyprowski
@ 2011-02-23 10:15 ` Kukjin Kim
2011-02-25 9:00 ` Marek Szyprowski
0 siblings, 1 reply; 10+ messages in thread
From: Kukjin Kim @ 2011-02-23 10:15 UTC (permalink / raw)
To: linux-arm-kernel
Marek Szyprowski wrote:
>
> This patch performs a global cleanup in s5p gpio interrupt support code.
> The code is prepared for upcoming support for gpio interrupts on S5PC210
> platform, which has 2 gpio banks (regions) instead of one (like on
> S5PC110 and S5PC100).
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
> arch/arm/plat-s5p/irq-gpioint.c | 106
+++++++++++++++++--------------------
> --
> 1 files changed, 46 insertions(+), 60 deletions(-)
>
> diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-
> gpioint.c
> index 3b6bf89..af10328 100644
> --- a/arch/arm/plat-s5p/irq-gpioint.c
> +++ b/arch/arm/plat-s5p/irq-gpioint.c
> @@ -22,77 +22,64 @@
> #include <plat/gpio-core.h>
> #include <plat/gpio-cfg.h>
>
> -#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
> +#define GPIO_BASE(chip) (((unsigned long)(chip)->base) &
> ~(SZ_4K - 1))
>
Need SZ_4K here instead of 0xFFFFF000?
> -#define GPIOINT_CON_OFFSET 0x700
> -#define GPIOINT_MASK_OFFSET 0x900
> -#define GPIOINT_PEND_OFFSET 0xA00
> +#define CON_OFFSET 0x700
> +#define MASK_OFFSET 0x900
> +#define PEND_OFFSET 0xA00
I don't know why need to change above definitions...
> +#define REG_OFFSET(x) ((x) << 2)
>
Actually, this is used instead of "group << 2" in this file.
So how about "GPIOINT_REG_OFFSET(x)" like others?
> static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
>
> -static int s5p_gpioint_get_group(struct irq_data *data)
> -{
> - struct gpio_chip *chip = irq_data_get_irq_data(data);
> - struct s3c_gpio_chip *s3c_chip = container_of(chip,
> - struct s3c_gpio_chip, chip);
> - int group;
> -
> - for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
> - if (s3c_chip == irq_chips[group])
> - break;
> -
> - return group;
> -}
> -
> static int s5p_gpioint_get_offset(struct irq_data *data)
> {
> - struct gpio_chip *chip = irq_data_get_irq_data(data);
> - struct s3c_gpio_chip *s3c_chip = container_of(chip,
> - struct s3c_gpio_chip, chip);
> -
> - return data->irq - s3c_chip->irq_base;
> + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> + return data->irq - chip->irq_base;
> }
>
> static void s5p_gpioint_ack(struct irq_data *data)
> {
> + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> int group, offset, pend_offset;
> unsigned int value;
>
> - group = s5p_gpioint_get_group(data);
> + group = chip->group;
> offset = s5p_gpioint_get_offset(data);
> - pend_offset = group << 2;
> + pend_offset = REG_OFFSET(group);
>
> - value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
> - value |= 1 << offset;
> - __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
> + value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
> + value |= BIT(offset);
No need inclusion <linux/bitops.h>?
> + __raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
> }
>
> static void s5p_gpioint_mask(struct irq_data *data)
> {
> + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> int group, offset, mask_offset;
> unsigned int value;
>
> - group = s5p_gpioint_get_group(data);
> + group = chip->group;
> offset = s5p_gpioint_get_offset(data);
> - mask_offset = group << 2;
> + mask_offset = REG_OFFSET(group);
>
> - value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
> - value |= 1 << offset;
> - __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
> + value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
> + value |= BIT(offset);
> + __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
> }
>
> static void s5p_gpioint_unmask(struct irq_data *data)
> {
> + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> int group, offset, mask_offset;
> unsigned int value;
>
> - group = s5p_gpioint_get_group(data);
> + group = chip->group;
> offset = s5p_gpioint_get_offset(data);
> - mask_offset = group << 2;
> + mask_offset = REG_OFFSET(group);
>
> - value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
> - value &= ~(1 << offset);
> - __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
> + value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
> + value &= ~BIT(offset);
> + __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
> }
>
> static void s5p_gpioint_mask_ack(struct irq_data *data)
> @@ -103,12 +90,13 @@ static void s5p_gpioint_mask_ack(struct irq_data
*data)
>
> static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
> {
> + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> int group, offset, con_offset;
> unsigned int value;
>
> - group = s5p_gpioint_get_group(data);
> + group = chip->group;
> offset = s5p_gpioint_get_offset(data);
> - con_offset = group << 2;
> + con_offset = REG_OFFSET(group);
>
> switch (type) {
> case IRQ_TYPE_EDGE_RISING:
> @@ -132,15 +120,15 @@ static int s5p_gpioint_set_type(struct irq_data
*data,
> unsigned int type)
> return -EINVAL;
> }
>
> - value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
> + value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
> value &= ~(0x7 << (offset * 0x4));
> value |= (type << (offset * 0x4));
> - __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
> + __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
>
> return 0;
> }
>
> -struct irq_chip s5p_gpioint = {
> +static struct irq_chip s5p_gpioint = {
> .name = "s5p_gpioint",
> .irq_ack = s5p_gpioint_ack,
> .irq_mask = s5p_gpioint_mask,
> @@ -151,30 +139,28 @@ struct irq_chip s5p_gpioint = {
>
> static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
> {
> - int group, offset, pend_offset, mask_offset;
> - int real_irq;
> + int group, pend_offset, mask_offset;
> unsigned int pend, mask;
>
> for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
> - pend_offset = group << 2;
> - pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
> - pend_offset);
> + struct s3c_gpio_chip *chip = irq_chips[group];
> + if (!chip)
> + continue;
> +
> + pend_offset = REG_OFFSET(group);
> + pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET +
> pend_offset);
> if (!pend)
> continue;
>
> - mask_offset = group << 2;
> - mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
> - mask_offset);
> + mask_offset = REG_OFFSET(group);
> + mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET +
> mask_offset);
> pend &= ~mask;
>
> - for (offset = 0; offset < 8; offset++) {
> - if (pend & (1 << offset)) {
> - struct s3c_gpio_chip *chip =
irq_chips[group];
> - if (chip) {
> - real_irq = chip->irq_base + offset;
> - generic_handle_irq(real_irq);
> - }
> - }
> + while (pend) {
> + int offset = fls(pend) - 1;
__ffs?
And hmm...do we really need while loop here?
> + int real_irq = chip->irq_base + offset;
> + generic_handle_irq(real_irq);
> + pend &= ~BIT(offset);
> }
> }
> }
> @@ -202,7 +188,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip
> *chip)
> for (i = 0; i < chip->chip.ngpio; i++) {
> irq = chip->irq_base + i;
> set_irq_chip(irq, &s5p_gpioint);
> - set_irq_data(irq, &chip->chip);
> + set_irq_data(irq, chip);
?
> set_irq_handler(irq, handle_level_irq);
> set_irq_flags(irq, IRQF_VALID);
> }
> --
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code
2011-02-23 10:15 ` Kukjin Kim
@ 2011-02-25 9:00 ` Marek Szyprowski
0 siblings, 0 replies; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-25 9:00 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
On Wednesday, February 23, 2011 11:15 AM Kukjin Kim wrote:
> Marek Szyprowski wrote:
> >
> > This patch performs a global cleanup in s5p gpio interrupt support code.
> > The code is prepared for upcoming support for gpio interrupts on S5PC210
> > platform, which has 2 gpio banks (regions) instead of one (like on
> > S5PC110 and S5PC100).
> >
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> > ---
> > arch/arm/plat-s5p/irq-gpioint.c | 106
> +++++++++++++++++--------------------
> > --
> > 1 files changed, 46 insertions(+), 60 deletions(-)
> >
> > diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-
> > gpioint.c
> > index 3b6bf89..af10328 100644
> > --- a/arch/arm/plat-s5p/irq-gpioint.c
> > +++ b/arch/arm/plat-s5p/irq-gpioint.c
> > @@ -22,77 +22,64 @@
> > #include <plat/gpio-core.h>
> > #include <plat/gpio-cfg.h>
> >
> > -#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
> > +#define GPIO_BASE(chip) (((unsigned long)(chip)->base) &
> > ~(SZ_4K - 1))
> >
>
> Need SZ_4K here instead of 0xFFFFF000?
No problem, I can change it to 0xFFFFF000
>
> > -#define GPIOINT_CON_OFFSET 0x700
> > -#define GPIOINT_MASK_OFFSET 0x900
> > -#define GPIOINT_PEND_OFFSET 0xA00
> > +#define CON_OFFSET 0x700
> > +#define MASK_OFFSET 0x900
> > +#define PEND_OFFSET 0xA00
>
> I don't know why need to change above definitions...
I've shortened them to make the code the uses them to fit 80 characters
per line... They are just a local defines that imho don't need to be
prefixed with GPIOINT_
> > +#define REG_OFFSET(x) ((x) << 2)
> >
> Actually, this is used instead of "group << 2" in this file.
> So how about "GPIOINT_REG_OFFSET(x)" like others?
Ok.
> > static void s5p_gpioint_ack(struct irq_data *data)
> > {
> > + struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
> > int group, offset, pend_offset;
> > unsigned int value;
> >
> > - group = s5p_gpioint_get_group(data);
> > + group = chip->group;
> > offset = s5p_gpioint_get_offset(data);
> > - pend_offset = group << 2;
> > + pend_offset = REG_OFFSET(group);
> >
> > - value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
> > - value |= 1 << offset;
> > - __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
> > + value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
> > + value |= BIT(offset);
>
> No need inclusion <linux/bitops.h>?
It has been included indirectly, because the code compiled fine.
snip
> > static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
> > {
> > - int group, offset, pend_offset, mask_offset;
> > - int real_irq;
> > + int group, pend_offset, mask_offset;
> > unsigned int pend, mask;
> >
> > for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
> > - pend_offset = group << 2;
> > - pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
> > - pend_offset);
> > + struct s3c_gpio_chip *chip = irq_chips[group];
> > + if (!chip)
> > + continue;
> > +
> > + pend_offset = REG_OFFSET(group);
> > + pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET +
> > pend_offset);
> > if (!pend)
> > continue;
> >
> > - mask_offset = group << 2;
> > - mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
> > - mask_offset);
> > + mask_offset = REG_OFFSET(group);
> > + mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET +
> > mask_offset);
> > pend &= ~mask;
> >
> > - for (offset = 0; offset < 8; offset++) {
> > - if (pend & (1 << offset)) {
> > - struct s3c_gpio_chip *chip =
> irq_chips[group];
> > - if (chip) {
> > - real_irq = chip->irq_base + offset;
> > - generic_handle_irq(real_irq);
> > - }
> > - }
> > + while (pend) {
> > + int offset = fls(pend) - 1;
>
> __ffs?
I don't see much difference between ffs and fls here...
> And hmm...do we really need while loop here?
Yes, because more than one gpio pin in a group can issue an interrupt at the
same time. The previous version used for() loop here.
>
> > + int real_irq = chip->irq_base + offset;
> > + generic_handle_irq(real_irq);
> > + pend &= ~BIT(offset);
> > }
> > }
> > }
> > @@ -202,7 +188,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip
> > *chip)
> > for (i = 0; i < chip->chip.ngpio; i++) {
> > irq = chip->irq_base + i;
> > set_irq_chip(irq, &s5p_gpioint);
> > - set_irq_data(irq, &chip->chip);
> > + set_irq_data(irq, chip);
>
> ?
This simplifies all the functions that use get_irq_data. Now they get s3c_gpio_chip
directly and don't need to extract it with contrainer_of().
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/5] ARM: Samsung: add function to register gpio interrupt bank data
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
2011-02-17 7:25 ` [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks Marek Szyprowski
2011-02-17 7:25 ` [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code Marek Szyprowski
@ 2011-02-17 7:25 ` Marek Szyprowski
2011-02-17 7:25 ` [PATCH 4/5] ARM: S5PC210: add support for gpio interrupts Marek Szyprowski
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-17 7:25 UTC (permalink / raw)
To: linux-arm-kernel
This patch removes all global data from common s5p gpio interrupt
handler code. This enables to reuse this code on S5PC210 platform.
Instead of global data (IRQ_GPIOINT interrupt number,
S5P_GPIOINT_GROUP_MAXNR groups count), a s5p_register_gpioint_bank()
function is introduced. It is aimed to be called from gpiolib init.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-s5pc100/gpiolib.c | 1 +
arch/arm/mach-s5pv210/gpiolib.c | 1 +
arch/arm/plat-s5p/irq-gpioint.c | 69 +++++++++++++++++++++----
arch/arm/plat-samsung/include/plat/gpio-cfg.h | 16 ++++++
4 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c
index 20856eb..2842394 100644
--- a/arch/arm/mach-s5pc100/gpiolib.c
+++ b/arch/arm/mach-s5pc100/gpiolib.c
@@ -348,6 +348,7 @@ static __init int s5pc100_gpiolib_init(void)
}
samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
+ s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
return 0;
}
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
index ab673ef..1ba20a7 100644
--- a/arch/arm/mach-s5pv210/gpiolib.c
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -281,6 +281,7 @@ static __init int s5pv210_gpiolib_init(void)
}
samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
+ s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
return 0;
}
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index af10328..70329e6 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -17,6 +17,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <mach/map.h>
#include <plat/gpio-core.h>
@@ -29,7 +30,17 @@
#define PEND_OFFSET 0xA00
#define REG_OFFSET(x) ((x) << 2)
-static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
+struct s5p_gpioint_bank
+{
+ struct list_head list;
+ int start;
+ int nr_groups;
+ int irq;
+ struct s3c_gpio_chip **chips;
+ void (*handler)(unsigned int, struct irq_desc *);
+};
+
+LIST_HEAD(banks);
static int s5p_gpioint_get_offset(struct irq_data *data)
{
@@ -139,11 +150,12 @@ static struct irq_chip s5p_gpioint = {
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
+ struct s5p_gpioint_bank *bank = get_irq_data(irq);
int group, pend_offset, mask_offset;
unsigned int pend, mask;
- for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
- struct s3c_gpio_chip *chip = irq_chips[group];
+ for (group = 0; group < bank->nr_groups; group++) {
+ struct s3c_gpio_chip *chip = bank->chips[group];
if (!chip)
continue;
@@ -168,23 +180,44 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
static int used_gpioint_groups = 0;
- static bool handler_registered = 0;
int irq, group = chip->group;
int i;
+ struct s5p_gpioint_bank *bank = NULL;
if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
return -ENOMEM;
+ list_for_each_entry(bank, &banks, list) {
+ if (group >= bank->start &&
+ group < bank->start + bank->nr_groups)
+ break;
+ }
+ if (!bank)
+ return -EINVAL;
+
+ if (!bank->handler) {
+ bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
+ bank->nr_groups, GFP_KERNEL);
+ if (!bank->chips)
+ return -ENOMEM;
+
+ set_irq_chained_handler(bank->irq, s5p_gpioint_handler);
+ set_irq_data(bank->irq, bank);
+ bank->handler = s5p_gpioint_handler;
+ printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
+ bank->irq);
+ }
+
+ /*
+ * chained GPIO irq has been sucessfully registered, allocate new gpio
+ * int group and assign irq nubmers
+ */
+
chip->irq_base = S5P_GPIOINT_BASE +
used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
used_gpioint_groups++;
- if (!handler_registered) {
- set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
- handler_registered = 1;
- }
-
- irq_chips[group] = chip;
+ bank->chips[group - bank->start] = chip;
for (i = 0; i < chip->chip.ngpio; i++) {
irq = chip->irq_base + i;
set_irq_chip(irq, &s5p_gpioint);
@@ -221,3 +254,19 @@ int __init s5p_register_gpio_interrupt(int pin)
}
return ret;
}
+
+int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
+{
+ struct s5p_gpioint_bank *bank;
+
+ bank = kzalloc(sizeof(*bank), GFP_KERNEL);
+ if (!bank)
+ return -ENOMEM;
+
+ bank->start = start;
+ bank->nr_groups = nr_groups;
+ bank->irq = chain_irq;
+
+ list_add_tail(&bank->list, &banks);
+ return 0;
+}
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index e4b5cf1..5e04fa6 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -225,4 +225,20 @@ extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
*/
extern int s5p_register_gpio_interrupt(int pin);
+/** s5p_register_gpioint_bank() - add gpio bank for further gpio interrupt
+ * registration (see s5p_register_gpio_interrupt function)
+ * @chain_irq: chained irq number for the gpio int handler for this bank
+ * @start: start gpio group number of this bank
+ * @nr_groups: number of gpio groups handled by this bank
+ *
+ * This functions registers initial information about gpio banks that
+ * can be later used by the s5p_register_gpio_interrupt() function to
+ * enable support for gpio interrupt for particular gpio group.
+ */
+#ifdef CONFIG_S5P_GPIO_INT
+extern int s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups);
+#else
+#define s5p_register_gpioint_bank(chain_irq, start, nr_groups) do { } while (0)
+#endif
+
#endif /* __PLAT_GPIO_CFG_H */
--
1.7.1.569.g6f426
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/5] ARM: S5PC210: add support for gpio interrupts
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
` (2 preceding siblings ...)
2011-02-17 7:25 ` [PATCH 3/5] ARM: Samsung: add function to register gpio interrupt bank data Marek Szyprowski
@ 2011-02-17 7:25 ` Marek Szyprowski
2011-02-17 7:25 ` [PATCH 5/5] ARM: S5PC210: add a placeholder for board specific interrupts Marek Szyprowski
2011-03-12 3:23 ` [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Kukjin Kim
5 siblings, 0 replies; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-17 7:25 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds support for gpio interrupts on Samsung S5PC210 platform.
Common s5p-gpioint.c code is used for handling gpio interrupts. Each gpio
line that needs gpio interrupt support must be later registered with
s5p_register_gpio_interrupt() function.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-s5pv310/gpiolib.c | 18 +++++++++++++++---
arch/arm/mach-s5pv310/include/mach/irqs.h | 12 ++++++++++--
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
index f417ecd..288f672 100644
--- a/arch/arm/mach-s5pv310/gpiolib.c
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -304,6 +304,7 @@ static __init int s5pv310_gpiolib_init(void)
{
struct s3c_gpio_chip *chip;
int i;
+ int group = 0;
int nr_chips;
/* GPIO part 1 */
@@ -312,8 +313,11 @@ static __init int s5pv310_gpiolib_init(void)
nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL)
+ if (chip->config == NULL) {
chip->config = &gpio_cfg;
+ /* Assign the GPIO interrupt group */
+ chip->group = group++;
+ }
if (chip->base == NULL)
chip->base = S5P_VA_GPIO1 + (i) * 0x20;
}
@@ -326,8 +330,11 @@ static __init int s5pv310_gpiolib_init(void)
nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL)
+ if (chip->config == NULL) {
chip->config = &gpio_cfg;
+ /* Assign the GPIO interrupt group */
+ chip->group = group++;
+ }
if (chip->base == NULL)
chip->base = S5P_VA_GPIO2 + (i) * 0x20;
}
@@ -340,13 +347,18 @@ static __init int s5pv310_gpiolib_init(void)
nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL)
+ if (chip->config == NULL) {
chip->config = &gpio_cfg;
+ /* Assign the GPIO interrupt group */
+ chip->group = group++;
+ }
if (chip->base == NULL)
chip->base = S5P_VA_GPIO3 + (i) * 0x20;
}
samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
+ s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
+ s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
return 0;
}
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 536b0b5..64dbe15 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -85,6 +85,9 @@
#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
+#define IRQ_GPIO_XB COMBINER_IRQ(24, 0)
+#define IRQ_GPIO_XA COMBINER_IRQ(24, 1)
+
#define IRQ_UART0 COMBINER_IRQ(26, 0)
#define IRQ_UART1 COMBINER_IRQ(26, 1)
#define IRQ_UART2 COMBINER_IRQ(26, 2)
@@ -139,8 +142,13 @@
#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
-/* Set the default NR_IRQS */
+/* optional GPIO interrupts */
+#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32)
+#define IRQ_GPIO1_NR_GROUPS 16
+#define IRQ_GPIO2_NR_GROUPS 9
+#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
-#define NR_IRQS (S5P_IRQ_EINT_BASE + 32)
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_GPIO_END)
#endif /* __ASM_ARCH_IRQS_H */
--
1.7.1.569.g6f426
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/5] ARM: S5PC210: add a placeholder for board specific interrupts
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
` (3 preceding siblings ...)
2011-02-17 7:25 ` [PATCH 4/5] ARM: S5PC210: add support for gpio interrupts Marek Szyprowski
@ 2011-02-17 7:25 ` Marek Szyprowski
2011-03-12 3:23 ` [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Kukjin Kim
5 siblings, 0 replies; 10+ messages in thread
From: Marek Szyprowski @ 2011-02-17 7:25 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds a placeholder for board specific interrupts on S5PC210
platform.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-s5pv310/include/mach/irqs.h | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 64dbe15..a28de22 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -148,7 +148,11 @@
#define IRQ_GPIO2_NR_GROUPS 9
#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
+/* optional board specific irqs */
+#define IRQ_BOARD_START IRQ_GPIO_END
+#define IRQ_NR_BOARD 16
+
/* Set the default NR_IRQS */
-#define NR_IRQS (IRQ_GPIO_END)
+#define NR_IRQS (IRQ_GPIO_END + IRQ_NR_BOARD)
#endif /* __ASM_ARCH_IRQS_H */
--
1.7.1.569.g6f426
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update
2011-02-17 7:25 [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update Marek Szyprowski
` (4 preceding siblings ...)
2011-02-17 7:25 ` [PATCH 5/5] ARM: S5PC210: add a placeholder for board specific interrupts Marek Szyprowski
@ 2011-03-12 3:23 ` Kukjin Kim
5 siblings, 0 replies; 10+ messages in thread
From: Kukjin Kim @ 2011-03-12 3:23 UTC (permalink / raw)
To: linux-arm-kernel
Marek Szyprowski wrote:
>
> Hello,
>
> This patch series perform an update on interrupts support for
> S5PC210/S5PV310/EXYNOS4 platform. Two optional features have been added.
> The first one is GPIO interrupts handler, a second is support for board
> specific interrupts. The patches have been prepared to maximise the code
> reuse, so common code for gpio interrupts for s5pc100, s5pc110 & s5pc210
> have been prepared.
>
> The patches have been prepared against
> git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> for-next branch (commit 857ddb87db).
>
> Patches that make use of these 2 optional features for universal c210
> board will follow soon.
>
> Best regards
> --
> Marek Szyprowski
> Samsung Poland R&D Center
>
>
>
> Patch summary:
>
> Marek Szyprowski (5):
> ARM: S5PV310: Add missing GPYx banks.
> ARM: Samsung: cleanup S5P gpio interrupt code
> ARM: Samsung: add function to register gpio interrupt bank data
> ARM: S5PC210: add support for gpio interrupts
> ARM: S5PC210: add a placeholder for board specific interrupts
>
> arch/arm/mach-s5pc100/gpiolib.c | 1 +
> arch/arm/mach-s5pv210/gpiolib.c | 1 +
> arch/arm/mach-s5pv310/gpiolib.c | 67 ++++++++++-
> arch/arm/mach-s5pv310/include/mach/gpio.h | 23 ++++-
> arch/arm/mach-s5pv310/include/mach/irqs.h | 16 ++-
> arch/arm/plat-s5p/irq-gpioint.c | 169
+++++++++++++++--------
> --
> arch/arm/plat-samsung/include/plat/gpio-cfg.h | 16 +++
> 7 files changed, 220 insertions(+), 73 deletions(-)
>
> --
> 1.7.1.569.g6f426
Marek,
Could you please re-send this based on my latest for-next which includes
Exynos4 changes?
And would be better to be separate gpio interrupt and board specific
interrupt.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 10+ messages in thread