18c2ecf20Sopenharmony_ci/**************************************************************************
28c2ecf20Sopenharmony_ci * Copyright (c) 2009-2011, Intel Corporation.
38c2ecf20Sopenharmony_ci * All Rights Reserved.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
68c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
78c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
88c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
98c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
108c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next
138c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
148c2ecf20Sopenharmony_ci * Software.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
198c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218c2ecf20Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
228c2ecf20Sopenharmony_ci * SOFTWARE.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Authors:
258c2ecf20Sopenharmony_ci *    Benjamin Defnet <benjamin.r.defnet@intel.com>
268c2ecf20Sopenharmony_ci *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
278c2ecf20Sopenharmony_ci * Massively reworked
288c2ecf20Sopenharmony_ci *    Alan Cox <alan@linux.intel.com>
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#include "power.h"
328c2ecf20Sopenharmony_ci#include "psb_drv.h"
338c2ecf20Sopenharmony_ci#include "psb_reg.h"
348c2ecf20Sopenharmony_ci#include "psb_intel_reg.h"
358c2ecf20Sopenharmony_ci#include <linux/mutex.h>
368c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic struct mutex power_mutex;	/* Serialize power ops */
398c2ecf20Sopenharmony_cistatic spinlock_t power_ctrl_lock;	/* Serialize power claim */
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/**
428c2ecf20Sopenharmony_ci *	gma_power_init		-	initialise power manager
438c2ecf20Sopenharmony_ci *	@dev: our device
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci *	Set up for power management tracking of our hardware.
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_civoid gma_power_init(struct drm_device *dev)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* FIXME: Move APM/OSPM base into relevant device code */
528c2ecf20Sopenharmony_ci	dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
538c2ecf20Sopenharmony_ci	dev_priv->ospm_base &= 0xffff;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	dev_priv->display_power = true;	/* We start active */
568c2ecf20Sopenharmony_ci	dev_priv->display_count = 0;	/* Currently no users */
578c2ecf20Sopenharmony_ci	dev_priv->suspended = false;	/* And not suspended */
588c2ecf20Sopenharmony_ci	spin_lock_init(&power_ctrl_lock);
598c2ecf20Sopenharmony_ci	mutex_init(&power_mutex);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	if (dev_priv->ops->init_pm)
628c2ecf20Sopenharmony_ci		dev_priv->ops->init_pm(dev);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/**
668c2ecf20Sopenharmony_ci *	gma_power_uninit	-	end power manager
678c2ecf20Sopenharmony_ci *	@dev: device to end for
688c2ecf20Sopenharmony_ci *
698c2ecf20Sopenharmony_ci *	Undo the effects of gma_power_init
708c2ecf20Sopenharmony_ci */
718c2ecf20Sopenharmony_civoid gma_power_uninit(struct drm_device *dev)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	pm_runtime_disable(&dev->pdev->dev);
748c2ecf20Sopenharmony_ci	pm_runtime_set_suspended(&dev->pdev->dev);
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci/**
788c2ecf20Sopenharmony_ci *	gma_suspend_display	-	suspend the display logic
798c2ecf20Sopenharmony_ci *	@dev: our DRM device
808c2ecf20Sopenharmony_ci *
818c2ecf20Sopenharmony_ci *	Suspend the display logic of the graphics interface
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_cistatic void gma_suspend_display(struct drm_device *dev)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	if (dev_priv->suspended)
888c2ecf20Sopenharmony_ci		return;
898c2ecf20Sopenharmony_ci	dev_priv->ops->save_regs(dev);
908c2ecf20Sopenharmony_ci	dev_priv->ops->power_down(dev);
918c2ecf20Sopenharmony_ci	dev_priv->display_power = false;
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci/**
958c2ecf20Sopenharmony_ci *	gma_resume_display	-	resume display side logic
968c2ecf20Sopenharmony_ci *
978c2ecf20Sopenharmony_ci *	Resume the display hardware restoring state and enabling
988c2ecf20Sopenharmony_ci *	as necessary.
998c2ecf20Sopenharmony_ci */
1008c2ecf20Sopenharmony_cistatic void gma_resume_display(struct pci_dev *pdev)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	struct drm_device *dev = pci_get_drvdata(pdev);
1038c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/* turn on the display power island */
1068c2ecf20Sopenharmony_ci	dev_priv->ops->power_up(dev);
1078c2ecf20Sopenharmony_ci	dev_priv->suspended = false;
1088c2ecf20Sopenharmony_ci	dev_priv->display_power = true;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
1118c2ecf20Sopenharmony_ci	pci_write_config_word(pdev, PSB_GMCH_CTRL,
1128c2ecf20Sopenharmony_ci			dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	psb_gtt_restore(dev); /* Rebuild our GTT mappings */
1158c2ecf20Sopenharmony_ci	dev_priv->ops->restore_regs(dev);
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci/**
1198c2ecf20Sopenharmony_ci *	gma_suspend_pci		-	suspend PCI side
1208c2ecf20Sopenharmony_ci *	@pdev: PCI device
1218c2ecf20Sopenharmony_ci *
1228c2ecf20Sopenharmony_ci *	Perform the suspend processing on our PCI device state
1238c2ecf20Sopenharmony_ci */
1248c2ecf20Sopenharmony_cistatic void gma_suspend_pci(struct pci_dev *pdev)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	struct drm_device *dev = pci_get_drvdata(pdev);
1278c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
1288c2ecf20Sopenharmony_ci	int bsm, vbt;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	if (dev_priv->suspended)
1318c2ecf20Sopenharmony_ci		return;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	pci_save_state(pdev);
1348c2ecf20Sopenharmony_ci	pci_read_config_dword(pdev, 0x5C, &bsm);
1358c2ecf20Sopenharmony_ci	dev_priv->regs.saveBSM = bsm;
1368c2ecf20Sopenharmony_ci	pci_read_config_dword(pdev, 0xFC, &vbt);
1378c2ecf20Sopenharmony_ci	dev_priv->regs.saveVBT = vbt;
1388c2ecf20Sopenharmony_ci	pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
1398c2ecf20Sopenharmony_ci	pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	pci_disable_device(pdev);
1428c2ecf20Sopenharmony_ci	pci_set_power_state(pdev, PCI_D3hot);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	dev_priv->suspended = true;
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci/**
1488c2ecf20Sopenharmony_ci *	gma_resume_pci		-	resume helper
1498c2ecf20Sopenharmony_ci *	@dev: our PCI device
1508c2ecf20Sopenharmony_ci *
1518c2ecf20Sopenharmony_ci *	Perform the resume processing on our PCI device state - rewrite
1528c2ecf20Sopenharmony_ci *	register state and re-enable the PCI device
1538c2ecf20Sopenharmony_ci */
1548c2ecf20Sopenharmony_cistatic bool gma_resume_pci(struct pci_dev *pdev)
1558c2ecf20Sopenharmony_ci{
1568c2ecf20Sopenharmony_ci	struct drm_device *dev = pci_get_drvdata(pdev);
1578c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
1588c2ecf20Sopenharmony_ci	int ret;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	if (!dev_priv->suspended)
1618c2ecf20Sopenharmony_ci		return true;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	pci_set_power_state(pdev, PCI_D0);
1648c2ecf20Sopenharmony_ci	pci_restore_state(pdev);
1658c2ecf20Sopenharmony_ci	pci_write_config_dword(pdev, 0x5c, dev_priv->regs.saveBSM);
1668c2ecf20Sopenharmony_ci	pci_write_config_dword(pdev, 0xFC, dev_priv->regs.saveVBT);
1678c2ecf20Sopenharmony_ci	/* restoring MSI address and data in PCIx space */
1688c2ecf20Sopenharmony_ci	pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
1698c2ecf20Sopenharmony_ci	pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
1708c2ecf20Sopenharmony_ci	ret = pci_enable_device(pdev);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	if (ret != 0)
1738c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
1748c2ecf20Sopenharmony_ci	else
1758c2ecf20Sopenharmony_ci		dev_priv->suspended = false;
1768c2ecf20Sopenharmony_ci	return !dev_priv->suspended;
1778c2ecf20Sopenharmony_ci}
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci/**
1808c2ecf20Sopenharmony_ci *	gma_power_suspend		-	bus callback for suspend
1818c2ecf20Sopenharmony_ci *	@pdev: our PCI device
1828c2ecf20Sopenharmony_ci *	@state: suspend type
1838c2ecf20Sopenharmony_ci *
1848c2ecf20Sopenharmony_ci *	Called back by the PCI layer during a suspend of the system. We
1858c2ecf20Sopenharmony_ci *	perform the necessary shut down steps and save enough state that
1868c2ecf20Sopenharmony_ci *	we can undo this when resume is called.
1878c2ecf20Sopenharmony_ci */
1888c2ecf20Sopenharmony_ciint gma_power_suspend(struct device *_dev)
1898c2ecf20Sopenharmony_ci{
1908c2ecf20Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(_dev);
1918c2ecf20Sopenharmony_ci	struct drm_device *dev = pci_get_drvdata(pdev);
1928c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	mutex_lock(&power_mutex);
1958c2ecf20Sopenharmony_ci	if (!dev_priv->suspended) {
1968c2ecf20Sopenharmony_ci		if (dev_priv->display_count) {
1978c2ecf20Sopenharmony_ci			mutex_unlock(&power_mutex);
1988c2ecf20Sopenharmony_ci			dev_err(dev->dev, "GPU hardware busy, cannot suspend\n");
1998c2ecf20Sopenharmony_ci			return -EBUSY;
2008c2ecf20Sopenharmony_ci		}
2018c2ecf20Sopenharmony_ci		psb_irq_uninstall(dev);
2028c2ecf20Sopenharmony_ci		gma_suspend_display(dev);
2038c2ecf20Sopenharmony_ci		gma_suspend_pci(pdev);
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci	mutex_unlock(&power_mutex);
2068c2ecf20Sopenharmony_ci	return 0;
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci/**
2108c2ecf20Sopenharmony_ci *	gma_power_resume		-	resume power
2118c2ecf20Sopenharmony_ci *	@pdev: PCI device
2128c2ecf20Sopenharmony_ci *
2138c2ecf20Sopenharmony_ci *	Resume the PCI side of the graphics and then the displays
2148c2ecf20Sopenharmony_ci */
2158c2ecf20Sopenharmony_ciint gma_power_resume(struct device *_dev)
2168c2ecf20Sopenharmony_ci{
2178c2ecf20Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(_dev);
2188c2ecf20Sopenharmony_ci	struct drm_device *dev = pci_get_drvdata(pdev);
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	mutex_lock(&power_mutex);
2218c2ecf20Sopenharmony_ci	gma_resume_pci(pdev);
2228c2ecf20Sopenharmony_ci	gma_resume_display(pdev);
2238c2ecf20Sopenharmony_ci	psb_irq_preinstall(dev);
2248c2ecf20Sopenharmony_ci	psb_irq_postinstall(dev);
2258c2ecf20Sopenharmony_ci	mutex_unlock(&power_mutex);
2268c2ecf20Sopenharmony_ci	return 0;
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci/**
2308c2ecf20Sopenharmony_ci *	gma_power_is_on		-	returne true if power is on
2318c2ecf20Sopenharmony_ci *	@dev: our DRM device
2328c2ecf20Sopenharmony_ci *
2338c2ecf20Sopenharmony_ci *	Returns true if the display island power is on at this moment
2348c2ecf20Sopenharmony_ci */
2358c2ecf20Sopenharmony_cibool gma_power_is_on(struct drm_device *dev)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
2388c2ecf20Sopenharmony_ci	return dev_priv->display_power;
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci/**
2428c2ecf20Sopenharmony_ci *	gma_power_begin		-	begin requiring power
2438c2ecf20Sopenharmony_ci *	@dev: our DRM device
2448c2ecf20Sopenharmony_ci *	@force_on: true to force power on
2458c2ecf20Sopenharmony_ci *
2468c2ecf20Sopenharmony_ci *	Begin an action that requires the display power island is enabled.
2478c2ecf20Sopenharmony_ci *	We refcount the islands.
2488c2ecf20Sopenharmony_ci */
2498c2ecf20Sopenharmony_cibool gma_power_begin(struct drm_device *dev, bool force_on)
2508c2ecf20Sopenharmony_ci{
2518c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
2528c2ecf20Sopenharmony_ci	int ret;
2538c2ecf20Sopenharmony_ci	unsigned long flags;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	spin_lock_irqsave(&power_ctrl_lock, flags);
2568c2ecf20Sopenharmony_ci	/* Power already on ? */
2578c2ecf20Sopenharmony_ci	if (dev_priv->display_power) {
2588c2ecf20Sopenharmony_ci		dev_priv->display_count++;
2598c2ecf20Sopenharmony_ci		pm_runtime_get(&dev->pdev->dev);
2608c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&power_ctrl_lock, flags);
2618c2ecf20Sopenharmony_ci		return true;
2628c2ecf20Sopenharmony_ci	}
2638c2ecf20Sopenharmony_ci	if (force_on == false)
2648c2ecf20Sopenharmony_ci		goto out_false;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	/* Ok power up needed */
2678c2ecf20Sopenharmony_ci	ret = gma_resume_pci(dev->pdev);
2688c2ecf20Sopenharmony_ci	if (ret == 0) {
2698c2ecf20Sopenharmony_ci		psb_irq_preinstall(dev);
2708c2ecf20Sopenharmony_ci		psb_irq_postinstall(dev);
2718c2ecf20Sopenharmony_ci		pm_runtime_get(&dev->pdev->dev);
2728c2ecf20Sopenharmony_ci		dev_priv->display_count++;
2738c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&power_ctrl_lock, flags);
2748c2ecf20Sopenharmony_ci		return true;
2758c2ecf20Sopenharmony_ci	}
2768c2ecf20Sopenharmony_ciout_false:
2778c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&power_ctrl_lock, flags);
2788c2ecf20Sopenharmony_ci	return false;
2798c2ecf20Sopenharmony_ci}
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci/**
2828c2ecf20Sopenharmony_ci *	gma_power_end		-	end use of power
2838c2ecf20Sopenharmony_ci *	@dev: Our DRM device
2848c2ecf20Sopenharmony_ci *
2858c2ecf20Sopenharmony_ci *	Indicate that one of our gma_power_begin() requested periods when
2868c2ecf20Sopenharmony_ci *	the diplay island power is needed has completed.
2878c2ecf20Sopenharmony_ci */
2888c2ecf20Sopenharmony_civoid gma_power_end(struct drm_device *dev)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = dev->dev_private;
2918c2ecf20Sopenharmony_ci	unsigned long flags;
2928c2ecf20Sopenharmony_ci	spin_lock_irqsave(&power_ctrl_lock, flags);
2938c2ecf20Sopenharmony_ci	dev_priv->display_count--;
2948c2ecf20Sopenharmony_ci	WARN_ON(dev_priv->display_count < 0);
2958c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&power_ctrl_lock, flags);
2968c2ecf20Sopenharmony_ci	pm_runtime_put(&dev->pdev->dev);
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ciint psb_runtime_suspend(struct device *dev)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	return gma_power_suspend(dev);
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ciint psb_runtime_resume(struct device *dev)
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci	return gma_power_resume(dev);
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ciint psb_runtime_idle(struct device *dev)
3108c2ecf20Sopenharmony_ci{
3118c2ecf20Sopenharmony_ci	struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
3128c2ecf20Sopenharmony_ci	struct drm_psb_private *dev_priv = drmdev->dev_private;
3138c2ecf20Sopenharmony_ci	if (dev_priv->display_count)
3148c2ecf20Sopenharmony_ci		return 0;
3158c2ecf20Sopenharmony_ci	else
3168c2ecf20Sopenharmony_ci		return 1;
3178c2ecf20Sopenharmony_ci}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ciint gma_power_thaw(struct device *_dev)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	return gma_power_resume(_dev);
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ciint gma_power_freeze(struct device *_dev)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	return gma_power_suspend(_dev);
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ciint gma_power_restore(struct device *_dev)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	return gma_power_resume(_dev);
3328c2ecf20Sopenharmony_ci}
333