Re: [PATCH 1/2] ARM: S5P6440: Add S5P6440 GPIO support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



See attached files from Samsungs CQ database

Ben Dooks wrote:
On Thu, Jan 14, 2010 at 04:28:48PM +0100, Niels Langendorff wrote:
Make sure this patch includes the fixes I supplied in the Samsung CQ database APTT00000153

Which would those be, other mortals don't have access to that information.

[snip]
diff -Naur linux-base/arch/arm/plat-s3c64xx/gpiolib.c linux/arch/arm/plat-s3c64xx/gpiolib.c
--- linux-base/arch/arm/plat-s3c64xx/gpiolib.c	2009-06-25 17:02:41.000000000 +0200
+++ linux/arch/arm/plat-s3c64xx/gpiolib.c	2009-06-26 11:11:18.000000000 +0200
@@ -168,15 +168,16 @@
 	void __iomem *regcon = base;
 	unsigned long con;
 	unsigned long dat;
+	unsigned con_offset = offset;
 
-	if (offset > 7)
-		offset -= 8;
+	if (con_offset > 7)
+		con_offset -= 8;
 	else
 		regcon -= 4;
 
 	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
 
 	dat = __raw_readl(base + OFF_GPDAT);
 	if (value)
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c
--- linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c	2009-06-17 10:54:11.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c	2009-06-17 10:57:39.000000000 +0200
@@ -132,6 +132,44 @@
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+				 unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift;
+	u32 con;
+
+	switch(off) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+			shift = (off & 7) * 4;
+			reg -= 4;
+			break;
+		case 6:
+			shift = ((off + 1) & 7) * 4;
+			reg -= 4;
+		default:
+			shift = ((off + 1) & 7) * 4;
+			break;
+	}
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0xf << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
 int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 				 unsigned int off, unsigned int cfg)
 {
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
--- linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-17 10:54:11.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-17 10:59:12.000000000 +0200
@@ -72,6 +72,28 @@
 				     unsigned int off, unsigned int cfg);
 
 /**
+ * s3c_gpio_setcfg_s3c64xx_4bit_rbank - S3C64XX 4bit single register GPIO R config.
+ * @chip: The gpio chip that is being configured (always R).
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *	0000 = Input
+ *	0001 = Output
+ *	others = Special functions (dependant on bank)
+ *
+ * A special function is implemented for the R bank because of the GPIO gaps
+ * in this bank
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+					unsigned int off, unsigned int cfg);
+
+/**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
@@ -83,6 +105,8 @@
  *	0001 = Output
  *	others = Special functions (dependant on bank)
  *
+ * Note, do not use this function for register bank R
+ *
  * Note, since the code to deal with the case where there are two control
  * registers instead of one, we do not have a seperate set of functions for
  * each case.
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c
--- linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-17 10:54:07.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-17 11:01:00.000000000 +0200
@@ -210,7 +210,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
 	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit_rbank,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 	.set_pin	= s3c_gpio_setpin_updown,
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c
--- linux-2.6-samsung-base/arch/arm/plat-s3c/gpio-config.c	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/gpio-config.c	2009-06-26 13:56:14.000000000 +0200
@@ -132,6 +132,44 @@
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+				 unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift;
+	u32 con;
+
+	switch(off) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+			shift = (off & 7) * 4;
+			reg -= 4;
+			break;
+		case 6:
+			shift = ((off + 1) & 7) * 4;
+			reg -= 4;
+		default:
+			shift = ((off + 1) & 7) * 4;
+			break;
+	}
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0xf << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
 int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 				 unsigned int off, unsigned int cfg)
 {
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
--- linux-2.6-samsung-base/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2009-06-26 13:55:58.000000000 +0200
@@ -72,6 +72,28 @@
 				     unsigned int off, unsigned int cfg);
 
 /**
+ * s3c_gpio_setcfg_s3c64xx_4bit_rbank - S3C64XX 4bit single register GPIO R config.
+ * @chip: The gpio chip that is being configured (always R).
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *	0000 = Input
+ *	0001 = Output
+ *	others = Special functions (dependant on bank)
+ *
+ * A special function is implemented for the R bank because of the GPIO gaps
+ * in this bank
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit_rbank(struct s3c_gpio_chip *chip,
+					unsigned int off, unsigned int cfg);
+
+/**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
@@ -83,6 +105,8 @@
  *	0001 = Output
  *	others = Special functions (dependant on bank)
  *
+ * Note, do not use this function for register bank R
+ *
  * Note, since the code to deal with the case where there are two control
  * registers instead of one, we do not have a seperate set of functions for
  * each case.
diff -Naur linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c
--- linux-2.6-samsung-base/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-08 09:53:44.000000000 +0200
+++ linux-2.6-samsung/arch/arm/plat-s5p64xx/gpiolib.c	2009-06-26 13:55:41.000000000 +0200
@@ -160,6 +160,38 @@
 
 }
 
+static int s5p64xx_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+
+	switch(offset) {
+		case 6:
+			offset += 1;
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+			regcon -= 4;
+			break;
+		default:
+			offset -= 7;
+			break;
+	}
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, regcon);
+
+	gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
 static int s5p64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
 				       unsigned offset, int value)
 {
@@ -168,15 +200,61 @@
 	void __iomem *regcon = base;
 	unsigned long con;
 	unsigned long dat;
+	unsigned con_offset = offset;
 
-	if (offset > 7)
-		offset -= 8;
+	if (con_offset > 7)
+		con_offset -= 8;
 	else
 		regcon -= 4;
 
 	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
+
+	dat = __raw_readl(base + OFF_GPDAT);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + OFF_GPDAT);
+	__raw_writel(con, regcon);
+	__raw_writel(dat, base + OFF_GPDAT);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+static int s5p64xx_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+	unsigned long dat;
+	unsigned con_offset  = offset;
+
+	switch(con_offset) {
+		case 6:
+			con_offset += 1;
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+			regcon -= 4;
+			break;
+		default:
+			con_offset -= 7;
+			break;
+	}
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
 
 	dat = __raw_readl(base + OFF_GPDAT);
 	if (value)
@@ -210,7 +288,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
 	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit_rbank,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 	.set_pin	= s3c_gpio_setpin_updown,
@@ -261,7 +339,11 @@
 			.ngpio	= S5P64XX_GPIO_H_NR,
 			.label	= "GPH",
 		},
-	}, {
+	}, 
+};
+
+static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+	{
 		.base	= S5P64XX_GPR_BASE + 0x4,
 		.config	= &gpio_4bit_cfg_eint0011,
 		.chip	= {
@@ -351,6 +433,12 @@
 	chip->chip.direction_output = s5p64xx_gpiolib_4bit2_output;
 }
 
+static __init void s5p64xx_gpiolib_add_rbank_4bit2(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = s5p64xx_gpiolib_rbank_4bit2_input;
+	chip->chip.direction_output = s5p64xx_gpiolib_rbank_4bit2_output;
+}
+
 static __init void s5p64xx_gpiolib_add(struct s3c_gpio_chip *chips,
 				       int nr_chips,
 				       void (*fn)(struct s3c_gpio_chip *))
@@ -370,6 +458,9 @@
 	s5p64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
 			    s5p64xx_gpiolib_add_4bit2);
 
+	s5p64xx_gpiolib_add(gpio_rbank_4bit2, ARRAY_SIZE(gpio_rbank_4bit2),
+			    s5p64xx_gpiolib_add_rbank_4bit2);
+
 	s5p64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), NULL);
 
 	return 0;

[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux