1 // SPDX-License-Identifier: GPL-2.0
3 * Power off through MediaTek PMIC
5 * Copyright (C) 2018 MediaTek Inc.
7 * Author: Sean Wang <sean.wang@mediatek.com>
11 #include <linux/err.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/mfd/mt6397/core.h>
16 #include <linux/mfd/mt6397/rtc.h>
20 struct regmap
*regmap
;
24 static struct mt6323_pwrc
*mt_pwrc
;
26 static void mt6323_do_pwroff(void)
28 struct mt6323_pwrc
*pwrc
= mt_pwrc
;
32 regmap_write(pwrc
->regmap
, pwrc
->base
+ RTC_BBPU
, RTC_BBPU_KEY
);
33 regmap_write(pwrc
->regmap
, pwrc
->base
+ RTC_WRTGR_MT6323
, 1);
35 ret
= regmap_read_poll_timeout(pwrc
->regmap
,
36 pwrc
->base
+ RTC_BBPU
, val
,
37 !(val
& RTC_BBPU_CBUSY
),
38 MTK_RTC_POLL_DELAY_US
,
39 MTK_RTC_POLL_TIMEOUT
);
41 dev_err(pwrc
->dev
, "failed to write BBPU: %d\n", ret
);
43 /* Wait some time until system down, otherwise, notice with a warn */
46 WARN_ONCE(1, "Unable to power off system\n");
49 static int mt6323_pwrc_probe(struct platform_device
*pdev
)
51 struct mt6397_chip
*mt6397_chip
= dev_get_drvdata(pdev
->dev
.parent
);
52 struct mt6323_pwrc
*pwrc
;
55 pwrc
= devm_kzalloc(&pdev
->dev
, sizeof(*pwrc
), GFP_KERNEL
);
59 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
60 pwrc
->base
= res
->start
;
61 pwrc
->regmap
= mt6397_chip
->regmap
;
62 pwrc
->dev
= &pdev
->dev
;
65 pm_power_off
= &mt6323_do_pwroff
;
70 static int mt6323_pwrc_remove(struct platform_device
*pdev
)
72 if (pm_power_off
== &mt6323_do_pwroff
)
78 static const struct of_device_id mt6323_pwrc_dt_match
[] = {
79 { .compatible
= "mediatek,mt6323-pwrc" },
82 MODULE_DEVICE_TABLE(of
, mt6323_pwrc_dt_match
);
84 static struct platform_driver mt6323_pwrc_driver
= {
85 .probe
= mt6323_pwrc_probe
,
86 .remove
= mt6323_pwrc_remove
,
88 .name
= "mt6323-pwrc",
89 .of_match_table
= mt6323_pwrc_dt_match
,
93 module_platform_driver(mt6323_pwrc_driver
);
95 MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC");
96 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
97 MODULE_LICENSE("GPL v2");