-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'timers-v5.7' of https://git.linaro.org/people/daniel.lezca…
…no/linux into timers/core Pull clockevent/clocksource updates from Daniel Lezcano: - Avoid creating dead devices by flagging the driver with OF_POPULATED in order to prevent the platform to create another device (Saravana Kannan) - Remove unused includes from imx family drivers (Anson Huang) - timer-dm-ti rework to prepare for pwm and suspend support (Lokesh Vutla) - Fix the rate for the global clock on the pit64b (Claudiu Beznea) - Fix timer-cs5535 by requesting an irq with non-NULL dev_id (Afzal Mohammed) - Replace setup_irq() by request_irq() (Afzal Mohammed) - Add support for the TCU of X1000 (Zhou Yanjie) - Drop the bogus omap_dm_timer_of_set_source() function (Suman Anna) - Do not update the counter when updating the period in order to prevent a disruption when the pwm is used (Lokesh Vutla) - Improve owl_timer_init() failure messages (Matheus Castello) - Add driver for the Ingenic JZ47xx OST (Maarten ter Huurne) - Pass the interrupt and the shutdown callbacks in the init function for ast2600 support (Joel Stanley) - Add the ast2600 compatible string for the fttmr010 (Joel Stanley)
- Loading branch information
Showing
39 changed files
with
471 additions
and
330 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* JZ47xx SoCs TCU Operating System Timer driver | ||
* | ||
* Copyright (C) 2016 Maarten ter Huurne <maarten@treewalker.org> | ||
* Copyright (C) 2020 Paul Cercueil <paul@crapouillou.net> | ||
*/ | ||
|
||
#include <linux/clk.h> | ||
#include <linux/clocksource.h> | ||
#include <linux/mfd/ingenic-tcu.h> | ||
#include <linux/mfd/syscon.h> | ||
#include <linux/of.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/pm.h> | ||
#include <linux/regmap.h> | ||
#include <linux/sched_clock.h> | ||
|
||
#define TCU_OST_TCSR_MASK 0xffc0 | ||
#define TCU_OST_TCSR_CNT_MD BIT(15) | ||
|
||
#define TCU_OST_CHANNEL 15 | ||
|
||
/* | ||
* The TCU_REG_OST_CNT{L,R} from <linux/mfd/ingenic-tcu.h> are only for the | ||
* regmap; these are for use with the __iomem pointer. | ||
*/ | ||
#define OST_REG_CNTL 0x4 | ||
#define OST_REG_CNTH 0x8 | ||
|
||
struct ingenic_ost_soc_info { | ||
bool is64bit; | ||
}; | ||
|
||
struct ingenic_ost { | ||
void __iomem *regs; | ||
struct clk *clk; | ||
|
||
struct clocksource cs; | ||
}; | ||
|
||
static struct ingenic_ost *ingenic_ost; | ||
|
||
static u64 notrace ingenic_ost_read_cntl(void) | ||
{ | ||
/* Read using __iomem pointer instead of regmap to avoid locking */ | ||
return readl(ingenic_ost->regs + OST_REG_CNTL); | ||
} | ||
|
||
static u64 notrace ingenic_ost_read_cnth(void) | ||
{ | ||
/* Read using __iomem pointer instead of regmap to avoid locking */ | ||
return readl(ingenic_ost->regs + OST_REG_CNTH); | ||
} | ||
|
||
static u64 notrace ingenic_ost_clocksource_readl(struct clocksource *cs) | ||
{ | ||
return ingenic_ost_read_cntl(); | ||
} | ||
|
||
static u64 notrace ingenic_ost_clocksource_readh(struct clocksource *cs) | ||
{ | ||
return ingenic_ost_read_cnth(); | ||
} | ||
|
||
static int __init ingenic_ost_probe(struct platform_device *pdev) | ||
{ | ||
const struct ingenic_ost_soc_info *soc_info; | ||
struct device *dev = &pdev->dev; | ||
struct ingenic_ost *ost; | ||
struct clocksource *cs; | ||
struct regmap *map; | ||
unsigned long rate; | ||
int err; | ||
|
||
soc_info = device_get_match_data(dev); | ||
if (!soc_info) | ||
return -EINVAL; | ||
|
||
ost = devm_kzalloc(dev, sizeof(*ost), GFP_KERNEL); | ||
if (!ost) | ||
return -ENOMEM; | ||
|
||
ingenic_ost = ost; | ||
|
||
ost->regs = devm_platform_ioremap_resource(pdev, 0); | ||
if (IS_ERR(ost->regs)) | ||
return PTR_ERR(ost->regs); | ||
|
||
map = device_node_to_regmap(dev->parent->of_node); | ||
if (!map) { | ||
dev_err(dev, "regmap not found"); | ||
return -EINVAL; | ||
} | ||
|
||
ost->clk = devm_clk_get(dev, "ost"); | ||
if (IS_ERR(ost->clk)) | ||
return PTR_ERR(ost->clk); | ||
|
||
err = clk_prepare_enable(ost->clk); | ||
if (err) | ||
return err; | ||
|
||
/* Clear counter high/low registers */ | ||
if (soc_info->is64bit) | ||
regmap_write(map, TCU_REG_OST_CNTL, 0); | ||
regmap_write(map, TCU_REG_OST_CNTH, 0); | ||
|
||
/* Don't reset counter at compare value. */ | ||
regmap_update_bits(map, TCU_REG_OST_TCSR, | ||
TCU_OST_TCSR_MASK, TCU_OST_TCSR_CNT_MD); | ||
|
||
rate = clk_get_rate(ost->clk); | ||
|
||
/* Enable OST TCU channel */ | ||
regmap_write(map, TCU_REG_TESR, BIT(TCU_OST_CHANNEL)); | ||
|
||
cs = &ost->cs; | ||
cs->name = "ingenic-ost"; | ||
cs->rating = 320; | ||
cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; | ||
cs->mask = CLOCKSOURCE_MASK(32); | ||
|
||
if (soc_info->is64bit) | ||
cs->read = ingenic_ost_clocksource_readl; | ||
else | ||
cs->read = ingenic_ost_clocksource_readh; | ||
|
||
err = clocksource_register_hz(cs, rate); | ||
if (err) { | ||
dev_err(dev, "clocksource registration failed"); | ||
clk_disable_unprepare(ost->clk); | ||
return err; | ||
} | ||
|
||
if (soc_info->is64bit) | ||
sched_clock_register(ingenic_ost_read_cntl, 32, rate); | ||
else | ||
sched_clock_register(ingenic_ost_read_cnth, 32, rate); | ||
|
||
return 0; | ||
} | ||
|
||
static int __maybe_unused ingenic_ost_suspend(struct device *dev) | ||
{ | ||
struct ingenic_ost *ost = dev_get_drvdata(dev); | ||
|
||
clk_disable(ost->clk); | ||
|
||
return 0; | ||
} | ||
|
||
static int __maybe_unused ingenic_ost_resume(struct device *dev) | ||
{ | ||
struct ingenic_ost *ost = dev_get_drvdata(dev); | ||
|
||
return clk_enable(ost->clk); | ||
} | ||
|
||
static const struct dev_pm_ops __maybe_unused ingenic_ost_pm_ops = { | ||
/* _noirq: We want the OST clock to be gated last / ungated first */ | ||
.suspend_noirq = ingenic_ost_suspend, | ||
.resume_noirq = ingenic_ost_resume, | ||
}; | ||
|
||
static const struct ingenic_ost_soc_info jz4725b_ost_soc_info = { | ||
.is64bit = false, | ||
}; | ||
|
||
static const struct ingenic_ost_soc_info jz4770_ost_soc_info = { | ||
.is64bit = true, | ||
}; | ||
|
||
static const struct of_device_id ingenic_ost_of_match[] = { | ||
{ .compatible = "ingenic,jz4725b-ost", .data = &jz4725b_ost_soc_info, }, | ||
{ .compatible = "ingenic,jz4770-ost", .data = &jz4770_ost_soc_info, }, | ||
{ } | ||
}; | ||
|
||
static struct platform_driver ingenic_ost_driver = { | ||
.driver = { | ||
.name = "ingenic-ost", | ||
#ifdef CONFIG_PM_SUSPEND | ||
.pm = &ingenic_ost_pm_ops, | ||
#endif | ||
.of_match_table = ingenic_ost_of_match, | ||
}, | ||
}; | ||
builtin_platform_driver_probe(ingenic_ost_driver, ingenic_ost_probe); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.