static int shuttle_camera_resume(struct platform_device *pdev)
{
	struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev);
	dev_dbg(&pdev->dev, "resuming\n");

	__shuttle_pm_camera_power(&pdev->dev, camera_data->pre_resume_state);
	return 0;
}
static int shuttle_camera_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev);

	dev_dbg(&pdev->dev, "suspending\n");

	camera_data->pre_resume_state = camera_data->state;
	__shuttle_pm_camera_power(&pdev->dev, 0);

	return 0;
}
static ssize_t camera_write(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long on = simple_strtoul(buf, NULL, 10);
	/*struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(dev);*/

	if (!strcmp(attr->attr.name, "power_on")) {
		__shuttle_pm_camera_power(dev, on);
	} 

	return count;
}
static int shuttle_camera_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev);

	dev_dbg(&pdev->dev, "suspending\n");

	camera_data->pre_resume_state = camera_data->powered_up;
	
	if (!camera_data->keep_on_in_suspend)
		__shuttle_pm_camera_power(&pdev->dev, 0);
	else
		dev_warn(&pdev->dev, "keeping camera ON during suspend\n");
	return 0;
}
static int shuttle_camera_remove(struct platform_device *pdev)
{
	struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev);
	if (!camera_data)
		return 0;

	sysfs_remove_group(&pdev->dev.kobj, &shuttle_camera_attr_group);

	__shuttle_pm_camera_power(&pdev->dev, 0);
	
	regulator_put(camera_data->regulator);	

	kfree(camera_data);
	dev_set_drvdata(&pdev->dev, NULL);
	
	return 0;
}
static ssize_t camera_write(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long on = simple_strtoul(buf, NULL, 10);
	struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(dev);

	if (!strcmp(attr->attr.name, "power_on")) {
		__shuttle_pm_camera_power(dev, !!on);
	}
#ifdef CONFIG_PM
	else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) {
		camera_data->keep_on_in_suspend = on;
	}
#endif

	return count;
}
/* ----- Initialization/removal -------------------------------------------- */
static int __init shuttle_camera_probe(struct platform_device *pdev)
{
	/* default-off */
	const int default_state = 0;

	struct regulator *regulator;
	struct shuttle_pm_camera_data *camera_data;

	camera_data = kzalloc(sizeof(*camera_data), GFP_KERNEL);
	if (!camera_data) {
		dev_err(&pdev->dev, "no memory for context\n");
		return -ENOMEM;
	}
	dev_set_drvdata(&pdev->dev, camera_data);

	regulator = regulator_get(&pdev->dev, "vdd_camera");
	if (IS_ERR(regulator)) {
		dev_err(&pdev->dev, "unable to get regulator 0\n");
		kfree(camera_data);
		dev_set_drvdata(&pdev->dev, NULL);
		return -ENODEV;
	}

	camera_data->regulator = regulator;

	/* Init io pins and disable camera */
	gpio_request(SHUTTLE_CAMERA_POWER, "camera_power");
	gpio_direction_output(SHUTTLE_CAMERA_POWER, 0);

	/* Set the default state */
	__shuttle_pm_camera_power(&pdev->dev, default_state);
	
	dev_info(&pdev->dev, "Camera power management driver loaded\n");
	
	return sysfs_create_group(&pdev->dev.kobj, &shuttle_camera_attr_group);
}