@@ -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;
@@ -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;
@@ -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,
@@ -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;
@@ -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);
@@ -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
@@ -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)
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@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(-)