From d74710dd508eb1b60b410048a151e1d541d749d2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 25 Jul 2008 23:06:15 +0100 Subject: [PATCH] fix-pcf50633-migrate-gta02-peripherals-out.patch 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 --- arch/arm/mach-s3c2440/mach-gta02.c | 30 ++++++++++++++++++- drivers/i2c/chips/pcf50633.c | 57 ++++++++++++++++++----------------- include/linux/pcf50633.h | 9 +++++- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 309e484..fd746fd 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -464,6 +464,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(>a01_pm_bt_dev); + platform_device_register(>a01_pm_gps_dev); +} + static struct pcf50633_platform_data gta02_pcf_pdata = { .used_features = PCF50633_FEAT_MBC | PCF50633_FEAT_BBC | @@ -478,6 +501,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 | @@ -577,7 +601,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 */ @@ -772,6 +798,7 @@ struct platform_device s3c24xx_pwm_device = { .num_resources = 0, }; + static struct platform_device *gta02_devices[] __initdata = { &s3c_device_usb, &s3c_device_wdt, @@ -786,6 +813,7 @@ static struct platform_device *gta02_devices[] __initdata = { >a02_version_device, >a02_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 6745993..850bf93 100644 --- a/drivers/i2c/chips/pcf50633.c +++ b/drivers/i2c/chips/pcf50633.c @@ -50,7 +50,6 @@ #include #include -#include #include "pcf50633.h" #include @@ -2004,18 +2003,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! */ @@ -2209,14 +2196,15 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind) apm_get_power_status = pcf50633_get_power_status; data->probe_completed = 1; -#ifdef CONFIG_MACH_NEO1973_GTA02 - 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(>a01_pm_bt_dev); - platform_device_register(>a01_pm_gps_dev); - } -#endif + 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: @@ -2261,13 +2249,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(>a01_pm_bt_dev); - platform_device_unregister(>a01_pm_gps_dev); - } -#endif - sysfs_remove_group(&client->dev.kobj, &pcf_attr_group); pm_power_off = NULL; @@ -2465,6 +2446,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]; -- 1.5.6.3