root/drivers/clk/bcm/clk-bcm63xx-gate.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clk_bcm63xx_probe
  2. clk_bcm63xx_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 #include <linux/clk-provider.h>
   4 #include <linux/init.h>
   5 #include <linux/of.h>
   6 #include <linux/of_device.h>
   7 #include <linux/platform_device.h>
   8 
   9 struct clk_bcm63xx_table_entry {
  10         const char * const name;
  11         u8 bit;
  12         unsigned long flags;
  13 };
  14 
  15 struct clk_bcm63xx_hw {
  16         void __iomem *regs;
  17         spinlock_t lock;
  18 
  19         struct clk_hw_onecell_data data;
  20 };
  21 
  22 static const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {
  23         { .name = "mac", .bit = 3, },
  24         { .name = "tc", .bit = 5, },
  25         { .name = "us_top", .bit = 6, },
  26         { .name = "ds_top", .bit = 7, },
  27         { .name = "acm", .bit = 8, },
  28         { .name = "spi", .bit = 9, },
  29         { .name = "usbs", .bit = 10, },
  30         { .name = "bmu", .bit = 11, },
  31         { .name = "pcm", .bit = 12, },
  32         { .name = "ntp", .bit = 13, },
  33         { .name = "acp_b", .bit = 14, },
  34         { .name = "acp_a", .bit = 15, },
  35         { .name = "emusb", .bit = 17, },
  36         { .name = "enet0", .bit = 18, },
  37         { .name = "enet1", .bit = 19, },
  38         { .name = "usbsu", .bit = 20, },
  39         { .name = "ephy", .bit = 21, },
  40         { },
  41 };
  42 
  43 static const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {
  44         { .name = "phy_mips", .bit = 0, },
  45         { .name = "adsl_qproc", .bit = 1, },
  46         { .name = "adsl_afe", .bit = 2, },
  47         { .name = "adsl", .bit = 3, },
  48         { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
  49         { .name = "sar", .bit = 5, },
  50         { .name = "pcm", .bit = 6, },
  51         { .name = "usbd", .bit = 7, },
  52         { .name = "usbh", .bit = 8, },
  53         { .name = "hsspi", .bit = 9, },
  54         { .name = "pcie", .bit = 10, },
  55         { .name = "robosw", .bit = 11, },
  56         { },
  57 };
  58 
  59 static const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {
  60         { .name = "enet", .bit = 4, },
  61         { .name = "adslphy", .bit = 5, },
  62         { .name = "pcm", .bit = 8, },
  63         { .name = "spi", .bit = 9, },
  64         { .name = "usbs", .bit = 10, },
  65         { .name = "sar", .bit = 11, },
  66         { .name = "emusb", .bit = 17, },
  67         { .name = "enet0", .bit = 18, },
  68         { .name = "enet1", .bit = 19, },
  69         { .name = "usbsu", .bit = 20, },
  70         { .name = "ephy", .bit = 21, },
  71         { },
  72 };
  73 
  74 static const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {
  75         { .name = "adsl_qproc", .bit = 1, },
  76         { .name = "adsl_afe", .bit = 2, },
  77         { .name = "adsl", .bit = 3, },
  78         { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
  79         { .name = "wlan_ocp", .bit = 5, },
  80         { .name = "swpkt_usb", .bit = 7, },
  81         { .name = "swpkt_sar", .bit = 8, },
  82         { .name = "sar", .bit = 9, },
  83         { .name = "robosw", .bit = 10, },
  84         { .name = "pcm", .bit = 11, },
  85         { .name = "usbd", .bit = 12, },
  86         { .name = "usbh", .bit = 13, },
  87         { .name = "ipsec", .bit = 14, },
  88         { .name = "spi", .bit = 15, },
  89         { .name = "hsspi", .bit = 16, },
  90         { .name = "pcie", .bit = 17, },
  91         { .name = "fap", .bit = 18, },
  92         { .name = "phymips", .bit = 19, },
  93         { .name = "nand", .bit = 20, },
  94         { },
  95 };
  96 
  97 static const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {
  98         { .name = "vdsl_qproc", .bit = 2, },
  99         { .name = "vdsl_afe", .bit = 3, },
 100         { .name = "vdsl_bonding", .bit = 4, },
 101         { .name = "vdsl", .bit = 5, },
 102         { .name = "phymips", .bit = 6, },
 103         { .name = "swpkt_usb", .bit = 7, },
 104         { .name = "swpkt_sar", .bit = 8, },
 105         { .name = "spi", .bit = 9, },
 106         { .name = "usbd", .bit = 10, },
 107         { .name = "sar", .bit = 11, },
 108         { .name = "robosw", .bit = 12, },
 109         { .name = "utopia", .bit = 13, },
 110         { .name = "pcm", .bit = 14, },
 111         { .name = "usbh", .bit = 15, },
 112         { .name = "disable_gless", .bit = 16, },
 113         { .name = "nand", .bit = 17, },
 114         { .name = "ipsec", .bit = 18, },
 115         { },
 116 };
 117 
 118 static const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {
 119         { .name = "disable_gless", .bit = 0, },
 120         { .name = "vdsl_qproc", .bit = 1, },
 121         { .name = "vdsl_afe", .bit = 2, },
 122         { .name = "vdsl", .bit = 3, },
 123         { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
 124         { .name = "wlan_ocp", .bit = 5, },
 125         { .name = "dect", .bit = 6, },
 126         { .name = "fap0", .bit = 7, },
 127         { .name = "fap1", .bit = 8, },
 128         { .name = "sar", .bit = 9, },
 129         { .name = "robosw", .bit = 10, },
 130         { .name = "pcm", .bit = 11, },
 131         { .name = "usbd", .bit = 12, },
 132         { .name = "usbh", .bit = 13, },
 133         { .name = "ipsec", .bit = 14, },
 134         { .name = "spi", .bit = 15, },
 135         { .name = "hsspi", .bit = 16, },
 136         { .name = "pcie", .bit = 17, },
 137         { .name = "phymips", .bit = 18, },
 138         { .name = "gmac", .bit = 19, },
 139         { .name = "nand", .bit = 20, },
 140         { .name = "tbus", .bit = 27, },
 141         { .name = "robosw250", .bit = 31, },
 142         { },
 143 };
 144 
 145 static int clk_bcm63xx_probe(struct platform_device *pdev)
 146 {
 147         const struct clk_bcm63xx_table_entry *entry, *table;
 148         struct clk_bcm63xx_hw *hw;
 149         u8 maxbit = 0;
 150         int i, ret;
 151 
 152         table = of_device_get_match_data(&pdev->dev);
 153         if (!table)
 154                 return -EINVAL;
 155 
 156         for (entry = table; entry->name; entry++)
 157                 maxbit = max_t(u8, maxbit, entry->bit);
 158 
 159         hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
 160                           GFP_KERNEL);
 161         if (!hw)
 162                 return -ENOMEM;
 163 
 164         platform_set_drvdata(pdev, hw);
 165 
 166         spin_lock_init(&hw->lock);
 167 
 168         hw->data.num = maxbit;
 169         for (i = 0; i < maxbit; i++)
 170                 hw->data.hws[i] = ERR_PTR(-ENODEV);
 171 
 172         hw->regs = devm_platform_ioremap_resource(pdev, 0);
 173         if (IS_ERR(hw->regs))
 174                 return PTR_ERR(hw->regs);
 175 
 176         for (entry = table; entry->name; entry++) {
 177                 struct clk_hw *clk;
 178 
 179                 clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL,
 180                                            entry->flags, hw->regs, entry->bit,
 181                                            CLK_GATE_BIG_ENDIAN, &hw->lock);
 182                 if (IS_ERR(clk)) {
 183                         ret = PTR_ERR(clk);
 184                         goto out_err;
 185                 }
 186 
 187                 hw->data.hws[entry->bit] = clk;
 188         }
 189 
 190         ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
 191                                      &hw->data);
 192         if (!ret)
 193                 return 0;
 194 out_err:
 195         for (i = 0; i < hw->data.num; i++) {
 196                 if (!IS_ERR(hw->data.hws[i]))
 197                         clk_hw_unregister_gate(hw->data.hws[i]);
 198         }
 199 
 200         return ret;
 201 }
 202 
 203 static int clk_bcm63xx_remove(struct platform_device *pdev)
 204 {
 205         struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev);
 206         int i;
 207 
 208         of_clk_del_provider(pdev->dev.of_node);
 209 
 210         for (i = 0; i < hw->data.num; i++) {
 211                 if (!IS_ERR(hw->data.hws[i]))
 212                         clk_hw_unregister_gate(hw->data.hws[i]);
 213         }
 214 
 215         return 0;
 216 }
 217 
 218 static const struct of_device_id clk_bcm63xx_dt_ids[] = {
 219         { .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },
 220         { .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },
 221         { .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },
 222         { .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },
 223         { .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, },
 224         { .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, },
 225         { }
 226 };
 227 
 228 static struct platform_driver clk_bcm63xx = {
 229         .probe = clk_bcm63xx_probe,
 230         .remove = clk_bcm63xx_remove,
 231         .driver = {
 232                 .name = "bcm63xx-clock",
 233                 .of_match_table = clk_bcm63xx_dt_ids,
 234         },
 235 };
 236 builtin_platform_driver(clk_bcm63xx);

/* [<][>][^][v][top][bottom][index][help] */