Skip to content

Commit

Permalink
added patch for RTC and poweroff
Browse files Browse the repository at this point in the history
  • Loading branch information
frank-w committed Apr 11, 2018
1 parent 8513b38 commit 5a350ae
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 118 deletions.
4 changes: 3 additions & 1 deletion Documentation/devicetree/bindings/mfd/mt6397.txt
Expand Up @@ -21,8 +21,10 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323"
Optional subnodes:

- rtc
Required properties:
Required properties: Should be one of follows
- compatible: "mediatek,mt6323-rtc"
- compatible: "mediatek,mt6397-rtc"
For details, see Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
Expand Down
@@ -0,0 +1,24 @@
Device-Tree bindings for Power Device on MediaTek PMIC RTC

The power device is responsible for externally power off or on the remote
MediaTek SoC through the a tiny circuit block BBPU inside PMIC RTC.

Required parent node:
- rtc
For MediaTek PMIC RTC bindings, see:
Documentation/devicetree/bindings/mfd/mt6397.txt

Required properties:
- compatible: Should be one of follows
"mediatek,mt6323-rtc-poweroff": for MT6323 PMIC
"mediatek,mt6397-rtc-poweroff": for MT6397 PMIC

Example:

rtc {
compatible = "mediatek,mt6323-rtc";

power-off {
compatible = "mediatek,mt6323-rtc-poweroff";
};
};
39 changes: 39 additions & 0 deletions Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
@@ -0,0 +1,39 @@
Device-Tree bindings for MediaTek PMIC based RTC

MediaTek PMIC based RTC is an independent function of MediaTek PMIC which
is working as a multi-function device (MFD). And the RTC can be configured and
set up via PMIC wrapper bus. Which is also common resource shared among the
other functions present on the PMIC.

For MediaTek PMIC wrapper bus bindings, see:
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt

Required parent node:
- pmic
For MediaTek PMIC MFD bindings, see:
Documentation/devicetree/bindings/mfd/mt6397.txt

Required properties:
- compatible: Should be one of follows
"mediatek,mt6323-rtc": for MT6323 PMIC
"mediatek,mt6397-rtc": for MT6397 PMIC

Optional child node:
- power-off
For Power-Off Device for MediaTek PMIC RTC bindings, see:
Documentation/devicetree/bindings/power/reset/mt6397-rtc-poweroff.txt

Example:

pmic {
compatible = "mediatek,mt6323";

...
rtc {
compatible = "mediatek,mt6323-rtc";

power-off {
compatible = "mediatek,mt6323-rtc-poweroff";
};
};
};
8 changes: 8 additions & 0 deletions arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
Expand Up @@ -760,7 +760,15 @@
};
};

mt6323rtc: rtc {
compatible = "mediatek,mt6323-rtc";

power-off {
compatible = "mediatek,mt6323-rtc-poweroff";
};
};
};

};

&consys {
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/configs/mt7623n_evb_fwu_defconfig
Expand Up @@ -532,3 +532,6 @@ CONFIG_NFS_COMMON=y
#xfs
CONFIG_XFS_FS=m

#RTC/POWER
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_MT6397_RTC=y
27 changes: 24 additions & 3 deletions drivers/mfd/mt6397-core.c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Copyright (c) 2014-2018 MediaTek Inc.
* Author: Flora Fu, MediaTek
*
* This program is free software; you can redistribute it and/or modify
Expand All @@ -23,13 +23,29 @@
#include <linux/mfd/mt6397/registers.h>
#include <linux/mfd/mt6323/registers.h>

#define MT6323_RTC_BASE 0x8000
#define MT6323_RTC_SIZE 0x3e

#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e

#define MT6323_CID_CODE 0x23
#define MT6391_CID_CODE 0x91
#define MT6397_CID_CODE 0x97

static const struct resource mt6323_rtc_resources[] = {
{
.start = MT6323_RTC_BASE,
.end = MT6323_RTC_BASE + MT6323_RTC_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = MT6323_IRQ_STATUS_RTC,
.end = MT6323_IRQ_STATUS_RTC,
.flags = IORESOURCE_IRQ,
},
};

static const struct resource mt6397_rtc_resources[] = {
{
.start = MT6397_RTC_BASE,
Expand All @@ -45,6 +61,11 @@ static const struct resource mt6397_rtc_resources[] = {

static const struct mfd_cell mt6323_devs[] = {
{
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
.resources = mt6323_rtc_resources,
.of_compatible = "mediatek,mt6323-rtc",
}, {
.name = "mt6323-regulator",
.of_compatible = "mediatek,mt6323-regulator"
}, {
Expand Down Expand Up @@ -289,7 +310,7 @@ static int mt6397_probe(struct platform_device *pdev)

ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
ARRAY_SIZE(mt6323_devs), NULL,
0, NULL);
0, pmic->irq_domain);
break;

case MT6397_CID_CODE:
Expand All @@ -304,7 +325,7 @@ static int mt6397_probe(struct platform_device *pdev)

ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
ARRAY_SIZE(mt6397_devs), NULL,
0, NULL);
0, pmic->irq_domain);
break;

default:
Expand Down
9 changes: 9 additions & 0 deletions drivers/power/reset/Kconfig
Expand Up @@ -130,6 +130,15 @@ config POWER_RESET_LTC2952
This driver supports an external powerdown trigger and board power
down via the LTC2952. Bindings are made in the device tree.

config POWER_RESET_MT6397_RTC
bool "MediaTek MT6397 RTC power-off driver"
help
This driver supports turning off a remote MediaTek SoC by
controlling BBPU on MT6397 or MT6323 RTC.

Select this if you're building a kernel with your MediaTek SoC
with an equipment with MT6397 or MT6323 PMIC.

config POWER_RESET_QNAP
bool "QNAP power-off driver"
depends on OF_GPIO && PLAT_ORION
Expand Down
1 change: 1 addition & 0 deletions drivers/power/reset/Makefile
Expand Up @@ -12,6 +12,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
obj-$(CONFIG_POWER_RESET_MT6397_RTC) += mt6397-rtc-poweroff.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
Expand Down
100 changes: 100 additions & 0 deletions drivers/power/reset/mt6397-rtc-poweroff.c
@@ -0,0 +1,100 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Power-off using MediaTek PMIC RTC device
*
* Copyright (C) 2018 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
*
*/

#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/rtc/mt6397.h>

struct mt6397_rtc_powercon {
struct device *dev;
struct mt6397_rtc *rtc;
};

static struct mt6397_rtc_powercon *mt_powercon;

static void mt6397_rtc_do_poweroff(void)
{
struct mt6397_rtc_powercon *powercon = mt_powercon;
struct mt6397_rtc *rtc = powercon->rtc;
unsigned int val;
int ret;

regmap_write(rtc->regmap, rtc->addr_base + RTC_BBPU, RTC_BBPU_KEY);
regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);

ret = regmap_read_poll_timeout(rtc->regmap,
rtc->addr_base + RTC_BBPU, val,
!(val & RTC_BBPU_CBUSY),
MTK_RTC_POLL_DELAY_US,
MTK_RTC_POLL_TIMEOUT);
if (ret)
dev_err(powercon->dev, "failed to write BBPU: %d\n", ret);

/* Wait some time until system down, otherwise, notice with a warn */
mdelay(1000);

WARN_ONCE(1, "Unable to poweroff system\n");
}

static int mt6397_rtc_poweroff_probe(struct platform_device *pdev)
{
struct mt6397_rtc *rtc = dev_get_drvdata(pdev->dev.parent);
struct mt6397_rtc_powercon *powercon;

if (!rtc) {
dev_err(&pdev->dev, "Can't find RTC as the parent\n");
return -ENODEV;
}

powercon = devm_kzalloc(&pdev->dev, sizeof(*powercon), GFP_KERNEL);
if (!powercon)
return -ENOMEM;

powercon->dev = &pdev->dev;
powercon->rtc = rtc;
mt_powercon = powercon;

pm_power_off = &mt6397_rtc_do_poweroff;

return 0;
}

static int mt6397_rtc_poweroff_remove(struct platform_device *pdev)
{
if (pm_power_off == &mt6397_rtc_do_poweroff)
pm_power_off = NULL;

return 0;
}

static const struct of_device_id mt6397_rtc_poweroff_dt_match[] = {
{ .compatible = "mediatek,mt6323-rtc-poweroff" },
{ .compatible = "mediatek,mt6397-rtc-poweroff" },
{},
};
MODULE_DEVICE_TABLE(of, mt6397_rtc_poweroff_dt_match);

static struct platform_driver mt6397_rtc_poweroff_driver = {
.probe = mt6397_rtc_poweroff_probe,
.remove = mt6397_rtc_poweroff_remove,
.driver = {
.name = "mt6397-rtc-poweroff",
.of_match_table = mt6397_rtc_poweroff_dt_match,
},
};

module_platform_driver(mt6397_rtc_poweroff_driver);

MODULE_DESCRIPTION("Poweroff driver using MediaTek PMIC RTC");
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:mt6397-rtc-poweroff");

0 comments on commit 5a350ae

Please sign in to comment.