aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAndy Green <andy@openmoko.com>2009-02-23 01:21:27 +0000
committerAndy Green <agreen@octopus.localdomain>2009-02-23 01:21:27 +0000
commit8df75a337131d835d4dd8509696d684e4fa8970e (patch)
tree08da880f825c191b7f815045b24f39bf3b4fcbd7 /arch
parentbc49de906ce5a6e39a4bc9a46ab33af09b93295f (diff)
fix-pm-gsm-disable-serial-drive-when-off.patch
This patch cleans some cruft from neo1973-pm-gsm.c and makes some changes to the power code for gsm. First, on probe it enforces GSM is OFF. Second, when GSM is OFF, it changes the RTS and TXD pins on UART 0 to be inputs, instead of driving into a dead subsystem and costing us ~70mA @ 5V constant dissipation (these 3.3V pins were found at 1.5V due to that). Third it asserts the GPIO peripheral function when ON, to keep the same flow for the new interrupt generation workaround code. Since several people worked on this area before, and maybe the assertion of GSM OFF is different (it's OFF from bootloader though) or maybe something else gets broken, I send the patch for comment before applying it. Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gsm.c132
1 files changed, 71 insertions, 61 deletions
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
index c493018b737..63591cdff6f 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
@@ -92,75 +92,78 @@ out_1:
return strlcpy(buf, "1\n", 3);
}
-static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static void gsm_on_off(struct device *dev, int on)
{
- unsigned long on = simple_strtoul(buf, NULL, 10);
+ if (!on) {
+ /* do not drive into powered-down GSM side */
+ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPIO_INPUT);
+ s3c2410_gpio_cfgpin(S3C2410_GPH2, S3C2410_GPIO_INPUT);
- if (!strcmp(attr->attr.name, "power_on")) {
- if (on) {
- if (gta01_gsm.con) {
- dev_dbg(dev, "powering up GSM, thus "
- "disconnecting serial console\n");
+ if (machine_is_neo1973_gta02())
+ pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 0);
- console_stop(gta01_gsm.con);
- s3c24xx_serial_console_set_silence(1);
- }
+ if (gta01_gsm.gpio_ngsm_en)
+ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1);
- if (gta01_gsm.gpio_ngsm_en)
- s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0);
-
- if (machine_is_neo1973_gta02()) {
- switch (system_rev) {
- case GTA02v2_SYSTEM_REV:
- case GTA02v3_SYSTEM_REV:
- case GTA02v4_SYSTEM_REV:
- case GTA02v5_SYSTEM_REV:
- case GTA02v6_SYSTEM_REV:
- pcf50633_gpio_set(gta02_pcf,
- PCF50633_GPIO2, 7);
- break;
- }
- }
- msleep(100);
+ if (gta01_gsm.con) {
+ s3c24xx_serial_console_set_silence(0);
+ console_start(gta01_gsm.con);
- neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 1);
- msleep(500);
- neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 0);
+ dev_dbg(dev, "powered down GTA01 GSM, enabling "
+ "serial console\n");
+ }
- /* workaround for calypso firmware moko10 and earlier,
- without this it will leave IRQ line high after booting */
- s3c2410_gpio_setpin(S3C2410_GPH1, 1);
- s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_OUTP);
- msleep(1000);
- s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0);
- } else {
- /* FIXME should all GPIOs connected to the modem be tri-stated? */
- if (machine_is_neo1973_gta02()) {
- switch (system_rev) {
- case GTA02v2_SYSTEM_REV:
- case GTA02v3_SYSTEM_REV:
- case GTA02v4_SYSTEM_REV:
- case GTA02v5_SYSTEM_REV:
- case GTA02v6_SYSTEM_REV:
- pcf50633_gpio_set(gta02_pcf,
- PCF50633_GPIO2, 0);
- break;
- }
- }
+ return;
+ }
- if (gta01_gsm.gpio_ngsm_en)
- s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1);
+ if (gta01_gsm.con) {
+ dev_dbg(dev, "powering up GSM, thus "
+ "disconnecting serial console\n");
- if (gta01_gsm.con) {
- s3c24xx_serial_console_set_silence(0);
- console_start(gta01_gsm.con);
+ console_stop(gta01_gsm.con);
+ s3c24xx_serial_console_set_silence(1);
+ }
- dev_dbg(dev, "powered down GSM, thus enabling "
- "serial console\n");
- }
- }
- } else if (!strcmp(attr->attr.name, "download")) {
+ /* allow UART to talk to GSM side now we will power it */
+ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0);
+ s3c2410_gpio_cfgpin(S3C2410_GPH2, S3C2410_GPH2_TXD0);
+
+ if (gta01_gsm.gpio_ngsm_en)
+ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0);
+
+ if (machine_is_neo1973_gta02())
+ pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 7);
+
+ msleep(100);
+
+ neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 1);
+ msleep(500);
+ neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 0);
+
+ /*
+ * workaround for calypso firmware moko10 and earlier,
+ * without this it will leave IRQ line high after
+ * booting
+ */
+ s3c2410_gpio_setpin(S3C2410_GPH1, 1);
+ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_OUTP);
+ msleep(1000);
+ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0);
+
+}
+
+static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long on = simple_strtoul(buf, NULL, 10);
+
+ if (!strcmp(attr->attr.name, "power_on")) {
+ gsm_on_off(dev, on);
+
+ return count;
+ }
+
+ if (!strcmp(attr->attr.name, "download")) {
if (machine_is_neo1973_gta01())
s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
@@ -187,7 +190,11 @@ static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
gta01_gsm.gpio_ndl_gsm = !on;
s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, !on);
}
- } else if (!strcmp(attr->attr.name, "flowcontrolled")) {
+
+ return count;
+ }
+
+ if (!strcmp(attr->attr.name, "flowcontrolled")) {
if (on) {
gta_gsm_interrupts = 0;
s3c2410_gpio_setpin(S3C2410_GPH1, 1);
@@ -325,6 +332,9 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
if (machine_is_neo1973_gta02())
s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1);
+ /* GSM is to be initially off (at boot, or if this module inserted) */
+ gsm_on_off(&pdev->dev, 0);
+
return sysfs_create_group(&pdev->dev.kobj, &gta01_gsm_attr_group);
}