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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc7 528 lines 14 kB view raw
1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License version 2 as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope that it will be useful, 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * GNU General Public License for more details. 10 * 11 * Copyright (C) 2012 ARM Limited 12 */ 13 14#include <linux/err.h> 15#include <linux/gpio.h> 16#include <linux/io.h> 17#include <linux/leds.h> 18#include <linux/of_address.h> 19#include <linux/platform_device.h> 20#include <linux/regulator/driver.h> 21#include <linux/slab.h> 22#include <linux/stat.h> 23#include <linux/timer.h> 24#include <linux/vexpress.h> 25 26#define SYS_ID 0x000 27#define SYS_SW 0x004 28#define SYS_LED 0x008 29#define SYS_100HZ 0x024 30#define SYS_FLAGS 0x030 31#define SYS_FLAGSSET 0x030 32#define SYS_FLAGSCLR 0x034 33#define SYS_NVFLAGS 0x038 34#define SYS_NVFLAGSSET 0x038 35#define SYS_NVFLAGSCLR 0x03c 36#define SYS_MCI 0x048 37#define SYS_FLASH 0x04c 38#define SYS_CFGSW 0x058 39#define SYS_24MHZ 0x05c 40#define SYS_MISC 0x060 41#define SYS_DMA 0x064 42#define SYS_PROCID0 0x084 43#define SYS_PROCID1 0x088 44#define SYS_CFGDATA 0x0a0 45#define SYS_CFGCTRL 0x0a4 46#define SYS_CFGSTAT 0x0a8 47 48#define SYS_HBI_MASK 0xfff 49#define SYS_ID_HBI_SHIFT 16 50#define SYS_PROCIDx_HBI_SHIFT 0 51 52#define SYS_LED_LED(n) (1 << (n)) 53 54#define SYS_MCI_CARDIN (1 << 0) 55#define SYS_MCI_WPROT (1 << 1) 56 57#define SYS_FLASH_WPn (1 << 0) 58 59#define SYS_MISC_MASTERSITE (1 << 14) 60 61#define SYS_CFGCTRL_START (1 << 31) 62#define SYS_CFGCTRL_WRITE (1 << 30) 63#define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26) 64#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20) 65#define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16) 66#define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12) 67#define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0) 68 69#define SYS_CFGSTAT_ERR (1 << 1) 70#define SYS_CFGSTAT_COMPLETE (1 << 0) 71 72 73static void __iomem *vexpress_sysreg_base; 74static struct device *vexpress_sysreg_dev; 75static int vexpress_master_site; 76 77 78void vexpress_flags_set(u32 data) 79{ 80 writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR); 81 writel(data, vexpress_sysreg_base + SYS_FLAGSSET); 82} 83 84u32 vexpress_get_procid(int site) 85{ 86 if (site == VEXPRESS_SITE_MASTER) 87 site = vexpress_master_site; 88 89 return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ? 90 SYS_PROCID0 : SYS_PROCID1)); 91} 92 93u32 vexpress_get_hbi(int site) 94{ 95 u32 id; 96 97 switch (site) { 98 case VEXPRESS_SITE_MB: 99 id = readl(vexpress_sysreg_base + SYS_ID); 100 return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK; 101 case VEXPRESS_SITE_MASTER: 102 case VEXPRESS_SITE_DB1: 103 case VEXPRESS_SITE_DB2: 104 id = vexpress_get_procid(site); 105 return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; 106 } 107 108 return ~0; 109} 110 111void __iomem *vexpress_get_24mhz_clock_base(void) 112{ 113 return vexpress_sysreg_base + SYS_24MHZ; 114} 115 116 117static void vexpress_sysreg_find_prop(struct device_node *node, 118 const char *name, u32 *val) 119{ 120 of_node_get(node); 121 while (node) { 122 if (of_property_read_u32(node, name, val) == 0) { 123 of_node_put(node); 124 return; 125 } 126 node = of_get_next_parent(node); 127 } 128} 129 130unsigned __vexpress_get_site(struct device *dev, struct device_node *node) 131{ 132 u32 site = 0; 133 134 WARN_ON(dev && node && dev->of_node != node); 135 if (dev && !node) 136 node = dev->of_node; 137 138 if (node) { 139 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site); 140 } else if (dev && dev->bus == &platform_bus_type) { 141 struct platform_device *pdev = to_platform_device(dev); 142 143 if (pdev->num_resources == 1 && 144 pdev->resource[0].flags == IORESOURCE_BUS) 145 site = pdev->resource[0].start; 146 } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) { 147 site = VEXPRESS_SITE_MASTER; 148 } 149 150 if (site == VEXPRESS_SITE_MASTER) 151 site = vexpress_master_site; 152 153 return site; 154} 155 156 157struct vexpress_sysreg_config_func { 158 u32 template; 159 u32 device; 160}; 161 162static struct vexpress_config_bridge *vexpress_sysreg_config_bridge; 163static struct timer_list vexpress_sysreg_config_timer; 164static u32 *vexpress_sysreg_config_data; 165static int vexpress_sysreg_config_tries; 166 167static void *vexpress_sysreg_config_func_get(struct device *dev, 168 struct device_node *node) 169{ 170 struct vexpress_sysreg_config_func *config_func; 171 u32 site; 172 u32 position = 0; 173 u32 dcc = 0; 174 u32 func_device[2]; 175 int err = -EFAULT; 176 177 if (node) { 178 of_node_get(node); 179 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site); 180 vexpress_sysreg_find_prop(node, "arm,vexpress,position", 181 &position); 182 vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc); 183 err = of_property_read_u32_array(node, 184 "arm,vexpress-sysreg,func", func_device, 185 ARRAY_SIZE(func_device)); 186 of_node_put(node); 187 } else if (dev && dev->bus == &platform_bus_type) { 188 struct platform_device *pdev = to_platform_device(dev); 189 190 if (pdev->num_resources == 1 && 191 pdev->resource[0].flags == IORESOURCE_BUS) { 192 site = pdev->resource[0].start; 193 func_device[0] = pdev->resource[0].end; 194 func_device[1] = pdev->id; 195 err = 0; 196 } 197 } 198 if (err) 199 return NULL; 200 201 config_func = kzalloc(sizeof(*config_func), GFP_KERNEL); 202 if (!config_func) 203 return NULL; 204 205 config_func->template = SYS_CFGCTRL_DCC(dcc); 206 config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]); 207 config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ? 208 vexpress_master_site : site); 209 config_func->template |= SYS_CFGCTRL_POSITION(position); 210 config_func->device |= func_device[1]; 211 212 dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func, 213 config_func->template, config_func->device); 214 215 return config_func; 216} 217 218static void vexpress_sysreg_config_func_put(void *func) 219{ 220 kfree(func); 221} 222 223static int vexpress_sysreg_config_func_exec(void *func, int offset, 224 bool write, u32 *data) 225{ 226 int status; 227 struct vexpress_sysreg_config_func *config_func = func; 228 u32 command; 229 230 if (WARN_ON(!vexpress_sysreg_base)) 231 return -ENOENT; 232 233 command = readl(vexpress_sysreg_base + SYS_CFGCTRL); 234 if (WARN_ON(command & SYS_CFGCTRL_START)) 235 return -EBUSY; 236 237 command = SYS_CFGCTRL_START; 238 command |= write ? SYS_CFGCTRL_WRITE : 0; 239 command |= config_func->template; 240 command |= SYS_CFGCTRL_DEVICE(config_func->device + offset); 241 242 /* Use a canary for reads */ 243 if (!write) 244 *data = 0xdeadbeef; 245 246 dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n", 247 command, *data); 248 writel(*data, vexpress_sysreg_base + SYS_CFGDATA); 249 writel(0, vexpress_sysreg_base + SYS_CFGSTAT); 250 writel(command, vexpress_sysreg_base + SYS_CFGCTRL); 251 mb(); 252 253 if (vexpress_sysreg_dev) { 254 /* Schedule completion check */ 255 if (!write) 256 vexpress_sysreg_config_data = data; 257 vexpress_sysreg_config_tries = 100; 258 mod_timer(&vexpress_sysreg_config_timer, 259 jiffies + usecs_to_jiffies(100)); 260 status = VEXPRESS_CONFIG_STATUS_WAIT; 261 } else { 262 /* Early execution, no timer available, have to spin */ 263 u32 cfgstat; 264 265 do { 266 cpu_relax(); 267 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT); 268 } while (!cfgstat); 269 270 if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE)) 271 *data = readl(vexpress_sysreg_base + SYS_CFGDATA); 272 status = VEXPRESS_CONFIG_STATUS_DONE; 273 274 if (cfgstat & SYS_CFGSTAT_ERR) 275 status = -EINVAL; 276 } 277 278 return status; 279} 280 281struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = { 282 .name = "vexpress-sysreg", 283 .func_get = vexpress_sysreg_config_func_get, 284 .func_put = vexpress_sysreg_config_func_put, 285 .func_exec = vexpress_sysreg_config_func_exec, 286}; 287 288static void vexpress_sysreg_config_complete(unsigned long data) 289{ 290 int status = VEXPRESS_CONFIG_STATUS_DONE; 291 u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT); 292 293 if (cfgstat & SYS_CFGSTAT_ERR) 294 status = -EINVAL; 295 if (!vexpress_sysreg_config_tries--) 296 status = -ETIMEDOUT; 297 298 if (status < 0) { 299 dev_err(vexpress_sysreg_dev, "error %d\n", status); 300 } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) { 301 mod_timer(&vexpress_sysreg_config_timer, 302 jiffies + usecs_to_jiffies(50)); 303 return; 304 } 305 306 if (vexpress_sysreg_config_data) { 307 *vexpress_sysreg_config_data = readl(vexpress_sysreg_base + 308 SYS_CFGDATA); 309 dev_dbg(vexpress_sysreg_dev, "read data %x\n", 310 *vexpress_sysreg_config_data); 311 vexpress_sysreg_config_data = NULL; 312 } 313 314 vexpress_config_complete(vexpress_sysreg_config_bridge, status); 315} 316 317 318void vexpress_sysreg_setup(struct device_node *node) 319{ 320 if (WARN_ON(!vexpress_sysreg_base)) 321 return; 322 323 if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE) 324 vexpress_master_site = VEXPRESS_SITE_DB2; 325 else 326 vexpress_master_site = VEXPRESS_SITE_DB1; 327 328 vexpress_sysreg_config_bridge = vexpress_config_bridge_register( 329 node, &vexpress_sysreg_config_bridge_info); 330 WARN_ON(!vexpress_sysreg_config_bridge); 331} 332 333void __init vexpress_sysreg_early_init(void __iomem *base) 334{ 335 vexpress_sysreg_base = base; 336 vexpress_sysreg_setup(NULL); 337} 338 339void __init vexpress_sysreg_of_early_init(void) 340{ 341 struct device_node *node; 342 343 if (vexpress_sysreg_base) 344 return; 345 346 node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); 347 if (node) { 348 vexpress_sysreg_base = of_iomap(node, 0); 349 vexpress_sysreg_setup(node); 350 } 351} 352 353 354#ifdef CONFIG_GPIOLIB 355 356#define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \ 357 [VEXPRESS_GPIO_##_name] = { \ 358 .reg = _reg, \ 359 .value = _reg##_##_value, \ 360 } 361 362static struct vexpress_sysreg_gpio { 363 unsigned long reg; 364 u32 value; 365} vexpress_sysreg_gpios[] = { 366 VEXPRESS_SYSREG_GPIO(MMC_CARDIN, SYS_MCI, CARDIN), 367 VEXPRESS_SYSREG_GPIO(MMC_WPROT, SYS_MCI, WPROT), 368 VEXPRESS_SYSREG_GPIO(FLASH_WPn, SYS_FLASH, WPn), 369 VEXPRESS_SYSREG_GPIO(LED0, SYS_LED, LED(0)), 370 VEXPRESS_SYSREG_GPIO(LED1, SYS_LED, LED(1)), 371 VEXPRESS_SYSREG_GPIO(LED2, SYS_LED, LED(2)), 372 VEXPRESS_SYSREG_GPIO(LED3, SYS_LED, LED(3)), 373 VEXPRESS_SYSREG_GPIO(LED4, SYS_LED, LED(4)), 374 VEXPRESS_SYSREG_GPIO(LED5, SYS_LED, LED(5)), 375 VEXPRESS_SYSREG_GPIO(LED6, SYS_LED, LED(6)), 376 VEXPRESS_SYSREG_GPIO(LED7, SYS_LED, LED(7)), 377}; 378 379static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, 380 unsigned offset) 381{ 382 return 0; 383} 384 385static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, 386 unsigned offset) 387{ 388 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset]; 389 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg); 390 391 return !!(reg_value & gpio->value); 392} 393 394static void vexpress_sysreg_gpio_set(struct gpio_chip *chip, 395 unsigned offset, int value) 396{ 397 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset]; 398 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg); 399 400 if (value) 401 reg_value |= gpio->value; 402 else 403 reg_value &= ~gpio->value; 404 405 writel(reg_value, vexpress_sysreg_base + gpio->reg); 406} 407 408static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, 409 unsigned offset, int value) 410{ 411 vexpress_sysreg_gpio_set(chip, offset, value); 412 413 return 0; 414} 415 416static struct gpio_chip vexpress_sysreg_gpio_chip = { 417 .label = "vexpress-sysreg", 418 .direction_input = vexpress_sysreg_gpio_direction_input, 419 .direction_output = vexpress_sysreg_gpio_direction_output, 420 .get = vexpress_sysreg_gpio_get, 421 .set = vexpress_sysreg_gpio_set, 422 .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios), 423 .base = 0, 424}; 425 426 427#define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \ 428 { \ 429 .name = "v2m:green:"_name, \ 430 .default_trigger = _default_trigger, \ 431 .gpio = VEXPRESS_GPIO_##_gpio, \ 432 } 433 434struct gpio_led vexpress_sysreg_leds[] = { 435 VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0), 436 VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1), 437 VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2), 438 VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3), 439 VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4), 440 VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5), 441 VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6), 442 VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7), 443}; 444 445struct gpio_led_platform_data vexpress_sysreg_leds_pdata = { 446 .num_leds = ARRAY_SIZE(vexpress_sysreg_leds), 447 .leds = vexpress_sysreg_leds, 448}; 449 450#endif 451 452 453static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, 454 struct device_attribute *attr, char *buf) 455{ 456 return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID)); 457} 458 459DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL); 460 461static int vexpress_sysreg_probe(struct platform_device *pdev) 462{ 463 int err; 464 struct resource *res = platform_get_resource(pdev, 465 IORESOURCE_MEM, 0); 466 467 if (!devm_request_mem_region(&pdev->dev, res->start, 468 resource_size(res), pdev->name)) { 469 dev_err(&pdev->dev, "Failed to request memory region!\n"); 470 return -EBUSY; 471 } 472 473 if (!vexpress_sysreg_base) { 474 vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start, 475 resource_size(res)); 476 vexpress_sysreg_setup(pdev->dev.of_node); 477 } 478 479 if (!vexpress_sysreg_base) { 480 dev_err(&pdev->dev, "Failed to obtain base address!\n"); 481 return -EFAULT; 482 } 483 484 setup_timer(&vexpress_sysreg_config_timer, 485 vexpress_sysreg_config_complete, 0); 486 487 vexpress_sysreg_dev = &pdev->dev; 488 489#ifdef CONFIG_GPIOLIB 490 vexpress_sysreg_gpio_chip.dev = &pdev->dev; 491 err = gpiochip_add(&vexpress_sysreg_gpio_chip); 492 if (err) { 493 vexpress_config_bridge_unregister( 494 vexpress_sysreg_config_bridge); 495 dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n", 496 err); 497 return err; 498 } 499 500 platform_device_register_data(vexpress_sysreg_dev, "leds-gpio", 501 PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata, 502 sizeof(vexpress_sysreg_leds_pdata)); 503#endif 504 505 device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); 506 507 return 0; 508} 509 510static const struct of_device_id vexpress_sysreg_match[] = { 511 { .compatible = "arm,vexpress-sysreg", }, 512 {}, 513}; 514 515static struct platform_driver vexpress_sysreg_driver = { 516 .driver = { 517 .name = "vexpress-sysreg", 518 .of_match_table = vexpress_sysreg_match, 519 }, 520 .probe = vexpress_sysreg_probe, 521}; 522 523static int __init vexpress_sysreg_init(void) 524{ 525 vexpress_sysreg_of_early_init(); 526 return platform_driver_register(&vexpress_sysreg_driver); 527} 528core_initcall(vexpress_sysreg_init);