[RFC PATCH 08/18] ARM: msm: fix gpiomux config for multiplatform

Arnd Bergmann arnd at arndb.de
Wed Mar 4 11:33:02 PST 2015


The msm gpiomux code uses a global symbol for configuration
that has multiple definitions, and a size that depends on
the SoC that is configured. Both of these are broken
when dealing with a kernel that enables more than one soc,
so we have to pass the data at boot time.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-msm/board-msm7x30.c |  4 +++-
 arch/arm/mach-msm/board-qsd8x50.c |  3 +++
 arch/arm/mach-msm/gpiomux-8x50.c  |  2 +-
 arch/arm/mach-msm/gpiomux-v1.h    |  9 ++-------
 arch/arm/mach-msm/gpiomux.c       | 18 +++++++++---------
 arch/arm/mach-msm/gpiomux.h       |  8 +++++++-
 drivers/gpio/gpio-msm-v1.c        | 16 +++++++++++-----
 7 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index e19109f69096..a964e3e3724d 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -99,7 +99,7 @@ static struct msm_otg_platform_data msm_otg_pdata = {
 	.phy_clk_reset		= hsusb_phy_clk_reset,
 };
 
-struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+static struct msm_gpiomux_config msm7x30_gpiomux_configs[MSM7X30_GPIOMUX_NGPIOS] = {
 #ifdef CONFIG_SERIAL_MSM_CONSOLE
 	[49] = { /* UART2 RFR */
 		.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
@@ -139,6 +139,8 @@ static void __init msm7x30_init_irq(void)
 
 static void __init msm7x30_init(void)
 {
+	gpiomux_init(msm7x30_gpiomux_configs,
+		     ARRAY_SIZE(msm7x30_gpiomux_configs));
 	msm_device_otg.dev.platform_data = &msm_otg_pdata;
 	msm_device_hsusb.dev.parent = &msm_device_otg.dev;
 	msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 24f4ae061f79..259ea05c41b9 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -36,6 +36,7 @@
 
 #include "devices.h"
 #include "common.h"
+#include "gpiomux.h"
 
 static const resource_size_t qsd8x50_surf_smc91x_base __initconst = 0x70000300;
 static const unsigned        qsd8x50_surf_smc91x_gpio __initconst = 156;
@@ -228,6 +229,8 @@ static void __init qsd8x50_init_irq(void)
 
 static void __init qsd8x50_init(void)
 {
+	gpiomux_init(qsd8x50_gpiomux_configs,
+		     ARRAY_SIZE(qsd8x50_gpiomux_configs));
 	msm_device_otg.dev.platform_data = &msm_otg_pdata;
 	msm_device_hsusb.dev.parent = &msm_device_otg.dev;
 	msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
index f7a4ea593c95..6851342ec049 100644
--- a/arch/arm/mach-msm/gpiomux-8x50.c
+++ b/arch/arm/mach-msm/gpiomux-8x50.c
@@ -29,7 +29,7 @@
 #define SDC1_SUSPEND_CONFIG (GPIOMUX_VALID | GPIOMUX_PULL_DOWN\
 				| GPIOMUX_FUNC_GPIO | GPIOMUX_DRV_2MA)
 
-struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+struct msm_gpiomux_config qsd8x50_gpiomux_configs[QSD8X50_GPIOMUX_NGPIOS] = {
 	[86] = { /* UART3 RX */
 		.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
 			     GPIOMUX_FUNC_1 | GPIOMUX_VALID,
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
index 71d86feba450..733c11aa7707 100644
--- a/arch/arm/mach-msm/gpiomux-v1.h
+++ b/arch/arm/mach-msm/gpiomux-v1.h
@@ -17,13 +17,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
 #define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
 
-#if defined(CONFIG_ARCH_MSM7X30)
-#define GPIOMUX_NGPIOS 182
-#elif defined(CONFIG_ARCH_QSD8X50)
-#define GPIOMUX_NGPIOS 165
-#else
-#define GPIOMUX_NGPIOS 133
-#endif
+#define MSM7X30_GPIOMUX_NGPIOS 182
+#define QSD8X50_GPIOMUX_NGPIOS 165
 
 typedef u32 gpiomux_config_t;
 
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 2b8e2d217082..768de1a05a56 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -20,6 +20,8 @@
 #include "proc_comm.h"
 
 static DEFINE_SPINLOCK(gpiomux_lock);
+static int gpiomux_ngpios;
+static struct msm_gpiomux_config *msm_gpiomux_configs;
 
 static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
 {
@@ -43,7 +45,7 @@ int msm_gpiomux_write(unsigned gpio,
 	unsigned long irq_flags;
 	gpiomux_config_t setting;
 
-	if (gpio >= GPIOMUX_NGPIOS)
+	if (gpio >= gpiomux_ngpios)
 		return -EINVAL;
 
 	spin_lock_irqsave(&gpiomux_lock, irq_flags);
@@ -61,14 +63,13 @@ int msm_gpiomux_write(unsigned gpio,
 	spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
 	return 0;
 }
-EXPORT_SYMBOL(msm_gpiomux_write);
 
 int msm_gpiomux_get(unsigned gpio)
 {
 	struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
 	unsigned long irq_flags;
 
-	if (gpio >= GPIOMUX_NGPIOS)
+	if (gpio >= gpiomux_ngpios)
 		return -EINVAL;
 
 	spin_lock_irqsave(&gpiomux_lock, irq_flags);
@@ -77,14 +78,13 @@ int msm_gpiomux_get(unsigned gpio)
 	spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
 	return 0;
 }
-EXPORT_SYMBOL(msm_gpiomux_get);
 
 int msm_gpiomux_put(unsigned gpio)
 {
 	struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
 	unsigned long irq_flags;
 
-	if (gpio >= GPIOMUX_NGPIOS)
+	if (gpio >= gpiomux_ngpios)
 		return -EINVAL;
 
 	spin_lock_irqsave(&gpiomux_lock, irq_flags);
@@ -94,13 +94,14 @@ int msm_gpiomux_put(unsigned gpio)
 	spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
 	return 0;
 }
-EXPORT_SYMBOL(msm_gpiomux_put);
 
-static int __init gpiomux_init(void)
+int __init gpiomux_init(struct msm_gpiomux_config *config, unsigned int ngpios)
 {
 	unsigned n;
+	msm_gpiomux_configs = config;
+	gpiomux_ngpios = ngpios;
 
-	for (n = 0; n < GPIOMUX_NGPIOS; ++n) {
+	for (n = 0; n < gpiomux_ngpios; ++n) {
 		msm_gpiomux_configs[n].ref = 0;
 		if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID))
 			continue;
@@ -108,4 +109,3 @@ static int __init gpiomux_init(void)
 	}
 	return 0;
 }
-postcore_initcall(gpiomux_init);
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
index 4410d7766f93..cdc1578d1e73 100644
--- a/arch/arm/mach-msm/gpiomux.h
+++ b/arch/arm/mach-msm/gpiomux.h
@@ -65,7 +65,7 @@ enum {
  * of that flag will prevent the configuration from being applied
  * during state transitions.
  */
-extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
+extern struct msm_gpiomux_config qsd8x50_gpiomux_configs[QSD8X50_GPIOMUX_NGPIOS];
 
 /* Install a new configuration to the gpio line.  To avoid overwriting
  * a configuration, leave the VALID bit out.
@@ -73,6 +73,8 @@ extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
 int msm_gpiomux_write(unsigned gpio,
 		      gpiomux_config_t active,
 		      gpiomux_config_t suspended);
+
+int gpiomux_init(struct msm_gpiomux_config *config, unsigned int ngpios);
 #else
 static inline int msm_gpiomux_write(unsigned gpio,
 				    gpiomux_config_t active,
@@ -80,5 +82,9 @@ static inline int msm_gpiomux_write(unsigned gpio,
 {
 	return -ENOSYS;
 }
+int gpiomux_init(struct msm_gpiomux_config *config, unsigned int ngpios)
+{
+	return 0;
+}
 #endif
 #endif
diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c
index edf285e26667..589115c1faa2 100644
--- a/drivers/gpio/gpio-msm-v1.c
+++ b/drivers/gpio/gpio-msm-v1.c
@@ -328,8 +328,11 @@ struct msm_gpio_chip {
 struct msm_gpio_initdata {
 	struct msm_gpio_chip *chips;
 	int count;
+	bool mux;
 };
 
+static bool msm_gpio_mux;
+
 static void msm_gpio_writel(struct msm_gpio_chip *chip, u32 val,
 			    enum msm_gpio_reg reg)
 {
@@ -446,20 +449,19 @@ static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 	return MSM_GPIO_TO_INT(chip->base + offset);
 }
 
-#ifdef CONFIG_MSM_GPIOMUX
 static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
+	if (!IS_ENABLED(CONFIG_MSM_GPIOMUX) || !msm_gpio_mux)
+		return 0;
 	return msm_gpiomux_get(chip->base + offset);
 }
 
 static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
+	if (!IS_ENABLED(CONFIG_MSM_GPIOMUX) || !msm_gpio_mux)
+		return;
 	msm_gpiomux_put(chip->base + offset);
 }
-#else
-#define msm_gpio_request NULL
-#define msm_gpio_free NULL
-#endif
 
 static struct msm_gpio_chip *msm_gpio_chips;
 static int msm_gpio_count;
@@ -476,6 +478,7 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x01[] = {
 static struct msm_gpio_initdata msm_gpio_7x01_init = {
 	.chips = msm_gpio_chips_msm7x01,
 	.count = ARRAY_SIZE(msm_gpio_chips_msm7x01),
+	.mux = false,
 };
 
 static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = {
@@ -492,6 +495,7 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = {
 static struct msm_gpio_initdata msm_gpio_7x30_init = {
 	.chips = msm_gpio_chips_msm7x30,
 	.count = ARRAY_SIZE(msm_gpio_chips_msm7x30),
+	.mux = true,
 };
 
 static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = {
@@ -508,6 +512,7 @@ static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = {
 static struct msm_gpio_initdata msm_gpio_8x50_init = {
 	.chips = msm_gpio_chips_qsd8x50,
 	.count = ARRAY_SIZE(msm_gpio_chips_qsd8x50),
+	.mux = true,
 };
 
 static void msm_gpio_irq_ack(struct irq_data *d)
@@ -643,6 +648,7 @@ static int gpio_msm_v1_probe(struct platform_device *pdev)
 	data = (struct msm_gpio_initdata *)dev_id->driver_data;
 	msm_gpio_chips = data->chips;
 	msm_gpio_count = data->count;
+	msm_gpio_mux = data->mux;
 
 	irq1 = platform_get_irq(pdev, 0);
 	if (irq1 < 0)
-- 
2.1.0.rc2




More information about the linux-arm-kernel mailing list