Commit 7c5b0264 authored by Lee Jones's avatar Lee Jones

Merge branches 'ib-mfd-doc-sparc-libdevres-5.5' and 'ib-mfd-power-rtc-5.5' into ibs-for-mfd-merged

parents 7b8c4d73 9d0863ba
Device-Tree bindings for MediaTek PMIC based RTC
MediaTek PMIC based RTC is an independent function of MediaTek PMIC that works
as a type of multi-function device (MFD). The RTC can be configured and set up
with PMIC wrapper bus which is a common resource shared with the other
functions found on the same PMIC.
For MediaTek PMIC MFD bindings, see:
../mfd/mt6397.txt
For MediaTek PMIC wrapper bus bindings, see:
../soc/mediatek/pwrap.txt
Required properties:
- compatible: Should be one of follows
"mediatek,mt6323-rtc": for MT6323 PMIC
"mediatek,mt6397-rtc": for MT6397 PMIC
Example:
pmic {
compatible = "mediatek,mt6323";
...
rtc {
compatible = "mediatek,mt6323-rtc";
};
};
......@@ -10266,6 +10266,13 @@ S: Maintained
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS
M: Sean Wang <sean.wang@mediatek.com>
L: linux-pm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
F: drivers/power/reset/mt6323-poweroff.c
MEDIATEK JPEG DRIVER
M: Rick Chang <rick.chang@mediatek.com>
M: Bin Liu <bin.liu@mediatek.com>
......
......@@ -140,6 +140,16 @@ 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_MT6323
bool "MediaTek MT6323 power-off driver"
depends on MFD_MT6397
help
The power-off driver is responsible for externally shutdown down
the power of a remote MediaTek SoC MT6323 is connected to through
controlling a tiny circuit BBPU inside MT6323 RTC.
Say Y if you have a board where MT6323 could be found.
config POWER_RESET_QNAP
bool "QNAP power-off driver"
depends on OF_GPIO && PLAT_ORION
......
......@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Power off through MediaTek PMIC
*
* 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/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/rtc.h>
struct mt6323_pwrc {
struct device *dev;
struct regmap *regmap;
u32 base;
};
static struct mt6323_pwrc *mt_pwrc;
static void mt6323_do_pwroff(void)
{
struct mt6323_pwrc *pwrc = mt_pwrc;
unsigned int val;
int ret;
regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY);
regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1);
ret = regmap_read_poll_timeout(pwrc->regmap,
pwrc->base + RTC_BBPU, val,
!(val & RTC_BBPU_CBUSY),
MTK_RTC_POLL_DELAY_US,
MTK_RTC_POLL_TIMEOUT);
if (ret)
dev_err(pwrc->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 power off system\n");
}
static int mt6323_pwrc_probe(struct platform_device *pdev)
{
struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
struct mt6323_pwrc *pwrc;
struct resource *res;
pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
if (!pwrc)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pwrc->base = res->start;
pwrc->regmap = mt6397_chip->regmap;
pwrc->dev = &pdev->dev;
mt_pwrc = pwrc;
pm_power_off = &mt6323_do_pwroff;
return 0;
}
static int mt6323_pwrc_remove(struct platform_device *pdev)
{
if (pm_power_off == &mt6323_do_pwroff)
pm_power_off = NULL;
return 0;
}
static const struct of_device_id mt6323_pwrc_dt_match[] = {
{ .compatible = "mediatek,mt6323-pwrc" },
{},
};
MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
static struct platform_driver mt6323_pwrc_driver = {
.probe = mt6323_pwrc_probe,
.remove = mt6323_pwrc_remove,
.driver = {
.name = "mt6323-pwrc",
.of_match_table = mt6323_pwrc_dt_match,
},
};
module_platform_driver(mt6323_pwrc_driver);
MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC");
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_LICENSE("GPL v2");
......@@ -4,69 +4,19 @@
* Author: Tianping.Fang <tianping.fang@mediatek.com>
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#include <linux/irqdomain.h>
#include <linux/platform_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/mfd/mt6397/core.h>
#define RTC_BBPU 0x0000
#define RTC_BBPU_CBUSY BIT(6)
#define RTC_WRTGR 0x003c
#define RTC_IRQ_STA 0x0002
#define RTC_IRQ_STA_AL BIT(0)
#define RTC_IRQ_STA_LP BIT(3)
#define RTC_IRQ_EN 0x0004
#define RTC_IRQ_EN_AL BIT(0)
#define RTC_IRQ_EN_ONESHOT BIT(2)
#define RTC_IRQ_EN_LP BIT(3)
#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
#define RTC_AL_MASK 0x0008
#define RTC_AL_MASK_DOW BIT(4)
#define RTC_TC_SEC 0x000a
/* Min, Hour, Dom... register offset to RTC_TC_SEC */
#define RTC_OFFSET_SEC 0
#define RTC_OFFSET_MIN 1
#define RTC_OFFSET_HOUR 2
#define RTC_OFFSET_DOM 3
#define RTC_OFFSET_DOW 4
#define RTC_OFFSET_MTH 5
#define RTC_OFFSET_YEAR 6
#define RTC_OFFSET_COUNT 7
#define RTC_AL_SEC 0x0018
#define RTC_PDN2 0x002e
#define RTC_PDN2_PWRON_ALARM BIT(4)
#define RTC_MIN_YEAR 1968
#define RTC_BASE_YEAR 1900
#define RTC_NUM_YEARS 128
#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
struct mt6397_rtc {
struct device *dev;
struct rtc_device *rtc_dev;
struct mutex lock;
struct regmap *regmap;
int irq;
u32 addr_base;
};
#include <linux/mfd/mt6397/rtc.h>
#include <linux/mod_devicetable.h>
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
{
unsigned long timeout = jiffies + HZ;
int ret;
u32 data;
......@@ -74,19 +24,13 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
if (ret < 0)
return ret;
while (1) {
ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU,
&data);
if (ret < 0)
break;
if (!(data & RTC_BBPU_CBUSY))
break;
if (time_after(jiffies, timeout)) {
ret = -ETIMEDOUT;
break;
}
cpu_relax();
}
ret = regmap_read_poll_timeout(rtc->regmap,
rtc->addr_base + RTC_BBPU, data,
!(data & RTC_BBPU_CBUSY),
MTK_RTC_POLL_DELAY_US,
MTK_RTC_POLL_TIMEOUT);
if (ret < 0)
dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret);
return ret;
}
......@@ -319,19 +263,19 @@ static int mtk_rtc_probe(struct platform_device *pdev)
return rtc->irq;
rtc->regmap = mt6397_chip->regmap;
rtc->dev = &pdev->dev;
mutex_init(&rtc->lock);
platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
ret = request_threaded_irq(rtc->irq, NULL,
mtk_rtc_irq_handler_thread,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mt6397-rtc", rtc);
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
mtk_rtc_irq_handler_thread,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mt6397-rtc", rtc);
if (ret) {
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
rtc->irq, ret);
......@@ -353,15 +297,6 @@ static int mtk_rtc_probe(struct platform_device *pdev)
return ret;
}
static int mtk_rtc_remove(struct platform_device *pdev)
{
struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
free_irq(rtc->irq, rtc);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int mt6397_rtc_suspend(struct device *dev)
{
......@@ -388,6 +323,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
mt6397_rtc_resume);
static const struct of_device_id mt6397_rtc_of_match[] = {
{ .compatible = "mediatek,mt6323-rtc", },
{ .compatible = "mediatek,mt6397-rtc", },
{ }
};
......@@ -400,7 +336,6 @@ static struct platform_driver mtk_rtc_driver = {
.pm = &mt6397_pm_ops,
},
.probe = mtk_rtc_probe,
.remove = mtk_rtc_remove,
};
module_platform_driver(mtk_rtc_driver);
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014-2019 MediaTek Inc.
*
* Author: Tianping.Fang <tianping.fang@mediatek.com>
* Sean Wang <sean.wang@mediatek.com>
*/
#ifndef _LINUX_MFD_MT6397_RTC_H_
#define _LINUX_MFD_MT6397_RTC_H_
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#define RTC_BBPU 0x0000
#define RTC_BBPU_CBUSY BIT(6)
#define RTC_BBPU_KEY (0x43 << 8)
#define RTC_WRTGR 0x003c
#define RTC_IRQ_STA 0x0002
#define RTC_IRQ_STA_AL BIT(0)
#define RTC_IRQ_STA_LP BIT(3)
#define RTC_IRQ_EN 0x0004
#define RTC_IRQ_EN_AL BIT(0)
#define RTC_IRQ_EN_ONESHOT BIT(2)
#define RTC_IRQ_EN_LP BIT(3)
#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
#define RTC_AL_MASK 0x0008
#define RTC_AL_MASK_DOW BIT(4)
#define RTC_TC_SEC 0x000a
/* Min, Hour, Dom... register offset to RTC_TC_SEC */
#define RTC_OFFSET_SEC 0
#define RTC_OFFSET_MIN 1
#define RTC_OFFSET_HOUR 2
#define RTC_OFFSET_DOM 3
#define RTC_OFFSET_DOW 4
#define RTC_OFFSET_MTH 5
#define RTC_OFFSET_YEAR 6
#define RTC_OFFSET_COUNT 7
#define RTC_AL_SEC 0x0018
#define RTC_PDN2 0x002e
#define RTC_PDN2_PWRON_ALARM BIT(4)
#define RTC_MIN_YEAR 1968
#define RTC_BASE_YEAR 1900
#define RTC_NUM_YEARS 128
#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
#define MTK_RTC_POLL_DELAY_US 10
#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ))
struct mt6397_rtc {
struct device *dev;
struct rtc_device *rtc_dev;
/* Protect register access from multiple tasks */
struct mutex lock;
struct regmap *regmap;
int irq;
u32 addr_base;
};
#endif /* _LINUX_MFD_MT6397_RTC_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment