1 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 #include <linux/module.h>
18 #include <linux/spinlock.h>
21 static DEFINE_SPINLOCK(gpiomux_lock
);
23 int msm_gpiomux_write(unsigned gpio
,
24 gpiomux_config_t active
,
25 gpiomux_config_t suspended
)
27 struct msm_gpiomux_config
*cfg
= msm_gpiomux_configs
+ gpio
;
28 unsigned long irq_flags
;
29 gpiomux_config_t setting
;
31 if (gpio
>= GPIOMUX_NGPIOS
)
34 spin_lock_irqsave(&gpiomux_lock
, irq_flags
);
36 if (active
& GPIOMUX_VALID
)
39 if (suspended
& GPIOMUX_VALID
)
40 cfg
->suspended
= suspended
;
42 setting
= cfg
->ref
? active
: suspended
;
43 if (setting
& GPIOMUX_VALID
)
44 __msm_gpiomux_write(gpio
, setting
);
46 spin_unlock_irqrestore(&gpiomux_lock
, irq_flags
);
49 EXPORT_SYMBOL(msm_gpiomux_write
);
51 int msm_gpiomux_get(unsigned gpio
)
53 struct msm_gpiomux_config
*cfg
= msm_gpiomux_configs
+ gpio
;
54 unsigned long irq_flags
;
56 if (gpio
>= GPIOMUX_NGPIOS
)
59 spin_lock_irqsave(&gpiomux_lock
, irq_flags
);
60 if (cfg
->ref
++ == 0 && cfg
->active
& GPIOMUX_VALID
)
61 __msm_gpiomux_write(gpio
, cfg
->active
);
62 spin_unlock_irqrestore(&gpiomux_lock
, irq_flags
);
65 EXPORT_SYMBOL(msm_gpiomux_get
);
67 int msm_gpiomux_put(unsigned gpio
)
69 struct msm_gpiomux_config
*cfg
= msm_gpiomux_configs
+ gpio
;
70 unsigned long irq_flags
;
72 if (gpio
>= GPIOMUX_NGPIOS
)
75 spin_lock_irqsave(&gpiomux_lock
, irq_flags
);
76 BUG_ON(cfg
->ref
== 0);
77 if (--cfg
->ref
== 0 && cfg
->suspended
& GPIOMUX_VALID
)
78 __msm_gpiomux_write(gpio
, cfg
->suspended
);
79 spin_unlock_irqrestore(&gpiomux_lock
, irq_flags
);
82 EXPORT_SYMBOL(msm_gpiomux_put
);
84 static int __init
gpiomux_init(void)
88 for (n
= 0; n
< GPIOMUX_NGPIOS
; ++n
) {
89 msm_gpiomux_configs
[n
].ref
= 0;
90 if (!(msm_gpiomux_configs
[n
].suspended
& GPIOMUX_VALID
))
92 __msm_gpiomux_write(n
, msm_gpiomux_configs
[n
].suspended
);
96 postcore_initcall(gpiomux_init
);