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

Merge master.kernel.org:/home/rmk/linux-2.6-drvmodel

+182 -123
+126 -27
drivers/base/platform.c
··· 116 116 return ret; 117 117 } 118 118 119 + struct platform_object { 120 + struct platform_device pdev; 121 + char name[1]; 122 + }; 123 + 119 124 /** 120 - * platform_device_register - add a platform-level device 125 + * platform_device_put 126 + * @pdev: platform device to free 127 + * 128 + * Free all memory associated with a platform device. This function 129 + * must _only_ be externally called in error cases. All other usage 130 + * is a bug. 131 + */ 132 + void platform_device_put(struct platform_device *pdev) 133 + { 134 + if (pdev) 135 + put_device(&pdev->dev); 136 + } 137 + EXPORT_SYMBOL_GPL(platform_device_put); 138 + 139 + static void platform_device_release(struct device *dev) 140 + { 141 + struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); 142 + 143 + kfree(pa->pdev.dev.platform_data); 144 + kfree(pa->pdev.resource); 145 + kfree(pa); 146 + } 147 + 148 + /** 149 + * platform_device_alloc 150 + * @name: base name of the device we're adding 151 + * @id: instance id 152 + * 153 + * Create a platform device object which can have other objects attached 154 + * to it, and which will have attached objects freed when it is released. 155 + */ 156 + struct platform_device *platform_device_alloc(const char *name, unsigned int id) 157 + { 158 + struct platform_object *pa; 159 + 160 + pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL); 161 + if (pa) { 162 + strcpy(pa->name, name); 163 + pa->pdev.name = pa->name; 164 + pa->pdev.id = id; 165 + device_initialize(&pa->pdev.dev); 166 + pa->pdev.dev.release = platform_device_release; 167 + } 168 + 169 + return pa ? &pa->pdev : NULL; 170 + } 171 + EXPORT_SYMBOL_GPL(platform_device_alloc); 172 + 173 + /** 174 + * platform_device_add_resources 175 + * @pdev: platform device allocated by platform_device_alloc to add resources to 176 + * @res: set of resources that needs to be allocated for the device 177 + * @num: number of resources 178 + * 179 + * Add a copy of the resources to the platform device. The memory 180 + * associated with the resources will be freed when the platform 181 + * device is released. 182 + */ 183 + int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num) 184 + { 185 + struct resource *r; 186 + 187 + r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); 188 + if (r) { 189 + memcpy(r, res, sizeof(struct resource) * num); 190 + pdev->resource = r; 191 + pdev->num_resources = num; 192 + } 193 + return r ? 0 : -ENOMEM; 194 + } 195 + EXPORT_SYMBOL_GPL(platform_device_add_resources); 196 + 197 + /** 198 + * platform_device_add_data 199 + * @pdev: platform device allocated by platform_device_alloc to add resources to 200 + * @data: platform specific data for this platform device 201 + * @size: size of platform specific data 202 + * 203 + * Add a copy of platform specific data to the platform device's platform_data 204 + * pointer. The memory associated with the platform data will be freed 205 + * when the platform device is released. 206 + */ 207 + int platform_device_add_data(struct platform_device *pdev, void *data, size_t size) 208 + { 209 + void *d; 210 + 211 + d = kmalloc(size, GFP_KERNEL); 212 + if (d) { 213 + memcpy(d, data, size); 214 + pdev->dev.platform_data = d; 215 + } 216 + return d ? 0 : -ENOMEM; 217 + } 218 + EXPORT_SYMBOL_GPL(platform_device_add_data); 219 + 220 + /** 221 + * platform_device_add - add a platform device to device hierarchy 121 222 * @pdev: platform device we're adding 122 223 * 224 + * This is part 2 of platform_device_register(), though may be called 225 + * separately _iff_ pdev was allocated by platform_device_alloc(). 123 226 */ 124 - int platform_device_register(struct platform_device * pdev) 227 + int platform_device_add(struct platform_device *pdev) 125 228 { 126 229 int i, ret = 0; 127 230 ··· 277 174 release_resource(&pdev->resource[i]); 278 175 return ret; 279 176 } 177 + EXPORT_SYMBOL_GPL(platform_device_add); 178 + 179 + /** 180 + * platform_device_register - add a platform-level device 181 + * @pdev: platform device we're adding 182 + * 183 + */ 184 + int platform_device_register(struct platform_device * pdev) 185 + { 186 + device_initialize(&pdev->dev); 187 + return platform_device_add(pdev); 188 + } 280 189 281 190 /** 282 191 * platform_device_unregister - remove a platform-level device ··· 312 197 } 313 198 } 314 199 315 - struct platform_object { 316 - struct platform_device pdev; 317 - struct resource resources[0]; 318 - }; 319 - 320 - static void platform_device_release_simple(struct device *dev) 321 - { 322 - struct platform_device *pdev = to_platform_device(dev); 323 - 324 - kfree(container_of(pdev, struct platform_object, pdev)); 325 - } 326 - 327 200 /** 328 201 * platform_device_register_simple 329 202 * @name: base name of the device we're adding ··· 328 225 struct platform_device *platform_device_register_simple(char *name, unsigned int id, 329 226 struct resource *res, unsigned int num) 330 227 { 331 - struct platform_object *pobj; 228 + struct platform_device *pdev; 332 229 int retval; 333 230 334 - pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL); 335 - if (!pobj) { 231 + pdev = platform_device_alloc(name, id); 232 + if (!pdev) { 336 233 retval = -ENOMEM; 337 234 goto error; 338 235 } 339 236 340 - pobj->pdev.name = name; 341 - pobj->pdev.id = id; 342 - pobj->pdev.dev.release = platform_device_release_simple; 343 - 344 237 if (num) { 345 - memcpy(pobj->resources, res, sizeof(struct resource) * num); 346 - pobj->pdev.resource = pobj->resources; 347 - pobj->pdev.num_resources = num; 238 + retval = platform_device_add_resources(pdev, res, num); 239 + if (retval) 240 + goto error; 348 241 } 349 242 350 - retval = platform_device_register(&pobj->pdev); 243 + retval = platform_device_add(pdev); 351 244 if (retval) 352 245 goto error; 353 246 354 - return &pobj->pdev; 247 + return pdev; 355 248 356 249 error: 357 - kfree(pobj); 250 + platform_device_put(pdev); 358 251 return ERR_PTR(retval); 359 252 } 360 253
+7 -17
drivers/net/depca.c
··· 1470 1470 ** ISA bus I/O device probe 1471 1471 */ 1472 1472 1473 - static void depca_platform_release (struct device *device) 1474 - { 1475 - struct platform_device *pldev; 1476 - 1477 - /* free device */ 1478 - pldev = to_platform_device (device); 1479 - kfree (pldev); 1480 - } 1481 - 1482 1473 static void __init depca_platform_probe (void) 1483 1474 { 1484 1475 int i; ··· 1482 1491 * line, use it (if valid) */ 1483 1492 if (io && io != depca_io_ports[i].iobase) 1484 1493 continue; 1485 - 1486 - if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) 1494 + 1495 + pldev = platform_device_alloc(depca_string, i); 1496 + if (!pldev) 1487 1497 continue; 1488 1498 1489 - memset (pldev, 0, sizeof (*pldev)); 1490 - pldev->name = depca_string; 1491 - pldev->id = i; 1492 1499 pldev->dev.platform_data = (void *) depca_io_ports[i].iobase; 1493 - pldev->dev.release = depca_platform_release; 1494 1500 depca_io_ports[i].device = pldev; 1495 1501 1496 - if (platform_device_register (pldev)) { 1497 - kfree (pldev); 1502 + if (platform_device_add(pldev)) { 1503 + platform_device_put(pldev); 1498 1504 depca_io_ports[i].device = NULL; 1499 1505 continue; 1500 1506 } ··· 1503 1515 * allocated structure */ 1504 1516 1505 1517 depca_io_ports[i].device = NULL; 1518 + pldev->dev.platform_data = NULL; 1506 1519 platform_device_unregister (pldev); 1507 1520 } 1508 1521 } ··· 2101 2112 2102 2113 for (i = 0; depca_io_ports[i].iobase; i++) { 2103 2114 if (depca_io_ports[i].device) { 2115 + depca_io_ports[i].device->dev.platform_data = NULL; 2104 2116 platform_device_unregister (depca_io_ports[i].device); 2105 2117 depca_io_ports[i].device = NULL; 2106 2118 }
+5 -23
drivers/net/jazzsonic.c
··· 285 285 .remove = __devexit_p(jazz_sonic_device_remove), 286 286 }; 287 287 288 - static void jazz_sonic_platform_release (struct device *device) 289 - { 290 - struct platform_device *pldev; 291 - 292 - /* free device */ 293 - pldev = to_platform_device (device); 294 - kfree (pldev); 295 - } 296 - 297 288 static int __init jazz_sonic_init_module(void) 298 289 { 299 - struct platform_device *pldev; 300 290 int err; 301 291 302 292 if ((err = driver_register(&jazz_sonic_driver))) { ··· 294 304 return err; 295 305 } 296 306 297 - jazz_sonic_device = NULL; 298 - 299 - if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { 307 + jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0); 308 + if (!jazz_sonnic_device) 300 309 goto out_unregister; 301 - } 302 310 303 - memset(pldev, 0, sizeof (*pldev)); 304 - pldev->name = jazz_sonic_string; 305 - pldev->id = 0; 306 - pldev->dev.release = jazz_sonic_platform_release; 307 - jazz_sonic_device = pldev; 308 - 309 - if (platform_device_register (pldev)) { 310 - kfree(pldev); 311 + if (platform_device_add(jazz_sonic_device)) { 312 + platform_device_put(jazz_sonic_device); 311 313 jazz_sonic_device = NULL; 312 314 } 313 315 314 316 return 0; 315 317 316 318 out_unregister: 317 - platform_device_unregister(pldev); 319 + driver_unregister(&jazz_sonic_driver); 318 320 319 321 return -ENOMEM; 320 322 }
+5 -22
drivers/net/macsonic.c
··· 599 599 .remove = __devexit_p(mac_sonic_device_remove), 600 600 }; 601 601 602 - static void mac_sonic_platform_release(struct device *device) 603 - { 604 - struct platform_device *pldev; 605 - 606 - /* free device */ 607 - pldev = to_platform_device (device); 608 - kfree (pldev); 609 - } 610 - 611 602 static int __init mac_sonic_init_module(void) 612 603 { 613 - struct platform_device *pldev; 614 604 int err; 615 605 616 606 if ((err = driver_register(&mac_sonic_driver))) { ··· 608 618 return err; 609 619 } 610 620 611 - mac_sonic_device = NULL; 612 - 613 - if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { 621 + mac_sonic_device = platform_device_alloc(mac_sonic_string, 0); 622 + if (!mac_sonic_device) { 614 623 goto out_unregister; 615 624 } 616 625 617 - memset(pldev, 0, sizeof (*pldev)); 618 - pldev->name = mac_sonic_string; 619 - pldev->id = 0; 620 - pldev->dev.release = mac_sonic_platform_release; 621 - mac_sonic_device = pldev; 622 - 623 - if (platform_device_register (pldev)) { 624 - kfree(pldev); 626 + if (platform_device_add(mac_sonic_device)) { 627 + platform_device_put(mac_sonic_device); 625 628 mac_sonic_device = NULL; 626 629 } 627 630 628 631 return 0; 629 632 630 633 out_unregister: 631 - platform_device_unregister(pldev); 634 + driver_unregister(&mac_sonic_driver); 632 635 633 636 return -ENOMEM; 634 637 }
+11 -14
drivers/video/arcfb.c
··· 502 502 return err; 503 503 } 504 504 505 - static void arcfb_platform_release(struct device *device) 506 - { 507 - } 508 - 509 505 static struct fb_ops arcfb_ops = { 510 506 .owner = THIS_MODULE, 511 507 .fb_open = arcfb_open, ··· 620 624 .remove = arcfb_remove, 621 625 }; 622 626 623 - static struct platform_device arcfb_device = { 624 - .name = "arcfb", 625 - .id = 0, 626 - .dev = { 627 - .release = arcfb_platform_release, 628 - } 629 - }; 627 + static struct platform_device *arcfb_device; 630 628 631 629 static int __init arcfb_init(void) 632 630 { ··· 631 641 632 642 ret = driver_register(&arcfb_driver); 633 643 if (!ret) { 634 - ret = platform_device_register(&arcfb_device); 635 - if (ret) 644 + arcfb_device = platform_device_alloc("arcfb", 0); 645 + if (arcfb_device) { 646 + ret = platform_device_add(arcfb_device); 647 + } else { 648 + ret = -ENOMEM; 649 + } 650 + if (ret) { 651 + platform_device_put(arcfb_device); 636 652 driver_unregister(&arcfb_driver); 653 + } 637 654 } 638 655 return ret; 639 656 ··· 648 651 649 652 static void __exit arcfb_exit(void) 650 653 { 651 - platform_device_unregister(&arcfb_device); 654 + platform_device_unregister(arcfb_device); 652 655 driver_unregister(&arcfb_driver); 653 656 } 654 657
+12 -6
drivers/video/gbefb.c
··· 1260 1260 .remove = __devexit_p(gbefb_remove), 1261 1261 }; 1262 1262 1263 - static struct platform_device gbefb_device = { 1264 - .name = "gbefb", 1265 - }; 1263 + static struct platform_device *gbefb_device; 1266 1264 1267 1265 int __init gbefb_init(void) 1268 1266 { 1269 1267 int ret = driver_register(&gbefb_driver); 1270 1268 if (!ret) { 1271 - ret = platform_device_register(&gbefb_device); 1272 - if (ret) 1269 + gbefb_device = platform_device_alloc("gbefb", 0); 1270 + if (gbefb_device) { 1271 + ret = platform_device_add(gbefb_device); 1272 + } else { 1273 + ret = -ENOMEM; 1274 + } 1275 + if (ret) { 1276 + platform_device_put(gbefb_device); 1273 1277 driver_unregister(&gbefb_driver); 1278 + } 1274 1279 } 1275 1280 return ret; 1276 1281 } 1277 1282 1278 1283 void __exit gbefb_exit(void) 1279 1284 { 1280 - driver_unregister(&gbefb_driver); 1285 + platform_device_unregister(gbefb_device); 1286 + driver_unregister(&gbefb_driver); 1281 1287 } 1282 1288 1283 1289 module_init(gbefb_init);
+10 -14
drivers/video/sgivwfb.c
··· 751 751 /* 752 752 * Initialisation 753 753 */ 754 - static void sgivwfb_release(struct device *device) 755 - { 756 - } 757 - 758 754 static int __init sgivwfb_probe(struct device *device) 759 755 { 760 756 struct platform_device *dev = to_platform_device(device); ··· 855 859 .remove = sgivwfb_remove, 856 860 }; 857 861 858 - static struct platform_device sgivwfb_device = { 859 - .name = "sgivwfb", 860 - .id = 0, 861 - .dev = { 862 - .release = sgivwfb_release, 863 - } 864 - }; 862 + static struct platform_device *sgivwfb_device; 865 863 866 864 int __init sgivwfb_init(void) 867 865 { ··· 870 880 #endif 871 881 ret = driver_register(&sgivwfb_driver); 872 882 if (!ret) { 873 - ret = platform_device_register(&sgivwfb_device); 874 - if (ret) 883 + sgivwfb_device = platform_device_alloc("sgivwfb", 0); 884 + if (sgivwfb_device) { 885 + ret = platform_device_add(sgivwfb_device); 886 + } else 887 + ret = -ENOMEM; 888 + if (ret) { 875 889 driver_unregister(&sgivwfb_driver); 890 + platform_device_put(sgivwfb_device); 891 + } 876 892 } 877 893 return ret; 878 894 } ··· 890 894 891 895 static void __exit sgivwfb_exit(void) 892 896 { 893 - platform_device_unregister(&sgivwfb_device); 897 + platform_device_unregister(sgivwfb_device); 894 898 driver_unregister(&sgivwfb_driver); 895 899 } 896 900
+6
include/linux/platform_device.h
··· 37 37 38 38 extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int); 39 39 40 + extern struct platform_device *platform_device_alloc(const char *name, unsigned int id); 41 + extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num); 42 + extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size); 43 + extern int platform_device_add(struct platform_device *pdev); 44 + extern void platform_device_put(struct platform_device *pdev); 45 + 40 46 #endif /* _PLATFORM_DEVICE_H_ */