1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2015 Broadcom |
4 | */ |
5 | |
6 | #include <linux/clk.h> |
7 | #include <linux/clk-provider.h> |
8 | #include <linux/io.h> |
9 | #include <linux/module.h> |
10 | #include <linux/platform_device.h> |
11 | #include <dt-bindings/clock/bcm2835-aux.h> |
12 | |
13 | #define BCM2835_AUXIRQ 0x00 |
14 | #define BCM2835_AUXENB 0x04 |
15 | |
16 | static int bcm2835_aux_clk_probe(struct platform_device *pdev) |
17 | { |
18 | struct device *dev = &pdev->dev; |
19 | struct clk_hw_onecell_data *onecell; |
20 | const char *parent; |
21 | struct clk *parent_clk; |
22 | void __iomem *reg, *gate; |
23 | |
24 | parent_clk = devm_clk_get(dev, NULL); |
25 | if (IS_ERR(ptr: parent_clk)) |
26 | return PTR_ERR(ptr: parent_clk); |
27 | parent = __clk_get_name(clk: parent_clk); |
28 | |
29 | reg = devm_platform_ioremap_resource(pdev, index: 0); |
30 | if (IS_ERR(ptr: reg)) |
31 | return PTR_ERR(ptr: reg); |
32 | |
33 | onecell = devm_kmalloc(dev, |
34 | struct_size(onecell, hws, |
35 | BCM2835_AUX_CLOCK_COUNT), |
36 | GFP_KERNEL); |
37 | if (!onecell) |
38 | return -ENOMEM; |
39 | onecell->num = BCM2835_AUX_CLOCK_COUNT; |
40 | |
41 | gate = reg + BCM2835_AUXENB; |
42 | onecell->hws[BCM2835_AUX_CLOCK_UART] = |
43 | clk_hw_register_gate(dev, "aux_uart" , parent, 0, gate, 0, 0, NULL); |
44 | |
45 | onecell->hws[BCM2835_AUX_CLOCK_SPI1] = |
46 | clk_hw_register_gate(dev, "aux_spi1" , parent, 0, gate, 1, 0, NULL); |
47 | |
48 | onecell->hws[BCM2835_AUX_CLOCK_SPI2] = |
49 | clk_hw_register_gate(dev, "aux_spi2" , parent, 0, gate, 2, 0, NULL); |
50 | |
51 | return of_clk_add_hw_provider(np: pdev->dev.of_node, get: of_clk_hw_onecell_get, |
52 | data: onecell); |
53 | } |
54 | |
55 | static const struct of_device_id bcm2835_aux_clk_of_match[] = { |
56 | { .compatible = "brcm,bcm2835-aux" , }, |
57 | {}, |
58 | }; |
59 | MODULE_DEVICE_TABLE(of, bcm2835_aux_clk_of_match); |
60 | |
61 | static struct platform_driver bcm2835_aux_clk_driver = { |
62 | .driver = { |
63 | .name = "bcm2835-aux-clk" , |
64 | .of_match_table = bcm2835_aux_clk_of_match, |
65 | }, |
66 | .probe = bcm2835_aux_clk_probe, |
67 | }; |
68 | builtin_platform_driver(bcm2835_aux_clk_driver); |
69 | |
70 | MODULE_AUTHOR("Eric Anholt <eric@anholt.net>" ); |
71 | MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver" ); |
72 | |