1 /* 2 * Based on linux/arch/mips/txx9/rbtx4938/setup.c, 3 * and RBTX49xx patch from CELF patch archive. 4 * 5 * 2003-2005 (c) MontaVista Software, Inc. 6 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive 10 * for more details. 11 */ 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/types.h> 15 #include <linux/interrupt.h> 16 #include <linux/string.h> 17 #include <linux/export.h> 18 #include <linux/clk-provider.h> 19 #include <linux/clkdev.h> 20 #include <linux/err.h> 21 #include <linux/gpio/driver.h> 22 #include <linux/platform_device.h> 23 #include <linux/platform_data/txx9/ndfmc.h> 24 #include <linux/serial_core.h> 25 #include <linux/mtd/physmap.h> 26 #include <linux/leds.h> 27 #include <linux/device.h> 28 #include <linux/slab.h> 29 #include <linux/io.h> 30 #include <linux/irq.h> 31 #include <asm/bootinfo.h> 32 #include <asm/idle.h> 33 #include <asm/time.h> 34 #include <asm/reboot.h> 35 #include <asm/r4kcache.h> 36 #include <asm/sections.h> 37 #include <asm/setup.h> 38 #include <asm/txx9/generic.h> 39 #include <asm/txx9/pci.h> 40 #include <asm/txx9tmr.h> 41 #include <asm/txx9/dmac.h> 42 #ifdef CONFIG_CPU_TX49XX 43 #include <asm/txx9/tx4938.h> 44 #endif 45 46 /* EBUSC settings of TX4927, etc. */ 47 struct resource txx9_ce_res[8]; 48 static char txx9_ce_res_name[8][4]; /* "CEn" */ 49 50 /* pcode, internal register */ 51 unsigned int txx9_pcode; 52 char txx9_pcode_str[8]; 53 static struct resource txx9_reg_res = { 54 .name = txx9_pcode_str, 55 .flags = IORESOURCE_MEM, 56 }; 57 void __init 58 txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) 59 { 60 int i; 61 62 for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) { 63 sprintf(txx9_ce_res_name[i], "CE%d", i); 64 txx9_ce_res[i].flags = IORESOURCE_MEM; 65 txx9_ce_res[i].name = txx9_ce_res_name[i]; 66 } 67 68 txx9_pcode = pcode; 69 sprintf(txx9_pcode_str, "TX%x", pcode); 70 if (base) { 71 txx9_reg_res.start = base & 0xfffffffffULL; 72 txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1); 73 request_resource(&iomem_resource, &txx9_reg_res); 74 } 75 } 76 77 /* clocks */ 78 unsigned int txx9_master_clock; 79 unsigned int txx9_cpu_clock; 80 unsigned int txx9_gbus_clock; 81 82 #ifdef CONFIG_CPU_TX39XX 83 /* don't enable by default - see errata */ 84 int txx9_ccfg_toeon __initdata; 85 #else 86 int txx9_ccfg_toeon __initdata = 1; 87 #endif 88 89 #define BOARD_VEC(board) extern struct txx9_board_vec board; 90 #include <asm/txx9/boards.h> 91 #undef BOARD_VEC 92 93 struct txx9_board_vec *txx9_board_vec __initdata; 94 static char txx9_system_type[32]; 95 96 static struct txx9_board_vec *board_vecs[] __initdata = { 97 #define BOARD_VEC(board) &board, 98 #include <asm/txx9/boards.h> 99 #undef BOARD_VEC 100 }; 101 102 static struct txx9_board_vec *__init find_board_byname(const char *name) 103 { 104 int i; 105 106 /* search board_vecs table */ 107 for (i = 0; i < ARRAY_SIZE(board_vecs); i++) { 108 if (strstr(board_vecs[i]->system, name)) 109 return board_vecs[i]; 110 } 111 return NULL; 112 } 113 114 static void __init prom_init_cmdline(void) 115 { 116 int argc; 117 int *argv32; 118 int i; /* Always ignore the "-c" at argv[0] */ 119 120 if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) { 121 /* 122 * argc is not a valid number, or argv32 is not a valid 123 * pointer 124 */ 125 argc = 0; 126 argv32 = NULL; 127 } else { 128 argc = (int)fw_arg0; 129 argv32 = (int *)fw_arg1; 130 } 131 132 arcs_cmdline[0] = '\0'; 133 134 for (i = 1; i < argc; i++) { 135 char *str = (char *)(long)argv32[i]; 136 if (i != 1) 137 strcat(arcs_cmdline, " "); 138 if (strchr(str, ' ')) { 139 strcat(arcs_cmdline, "\""); 140 strcat(arcs_cmdline, str); 141 strcat(arcs_cmdline, "\""); 142 } else 143 strcat(arcs_cmdline, str); 144 } 145 } 146 147 static int txx9_ic_disable __initdata; 148 static int txx9_dc_disable __initdata; 149 150 #if defined(CONFIG_CPU_TX49XX) 151 /* flush all cache on very early stage (before 4k_cache_init) */ 152 static void __init early_flush_dcache(void) 153 { 154 unsigned int conf = read_c0_config(); 155 unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6)); 156 unsigned int linesz = 32; 157 unsigned long addr, end; 158 159 end = INDEX_BASE + dc_size / 4; 160 /* 4way, waybit=0 */ 161 for (addr = INDEX_BASE; addr < end; addr += linesz) { 162 cache_op(Index_Writeback_Inv_D, addr | 0); 163 cache_op(Index_Writeback_Inv_D, addr | 1); 164 cache_op(Index_Writeback_Inv_D, addr | 2); 165 cache_op(Index_Writeback_Inv_D, addr | 3); 166 } 167 } 168 169 static void __init txx9_cache_fixup(void) 170 { 171 unsigned int conf; 172 173 conf = read_c0_config(); 174 /* flush and disable */ 175 if (txx9_ic_disable) { 176 conf |= TX49_CONF_IC; 177 write_c0_config(conf); 178 } 179 if (txx9_dc_disable) { 180 early_flush_dcache(); 181 conf |= TX49_CONF_DC; 182 write_c0_config(conf); 183 } 184 185 /* enable cache */ 186 conf = read_c0_config(); 187 if (!txx9_ic_disable) 188 conf &= ~TX49_CONF_IC; 189 if (!txx9_dc_disable) 190 conf &= ~TX49_CONF_DC; 191 write_c0_config(conf); 192 193 if (conf & TX49_CONF_IC) 194 pr_info("TX49XX I-Cache disabled.\n"); 195 if (conf & TX49_CONF_DC) 196 pr_info("TX49XX D-Cache disabled.\n"); 197 } 198 #elif defined(CONFIG_CPU_TX39XX) 199 /* flush all cache on very early stage (before tx39_cache_init) */ 200 static void __init early_flush_dcache(void) 201 { 202 unsigned int conf = read_c0_config(); 203 unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >> 204 TX39_CONF_DCS_SHIFT)); 205 unsigned int linesz = 16; 206 unsigned long addr, end; 207 208 end = INDEX_BASE + dc_size / 2; 209 /* 2way, waybit=0 */ 210 for (addr = INDEX_BASE; addr < end; addr += linesz) { 211 cache_op(Index_Writeback_Inv_D, addr | 0); 212 cache_op(Index_Writeback_Inv_D, addr | 1); 213 } 214 } 215 216 static void __init txx9_cache_fixup(void) 217 { 218 unsigned int conf; 219 220 conf = read_c0_config(); 221 /* flush and disable */ 222 if (txx9_ic_disable) { 223 conf &= ~TX39_CONF_ICE; 224 write_c0_config(conf); 225 } 226 if (txx9_dc_disable) { 227 early_flush_dcache(); 228 conf &= ~TX39_CONF_DCE; 229 write_c0_config(conf); 230 } 231 232 /* enable cache */ 233 conf = read_c0_config(); 234 if (!txx9_ic_disable) 235 conf |= TX39_CONF_ICE; 236 if (!txx9_dc_disable) 237 conf |= TX39_CONF_DCE; 238 write_c0_config(conf); 239 240 if (!(conf & TX39_CONF_ICE)) 241 pr_info("TX39XX I-Cache disabled.\n"); 242 if (!(conf & TX39_CONF_DCE)) 243 pr_info("TX39XX D-Cache disabled.\n"); 244 } 245 #else 246 static inline void txx9_cache_fixup(void) 247 { 248 } 249 #endif 250 251 static void __init preprocess_cmdline(void) 252 { 253 static char cmdline[COMMAND_LINE_SIZE] __initdata; 254 char *s; 255 256 strcpy(cmdline, arcs_cmdline); 257 s = cmdline; 258 arcs_cmdline[0] = '\0'; 259 while (s && *s) { 260 char *str = strsep(&s, " "); 261 if (strncmp(str, "board=", 6) == 0) { 262 txx9_board_vec = find_board_byname(str + 6); 263 continue; 264 } else if (strncmp(str, "masterclk=", 10) == 0) { 265 unsigned int val; 266 if (kstrtouint(str + 10, 10, &val) == 0) 267 txx9_master_clock = val; 268 continue; 269 } else if (strcmp(str, "icdisable") == 0) { 270 txx9_ic_disable = 1; 271 continue; 272 } else if (strcmp(str, "dcdisable") == 0) { 273 txx9_dc_disable = 1; 274 continue; 275 } else if (strcmp(str, "toeoff") == 0) { 276 txx9_ccfg_toeon = 0; 277 continue; 278 } else if (strcmp(str, "toeon") == 0) { 279 txx9_ccfg_toeon = 1; 280 continue; 281 } 282 if (arcs_cmdline[0]) 283 strcat(arcs_cmdline, " "); 284 strcat(arcs_cmdline, str); 285 } 286 287 txx9_cache_fixup(); 288 } 289 290 static void __init select_board(void) 291 { 292 const char *envstr; 293 294 /* first, determine by "board=" argument in preprocess_cmdline() */ 295 if (txx9_board_vec) 296 return; 297 /* next, determine by "board" envvar */ 298 envstr = prom_getenv("board"); 299 if (envstr) { 300 txx9_board_vec = find_board_byname(envstr); 301 if (txx9_board_vec) 302 return; 303 } 304 305 /* select "default" board */ 306 #ifdef CONFIG_TOSHIBA_JMR3927 307 txx9_board_vec = &jmr3927_vec; 308 #endif 309 #ifdef CONFIG_CPU_TX49XX 310 switch (TX4938_REV_PCODE()) { 311 #ifdef CONFIG_TOSHIBA_RBTX4927 312 case 0x4927: 313 txx9_board_vec = &rbtx4927_vec; 314 break; 315 case 0x4937: 316 txx9_board_vec = &rbtx4937_vec; 317 break; 318 #endif 319 #ifdef CONFIG_TOSHIBA_RBTX4938 320 case 0x4938: 321 txx9_board_vec = &rbtx4938_vec; 322 break; 323 #endif 324 #ifdef CONFIG_TOSHIBA_RBTX4939 325 case 0x4939: 326 txx9_board_vec = &rbtx4939_vec; 327 break; 328 #endif 329 } 330 #endif 331 } 332 333 void __init prom_init(void) 334 { 335 prom_init_cmdline(); 336 preprocess_cmdline(); 337 select_board(); 338 339 strcpy(txx9_system_type, txx9_board_vec->system); 340 341 txx9_board_vec->prom_init(); 342 } 343 344 void __init prom_free_prom_memory(void) 345 { 346 unsigned long saddr = PAGE_SIZE; 347 unsigned long eaddr = __pa_symbol(&_text); 348 349 if (saddr < eaddr) 350 free_init_pages("prom memory", saddr, eaddr); 351 } 352 353 const char *get_system_type(void) 354 { 355 return txx9_system_type; 356 } 357 358 const char *__init prom_getenv(const char *name) 359 { 360 const s32 *str; 361 362 if (fw_arg2 < CKSEG0) 363 return NULL; 364 365 str = (const s32 *)fw_arg2; 366 /* YAMON style ("name", "value" pairs) */ 367 while (str[0] && str[1]) { 368 if (!strcmp((const char *)(unsigned long)str[0], name)) 369 return (const char *)(unsigned long)str[1]; 370 str += 2; 371 } 372 return NULL; 373 } 374 375 static void __noreturn txx9_machine_halt(void) 376 { 377 local_irq_disable(); 378 clear_c0_status(ST0_IM); 379 while (1) { 380 if (cpu_wait) { 381 (*cpu_wait)(); 382 if (cpu_has_counter) { 383 /* 384 * Clear counter interrupt while it 385 * breaks WAIT instruction even if 386 * masked. 387 */ 388 write_c0_compare(0); 389 } 390 } 391 } 392 } 393 394 /* Watchdog support */ 395 void __init txx9_wdt_init(unsigned long base) 396 { 397 struct resource res = { 398 .start = base, 399 .end = base + 0x100 - 1, 400 .flags = IORESOURCE_MEM, 401 }; 402 platform_device_register_simple("txx9wdt", -1, &res, 1); 403 } 404 405 void txx9_wdt_now(unsigned long base) 406 { 407 struct txx9_tmr_reg __iomem *tmrptr = 408 ioremap(base, sizeof(struct txx9_tmr_reg)); 409 /* disable watch dog timer */ 410 __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr); 411 __raw_writel(0, &tmrptr->tcr); 412 /* kick watchdog */ 413 __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr); 414 __raw_writel(1, &tmrptr->cpra); /* immediate */ 415 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, 416 &tmrptr->tcr); 417 } 418 419 /* SPI support */ 420 void __init txx9_spi_init(int busid, unsigned long base, int irq) 421 { 422 struct resource res[] = { 423 { 424 .start = base, 425 .end = base + 0x20 - 1, 426 .flags = IORESOURCE_MEM, 427 }, { 428 .start = irq, 429 .flags = IORESOURCE_IRQ, 430 }, 431 }; 432 platform_device_register_simple("spi_txx9", busid, 433 res, ARRAY_SIZE(res)); 434 } 435 436 void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr) 437 { 438 struct platform_device *pdev = 439 platform_device_alloc("tc35815-mac", id); 440 if (!pdev || 441 platform_device_add_data(pdev, ethaddr, 6) || 442 platform_device_add(pdev)) 443 platform_device_put(pdev); 444 } 445 446 void __init txx9_sio_init(unsigned long baseaddr, int irq, 447 unsigned int line, unsigned int sclk, int nocts) 448 { 449 #ifdef CONFIG_SERIAL_TXX9 450 struct uart_port req; 451 452 memset(&req, 0, sizeof(req)); 453 req.line = line; 454 req.iotype = UPIO_MEM; 455 req.membase = ioremap(baseaddr, 0x24); 456 req.mapbase = baseaddr; 457 req.irq = irq; 458 if (!nocts) 459 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; 460 if (sclk) { 461 req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/; 462 req.uartclk = sclk; 463 } else 464 req.uartclk = TXX9_IMCLK; 465 early_serial_txx9_setup(&req); 466 #endif /* CONFIG_SERIAL_TXX9 */ 467 } 468 469 #ifdef CONFIG_EARLY_PRINTK 470 static void null_prom_putchar(char c) 471 { 472 } 473 void (*txx9_prom_putchar)(char c) = null_prom_putchar; 474 475 void prom_putchar(char c) 476 { 477 txx9_prom_putchar(c); 478 } 479 480 static void __iomem *early_txx9_sio_port; 481 482 static void early_txx9_sio_putchar(char c) 483 { 484 #define TXX9_SICISR 0x0c 485 #define TXX9_SITFIFO 0x1c 486 #define TXX9_SICISR_TXALS 0x00000002 487 while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) & 488 TXX9_SICISR_TXALS)) 489 ; 490 __raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO); 491 } 492 493 void __init txx9_sio_putchar_init(unsigned long baseaddr) 494 { 495 early_txx9_sio_port = ioremap(baseaddr, 0x24); 496 txx9_prom_putchar = early_txx9_sio_putchar; 497 } 498 #endif /* CONFIG_EARLY_PRINTK */ 499 500 /* wrappers */ 501 void __init plat_mem_setup(void) 502 { 503 ioport_resource.start = 0; 504 ioport_resource.end = ~0UL; /* no limit */ 505 iomem_resource.start = 0; 506 iomem_resource.end = ~0UL; /* no limit */ 507 508 /* fallback restart/halt routines */ 509 _machine_restart = (void (*)(char *))txx9_machine_halt; 510 _machine_halt = txx9_machine_halt; 511 pm_power_off = txx9_machine_halt; 512 513 #ifdef CONFIG_PCI 514 pcibios_plat_setup = txx9_pcibios_setup; 515 #endif 516 txx9_board_vec->mem_setup(); 517 } 518 519 void __init arch_init_irq(void) 520 { 521 txx9_board_vec->irq_setup(); 522 } 523 524 void __init plat_time_init(void) 525 { 526 #ifdef CONFIG_CPU_TX49XX 527 mips_hpt_frequency = txx9_cpu_clock / 2; 528 #endif 529 txx9_board_vec->time_init(); 530 } 531 532 static void txx9_clk_init(void) 533 { 534 struct clk_hw *hw; 535 int error; 536 537 hw = clk_hw_register_fixed_rate(NULL, "gbus", NULL, 0, txx9_gbus_clock); 538 if (IS_ERR(hw)) { 539 error = PTR_ERR(hw); 540 goto fail; 541 } 542 543 hw = clk_hw_register_fixed_factor(NULL, "imbus", "gbus", 0, 1, 2); 544 error = clk_hw_register_clkdev(hw, "imbus_clk", NULL); 545 if (error) 546 goto fail; 547 548 #ifdef CONFIG_CPU_TX49XX 549 if (TX4938_REV_PCODE() == 0x4938) { 550 hw = clk_hw_register_fixed_factor(NULL, "spi", "gbus", 0, 1, 4); 551 error = clk_hw_register_clkdev(hw, "spi-baseclk", NULL); 552 if (error) 553 goto fail; 554 } 555 #endif 556 557 return; 558 559 fail: 560 pr_err("Failed to register clocks: %d\n", error); 561 } 562 563 static int __init _txx9_arch_init(void) 564 { 565 txx9_clk_init(); 566 567 if (txx9_board_vec->arch_init) 568 txx9_board_vec->arch_init(); 569 return 0; 570 } 571 arch_initcall(_txx9_arch_init); 572 573 static int __init _txx9_device_init(void) 574 { 575 if (txx9_board_vec->device_init) 576 txx9_board_vec->device_init(); 577 return 0; 578 } 579 device_initcall(_txx9_device_init); 580 581 int (*txx9_irq_dispatch)(int pending); 582 asmlinkage void plat_irq_dispatch(void) 583 { 584 int pending = read_c0_status() & read_c0_cause() & ST0_IM; 585 int irq = txx9_irq_dispatch(pending); 586 587 if (likely(irq >= 0)) 588 do_IRQ(irq); 589 else 590 spurious_interrupt(); 591 } 592 593 /* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */ 594 #ifdef NEEDS_TXX9_SWIZZLE_ADDR_B 595 static unsigned long __swizzle_addr_none(unsigned long port) 596 { 597 return port; 598 } 599 unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; 600 EXPORT_SYMBOL(__swizzle_addr_b); 601 #endif 602 603 #ifdef NEEDS_TXX9_IOSWABW 604 static u16 ioswabw_default(volatile u16 *a, u16 x) 605 { 606 return le16_to_cpu(x); 607 } 608 static u16 __mem_ioswabw_default(volatile u16 *a, u16 x) 609 { 610 return x; 611 } 612 u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default; 613 EXPORT_SYMBOL(ioswabw); 614 u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default; 615 EXPORT_SYMBOL(__mem_ioswabw); 616 #endif 617 618 void __init txx9_physmap_flash_init(int no, unsigned long addr, 619 unsigned long size, 620 const struct physmap_flash_data *pdata) 621 { 622 #if IS_ENABLED(CONFIG_MTD_PHYSMAP) 623 struct resource res = { 624 .start = addr, 625 .end = addr + size - 1, 626 .flags = IORESOURCE_MEM, 627 }; 628 struct platform_device *pdev; 629 static struct mtd_partition parts[2]; 630 struct physmap_flash_data pdata_part; 631 632 /* If this area contained boot area, make separate partition */ 633 if (pdata->nr_parts == 0 && !pdata->parts && 634 addr < 0x1fc00000 && addr + size > 0x1fc00000 && 635 !parts[0].name) { 636 parts[0].name = "boot"; 637 parts[0].offset = 0x1fc00000 - addr; 638 parts[0].size = addr + size - 0x1fc00000; 639 parts[1].name = "user"; 640 parts[1].offset = 0; 641 parts[1].size = 0x1fc00000 - addr; 642 pdata_part = *pdata; 643 pdata_part.nr_parts = ARRAY_SIZE(parts); 644 pdata_part.parts = parts; 645 pdata = &pdata_part; 646 } 647 648 pdev = platform_device_alloc("physmap-flash", no); 649 if (!pdev || 650 platform_device_add_resources(pdev, &res, 1) || 651 platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 652 platform_device_add(pdev)) 653 platform_device_put(pdev); 654 #endif 655 } 656 657 void __init txx9_ndfmc_init(unsigned long baseaddr, 658 const struct txx9ndfmc_platform_data *pdata) 659 { 660 #if IS_ENABLED(CONFIG_MTD_NAND_TXX9NDFMC) 661 struct resource res = { 662 .start = baseaddr, 663 .end = baseaddr + 0x1000 - 1, 664 .flags = IORESOURCE_MEM, 665 }; 666 struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1); 667 668 if (!pdev || 669 platform_device_add_resources(pdev, &res, 1) || 670 platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 671 platform_device_add(pdev)) 672 platform_device_put(pdev); 673 #endif 674 } 675 676 #if IS_ENABLED(CONFIG_LEDS_GPIO) 677 static DEFINE_SPINLOCK(txx9_iocled_lock); 678 679 #define TXX9_IOCLED_MAXLEDS 8 680 681 struct txx9_iocled_data { 682 struct gpio_chip chip; 683 u8 cur_val; 684 void __iomem *mmioaddr; 685 struct gpio_led_platform_data pdata; 686 struct gpio_led leds[TXX9_IOCLED_MAXLEDS]; 687 char names[TXX9_IOCLED_MAXLEDS][32]; 688 }; 689 690 static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) 691 { 692 struct txx9_iocled_data *data = gpiochip_get_data(chip); 693 return !!(data->cur_val & (1 << offset)); 694 } 695 696 static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, 697 int value) 698 { 699 struct txx9_iocled_data *data = gpiochip_get_data(chip); 700 unsigned long flags; 701 spin_lock_irqsave(&txx9_iocled_lock, flags); 702 if (value) 703 data->cur_val |= 1 << offset; 704 else 705 data->cur_val &= ~(1 << offset); 706 writeb(data->cur_val, data->mmioaddr); 707 mmiowb(); 708 spin_unlock_irqrestore(&txx9_iocled_lock, flags); 709 } 710 711 static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset) 712 { 713 return 0; 714 } 715 716 static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset, 717 int value) 718 { 719 txx9_iocled_set(chip, offset, value); 720 return 0; 721 } 722 723 void __init txx9_iocled_init(unsigned long baseaddr, 724 int basenum, unsigned int num, int lowactive, 725 const char *color, char **deftriggers) 726 { 727 struct txx9_iocled_data *iocled; 728 struct platform_device *pdev; 729 int i; 730 static char *default_triggers[] __initdata = { 731 "heartbeat", 732 "disk-activity", 733 "nand-disk", 734 NULL, 735 }; 736 737 if (!deftriggers) 738 deftriggers = default_triggers; 739 iocled = kzalloc(sizeof(*iocled), GFP_KERNEL); 740 if (!iocled) 741 return; 742 iocled->mmioaddr = ioremap(baseaddr, 1); 743 if (!iocled->mmioaddr) 744 goto out_free; 745 iocled->chip.get = txx9_iocled_get; 746 iocled->chip.set = txx9_iocled_set; 747 iocled->chip.direction_input = txx9_iocled_dir_in; 748 iocled->chip.direction_output = txx9_iocled_dir_out; 749 iocled->chip.label = "iocled"; 750 iocled->chip.base = basenum; 751 iocled->chip.ngpio = num; 752 if (gpiochip_add_data(&iocled->chip, iocled)) 753 goto out_unmap; 754 if (basenum < 0) 755 basenum = iocled->chip.base; 756 757 pdev = platform_device_alloc("leds-gpio", basenum); 758 if (!pdev) 759 goto out_gpio; 760 iocled->pdata.num_leds = num; 761 iocled->pdata.leds = iocled->leds; 762 for (i = 0; i < num; i++) { 763 struct gpio_led *led = &iocled->leds[i]; 764 snprintf(iocled->names[i], sizeof(iocled->names[i]), 765 "iocled:%s:%u", color, i); 766 led->name = iocled->names[i]; 767 led->gpio = basenum + i; 768 led->active_low = lowactive; 769 if (deftriggers && *deftriggers) 770 led->default_trigger = *deftriggers++; 771 } 772 pdev->dev.platform_data = &iocled->pdata; 773 if (platform_device_add(pdev)) 774 goto out_pdev; 775 return; 776 777 out_pdev: 778 platform_device_put(pdev); 779 out_gpio: 780 gpiochip_remove(&iocled->chip); 781 out_unmap: 782 iounmap(iocled->mmioaddr); 783 out_free: 784 kfree(iocled); 785 } 786 #else /* CONFIG_LEDS_GPIO */ 787 void __init txx9_iocled_init(unsigned long baseaddr, 788 int basenum, unsigned int num, int lowactive, 789 const char *color, char **deftriggers) 790 { 791 } 792 #endif /* CONFIG_LEDS_GPIO */ 793 794 void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq, 795 const struct txx9dmac_platform_data *pdata) 796 { 797 #if IS_ENABLED(CONFIG_TXX9_DMAC) 798 struct resource res[] = { 799 { 800 .start = baseaddr, 801 .end = baseaddr + 0x800 - 1, 802 .flags = IORESOURCE_MEM, 803 #ifndef CONFIG_MACH_TX49XX 804 }, { 805 .start = irq, 806 .flags = IORESOURCE_IRQ, 807 #endif 808 } 809 }; 810 #ifdef CONFIG_MACH_TX49XX 811 struct resource chan_res[] = { 812 { 813 .flags = IORESOURCE_IRQ, 814 } 815 }; 816 #endif 817 struct platform_device *pdev = platform_device_alloc("txx9dmac", id); 818 struct txx9dmac_chan_platform_data cpdata; 819 int i; 820 821 if (!pdev || 822 platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) || 823 platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 824 platform_device_add(pdev)) { 825 platform_device_put(pdev); 826 return; 827 } 828 memset(&cpdata, 0, sizeof(cpdata)); 829 cpdata.dmac_dev = pdev; 830 for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) { 831 #ifdef CONFIG_MACH_TX49XX 832 chan_res[0].start = irq + i; 833 #endif 834 pdev = platform_device_alloc("txx9dmac-chan", 835 id * TXX9_DMA_MAX_NR_CHANNELS + i); 836 if (!pdev || 837 #ifdef CONFIG_MACH_TX49XX 838 platform_device_add_resources(pdev, chan_res, 839 ARRAY_SIZE(chan_res)) || 840 #endif 841 platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) || 842 platform_device_add(pdev)) 843 platform_device_put(pdev); 844 } 845 #endif 846 } 847 848 void __init txx9_aclc_init(unsigned long baseaddr, int irq, 849 unsigned int dmac_id, 850 unsigned int dma_chan_out, 851 unsigned int dma_chan_in) 852 { 853 #if IS_ENABLED(CONFIG_SND_SOC_TXX9ACLC) 854 unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS; 855 struct resource res[] = { 856 { 857 .start = baseaddr, 858 .end = baseaddr + 0x100 - 1, 859 .flags = IORESOURCE_MEM, 860 }, { 861 .start = irq, 862 .flags = IORESOURCE_IRQ, 863 }, { 864 .name = "txx9dmac-chan", 865 .start = dma_base + dma_chan_out, 866 .flags = IORESOURCE_DMA, 867 }, { 868 .name = "txx9dmac-chan", 869 .start = dma_base + dma_chan_in, 870 .flags = IORESOURCE_DMA, 871 } 872 }; 873 struct platform_device *pdev = 874 platform_device_alloc("txx9aclc-ac97", -1); 875 876 if (!pdev || 877 platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) || 878 platform_device_add(pdev)) 879 platform_device_put(pdev); 880 #endif 881 } 882 883 static struct bus_type txx9_sramc_subsys = { 884 .name = "txx9_sram", 885 .dev_name = "txx9_sram", 886 }; 887 888 struct txx9_sramc_dev { 889 struct device dev; 890 struct bin_attribute bindata_attr; 891 void __iomem *base; 892 }; 893 894 static ssize_t txx9_sram_read(struct file *filp, struct kobject *kobj, 895 struct bin_attribute *bin_attr, 896 char *buf, loff_t pos, size_t size) 897 { 898 struct txx9_sramc_dev *dev = bin_attr->private; 899 size_t ramsize = bin_attr->size; 900 901 if (pos >= ramsize) 902 return 0; 903 if (pos + size > ramsize) 904 size = ramsize - pos; 905 memcpy_fromio(buf, dev->base + pos, size); 906 return size; 907 } 908 909 static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj, 910 struct bin_attribute *bin_attr, 911 char *buf, loff_t pos, size_t size) 912 { 913 struct txx9_sramc_dev *dev = bin_attr->private; 914 size_t ramsize = bin_attr->size; 915 916 if (pos >= ramsize) 917 return 0; 918 if (pos + size > ramsize) 919 size = ramsize - pos; 920 memcpy_toio(dev->base + pos, buf, size); 921 return size; 922 } 923 924 static void txx9_device_release(struct device *dev) 925 { 926 struct txx9_sramc_dev *tdev; 927 928 tdev = container_of(dev, struct txx9_sramc_dev, dev); 929 kfree(tdev); 930 } 931 932 void __init txx9_sramc_init(struct resource *r) 933 { 934 struct txx9_sramc_dev *dev; 935 size_t size; 936 int err; 937 938 err = subsys_system_register(&txx9_sramc_subsys, NULL); 939 if (err) 940 return; 941 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 942 if (!dev) 943 return; 944 size = resource_size(r); 945 dev->base = ioremap(r->start, size); 946 if (!dev->base) { 947 kfree(dev); 948 return; 949 } 950 dev->dev.release = &txx9_device_release; 951 dev->dev.bus = &txx9_sramc_subsys; 952 sysfs_bin_attr_init(&dev->bindata_attr); 953 dev->bindata_attr.attr.name = "bindata"; 954 dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR; 955 dev->bindata_attr.read = txx9_sram_read; 956 dev->bindata_attr.write = txx9_sram_write; 957 dev->bindata_attr.size = size; 958 dev->bindata_attr.private = dev; 959 err = device_register(&dev->dev); 960 if (err) 961 goto exit_put; 962 err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr); 963 if (err) { 964 iounmap(dev->base); 965 device_unregister(&dev->dev); 966 } 967 return; 968 exit_put: 969 iounmap(dev->base); 970 put_device(&dev->dev); 971 } 972