* [PATCH v1 3/6] ARM: davinci: don't use static clk_lookup
From: David Lechner @ 2017-12-02 2:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512182054-17410-1-git-send-email-david@lechnology.com>
In preparation of moving to the common clock framework, usage of static
struct clk_lookup is removed. The common clock framework uses an opaque
struct clk, so we won't be able to use static tables as was previously
done.
Each CPU family is given a new CPU-specific init_time function that
registers the clocks individually via function calls instead of using
a clk_lookup table.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 2 +-
arch/arm/mach-davinci/board-da850-evm.c | 2 +-
arch/arm/mach-davinci/board-dm355-evm.c | 2 +-
arch/arm/mach-davinci/board-dm355-leopard.c | 2 +-
arch/arm/mach-davinci/board-dm365-evm.c | 2 +-
arch/arm/mach-davinci/board-dm644x-evm.c | 2 +-
arch/arm/mach-davinci/board-dm646x-evm.c | 4 +-
arch/arm/mach-davinci/board-mityomapl138.c | 2 +-
arch/arm/mach-davinci/board-neuros-osd2.c | 2 +-
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 +-
arch/arm/mach-davinci/board-sffsdr.c | 2 +-
arch/arm/mach-davinci/clock.c | 75 +++++++--------
arch/arm/mach-davinci/clock.h | 9 +-
arch/arm/mach-davinci/da830.c | 115 ++++++++++++-----------
arch/arm/mach-davinci/da850.c | 137 ++++++++++++++--------------
arch/arm/mach-davinci/da8xx-dt.c | 2 +-
arch/arm/mach-davinci/davinci.h | 4 +
arch/arm/mach-davinci/devices-da8xx.c | 5 +-
arch/arm/mach-davinci/dm355.c | 97 ++++++++++----------
arch/arm/mach-davinci/dm365.c | 127 +++++++++++++-------------
arch/arm/mach-davinci/dm644x.c | 89 +++++++++---------
arch/arm/mach-davinci/dm646x.c | 99 +++++++++++---------
arch/arm/mach-davinci/include/mach/common.h | 1 -
arch/arm/mach-davinci/include/mach/da8xx.h | 3 +
arch/arm/mach-davinci/time.c | 8 --
arch/arm/mach-davinci/usb-da8xx.c | 15 +--
26 files changed, 407 insertions(+), 403 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index db656d4..524049a 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -633,7 +633,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
.atag_offset = 0x100,
.map_io = da830_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da830_init_time,
.init_machine = da830_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 7333ade..f766823 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1476,7 +1476,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
.atag_offset = 0x100,
.map_io = da850_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = da850_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index da462e7..ef27f55 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -411,7 +411,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
.atag_offset = 0x100,
.map_io = dm355_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm355_init_time,
.init_machine = dm355_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 21fd713..e705a6e 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -266,7 +266,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
.atag_offset = 0x100,
.map_io = dm355_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm355_init_time,
.init_machine = dm355_leopard_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 4ec759b..4232c09 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -769,7 +769,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
.atag_offset = 0x100,
.map_io = dm365_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm365_init_time,
.init_machine = dm365_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 8f6e9ea..2f6c0c4 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -811,7 +811,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
.atag_offset = 0x100,
.map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index f0e2762..de28f75 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -787,7 +787,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
.atag_offset = 0x100,
.map_io = dm646x_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm646x_init_time,
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
@@ -798,7 +798,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
.atag_offset = 0x100,
.map_io = dm646x_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm646x_init_time,
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 9ea2628..d178932 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -565,7 +565,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
.atag_offset = 0x100,
.map_io = da850_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = mityomapl138_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 6f4e7dc..bd01108 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -222,7 +222,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
.atag_offset = 0x100,
.map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_ntosd2_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 0fdb7b7..c1af201 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -329,7 +329,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
.atag_offset = 0x100,
.map_io = da850_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = omapl138_hawk_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 3c1059a..8e659e1 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -145,7 +145,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
.atag_offset = 0x100,
.map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_sffsdr_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f77a4f7..5f0a31d 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -607,62 +607,51 @@ int davinci_set_refclk_rate(unsigned long rate)
return 0;
}
-int __init davinci_clk_init(struct clk_lookup *clocks)
+void __init davinci_clk_init(struct clk *clk, const char *con_id,
+ const char *dev_id)
{
- struct clk_lookup *c;
- struct clk *clk;
- size_t num_clocks = 0;
-
- for (c = clocks; c->clk; c++) {
- clk = c->clk;
+ if (!clk->recalc) {
- if (!clk->recalc) {
+ /* Check if clock is a PLL */
+ if (clk->pll_data)
+ clk->recalc = clk_pllclk_recalc;
- /* Check if clock is a PLL */
- if (clk->pll_data)
- clk->recalc = clk_pllclk_recalc;
+ /* Else, if it is a PLL-derived clock */
+ else if (clk->flags & CLK_PLL)
+ clk->recalc = clk_sysclk_recalc;
- /* Else, if it is a PLL-derived clock */
- else if (clk->flags & CLK_PLL)
- clk->recalc = clk_sysclk_recalc;
-
- /* Otherwise, it is a leaf clock (PSC clock) */
- else if (clk->parent)
- clk->recalc = clk_leafclk_recalc;
- }
+ /* Otherwise, it is a leaf clock (PSC clock) */
+ else if (clk->parent)
+ clk->recalc = clk_leafclk_recalc;
+ }
- if (clk->pll_data) {
- struct pll_data *pll = clk->pll_data;
+ if (clk->pll_data) {
+ struct pll_data *pll = clk->pll_data;
- if (!pll->div_ratio_mask)
- pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+ if (!pll->div_ratio_mask)
+ pll->div_ratio_mask = PLLDIV_RATIO_MASK;
- if (pll->phys_base && !pll->base) {
- pll->base = ioremap(pll->phys_base, SZ_4K);
- WARN_ON(!pll->base);
- }
+ if (pll->phys_base && !pll->base) {
+ pll->base = ioremap(pll->phys_base, SZ_4K);
+ WARN_ON(!pll->base);
}
+ }
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
-
- if (clk->lpsc)
- clk->flags |= CLK_PSC;
-
- if (clk->flags & PSC_LRST)
- clk->reset = davinci_clk_reset;
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
- clk_register(clk);
- num_clocks++;
+ if (clk->lpsc)
+ clk->flags |= CLK_PSC;
- /* Turn on clocks that Linux doesn't otherwise manage */
- if (clk->flags & ALWAYS_ENABLED)
- clk_enable(clk);
- }
+ if (clk->flags & PSC_LRST)
+ clk->reset = davinci_clk_reset;
- clkdev_add_table(clocks, num_clocks);
+ clk_register(clk);
+ clk_register_clkdev(clk, con_id, dev_id);
- return 0;
+ /* Turn on clocks that Linux doesn't otherwise manage */
+ if (clk->flags & ALWAYS_ENABLED)
+ clk_enable(clk);
}
#ifdef CONFIG_DEBUG_FS
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index fa2b837..e4afaa9 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -118,14 +118,7 @@ struct clk {
#define PSC_FORCE BIT(6) /* Force module state transtition */
#define PSC_LRST BIT(8) /* Use local reset on enable/disable */
-#define CLK(dev, con, ck) \
- { \
- .dev_id = dev, \
- .con_id = con, \
- .clk = ck, \
- } \
-
-int davinci_clk_init(struct clk_lookup *clocks);
+void davinci_clk_init(struct clk *clk, const char *con_id, const char *dev_id);
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
unsigned int mult, unsigned int postdiv);
int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index f28eda1..7771161 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -378,60 +378,60 @@ static struct clk rmii_clk = {
.parent = &pll0_sysclk7,
};
-static struct clk_lookup da830_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
- CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
- CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
- CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
- CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
- CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
- CLK("i2c_davinci.1", NULL, &i2c0_clk),
- CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("davinci-wdt", NULL, &timerp64_1_clk),
- CLK(NULL, "arm_rom", &arm_rom_clk),
- CLK(NULL, "scr0_ss", &scr0_ss_clk),
- CLK(NULL, "scr1_ss", &scr1_ss_clk),
- CLK(NULL, "scr2_ss", &scr2_ss_clk),
- CLK(NULL, "dmax", &dmax_clk),
- CLK(NULL, "tpcc", &tpcc_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK("da830-mmc.0", NULL, &mmcsd_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK(NULL, "ecap0", &ecap0_clk),
- CLK(NULL, "ecap1", &ecap1_clk),
- CLK(NULL, "ecap2", &ecap2_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK("eqep.0", NULL, &eqep0_clk),
- CLK("eqep.1", NULL, &eqep1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
- CLK("musb-da8xx", "usb20", &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "secu_mgr", &secu_mgr_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK("ohci-da8xx", "usb11", &usb11_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK(NULL, NULL, NULL),
-};
+static __init void da830_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&pll0_clk, "pll0", NULL);
+ davinci_clk_init(&pll0_aux_clk, "pll0_aux", NULL);
+ davinci_clk_init(&pll0_sysclk2, "pll0_sysclk2", NULL);
+ davinci_clk_init(&pll0_sysclk3, "pll0_sysclk3", NULL);
+ davinci_clk_init(&pll0_sysclk4, "pll0_sysclk4", NULL);
+ davinci_clk_init(&pll0_sysclk5, "pll0_sysclk5", NULL);
+ davinci_clk_init(&pll0_sysclk6, "pll0_sysclk6", NULL);
+ davinci_clk_init(&pll0_sysclk7, "pll0_sysclk7", NULL);
+ davinci_clk_init(&i2c0_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&timerp64_0_clk, "timer0", NULL);
+ davinci_clk_init(&timerp64_1_clk, NULL, "davinci-wdt");
+ davinci_clk_init(&arm_rom_clk, "arm_rom", NULL);
+ davinci_clk_init(&scr0_ss_clk, "scr0_ss", NULL);
+ davinci_clk_init(&scr1_ss_clk, "scr1_ss", NULL);
+ davinci_clk_init(&scr2_ss_clk, "scr2_ss", NULL);
+ davinci_clk_init(&dmax_clk, "dmax", NULL);
+ davinci_clk_init(&tpcc_clk, "tpcc", NULL);
+ davinci_clk_init(&tptc0_clk, "tptc0", NULL);
+ davinci_clk_init(&tptc1_clk, "tptc1", NULL);
+ davinci_clk_init(&mmcsd_clk, NULL, "da830-mmc.0");
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&uart2_clk, NULL, "serial8250.2");
+ davinci_clk_init(&spi0_clk, NULL, "spi_davinci.0");
+ davinci_clk_init(&spi1_clk, NULL, "spi_davinci.1");
+ davinci_clk_init(&ecap0_clk, "ecap0", NULL);
+ davinci_clk_init(&ecap1_clk, "ecap1", NULL);
+ davinci_clk_init(&ecap2_clk, "ecap2", NULL);
+ davinci_clk_init(&pwm0_clk, "pwm0", NULL);
+ davinci_clk_init(&pwm1_clk, "pwm1", NULL);
+ davinci_clk_init(&pwm2_clk, "pwm2", NULL);
+ davinci_clk_init(&eqep0_clk, NULL, "eqep.0");
+ davinci_clk_init(&eqep1_clk, NULL, "eqep.1");
+ davinci_clk_init(&lcdc_clk, "fck", "da8xx_lcdc.0");
+ davinci_clk_init(&mcasp0_clk, NULL, "davinci-mcasp.0");
+ davinci_clk_init(&mcasp1_clk, NULL, "davinci-mcasp.1");
+ davinci_clk_init(&mcasp2_clk, NULL, "davinci-mcasp.2");
+ davinci_clk_init(&usb20_clk, "usb20", "musb-da8xx");
+ davinci_clk_init(&cppi41_clk, NULL, "cppi41-dmaengine");
+ davinci_clk_init(&aemif_clk, "aemif", NULL);
+ davinci_clk_init(&aintc_clk, "aintc", NULL);
+ davinci_clk_init(&secu_mgr_clk, "secu_mgr", NULL);
+ davinci_clk_init(&emac_clk, NULL, "davinci_emac.1");
+ davinci_clk_init(&emac_clk, "fck", "davinci_mdio.0");
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&i2c1_clk, NULL, "i2c_davinci.2");
+ davinci_clk_init(&usb11_clk, "usb11", "ohci-da8xx");
+ davinci_clk_init(&emif3_clk, "emif3", NULL);
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&rmii_clk, "rmii", NULL);
+}
/*
* Device specific mux setup
@@ -1200,7 +1200,6 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da830_ids,
.ids_num = ARRAY_SIZE(da830_ids),
- .cpu_clks = da830_clks,
.psc_bases = da830_psc_bases,
.psc_bases_num = ARRAY_SIZE(da830_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
@@ -1221,3 +1220,9 @@ void __init da830_map_io(void)
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
}
+
+void __init da830_init_time(void)
+{
+ da830_clk_init();
+ davinci_timer_init();
+}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 28d8ec2..a7484e6 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -518,71 +518,71 @@ static struct clk ecap2_clk = {
.parent = &ecap_clk,
};
-static struct clk_lookup da850_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- CLK(NULL, "pll0_sysclk1", &pll0_sysclk1),
- CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
- CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
- CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
- CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
- CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
- CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "async3", &async3_clk),
- CLK("i2c_davinci.1", NULL, &i2c0_clk),
- CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("davinci-wdt", NULL, &timerp64_1_clk),
- CLK(NULL, "arm_rom", &arm_rom_clk),
- CLK(NULL, "tpcc0", &tpcc0_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK(NULL, "tpcc1", &tpcc1_clk),
- CLK(NULL, "tptc2", &tptc2_clk),
- CLK("pruss_uio", "pruss", &pruss_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &mdio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp_clk),
- CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
- CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("ti-aemif", NULL, &aemif_clk),
- CLK("davinci-nand.0", "aemif", &aemif_nand_clk),
- CLK("ohci-da8xx", "usb11", &usb11_clk),
- CLK("musb-da8xx", "usb20", &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("vpif", NULL, &vpif_clk),
- CLK("ahci_da850", "fck", &sata_clk),
- CLK("davinci-rproc.0", NULL, &dsp_clk),
- CLK(NULL, NULL, &ehrpwm_clk),
- CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
- CLK("ehrpwm.1", "fck", &ehrpwm1_clk),
- CLK(NULL, NULL, &ehrpwm_tbclk),
- CLK("ehrpwm.0", "tbclk", &ehrpwm0_tbclk),
- CLK("ehrpwm.1", "tbclk", &ehrpwm1_tbclk),
- CLK(NULL, NULL, &ecap_clk),
- CLK("ecap.0", "fck", &ecap0_clk),
- CLK("ecap.1", "fck", &ecap1_clk),
- CLK("ecap.2", "fck", &ecap2_clk),
- CLK(NULL, NULL, NULL),
-};
+static __init void da850_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&pll0_clk, "pll0", NULL);
+ davinci_clk_init(&pll0_aux_clk, "pll0_aux", NULL);
+ davinci_clk_init(&pll0_sysclk1, "pll0_sysclk1", NULL);
+ davinci_clk_init(&pll0_sysclk2, "pll0_sysclk2", NULL);
+ davinci_clk_init(&pll0_sysclk3, "pll0_sysclk3", NULL);
+ davinci_clk_init(&pll0_sysclk4, "pll0_sysclk4", NULL);
+ davinci_clk_init(&pll0_sysclk5, "pll0_sysclk5", NULL);
+ davinci_clk_init(&pll0_sysclk6, "pll0_sysclk6", NULL);
+ davinci_clk_init(&pll0_sysclk7, "pll0_sysclk7", NULL);
+ davinci_clk_init(&pll1_clk, "pll1", NULL);
+ davinci_clk_init(&pll1_aux_clk, "pll1_aux", NULL);
+ davinci_clk_init(&pll1_sysclk2, "pll1_sysclk2", NULL);
+ davinci_clk_init(&pll1_sysclk3, "pll1_sysclk3", NULL);
+ davinci_clk_init(&async3_clk, "async3", NULL);
+ davinci_clk_init(&i2c0_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&timerp64_0_clk, "timer0", NULL);
+ davinci_clk_init(&timerp64_1_clk, NULL, "davinci-wdt");
+ davinci_clk_init(&arm_rom_clk, "arm_rom", NULL);
+ davinci_clk_init(&tpcc0_clk, "tpcc0", NULL);
+ davinci_clk_init(&tptc0_clk, "tptc0", NULL);
+ davinci_clk_init(&tptc1_clk, "tptc1", NULL);
+ davinci_clk_init(&tpcc1_clk, "tpcc1", NULL);
+ davinci_clk_init(&tptc2_clk, "tptc2", NULL);
+ davinci_clk_init(&pruss_clk, "pruss", "pruss_uio");
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&uart2_clk, NULL, "serial8250.2");
+ davinci_clk_init(&aintc_clk, "aintc", NULL);
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&i2c1_clk, NULL, "i2c_davinci.2");
+ davinci_clk_init(&emif3_clk, "emif3", NULL);
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&rmii_clk, "rmii", NULL);
+ davinci_clk_init(&emac_clk, NULL, "davinci_emac.1");
+ davinci_clk_init(&mdio_clk, "fck", "davinci_mdio.0");
+ davinci_clk_init(&mcasp_clk, NULL, "davinci-mcasp.0");
+ davinci_clk_init(&mcbsp0_clk, NULL, "davinci-mcbsp.0");
+ davinci_clk_init(&mcbsp1_clk, NULL, "davinci-mcbsp.1");
+ davinci_clk_init(&lcdc_clk, "fck", "da8xx_lcdc.0");
+ davinci_clk_init(&mmcsd0_clk, NULL, "da830-mmc.0");
+ davinci_clk_init(&mmcsd1_clk, NULL, "da830-mmc.1");
+ davinci_clk_init(&aemif_clk, NULL, "ti-aemif");
+ davinci_clk_init(&aemif_nand_clk, "aemif", "davinci-nand.0");
+ davinci_clk_init(&usb11_clk, "usb11", "ohci-da8xx");
+ davinci_clk_init(&usb20_clk, "usb20", "musb-da8xx");
+ davinci_clk_init(&cppi41_clk, NULL, "cppi41-dmaengine");
+ davinci_clk_init(&spi0_clk, NULL, "spi_davinci.0");
+ davinci_clk_init(&spi1_clk, NULL, "spi_davinci.1");
+ davinci_clk_init(&vpif_clk, NULL, "vpif");
+ davinci_clk_init(&sata_clk, "fck", "ahci_da850");
+ davinci_clk_init(&dsp_clk, NULL, "davinci-rproc.0");
+ davinci_clk_init(&ehrpwm_clk, NULL, NULL);
+ davinci_clk_init(&ehrpwm0_clk, "fck", "ehrpwm.0");
+ davinci_clk_init(&ehrpwm1_clk, "fck", "ehrpwm.1");
+ davinci_clk_init(&ehrpwm_tbclk, NULL, NULL);
+ davinci_clk_init(&ehrpwm0_tbclk, "tbclk", "ehrpwm.0");
+ davinci_clk_init(&ehrpwm1_tbclk, "tbclk", "ehrpwm.1");
+ davinci_clk_init(&ecap_clk, NULL, NULL);
+ davinci_clk_init(&ecap0_clk, "fck", "ecap.0");
+ davinci_clk_init(&ecap1_clk, "fck", "ecap.1");
+ davinci_clk_init(&ecap2_clk, "fck", "ecap.2");
+}
/*
* Device specific mux setup
@@ -1353,7 +1353,6 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da850_ids,
.ids_num = ARRAY_SIZE(da850_ids),
- .cpu_clks = da850_clks,
.psc_bases = da850_psc_bases,
.psc_bases_num = ARRAY_SIZE(da850_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
@@ -1393,3 +1392,9 @@ void __init da850_map_io(void)
v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
}
+
+void __init da850_init_time(void)
+{
+ da850_clk_init();
+ davinci_timer_init();
+}
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 92c7c34..1a09215 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -96,7 +96,7 @@ static const char *const da850_boards_compat[] __initconst = {
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.map_io = da850_map_io,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index d550717..ce67a65 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -83,6 +83,7 @@ int davinci_init_wdt(void);
/* DM355 function declarations */
void dm355_map_io(void);
+void dm355_init_time(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable);
@@ -91,6 +92,7 @@ int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_map_io(void);
+void dm365_init_time(void);
void dm365_init_asp(void);
void dm365_init_vc(void);
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -102,12 +104,14 @@ int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_map_io(void);
+void dm644x_init_time(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_map_io(void);
+void dm646x_init_time(void);
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 22440c0..cc497f4 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -1059,9 +1059,6 @@ static struct clk sata_refclk = {
.set_rate = davinci_simple_set_rate,
};
-static struct clk_lookup sata_refclk_lookup =
- CLK("ahci_da850", "refclk", &sata_refclk);
-
int __init da850_register_sata_refclk(int rate)
{
int ret;
@@ -1071,7 +1068,7 @@ int __init da850_register_sata_refclk(int rate)
if (ret)
return ret;
- clkdev_add(&sata_refclk_lookup);
+ clk_register_clkdev(&sata_refclk, "refclk", "ahci_da850");
return 0;
}
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 164ff27..555b99d 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -337,51 +337,51 @@ static struct clk usb_clk = {
.lpsc = DAVINCI_LPSC_USB,
};
-static struct clk_lookup dm355_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "clkout2", &clkout2_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "clkout3", &clkout3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("davinci-mcbsp.0", NULL, &asp0_clk),
- CLK("davinci-mcbsp.1", NULL, &asp1_clk),
- CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
- CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, NULL, NULL),
-};
+static __init void dm355_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&pll1_clk, "pll1", NULL);
+ davinci_clk_init(&pll1_sysclk1, "pll1_sysclk1", NULL);
+ davinci_clk_init(&pll1_sysclk2, "pll1_sysclk2", NULL);
+ davinci_clk_init(&pll1_sysclk3, "pll1_sysclk3", NULL);
+ davinci_clk_init(&pll1_sysclk4, "pll1_sysclk4", NULL);
+ davinci_clk_init(&pll1_aux_clk, "pll1_aux", NULL);
+ davinci_clk_init(&pll1_sysclkbp, "pll1_sysclkbp", NULL);
+ davinci_clk_init(&vpss_dac_clk, "vpss_dac", NULL);
+ davinci_clk_init(&vpss_master_clk, "master", "vpss");
+ davinci_clk_init(&vpss_slave_clk, "slave", "vpss");
+ davinci_clk_init(&clkout1_clk, "clkout1", NULL);
+ davinci_clk_init(&clkout2_clk, "clkout2", NULL);
+ davinci_clk_init(&pll2_clk, "pll2", NULL);
+ davinci_clk_init(&pll2_sysclk1, "pll2_sysclk1", NULL);
+ davinci_clk_init(&pll2_sysclkbp, "pll2_sysclkbp", NULL);
+ davinci_clk_init(&clkout3_clk, "clkout3", NULL);
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&mjcp_clk, "mjcp", NULL);
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&uart2_clk, NULL, "serial8250.2");
+ davinci_clk_init(&i2c_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&asp0_clk, NULL, "davinci-mcbsp.0");
+ davinci_clk_init(&asp1_clk, NULL, "davinci-mcbsp.1");
+ davinci_clk_init(&mmcsd0_clk, NULL, "dm6441-mmc.0");
+ davinci_clk_init(&mmcsd1_clk, NULL, "dm6441-mmc.1");
+ davinci_clk_init(&spi0_clk, NULL, "spi_davinci.0");
+ davinci_clk_init(&spi1_clk, NULL, "spi_davinci.1");
+ davinci_clk_init(&spi2_clk, NULL, "spi_davinci.2");
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&aemif_clk, "aemif", NULL);
+ davinci_clk_init(&pwm0_clk, "pwm0", NULL);
+ davinci_clk_init(&pwm1_clk, "pwm1", NULL);
+ davinci_clk_init(&pwm2_clk, "pwm2", NULL);
+ davinci_clk_init(&pwm3_clk, "pwm3", NULL);
+ davinci_clk_init(&timer0_clk, "timer0", NULL);
+ davinci_clk_init(&timer1_clk, "timer1", NULL);
+ davinci_clk_init(&timer2_clk, NULL, "davinci-wdt");
+ davinci_clk_init(&timer3_clk, "timer3", NULL);
+ davinci_clk_init(&rto_clk, "rto", NULL);
+ davinci_clk_init(&usb_clk, "usb", NULL);
+}
/*----------------------------------------------------------------------*/
@@ -1012,7 +1012,6 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
.jtag_id_reg = 0x01c40028,
.ids = dm355_ids,
.ids_num = ARRAY_SIZE(dm355_ids),
- .cpu_clks = dm355_clks,
.psc_bases = dm355_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -1045,6 +1044,12 @@ void __init dm355_map_io(void)
davinci_map_sysmod();
}
+void __init dm355_init_time(void)
+{
+ dm355_clk_init();
+ davinci_timer_init();
+}
+
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
struct vpbe_config *vpbe_cfg)
{
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 6076085..44bbfae 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -425,66 +425,66 @@ static struct clk mjcp_clk = {
.lpsc = DM365_LPSC_MJCP,
};
-static struct clk_lookup dm365_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "clkout0", &clkout0_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
- CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_aux", &pll2_aux_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
- CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
- CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
- CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
- CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
- CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
- CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK("spi_davinci.3", NULL, &spi3_clk),
- CLK("spi_davinci.4", NULL, &spi4_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("davinci_voicecodec", NULL, &voicecodec_clk),
- CLK("davinci-mcbsp", NULL, &asp0_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK(NULL, NULL, NULL),
-};
+static __init void dm365_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&pll1_clk, "pll1", NULL);
+ davinci_clk_init(&pll1_aux_clk, "pll1_aux", NULL);
+ davinci_clk_init(&pll1_sysclkbp, "pll1_sysclkbp", NULL);
+ davinci_clk_init(&clkout0_clk, "clkout0", NULL);
+ davinci_clk_init(&pll1_sysclk1, "pll1_sysclk1", NULL);
+ davinci_clk_init(&pll1_sysclk2, "pll1_sysclk2", NULL);
+ davinci_clk_init(&pll1_sysclk3, "pll1_sysclk3", NULL);
+ davinci_clk_init(&pll1_sysclk4, "pll1_sysclk4", NULL);
+ davinci_clk_init(&pll1_sysclk5, "pll1_sysclk5", NULL);
+ davinci_clk_init(&pll1_sysclk6, "pll1_sysclk6", NULL);
+ davinci_clk_init(&pll1_sysclk7, "pll1_sysclk7", NULL);
+ davinci_clk_init(&pll1_sysclk8, "pll1_sysclk8", NULL);
+ davinci_clk_init(&pll1_sysclk9, "pll1_sysclk9", NULL);
+ davinci_clk_init(&pll2_clk, "pll2", NULL);
+ davinci_clk_init(&pll2_aux_clk, "pll2_aux", NULL);
+ davinci_clk_init(&clkout1_clk, "clkout1", NULL);
+ davinci_clk_init(&pll2_sysclk1, "pll2_sysclk1", NULL);
+ davinci_clk_init(&pll2_sysclk2, "pll2_sysclk2", NULL);
+ davinci_clk_init(&pll2_sysclk3, "pll2_sysclk3", NULL);
+ davinci_clk_init(&pll2_sysclk4, "pll2_sysclk4", NULL);
+ davinci_clk_init(&pll2_sysclk5, "pll2_sysclk5", NULL);
+ davinci_clk_init(&pll2_sysclk6, "pll2_sysclk6", NULL);
+ davinci_clk_init(&pll2_sysclk7, "pll2_sysclk7", NULL);
+ davinci_clk_init(&pll2_sysclk8, "pll2_sysclk8", NULL);
+ davinci_clk_init(&pll2_sysclk9, "pll2_sysclk9", NULL);
+ davinci_clk_init(&vpss_dac_clk, "vpss_dac", NULL);
+ davinci_clk_init(&vpss_master_clk, "master", "vpss");
+ davinci_clk_init(&vpss_slave_clk, "slave", "vpss");
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&i2c_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&mmcsd0_clk, NULL, "da830-mmc.0");
+ davinci_clk_init(&mmcsd1_clk, NULL, "da830-mmc.1");
+ davinci_clk_init(&spi0_clk, NULL, "spi_davinci.0");
+ davinci_clk_init(&spi1_clk, NULL, "spi_davinci.1");
+ davinci_clk_init(&spi2_clk, NULL, "spi_davinci.2");
+ davinci_clk_init(&spi3_clk, NULL, "spi_davinci.3");
+ davinci_clk_init(&spi4_clk, NULL, "spi_davinci.4");
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&aemif_clk, "aemif", NULL);
+ davinci_clk_init(&pwm0_clk, "pwm0", NULL);
+ davinci_clk_init(&pwm1_clk, "pwm1", NULL);
+ davinci_clk_init(&pwm2_clk, "pwm2", NULL);
+ davinci_clk_init(&pwm3_clk, "pwm3", NULL);
+ davinci_clk_init(&timer0_clk, "timer0", NULL);
+ davinci_clk_init(&timer1_clk, "timer1", NULL);
+ davinci_clk_init(&timer2_clk, NULL, "davinci-wdt");
+ davinci_clk_init(&timer3_clk, "timer3", NULL);
+ davinci_clk_init(&usb_clk, "usb", NULL);
+ davinci_clk_init(&emac_clk, NULL, "davinci_emac.1");
+ davinci_clk_init(&emac_clk, "fck", "davinci_mdio.0");
+ davinci_clk_init(&voicecodec_clk, NULL, "davinci_voicecodec");
+ davinci_clk_init(&asp0_clk, NULL, "davinci-mcbsp");
+ davinci_clk_init(&rto_clk, "rto", NULL);
+ davinci_clk_init(&mjcp_clk, "mjcp", NULL);
+}
/*----------------------------------------------------------------------*/
@@ -1114,7 +1114,6 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
.jtag_id_reg = 0x01c40028,
.ids = dm365_ids,
.ids_num = ARRAY_SIZE(dm365_ids),
- .cpu_clks = dm365_clks,
.psc_bases = dm365_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -1168,6 +1167,12 @@ void __init dm365_map_io(void)
davinci_map_sysmod();
}
+void __init dm365_init_time(void)
+{
+ dm365_clk_init();
+ davinci_timer_init();
+}
+
static struct resource dm365_vpss_resources[] = {
{
/* VPSS ISP5 Base address */
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index c5b1cf3..5d5f70d 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -285,47 +285,47 @@ static struct clk timer2_clk = {
.usecount = 1, /* REVISIT: why can't this be disabled? */
};
-static struct clk_lookup dm644x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "vicp", &vicp_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK("davinci-mcbsp", NULL, &asp_clk),
- CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
- CLK(NULL, "spi", &spi_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, "vlynq", &vlynq_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, NULL, NULL),
-};
+static __init void dm644x_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&pll1_clk, "pll1", NULL);
+ davinci_clk_init(&pll1_sysclk1, "pll1_sysclk1", NULL);
+ davinci_clk_init(&pll1_sysclk2, "pll1_sysclk2", NULL);
+ davinci_clk_init(&pll1_sysclk3, "pll1_sysclk3", NULL);
+ davinci_clk_init(&pll1_sysclk5, "pll1_sysclk5", NULL);
+ davinci_clk_init(&pll1_aux_clk, "pll1_aux", NULL);
+ davinci_clk_init(&pll1_sysclkbp, "pll1_sysclkbp", NULL);
+ davinci_clk_init(&pll2_clk, "pll2", NULL);
+ davinci_clk_init(&pll2_sysclk1, "pll2_sysclk1", NULL);
+ davinci_clk_init(&pll2_sysclk2, "pll2_sysclk2", NULL);
+ davinci_clk_init(&pll2_sysclkbp, "pll2_sysclkbp", NULL);
+ davinci_clk_init(&dsp_clk, "dsp", NULL);
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&vicp_clk, "vicp", NULL);
+ davinci_clk_init(&vpss_master_clk, "master", "vpss");
+ davinci_clk_init(&vpss_slave_clk, "slave", "vpss");
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&uart2_clk, NULL, "serial8250.2");
+ davinci_clk_init(&emac_clk, NULL, "davinci_emac.1");
+ davinci_clk_init(&emac_clk, "fck", "davinci_mdio.0");
+ davinci_clk_init(&i2c_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&ide_clk, NULL, "palm_bk3710");
+ davinci_clk_init(&asp_clk, NULL, "davinci-mcbsp");
+ davinci_clk_init(&mmcsd_clk, NULL, "dm6441-mmc.0");
+ davinci_clk_init(&spi_clk, "spi", NULL);
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&usb_clk, "usb", NULL);
+ davinci_clk_init(&vlynq_clk, "vlynq", NULL);
+ davinci_clk_init(&aemif_clk, "aemif", NULL);
+ davinci_clk_init(&pwm0_clk, "pwm0", NULL);
+ davinci_clk_init(&pwm1_clk, "pwm1", NULL);
+ davinci_clk_init(&pwm2_clk, "pwm2", NULL);
+ davinci_clk_init(&timer0_clk, "timer0", NULL);
+ davinci_clk_init(&timer1_clk, "timer1", NULL);
+ davinci_clk_init(&timer2_clk, NULL, "davinci-wdt");
+}
static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
@@ -905,7 +905,6 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
- .cpu_clks = dm644x_clks,
.psc_bases = dm644x_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -933,6 +932,12 @@ void __init dm644x_map_io(void)
davinci_map_sysmod();
}
+void __init dm644x_init_time(void)
+{
+ dm644x_clk_init();
+ davinci_timer_init();
+}
+
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
struct vpbe_config *vpbe_cfg)
{
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index a844f7b..9b09e5d 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -17,6 +17,7 @@
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
@@ -320,49 +321,54 @@ static struct clk vpif1_clk = {
.flags = ALWAYS_ENABLED,
};
-static struct clk_lookup dm646x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "aux", &aux_clkin),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
- CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "edma_cc", &edma_cc_clk),
- CLK(NULL, "edma_tc0", &edma_tc0_clk),
- CLK(NULL, "edma_tc1", &edma_tc1_clk),
- CLK(NULL, "edma_tc2", &edma_tc2_clk),
- CLK(NULL, "edma_tc3", &edma_tc3_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK(NULL, "vpif0", &vpif0_clk),
- CLK(NULL, "vpif1", &vpif1_clk),
- CLK(NULL, NULL, NULL),
-};
+#define DM6467T_EVM_REF_FREQ 33000000
+
+static __init void dm646x_clk_init(void)
+{
+ davinci_clk_init(&ref_clk, "ref", NULL);
+ davinci_clk_init(&aux_clkin, "aux", NULL);
+ davinci_clk_init(&pll1_clk, "pll1", NULL);
+ davinci_clk_init(&pll1_sysclk1, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk2, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk3, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk4, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk5, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk6, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk8, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclk9, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_sysclkbp, "pll1_sysclk", NULL);
+ davinci_clk_init(&pll1_aux_clk, "pll1_aux", NULL);
+ davinci_clk_init(&pll2_clk, "pll2", NULL);
+ davinci_clk_init(&pll2_sysclk1, "pll2_sysclk1", NULL);
+ davinci_clk_init(&dsp_clk, "dsp", NULL);
+ davinci_clk_init(&arm_clk, "arm", NULL);
+ davinci_clk_init(&edma_cc_clk, "edma_cc", NULL);
+ davinci_clk_init(&edma_tc0_clk, "edma_tc0", NULL);
+ davinci_clk_init(&edma_tc1_clk, "edma_tc1", NULL);
+ davinci_clk_init(&edma_tc2_clk, "edma_tc2", NULL);
+ davinci_clk_init(&edma_tc3_clk, "edma_tc3", NULL);
+ davinci_clk_init(&uart0_clk, NULL, "serial8250.0");
+ davinci_clk_init(&uart1_clk, NULL, "serial8250.1");
+ davinci_clk_init(&uart2_clk, NULL, "serial8250.2");
+ davinci_clk_init(&i2c_clk, NULL, "i2c_davinci.1");
+ davinci_clk_init(&gpio_clk, "gpio", NULL);
+ davinci_clk_init(&mcasp0_clk, NULL, "davinci-mcasp.0");
+ davinci_clk_init(&mcasp1_clk, NULL, "davinci-mcasp.1");
+ davinci_clk_init(&aemif_clk, "aemif", NULL);
+ davinci_clk_init(&emac_clk, NULL, "davinci_emac.1");
+ davinci_clk_init(&emac_clk, "fck", "davinci_mdio.0");
+ davinci_clk_init(&pwm0_clk, "pwm0", NULL);
+ davinci_clk_init(&pwm1_clk, "pwm1", NULL);
+ davinci_clk_init(&timer0_clk, "timer0", NULL);
+ davinci_clk_init(&timer1_clk, "timer1", NULL);
+ davinci_clk_init(&timer2_clk, NULL, "davinci-wdt");
+ davinci_clk_init(&ide_clk, NULL, "palm_bk3710");
+ davinci_clk_init(&vpif0_clk, "vpif0", NULL);
+ davinci_clk_init(&vpif1_clk, "vpif1", NULL);
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+}
static struct emac_platform_data dm646x_emac_pdata = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
@@ -888,7 +894,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
.jtag_id_reg = 0x01c40028,
.ids = dm646x_ids,
.ids_num = ARRAY_SIZE(dm646x_ids),
- .cpu_clks = dm646x_clks,
.psc_bases = dm646x_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -958,6 +963,12 @@ void __init dm646x_map_io(void)
davinci_map_sysmod();
}
+void __init dm646x_init_time(void)
+{
+ dm646x_clk_init();
+ davinci_timer_init();
+}
+
static int __init dm646x_init_devices(void)
{
int ret = 0;
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 037aa66..9b85d5d 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,7 +53,6 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
- struct clk_lookup *cpu_clks;
u32 *psc_bases;
unsigned long psc_bases_num;
u32 pinmux_base;
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index c760c1b..90b00d0 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -87,7 +87,10 @@ extern unsigned int da850_max_speed;
#define DA8XX_ARM_RAM_BASE 0xffff0000
void da830_map_io(void);
+void da830_init_time(void);
+
void da850_map_io(void);
+void da850_init_time(void);
int da830_register_edma(struct edma_rsv_info *rsv);
int da850_register_edma(struct edma_rsv_info *rsv[2]);
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 6ba156e..65b28e6 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -20,7 +20,6 @@
#include <linux/platform_device.h>
#include <linux/sched_clock.h>
-#include <asm/mach-types.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
@@ -342,8 +341,6 @@ static struct clock_event_device clockevent_davinci = {
.set_state_oneshot = davinci_set_oneshot,
};
-#define DM6467T_EVM_REF_FREQ 33000000
-
void __init davinci_timer_init(void)
{
struct clk *timer_clk;
@@ -352,11 +349,6 @@ void __init davinci_timer_init(void)
unsigned int clocksource_id;
int i;
- davinci_clk_init(soc_info->cpu_clks);
-
- if (machine_is_davinci_dm6467tevm())
- davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
-
clockevent_id = soc_info->timer_info->clockevent_id;
clocksource_id = soc_info->timer_info->clocksource_id;
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index 9a6af0b..2630efa9e 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -132,9 +132,6 @@ static struct clk usb_refclkin = {
.set_rate = davinci_simple_set_rate,
};
-static struct clk_lookup usb_refclkin_lookup =
- CLK(NULL, "usb_refclkin", &usb_refclkin);
-
/**
* da8xx_register_usb_refclkin - register USB_REFCLKIN clock
*
@@ -153,7 +150,7 @@ int __init da8xx_register_usb_refclkin(int rate)
if (ret)
return ret;
- clkdev_add(&usb_refclkin_lookup);
+ clk_register_clkdev(&usb_refclkin, "usb_refclkin", NULL);
return 0;
}
@@ -261,9 +258,6 @@ static struct clk usb20_phy_clk = {
.set_parent = usb20_phy_clk_set_parent,
};
-static struct clk_lookup usb20_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
-
/**
* da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
*
@@ -290,7 +284,7 @@ int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
usb20_phy_clk.parent = parent;
ret = clk_register(&usb20_phy_clk);
if (!ret)
- clkdev_add(&usb20_phy_clk_lookup);
+ clk_register_clkdev(&usb20_phy_clk, "usb20_phy", "da8xx-usb-phy");
clk_put(parent);
@@ -323,9 +317,6 @@ static struct clk usb11_phy_clk = {
.set_parent = usb11_phy_clk_set_parent,
};
-static struct clk_lookup usb11_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
-
/**
* da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
*
@@ -347,7 +338,7 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
usb11_phy_clk.parent = parent;
ret = clk_register(&usb11_phy_clk);
if (!ret)
- clkdev_add(&usb11_phy_clk_lookup);
+ clk_register_clkdev(&usb11_phy_clk, "usb11_phy", "da8xx-usb-phy");
clk_put(parent);
--
2.7.4
^ permalink raw reply related
* [PATCH v1 2/6] ARM: davinci: move davinci_clk_init() to init_time
From: David Lechner @ 2017-12-02 2:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512182054-17410-1-git-send-email-david@lechnology.com>
This moves the call of davinci_clk_init() from map_io to init_time for all
boards.
This is the proper place to init clocks. This is also done in preparation
for moving to the common clock framework.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/da830.c | 2 --
arch/arm/mach-davinci/da850.c | 2 --
arch/arm/mach-davinci/dm355.c | 1 -
arch/arm/mach-davinci/dm365.c | 1 -
arch/arm/mach-davinci/dm644x.c | 1 -
arch/arm/mach-davinci/dm646x.c | 7 -------
arch/arm/mach-davinci/time.c | 7 +++++++
7 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 2e249f0..f28eda1 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1220,6 +1220,4 @@ void __init da830_map_io(void)
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
-
- davinci_clk_init(davinci_soc_info_da830.cpu_clks);
}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 056b148..28d8ec2 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1392,6 +1392,4 @@ void __init da850_map_io(void)
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
- davinci_clk_init(davinci_soc_info_da850.cpu_clks);
}
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 88c3c80..164ff27 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1043,7 +1043,6 @@ void __init dm355_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm355);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
}
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index f979180..6076085 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1166,7 +1166,6 @@ void __init dm365_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm365);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
}
static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 80048c0..c5b1cf3 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -931,7 +931,6 @@ void __init dm644x_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm644x);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
}
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index b3be5c8..a844f7b 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -17,7 +17,6 @@
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
-#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
@@ -953,16 +952,10 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv)
return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
}
-#define DM6467T_EVM_REF_FREQ 33000000
-
void __init dm646x_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm646x);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
-
- if (machine_is_davinci_dm6467tevm())
- davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
}
static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 034f865..6ba156e 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/sched_clock.h>
+#include <asm/mach-types.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
@@ -341,6 +342,7 @@ static struct clock_event_device clockevent_davinci = {
.set_state_oneshot = davinci_set_oneshot,
};
+#define DM6467T_EVM_REF_FREQ 33000000
void __init davinci_timer_init(void)
{
@@ -350,6 +352,11 @@ void __init davinci_timer_init(void)
unsigned int clocksource_id;
int i;
+ davinci_clk_init(soc_info->cpu_clks);
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+
clockevent_id = soc_info->timer_info->clockevent_id;
clocksource_id = soc_info->timer_info->clocksource_id;
--
2.7.4
^ permalink raw reply related
* [PATCH v1 1/6] ARM: davinci: clean up map_io functions
From: David Lechner @ 2017-12-02 2:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512182054-17410-1-git-send-email-david@lechnology.com>
This cleans up the map_io functions in the board init files for
mach-davinci.
Most of the boards had a wrapper function around <board>_init(). This
wrapper is removed and the function is used directly. Additionally, the
<board>_init() functions are renamed to <board>_map_io() to match the
field name.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 7 +------
arch/arm/mach-davinci/board-da850-evm.c | 7 +------
arch/arm/mach-davinci/board-dm355-evm.c | 7 +------
arch/arm/mach-davinci/board-dm355-leopard.c | 7 +------
arch/arm/mach-davinci/board-dm365-evm.c | 7 +------
arch/arm/mach-davinci/board-dm644x-evm.c | 8 +-------
arch/arm/mach-davinci/board-dm646x-evm.c | 14 ++------------
arch/arm/mach-davinci/board-mityomapl138.c | 7 +------
arch/arm/mach-davinci/board-neuros-osd2.c | 7 +------
arch/arm/mach-davinci/board-omapl138-hawk.c | 7 +------
arch/arm/mach-davinci/board-sffsdr.c | 7 +------
arch/arm/mach-davinci/da830.c | 2 +-
arch/arm/mach-davinci/da850.c | 2 +-
arch/arm/mach-davinci/da8xx-dt.c | 2 +-
arch/arm/mach-davinci/davinci.h | 8 ++++----
arch/arm/mach-davinci/dm355.c | 2 +-
arch/arm/mach-davinci/dm365.c | 2 +-
arch/arm/mach-davinci/dm644x.c | 2 +-
arch/arm/mach-davinci/dm646x.c | 8 +++++++-
arch/arm/mach-davinci/include/mach/da8xx.h | 4 ++--
20 files changed, 31 insertions(+), 86 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index f673cd7..db656d4 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -629,14 +629,9 @@ static int __init da830_evm_console_init(void)
console_initcall(da830_evm_console_init);
#endif
-static void __init da830_evm_map_io(void)
-{
- da830_init();
-}
-
MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
.atag_offset = 0x100,
- .map_io = da830_evm_map_io,
+ .map_io = da830_map_io,
.init_irq = cp_intc_init,
.init_time = davinci_timer_init,
.init_machine = da830_evm_init,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index cbde003..7333ade 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1472,14 +1472,9 @@ static int __init da850_evm_console_init(void)
console_initcall(da850_evm_console_init);
#endif
-static void __init da850_evm_map_io(void)
-{
- da850_init();
-}
-
MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
.atag_offset = 0x100,
- .map_io = da850_evm_map_io,
+ .map_io = da850_map_io,
.init_irq = cp_intc_init,
.init_time = davinci_timer_init,
.init_machine = da850_evm_init,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 62e7bc3..da462e7 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -314,11 +314,6 @@ static struct platform_device *davinci_evm_devices[] __initdata = {
&davinci_nand_device,
};
-static void __init dm355_evm_map_io(void)
-{
- dm355_init();
-}
-
static int dm355evm_mmc_get_cd(int module)
{
if (!gpio_is_valid(dm355evm_mmc_gpios))
@@ -414,7 +409,7 @@ static __init void dm355_evm_init(void)
MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
.atag_offset = 0x100,
- .map_io = dm355_evm_map_io,
+ .map_io = dm355_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = dm355_evm_init,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index be99724..21fd713 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -174,11 +174,6 @@ static struct platform_device *davinci_leopard_devices[] __initdata = {
&davinci_nand_device,
};
-static void __init dm355_leopard_map_io(void)
-{
- dm355_init();
-}
-
static int dm355leopard_mmc_get_cd(int module)
{
if (!gpio_is_valid(leopard_mmc_gpio))
@@ -269,7 +264,7 @@ static __init void dm355_leopard_init(void)
MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
.atag_offset = 0x100,
- .map_io = dm355_leopard_map_io,
+ .map_io = dm355_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = dm355_leopard_init,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index e75741f..4ec759b 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -714,11 +714,6 @@ static void __init evm_init_cpld(void)
/* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */
}
-static void __init dm365_evm_map_io(void)
-{
- dm365_init();
-}
-
static struct spi_eeprom at25640 = {
.byte_len = SZ_64K / 8,
.name = "at25640",
@@ -772,7 +767,7 @@ static __init void dm365_evm_init(void)
MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
.atag_offset = 0x100,
- .map_io = dm365_evm_map_io,
+ .map_io = dm365_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = dm365_evm_init,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index b07c9b1..8f6e9ea 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -725,12 +725,6 @@ static struct platform_device *davinci_evm_devices[] __initdata = {
&rtc_dev,
};
-static void __init
-davinci_evm_map_io(void)
-{
- dm644x_init();
-}
-
static int davinci_phy_fixup(struct phy_device *phydev)
{
unsigned int control;
@@ -815,7 +809,7 @@ static __init void davinci_evm_init(void)
MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
/* Maintainer: MontaVista Software <source@mvista.com> */
.atag_offset = 0x100,
- .map_io = davinci_evm_map_io,
+ .map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = davinci_evm_init,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index cb0a41e..f0e2762 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -716,16 +716,6 @@ static void __init evm_init_i2c(void)
}
#endif
-#define DM6467T_EVM_REF_FREQ 33000000
-
-static void __init davinci_map_io(void)
-{
- dm646x_init();
-
- if (machine_is_davinci_dm6467tevm())
- davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
-}
-
#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
/*
* The following EDMA channels/slots are not being used by drivers (for
@@ -795,7 +785,7 @@ static __init void evm_init(void)
MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
.atag_offset = 0x100,
- .map_io = davinci_map_io,
+ .map_io = dm646x_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = evm_init,
@@ -806,7 +796,7 @@ MACHINE_END
MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
.atag_offset = 0x100,
- .map_io = davinci_map_io,
+ .map_io = dm646x_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = evm_init,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index b73ce7b..9ea2628 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -561,14 +561,9 @@ static int __init mityomapl138_console_init(void)
console_initcall(mityomapl138_console_init);
#endif
-static void __init mityomapl138_map_io(void)
-{
- da850_init();
-}
-
MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
.atag_offset = 0x100,
- .map_io = mityomapl138_map_io,
+ .map_io = da850_map_io,
.init_irq = cp_intc_init,
.init_time = davinci_timer_init,
.init_machine = mityomapl138_init,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 0c02aaa..6f4e7dc 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -154,11 +154,6 @@ static struct platform_device *davinci_ntosd2_devices[] __initdata = {
&ntosd2_leds_dev,
};
-static void __init davinci_ntosd2_map_io(void)
-{
- dm644x_init();
-}
-
static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
.wires = 4,
};
@@ -225,7 +220,7 @@ static __init void davinci_ntosd2_init(void)
MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
/* Maintainer: Neuros Technologies <neuros@groups.google.com> */
.atag_offset = 0x100,
- .map_io = davinci_ntosd2_map_io,
+ .map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = davinci_ntosd2_init,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index a3e7807..0fdb7b7 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -325,14 +325,9 @@ static int __init omapl138_hawk_console_init(void)
console_initcall(omapl138_hawk_console_init);
#endif
-static void __init omapl138_hawk_map_io(void)
-{
- da850_init();
-}
-
MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
.atag_offset = 0x100,
- .map_io = omapl138_hawk_map_io,
+ .map_io = da850_map_io,
.init_irq = cp_intc_init,
.init_time = davinci_timer_init,
.init_machine = omapl138_hawk_init,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index d85accf..3c1059a 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -125,11 +125,6 @@ static struct platform_device *davinci_sffsdr_devices[] __initdata = {
&davinci_sffsdr_nandflash_device,
};
-static void __init davinci_sffsdr_map_io(void)
-{
- dm644x_init();
-}
-
static __init void davinci_sffsdr_init(void)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -148,7 +143,7 @@ static __init void davinci_sffsdr_init(void)
MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
.atag_offset = 0x100,
- .map_io = davinci_sffsdr_map_io,
+ .map_io = dm644x_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = davinci_sffsdr_init,
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index bd88470..2e249f0 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1214,7 +1214,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
.emac_pdata = &da8xx_emac_pdata,
};
-void __init da830_init(void)
+void __init da830_map_io(void)
{
davinci_common_init(&davinci_soc_info_da830);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 07d6f0e..056b148 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1369,7 +1369,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
.sram_len = SZ_128K,
};
-void __init da850_init(void)
+void __init da850_map_io(void)
{
unsigned int v;
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index f06db67..92c7c34 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -95,7 +95,7 @@ static const char *const da850_boards_compat[] __initconst = {
};
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
- .map_io = da850_init,
+ .map_io = da850_map_io,
.init_time = davinci_timer_init,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c62b90c..d550717 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -82,7 +82,7 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata);
int davinci_init_wdt(void);
/* DM355 function declarations */
-void dm355_init(void);
+void dm355_map_io(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable);
@@ -90,7 +90,7 @@ int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
int dm355_gpio_register(void);
/* DM365 function declarations */
-void dm365_init(void);
+void dm365_map_io(void);
void dm365_init_asp(void);
void dm365_init_vc(void);
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -101,13 +101,13 @@ int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
int dm365_gpio_register(void);
/* DM644x function declarations */
-void dm644x_init(void);
+void dm644x_map_io(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
/* DM646x function declarations */
-void dm646x_init(void);
+void dm646x_map_io(void);
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index bd50367..88c3c80 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1039,7 +1039,7 @@ void __init dm355_init_asp1(u32 evt_enable)
platform_device_register(&dm355_asp1_device);
}
-void __init dm355_init(void)
+void __init dm355_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm355);
davinci_map_sysmod();
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 8be04ec..f979180 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1162,7 +1162,7 @@ void __init dm365_init_rtc(void)
platform_device_register(&dm365_rtc_device);
}
-void __init dm365_init(void)
+void __init dm365_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm365);
davinci_map_sysmod();
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index b437c37..80048c0 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -927,7 +927,7 @@ void __init dm644x_init_asp(void)
platform_device_register(&dm644x_asp_device);
}
-void __init dm644x_init(void)
+void __init dm644x_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm644x);
davinci_map_sysmod();
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index da21353..b3be5c8 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -17,6 +17,7 @@
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
@@ -952,11 +953,16 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv)
return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
}
-void __init dm646x_init(void)
+#define DM6467T_EVM_REF_FREQ 33000000
+
+void __init dm646x_map_io(void)
{
davinci_common_init(&davinci_soc_info_dm646x);
davinci_map_sysmod();
davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
}
static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 93ff156..c760c1b 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -86,8 +86,8 @@ extern unsigned int da850_max_speed;
#define DA8XX_SHARED_RAM_BASE 0x80000000
#define DA8XX_ARM_RAM_BASE 0xffff0000
-void da830_init(void);
-void da850_init(void);
+void da830_map_io(void);
+void da850_map_io(void);
int da830_register_edma(struct edma_rsv_info *rsv);
int da850_register_edma(struct edma_rsv_info *rsv[2]);
--
2.7.4
^ permalink raw reply related
* [PATCH v1 0/6] ARM: davinci: convert to common clock framework
From: David Lechner @ 2017-12-02 2:34 UTC (permalink / raw)
To: linux-arm-kernel
This series takes the first steps towards moving mach-davinci to the common
clock framework.
Basically, this series does some cleanup and rearranging to get things
ready for the conversion. Then in "ARM: davinci: convert to common clock
framework" we actually make the conversion. This is done by just creating
a thin layer around the existing mach clock code.
There is certainly more to be done to make full use of the common clock
framework, but this seems like the smallest logical set of patches to get
CONFIG_COMMON_CLK switched on. Otherwise, I think we would end up with a
series of 20+ patches that would be harder to review.
I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
that I haven't broken anything (too badly) in da850. But, I don't have
other hardware to test.
David Lechner (6):
ARM: davinci: clean up map_io functions
ARM: davinci: move davinci_clk_init() to init_time
ARM: davinci: don't use static clk_lookup
ARM: davinci: make davinci_clk_reset() static
ARM: davinci: convert to common clock framework
ARM: davinci: remove clock debugfs
arch/arm/Kconfig | 2 +-
arch/arm/mach-davinci/board-da830-evm.c | 9 +-
arch/arm/mach-davinci/board-da850-evm.c | 9 +-
arch/arm/mach-davinci/board-dm355-evm.c | 9 +-
arch/arm/mach-davinci/board-dm355-leopard.c | 9 +-
arch/arm/mach-davinci/board-dm365-evm.c | 9 +-
arch/arm/mach-davinci/board-dm644x-evm.c | 10 +-
arch/arm/mach-davinci/board-dm646x-evm.c | 18 +-
arch/arm/mach-davinci/board-mityomapl138.c | 9 +-
arch/arm/mach-davinci/board-neuros-osd2.c | 9 +-
arch/arm/mach-davinci/board-omapl138-hawk.c | 9 +-
arch/arm/mach-davinci/board-sffsdr.c | 9 +-
arch/arm/mach-davinci/clock.c | 299 +++++++++-------------------
arch/arm/mach-davinci/clock.h | 48 +++--
arch/arm/mach-davinci/da830.c | 217 ++++++++++----------
arch/arm/mach-davinci/da850.c | 292 +++++++++++++--------------
arch/arm/mach-davinci/da8xx-dt.c | 4 +-
arch/arm/mach-davinci/davinci.h | 12 +-
arch/arm/mach-davinci/devices-da8xx.c | 9 +-
arch/arm/mach-davinci/dm355.c | 184 ++++++++---------
arch/arm/mach-davinci/dm365.c | 242 +++++++++++-----------
arch/arm/mach-davinci/dm644x.c | 164 +++++++--------
arch/arm/mach-davinci/dm646x.c | 180 +++++++++--------
arch/arm/mach-davinci/include/mach/clock.h | 3 -
arch/arm/mach-davinci/include/mach/common.h | 1 -
arch/arm/mach-davinci/include/mach/da8xx.h | 7 +-
arch/arm/mach-davinci/time.c | 1 -
arch/arm/mach-davinci/usb-da8xx.c | 57 +++---
28 files changed, 841 insertions(+), 990 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 0/2] Add devicetree for Axentia Nattis
From: Javier Martinez Canillas @ 2017-12-02 1:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201224425.5477-1-peda@axentia.se>
Hello Peter,
On Fri, Dec 1, 2017 at 11:44 PM, Peter Rosin <peda@axentia.se> wrote:
> Hi!
>
> I'd like to add a devicetree for our Nattis to the kernel. The
> Nattis is a device for showing departures for public transportation
> (optionally including a text-to-speech module for the visually
> impaired).
>
> I'm a bit unsure if the tfa9879 sound codec binding is needed,
> but I suppose it belongs in trivial-devices?
>
There's a DT binding for this device now:
https://patchwork.ozlabs.org/patch/816157/
> Cheers,
> Peter
>
Best regards,
Javier
^ permalink raw reply
* [PATCH 4/4] [v4] pinctrl: qcom: qdf2xxx: add support for new ACPI HID QCOM8002
From: Timur Tabi @ 2017-12-01 23:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512170904-4749-1-git-send-email-timur@codeaurora.org>
Newer versions of the firmware for the Qualcomm Datacenter Technologies
QDF2400 restricts access to a subset of the GPIOs on the TLMM. To
prevent older kernels from accidentally accessing the restricted GPIOs,
we change the ACPI HID for the TLMM block from QCOM8001 to QCOM8002,
and introduce a new property "gpios". This property is an array of
specific GPIOs that are accessible. When an older kernel boots on
newer (restricted) firmware, it will fail to probe.
To implement the sparse GPIO map, we register all of the GPIOs, but set
the pin count for the unavailable GPIOs to zero. The pinctrl-msm
driver will block those unavailable GPIOs from being accessed.
To allow newer kernels to support older firmware, the driver retains
support for QCOM8001.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/pinctrl/qcom/pinctrl-qdf2xxx.c | 149 +++++++++++++++++++++++++--------
1 file changed, 113 insertions(+), 36 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c b/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c
index bb3ce5c3e18b..fa39b0eb329d 100644
--- a/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c
+++ b/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c
@@ -38,68 +38,151 @@
/* maximum size of each gpio name (enough room for "gpioXXX" + null) */
#define NAME_SIZE 8
+enum {
+ QDF2XXX_V1,
+ QDF2XXX_V2,
+};
+
+static const struct acpi_device_id qdf2xxx_acpi_ids[] = {
+ {"QCOM8001", QDF2XXX_V1},
+ {"QCOM8002", QDF2XXX_V2},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, qdf2xxx_acpi_ids);
+
static int qdf2xxx_pinctrl_probe(struct platform_device *pdev)
{
+ const struct acpi_device_id *id =
+ acpi_match_device(qdf2xxx_acpi_ids, &pdev->dev);
struct pinctrl_pin_desc *pins;
struct msm_pingroup *groups;
char (*names)[NAME_SIZE];
unsigned int i;
u32 num_gpios;
+ unsigned int avail_gpios; /* The number of GPIOs we support */
+ u16 *gpios; /* An array of supported GPIOs */
int ret;
/* Query the number of GPIOs from ACPI */
ret = device_property_read_u32(&pdev->dev, "num-gpios", &num_gpios);
if (ret < 0) {
- dev_warn(&pdev->dev, "missing num-gpios property\n");
+ dev_err(&pdev->dev, "missing 'num-gpios' property\n");
return ret;
}
-
if (!num_gpios || num_gpios > MAX_GPIOS) {
- dev_warn(&pdev->dev, "invalid num-gpios property\n");
+ dev_err(&pdev->dev, "invalid 'num-gpios' property\n");
return -ENODEV;
}
+ /*
+ * The QCOM8001 HID contains only the number of GPIOs, and assumes
+ * that all of them are available. avail_gpios is the same as num_gpios.
+ *
+ * The QCOM8002 HID introduces the 'gpios' DSD, which lists
+ * specific GPIOs that the driver is allowed to access.
+ *
+ * The make the common code simpler, in both cases we create an
+ * array of GPIOs that are accessible. So for QCOM8001, that would
+ * be all of the GPIOs.
+ */
+ if (id->driver_data == QDF2XXX_V1) {
+ avail_gpios = num_gpios;
+
+ gpios = devm_kmalloc_array(&pdev->dev, avail_gpios,
+ sizeof(gpios[0]), GFP_KERNEL);
+ if (!gpios)
+ return -ENOMEM;
+
+ for (i = 0; i < avail_gpios; i++)
+ gpios[i] = i;
+ } else {
+ /* The number of GPIOs in the approved list */
+ ret = device_property_read_u16_array(&pdev->dev, "gpios",
+ NULL, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "missing 'gpios' property\n");
+ return ret;
+ }
+ /*
+ * The number of available GPIOs should be non-zero, and no
+ * more than the total number of GPIOS.
+ */
+ if (!ret || ret > num_gpios) {
+ dev_err(&pdev->dev, "invalid 'gpios' property\n");
+ return -ENODEV;
+ }
+ avail_gpios = ret;
+
+ gpios = devm_kmalloc_array(&pdev->dev, avail_gpios,
+ sizeof(gpios[0]), GFP_KERNEL);
+ if (!gpios)
+ return -ENOMEM;
+
+ ret = device_property_read_u16_array(&pdev->dev, "gpios", gpios,
+ avail_gpios);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not read list of GPIOs\n");
+ return ret;
+ }
+
+ /*
+ * Because we have a specific list of GPIOs, the GPIO map
+ * is 'sparse'.
+ */
+ qdf2xxx_pinctrl.sparse = true;
+ }
+
pins = devm_kcalloc(&pdev->dev, num_gpios,
sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
groups = devm_kcalloc(&pdev->dev, num_gpios,
sizeof(struct msm_pingroup), GFP_KERNEL);
- names = devm_kcalloc(&pdev->dev, num_gpios, NAME_SIZE, GFP_KERNEL);
+ names = devm_kcalloc(&pdev->dev, avail_gpios, NAME_SIZE, GFP_KERNEL);
if (!pins || !groups || !names)
return -ENOMEM;
+ /*
+ * Initialize the array. GPIOs not listed in the 'gpios' array
+ * still need a number, but nothing else.
+ */
for (i = 0; i < num_gpios; i++) {
- snprintf(names[i], NAME_SIZE, "gpio%u", i);
-
pins[i].number = i;
- pins[i].name = names[i];
-
- groups[i].npins = 1;
- groups[i].name = names[i];
groups[i].pins = &pins[i].number;
+ }
- groups[i].ctl_reg = 0x10000 * i;
- groups[i].io_reg = 0x04 + 0x10000 * i;
- groups[i].intr_cfg_reg = 0x08 + 0x10000 * i;
- groups[i].intr_status_reg = 0x0c + 0x10000 * i;
- groups[i].intr_target_reg = 0x08 + 0x10000 * i;
-
- groups[i].mux_bit = 2;
- groups[i].pull_bit = 0;
- groups[i].drv_bit = 6;
- groups[i].oe_bit = 9;
- groups[i].in_bit = 0;
- groups[i].out_bit = 1;
- groups[i].intr_enable_bit = 0;
- groups[i].intr_status_bit = 0;
- groups[i].intr_target_bit = 5;
- groups[i].intr_target_kpss_val = 1;
- groups[i].intr_raw_status_bit = 4;
- groups[i].intr_polarity_bit = 1;
- groups[i].intr_detection_bit = 2;
- groups[i].intr_detection_width = 2;
+ /* Populate the entries that are meant to be exposes as GPIOs. */
+ for (i = 0; i < avail_gpios; i++) {
+ unsigned int gpio = gpios[i];
+
+ groups[gpio].npins = 1;
+ snprintf(names[i], NAME_SIZE, "gpio%u", gpio);
+ pins[gpio].name = names[i];
+ groups[gpio].name = names[i];
+
+ groups[gpio].ctl_reg = 0x10000 * gpio;
+ groups[gpio].io_reg = 0x04 + 0x10000 * gpio;
+ groups[gpio].intr_cfg_reg = 0x08 + 0x10000 * gpio;
+ groups[gpio].intr_status_reg = 0x0c + 0x10000 * gpio;
+ groups[gpio].intr_target_reg = 0x08 + 0x10000 * gpio;
+
+ groups[gpio].mux_bit = 2;
+ groups[gpio].pull_bit = 0;
+ groups[gpio].drv_bit = 6;
+ groups[gpio].oe_bit = 9;
+ groups[gpio].in_bit = 0;
+ groups[gpio].out_bit = 1;
+ groups[gpio].intr_enable_bit = 0;
+ groups[gpio].intr_status_bit = 0;
+ groups[gpio].intr_target_bit = 5;
+ groups[gpio].intr_target_kpss_val = 1;
+ groups[gpio].intr_raw_status_bit = 4;
+ groups[gpio].intr_polarity_bit = 1;
+ groups[gpio].intr_detection_bit = 2;
+ groups[gpio].intr_detection_width = 2;
}
+ devm_kfree(&pdev->dev, gpios);
+
qdf2xxx_pinctrl.pins = pins;
qdf2xxx_pinctrl.groups = groups;
qdf2xxx_pinctrl.npins = num_gpios;
@@ -109,12 +192,6 @@ static int qdf2xxx_pinctrl_probe(struct platform_device *pdev)
return msm_pinctrl_probe(pdev, &qdf2xxx_pinctrl);
}
-static const struct acpi_device_id qdf2xxx_acpi_ids[] = {
- {"QCOM8001"},
- {},
-};
-MODULE_DEVICE_TABLE(acpi, qdf2xxx_acpi_ids);
-
static struct platform_driver qdf2xxx_pinctrl_driver = {
.driver = {
.name = "qdf2xxx-pinctrl",
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 3/4] [v7] pinctrl: qcom: disable GPIO groups with no pins
From: Timur Tabi @ 2017-12-01 23:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512170904-4749-1-git-send-email-timur@codeaurora.org>
pinctrl-msm only accepts an array of GPIOs from 0 to n-1, and it expects
each group to support have only one pin (npins == 1).
We can support "sparse" GPIO maps if we allow for some groups to have zero
pins (npins == 0). These pins are "hidden" from the rest of the driver
and gpiolib.
A new boolean 'sparse' indicates whether the GPIO map is sparse. If any
GPIO has an 'npins' value of 0, then 'sparse' must be set to True.
Access to unavailable GPIOs is blocked by in gpiod_get_index(), which
checks whether the gpio is available before requesting it.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/pinctrl/qcom/pinctrl-msm.c | 44 ++++++++++++++++++++++++++++++++------
drivers/pinctrl/qcom/pinctrl-msm.h | 2 ++
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 7a960590ecaa..2f578a9eb571 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -507,6 +507,11 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
};
g = &pctrl->soc->groups[offset];
+
+ /* If the GPIO group has no pins, then don't show it. */
+ if (!g->npins)
+ return;
+
ctl_reg = readl(pctrl->regs + g->ctl_reg);
is_out = !!(ctl_reg & BIT(g->oe_bit));
@@ -516,7 +521,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
seq_printf(s, " %dmA", msm_regval_to_drive(drive));
- seq_printf(s, " %s", pulls[pull]);
+ seq_printf(s, " %s\n", pulls[pull]);
}
static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@@ -524,23 +529,36 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
unsigned gpio = chip->base;
unsigned i;
- for (i = 0; i < chip->ngpio; i++, gpio++) {
+ for (i = 0; i < chip->ngpio; i++, gpio++)
msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
- seq_puts(s, "\n");
- }
}
#else
#define msm_gpio_dbg_show NULL
#endif
+/*
+ * If the requested GPIO has no pins, then treat it as unavailable.
+ * Otherwise, call the standard request function.
+ */
+static int msm_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+ struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
+ const struct msm_pingroup *g = &pctrl->soc->groups[offset];
+
+ if (!g->npins)
+ return -ENODEV;
+
+ return gpiochip_generic_request(chip, offset);
+}
+
static const struct gpio_chip msm_gpio_template = {
.direction_input = msm_gpio_direction_input,
.direction_output = msm_gpio_direction_output,
.get_direction = msm_gpio_get_direction,
.get = msm_gpio_get,
.set = msm_gpio_set,
- .request = gpiochip_generic_request,
+ .request = msm_gpio_request,
.free = gpiochip_generic_free,
.dbg_show = msm_gpio_dbg_show,
};
@@ -813,6 +831,8 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
struct gpio_chip *chip;
int ret;
unsigned ngpio = pctrl->soc->ngpios;
+ const struct msm_pingroup *groups = pctrl->soc->groups;
+ unsigned int i;
if (WARN_ON(ngpio > MAX_NR_GPIO))
return -EINVAL;
@@ -825,13 +845,25 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
chip->owner = THIS_MODULE;
chip->of_node = pctrl->dev->of_node;
+ /* If the GPIO map is sparse, then we need to disable specific IRQs */
+ if (pctrl->soc->sparse)
+ chip->need_valid_mask = true;
+
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {
dev_err(pctrl->dev, "Failed register gpiochip\n");
return ret;
}
- ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
+ if (chip->need_valid_mask) {
+ for (i = 0; i < ngpio; i++)
+ if (!groups[i].npins)
+ clear_bit(i, pctrl->chip.valid_mask);
+ }
+
+ ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
+ 0, 0, ngpio);
+
if (ret) {
dev_err(pctrl->dev, "Failed to add pin range\n");
gpiochip_remove(&pctrl->chip);
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
index 9b9feea540ff..70762bcb84cb 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.h
+++ b/drivers/pinctrl/qcom/pinctrl-msm.h
@@ -107,6 +107,7 @@ struct msm_pingroup {
* @ngroups: The numbmer of entries in @groups.
* @ngpio: The number of pingroups the driver should expose as GPIOs.
* @pull_no_keeper: The SoC does not support keeper bias.
+ * @sparse: The GPIO map is sparse (some GPIOs have npins == 0)
*/
struct msm_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
@@ -117,6 +118,7 @@ struct msm_pinctrl_soc_data {
unsigned ngroups;
unsigned ngpios;
bool pull_no_keeper;
+ bool sparse;
};
int msm_pinctrl_probe(struct platform_device *pdev,
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 2/4] [v2] gpiolib: add bitmask for valid GPIO lines
From: Timur Tabi @ 2017-12-01 23:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512170904-4749-1-git-send-email-timur@codeaurora.org>
Add support for specifying that some GPIOs within a range are unavailable.
Some systems have a sparse list of GPIOs, where a range of GPIOs is
specified (usually 0 to n-1), but some subset within that range is
absent or unavailable for whatever reason.
To support this, allow drivers to specify a bitmask of GPIOs that
are present or absent. Gpiolib will then block access to those that
are absent.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/gpio/gpiolib.c | 47 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/gpio/driver.h | 3 +++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 168dd831551d..2c71e8db95a3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -191,6 +191,28 @@ static int gpiochip_find_base(int ngpio)
}
}
+static int gpiochip_init_valid_mask(struct gpio_chip *chip)
+{
+ if (!chip->need_valid_mask)
+ return 0;
+
+ chip->valid_mask = kmalloc_array(BITS_TO_LONGS(chip->ngpio),
+ sizeof(long), GFP_KERNEL);
+ if (!chip->valid_mask)
+ return -ENOMEM;
+
+ /* Assume by default all GPIOs are valid */
+ bitmap_fill(chip->valid_mask, chip->ngpio);
+
+ return 0;
+}
+
+static void gpiochip_remove_valid_mask(struct gpio_chip *chip)
+{
+ kfree(chip->valid_mask);
+ chip->valid_mask = NULL;
+}
+
/**
* gpiod_get_direction - return the current direction of a GPIO
* @desc: GPIO to get the direction of
@@ -1225,10 +1247,14 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
if (status)
goto err_remove_from_list;
- status = gpiochip_irqchip_init_valid_mask(chip);
+ status = gpiochip_init_valid_mask(chip);
if (status)
goto err_remove_from_list;
+ status = gpiochip_irqchip_init_valid_mask(chip);
+ if (status)
+ goto err_remove_valid_mask;
+
status = gpiochip_add_irqchip(chip, key);
if (status)
goto err_remove_chip;
@@ -1259,6 +1285,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
gpiochip_free_hogs(chip);
of_gpiochip_remove(chip);
gpiochip_irqchip_free_valid_mask(chip);
+err_remove_valid_mask:
+ gpiochip_remove_valid_mask(chip);
err_remove_from_list:
spin_lock_irqsave(&gpio_lock, flags);
list_del(&gdev->list);
@@ -1311,6 +1339,7 @@ void gpiochip_remove(struct gpio_chip *chip)
/* Numb the device, cancelling all outstanding operations */
gdev->chip = NULL;
gpiochip_irqchip_remove(chip);
+ gpiochip_remove_valid_mask(chip);
acpi_gpiochip_remove(chip);
gpiochip_remove_pin_ranges(chip);
of_gpiochip_remove(chip);
@@ -1500,6 +1529,18 @@ static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
return test_bit(offset, gpiochip->irq.valid_mask);
}
+static bool gpiochip_available(const struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ pr_info("%s:%u offset=%u\n", __func__, __LINE__, offset);
+
+ /* No mask means all valid */
+ if (likely(!gpiochip->valid_mask))
+ return true;
+
+ return test_bit(offset, gpiochip->valid_mask);
+}
+
/**
* gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip
* @gpiochip: the gpiochip to set the irqchip chain to
@@ -3597,6 +3638,10 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
return desc;
}
+ /* Check if the GPIO line itself is valid */
+ if (!gpiochip_available(desc->gdev->chip, idx))
+ return ERR_PTR(-EACCES);
+
status = gpiod_request(desc, con_id);
if (status < 0)
return ERR_PTR(status);
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 55e672592fa9..b68450caf554 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -316,6 +316,9 @@ struct gpio_chip {
int (*of_xlate)(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags);
#endif
+
+ bool need_valid_mask;
+ unsigned long *valid_mask;
};
extern const char *gpiochip_is_requested(struct gpio_chip *chip,
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 1/4] [v2] Revert "gpio: set up initial state from .get_direction()"
From: Timur Tabi @ 2017-12-01 23:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512170904-4749-1-git-send-email-timur@codeaurora.org>
This reverts commit 72d3200061776264941be1b5a9bb8e926b3b30a5.
We cannot blindly query the direction of all GPIOs when the pins are
first registered. The get_direction callback normally triggers a
read/write to hardware, but we shouldn't be touching the hardware for
an individual GPIO until after it's been properly claimed.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/gpio/gpiolib.c | 31 +++++++------------------------
1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 641a5eb552cb..168dd831551d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1207,31 +1207,14 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
struct gpio_desc *desc = &gdev->descs[i];
desc->gdev = gdev;
- /*
- * REVISIT: most hardware initializes GPIOs as inputs
- * (often with pullups enabled) so power usage is
- * minimized. Linux code should set the gpio direction
- * first thing; but until it does, and in case
- * chip->get_direction is not set, we may expose the
- * wrong direction in sysfs.
- */
-
- if (chip->get_direction) {
- /*
- * If we have .get_direction, set up the initial
- * direction flag from the hardware.
- */
- int dir = chip->get_direction(chip, i);
- if (!dir)
- set_bit(FLAG_IS_OUT, &desc->flags);
- } else if (!chip->direction_input) {
- /*
- * If the chip lacks the .direction_input callback
- * we logically assume all lines are outputs.
- */
- set_bit(FLAG_IS_OUT, &desc->flags);
- }
+ /* REVISIT: most hardware initializes GPIOs as inputs (often
+ * with pullups enabled) so power usage is minimized. Linux
+ * code should set the gpio direction first thing; but until
+ * it does, and in case chip->get_direction is not set, we may
+ * expose the wrong direction in sysfs.
+ */
+ desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0;
}
#ifdef CONFIG_PINCTRL
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 0/4] [v8] pinctrl: qcom: add support for sparse GPIOs
From: Timur Tabi @ 2017-12-01 23:28 UTC (permalink / raw)
To: linux-arm-kernel
A series of patches that add support for GPIO maps that have holes in
them. That is, even though a client driver has N consecutive GPIOs,
some are just unavailable for whatever reason, and the hardware should
not be accessed for those GPIOs.
Note that this version does not address the failure of gpiod_get()
when GPIO 0 is not available. I don't know how to fix that because I
don't understand what gpiod_get() is trying to do.
Also note that I would prefer to have the call to gpiochip_available()
be inside gpiod_request(), but I don't know how to get the GPIO index
inside that function (without adding a function a parameter).
In other words, there will be a v9, but I need help.
v8:
rebased onto 4.15-rc1
fix issues raised during review of v7
Timur Tabi (4):
[v2] Revert "gpio: set up initial state from .get_direction()"
[v2] gpiolib: add bitmask for valid GPIO lines
[v7] pinctrl: qcom: disable GPIO groups with no pins
[v4] pinctrl: qcom: qdf2xxx: add support for new ACPI HID QCOM8002
drivers/gpio/gpiolib.c | 80 ++++++++++++------
drivers/pinctrl/qcom/pinctrl-msm.c | 44 ++++++++--
drivers/pinctrl/qcom/pinctrl-msm.h | 2 +
drivers/pinctrl/qcom/pinctrl-qdf2xxx.c | 145 +++++++++++++++++++++++++--------
include/linux/gpio/driver.h | 3 +
5 files changed, 207 insertions(+), 67 deletions(-)
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v4.14] Add support for bq27521 battery monitor
From: Pavel Machek @ 2017-12-01 23:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171110103937.GA29900@amd>
Hi!
> This adds basic support for BQ27521 battery monitor, used in Nokia N9
> and N950. In particular, battery voltage is important to be able to
> tell when the battery is almost empty. Emptying battery on N950 is
> pretty painful, as flasher needs to be used to recover phone in such
> case.
Sebastian, ping? This one should not be too controversial.
If you could also apply the "shut down when battery is low", that
would be nice.
Thanks,
Pavel
> Signed-off-by: Pavel Machek <pavel@ucw.cz>
>
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 51f0961..f684288 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c
> @@ -323,6 +323,30 @@ static u8
> [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
> BQ27XXX_DM_REG_ROWS,
> },
> + bq27521_regs[BQ27XXX_REG_MAX] = {
> + [BQ27XXX_REG_CTRL] = 0x02,
> + [BQ27XXX_REG_TEMP] = 0x0a,
> + [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_VOLT] = 0x0c,
> + [BQ27XXX_REG_AI] = 0x0e,
> + [BQ27XXX_REG_FLAGS] = 0x08,
> + [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_FCC] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_SOC] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
> + [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
> + [BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,
> + [BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,
> + [BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,
> + [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
> + [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
> + },
> bq27530_regs[BQ27XXX_REG_MAX] = {
> [BQ27XXX_REG_CTRL] = 0x00,
> [BQ27XXX_REG_TEMP] = 0x06,
> @@ -557,6 +581,15 @@ static enum power_supply_property bq27520g4_props[] = {
> POWER_SUPPLY_PROP_MANUFACTURER,
> };
>
> +static enum power_supply_property bq27521_props[] = {
> + POWER_SUPPLY_PROP_STATUS,
> + POWER_SUPPLY_PROP_PRESENT,
> + POWER_SUPPLY_PROP_VOLTAGE_NOW,
> + POWER_SUPPLY_PROP_CURRENT_NOW,
> + POWER_SUPPLY_PROP_TEMP,
> + POWER_SUPPLY_PROP_TECHNOLOGY,
> +};
> +
> static enum power_supply_property bq27530_props[] = {
> POWER_SUPPLY_PROP_STATUS,
> POWER_SUPPLY_PROP_PRESENT,
> @@ -671,6 +704,7 @@ static struct bq27xxx_dm_reg bq27500_dm_regs[] = {
> #define bq27520g2_dm_regs 0
> #define bq27520g3_dm_regs 0
> #define bq27520g4_dm_regs 0
> +#define bq27521_dm_regs 0
> #define bq27530_dm_regs 0
> #define bq27531_dm_regs 0
> #define bq27541_dm_regs 0
> @@ -717,8 +751,8 @@ static struct bq27xxx_dm_reg bq27621_dm_regs[] = {
> #endif
>
> #define BQ27XXX_O_ZERO 0x00000001
> -#define BQ27XXX_O_OTDC 0x00000002
> -#define BQ27XXX_O_UTOT 0x00000004
> +#define BQ27XXX_O_OTDC 0x00000002 /* has OTC/OTD overtemperature flags */
> +#define BQ27XXX_O_UTOT 0x00000004 /* has OT overtemperature flag */
> #define BQ27XXX_O_CFGUP 0x00000008
> #define BQ27XXX_O_RAM 0x00000010
>
> @@ -751,6 +785,7 @@ static struct {
> [BQ27520G2] = BQ27XXX_DATA(bq27520g2, 0 , BQ27XXX_O_OTDC),
> [BQ27520G3] = BQ27XXX_DATA(bq27520g3, 0 , BQ27XXX_O_OTDC),
> [BQ27520G4] = BQ27XXX_DATA(bq27520g4, 0 , BQ27XXX_O_OTDC),
> + [BQ27521] = BQ27XXX_DATA(bq27521, 0 , 0),
> [BQ27530] = BQ27XXX_DATA(bq27530, 0 , BQ27XXX_O_UTOT),
> [BQ27531] = BQ27XXX_DATA(bq27531, 0 , BQ27XXX_O_UTOT),
> [BQ27541] = BQ27XXX_DATA(bq27541, 0 , BQ27XXX_O_OTDC),
> diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
> index 0b11ed4..6b25e5f 100644
> --- a/drivers/power/supply/bq27xxx_battery_i2c.c
> +++ b/drivers/power/supply/bq27xxx_battery_i2c.c
> @@ -239,6 +239,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
> { "bq27520g2", BQ27520G2 },
> { "bq27520g3", BQ27520G3 },
> { "bq27520g4", BQ27520G4 },
> + { "bq27521", BQ27521 },
> { "bq27530", BQ27530 },
> { "bq27531", BQ27531 },
> { "bq27541", BQ27541 },
> @@ -269,6 +270,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
> { .compatible = "ti,bq27520g2" },
> { .compatible = "ti,bq27520g3" },
> { .compatible = "ti,bq27520g4" },
> + { .compatible = "ti,bq27521" },
> { .compatible = "ti,bq27530" },
> { .compatible = "ti,bq27531" },
> { .compatible = "ti,bq27541" },
> diff --git a/include/linux/mfd/twl.h b/include/linux/mfd/twl.h
> index 9ad7828..6547d30 100644
> --- a/include/linux/mfd/twl.h
> +++ b/include/linux/mfd/twl.h
> @@ -70,6 +70,7 @@ enum twl4030_module_ids {
> TWL4030_MODULE_INT,
>
> TWL5031_MODULE_ACCESSORY,
> + TWL5031_MODULE_BCC,
> TWL5031_MODULE_INTERRUPTS,
>
> TWL4030_MODULE_LAST,
> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
> index 43194e0..d8d127a 100644
> --- a/include/linux/power/bq27xxx_battery.h
> +++ b/include/linux/power/bq27xxx_battery.h
> @@ -15,6 +15,7 @@ enum bq27xxx_chip {
> BQ27520G2, /* bq27520G2 */
> BQ27520G3, /* bq27520G3 */
> BQ27520G4, /* bq27520G4 */
> + BQ27521, /* bq27521 */
> BQ27530, /* bq27530, bq27531 */
> BQ27531,
> BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171202/fec600f6/attachment.sig>
^ permalink raw reply
* [PATCH] ARM: dts: sun8i: h3: enable USB OTG for NanoPi Neo board
From: Krzysztof Adamski @ 2017-12-01 22:49 UTC (permalink / raw)
To: linux-arm-kernel
Similarly to Orange Pi Zero, NanoPi Neo board has an USB OTG port with
an ID pin but with unpowered VBUS. This patch enables this port in
forced peripheral mode.
Signed-off-by: Krzysztof Adamski <k@japko.eu>
---
arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
index 78f6c24952dd..14c3f137dbd3 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
@@ -53,3 +53,20 @@
allwinner,leds-active-low;
status = "okay";
};
+
+&usb_otg {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
--
2.13.6
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: at91: add devicetree for the Axentia Nattis with Natte power
From: Peter Rosin @ 2017-12-01 22:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201224425.5477-1-peda@axentia.se>
The Axentia Nattis is a device designed for presenting departures for
public transport systems. The Natte helper board provides power and
features a battery of battery chargers.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
Documentation/devicetree/bindings/arm/axentia.txt | 9 +
MAINTAINERS | 2 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/at91-natte.dtsi | 245 ++++++++++++++++++++
arch/arm/boot/dts/at91-nattis-2-natte-2.dts | 258 ++++++++++++++++++++++
5 files changed, 515 insertions(+)
create mode 100644 arch/arm/boot/dts/at91-natte.dtsi
create mode 100644 arch/arm/boot/dts/at91-nattis-2-natte-2.dts
diff --git a/Documentation/devicetree/bindings/arm/axentia.txt b/Documentation/devicetree/bindings/arm/axentia.txt
index ea3fb96ae465..de58f2463880 100644
--- a/Documentation/devicetree/bindings/arm/axentia.txt
+++ b/Documentation/devicetree/bindings/arm/axentia.txt
@@ -10,6 +10,15 @@ compatible = "axentia,linea",
and following the rules from atmel-at91.txt for a sama5d31 SoC.
+Nattis v2 board with Natte v2 power board
+-----------------------------------------
+
+Required root node properties:
+compatible = "axentia,nattis-2", "axentia,natte-2", "axentia,linea",
+ "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+and following the rules from above for the axentia,linea CPU module.
+
+
TSE-850 v3 board
----------------
diff --git a/MAINTAINERS b/MAINTAINERS
index 2811a211632c..303d04502b8f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2488,6 +2488,8 @@ L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/arm/axentia.txt
F: arch/arm/boot/dts/at91-linea.dtsi
+F: arch/arm/boot/dts/at91-natte.dtsi
+F: arch/arm/boot/dts/at91-nattis-2-natte-2.dts
F: arch/arm/boot/dts/at91-tse850-3.dts
AXENTIA ASOC DRIVERS
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index eff87a344566..0c10d89adbc8 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -47,6 +47,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
at91sam9x35ek.dtb
dtb-$(CONFIG_SOC_SAM_V7) += \
at91-kizbox2.dtb \
+ at91-nattis-2-natte-2.dtb \
at91-sama5d27_som1_ek.dtb \
at91-sama5d2_xplained.dtb \
at91-sama5d3_xplained.dtb \
diff --git a/arch/arm/boot/dts/at91-natte.dtsi b/arch/arm/boot/dts/at91-natte.dtsi
new file mode 100644
index 000000000000..53b7bb9098f4
--- /dev/null
+++ b/arch/arm/boot/dts/at91-natte.dtsi
@@ -0,0 +1,245 @@
+/*
+ * at91-natte.dts - Device Tree include file for the Natte board
+ *
+ * Copyright (C) 2017 Axentia Technologies AB
+ *
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-control-cells = <0>;
+
+ mux-gpios = <&ioexp 0 GPIO_ACTIVE_HIGH>,
+ <&ioexp 1 GPIO_ACTIVE_HIGH>,
+ <&ioexp 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ batntc-mux {
+ compatible = "io-channel-mux";
+ io-channels = <&adc 5>;
+ io-channel-names = "parent";
+ mux-controls = <&mux>;
+
+ channels =
+ "batntc0", "batntc1", "batntc2", "batntc3",
+ "batntc4", "batntc5", "batntc6", "batntc7";
+ };
+
+ batv-mux {
+ compatible = "io-channel-mux";
+ io-channels = <&adc 6>;
+ io-channel-names = "parent";
+ mux-controls = <&mux>;
+
+ channels =
+ "batv0", "batv1", "batv2", "batv3",
+ "batv4", "batv5", "batv6", "batv7";
+ };
+
+ iout-mux {
+ compatible = "io-channel-mux";
+ io-channels = <&adc 7>;
+ io-channel-names = "parent";
+ mux-controls = <&mux>;
+
+ channels =
+ "iout0", "iout1", "iout2", "iout3",
+ "iout4", "iout5", "iout6", "iout7";
+ };
+
+ i2c-mux {
+ compatible = "i2c-mux";
+ mux-locked;
+ i2c-parent = <&i2c0>;
+ mux-controls = <&mux>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c at 0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+
+ i2c at 7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bq24735-charger at 9 {
+ compatible = "ti,bq24735";
+ reg = <0x9>;
+
+ ti,charge-current = <2000>;
+ ti,charge-voltage = <16800>;
+
+ poll-interval = <20000>;
+ };
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ ioexp: sx1502q at 20 {
+ #gpio-cells = <2>;
+ compatible = "semtech,sx1502q";
+ reg = <0x20>;
+
+ gpio-controller;
+ ngpios = <8>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio3_cfg_pins>;
+
+ gpio3_cfg_pins: gpio3_cfg {
+ pins = "gpio3";
+ bias-pull-up;
+ };
+ };
+
+ adc: ads1015 at 48 {
+ compatible = "ti,ads1015";
+ reg = <0x48>;
+ #io-channel-cells = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel at 4 {
+ reg = <4>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ channel at 5 {
+ reg = <5>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ channel at 6 {
+ reg = <6>;
+ ti,gain = <1>;
+ ti,datarate = <4>;
+ };
+
+ channel at 7 {
+ reg = <7>;
+ ti,gain = <3>;
+ ti,datarate = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91-nattis-2-natte-2.dts b/arch/arm/boot/dts/at91-nattis-2-natte-2.dts
new file mode 100644
index 000000000000..c7224cbb50b4
--- /dev/null
+++ b/arch/arm/boot/dts/at91-nattis-2-natte-2.dts
@@ -0,0 +1,258 @@
+/*
+ * at91-nattis-2-natte-2.dts - Device Tree file for the Linea/Nattis board
+ *
+ * Copyright (C) 2017 Axentia Technologies AB
+ *
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91-linea.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "at91-natte.dtsi"
+
+/ {
+ model = "Axentia Linea-Nattis v2 Natte v2";
+ compatible = "axentia,nattis-2", "axentia,natte-2", "axentia,linea",
+ "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ pinctrl at fffff200 {
+ nattis {
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOD 28
+ AT91_PERIPH_GPIO
+ AT91_PINCTRL_DEGLITCH>;
+ };
+
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOD 5
+ AT91_PERIPH_GPIO
+ AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_lcd_prlud0: lcd_prlud0 {
+ atmel,pins =
+ <AT91_PIOA 21
+ AT91_PERIPH_GPIO
+ AT91_PINCTRL_OUTPUT_VAL(0)>;
+ };
+
+ pinctrl_lcd_hipow0: lcd_hipow0 {
+ atmel,pins =
+ <AT91_PIOA 23
+ AT91_PERIPH_GPIO
+ AT91_PINCTRL_OUTPUT_VAL(0)>;
+ };
+ };
+ };
+
+ watchdog at fffffe40 {
+ status = "okay";
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ wakeup {
+ label = "Wakeup";
+ linux,code = <10>;
+ gpio-key,wakeup;
+ gpios = <&pioB 27 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ panel_reg: panel-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "panel-VCC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ bl_reg: backlight-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "panel-VDD";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ panel_bl: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&hlcdc_pwm 0 100000 0>;
+
+ brightness-levels = < 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32 33 34 35 36 37 38 39
+ 40 41 42 43 44 45 46 47 48 49
+ 50 51 52 53 54 55 56 57 58 59
+ 60 61 62 63 64 65 66 67 68 69
+ 70 71 72 73 74 75 76 77 78 79
+ 80 81 82 83 84 85 86 87 88 89
+ 90 91 92 93 94 95 96 97 98 99
+ 100>;
+ default-brightness-level = <40>;
+
+ power-supply = <&bl_reg>;
+ enable-gpios = <&pioA 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ panel: panel {
+ compatible = "sharp,lq150x1lg11";
+ backlight = <&panel_bl>;
+ power-supply = <&panel_reg>;
+
+ port {
+ panel_input: endpoint {
+ remote-endpoint = <&hlcdc_panel_output>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,name = "nattis-tfa9879";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&cpu_dai>;
+ simple-audio-card,frame-master = <&cpu_dai>;
+ simple-audio-card,widgets = "Line", "Line Out Jack";
+ simple-audio-card,routing = "Line Out Jack", "LINEOUT";
+
+ cpu_dai: simple-audio-card,cpu {
+ sound-dai = <&ssc0>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&codec>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ clock-frequency = <100000>;
+
+ temp at 18 {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x18>;
+ smbus-timeout-disable;
+ };
+
+ eeprom at 50 {
+ compatible = "nxp,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ codec: codec at 6c {
+ compatible = "nxp,tfa9879";
+ reg = <0x6c>;
+ };
+};
+
+&ssc0 {
+ status = "okay";
+
+ atmel,clk-from-rk-pin;
+ #sound-dai-cells = <0>;
+};
+
+&hlcdc {
+ status = "okay";
+
+ hlcdc-display-controller {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_base
+ &pinctrl_lcd_rgb565
+ &pinctrl_lcd_prlud0
+ &pinctrl_lcd_hipow0>;
+
+ port at 0 {
+ hlcdc_panel_output: endpoint {
+ remote-endpoint = <&panel_input>;
+ };
+ };
+ };
+};
+
+&mmc0 {
+ status = "okay";
+
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0
+ &pinctrl_mmc0_dat1_3
+ &pinctrl_mmc0_cd>;
+
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&usart0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
+ atmel,use-dma-rx;
+};
+
+&nand {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ at91bootstrap at 0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader at 40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv at c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb at 180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel at 200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs at 800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+};
+
+&dbgu {
+ status = "okay";
+
+ atmel,use-dma-rx;
+};
+
+&usb0 {
+ status = "okay";
+
+ atmel,vbus-gpio = <&pioD 28 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+};
--
2.11.0
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: trivial: add tfa9879 device
From: Peter Rosin @ 2017-12-01 22:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201224425.5477-1-peda@axentia.se>
Add record for NXP TFA9879 Mono BTL Class D audio amplifier.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
Documentation/devicetree/bindings/trivial-devices.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
index af284fbd4d23..4cf30ce4e71f 100644
--- a/Documentation/devicetree/bindings/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/trivial-devices.txt
@@ -157,6 +157,7 @@ nxp,pcf2127 Real-time clock
nxp,pcf2129 Real-time clock
nxp,pcf8563 Real-time clock/calendar
nxp,pcf85063 Tiny Real-Time Clock
+nxp,tfa9879 Mono BTL Class D audio amplifier
oki,ml86v7667 OKI ML86V7667 video decoder
ovti,ov5642 OV5642: Color CMOS QSXGA (5-megapixel) Image Sensor with OmniBSI and Embedded TrueFocus
pericom,pt7c4338 Real-time Clock Module
--
2.11.0
^ permalink raw reply related
* [PATCH 0/2] Add devicetree for Axentia Nattis
From: Peter Rosin @ 2017-12-01 22:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi!
I'd like to add a devicetree for our Nattis to the kernel. The
Nattis is a device for showing departures for public transportation
(optionally including a text-to-speech module for the visually
impaired).
I'm a bit unsure if the tfa9879 sound codec binding is needed,
but I suppose it belongs in trivial-devices?
Cheers,
Peter
Peter Rosin (2):
dt-bindings: trivial: add tfa9879 device
ARM: dts: at91: add devicetree for the Axentia Nattis with Natte power
Documentation/devicetree/bindings/arm/axentia.txt | 9 +
.../devicetree/bindings/trivial-devices.txt | 1 +
MAINTAINERS | 2 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/at91-natte.dtsi | 245 +++++++++++++++++++
arch/arm/boot/dts/at91-nattis-2-natte-2.dts | 258 +++++++++++++++++++++
6 files changed, 516 insertions(+)
create mode 100644 arch/arm/boot/dts/at91-natte.dtsi
create mode 100644 arch/arm/boot/dts/at91-nattis-2-natte-2.dts
--
2.11.0
^ permalink raw reply
* [PATCH v5 9/9] ACPI: Add PPTT to injectable table list
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Add ACPI_SIG_PPTT to the table so initrd's can override the
system topology.
Signed-off-by: Geoffrey Blake <geoffrey.blake@arm.com>
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
drivers/acpi/tables.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 80ce2a7d224b..6d254450115b 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -456,7 +456,8 @@ static const char * const table_sigs[] = {
ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
- ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
+ ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_PPTT,
+ NULL };
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
--
2.13.5
^ permalink raw reply related
* [PATCH v5 8/9] arm64: topology: Enable ACPI/PPTT based CPU topology.
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Propagate the topology information from the PPTT tree to the
cpu_topology array. We can get the thread id, core_id and
cluster_id by assuming certain levels of the PPTT tree correspond
to those concepts. The package_id is flagged in the tree and can be
found by calling find_acpi_cpu_topology_package() which terminates
its search when it finds an ACPI node flagged as the physical
package. If the tree doesn't contain enough levels to represent
all of the requested levels then the root node will be returned
for all subsequent levels.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
arch/arm64/kernel/topology.c | 47 +++++++++++++++++++++++++++++++++++++++++++-
include/linux/topology.h | 2 ++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 74a8a5173a35..198714aca9e8 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -11,6 +11,7 @@
* for more details.
*/
+#include <linux/acpi.h>
#include <linux/arch_topology.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
@@ -22,6 +23,7 @@
#include <linux/sched.h>
#include <linux/sched/topology.h>
#include <linux/slab.h>
+#include <linux/smp.h>
#include <linux/string.h>
#include <asm/cpu.h>
@@ -300,6 +302,47 @@ static void __init reset_cpu_topology(void)
}
}
+#ifdef CONFIG_ACPI
+/*
+ * Propagate the topology information of the processor_topology_node tree to the
+ * cpu_topology array.
+ */
+static int __init parse_acpi_topology(void)
+{
+ u64 is_threaded;
+ int cpu;
+ int topology_id;
+
+ is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
+
+ for_each_possible_cpu(cpu) {
+ topology_id = find_acpi_cpu_topology(cpu, 0);
+ if (topology_id < 0)
+ return topology_id;
+
+ if (is_threaded) {
+ cpu_topology[cpu].thread_id = topology_id;
+ topology_id = find_acpi_cpu_topology(cpu, 1);
+ cpu_topology[cpu].core_id = topology_id;
+ topology_id = find_acpi_cpu_topology_package(cpu);
+ cpu_topology[cpu].physical_id = topology_id;
+ } else {
+ cpu_topology[cpu].thread_id = -1;
+ cpu_topology[cpu].core_id = topology_id;
+ topology_id = find_acpi_cpu_topology_package(cpu);
+ cpu_topology[cpu].physical_id = topology_id;
+ }
+ }
+ return 0;
+}
+
+#else
+static int __init parse_acpi_topology(void)
+{
+ /*ACPI kernels should be built with PPTT support*/
+ return -EINVAL;
+}
+#endif
void __init init_cpu_topology(void)
{
@@ -309,6 +352,8 @@ void __init init_cpu_topology(void)
* Discard anything that was parsed if we hit an error so we
* don't use partial information.
*/
- if (of_have_populated_dt() && parse_dt_topology())
+ if ((!acpi_disabled) && parse_acpi_topology())
+ reset_cpu_topology();
+ else if (of_have_populated_dt() && parse_dt_topology())
reset_cpu_topology();
}
diff --git a/include/linux/topology.h b/include/linux/topology.h
index cb0775e1ee4b..170ce87edd88 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -43,6 +43,8 @@
if (nr_cpus_node(node))
int arch_update_cpu_topology(void);
+int find_acpi_cpu_topology(unsigned int cpu, int level);
+int find_acpi_cpu_topology_package(unsigned int cpu);
/* Conform to ACPI 2.0 SLIT distance definitions */
#define LOCAL_DISTANCE 10
--
2.13.5
^ permalink raw reply related
* [PATCH v5 7/9] arm64: Topology, rename cluster_id
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Lets match the name of the arm64 topology field
to the kernel macro that uses it.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
arch/arm64/include/asm/topology.h | 4 ++--
arch/arm64/kernel/topology.c | 27 ++++++++++++++-------------
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index c4f2d50491eb..118136268f66 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -7,14 +7,14 @@
struct cpu_topology {
int thread_id;
int core_id;
- int cluster_id;
+ int physical_id;
cpumask_t thread_sibling;
cpumask_t core_sibling;
};
extern struct cpu_topology cpu_topology[NR_CPUS];
-#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id)
+#define topology_physical_package_id(cpu) (cpu_topology[cpu].physical_id)
#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
#define topology_sibling_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 8d48b233e6ce..74a8a5173a35 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -51,7 +51,7 @@ static int __init get_cpu_for_node(struct device_node *node)
return -1;
}
-static int __init parse_core(struct device_node *core, int cluster_id,
+static int __init parse_core(struct device_node *core, int physical_id,
int core_id)
{
char name[10];
@@ -67,7 +67,7 @@ static int __init parse_core(struct device_node *core, int cluster_id,
leaf = false;
cpu = get_cpu_for_node(t);
if (cpu >= 0) {
- cpu_topology[cpu].cluster_id = cluster_id;
+ cpu_topology[cpu].physical_id = physical_id;
cpu_topology[cpu].core_id = core_id;
cpu_topology[cpu].thread_id = i;
} else {
@@ -89,7 +89,7 @@ static int __init parse_core(struct device_node *core, int cluster_id,
return -EINVAL;
}
- cpu_topology[cpu].cluster_id = cluster_id;
+ cpu_topology[cpu].physical_id = physical_id;
cpu_topology[cpu].core_id = core_id;
} else if (leaf) {
pr_err("%pOF: Can't get CPU for leaf core\n", core);
@@ -105,7 +105,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
bool leaf = true;
bool has_cores = false;
struct device_node *c;
- static int cluster_id __initdata;
+ static int physical_id __initdata;
int core_id = 0;
int i, ret;
@@ -144,7 +144,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
}
if (leaf) {
- ret = parse_core(c, cluster_id, core_id++);
+ ret = parse_core(c, physical_id, core_id++);
} else {
pr_err("%pOF: Non-leaf cluster with core %s\n",
cluster, name);
@@ -162,7 +162,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
pr_warn("%pOF: empty cluster\n", cluster);
if (leaf)
- cluster_id++;
+ physical_id++;
return 0;
}
@@ -198,7 +198,7 @@ static int __init parse_dt_topology(void)
* only mark cores described in the DT as possible.
*/
for_each_possible_cpu(cpu)
- if (cpu_topology[cpu].cluster_id == -1)
+ if (cpu_topology[cpu].physical_id == -1)
ret = -EINVAL;
out_map:
@@ -228,7 +228,7 @@ static void update_siblings_masks(unsigned int cpuid)
for_each_possible_cpu(cpu) {
cpu_topo = &cpu_topology[cpu];
- if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
+ if (cpuid_topo->physical_id != cpu_topo->physical_id)
continue;
cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
@@ -249,7 +249,7 @@ void store_cpu_topology(unsigned int cpuid)
struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
u64 mpidr;
- if (cpuid_topo->cluster_id != -1)
+ if (cpuid_topo->physical_id != -1)
goto topology_populated;
mpidr = read_cpuid_mpidr();
@@ -263,19 +263,19 @@ void store_cpu_topology(unsigned int cpuid)
/* Multiprocessor system : Multi-threads per core */
cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
- cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
+ cpuid_topo->physical_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8;
} else {
/* Multiprocessor system : Single-thread per core */
cpuid_topo->thread_id = -1;
cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
- cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
+ cpuid_topo->physical_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 |
MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16;
}
pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
- cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id,
+ cpuid, cpuid_topo->physical_id, cpuid_topo->core_id,
cpuid_topo->thread_id, mpidr);
topology_populated:
@@ -291,7 +291,7 @@ static void __init reset_cpu_topology(void)
cpu_topo->thread_id = -1;
cpu_topo->core_id = 0;
- cpu_topo->cluster_id = -1;
+ cpu_topo->physical_id = -1;
cpumask_clear(&cpu_topo->core_sibling);
cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
@@ -300,6 +300,7 @@ static void __init reset_cpu_topology(void)
}
}
+
void __init init_cpu_topology(void)
{
reset_cpu_topology();
--
2.13.5
^ permalink raw reply related
* [PATCH v5 6/9] ACPI/PPTT: Add topology parsing code
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
The PPTT can be used to determine the groupings of CPU's at
given levels in the system. Lets add a few routines to the PPTT
parsing code to return a unique id for each unique level in the
processor hierarchy. This can then be matched to build
thread/core/cluster/die/package/etc mappings for each processing
element in the system.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
drivers/acpi/pptt.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index a35e457cefb7..b9b7b8b8ad21 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -412,6 +412,79 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table,
}
}
+/* Passing level values greater than this will result in search termination */
+#define PPTT_ABORT_PACKAGE 0xFF
+
+/*
+ * Given an acpi_pptt_processor node, walk up until we identify the
+ * package that the node is associated with, or we run out of levels
+ * to request or the search is terminated with a flag match
+ * The level parameter also serves to limit possible loops within the tree.
+ */
+static struct acpi_pptt_processor *acpi_find_processor_package_id(
+ struct acpi_table_header *table_hdr,
+ struct acpi_pptt_processor *cpu,
+ int level, int flag)
+{
+ struct acpi_pptt_processor *prev_node;
+
+ while (cpu && level) {
+ if (cpu->flags & flag)
+ break;
+ pr_debug("level %d\n", level);
+ prev_node = fetch_pptt_node(table_hdr, cpu->parent);
+ if (prev_node == NULL)
+ break;
+ cpu = prev_node;
+ level--;
+ }
+ return cpu;
+}
+
+/*
+ * Get a unique value given a cpu, and a topology level, that can be
+ * matched to determine which cpus share common topological features
+ * at that level.
+ */
+static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
+ unsigned int cpu, int level, int flag)
+{
+ struct acpi_pptt_processor *cpu_node;
+ u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+
+ cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+ if (cpu_node) {
+ cpu_node = acpi_find_processor_package_id(table, cpu_node,
+ level, flag);
+ /* Only the first level has a guaranteed id */
+ if (level == 0)
+ return cpu_node->acpi_processor_id;
+ return (int)((u8 *)cpu_node - (u8 *)table);
+ }
+ pr_err_once("PPTT table found, but unable to locate core for %d\n",
+ cpu);
+ return -ENOENT;
+}
+
+static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
+{
+ struct acpi_table_header *table;
+ acpi_status status;
+ int retval;
+
+ status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+ if (ACPI_FAILURE(status)) {
+ pr_err_once("No PPTT table found, cpu topology may be inaccurate\n");
+ return -ENOENT;
+ }
+ retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
+ pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n",
+ cpu, level, retval);
+ acpi_put_table(table);
+
+ return retval;
+}
+
/**
* acpi_find_last_cache_level() - Determines the number of cache levels for a PE
* @cpu: Kernel logical cpu number
@@ -475,3 +548,45 @@ int cache_setup_acpi(unsigned int cpu)
return status;
}
+
+/**
+ * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu
+ * @cpu: Kernel logical cpu number
+ * @level: The topological level for which we would like a unique ID
+ *
+ * Determine a topology unique ID for each thread/core/cluster/mc_grouping
+ * /socket/etc. This ID can then be used to group peers, which will have
+ * matching ids.
+ *
+ * The search terminates when either the requested level is found or
+ * we reach a root node. Levels beyond the termination point will return the
+ * same unique ID. The unique id for level 0 is the acpi processor id. All
+ * other levels beyond this use a generated value to uniquely identify
+ * a topological feature.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
+ * Otherwise returns a value which represents a unique topological feature.
+ */
+int find_acpi_cpu_topology(unsigned int cpu, int level)
+{
+ return find_acpi_cpu_topology_tag(cpu, level, 0);
+}
+
+/**
+ * find_acpi_cpu_topology_package() - Determine a unique cpu package value
+ * @cpu: Kernel logical cpu number
+ *
+ * Determine a topology unique package ID for the given cpu.
+ * This ID can then be used to group peers, which will have matching ids.
+ *
+ * The search terminates when either a level is found with the PHYSICAL_PACKAGE
+ * flag set or we reach a root node.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
+ * Otherwise returns a value which represents the package for this cpu.
+ */
+int find_acpi_cpu_topology_package(unsigned int cpu)
+{
+ return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
+ ACPI_PPTT_PHYSICAL_PACKAGE);
+}
--
2.13.5
^ permalink raw reply related
* [PATCH v5 5/9] arm64: Add support for ACPI based firmware tables
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
The /sys cache entries should support ACPI/PPTT generated cache
topology information. Lets detect ACPI systems and call
an arch specific cache_setup_acpi() routine to update the hardware
probed cache topology.
For arm64, if ACPI is enabled, determine the max number of cache
levels and populate them using the PPTT table if one is available.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
arch/arm64/kernel/cacheinfo.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c
index 380f2e2fbed5..0bf0a835122f 100644
--- a/arch/arm64/kernel/cacheinfo.c
+++ b/arch/arm64/kernel/cacheinfo.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi.h>
#include <linux/cacheinfo.h>
#include <linux/of.h>
@@ -46,7 +47,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,
static int __init_cache_level(unsigned int cpu)
{
- unsigned int ctype, level, leaves, of_level;
+ unsigned int ctype, level, leaves, fw_level;
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
@@ -59,15 +60,19 @@ static int __init_cache_level(unsigned int cpu)
leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
}
- of_level = of_find_last_cache_level(cpu);
- if (level < of_level) {
+ if (acpi_disabled)
+ fw_level = of_find_last_cache_level(cpu);
+ else
+ fw_level = acpi_find_last_cache_level(cpu);
+
+ if (level < fw_level) {
/*
* some external caches not specified in CLIDR_EL1
* the information may be available in the device tree
* only unified external caches are considered here
*/
- leaves += (of_level - level);
- level = of_level;
+ leaves += (fw_level - level);
+ level = fw_level;
}
this_cpu_ci->num_levels = level;
--
2.13.5
^ permalink raw reply related
* [PATCH v5 4/9] drivers: base cacheinfo: Add support for ACPI based firmware tables
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Add a entry to to struct cacheinfo to maintain a reference to the PPTT
node which can be used to match identical caches across cores. Also
stub out cache_setup_acpi() so that individual architectures can
enable ACPI topology parsing.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
drivers/acpi/pptt.c | 1 +
drivers/base/cacheinfo.c | 20 ++++++++++++++------
include/linux/cacheinfo.h | 13 ++++++++++++-
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index 0f8a1631af33..a35e457cefb7 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -329,6 +329,7 @@ static void update_cache_properties(struct cacheinfo *this_leaf,
{
int valid_flags = 0;
+ this_leaf->firmware_node = cpu_node;
if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID) {
this_leaf->size = found_cache->size;
valid_flags++;
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index eb3af2739537..ba89f9310e6f 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -86,7 +86,10 @@ static int cache_setup_of_node(unsigned int cpu)
static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
struct cacheinfo *sib_leaf)
{
- return sib_leaf->of_node == this_leaf->of_node;
+ if (acpi_disabled)
+ return sib_leaf->of_node == this_leaf->of_node;
+ else
+ return sib_leaf->firmware_node == this_leaf->firmware_node;
}
/* OF properties to query for a given cache type */
@@ -215,6 +218,11 @@ static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
}
#endif
+int __weak cache_setup_acpi(unsigned int cpu)
+{
+ return -ENOTSUPP;
+}
+
static int cache_shared_cpu_map_setup(unsigned int cpu)
{
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
@@ -225,11 +233,11 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
if (this_cpu_ci->cpu_map_populated)
return 0;
- if (of_have_populated_dt())
+ if (!acpi_disabled)
+ ret = cache_setup_acpi(cpu);
+ else if (of_have_populated_dt())
ret = cache_setup_of_node(cpu);
- else if (!acpi_disabled)
- /* No cache property/hierarchy support yet in ACPI */
- ret = -ENOTSUPP;
+
if (ret)
return ret;
@@ -286,7 +294,7 @@ static void cache_shared_cpu_map_remove(unsigned int cpu)
static void cache_override_properties(unsigned int cpu)
{
- if (of_have_populated_dt())
+ if (acpi_disabled && of_have_populated_dt())
return cache_of_override_properties(cpu);
}
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index 3d9805297cda..7ebff157ae6c 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -37,6 +37,8 @@ enum cache_type {
* @of_node: if devicetree is used, this represents either the cpu node in
* case there's no explicit cache node or the cache node itself in the
* device tree
+ * @firmware_node: When not using DT, this may contain pointers to other
+ * firmware based values. Particularly ACPI/PPTT unique values.
* @disable_sysfs: indicates whether this node is visible to the user via
* sysfs or not
* @priv: pointer to any private data structure specific to particular
@@ -65,8 +67,8 @@ struct cacheinfo {
#define CACHE_ALLOCATE_POLICY_MASK \
(CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE)
#define CACHE_ID BIT(4)
-
struct device_node *of_node;
+ void *firmware_node;
bool disable_sysfs;
void *priv;
};
@@ -99,6 +101,15 @@ int func(unsigned int cpu) \
struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
int init_cache_level(unsigned int cpu);
int populate_cache_leaves(unsigned int cpu);
+int cache_setup_acpi(unsigned int cpu);
+int acpi_find_last_cache_level(unsigned int cpu);
+#ifndef CONFIG_ACPI
+int acpi_find_last_cache_level(unsigned int cpu)
+{
+ /*ACPI kernels should be built with PPTT support*/
+ return 0;
+}
+#endif
const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf);
--
2.13.5
^ permalink raw reply related
* [PATCH v5 3/9] ACPI: Enable PPTT support on ARM64
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Now that we have a PPTT parser, in preparation for its use
on arm64, lets build it.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
arch/arm64/Kconfig | 1 +
drivers/acpi/Kconfig | 3 +++
drivers/acpi/Makefile | 1 +
3 files changed, 5 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a93339f5178f..e62fd1e08c1f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -7,6 +7,7 @@ config ARM64
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ACPI_MCFG if ACPI
select ACPI_SPCR_TABLE if ACPI
+ select ACPI_PPTT if ACPI
select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 46505396869e..df7aebf0af0e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -545,6 +545,9 @@ config ACPI_CONFIGFS
if ARM64
source "drivers/acpi/arm64/Kconfig"
+
+config ACPI_PPTT
+ bool
endif
config TPS68470_PMIC_OPREGION
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 41954a601989..b6056b566df4 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_ACPI_BGRT) += bgrt.o
obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o
obj-$(CONFIG_ACPI_SPCR_TABLE) += spcr.o
obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
+obj-$(CONFIG_ACPI_PPTT) += pptt.o
# processor has its own "processor." module_param namespace
processor-y := processor_driver.o
--
2.13.5
^ permalink raw reply related
* [RFC 2/2] dt-bindings: mailbox: Add Xilinx IPI Mailbox
From: Rob Herring @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1511999947-8274-3-git-send-email-jliang@xilinx.com>
On Wed, Nov 29, 2017 at 03:59:07PM -0800, Wendy Liang wrote:
> Xilinx ZynqMP IPI(Inter Processor Interrupt) is a hardware block
> in ZynqMP SoC used for the communication between various processor
> systems.
>
> Signed-off-by: Wendy Liang <jliang@xilinx.com>
> ---
> .../bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt | 113 +++++++++++++++++++++
> 1 file changed, 113 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt
>
> diff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt
> new file mode 100644
> index 0000000..a118d00
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt
> @@ -0,0 +1,113 @@
> +Xilinx IPI Mailbox Controller
> +========================================
> +
> +The Xilinx IPI(Inter Processor Interrupt) mailbox controller is to manage
> +messaging between two Xilinx Zynq UltraScale+ MPSoC IPI agents. Each IPI
> +agent owns registers used for notification and buffers for message.
> +
> + +-------------------------------------+
> + | Xilinx ZynqMP IPI Controller |
> + +-------------------------------------+
> + +--------------------------------------------------+
> +ATF | |
> + | |
> + | |
> + +--------------------------+ |
> + | |
> + | |
> + +--------------------------------------------------+
> + +------------------------------------------+
> + | +----------------+ +----------------+ |
> +Hardware | | IPI Agent | | IPI Buffers | |
> + | | Registers | | | |
> + | | | | | |
> + | +----------------+ +----------------+ |
> + | |
> + | Xilinx IPI Agent Block |
> + +------------------------------------------+
> +
> +
> +Controller Device Node:
> +===========================
> +Required properties:
> +--------------------
> +- compatible: Shall be: "xlnx,zynqmp-ipi-mailbox"
> +- reg: IPI buffers address ranges
> +- reg-names: Names of the reg resources. It should have:
> + * local_request_region
> + - IPI request msg buffer written by local and read
> + by remote
> + * local_response_region
> + - IPI response msg buffer written by local and read
> + by remote
> + * remote_request_region
> + - IPI request msg buffer written by remote and read
> + by local
> + * remote_response_region
> + - IPI response msg buffer written by remote and read
> + by local
> +- #mbox-cells: Shall be 1. It contains:
> + * tx(0) or rx(1) channel
> +- xlnx-ipi-ids: Xilinx IPI agent IDs of the two peers of the
> + Xilinx IPI communication channel.
xlnx,ipi-ids
> +- interrupt-parent: Phandle for the interrupt controller
> +- interrupts: Interrupt information corresponding to the
> + interrupt-names property.
> +
> +Optional properties:
> +--------------------
> +- method: The method of accessing the IPI agent registers.
> + Permitted values are: "smc" and "hvc". Default is
> + "smc".
> +
> +Client Device Node:
> +===========================
> +Required properties:
> +--------------------
> +- mboxes: Standard property to specify a mailbox
> + (See ./mailbox.txt)
> +- mbox-names: List of identifier strings for each mailbox
> + channel.
This part is a standard part of the binding and doesn't need to be here.
> +
> +Example:
> +===========================
> + /* APU<->RPU0 IPI mailbox controller */
> + ipi_mailbox_rpu0: mailbox at ff90400 {
> + compatible = "xlnx,zynqmp-ipi-mailbox";
> + reg = <0x0 0xff990400 0x0 0x20>,
> + <0x0 0xff990420 0x0 0x20>,
> + <0x0 0xff990080 0x0 0x20>,
> + <0x0 0xff9900a0 0x0 0x20>;
> + reg-names = "local_request_region", "local_response_region",
> + "remote_request_region", "remote_response_region";
> + #mbox-cells = <1>;
> + xlnx-ipi-ids = <0 1>;
> + interrupt-parent = <&gic>;
> + interrupts = <0 29 4>;
> + };
> + /* APU<->RPU1 IPI mailbox controller */
> + ipi_mailbox_rpu1: mailbox at ff990440 {
> + compatible = "xlnx,zynqmp-ipi-mailbox";
> + reg = <0x0 0xff990440 0x0 0x20>,
> + <0x0 0xff990460 0x0 0x20>,
> + <0x0 0xff990280 0x0 0x20>,
> + <0x0 0xff9902a0 0x0 0x20>;
> + reg-names = "local_request_region", "local_response_region",
> + "remote_request_region", "remote_response_region";
> + #mbox-cells = <1>;
> + xlnx-ipi-ids = <0 2>;
> + interrupt-parent = <&gic>;
> + interrupts = <0 29 4>;
> + };
> + rpu0 {
> + ...
> + mboxes = <&ipi_mailbox_rpu0 0>,
> + <&ipi_mailbox_rpu0 1>;
> + mbox-names = "tx", "rx";
> + };
> + rpu1 {
> + ...
> + mboxes = <&ipi_mailbox_rpu1 0>,
> + <&ipi_mailbox_rpu1 1>;
> + mbox-names = "tx", "rx";
> + };
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v5 2/9] ACPI/PPTT: Add Processor Properties Topology Table parsing
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
ACPI 6.2 adds a new table, which describes how processing units
are related to each other in tree like fashion. Caches are
also sprinkled throughout the tree and describe the properties
of the caches in relation to other caches and processing units.
Add the code to parse the cache hierarchy and report the total
number of levels of cache for a given core using
acpi_find_last_cache_level() as well as fill out the individual
cores cache information with cache_setup_acpi() once the
cpu_cacheinfo structure has been populated by the arch specific
code.
An additional patch later in the set adds the ability to report
peers in the topology using find_acpi_cpu_topology()
to report a unique ID for each processing unit at a given level
in the tree. These unique id's can then be used to match related
processing units which exist as threads, COD (clusters
on die), within a given package, etc.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
drivers/acpi/pptt.c | 476 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 476 insertions(+)
create mode 100644 drivers/acpi/pptt.c
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
new file mode 100644
index 000000000000..0f8a1631af33
--- /dev/null
+++ b/drivers/acpi/pptt.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2017, ARM
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * This file implements parsing of Processor Properties Topology Table (PPTT)
+ * which is optionally used to describe the processor and cache topology.
+ * Due to the relative pointers used throughout the table, this doesn't
+ * leverage the existing subtable parsing in the kernel.
+ *
+ * The PPTT structure is an inverted tree, with each node potentially
+ * holding one or two inverted tree data structures describing
+ * the caches available at that level. Each cache structure optionally
+ * contains properties describing the cache at a given level which can be
+ * used to override hardware probed values.
+ */
+#define pr_fmt(fmt) "ACPI PPTT: " fmt
+
+#include <linux/acpi.h>
+#include <linux/cacheinfo.h>
+#include <acpi/processor.h>
+
+/* total number of attributes checked by the properties code */
+#define PPTT_CHECKED_ATTRIBUTES 6
+
+/*
+ * Given the PPTT table, find and verify that the subtable entry
+ * is located within the table
+ */
+static struct acpi_subtable_header *fetch_pptt_subtable(
+ struct acpi_table_header *table_hdr, u32 pptt_ref)
+{
+ struct acpi_subtable_header *entry;
+
+ /* there isn't a subtable at reference 0 */
+ if (pptt_ref < sizeof(struct acpi_subtable_header))
+ return NULL;
+
+ if (pptt_ref + sizeof(struct acpi_subtable_header) > table_hdr->length)
+ return NULL;
+
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, pptt_ref);
+
+ if (pptt_ref + entry->length > table_hdr->length)
+ return NULL;
+
+ return entry;
+}
+
+static struct acpi_pptt_processor *fetch_pptt_node(
+ struct acpi_table_header *table_hdr, u32 pptt_ref)
+{
+ return (struct acpi_pptt_processor *)fetch_pptt_subtable(table_hdr,
+ pptt_ref);
+}
+
+static struct acpi_pptt_cache *fetch_pptt_cache(
+ struct acpi_table_header *table_hdr, u32 pptt_ref)
+{
+ return (struct acpi_pptt_cache *)fetch_pptt_subtable(table_hdr,
+ pptt_ref);
+}
+
+static struct acpi_subtable_header *acpi_get_pptt_resource(
+ struct acpi_table_header *table_hdr,
+ struct acpi_pptt_processor *node, int resource)
+{
+ u32 *ref;
+
+ if (resource >= node->number_of_priv_resources)
+ return NULL;
+
+ ref = ACPI_ADD_PTR(u32, node, sizeof(struct acpi_pptt_processor));
+ ref += resource;
+
+ return fetch_pptt_subtable(table_hdr, *ref);
+}
+
+/*
+ * Attempt to find a given cache level, while counting the max number
+ * of cache levels for the cache node.
+ *
+ * Given a pptt resource, verify that it is a cache node, then walk
+ * down each level of caches, counting how many levels are found
+ * as well as checking the cache type (icache, dcache, unified). If a
+ * level & type match, then we set found, and continue the search.
+ * Once the entire cache branch has been walked return its max
+ * depth.
+ */
+static int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
+ int local_level,
+ struct acpi_subtable_header *res,
+ struct acpi_pptt_cache **found,
+ int level, int type)
+{
+ struct acpi_pptt_cache *cache;
+
+ if (res->type != ACPI_PPTT_TYPE_CACHE)
+ return 0;
+
+ cache = (struct acpi_pptt_cache *) res;
+ while (cache) {
+ local_level++;
+
+ if ((local_level == level) &&
+ (cache->flags & ACPI_PPTT_CACHE_TYPE_VALID) &&
+ ((cache->attributes & ACPI_PPTT_MASK_CACHE_TYPE) == type)) {
+ if ((*found != NULL) && (cache != *found))
+ pr_err("Found duplicate cache level/type unable to determine uniqueness\n");
+
+ pr_debug("Found cache @ level %d\n", level);
+ *found = cache;
+ /*
+ * continue looking at this node's resource list
+ * to verify that we don't find a duplicate
+ * cache node.
+ */
+ }
+ cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache);
+ }
+ return local_level;
+}
+
+/*
+ * Given a CPU node look for cache levels that exist at this level, and then
+ * for each cache node, count how many levels exist below (logically above) it.
+ * If a level and type are specified, and we find that level/type, abort
+ * processing and return the acpi_pptt_cache structure.
+ */
+static struct acpi_pptt_cache *acpi_find_cache_level(
+ struct acpi_table_header *table_hdr,
+ struct acpi_pptt_processor *cpu_node,
+ int *starting_level, int level, int type)
+{
+ struct acpi_subtable_header *res;
+ int number_of_levels = *starting_level;
+ int resource = 0;
+ struct acpi_pptt_cache *ret = NULL;
+ int local_level;
+
+ /* walk down from processor node */
+ while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) {
+ resource++;
+
+ local_level = acpi_pptt_walk_cache(table_hdr, *starting_level,
+ res, &ret, level, type);
+ /*
+ * we are looking for the max depth. Since its potentially
+ * possible for a given node to have resources with differing
+ * depths verify that the depth we have found is the largest.
+ */
+ if (number_of_levels < local_level)
+ number_of_levels = local_level;
+ }
+ if (number_of_levels > *starting_level)
+ *starting_level = number_of_levels;
+
+ return ret;
+}
+
+/*
+ * Given a processor node containing a processing unit, walk into it and count
+ * how many levels exist solely for it, and then walk up each level until we hit
+ * the root node (ignore the package level because it may be possible to have
+ * caches that exist across packages). Count the number of cache levels that
+ * exist at each level on the way up.
+ */
+static int acpi_process_node(struct acpi_table_header *table_hdr,
+ struct acpi_pptt_processor *cpu_node)
+{
+ int total_levels = 0;
+
+ do {
+ acpi_find_cache_level(table_hdr, cpu_node, &total_levels, 0, 0);
+ cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
+ } while (cpu_node);
+
+ return total_levels;
+}
+
+/*
+ * Determine if the *node parameter is a leaf node by iterating the
+ * PPTT table, looking for nodes which reference it.
+ * Return 0 if we find a node referencing the passed node,
+ * or 1 if we don't.
+ */
+static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
+ struct acpi_pptt_processor *node)
+{
+ struct acpi_subtable_header *entry;
+ unsigned long table_end;
+ u32 node_entry;
+ struct acpi_pptt_processor *cpu_node;
+
+ table_end = (unsigned long)table_hdr + table_hdr->length;
+ node_entry = ACPI_PTR_DIFF(node, table_hdr);
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+ sizeof(struct acpi_table_pptt));
+
+ while ((unsigned long)(entry + 1) < table_end) {
+ cpu_node = (struct acpi_pptt_processor *)entry;
+ if ((entry->type == ACPI_PPTT_TYPE_PROCESSOR) &&
+ (cpu_node->parent == node_entry))
+ return 0;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
+ entry->length);
+ }
+ return 1;
+}
+
+/*
+ * Find the subtable entry describing the provided processor.
+ * This is done by iterating the PPTT table looking for processor nodes
+ * which have an acpi_processor_id that matches the acpi_cpu_id parameter
+ * passed into the function. If we find a node that matches this criteria
+ * we verify that its a leaf node in the topology rather than depending
+ * on the valid flag, which doesn't need to be set for leaf nodes.
+ */
+static struct acpi_pptt_processor *acpi_find_processor_node(
+ struct acpi_table_header *table_hdr,
+ u32 acpi_cpu_id)
+{
+ struct acpi_subtable_header *entry;
+ unsigned long table_end;
+ struct acpi_pptt_processor *cpu_node;
+
+ table_end = (unsigned long)table_hdr + table_hdr->length;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+ sizeof(struct acpi_table_pptt));
+
+ /* find the processor structure associated with this cpuid */
+ while ((unsigned long)(entry + 1) < table_end) {
+ cpu_node = (struct acpi_pptt_processor *)entry;
+
+ if (entry->length == 0) {
+ pr_err("Invalid zero length subtable\n");
+ break;
+ }
+ if ((entry->type == ACPI_PPTT_TYPE_PROCESSOR) &&
+ (acpi_cpu_id == cpu_node->acpi_processor_id) &&
+ acpi_pptt_leaf_node(table_hdr, cpu_node)) {
+ return (struct acpi_pptt_processor *)entry;
+ }
+
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
+ entry->length);
+ }
+
+ return NULL;
+}
+
+static int acpi_find_cache_levels(struct acpi_table_header *table_hdr,
+ u32 acpi_cpu_id)
+{
+ int number_of_levels = 0;
+ struct acpi_pptt_processor *cpu;
+
+ cpu = acpi_find_processor_node(table_hdr, acpi_cpu_id);
+ if (cpu)
+ number_of_levels = acpi_process_node(table_hdr, cpu);
+
+ return number_of_levels;
+}
+
+/* Convert the linux cache_type to a ACPI PPTT cache type value */
+static u8 acpi_cache_type(enum cache_type type)
+{
+ switch (type) {
+ case CACHE_TYPE_DATA:
+ pr_debug("Looking for data cache\n");
+ return ACPI_PPTT_CACHE_TYPE_DATA;
+ case CACHE_TYPE_INST:
+ pr_debug("Looking for instruction cache\n");
+ return ACPI_PPTT_CACHE_TYPE_INSTR;
+ default:
+ case CACHE_TYPE_UNIFIED:
+ pr_debug("Looking for unified cache\n");
+ /*
+ * It is important that ACPI_PPTT_CACHE_TYPE_UNIFIED
+ * contains the bit pattern that will match both
+ * ACPI unified bit patterns because we use it later
+ * to match both cases.
+ */
+ return ACPI_PPTT_CACHE_TYPE_UNIFIED;
+ }
+}
+
+/* find the ACPI node describing the cache type/level for the given CPU */
+static struct acpi_pptt_cache *acpi_find_cache_node(
+ struct acpi_table_header *table_hdr, u32 acpi_cpu_id,
+ enum cache_type type, unsigned int level,
+ struct acpi_pptt_processor **node)
+{
+ int total_levels = 0;
+ struct acpi_pptt_cache *found = NULL;
+ struct acpi_pptt_processor *cpu_node;
+ u8 acpi_type = acpi_cache_type(type);
+
+ pr_debug("Looking for CPU %d's level %d cache type %d\n",
+ acpi_cpu_id, level, acpi_type);
+
+ cpu_node = acpi_find_processor_node(table_hdr, acpi_cpu_id);
+
+ while ((cpu_node) && (!found)) {
+ found = acpi_find_cache_level(table_hdr, cpu_node,
+ &total_levels, level, acpi_type);
+ *node = cpu_node;
+ cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
+ }
+
+ return found;
+}
+
+/*
+ * The ACPI spec implies that the fields in the cache structures are used to
+ * extend and correct the information probed from the hardware. In the case
+ * of arm64 the CCSIDR probing has been removed because it might be incorrect.
+ */
+static void update_cache_properties(struct cacheinfo *this_leaf,
+ struct acpi_pptt_cache *found_cache,
+ struct acpi_pptt_processor *cpu_node)
+{
+ int valid_flags = 0;
+
+ if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID) {
+ this_leaf->size = found_cache->size;
+ valid_flags++;
+ }
+ if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID) {
+ this_leaf->coherency_line_size = found_cache->line_size;
+ valid_flags++;
+ }
+ if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID) {
+ this_leaf->number_of_sets = found_cache->number_of_sets;
+ valid_flags++;
+ }
+ if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID) {
+ this_leaf->ways_of_associativity = found_cache->associativity;
+ valid_flags++;
+ }
+ if (found_cache->flags & ACPI_PPTT_WRITE_POLICY_VALID) {
+ switch (found_cache->attributes & ACPI_PPTT_MASK_WRITE_POLICY) {
+ case ACPI_PPTT_CACHE_POLICY_WT:
+ this_leaf->attributes = CACHE_WRITE_THROUGH;
+ break;
+ case ACPI_PPTT_CACHE_POLICY_WB:
+ this_leaf->attributes = CACHE_WRITE_BACK;
+ break;
+ }
+ valid_flags++;
+ }
+ if (found_cache->flags & ACPI_PPTT_ALLOCATION_TYPE_VALID) {
+ switch (found_cache->attributes & ACPI_PPTT_MASK_ALLOCATION_TYPE) {
+ case ACPI_PPTT_CACHE_READ_ALLOCATE:
+ this_leaf->attributes |= CACHE_READ_ALLOCATE;
+ break;
+ case ACPI_PPTT_CACHE_WRITE_ALLOCATE:
+ this_leaf->attributes |= CACHE_WRITE_ALLOCATE;
+ break;
+ case ACPI_PPTT_CACHE_RW_ALLOCATE:
+ case ACPI_PPTT_CACHE_RW_ALLOCATE_ALT:
+ this_leaf->attributes |=
+ CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE;
+ break;
+ }
+ valid_flags++;
+ }
+ /*
+ * If all the above flags are valid, and the cache type is NOCACHE
+ * update the cache type as well.
+ */
+ if ((this_leaf->type == CACHE_TYPE_NOCACHE) &&
+ (valid_flags == PPTT_CHECKED_ATTRIBUTES))
+ this_leaf->type = CACHE_TYPE_UNIFIED;
+}
+
+/*
+ * Update the kernel cache information for each level of cache
+ * associated with the given acpi cpu.
+ */
+static void cache_setup_acpi_cpu(struct acpi_table_header *table,
+ unsigned int cpu)
+{
+ struct acpi_pptt_cache *found_cache;
+ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+ u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+ struct cacheinfo *this_leaf;
+ unsigned int index = 0;
+ struct acpi_pptt_processor *cpu_node = NULL;
+
+ while (index < get_cpu_cacheinfo(cpu)->num_leaves) {
+ this_leaf = this_cpu_ci->info_list + index;
+ found_cache = acpi_find_cache_node(table, acpi_cpu_id,
+ this_leaf->type,
+ this_leaf->level,
+ &cpu_node);
+ pr_debug("found = %p %p\n", found_cache, cpu_node);
+ if (found_cache)
+ update_cache_properties(this_leaf,
+ found_cache,
+ cpu_node);
+
+ index++;
+ }
+}
+
+/**
+ * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
+ * @cpu: Kernel logical cpu number
+ *
+ * Given a logical cpu number, returns the number of levels of cache represented
+ * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
+ * indicating we didn't find any cache levels.
+ *
+ * Return: Cache levels visible to this core.
+ */
+int acpi_find_last_cache_level(unsigned int cpu)
+{
+ u32 acpi_cpu_id;
+ struct acpi_table_header *table;
+ int number_of_levels = 0;
+ acpi_status status;
+
+ pr_debug("Cache Setup find last level cpu=%d\n", cpu);
+
+ acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+ status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+ if (ACPI_FAILURE(status)) {
+ pr_err_once("No PPTT table found, cache topology may be inaccurate\n");
+ } else {
+ number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id);
+ acpi_put_table(table);
+ }
+ pr_debug("Cache Setup find last level level=%d\n", number_of_levels);
+
+ return number_of_levels;
+}
+
+/**
+ * cache_setup_acpi() - Override CPU cache topology with data from the PPTT
+ * @cpu: Kernel logical cpu number
+ *
+ * Updates the global cache info provided by cpu_get_cacheinfo()
+ * when there are valid properties in the acpi_pptt_cache nodes. A
+ * successful parse may not result in any updates if none of the
+ * cache levels have any valid flags set. Futher, a unique value is
+ * associated with each known CPU cache entry. This unique value
+ * can be used to determine whether caches are shared between cpus.
+ *
+ * Return: -ENOENT on failure to find table, or 0 on success
+ */
+int cache_setup_acpi(unsigned int cpu)
+{
+ struct acpi_table_header *table;
+ acpi_status status;
+
+ pr_debug("Cache Setup ACPI cpu %d\n", cpu);
+
+ status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+ if (ACPI_FAILURE(status)) {
+ pr_err_once("No PPTT table found, cache topology may be inaccurate\n");
+ return -ENOENT;
+ }
+
+ cache_setup_acpi_cpu(table, cpu);
+ acpi_put_table(table);
+
+ return status;
+}
--
2.13.5
^ permalink raw reply related
* [PATCH v5 1/9] arm64/acpi: Create arch specific cpu to acpi id helper
From: Jeremy Linton @ 2017-12-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171201222330.18863-1-jeremy.linton@arm.com>
Its helpful to be able to lookup the acpi_processor_id associated
with a logical cpu. Provide an arm64 helper to do this.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
arch/arm64/include/asm/acpi.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 32f465a80e4e..0db62a4cbce2 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -86,6 +86,10 @@ static inline bool acpi_has_cpu_in_madt(void)
}
struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu);
+static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
+{
+ return acpi_cpu_get_madt_gicc(cpu)->uid;
+}
static inline void arch_fix_phys_package_id(int num, u32 slot) { }
void __init acpi_init_cpus(void);
--
2.13.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox