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

Merge tag 'sunxi-clocks-for-4.1' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next

Allwinner clocks changes for 4.1

The usual round of clock changes for the Allwinner SoCs.

There is nothing really standing out here, but a few changes and fixes, most
notably to allow the AHB clock to be parented to a PLL, instead of the CPU
clock to avoid any AHB rate change due to cpufreq.

+319 -103
+3
Documentation/devicetree/bindings/clock/sunxi.txt
··· 20 20 "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 21 21 "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates 22 22 "allwinner,sun4i-a10-ahb-clk" - for the AHB clock 23 + "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13 23 24 "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 24 25 "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 25 26 "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 ··· 67 66 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 68 67 "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 69 68 "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31 69 + "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80 70 + "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80 70 71 71 72 Required properties for all clocks: 72 73 - reg : shall be the control register address for the clock.
+1
drivers/clk/sunxi/Makefile
··· 9 9 obj-y += clk-sun8i-mbus.o 10 10 obj-y += clk-sun9i-core.o 11 11 obj-y += clk-sun9i-mmc.o 12 + obj-y += clk-usb.o 12 13 13 14 obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 14 15 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
+82 -103
drivers/clk/sunxi/clk-sunxi.c
··· 482 482 } 483 483 484 484 /** 485 + * sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB 486 + * AHB rate is calculated as follows 487 + * rate = parent_rate >> p 488 + */ 489 + 490 + static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, 491 + u8 *n, u8 *k, u8 *m, u8 *p) 492 + { 493 + u32 div; 494 + 495 + /* divide only */ 496 + if (parent_rate < *freq) 497 + *freq = parent_rate; 498 + 499 + /* 500 + * user manual says valid speed is 8k ~ 276M, but tests show it 501 + * can work at speeds up to 300M, just after reparenting to pll6 502 + */ 503 + if (*freq < 8000) 504 + *freq = 8000; 505 + if (*freq > 300000000) 506 + *freq = 300000000; 507 + 508 + div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); 509 + 510 + /* p = 0 ~ 3 */ 511 + if (div > 3) 512 + div = 3; 513 + 514 + *freq = parent_rate >> div; 515 + 516 + /* we were called to round the frequency, we can now return */ 517 + if (p == NULL) 518 + return; 519 + 520 + *p = div; 521 + } 522 + 523 + /** 485 524 * sun4i_get_apb1_factors() - calculates m, p factors for APB1 486 525 * APB1 rate is calculated as follows 487 526 * rate = (parent_rate >> p) / (m + 1); ··· 655 616 .n_start = 1, 656 617 }; 657 618 619 + static struct clk_factors_config sun5i_a13_ahb_config = { 620 + .pshift = 4, 621 + .pwidth = 2, 622 + }; 623 + 658 624 static struct clk_factors_config sun4i_apb1_config = { 659 625 .mshift = 0, 660 626 .mwidth = 5, ··· 718 674 .table = &sun6i_a31_pll6_config, 719 675 .getter = sun6i_a31_get_pll6_factors, 720 676 .name = "pll6x2", 677 + }; 678 + 679 + static const struct factors_data sun5i_a13_ahb_data __initconst = { 680 + .mux = 6, 681 + .muxmask = BIT(1) | BIT(0), 682 + .table = &sun5i_a13_ahb_config, 683 + .getter = sun5i_a13_get_ahb_factors, 721 684 }; 722 685 723 686 static const struct factors_data sun4i_apb1_data __initconst = { ··· 889 838 890 839 891 840 /** 892 - * sunxi_gates_reset... - reset bits in leaf gate clk registers handling 893 - */ 894 - 895 - struct gates_reset_data { 896 - void __iomem *reg; 897 - spinlock_t *lock; 898 - struct reset_controller_dev rcdev; 899 - }; 900 - 901 - static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev, 902 - unsigned long id) 903 - { 904 - struct gates_reset_data *data = container_of(rcdev, 905 - struct gates_reset_data, 906 - rcdev); 907 - unsigned long flags; 908 - u32 reg; 909 - 910 - spin_lock_irqsave(data->lock, flags); 911 - 912 - reg = readl(data->reg); 913 - writel(reg & ~BIT(id), data->reg); 914 - 915 - spin_unlock_irqrestore(data->lock, flags); 916 - 917 - return 0; 918 - } 919 - 920 - static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev, 921 - unsigned long id) 922 - { 923 - struct gates_reset_data *data = container_of(rcdev, 924 - struct gates_reset_data, 925 - rcdev); 926 - unsigned long flags; 927 - u32 reg; 928 - 929 - spin_lock_irqsave(data->lock, flags); 930 - 931 - reg = readl(data->reg); 932 - writel(reg | BIT(id), data->reg); 933 - 934 - spin_unlock_irqrestore(data->lock, flags); 935 - 936 - return 0; 937 - } 938 - 939 - static struct reset_control_ops sunxi_gates_reset_ops = { 940 - .assert = sunxi_gates_reset_assert, 941 - .deassert = sunxi_gates_reset_deassert, 942 - }; 943 - 944 - /** 945 841 * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks 946 842 */ 947 843 ··· 896 898 897 899 struct gates_data { 898 900 DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); 899 - u32 reset_mask; 900 901 }; 901 902 902 903 static const struct gates_data sun4i_axi_gates_data __initconst = { ··· 994 997 .mask = {0x1F0007}, 995 998 }; 996 999 997 - static const struct gates_data sun4i_a10_usb_gates_data __initconst = { 998 - .mask = {0x1C0}, 999 - .reset_mask = 0x07, 1000 - }; 1001 - 1002 - static const struct gates_data sun5i_a13_usb_gates_data __initconst = { 1003 - .mask = {0x140}, 1004 - .reset_mask = 0x03, 1005 - }; 1006 - 1007 - static const struct gates_data sun6i_a31_usb_gates_data __initconst = { 1008 - .mask = { BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8) }, 1009 - .reset_mask = BIT(2) | BIT(1) | BIT(0), 1010 - }; 1011 - 1012 1000 static void __init sunxi_gates_clk_setup(struct device_node *node, 1013 1001 struct gates_data *data) 1014 1002 { 1015 1003 struct clk_onecell_data *clk_data; 1016 - struct gates_reset_data *reset_data; 1017 1004 const char *clk_parent; 1018 1005 const char *clk_name; 1019 1006 void __iomem *reg; ··· 1038 1057 clk_data->clk_num = i; 1039 1058 1040 1059 of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); 1041 - 1042 - /* Register a reset controler for gates with reset bits */ 1043 - if (data->reset_mask == 0) 1044 - return; 1045 - 1046 - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); 1047 - if (!reset_data) 1048 - return; 1049 - 1050 - reset_data->reg = reg; 1051 - reset_data->lock = &clk_lock; 1052 - reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1; 1053 - reset_data->rcdev.ops = &sunxi_gates_reset_ops; 1054 - reset_data->rcdev.of_node = node; 1055 - reset_controller_register(&reset_data->rcdev); 1056 1060 } 1057 1061 1058 1062 ··· 1046 1080 * sunxi_divs_clk_setup() helper data 1047 1081 */ 1048 1082 1049 - #define SUNXI_DIVS_MAX_QTY 2 1083 + #define SUNXI_DIVS_MAX_QTY 4 1050 1084 #define SUNXI_DIVISOR_WIDTH 2 1051 1085 1052 1086 struct divs_data { 1053 1087 const struct factors_data *factors; /* data for the factor clock */ 1054 - int ndivs; /* number of children */ 1088 + int ndivs; /* number of outputs */ 1089 + /* 1090 + * List of outputs. Refer to the diagram for sunxi_divs_clk_setup(): 1091 + * self or base factor clock refers to the output from the pll 1092 + * itself. The remaining refer to fixed or configurable divider 1093 + * outputs. 1094 + */ 1055 1095 struct { 1096 + u8 self; /* is it the base factor clock? (only one) */ 1056 1097 u8 fixed; /* is it a fixed divisor? if not... */ 1057 1098 struct clk_div_table *table; /* is it a table based divisor? */ 1058 1099 u8 shift; /* otherwise it's a normal divisor with this shift */ ··· 1082 1109 .div = { 1083 1110 { .shift = 0, .pow = 0, }, /* M, DDR */ 1084 1111 { .shift = 16, .pow = 1, }, /* P, other */ 1112 + /* No output for the base factor clock */ 1085 1113 } 1086 1114 }; 1087 1115 1088 1116 static const struct divs_data pll6_divs_data __initconst = { 1089 1117 .factors = &sun4i_pll6_data, 1090 - .ndivs = 2, 1118 + .ndivs = 4, 1091 1119 .div = { 1092 1120 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ 1093 1121 { .fixed = 2 }, /* P, other */ 1122 + { .self = 1 }, /* base factor clock, 2x */ 1123 + { .fixed = 4 }, /* pll6 / 4, used as ahb input */ 1094 1124 } 1095 1125 }; 1096 1126 1097 1127 static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { 1098 1128 .factors = &sun6i_a31_pll6_data, 1099 - .ndivs = 1, 1129 + .ndivs = 2, 1100 1130 .div = { 1101 1131 { .fixed = 2 }, /* normal output */ 1132 + { .self = 1 }, /* base factor clock, 2x */ 1102 1133 } 1103 1134 }; 1104 1135 ··· 1133 1156 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; 1134 1157 int flags, clkflags; 1135 1158 1159 + /* if number of children known, use it */ 1160 + if (data->ndivs) 1161 + ndivs = data->ndivs; 1162 + 1136 1163 /* Set up factor clock that we will be dividing */ 1137 1164 pclk = sunxi_factors_clk_setup(node, data->factors); 1138 1165 parent = __clk_get_name(pclk); ··· 1147 1166 if (!clk_data) 1148 1167 return; 1149 1168 1150 - clks = kzalloc((SUNXI_DIVS_MAX_QTY+1) * sizeof(*clks), GFP_KERNEL); 1169 + clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); 1151 1170 if (!clks) 1152 1171 goto free_clkdata; 1153 1172 ··· 1157 1176 * our RAM clock! */ 1158 1177 clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; 1159 1178 1160 - /* if number of children known, use it */ 1161 - if (data->ndivs) 1162 - ndivs = data->ndivs; 1163 - 1164 1179 for (i = 0; i < ndivs; i++) { 1165 1180 if (of_property_read_string_index(node, "clock-output-names", 1166 1181 i, &clk_name) != 0) 1167 1182 break; 1183 + 1184 + /* If this is the base factor clock, only update clks */ 1185 + if (data->div[i].self) { 1186 + clk_data->clks[i] = pclk; 1187 + continue; 1188 + } 1168 1189 1169 1190 gate_hw = NULL; 1170 1191 rate_hw = NULL; ··· 1226 1243 clk_register_clkdev(clks[i], clk_name, NULL); 1227 1244 } 1228 1245 1229 - /* The last clock available on the getter is the parent */ 1230 - clks[i++] = pclk; 1231 - 1232 1246 /* Adjust to the real max */ 1233 1247 clk_data->clk_num = i; 1234 1248 ··· 1249 1269 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, 1250 1270 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, 1251 1271 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, 1272 + {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,}, 1252 1273 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, 1253 1274 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, 1254 1275 {} ··· 1305 1324 {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,}, 1306 1325 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, 1307 1326 {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, 1308 - {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, 1309 - {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,}, 1310 - {.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,}, 1311 1327 {} 1312 1328 }; 1313 1329 ··· 1326 1348 { 1327 1349 unsigned int i; 1328 1350 1351 + /* Register divided output clocks */ 1352 + of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); 1353 + 1329 1354 /* Register factor clocks */ 1330 1355 of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); 1331 1356 1332 1357 /* Register divider clocks */ 1333 1358 of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); 1334 - 1335 - /* Register divided output clocks */ 1336 - of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); 1337 1359 1338 1360 /* Register mux clocks */ 1339 1361 of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); ··· 1363 1385 CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); 1364 1386 1365 1387 static const char *sun5i_critical_clocks[] __initdata = { 1388 + "cpu", 1366 1389 "pll5_ddr", 1367 1390 "ahb_sdram", 1368 1391 };
+233
drivers/clk/sunxi/clk-usb.c
··· 1 + /* 2 + * Copyright 2013-2015 Emilio López 3 + * 4 + * Emilio López <emilio@elopez.com.ar> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/clk-provider.h> 18 + #include <linux/clkdev.h> 19 + #include <linux/of.h> 20 + #include <linux/of_address.h> 21 + #include <linux/reset-controller.h> 22 + #include <linux/spinlock.h> 23 + 24 + 25 + /** 26 + * sunxi_usb_reset... - reset bits in usb clk registers handling 27 + */ 28 + 29 + struct usb_reset_data { 30 + void __iomem *reg; 31 + spinlock_t *lock; 32 + struct clk *clk; 33 + struct reset_controller_dev rcdev; 34 + }; 35 + 36 + static int sunxi_usb_reset_assert(struct reset_controller_dev *rcdev, 37 + unsigned long id) 38 + { 39 + struct usb_reset_data *data = container_of(rcdev, 40 + struct usb_reset_data, 41 + rcdev); 42 + unsigned long flags; 43 + u32 reg; 44 + 45 + clk_prepare_enable(data->clk); 46 + spin_lock_irqsave(data->lock, flags); 47 + 48 + reg = readl(data->reg); 49 + writel(reg & ~BIT(id), data->reg); 50 + 51 + spin_unlock_irqrestore(data->lock, flags); 52 + clk_disable_unprepare(data->clk); 53 + 54 + return 0; 55 + } 56 + 57 + static int sunxi_usb_reset_deassert(struct reset_controller_dev *rcdev, 58 + unsigned long id) 59 + { 60 + struct usb_reset_data *data = container_of(rcdev, 61 + struct usb_reset_data, 62 + rcdev); 63 + unsigned long flags; 64 + u32 reg; 65 + 66 + clk_prepare_enable(data->clk); 67 + spin_lock_irqsave(data->lock, flags); 68 + 69 + reg = readl(data->reg); 70 + writel(reg | BIT(id), data->reg); 71 + 72 + spin_unlock_irqrestore(data->lock, flags); 73 + clk_disable_unprepare(data->clk); 74 + 75 + return 0; 76 + } 77 + 78 + static struct reset_control_ops sunxi_usb_reset_ops = { 79 + .assert = sunxi_usb_reset_assert, 80 + .deassert = sunxi_usb_reset_deassert, 81 + }; 82 + 83 + /** 84 + * sunxi_usb_clk_setup() - Setup function for usb gate clocks 85 + */ 86 + 87 + #define SUNXI_USB_MAX_SIZE 32 88 + 89 + struct usb_clk_data { 90 + u32 clk_mask; 91 + u32 reset_mask; 92 + bool reset_needs_clk; 93 + }; 94 + 95 + static void __init sunxi_usb_clk_setup(struct device_node *node, 96 + const struct usb_clk_data *data, 97 + spinlock_t *lock) 98 + { 99 + struct clk_onecell_data *clk_data; 100 + struct usb_reset_data *reset_data; 101 + const char *clk_parent; 102 + const char *clk_name; 103 + void __iomem *reg; 104 + int qty; 105 + int i = 0; 106 + int j = 0; 107 + 108 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 109 + if (IS_ERR(reg)) 110 + return; 111 + 112 + clk_parent = of_clk_get_parent_name(node, 0); 113 + if (!clk_parent) 114 + return; 115 + 116 + /* Worst-case size approximation and memory allocation */ 117 + qty = find_last_bit((unsigned long *)&data->clk_mask, 118 + SUNXI_USB_MAX_SIZE); 119 + 120 + clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); 121 + if (!clk_data) 122 + return; 123 + 124 + clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL); 125 + if (!clk_data->clks) { 126 + kfree(clk_data); 127 + return; 128 + } 129 + 130 + for_each_set_bit(i, (unsigned long *)&data->clk_mask, 131 + SUNXI_USB_MAX_SIZE) { 132 + of_property_read_string_index(node, "clock-output-names", 133 + j, &clk_name); 134 + clk_data->clks[i] = clk_register_gate(NULL, clk_name, 135 + clk_parent, 0, 136 + reg, i, 0, lock); 137 + WARN_ON(IS_ERR(clk_data->clks[i])); 138 + 139 + j++; 140 + } 141 + 142 + /* Adjust to the real max */ 143 + clk_data->clk_num = i; 144 + 145 + of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); 146 + 147 + /* Register a reset controller for usb with reset bits */ 148 + if (data->reset_mask == 0) 149 + return; 150 + 151 + reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); 152 + if (!reset_data) 153 + return; 154 + 155 + if (data->reset_needs_clk) { 156 + reset_data->clk = of_clk_get(node, 0); 157 + if (IS_ERR(reset_data->clk)) { 158 + pr_err("Could not get clock for reset controls\n"); 159 + kfree(reset_data); 160 + return; 161 + } 162 + } 163 + 164 + reset_data->reg = reg; 165 + reset_data->lock = lock; 166 + reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1; 167 + reset_data->rcdev.ops = &sunxi_usb_reset_ops; 168 + reset_data->rcdev.of_node = node; 169 + reset_controller_register(&reset_data->rcdev); 170 + } 171 + 172 + static const struct usb_clk_data sun4i_a10_usb_clk_data __initconst = { 173 + .clk_mask = BIT(8) | BIT(7) | BIT(6), 174 + .reset_mask = BIT(2) | BIT(1) | BIT(0), 175 + }; 176 + 177 + static DEFINE_SPINLOCK(sun4i_a10_usb_lock); 178 + 179 + static void __init sun4i_a10_usb_setup(struct device_node *node) 180 + { 181 + sunxi_usb_clk_setup(node, &sun4i_a10_usb_clk_data, &sun4i_a10_usb_lock); 182 + } 183 + CLK_OF_DECLARE(sun4i_a10_usb, "allwinner,sun4i-a10-usb-clk", sun4i_a10_usb_setup); 184 + 185 + static const struct usb_clk_data sun5i_a13_usb_clk_data __initconst = { 186 + .clk_mask = BIT(8) | BIT(6), 187 + .reset_mask = BIT(1) | BIT(0), 188 + }; 189 + 190 + static void __init sun5i_a13_usb_setup(struct device_node *node) 191 + { 192 + sunxi_usb_clk_setup(node, &sun5i_a13_usb_clk_data, &sun4i_a10_usb_lock); 193 + } 194 + CLK_OF_DECLARE(sun5i_a13_usb, "allwinner,sun5i-a13-usb-clk", sun5i_a13_usb_setup); 195 + 196 + static const struct usb_clk_data sun6i_a31_usb_clk_data __initconst = { 197 + .clk_mask = BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8), 198 + .reset_mask = BIT(2) | BIT(1) | BIT(0), 199 + }; 200 + 201 + static void __init sun6i_a31_usb_setup(struct device_node *node) 202 + { 203 + sunxi_usb_clk_setup(node, &sun6i_a31_usb_clk_data, &sun4i_a10_usb_lock); 204 + } 205 + CLK_OF_DECLARE(sun6i_a31_usb, "allwinner,sun6i-a31-usb-clk", sun6i_a31_usb_setup); 206 + 207 + static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { 208 + .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), 209 + .reset_mask = BIT(19) | BIT(18) | BIT(17), 210 + .reset_needs_clk = 1, 211 + }; 212 + 213 + static DEFINE_SPINLOCK(a80_usb_mod_lock); 214 + 215 + static void __init sun9i_a80_usb_mod_setup(struct device_node *node) 216 + { 217 + sunxi_usb_clk_setup(node, &sun9i_a80_usb_mod_data, &a80_usb_mod_lock); 218 + } 219 + CLK_OF_DECLARE(sun9i_a80_usb_mod, "allwinner,sun9i-a80-usb-mod-clk", sun9i_a80_usb_mod_setup); 220 + 221 + static const struct usb_clk_data sun9i_a80_usb_phy_data __initconst = { 222 + .clk_mask = BIT(10) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), 223 + .reset_mask = BIT(21) | BIT(20) | BIT(19) | BIT(18) | BIT(17), 224 + .reset_needs_clk = 1, 225 + }; 226 + 227 + static DEFINE_SPINLOCK(a80_usb_phy_lock); 228 + 229 + static void __init sun9i_a80_usb_phy_setup(struct device_node *node) 230 + { 231 + sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); 232 + } 233 + CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup);