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

C6X: general SoC support

This patch provides a soc_ops struct which provides hooks for SoC functionality
which doesn't fit well into other places.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Aurelien Jacquiot <a-jacquiot@ti.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>

+126
+35
arch/c6x/include/asm/soc.h
··· 1 + /* 2 + * Miscellaneous SoC-specific hooks. 3 + * 4 + * Copyright (C) 2011 Texas Instruments Incorporated 5 + * 6 + * Author: Mark Salter <msalter@redhat.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public License 9 + * version 2. This program is licensed "as is" without any warranty of any 10 + * kind, whether express or implied. 11 + */ 12 + #ifndef _ASM_C6X_SOC_H 13 + #define _ASM_C6X_SOC_H 14 + 15 + struct soc_ops { 16 + /* Return active exception event or -1 if none */ 17 + int (*get_exception)(void); 18 + 19 + /* Assert an event */ 20 + void (*assert_event)(unsigned int evt); 21 + }; 22 + 23 + extern struct soc_ops soc_ops; 24 + 25 + extern int soc_get_exception(void); 26 + extern void soc_assert_event(unsigned int event); 27 + extern int soc_mac_addr(unsigned int index, u8 *addr); 28 + 29 + /* 30 + * for mmio on SoC devices. regs are always same byte order as cpu. 31 + */ 32 + #define soc_readl(addr) __raw_readl(addr) 33 + #define soc_writel(b, addr) __raw_writel((b), (addr)) 34 + 35 + #endif /* _ASM_C6X_SOC_H */
+91
arch/c6x/kernel/soc.c
··· 1 + /* 2 + * Miscellaneous SoC-specific hooks. 3 + * 4 + * Copyright (C) 2011 Texas Instruments Incorporated 5 + * Author: Mark Salter <msalter@redhat.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + #include <linux/module.h> 12 + #include <linux/ctype.h> 13 + #include <linux/etherdevice.h> 14 + #include <asm/system.h> 15 + #include <asm/setup.h> 16 + #include <asm/soc.h> 17 + 18 + struct soc_ops soc_ops; 19 + 20 + int soc_get_exception(void) 21 + { 22 + if (!soc_ops.get_exception) 23 + return -1; 24 + return soc_ops.get_exception(); 25 + } 26 + 27 + void soc_assert_event(unsigned int evt) 28 + { 29 + if (soc_ops.assert_event) 30 + soc_ops.assert_event(evt); 31 + } 32 + 33 + static u8 cmdline_mac[6]; 34 + 35 + static int __init get_mac_addr_from_cmdline(char *str) 36 + { 37 + int count, i, val; 38 + 39 + for (count = 0; count < 6 && *str; count++, str += 3) { 40 + if (!isxdigit(str[0]) || !isxdigit(str[1])) 41 + return 0; 42 + if (str[2] != ((count < 5) ? ':' : '\0')) 43 + return 0; 44 + 45 + for (i = 0, val = 0; i < 2; i++) { 46 + val = val << 4; 47 + val |= isdigit(str[i]) ? 48 + str[i] - '0' : toupper(str[i]) - 'A' + 10; 49 + } 50 + cmdline_mac[count] = val; 51 + } 52 + return 1; 53 + } 54 + __setup("emac_addr=", get_mac_addr_from_cmdline); 55 + 56 + /* 57 + * Setup the MAC address for SoC ethernet devices. 58 + * 59 + * Before calling this function, the ethernet driver will have 60 + * initialized the addr with local-mac-address from the device 61 + * tree (if found). Allow command line to override, but not 62 + * the fused address. 63 + */ 64 + int soc_mac_addr(unsigned int index, u8 *addr) 65 + { 66 + int i, have_dt_mac = 0, have_cmdline_mac = 0, have_fuse_mac = 0; 67 + 68 + for (i = 0; i < 6; i++) { 69 + if (cmdline_mac[i]) 70 + have_cmdline_mac = 1; 71 + if (c6x_fuse_mac[i]) 72 + have_fuse_mac = 1; 73 + if (addr[i]) 74 + have_dt_mac = 1; 75 + } 76 + 77 + /* cmdline overrides all */ 78 + if (have_cmdline_mac) 79 + memcpy(addr, cmdline_mac, 6); 80 + else if (!have_dt_mac) { 81 + if (have_fuse_mac) 82 + memcpy(addr, c6x_fuse_mac, 6); 83 + else 84 + random_ether_addr(addr); 85 + } 86 + 87 + /* adjust for specific EMAC device */ 88 + addr[5] += index * c6x_num_cores; 89 + return 1; 90 + } 91 + EXPORT_SYMBOL_GPL(soc_mac_addr);