at v2.6.14 153 lines 3.5 kB view raw
1/* 2 * arch/ppc/syslib/ppc_sys.c 3 * 4 * PPC System library functions 5 * 6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 7 * 8 * Copyright 2005 Freescale Semiconductor Inc. 9 * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2 of the License, or (at your 14 * option) any later version. 15 */ 16 17#include <asm/ppc_sys.h> 18 19int (*ppc_sys_device_fixup) (struct platform_device * pdev); 20 21static int ppc_sys_inited; 22 23void __init identify_ppc_sys_by_id(u32 id) 24{ 25 unsigned int i = 0; 26 while (1) { 27 if ((ppc_sys_specs[i].mask & id) == ppc_sys_specs[i].value) 28 break; 29 i++; 30 } 31 32 cur_ppc_sys_spec = &ppc_sys_specs[i]; 33 34 return; 35} 36 37void __init identify_ppc_sys_by_name(char *name) 38{ 39 unsigned int i = 0; 40 while (ppc_sys_specs[i].ppc_sys_name[0]) 41 { 42 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name)) 43 break; 44 i++; 45 } 46 cur_ppc_sys_spec = &ppc_sys_specs[i]; 47 return; 48} 49 50static int __init count_sys_specs(void) 51{ 52 int i = 0; 53 while (ppc_sys_specs[i].ppc_sys_name[0]) 54 i++; 55 return i; 56} 57 58static int __init find_chip_by_name_and_id(char *name, u32 id) 59{ 60 int ret = -1; 61 unsigned int i = 0; 62 unsigned int j = 0; 63 unsigned int dups = 0; 64 65 unsigned char matched[count_sys_specs()]; 66 67 while (ppc_sys_specs[i].ppc_sys_name[0]) { 68 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name)) 69 matched[j++] = i; 70 i++; 71 } 72 if (j != 0) { 73 for (i = 0; i < j; i++) { 74 if ((ppc_sys_specs[matched[i]].mask & id) == 75 ppc_sys_specs[matched[i]].value) { 76 ret = matched[i]; 77 dups++; 78 } 79 } 80 ret = (dups == 1) ? ret : (-1 * dups); 81 } 82 return ret; 83} 84 85void __init identify_ppc_sys_by_name_and_id(char *name, u32 id) 86{ 87 int i = find_chip_by_name_and_id(name, id); 88 BUG_ON(i < 0); 89 cur_ppc_sys_spec = &ppc_sys_specs[i]; 90} 91 92/* Update all memory resources by paddr, call before platform_device_register */ 93void __init 94ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr) 95{ 96 int i; 97 for (i = 0; i < pdev->num_resources; i++) { 98 struct resource *r = &pdev->resource[i]; 99 if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) { 100 r->start += paddr; 101 r->end += paddr; 102 } 103 } 104} 105 106/* Get platform_data pointer out of platform device, call before platform_device_register */ 107void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev) 108{ 109 return ppc_sys_platform_devices[dev].dev.platform_data; 110} 111 112void ppc_sys_device_remove(enum ppc_sys_devices dev) 113{ 114 unsigned int i; 115 116 if (ppc_sys_inited) { 117 platform_device_unregister(&ppc_sys_platform_devices[dev]); 118 } else { 119 if (cur_ppc_sys_spec == NULL) 120 return; 121 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) 122 if (cur_ppc_sys_spec->device_list[i] == dev) 123 cur_ppc_sys_spec->device_list[i] = -1; 124 } 125} 126 127static int __init ppc_sys_init(void) 128{ 129 unsigned int i, dev_id, ret = 0; 130 131 BUG_ON(cur_ppc_sys_spec == NULL); 132 133 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) { 134 dev_id = cur_ppc_sys_spec->device_list[i]; 135 if (dev_id != -1) { 136 if (ppc_sys_device_fixup != NULL) 137 ppc_sys_device_fixup(&ppc_sys_platform_devices 138 [dev_id]); 139 if (platform_device_register 140 (&ppc_sys_platform_devices[dev_id])) { 141 ret = 1; 142 printk(KERN_ERR 143 "unable to register device %d\n", 144 dev_id); 145 } 146 } 147 } 148 149 ppc_sys_inited = 1; 150 return ret; 151} 152 153subsys_initcall(ppc_sys_init);