[PATCH 09/10] fix-pcf50633-migrate-gta02-peripherals-out.patch

Andy Green andy at openmoko.com
Mon Jun 16 00:17:54 CEST 2008


pcf50633.c shouldn't know GTAxx at all.  Move to using a
platform callback to allow definition of platform devices
with pcf50633 as parent device (good for enforcing suspend /
resume ordering).  Remove all code references to GTAxx from
the sources (one string left for compatability).

Signed-off-by: Andy Green <andy at openmoko.com>
---

 arch/arm/mach-s3c2440/mach-gta02.c |   30 +++++++++++++++++++-
 drivers/i2c/chips/pcf50633.c       |   54 +++++++++++++++++++-----------------
 include/linux/pcf50633.h           |    9 +++++-
 3 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 474510e..2c44bc1 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -467,6 +467,29 @@ static int pmu_callback(struct device *dev, unsigned int feature,
 	return 0;
 }
 
+static struct platform_device gta01_pm_gps_dev = {
+	.name		= "neo1973-pm-gps",
+};
+
+static struct platform_device gta01_pm_bt_dev = {
+	.name		= "neo1973-pm-bt",
+};
+
+/* this is called when pc50633 is probed, unfortunately quite late in the
+ * day since it is an I2C bus device.  Here we can belatedly define some
+ * platform devices with the advantage that we can mark the pcf50633 as the
+ * parent.  This makes them get suspended and resumed with their parent
+ * the pcf50633 still around.
+ */
+
+static void gta02_pcf50633_attach_child_devices(struct device *parent_device)
+{
+	gta01_pm_gps_dev.dev.parent = parent_device;
+	gta01_pm_bt_dev.dev.parent = parent_device;
+	platform_device_register(&gta01_pm_bt_dev);
+	platform_device_register(&gta01_pm_gps_dev);
+}
+
 static struct pcf50633_platform_data gta02_pcf_pdata = {
 	.used_features	= PCF50633_FEAT_MBC |
 			  PCF50633_FEAT_BBC |
@@ -481,6 +504,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
 	.r_fix_batt	= 10000,
 	.r_fix_batt_par	= 10000,
 	.r_sense_milli	= 220,
+	.flag_use_apm_emulation = 0,
 	.resumers = {
 		[0] = PCF50633_INT1_USBINS |
 		      PCF50633_INT1_USBREM |
@@ -580,7 +604,9 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
 		},
 	},
 	.defer_resume_backlight = 1,
-	.resume_backlight_ramp_speed = 5
+	.resume_backlight_ramp_speed = 5,
+	.attach_child_devices = gta02_pcf50633_attach_child_devices
+
 };
 
 #if 0 /* currently unused */
@@ -775,6 +801,7 @@ struct platform_device s3c24xx_pwm_device = {
 	.num_resources	= 0,
 };
 
+
 static struct platform_device *gta02_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_wdt,
@@ -789,6 +816,7 @@ static struct platform_device *gta02_devices[] __initdata = {
 	&gta02_version_device,
 	&gta02_resume_reason_device,
 	&s3c24xx_pwm_device,
+
 };
 
 static struct s3c2410_nand_set gta02_nand_sets[] = {
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index a697ee1..0f40f3f 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -50,7 +50,6 @@
 #include <linux/jiffies.h>
 
 #include <asm/mach-types.h>
-#include <asm/arch/gta02.h>
 
 #include "pcf50633.h"
 #include <linux/resume-dependency.h>
@@ -2011,18 +2010,6 @@ static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL);
  * Driver initialization
  ***********************************************************************/
 
-#ifdef CONFIG_MACH_NEO1973_GTA02
-/* We currently place those platform devices here to make sure the device
- * suspend/resume order is correct */
-static struct platform_device gta01_pm_gps_dev = {
-	.name		= "neo1973-pm-gps",
-};
-
-static struct platform_device gta01_pm_bt_dev = {
-	.name		= "neo1973-pm-bt",
-};
-#endif
-
 /*
  * CARE!  This table is modified at runtime!
  */
@@ -2217,14 +2204,16 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
 
 	data->probe_completed = 1;
 
-	if (machine_is_neo1973_gta02()) {
-		gta01_pm_gps_dev.dev.parent = &new_client->dev;
-		gta01_pm_bt_dev.dev.parent = &new_client->dev;
-		platform_device_register(&gta01_pm_bt_dev);
-		platform_device_register(&gta01_pm_gps_dev);
-	} else
+	if (data->pdata->flag_use_apm_emulation)
 		apm_get_power_status = pcf50633_get_power_status;
 
+	/* if platform was interested, give him a chance to register
+	 * platform devices that switch power with us as the parent
+	 * at registration time -- ensures suspend / resume ordering
+	 */
+	if (data->pdata->attach_child_devices)
+		(data->pdata->attach_child_devices)(&new_client->dev);
+
 	return 0;
 exit_rtc:
 	if (data->pdata->used_features & PCF50633_FEAT_RTC)
@@ -2268,13 +2257,6 @@ static int pcf50633_detach_client(struct i2c_client *client)
 	if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
 		rtc_device_unregister(pcf->rtc);
 
-#ifdef CONFIG_MACH_NEO1973_GTA02
-	if (machine_is_neo1973_gta02()) {
-		platform_device_unregister(&gta01_pm_bt_dev);
-		platform_device_unregister(&gta01_pm_gps_dev);
-	}
-#endif
-
 	sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
 
 	pm_power_off = NULL;
@@ -2472,6 +2454,26 @@ int pcf50633_ready(struct pcf50633_data *pcf)
 }
 EXPORT_SYMBOL_GPL(pcf50633_ready);
 
+int pcf50633_wait_for_ready(struct pcf50633_data *pcf, int timeout_ms,
+								char *name)
+{
+	/* so we always go once */
+	timeout_ms += 5;
+
+	while ((timeout_ms >= 5) && (pcf50633_ready(pcf))) {
+		timeout_ms -= 5; /* well, it isn't very accurate, but OK */
+		msleep(5);
+	}
+
+	if (timeout_ms < 5) {
+		printk(KERN_ERR"pcf50633_wait_for_ready: "
+					"%s BAILING on timeout\n", name);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pcf50633_wait_for_ready);
 
 /*
  * if backlight resume is selected to be deferred by platform, then it
diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
index b94b72a..4653285 100644
--- a/include/linux/pcf50633.h
+++ b/include/linux/pcf50633.h
@@ -132,7 +132,9 @@ pcf50633_register_resume_dependency(struct pcf50633_data *pcf,
 extern int
 pcf50633_notify_usb_current_limit_change(struct pcf50633_data *pcf,
 							       unsigned int ma);
-
+extern int
+pcf50633_wait_for_ready(struct pcf50633_data *pcf, int timeout_ms,
+								char *name);
 
 /* 0 = initialized and resumed and ready to roll, !=0 = either not
  * initialized or not resumed yet
@@ -155,6 +157,10 @@ struct pcf50633_platform_data {
 	unsigned int onkey_seconds_sig_init;
 	unsigned int onkey_seconds_shutdown;
 
+	/* callback to attach platform children (to enforce suspend / resume
+	 * ordering */
+	void (*attach_child_devices)(struct device *parent_device);
+
 	/* voltage regulator related */
 	struct pmu_voltage_rail rails[__NUM_PCF50633_REGULATORS];
 	unsigned int used_regulators;
@@ -163,6 +169,7 @@ struct pcf50633_platform_data {
 	unsigned int r_fix_batt;
 	unsigned int r_fix_batt_par;
 	unsigned int r_sense_milli;
+	int flag_use_apm_emulation;
 
 	unsigned char resumers[5];
 





More information about the openmoko-kernel mailing list