aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c5
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/memory.c62
-rw-r--r--drivers/base/platform.c54
4 files changed, 83 insertions, 41 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index bc8729d603a7..82c865452c70 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1764,8 +1764,8 @@ void device_shutdown(void)
1764 1764
1765#ifdef CONFIG_PRINTK 1765#ifdef CONFIG_PRINTK
1766 1766
1767static int __dev_printk(const char *level, const struct device *dev, 1767int __dev_printk(const char *level, const struct device *dev,
1768 struct va_format *vaf) 1768 struct va_format *vaf)
1769{ 1769{
1770 if (!dev) 1770 if (!dev)
1771 return printk("%s(NULL device *): %pV", level, vaf); 1771 return printk("%s(NULL device *): %pV", level, vaf);
@@ -1773,6 +1773,7 @@ static int __dev_printk(const char *level, const struct device *dev,
1773 return printk("%s%s %s: %pV", 1773 return printk("%s%s %s: %pV",
1774 level, dev_driver_string(dev), dev_name(dev), vaf); 1774 level, dev_driver_string(dev), dev_name(dev), vaf);
1775} 1775}
1776EXPORT_SYMBOL(__dev_printk);
1776 1777
1777int dev_printk(const char *level, const struct device *dev, 1778int dev_printk(const char *level, const struct device *dev,
1778 const char *fmt, ...) 1779 const char *fmt, ...)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 6658da743c3a..142e3d600f14 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -147,6 +147,9 @@ probe_failed:
147 printk(KERN_WARNING 147 printk(KERN_WARNING
148 "%s: probe of %s failed with error %d\n", 148 "%s: probe of %s failed with error %d\n",
149 drv->name, dev_name(dev), ret); 149 drv->name, dev_name(dev), ret);
150 } else {
151 pr_debug("%s: probe of %s rejects match %d\n",
152 drv->name, dev_name(dev), ret);
150 } 153 }
151 /* 154 /*
152 * Ignore errors returned by ->probe so that the next driver can try 155 * Ignore errors returned by ->probe so that the next driver can try
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 2840ed4668c1..8272d92d22c0 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -224,13 +224,48 @@ int memory_isolate_notify(unsigned long val, void *v)
224} 224}
225 225
226/* 226/*
227 * The probe routines leave the pages reserved, just as the bootmem code does.
228 * Make sure they're still that way.
229 */
230static bool pages_correctly_reserved(unsigned long start_pfn,
231 unsigned long nr_pages)
232{
233 int i, j;
234 struct page *page;
235 unsigned long pfn = start_pfn;
236
237 /*
238 * memmap between sections is not contiguous except with
239 * SPARSEMEM_VMEMMAP. We lookup the page once per section
240 * and assume memmap is contiguous within each section
241 */
242 for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) {
243 if (WARN_ON_ONCE(!pfn_valid(pfn)))
244 return false;
245 page = pfn_to_page(pfn);
246
247 for (j = 0; j < PAGES_PER_SECTION; j++) {
248 if (PageReserved(page + j))
249 continue;
250
251 printk(KERN_WARNING "section number %ld page number %d "
252 "not reserved, was it already online?\n",
253 pfn_to_section_nr(pfn), j);
254
255 return false;
256 }
257 }
258
259 return true;
260}
261
262/*
227 * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is 263 * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
228 * OK to have direct references to sparsemem variables in here. 264 * OK to have direct references to sparsemem variables in here.
229 */ 265 */
230static int 266static int
231memory_block_action(unsigned long phys_index, unsigned long action) 267memory_block_action(unsigned long phys_index, unsigned long action)
232{ 268{
233 int i;
234 unsigned long start_pfn, start_paddr; 269 unsigned long start_pfn, start_paddr;
235 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; 270 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
236 struct page *first_page; 271 struct page *first_page;
@@ -238,26 +273,13 @@ memory_block_action(unsigned long phys_index, unsigned long action)
238 273
239 first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); 274 first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
240 275
241 /*
242 * The probe routines leave the pages reserved, just
243 * as the bootmem code does. Make sure they're still
244 * that way.
245 */
246 if (action == MEM_ONLINE) {
247 for (i = 0; i < nr_pages; i++) {
248 if (PageReserved(first_page+i))
249 continue;
250
251 printk(KERN_WARNING "section number %ld page number %d "
252 "not reserved, was it already online?\n",
253 phys_index, i);
254 return -EBUSY;
255 }
256 }
257
258 switch (action) { 276 switch (action) {
259 case MEM_ONLINE: 277 case MEM_ONLINE:
260 start_pfn = page_to_pfn(first_page); 278 start_pfn = page_to_pfn(first_page);
279
280 if (!pages_correctly_reserved(start_pfn, nr_pages))
281 return -EBUSY;
282
261 ret = online_pages(start_pfn, nr_pages); 283 ret = online_pages(start_pfn, nr_pages);
262 break; 284 break;
263 case MEM_OFFLINE: 285 case MEM_OFFLINE:
@@ -380,9 +402,13 @@ memory_probe_store(struct class *class, struct class_attribute *attr,
380 u64 phys_addr; 402 u64 phys_addr;
381 int nid; 403 int nid;
382 int i, ret; 404 int i, ret;
405 unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
383 406
384 phys_addr = simple_strtoull(buf, NULL, 0); 407 phys_addr = simple_strtoull(buf, NULL, 0);
385 408
409 if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
410 return -EINVAL;
411
386 for (i = 0; i < sections_per_block; i++) { 412 for (i = 0; i < sections_per_block; i++) {
387 nid = memory_add_physaddr_to_nid(phys_addr); 413 nid = memory_add_physaddr_to_nid(phys_addr);
388 ret = add_memory(nid, phys_addr, 414 ret = add_memory(nid, phys_addr,
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272d7c2f..7a24895543e7 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev)
375EXPORT_SYMBOL_GPL(platform_device_unregister); 375EXPORT_SYMBOL_GPL(platform_device_unregister);
376 376
377/** 377/**
378 * platform_device_register_resndata - add a platform-level device with 378 * platform_device_register_full - add a platform-level device with
379 * resources and platform-specific data 379 * resources and platform-specific data
380 * 380 *
381 * @parent: parent device for the device we're adding 381 * @pdevinfo: data used to create device
382 * @name: base name of the device we're adding
383 * @id: instance id
384 * @res: set of resources that needs to be allocated for the device
385 * @num: number of resources
386 * @data: platform specific data for this platform device
387 * @size: size of platform specific data
388 * 382 *
389 * Returns &struct platform_device pointer on success, or ERR_PTR() on error. 383 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
390 */ 384 */
391struct platform_device *platform_device_register_resndata( 385struct platform_device *platform_device_register_full(
392 struct device *parent, 386 struct platform_device_info *pdevinfo)
393 const char *name, int id,
394 const struct resource *res, unsigned int num,
395 const void *data, size_t size)
396{ 387{
397 int ret = -ENOMEM; 388 int ret = -ENOMEM;
398 struct platform_device *pdev; 389 struct platform_device *pdev;
399 390
400 pdev = platform_device_alloc(name, id); 391 pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
401 if (!pdev) 392 if (!pdev)
402 goto err; 393 goto err_alloc;
403 394
404 pdev->dev.parent = parent; 395 pdev->dev.parent = pdevinfo->parent;
396
397 if (pdevinfo->dma_mask) {
398 /*
399 * This memory isn't freed when the device is put,
400 * I don't have a nice idea for that though. Conceptually
401 * dma_mask in struct device should not be a pointer.
402 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
403 */
404 pdev->dev.dma_mask =
405 kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
406 if (!pdev->dev.dma_mask)
407 goto err;
408
409 *pdev->dev.dma_mask = pdevinfo->dma_mask;
410 pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
411 }
405 412
406 ret = platform_device_add_resources(pdev, res, num); 413 ret = platform_device_add_resources(pdev,
414 pdevinfo->res, pdevinfo->num_res);
407 if (ret) 415 if (ret)
408 goto err; 416 goto err;
409 417
410 ret = platform_device_add_data(pdev, data, size); 418 ret = platform_device_add_data(pdev,
419 pdevinfo->data, pdevinfo->size_data);
411 if (ret) 420 if (ret)
412 goto err; 421 goto err;
413 422
414 ret = platform_device_add(pdev); 423 ret = platform_device_add(pdev);
415 if (ret) { 424 if (ret) {
416err: 425err:
426 kfree(pdev->dev.dma_mask);
427
428err_alloc:
417 platform_device_put(pdev); 429 platform_device_put(pdev);
418 return ERR_PTR(ret); 430 return ERR_PTR(ret);
419 } 431 }
420 432
421 return pdev; 433 return pdev;
422} 434}
423EXPORT_SYMBOL_GPL(platform_device_register_resndata); 435EXPORT_SYMBOL_GPL(platform_device_register_full);
424 436
425static int platform_drv_probe(struct device *_dev) 437static int platform_drv_probe(struct device *_dev)
426{ 438{
@@ -614,7 +626,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
614 return rc; 626 return rc;
615 627
616 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, 628 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
617 (pdev->id_entry) ? pdev->id_entry->name : pdev->name); 629 pdev->name);
618 return 0; 630 return 0;
619} 631}
620 632