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

Merge tag 'vexpress-modules-for-soc-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux into arm/soc

VExpress modularization

This series enables building various Versatile Express platform drivers
as modules. The primary target is the Fast Model FVP which is supported
in Android. As Android is moving towards their GKI, or generic kernel,
the hardware support has to be in modules. Currently ARCH_VEXPRESS
enables several built-in only drivers. Some of these are needed, but
some are only needed for older 32-bit VExpress platforms and can just
be disabled.

* tag 'vexpress-modules-for-soc-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux:
ARM: vexpress: Don't select VEXPRESS_CONFIG
bus: vexpress-config: Support building as module
vexpress: Move setting master site to vexpress-config bus
bus: vexpress-config: simplify config bus probing
bus: vexpress-config: Merge vexpress-syscfg into vexpress-config
mfd: vexpress-sysreg: Support building as a module
mfd: vexpress-sysreg: Use devres API variants
mfd: vexpress-sysreg: Drop unused syscon child devices
mfd: vexpress-sysreg: Drop selecting CONFIG_CLKSRC_MMIO
clk: vexpress-osc: Support building as a module
clk: vexpress-osc: Use the devres clock API variants
clk: versatile: Only enable SP810 on 32-bit by default
clk: versatile: Rework kconfig structure
amba: Retry adding deferred devices at late_initcall
arm64: vexpress: Don't select CONFIG_POWER_RESET_VEXPRESS
ARM: vexpress: Move vexpress_flags_set() into arch code

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+371 -538
-1
arch/arm/mach-integrator/Kconfig
··· 3 3 bool "ARM Ltd. Integrator family" 4 4 depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 5 5 select ARM_AMBA 6 - select COMMON_CLK_VERSATILE 7 6 select CMA 8 7 select DMA_CMA 9 8 select HAVE_TCM
-1
arch/arm/mach-realview/Kconfig
··· 6 6 select ARM_GIC 7 7 select ARM_TIMER_SP804 8 8 select CLK_SP810 9 - select COMMON_CLK_VERSATILE 10 9 select GPIO_PL061 if GPIOLIB 11 10 select HAVE_ARM_SCU if SMP 12 11 select HAVE_ARM_TWD if SMP
-1
arch/arm/mach-versatile/Kconfig
··· 6 6 select ARM_TIMER_SP804 7 7 select ARM_VIC 8 8 select CLKSRC_VERSATILE 9 - select COMMON_CLK_VERSATILE 10 9 select CPU_ARM926T 11 10 select ICST 12 11 select MFD_SYSCON
-4
arch/arm/mach-vexpress/Kconfig
··· 7 7 select ARM_GIC 8 8 select ARM_GLOBAL_TIMER 9 9 select ARM_TIMER_SP804 10 - select COMMON_CLK_VERSATILE 11 10 select GPIOLIB 12 11 select HAVE_ARM_SCU if SMP 13 12 select HAVE_ARM_TWD if SMP ··· 19 20 select POWER_SUPPLY 20 21 select REGULATOR if MMC_ARMMMCI 21 22 select REGULATOR_FIXED_VOLTAGE if REGULATOR 22 - select VEXPRESS_CONFIG 23 - select VEXPRESS_SYSCFG 24 - select MFD_VEXPRESS_SYSREG 25 23 help 26 24 This option enables support for systems using Cortex processor based 27 25 ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
+1
arch/arm/mach-vexpress/core.h
··· 1 1 bool vexpress_smp_init_ops(void); 2 + void vexpress_flags_set(u32 data); 2 3 3 4 extern const struct smp_operations vexpress_smp_dt_ops;
+1
arch/arm/mach-vexpress/dcscb.c
··· 20 20 #include <asm/cputype.h> 21 21 #include <asm/cp15.h> 22 22 23 + #include "core.h" 23 24 24 25 #define RST_HOLD0 0x0 25 26 #define RST_HOLD1 0x4
+23
arch/arm/mach-vexpress/v2m.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/of.h> 3 + #include <linux/of_address.h> 2 4 #include <asm/mach/arch.h> 3 5 4 6 #include "core.h" 7 + 8 + #define SYS_FLAGSSET 0x030 9 + #define SYS_FLAGSCLR 0x034 10 + 11 + void vexpress_flags_set(u32 data) 12 + { 13 + static void __iomem *base; 14 + 15 + if (!base) { 16 + struct device_node *node = of_find_compatible_node(NULL, NULL, 17 + "arm,vexpress-sysreg"); 18 + 19 + base = of_iomap(node, 0); 20 + } 21 + 22 + if (WARN_ON(!base)) 23 + return; 24 + 25 + writel(~0, base + SYS_FLAGSCLR); 26 + writel(data, base + SYS_FLAGSSET); 27 + } 5 28 6 29 static const char * const v2m_dt_match[] __initconst = { 7 30 "arm,vexpress",
-3
arch/arm64/Kconfig.platforms
··· 274 274 275 275 config ARCH_VEXPRESS 276 276 bool "ARMv8 software model (Versatile Express)" 277 - select COMMON_CLK_VERSATILE 278 277 select GPIOLIB 279 278 select PM 280 279 select PM_GENERIC_DOMAINS 281 - select POWER_RESET_VEXPRESS 282 - select VEXPRESS_CONFIG 283 280 help 284 281 This enables support for the ARMv8 software model (Versatile 285 282 Express).
+11 -3
drivers/amba/bus.c
··· 505 505 506 506 #define DEFERRED_DEVICE_TIMEOUT (msecs_to_jiffies(5 * 1000)) 507 507 508 - static void amba_deferred_retry_func(struct work_struct *dummy) 508 + static int amba_deferred_retry(void) 509 509 { 510 510 struct deferred_device *ddev, *tmp; 511 511 ··· 521 521 kfree(ddev); 522 522 } 523 523 524 + mutex_unlock(&deferred_devices_lock); 525 + 526 + return 0; 527 + } 528 + late_initcall(amba_deferred_retry); 529 + 530 + static void amba_deferred_retry_func(struct work_struct *dummy) 531 + { 532 + amba_deferred_retry(); 533 + 524 534 if (!list_empty(&deferred_devices)) 525 535 schedule_delayed_work(&deferred_retry_work, 526 536 DEFERRED_DEVICE_TIMEOUT); 527 - 528 - mutex_unlock(&deferred_devices_lock); 529 537 } 530 538 531 539 /**
+1 -1
drivers/bus/Kconfig
··· 192 192 needed to use on-board devices connected to UniPhier SoCs. 193 193 194 194 config VEXPRESS_CONFIG 195 - bool "Versatile Express configuration bus" 195 + tristate "Versatile Express configuration bus" 196 196 default y if ARCH_VEXPRESS 197 197 depends on ARM || ARM64 198 198 depends on OF
+301 -85
drivers/bus/vexpress-config.c
··· 6 6 7 7 #include <linux/err.h> 8 8 #include <linux/init.h> 9 + #include <linux/io.h> 10 + #include <linux/module.h> 9 11 #include <linux/of.h> 12 + #include <linux/platform_device.h> 10 13 #include <linux/of_device.h> 14 + #include <linux/sched/signal.h> 15 + #include <linux/slab.h> 11 16 #include <linux/vexpress.h> 12 17 18 + #define SYS_MISC 0x0 19 + #define SYS_MISC_MASTERSITE (1 << 14) 20 + 21 + #define SYS_PROCID0 0x24 22 + #define SYS_PROCID1 0x28 23 + #define SYS_HBI_MASK 0xfff 24 + #define SYS_PROCIDx_HBI_SHIFT 0 25 + 26 + #define SYS_CFGDATA 0x40 27 + 28 + #define SYS_CFGCTRL 0x44 29 + #define SYS_CFGCTRL_START (1 << 31) 30 + #define SYS_CFGCTRL_WRITE (1 << 30) 31 + #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26) 32 + #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20) 33 + #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16) 34 + #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12) 35 + #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0) 36 + 37 + #define SYS_CFGSTAT 0x48 38 + #define SYS_CFGSTAT_ERR (1 << 1) 39 + #define SYS_CFGSTAT_COMPLETE (1 << 0) 40 + 41 + #define VEXPRESS_SITE_MB 0 42 + #define VEXPRESS_SITE_DB1 1 43 + #define VEXPRESS_SITE_DB2 2 44 + #define VEXPRESS_SITE_MASTER 0xf 45 + 46 + struct vexpress_syscfg { 47 + struct device *dev; 48 + void __iomem *base; 49 + struct list_head funcs; 50 + }; 51 + 52 + struct vexpress_syscfg_func { 53 + struct list_head list; 54 + struct vexpress_syscfg *syscfg; 55 + struct regmap *regmap; 56 + int num_templates; 57 + u32 template[]; /* Keep it last! */ 58 + }; 59 + 60 + struct vexpress_config_bridge_ops { 61 + struct regmap * (*regmap_init)(struct device *dev, void *context); 62 + void (*regmap_exit)(struct regmap *regmap, void *context); 63 + }; 13 64 14 65 struct vexpress_config_bridge { 15 66 struct vexpress_config_bridge_ops *ops; ··· 69 18 70 19 71 20 static DEFINE_MUTEX(vexpress_config_mutex); 72 - static struct class *vexpress_config_class; 73 21 static u32 vexpress_config_site_master = VEXPRESS_SITE_MASTER; 74 22 75 23 76 - void vexpress_config_set_master(u32 site) 24 + static void vexpress_config_set_master(u32 site) 77 25 { 78 26 vexpress_config_site_master = site; 79 27 } 80 28 81 - u32 vexpress_config_get_master(void) 82 - { 83 - return vexpress_config_site_master; 84 - } 85 - 86 - void vexpress_config_lock(void *arg) 29 + static void vexpress_config_lock(void *arg) 87 30 { 88 31 mutex_lock(&vexpress_config_mutex); 89 32 } 90 33 91 - void vexpress_config_unlock(void *arg) 34 + static void vexpress_config_unlock(void *arg) 92 35 { 93 36 mutex_unlock(&vexpress_config_mutex); 94 37 } ··· 104 59 } 105 60 } 106 61 107 - int vexpress_config_get_topo(struct device_node *node, u32 *site, 62 + static int vexpress_config_get_topo(struct device_node *node, u32 *site, 108 63 u32 *position, u32 *dcc) 109 64 { 110 65 vexpress_config_find_prop(node, "arm,vexpress,site", site); ··· 133 88 struct regmap *regmap; 134 89 struct regmap **res; 135 90 136 - if (WARN_ON(dev->parent->class != vexpress_config_class)) 137 - return ERR_PTR(-ENODEV); 138 - 139 91 bridge = dev_get_drvdata(dev->parent); 140 92 if (WARN_ON(!bridge)) 141 93 return ERR_PTR(-EINVAL); ··· 155 113 } 156 114 EXPORT_SYMBOL_GPL(devm_regmap_init_vexpress_config); 157 115 158 - struct device *vexpress_config_bridge_register(struct device *parent, 159 - struct vexpress_config_bridge_ops *ops, void *context) 116 + static int vexpress_syscfg_exec(struct vexpress_syscfg_func *func, 117 + int index, bool write, u32 *data) 160 118 { 161 - struct device *dev; 162 - struct vexpress_config_bridge *bridge; 119 + struct vexpress_syscfg *syscfg = func->syscfg; 120 + u32 command, status; 121 + int tries; 122 + long timeout; 163 123 164 - if (!vexpress_config_class) { 165 - vexpress_config_class = class_create(THIS_MODULE, 166 - "vexpress-config"); 167 - if (IS_ERR(vexpress_config_class)) 168 - return (void *)vexpress_config_class; 169 - } 170 - 171 - dev = device_create(vexpress_config_class, parent, 0, 172 - NULL, "%s.bridge", dev_name(parent)); 173 - 174 - if (IS_ERR(dev)) 175 - return dev; 176 - 177 - bridge = devm_kmalloc(dev, sizeof(*bridge), GFP_KERNEL); 178 - if (!bridge) { 179 - put_device(dev); 180 - device_unregister(dev); 181 - return ERR_PTR(-ENOMEM); 182 - } 183 - bridge->ops = ops; 184 - bridge->context = context; 185 - 186 - dev_set_drvdata(dev, bridge); 187 - 188 - dev_dbg(parent, "Registered bridge '%s', parent node %p\n", 189 - dev_name(dev), parent->of_node); 190 - 191 - return dev; 192 - } 193 - 194 - 195 - static int vexpress_config_node_match(struct device *dev, const void *data) 196 - { 197 - const struct device_node *node = data; 198 - 199 - dev_dbg(dev, "Parent node %p, looking for %p\n", 200 - dev->parent->of_node, node); 201 - 202 - return dev->parent->of_node == node; 203 - } 204 - 205 - static int vexpress_config_populate(struct device_node *node) 206 - { 207 - struct device_node *bridge; 208 - struct device *parent; 209 - int ret; 210 - 211 - bridge = of_parse_phandle(node, "arm,vexpress,config-bridge", 0); 212 - if (!bridge) 124 + if (WARN_ON(index >= func->num_templates)) 213 125 return -EINVAL; 214 126 215 - parent = class_find_device(vexpress_config_class, NULL, bridge, 216 - vexpress_config_node_match); 217 - of_node_put(bridge); 218 - if (WARN_ON(!parent)) 219 - return -ENODEV; 127 + command = readl(syscfg->base + SYS_CFGCTRL); 128 + if (WARN_ON(command & SYS_CFGCTRL_START)) 129 + return -EBUSY; 220 130 221 - ret = of_platform_populate(node, NULL, NULL, parent); 131 + command = func->template[index]; 132 + command |= SYS_CFGCTRL_START; 133 + command |= write ? SYS_CFGCTRL_WRITE : 0; 222 134 223 - put_device(parent); 135 + /* Use a canary for reads */ 136 + if (!write) 137 + *data = 0xdeadbeef; 224 138 225 - return ret; 139 + dev_dbg(syscfg->dev, "func %p, command %x, data %x\n", 140 + func, command, *data); 141 + writel(*data, syscfg->base + SYS_CFGDATA); 142 + writel(0, syscfg->base + SYS_CFGSTAT); 143 + writel(command, syscfg->base + SYS_CFGCTRL); 144 + mb(); 145 + 146 + /* The operation can take ages... Go to sleep, 100us initially */ 147 + tries = 100; 148 + timeout = 100; 149 + do { 150 + if (!irqs_disabled()) { 151 + set_current_state(TASK_INTERRUPTIBLE); 152 + schedule_timeout(usecs_to_jiffies(timeout)); 153 + if (signal_pending(current)) 154 + return -EINTR; 155 + } else { 156 + udelay(timeout); 157 + } 158 + 159 + status = readl(syscfg->base + SYS_CFGSTAT); 160 + if (status & SYS_CFGSTAT_ERR) 161 + return -EFAULT; 162 + 163 + if (timeout > 20) 164 + timeout -= 20; 165 + } while (--tries && !(status & SYS_CFGSTAT_COMPLETE)); 166 + if (WARN_ON_ONCE(!tries)) 167 + return -ETIMEDOUT; 168 + 169 + if (!write) { 170 + *data = readl(syscfg->base + SYS_CFGDATA); 171 + dev_dbg(syscfg->dev, "func %p, read data %x\n", func, *data); 172 + } 173 + 174 + return 0; 226 175 } 227 176 228 - static int __init vexpress_config_init(void) 177 + static int vexpress_syscfg_read(void *context, unsigned int index, 178 + unsigned int *val) 229 179 { 230 - int err = 0; 231 - struct device_node *node; 180 + struct vexpress_syscfg_func *func = context; 232 181 233 - /* Need the config devices early, before the "normal" devices... */ 234 - for_each_compatible_node(node, NULL, "arm,vexpress,config-bus") { 235 - err = vexpress_config_populate(node); 236 - if (err) { 237 - of_node_put(node); 182 + return vexpress_syscfg_exec(func, index, false, val); 183 + } 184 + 185 + static int vexpress_syscfg_write(void *context, unsigned int index, 186 + unsigned int val) 187 + { 188 + struct vexpress_syscfg_func *func = context; 189 + 190 + return vexpress_syscfg_exec(func, index, true, &val); 191 + } 192 + 193 + static struct regmap_config vexpress_syscfg_regmap_config = { 194 + .lock = vexpress_config_lock, 195 + .unlock = vexpress_config_unlock, 196 + .reg_bits = 32, 197 + .val_bits = 32, 198 + .reg_read = vexpress_syscfg_read, 199 + .reg_write = vexpress_syscfg_write, 200 + .reg_format_endian = REGMAP_ENDIAN_LITTLE, 201 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 202 + }; 203 + 204 + 205 + static struct regmap *vexpress_syscfg_regmap_init(struct device *dev, 206 + void *context) 207 + { 208 + int err; 209 + struct vexpress_syscfg *syscfg = context; 210 + struct vexpress_syscfg_func *func; 211 + struct property *prop; 212 + const __be32 *val = NULL; 213 + __be32 energy_quirk[4]; 214 + int num; 215 + u32 site, position, dcc; 216 + int i; 217 + 218 + err = vexpress_config_get_topo(dev->of_node, &site, 219 + &position, &dcc); 220 + if (err) 221 + return ERR_PTR(err); 222 + 223 + prop = of_find_property(dev->of_node, 224 + "arm,vexpress-sysreg,func", NULL); 225 + if (!prop) 226 + return ERR_PTR(-EINVAL); 227 + 228 + num = prop->length / sizeof(u32) / 2; 229 + val = prop->value; 230 + 231 + /* 232 + * "arm,vexpress-energy" function used to be described 233 + * by its first device only, now it requires both 234 + */ 235 + if (num == 1 && of_device_is_compatible(dev->of_node, 236 + "arm,vexpress-energy")) { 237 + num = 2; 238 + energy_quirk[0] = *val; 239 + energy_quirk[2] = *val++; 240 + energy_quirk[1] = *val; 241 + energy_quirk[3] = cpu_to_be32(be32_to_cpup(val) + 1); 242 + val = energy_quirk; 243 + } 244 + 245 + func = kzalloc(struct_size(func, template, num), GFP_KERNEL); 246 + if (!func) 247 + return ERR_PTR(-ENOMEM); 248 + 249 + func->syscfg = syscfg; 250 + func->num_templates = num; 251 + 252 + for (i = 0; i < num; i++) { 253 + u32 function, device; 254 + 255 + function = be32_to_cpup(val++); 256 + device = be32_to_cpup(val++); 257 + 258 + dev_dbg(dev, "func %p: %u/%u/%u/%u/%u\n", 259 + func, site, position, dcc, 260 + function, device); 261 + 262 + func->template[i] = SYS_CFGCTRL_DCC(dcc); 263 + func->template[i] |= SYS_CFGCTRL_SITE(site); 264 + func->template[i] |= SYS_CFGCTRL_POSITION(position); 265 + func->template[i] |= SYS_CFGCTRL_FUNC(function); 266 + func->template[i] |= SYS_CFGCTRL_DEVICE(device); 267 + } 268 + 269 + vexpress_syscfg_regmap_config.max_register = num - 1; 270 + 271 + func->regmap = regmap_init(dev, NULL, func, 272 + &vexpress_syscfg_regmap_config); 273 + 274 + if (IS_ERR(func->regmap)) { 275 + void *err = func->regmap; 276 + 277 + kfree(func); 278 + return err; 279 + } 280 + 281 + list_add(&func->list, &syscfg->funcs); 282 + 283 + return func->regmap; 284 + } 285 + 286 + static void vexpress_syscfg_regmap_exit(struct regmap *regmap, void *context) 287 + { 288 + struct vexpress_syscfg *syscfg = context; 289 + struct vexpress_syscfg_func *func, *tmp; 290 + 291 + regmap_exit(regmap); 292 + 293 + list_for_each_entry_safe(func, tmp, &syscfg->funcs, list) { 294 + if (func->regmap == regmap) { 295 + list_del(&syscfg->funcs); 296 + kfree(func); 238 297 break; 239 298 } 240 299 } 241 - 242 - return err; 243 300 } 244 - postcore_initcall(vexpress_config_init); 245 301 302 + static struct vexpress_config_bridge_ops vexpress_syscfg_bridge_ops = { 303 + .regmap_init = vexpress_syscfg_regmap_init, 304 + .regmap_exit = vexpress_syscfg_regmap_exit, 305 + }; 306 + 307 + 308 + static int vexpress_syscfg_probe(struct platform_device *pdev) 309 + { 310 + struct vexpress_syscfg *syscfg; 311 + struct resource *res; 312 + struct vexpress_config_bridge *bridge; 313 + struct device_node *node; 314 + int master; 315 + u32 dt_hbi; 316 + 317 + syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL); 318 + if (!syscfg) 319 + return -ENOMEM; 320 + syscfg->dev = &pdev->dev; 321 + INIT_LIST_HEAD(&syscfg->funcs); 322 + 323 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 324 + syscfg->base = devm_ioremap_resource(&pdev->dev, res); 325 + if (IS_ERR(syscfg->base)) 326 + return PTR_ERR(syscfg->base); 327 + 328 + bridge = devm_kmalloc(&pdev->dev, sizeof(*bridge), GFP_KERNEL); 329 + if (!bridge) 330 + return -ENOMEM; 331 + 332 + bridge->ops = &vexpress_syscfg_bridge_ops; 333 + bridge->context = syscfg; 334 + 335 + dev_set_drvdata(&pdev->dev, bridge); 336 + 337 + master = readl(syscfg->base + SYS_MISC) & SYS_MISC_MASTERSITE ? 338 + VEXPRESS_SITE_DB2 : VEXPRESS_SITE_DB1; 339 + vexpress_config_set_master(master); 340 + 341 + /* Confirm board type against DT property, if available */ 342 + if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) { 343 + u32 id = readl(syscfg->base + (master == VEXPRESS_SITE_DB1 ? 344 + SYS_PROCID0 : SYS_PROCID1)); 345 + u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; 346 + 347 + if (WARN_ON(dt_hbi != hbi)) 348 + dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n", 349 + dt_hbi, hbi); 350 + } 351 + 352 + for_each_compatible_node(node, NULL, "arm,vexpress,config-bus") { 353 + struct device_node *bridge_np; 354 + 355 + bridge_np = of_parse_phandle(node, "arm,vexpress,config-bridge", 0); 356 + if (bridge_np != pdev->dev.parent->of_node) 357 + continue; 358 + 359 + of_platform_populate(node, NULL, NULL, &pdev->dev); 360 + } 361 + 362 + return 0; 363 + } 364 + 365 + static const struct platform_device_id vexpress_syscfg_id_table[] = { 366 + { "vexpress-syscfg", }, 367 + {}, 368 + }; 369 + MODULE_DEVICE_TABLE(platform, vexpress_syscfg_id_table); 370 + 371 + static struct platform_driver vexpress_syscfg_driver = { 372 + .driver.name = "vexpress-syscfg", 373 + .id_table = vexpress_syscfg_id_table, 374 + .probe = vexpress_syscfg_probe, 375 + }; 376 + module_platform_driver(vexpress_syscfg_driver); 377 + MODULE_LICENSE("GPL v2");
+1 -1
drivers/clk/Makefile
··· 114 114 obj-y += ti/ 115 115 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ 116 116 obj-$(CONFIG_ARCH_U8500) += ux500/ 117 - obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 117 + obj-y += versatile/ 118 118 ifeq ($(CONFIG_COMMON_CLK), y) 119 119 obj-$(CONFIG_X86) += x86/ 120 120 endif
+14 -12
drivers/clk/versatile/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - config ICST 3 - bool 4 2 5 - config COMMON_CLK_VERSATILE 6 - bool "Clock driver for ARM Reference designs" 7 - depends on ARCH_INTEGRATOR || ARCH_REALVIEW || \ 8 - ARCH_VERSATILE || ARCH_VEXPRESS || ARM64 || \ 9 - COMPILE_TEST 3 + menuconfig COMMON_CLK_VERSATILE 4 + bool "Clock driver for ARM Reference designs" if COMPILE_TEST 5 + default y if ARCH_INTEGRATOR || ARCH_REALVIEW || \ 6 + ARCH_VERSATILE || ARCH_VEXPRESS 7 + 8 + if COMMON_CLK_VERSATILE 9 + 10 + config ICST 11 + bool "Clock driver for ARM Reference designs ICST" 10 12 select REGMAP_MMIO 11 13 ---help--- 12 14 Supports clocking on ARM Reference designs: 13 15 - Integrator/AP and Integrator/CP 14 16 - RealView PB1176, EB, PB11MP and PBX 15 - - Versatile Express 16 17 17 18 config CLK_SP810 18 19 bool "Clock driver for ARM SP810 System Controller" 19 - depends on COMMON_CLK_VERSATILE 20 - default y if ARCH_VEXPRESS 20 + default y if (ARCH_VEXPRESS && ARM) 21 21 ---help--- 22 22 Supports clock muxing (REFCLK/TIMCLK to TIMERCLKEN0-3) capabilities 23 23 of the ARM SP810 System Controller cell. 24 24 25 25 config CLK_VEXPRESS_OSC 26 - bool "Clock driver for Versatile Express OSC clock generators" 27 - depends on COMMON_CLK_VERSATILE 26 + tristate "Clock driver for Versatile Express OSC clock generators" 28 27 depends on VEXPRESS_CONFIG 28 + select REGMAP_MMIO 29 29 default y if ARCH_VEXPRESS 30 30 ---help--- 31 31 Simple regmap-based driver driving clock generators on Versatile 32 32 Express platforms hidden behind its configuration infrastructure, 33 33 commonly known as OSCs. 34 + 35 + endif
+9 -11
drivers/clk/versatile/clk-vexpress-osc.c
··· 7 7 #include <linux/clkdev.h> 8 8 #include <linux/clk-provider.h> 9 9 #include <linux/err.h> 10 + #include <linux/module.h> 10 11 #include <linux/of.h> 11 12 #include <linux/platform_device.h> 12 13 #include <linux/slab.h> ··· 66 65 { 67 66 struct clk_init_data init; 68 67 struct vexpress_osc *osc; 69 - struct clk *clk; 70 68 u32 range[2]; 69 + int ret; 71 70 72 71 osc = devm_kzalloc(&pdev->dev, sizeof(*osc), GFP_KERNEL); 73 72 if (!osc) ··· 93 92 94 93 osc->hw.init = &init; 95 94 96 - clk = clk_register(NULL, &osc->hw); 97 - if (IS_ERR(clk)) 98 - return PTR_ERR(clk); 95 + ret = devm_clk_hw_register(&pdev->dev, &osc->hw); 96 + if (ret < 0) 97 + return ret; 99 98 100 - of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk); 99 + devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, &osc->hw); 101 100 clk_hw_set_rate_range(&osc->hw, osc->rate_min, osc->rate_max); 102 101 103 102 dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name); ··· 109 108 { .compatible = "arm,vexpress-osc", }, 110 109 {} 111 110 }; 111 + MODULE_DEVICE_TABLE(of, vexpress_osc_of_match); 112 112 113 113 static struct platform_driver vexpress_osc_driver = { 114 114 .driver = { ··· 118 116 }, 119 117 .probe = vexpress_osc_probe, 120 118 }; 121 - 122 - static int __init vexpress_osc_init(void) 123 - { 124 - return platform_driver_register(&vexpress_osc_driver); 125 - } 126 - core_initcall(vexpress_osc_init); 119 + module_platform_driver(vexpress_osc_driver); 120 + MODULE_LICENSE("GPL v2");
+2 -3
drivers/mfd/Kconfig
··· 2028 2028 endmenu 2029 2029 2030 2030 config MFD_VEXPRESS_SYSREG 2031 - bool "Versatile Express System Registers" 2032 - depends on VEXPRESS_CONFIG && GPIOLIB && !ARCH_USES_GETTIMEOFFSET 2031 + tristate "Versatile Express System Registers" 2032 + depends on VEXPRESS_CONFIG && GPIOLIB 2033 2033 default y 2034 - select CLKSRC_MMIO 2035 2034 select GPIO_GENERIC_PLATFORM 2036 2035 select MFD_CORE 2037 2036 select MFD_SYSCON
+7 -92
drivers/mfd/vexpress-sysreg.c
··· 8 8 #include <linux/err.h> 9 9 #include <linux/io.h> 10 10 #include <linux/mfd/core.h> 11 - #include <linux/of_address.h> 11 + #include <linux/module.h> 12 12 #include <linux/of_platform.h> 13 13 #include <linux/platform_data/syscon.h> 14 14 #include <linux/platform_device.h> 15 15 #include <linux/slab.h> 16 16 #include <linux/stat.h> 17 - #include <linux/vexpress.h> 18 17 19 18 #define SYS_ID 0x000 20 19 #define SYS_SW 0x004 ··· 36 37 #define SYS_CFGCTRL 0x0a4 37 38 #define SYS_CFGSTAT 0x0a8 38 39 39 - #define SYS_HBI_MASK 0xfff 40 - #define SYS_PROCIDx_HBI_SHIFT 0 41 - 42 - #define SYS_MISC_MASTERSITE (1 << 14) 43 - 44 - void vexpress_flags_set(u32 data) 45 - { 46 - static void __iomem *base; 47 - 48 - if (!base) { 49 - struct device_node *node = of_find_compatible_node(NULL, NULL, 50 - "arm,vexpress-sysreg"); 51 - 52 - base = of_iomap(node, 0); 53 - } 54 - 55 - if (WARN_ON(!base)) 56 - return; 57 - 58 - writel(~0, base + SYS_FLAGSCLR); 59 - writel(data, base + SYS_FLAGSSET); 60 - } 61 - 62 40 /* The sysreg block is just a random collection of various functions... */ 63 - 64 - static struct syscon_platform_data vexpress_sysreg_sys_id_pdata = { 65 - .label = "sys_id", 66 - }; 67 41 68 42 static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = { 69 43 .label = "sys_led", ··· 56 84 .ngpio = 1, 57 85 }; 58 86 59 - static struct syscon_platform_data vexpress_sysreg_sys_misc_pdata = { 60 - .label = "sys_misc", 61 - }; 62 - 63 - static struct syscon_platform_data vexpress_sysreg_sys_procid_pdata = { 64 - .label = "sys_procid", 65 - }; 66 - 67 87 static struct mfd_cell vexpress_sysreg_cells[] = { 68 88 { 69 - .name = "syscon", 70 - .num_resources = 1, 71 - .resources = (struct resource []) { 72 - DEFINE_RES_MEM(SYS_ID, 0x4), 73 - }, 74 - .platform_data = &vexpress_sysreg_sys_id_pdata, 75 - .pdata_size = sizeof(vexpress_sysreg_sys_id_pdata), 76 - }, { 77 89 .name = "basic-mmio-gpio", 78 90 .of_compatible = "arm,vexpress-sysreg,sys_led", 79 91 .num_resources = 1, ··· 85 129 .platform_data = &vexpress_sysreg_sys_flash_pdata, 86 130 .pdata_size = sizeof(vexpress_sysreg_sys_flash_pdata), 87 131 }, { 88 - .name = "syscon", 89 - .num_resources = 1, 90 - .resources = (struct resource []) { 91 - DEFINE_RES_MEM(SYS_MISC, 0x4), 92 - }, 93 - .platform_data = &vexpress_sysreg_sys_misc_pdata, 94 - .pdata_size = sizeof(vexpress_sysreg_sys_misc_pdata), 95 - }, { 96 - .name = "syscon", 97 - .num_resources = 1, 98 - .resources = (struct resource []) { 99 - DEFINE_RES_MEM(SYS_PROCID0, 0x8), 100 - }, 101 - .platform_data = &vexpress_sysreg_sys_procid_pdata, 102 - .pdata_size = sizeof(vexpress_sysreg_sys_procid_pdata), 103 - }, { 104 132 .name = "vexpress-syscfg", 105 133 .num_resources = 1, 106 134 .resources = (struct resource []) { 107 - DEFINE_RES_MEM(SYS_CFGDATA, 0xc), 135 + DEFINE_RES_MEM(SYS_MISC, 0x4c), 108 136 }, 109 137 } 110 138 }; ··· 98 158 struct resource *mem; 99 159 void __iomem *base; 100 160 struct gpio_chip *mmc_gpio_chip; 101 - int master; 102 - u32 dt_hbi; 103 161 104 162 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 105 163 if (!mem) ··· 106 168 base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 107 169 if (!base) 108 170 return -ENOMEM; 109 - 110 - master = readl(base + SYS_MISC) & SYS_MISC_MASTERSITE ? 111 - VEXPRESS_SITE_DB2 : VEXPRESS_SITE_DB1; 112 - vexpress_config_set_master(master); 113 - 114 - /* Confirm board type against DT property, if available */ 115 - if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) { 116 - u32 id = readl(base + (master == VEXPRESS_SITE_DB1 ? 117 - SYS_PROCID0 : SYS_PROCID1)); 118 - u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; 119 - 120 - if (WARN_ON(dt_hbi != hbi)) 121 - dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n", 122 - dt_hbi, hbi); 123 - } 124 171 125 172 /* 126 173 * Duplicated SYS_MCI pseudo-GPIO controller for compatibility with ··· 118 195 bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI, 119 196 NULL, NULL, NULL, NULL, 0); 120 197 mmc_gpio_chip->ngpio = 2; 121 - gpiochip_add_data(mmc_gpio_chip, NULL); 198 + devm_gpiochip_add_data(&pdev->dev, mmc_gpio_chip, NULL); 122 199 123 - return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, 200 + return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, 124 201 vexpress_sysreg_cells, 125 202 ARRAY_SIZE(vexpress_sysreg_cells), mem, 0, NULL); 126 203 } ··· 129 206 { .compatible = "arm,vexpress-sysreg", }, 130 207 {}, 131 208 }; 209 + MODULE_DEVICE_TABLE(of, vexpress_sysreg_match); 132 210 133 211 static struct platform_driver vexpress_sysreg_driver = { 134 212 .driver = { ··· 139 215 .probe = vexpress_sysreg_probe, 140 216 }; 141 217 142 - static int __init vexpress_sysreg_init(void) 143 - { 144 - struct device_node *node; 145 - 146 - /* Need the sysreg early, before any other device... */ 147 - for_each_matching_node(node, vexpress_sysreg_match) 148 - of_platform_device_create(node, NULL, NULL); 149 - 150 - return platform_driver_register(&vexpress_sysreg_driver); 151 - } 152 - core_initcall(vexpress_sysreg_init); 218 + module_platform_driver(vexpress_sysreg_driver); 219 + MODULE_LICENSE("GPL v2");
-9
drivers/misc/Kconfig
··· 423 423 config SRAM_EXEC 424 424 bool 425 425 426 - config VEXPRESS_SYSCFG 427 - bool "Versatile Express System Configuration driver" 428 - depends on VEXPRESS_CONFIG 429 - default y 430 - help 431 - ARM Ltd. Versatile Express uses specialised platform configuration 432 - bus. System Configuration interface is one of the possible means 433 - of generating transactions on this bus. 434 - 435 426 config PCI_ENDPOINT_TEST 436 427 depends on PCI 437 428 select CRC32
-1
drivers/misc/Makefile
··· 49 49 obj-y += mic/ 50 50 obj-$(CONFIG_GENWQE) += genwqe/ 51 51 obj-$(CONFIG_ECHO) += echo/ 52 - obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o 53 52 obj-$(CONFIG_CXL_BASE) += cxl/ 54 53 obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o 55 54 obj-$(CONFIG_OCXL) += ocxl/
-280
drivers/misc/vexpress-syscfg.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * 4 - * Copyright (C) 2014 ARM Limited 5 - */ 6 - 7 - #include <linux/delay.h> 8 - #include <linux/err.h> 9 - #include <linux/io.h> 10 - #include <linux/of.h> 11 - #include <linux/platform_device.h> 12 - #include <linux/sched/signal.h> 13 - #include <linux/slab.h> 14 - #include <linux/syscore_ops.h> 15 - #include <linux/vexpress.h> 16 - 17 - 18 - #define SYS_CFGDATA 0x0 19 - 20 - #define SYS_CFGCTRL 0x4 21 - #define SYS_CFGCTRL_START (1 << 31) 22 - #define SYS_CFGCTRL_WRITE (1 << 30) 23 - #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26) 24 - #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20) 25 - #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16) 26 - #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12) 27 - #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0) 28 - 29 - #define SYS_CFGSTAT 0x8 30 - #define SYS_CFGSTAT_ERR (1 << 1) 31 - #define SYS_CFGSTAT_COMPLETE (1 << 0) 32 - 33 - 34 - struct vexpress_syscfg { 35 - struct device *dev; 36 - void __iomem *base; 37 - struct list_head funcs; 38 - }; 39 - 40 - struct vexpress_syscfg_func { 41 - struct list_head list; 42 - struct vexpress_syscfg *syscfg; 43 - struct regmap *regmap; 44 - int num_templates; 45 - u32 template[]; /* Keep it last! */ 46 - }; 47 - 48 - 49 - static int vexpress_syscfg_exec(struct vexpress_syscfg_func *func, 50 - int index, bool write, u32 *data) 51 - { 52 - struct vexpress_syscfg *syscfg = func->syscfg; 53 - u32 command, status; 54 - int tries; 55 - long timeout; 56 - 57 - if (WARN_ON(index >= func->num_templates)) 58 - return -EINVAL; 59 - 60 - command = readl(syscfg->base + SYS_CFGCTRL); 61 - if (WARN_ON(command & SYS_CFGCTRL_START)) 62 - return -EBUSY; 63 - 64 - command = func->template[index]; 65 - command |= SYS_CFGCTRL_START; 66 - command |= write ? SYS_CFGCTRL_WRITE : 0; 67 - 68 - /* Use a canary for reads */ 69 - if (!write) 70 - *data = 0xdeadbeef; 71 - 72 - dev_dbg(syscfg->dev, "func %p, command %x, data %x\n", 73 - func, command, *data); 74 - writel(*data, syscfg->base + SYS_CFGDATA); 75 - writel(0, syscfg->base + SYS_CFGSTAT); 76 - writel(command, syscfg->base + SYS_CFGCTRL); 77 - mb(); 78 - 79 - /* The operation can take ages... Go to sleep, 100us initially */ 80 - tries = 100; 81 - timeout = 100; 82 - do { 83 - if (!irqs_disabled()) { 84 - set_current_state(TASK_INTERRUPTIBLE); 85 - schedule_timeout(usecs_to_jiffies(timeout)); 86 - if (signal_pending(current)) 87 - return -EINTR; 88 - } else { 89 - udelay(timeout); 90 - } 91 - 92 - status = readl(syscfg->base + SYS_CFGSTAT); 93 - if (status & SYS_CFGSTAT_ERR) 94 - return -EFAULT; 95 - 96 - if (timeout > 20) 97 - timeout -= 20; 98 - } while (--tries && !(status & SYS_CFGSTAT_COMPLETE)); 99 - if (WARN_ON_ONCE(!tries)) 100 - return -ETIMEDOUT; 101 - 102 - if (!write) { 103 - *data = readl(syscfg->base + SYS_CFGDATA); 104 - dev_dbg(syscfg->dev, "func %p, read data %x\n", func, *data); 105 - } 106 - 107 - return 0; 108 - } 109 - 110 - static int vexpress_syscfg_read(void *context, unsigned int index, 111 - unsigned int *val) 112 - { 113 - struct vexpress_syscfg_func *func = context; 114 - 115 - return vexpress_syscfg_exec(func, index, false, val); 116 - } 117 - 118 - static int vexpress_syscfg_write(void *context, unsigned int index, 119 - unsigned int val) 120 - { 121 - struct vexpress_syscfg_func *func = context; 122 - 123 - return vexpress_syscfg_exec(func, index, true, &val); 124 - } 125 - 126 - static struct regmap_config vexpress_syscfg_regmap_config = { 127 - .lock = vexpress_config_lock, 128 - .unlock = vexpress_config_unlock, 129 - .reg_bits = 32, 130 - .val_bits = 32, 131 - .reg_read = vexpress_syscfg_read, 132 - .reg_write = vexpress_syscfg_write, 133 - .reg_format_endian = REGMAP_ENDIAN_LITTLE, 134 - .val_format_endian = REGMAP_ENDIAN_LITTLE, 135 - }; 136 - 137 - 138 - static struct regmap *vexpress_syscfg_regmap_init(struct device *dev, 139 - void *context) 140 - { 141 - int err; 142 - struct vexpress_syscfg *syscfg = context; 143 - struct vexpress_syscfg_func *func; 144 - struct property *prop; 145 - const __be32 *val = NULL; 146 - __be32 energy_quirk[4]; 147 - int num; 148 - u32 site, position, dcc; 149 - int i; 150 - 151 - err = vexpress_config_get_topo(dev->of_node, &site, 152 - &position, &dcc); 153 - if (err) 154 - return ERR_PTR(err); 155 - 156 - prop = of_find_property(dev->of_node, 157 - "arm,vexpress-sysreg,func", NULL); 158 - if (!prop) 159 - return ERR_PTR(-EINVAL); 160 - 161 - num = prop->length / sizeof(u32) / 2; 162 - val = prop->value; 163 - 164 - /* 165 - * "arm,vexpress-energy" function used to be described 166 - * by its first device only, now it requires both 167 - */ 168 - if (num == 1 && of_device_is_compatible(dev->of_node, 169 - "arm,vexpress-energy")) { 170 - num = 2; 171 - energy_quirk[0] = *val; 172 - energy_quirk[2] = *val++; 173 - energy_quirk[1] = *val; 174 - energy_quirk[3] = cpu_to_be32(be32_to_cpup(val) + 1); 175 - val = energy_quirk; 176 - } 177 - 178 - func = kzalloc(struct_size(func, template, num), GFP_KERNEL); 179 - if (!func) 180 - return ERR_PTR(-ENOMEM); 181 - 182 - func->syscfg = syscfg; 183 - func->num_templates = num; 184 - 185 - for (i = 0; i < num; i++) { 186 - u32 function, device; 187 - 188 - function = be32_to_cpup(val++); 189 - device = be32_to_cpup(val++); 190 - 191 - dev_dbg(dev, "func %p: %u/%u/%u/%u/%u\n", 192 - func, site, position, dcc, 193 - function, device); 194 - 195 - func->template[i] = SYS_CFGCTRL_DCC(dcc); 196 - func->template[i] |= SYS_CFGCTRL_SITE(site); 197 - func->template[i] |= SYS_CFGCTRL_POSITION(position); 198 - func->template[i] |= SYS_CFGCTRL_FUNC(function); 199 - func->template[i] |= SYS_CFGCTRL_DEVICE(device); 200 - } 201 - 202 - vexpress_syscfg_regmap_config.max_register = num - 1; 203 - 204 - func->regmap = regmap_init(dev, NULL, func, 205 - &vexpress_syscfg_regmap_config); 206 - 207 - if (IS_ERR(func->regmap)) { 208 - void *err = func->regmap; 209 - 210 - kfree(func); 211 - return err; 212 - } 213 - 214 - list_add(&func->list, &syscfg->funcs); 215 - 216 - return func->regmap; 217 - } 218 - 219 - static void vexpress_syscfg_regmap_exit(struct regmap *regmap, void *context) 220 - { 221 - struct vexpress_syscfg *syscfg = context; 222 - struct vexpress_syscfg_func *func, *tmp; 223 - 224 - regmap_exit(regmap); 225 - 226 - list_for_each_entry_safe(func, tmp, &syscfg->funcs, list) { 227 - if (func->regmap == regmap) { 228 - list_del(&syscfg->funcs); 229 - kfree(func); 230 - break; 231 - } 232 - } 233 - } 234 - 235 - static struct vexpress_config_bridge_ops vexpress_syscfg_bridge_ops = { 236 - .regmap_init = vexpress_syscfg_regmap_init, 237 - .regmap_exit = vexpress_syscfg_regmap_exit, 238 - }; 239 - 240 - 241 - static int vexpress_syscfg_probe(struct platform_device *pdev) 242 - { 243 - struct vexpress_syscfg *syscfg; 244 - struct resource *res; 245 - struct device *bridge; 246 - 247 - syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL); 248 - if (!syscfg) 249 - return -ENOMEM; 250 - syscfg->dev = &pdev->dev; 251 - INIT_LIST_HEAD(&syscfg->funcs); 252 - 253 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 254 - syscfg->base = devm_ioremap_resource(&pdev->dev, res); 255 - if (IS_ERR(syscfg->base)) 256 - return PTR_ERR(syscfg->base); 257 - 258 - /* Must use dev.parent (MFD), as that's where DT phandle points at... */ 259 - bridge = vexpress_config_bridge_register(pdev->dev.parent, 260 - &vexpress_syscfg_bridge_ops, syscfg); 261 - 262 - return PTR_ERR_OR_ZERO(bridge); 263 - } 264 - 265 - static const struct platform_device_id vexpress_syscfg_id_table[] = { 266 - { "vexpress-syscfg", }, 267 - {}, 268 - }; 269 - 270 - static struct platform_driver vexpress_syscfg_driver = { 271 - .driver.name = "vexpress-syscfg", 272 - .id_table = vexpress_syscfg_id_table, 273 - .probe = vexpress_syscfg_probe, 274 - }; 275 - 276 - static int __init vexpress_syscfg_init(void) 277 - { 278 - return platform_driver_register(&vexpress_syscfg_driver); 279 - } 280 - core_initcall(vexpress_syscfg_init);
-30
include/linux/vexpress.h
··· 10 10 #include <linux/device.h> 11 11 #include <linux/regmap.h> 12 12 13 - #define VEXPRESS_SITE_MB 0 14 - #define VEXPRESS_SITE_DB1 1 15 - #define VEXPRESS_SITE_DB2 2 16 - #define VEXPRESS_SITE_MASTER 0xf 17 - 18 - /* Config infrastructure */ 19 - 20 - void vexpress_config_set_master(u32 site); 21 - u32 vexpress_config_get_master(void); 22 - 23 - void vexpress_config_lock(void *arg); 24 - void vexpress_config_unlock(void *arg); 25 - 26 - int vexpress_config_get_topo(struct device_node *node, u32 *site, 27 - u32 *position, u32 *dcc); 28 - 29 - /* Config bridge API */ 30 - 31 - struct vexpress_config_bridge_ops { 32 - struct regmap * (*regmap_init)(struct device *dev, void *context); 33 - void (*regmap_exit)(struct regmap *regmap, void *context); 34 - }; 35 - 36 - struct device *vexpress_config_bridge_register(struct device *parent, 37 - struct vexpress_config_bridge_ops *ops, void *context); 38 - 39 13 /* Config regmap API */ 40 14 41 15 struct regmap *devm_regmap_init_vexpress_config(struct device *dev); 42 - 43 - /* Platform control */ 44 - 45 - void vexpress_flags_set(u32 data); 46 16 47 17 #endif