Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: mmp: Add Marvell PXA1908 APBCP driver

Add driver for the APBCP controller block found on Marvell's PXA1908
SoC.

Signed-off-by: Duje Mihanović <duje.mihanovic@skole.hr>
Link: https://lore.kernel.org/r/20241104-pxa1908-lkml-v13-6-e050609b8d6c@skole.hr
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Duje Mihanović and committed by
Stephen Boyd
a89233db 51ce5591

+83 -1
+1 -1
drivers/clk/mmp/Makefile
··· 11 11 obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o 12 12 obj-$(CONFIG_COMMON_CLK_MMP2_AUDIO) += clk-audio.o 13 13 14 - obj-$(CONFIG_ARCH_MMP) += clk-of-pxa1928.o clk-pxa1908-apbc.o 14 + obj-$(CONFIG_ARCH_MMP) += clk-of-pxa1928.o clk-pxa1908-apbc.o clk-pxa1908-apbcp.o
+82
drivers/clk/mmp/clk-pxa1908-apbcp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + #include <linux/clk-provider.h> 3 + #include <linux/module.h> 4 + #include <linux/platform_device.h> 5 + #include <linux/spinlock.h> 6 + 7 + #include <dt-bindings/clock/marvell,pxa1908.h> 8 + 9 + #include "clk.h" 10 + 11 + #define APBCP_UART2 0x1c 12 + #define APBCP_TWSI2 0x28 13 + #define APBCP_AICER 0x38 14 + 15 + #define APBCP_NR_CLKS 4 16 + 17 + struct pxa1908_clk_unit { 18 + struct mmp_clk_unit unit; 19 + void __iomem *base; 20 + }; 21 + 22 + static DEFINE_SPINLOCK(uart2_lock); 23 + 24 + static const char * const uart_parent_names[] = {"pll1_117", "uart_pll"}; 25 + 26 + static struct mmp_param_gate_clk apbcp_gate_clks[] = { 27 + {PXA1908_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock}, 28 + {PXA1908_CLK_TWSI2, "twsi2_clk", "pll1_32", CLK_SET_RATE_PARENT, APBCP_TWSI2, 0x7, 0x3, 0x0, 0, NULL}, 29 + {PXA1908_CLK_AICER, "ripc_clk", NULL, 0, APBCP_AICER, 0x7, 0x2, 0x0, 0, NULL}, 30 + }; 31 + 32 + static struct mmp_param_mux_clk apbcp_mux_clks[] = { 33 + {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBCP_UART2, 4, 3, 0, &uart2_lock}, 34 + }; 35 + 36 + static void pxa1908_apb_p_periph_clk_init(struct pxa1908_clk_unit *pxa_unit) 37 + { 38 + struct mmp_clk_unit *unit = &pxa_unit->unit; 39 + 40 + mmp_register_mux_clks(unit, apbcp_mux_clks, pxa_unit->base, 41 + ARRAY_SIZE(apbcp_mux_clks)); 42 + mmp_register_gate_clks(unit, apbcp_gate_clks, pxa_unit->base, 43 + ARRAY_SIZE(apbcp_gate_clks)); 44 + } 45 + 46 + static int pxa1908_apbcp_probe(struct platform_device *pdev) 47 + { 48 + struct pxa1908_clk_unit *pxa_unit; 49 + 50 + pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL); 51 + if (IS_ERR(pxa_unit)) 52 + return PTR_ERR(pxa_unit); 53 + 54 + pxa_unit->base = devm_platform_ioremap_resource(pdev, 0); 55 + if (IS_ERR(pxa_unit->base)) 56 + return PTR_ERR(pxa_unit->base); 57 + 58 + mmp_clk_init(pdev->dev.of_node, &pxa_unit->unit, APBCP_NR_CLKS); 59 + 60 + pxa1908_apb_p_periph_clk_init(pxa_unit); 61 + 62 + return 0; 63 + } 64 + 65 + static const struct of_device_id pxa1908_apbcp_match_table[] = { 66 + { .compatible = "marvell,pxa1908-apbcp" }, 67 + { } 68 + }; 69 + MODULE_DEVICE_TABLE(of, pxa1908_apbcp_match_table); 70 + 71 + static struct platform_driver pxa1908_apbcp_driver = { 72 + .probe = pxa1908_apbcp_probe, 73 + .driver = { 74 + .name = "pxa1908-apbcp", 75 + .of_match_table = pxa1908_apbcp_match_table 76 + } 77 + }; 78 + module_platform_driver(pxa1908_apbcp_driver); 79 + 80 + MODULE_AUTHOR("Duje Mihanović <duje.mihanovic@skole.hr>"); 81 + MODULE_DESCRIPTION("Marvell PXA1908 APBCP Clock Driver"); 82 + MODULE_LICENSE("GPL");