mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [GIT PATCH] driver core merge for .37-rc1
@ 2010-10-22 17:51 Greg KH
  2010-10-22 18:24 ` [PATCH 01/31] Dynamic Debug: Split out query string parsing/setup from proc_write Greg Kroah-Hartman
                   ` (30 more replies)
  0 siblings, 31 replies; 32+ messages in thread
From: Greg KH @ 2010-10-22 17:51 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel

Here's the big driver-core merge for .37-rc1

The largest thing in here is a new misc driver, which seemed to make
sense to go through this tree.  Other than that, it's a number of small
things, all described below.

Please pull from:
	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git/

All of these patches have been in the linux-next and mm trees for a
while now.

The patches will be sent as a follow-on to this message to lkml for
people to see.

thanks,

greg k-h

------------

 Documentation/ABI/testing/sysfs-module |   12 +
 Documentation/dynamic-debug-howto.txt  |   22 +-
 Documentation/kernel-parameters.txt    |   16 +-
 MAINTAINERS                            |    4 +-
 block/genhd.c                          |    7 +-
 drivers/base/Kconfig                   |    1 -
 drivers/base/Makefile                  |    4 +-
 drivers/base/bus.c                     |   22 -
 drivers/base/class.c                   |   23 +-
 drivers/base/core.c                    |  208 ++--------
 drivers/base/memory.c                  |   94 +++--
 drivers/base/node.c                    |    8 +-
 drivers/base/platform.c                |   80 +++-
 drivers/base/sys.c                     |    8 +-
 drivers/misc/Kconfig                   |   22 +-
 drivers/misc/Makefile                  |    1 +
 drivers/misc/hpilo.c                   |    2 +-
 drivers/misc/pch_phub.c                |  717 ++++++++++++++++++++++++++++++++
 drivers/scsi/hosts.c                   |    2 -
 drivers/scsi/scsi_scan.c               |    2 -
 drivers/uio/uio.c                      |  163 +++-----
 drivers/uio/uio_pci_generic.c          |   13 +-
 fs/partitions/check.c                  |   19 +-
 fs/sysfs/bin.c                         |   68 ++--
 include/linux/device.h                 |    7 +
 include/linux/kobject.h                |    2 +
 include/linux/memory.h                 |    4 +
 include/linux/platform_device.h        |    3 +
 include/linux/uio_driver.h             |    2 +-
 include/sound/core.h                   |    6 -
 init/Kconfig                           |   64 ++--
 lib/dynamic_debug.c                    |   98 ++++--
 lib/kobject.c                          |   39 ++
 sound/core/init.c                      |   11 +-
 34 files changed, 1238 insertions(+), 516 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-module
 create mode 100644 drivers/misc/pch_phub.c

---------------

Andi Kleen (1):
      SYSFS: Allow boot time switching between deprecated and modern sysfs layout

Anton Vorontsov (2):
      base/platform: Safe handling for NULL platform data and resources
      base/platform: Simplifications for NULL platform data/resources handling

Eric W. Biederman (7):
      uio: Fix lack of locking in init_uio_class
      uio: Don't clear driver data
      uio: Cleanup irq handling.
      uio: Support 2^MINOR_BITS minors
      uio: Statically allocate uio_class and use class .dev_attrs.
      sysfs: Fail bin file mmap if vma close is implemented.
      sysfs: only access bin file vm_ops with the active lock

Greg Kroah-Hartman (2):
      pch_phub: fix build warnings
      debugfs: mark me as the maintainer

Kay Sievers (1):
      driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices

Kevin Hilman (1):
      driver core: platform_bus: allow runtime override of dev_pm_ops

Kulikov Vasiliy (1):
      uio: do not use PCI resources before pci_enable_device()

Mark Brown (1):
      driver core: Display error codes when class suspend fails

Masayuki Ohtak (1):
      add Packet hub driver for Topcliff Platform controller hub

Nathan Fontenot (3):
      Driver core: Move find_memory_block routine
      Driver core: Add mutex for adding/removing memory blocks
      Driver core: Add section count to memory_block struct

Patrick Pannuto (1):
      driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type

Randy Dunlap (2):
      FW_LOADER: fix kconfig dependency warning on HOTPLUG
      driver core: fix build for CONFIG_BLOCK not enabled

Robin Holt (3):
      kobject: Introduce kset_find_obj_hinted.
      driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
      driver core: Convert link_mem_sections to use find_memory_block_hinted.

Thomas Renninger (3):
      Dynamic Debug: Split out query string parsing/setup from proc_write
      Dynamic Debug: Introduce ddebug_query= boot parameter
      Dynamic Debug: Initialize dynamic debug earlier via arch_initcall

dann frazier (1):
      hpilo: Despecificate driver from iLO generation

matt mooney (1):
      driver-core: base: change to new flag variable


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 01/31] Dynamic Debug: Split out query string parsing/setup from proc_write
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 02/31] Dynamic Debug: Introduce ddebug_query= boot parameter Greg Kroah-Hartman
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Thomas Renninger, Greg Kroah-Hartman

From: Thomas Renninger <trenn@suse.de>

The parsing and applying of dynamic debug strings is not only useful for
/sys/../dynamic_debug/control write access, but can also be used for
boot parameter parsing.
The boot parameter is introduced in a follow up patch.

Signed-off-by: Thomas Renninger <trenn@suse.de>
Acked-by: jbaron@redhat.com
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 lib/dynamic_debug.c |   40 +++++++++++++++++++++++++---------------
 1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 02afc25..84d103c4 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -429,6 +429,27 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
 	return 0;
 }
 
+static int ddebug_exec_query(char *query_string)
+{
+	unsigned int flags = 0, mask = 0;
+	struct ddebug_query query;
+#define MAXWORDS 9
+	int nwords;
+	char *words[MAXWORDS];
+
+	nwords = ddebug_tokenize(query_string, words, MAXWORDS);
+	if (nwords <= 0)
+		return -EINVAL;
+	if (ddebug_parse_query(words, nwords-1, &query))
+		return -EINVAL;
+	if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
+		return -EINVAL;
+
+	/* actually go and implement the change */
+	ddebug_change(&query, flags, mask);
+	return 0;
+}
+
 /*
  * File_ops->write method for <debugfs>/dynamic_debug/conrol.  Gathers the
  * command text from userspace, parses and executes it.
@@ -436,12 +457,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
 static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
 				  size_t len, loff_t *offp)
 {
-	unsigned int flags = 0, mask = 0;
-	struct ddebug_query query;
-#define MAXWORDS 9
-	int nwords;
-	char *words[MAXWORDS];
 	char tmpbuf[256];
+	int ret;
 
 	if (len == 0)
 		return 0;
@@ -455,16 +472,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
 		printk(KERN_INFO "%s: read %d bytes from userspace\n",
 			__func__, (int)len);
 
-	nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
-	if (nwords <= 0)
-		return -EINVAL;
-	if (ddebug_parse_query(words, nwords-1, &query))
-		return -EINVAL;
-	if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
-		return -EINVAL;
-
-	/* actually go and implement the change */
-	ddebug_change(&query, flags, mask);
+	ret = ddebug_exec_query(tmpbuf);
+	if (ret)
+		return ret;
 
 	*offp += len;
 	return len;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 02/31] Dynamic Debug: Introduce ddebug_query= boot parameter
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
  2010-10-22 18:24 ` [PATCH 01/31] Dynamic Debug: Split out query string parsing/setup from proc_write Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 03/31] Dynamic Debug: Initialize dynamic debug earlier via arch_initcall Greg Kroah-Hartman
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Thomas Renninger, Greg Kroah-Hartman

From: Thomas Renninger <trenn@suse.de>

Dynamic debug lacks the ability to enable debug messages at boot time.
One could patch initramfs or service startup scripts to write to
/sys/../dynamic_debug/control, but this sucks.

This patch makes it possible to pass a query in the same format one can
write to /sys/../dynamic_debug/control via boot param.
When dynamic debug gets initialized, this query will automatically be
applied.


Signed-off-by: Thomas Renninger <trenn@suse.de>
Acked-by: jbaron@redhat.com
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/dynamic-debug-howto.txt |   22 +++++++++++++++++++++-
 Documentation/kernel-parameters.txt   |    7 ++++++-
 lib/dynamic_debug.c                   |   25 +++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
index 674c566..58ea64a 100644
--- a/Documentation/dynamic-debug-howto.txt
+++ b/Documentation/dynamic-debug-howto.txt
@@ -24,7 +24,7 @@ Dynamic debug has even more useful features:
    read to display the complete list of known debug statements, to help guide you
 
 Controlling dynamic debug Behaviour
-===============================
+===================================
 
 The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
 control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
@@ -212,6 +212,26 @@ Note the regexp ^[-+=][scp]+$ matches a flags specification.
 Note also that there is no convenient syntax to remove all
 the flags at once, you need to use "-psc".
 
+
+Debug messages during boot process
+==================================
+
+To be able to activate debug messages during the boot process,
+even before userspace and debugfs exists, use the boot parameter:
+ddebug_query="QUERY"
+
+QUERY follows the syntax described above, but must not exceed 1023
+characters. The enablement of debug messages is done as an arch_initcall.
+Thus you can enable debug messages in all code processed after this
+arch_initcall via this boot parameter.
+On an x86 system for example ACPI enablement is a subsys_initcall and
+ddebug_query="file ec.c +p"
+will show early Embedded Controller transactions during ACPI setup if
+your machine (typically a laptop) has an Embedded Controller.
+PCI (or other devices) initialization also is a hot candidate for using
+this boot parameter for debugging purposes.
+
+
 Examples
 ========
 
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 8dd7248..3d854c9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -43,10 +43,11 @@ parameter is applicable:
 	AVR32	AVR32 architecture is enabled.
 	AX25	Appropriate AX.25 support is enabled.
 	BLACKFIN Blackfin architecture is enabled.
-	DRM	Direct Rendering Management support is enabled.
 	EDD	BIOS Enhanced Disk Drive Services (EDD) is enabled
 	EFI	EFI Partitioning (GPT) is enabled
 	EIDE	EIDE/ATAPI support is enabled.
+	DRM	Direct Rendering Management support is enabled.
+	DYNAMIC_DEBUG Build in debug messages and enable them at runtime
 	FB	The frame buffer device is enabled.
 	GCOV	GCOV profiling is enabled.
 	HW	Appropriate hardware is enabled.
@@ -570,6 +571,10 @@ and is between 256 and 4096 characters. It is defined in the file
 			Format: <port#>,<type>
 			See also Documentation/input/joystick-parport.txt
 
+	ddebug_query=   [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
+			time. See Documentation/dynamic-debug-howto.txt for
+			details.
+
 	debug		[KNL] Enable kernel debugging (events log level).
 
 	debug_locks_verbose=
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 84d103c4..44ce66b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -450,6 +450,19 @@ static int ddebug_exec_query(char *query_string)
 	return 0;
 }
 
+static __initdata char ddebug_setup_string[1024];
+static __init int ddebug_setup_query(char *str)
+{
+	if (strlen(str) >= 1024) {
+		pr_warning("ddebug boot param string too large\n");
+		return 0;
+	}
+	strcpy(ddebug_setup_string, str);
+	return 1;
+}
+
+__setup("ddebug_query=", ddebug_setup_query);
+
 /*
  * File_ops->write method for <debugfs>/dynamic_debug/conrol.  Gathers the
  * command text from userspace, parses and executes it.
@@ -769,6 +782,18 @@ static int __init dynamic_debug_init(void)
 		}
 		ret = ddebug_add_module(iter_start, n, modname);
 	}
+
+	/* ddebug_query boot param got passed -> set it up */
+	if (ddebug_setup_string[0] != '\0') {
+		ret = ddebug_exec_query(ddebug_setup_string);
+		if (ret)
+			pr_warning("Invalid ddebug boot param %s",
+				   ddebug_setup_string);
+		else
+			pr_info("ddebug initialized with string %s",
+				ddebug_setup_string);
+	}
+
 out_free:
 	if (ret) {
 		ddebug_remove_all_tables();
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 03/31] Dynamic Debug: Initialize dynamic debug earlier via arch_initcall
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
  2010-10-22 18:24 ` [PATCH 01/31] Dynamic Debug: Split out query string parsing/setup from proc_write Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 02/31] Dynamic Debug: Introduce ddebug_query= boot parameter Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 04/31] driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type Greg Kroah-Hartman
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Thomas Renninger, linux-acpi, Greg Kroah-Hartman

From: Thomas Renninger <trenn@suse.de>

Having the ddebug_query= boot parameter it makes sense to set up
dynamic debug as soon as possible.

I expect sysfs files cannot be set up via an arch_initcall, because
this one is even before fs_initcall. Therefore I splitted the
dynamic_debug_init function into an early one and a later one providing
/sys/../dynamic_debug/control file.

Possibly dynamic_debug can be initialized even earlier, not sure whether
this still makes sense then. I picked up arch_initcall as it covers
quite a lot already.

Dynamic debug needs to allocate memory, therefore it's not easily possible to
set it up even before the command line gets parsed.
Therefore the boot param query string is stored in a temp string which is
applied when dynamic debug gets set up.

This has been tested with ddebug_query="file ec.c +p"
and I could retrieve pr_debug() messages early at boot during ACPI setup:
ACPI: EC: Look up EC in DSDT
ACPI: EC: ---> status = 0x08
ACPI: EC: transaction start
ACPI: EC: <--- command = 0x80
ACPI: EC: ~~~> interrupt
ACPI: EC: ---> status = 0x08
ACPI: EC: <--- data = 0xa4
...
ACPI: Interpreter enabled
ACPI: (supports S0 S3 S4 S5)
ACPI: Using IOAPIC for interrupt routing
ACPI: EC: ---> status = 0x00
ACPI: EC: transaction start
ACPI: EC: <--- command = 0x80


Signed-off-by: Thomas Renninger <trenn@suse.de>
Acked-by: jbaron@redhat.com
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
CC: linux-acpi@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 lib/dynamic_debug.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 44ce66b..a687d90 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -748,13 +748,14 @@ static void ddebug_remove_all_tables(void)
 	mutex_unlock(&ddebug_lock);
 }
 
-static int __init dynamic_debug_init(void)
+static __initdata int ddebug_init_success;
+
+static int __init dynamic_debug_init_debugfs(void)
 {
 	struct dentry *dir, *file;
-	struct _ddebug *iter, *iter_start;
-	const char *modname = NULL;
-	int ret = 0;
-	int n = 0;
+
+	if (!ddebug_init_success)
+		return -ENODEV;
 
 	dir = debugfs_create_dir("dynamic_debug", NULL);
 	if (!dir)
@@ -765,6 +766,16 @@ static int __init dynamic_debug_init(void)
 		debugfs_remove(dir);
 		return -ENOMEM;
 	}
+	return 0;
+}
+
+static int __init dynamic_debug_init(void)
+{
+	struct _ddebug *iter, *iter_start;
+	const char *modname = NULL;
+	int ret = 0;
+	int n = 0;
+
 	if (__start___verbose != __stop___verbose) {
 		iter = __start___verbose;
 		modname = iter->modname;
@@ -795,11 +806,13 @@ static int __init dynamic_debug_init(void)
 	}
 
 out_free:
-	if (ret) {
+	if (ret)
 		ddebug_remove_all_tables();
-		debugfs_remove(dir);
-		debugfs_remove(file);
-	}
+	else
+		ddebug_init_success = 1;
 	return 0;
 }
-module_init(dynamic_debug_init);
+/* Allow early initialization for boot messages via boot param */
+arch_initcall(dynamic_debug_init);
+/* Debugfs setup must be done later */
+module_init(dynamic_debug_init_debugfs);
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 04/31] driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (2 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 03/31] Dynamic Debug: Initialize dynamic debug earlier via arch_initcall Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 05/31] uio: do not use PCI resources before pci_enable_device() Greg Kroah-Hartman
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Patrick Pannuto, Greg Kroah-Hartman

From: Patrick Pannuto <ppannuto@codeaurora.org>

In theory (although not *yet* in practice), a driver being passed
to platform_driver_probe might have driver.bus set to something
other than platform_bus_type. Locking drv->driver.bus is always
correct.

Signed-off-by: Patrick Pannuto <ppannuto@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/platform.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c6c933f..579906f 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -488,12 +488,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
 	 * if the probe was successful, and make sure any forced probes of
 	 * new devices fail.
 	 */
-	spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
+	spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
 	drv->probe = NULL;
 	if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
 		retval = -ENODEV;
 	drv->driver.probe = platform_drv_probe_fail;
-	spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
+	spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
 
 	if (code != retval)
 		platform_driver_unregister(drv);
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 05/31] uio: do not use PCI resources before pci_enable_device()
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (3 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 04/31] driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 06/31] driver core: platform_bus: allow runtime override of dev_pm_ops Greg Kroah-Hartman
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Kulikov Vasiliy, Hans J. Koch, Greg Kroah-Hartman

From: Kulikov Vasiliy <segooon@gmail.com>

IRQ and resource[] may not have correct values until
after PCI hotplug setup occurs at pci_enable_device() time.

The semantic match that finds this problem is as follows:

// <smpl>
@@
identifier x;
identifier request ~= "pci_request.*|pci_resource.*";
@@

(
* x->irq
|
* x->resource
|
* request(x, ...)
)
 ...
*pci_enable_device(x)
// </smpl>

Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio_pci_generic.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index 85c9884..fc22e1e 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev,
 	struct uio_pci_generic_dev *gdev;
 	int err;
 
-	if (!pdev->irq) {
-		dev_warn(&pdev->dev, "No IRQ assigned to device: "
-			 "no support for interrupts?\n");
-		return -ENODEV;
-	}
-
 	err = pci_enable_device(pdev);
 	if (err) {
 		dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
@@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev,
 		return err;
 	}
 
+	if (!pdev->irq) {
+		dev_warn(&pdev->dev, "No IRQ assigned to device: "
+			 "no support for interrupts?\n");
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
 	err = verify_pci_2_3(pdev);
 	if (err)
 		goto err_verify;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 06/31] driver core: platform_bus: allow runtime override of dev_pm_ops
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (4 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 05/31] uio: do not use PCI resources before pci_enable_device() Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 07/31] add Packet hub driver for Topcliff Platform controller hub Greg Kroah-Hartman
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Kevin Hilman, Magnus Damm, Kevin Hilman, Greg Kroah-Hartman

From: Kevin Hilman <khilman@ti.com>

Currently, the platform_bus allows customization of several of the
busses dev_pm_ops methods by using weak symbols so that platform code
can override them.  The weak-symbol approach is not scalable when
wanting to support multiple platforms in a single kernel binary.

Instead, provide __init methods for platform code to customize the
dev_pm_ops methods at runtime.

NOTE: after these dynamic methods are merged, the weak symbols should
      be removed from drivers/base/platform.c.  AFAIK, this will only
      affect SH and sh-mobile which should be converted to use this
      runtime approach instead of the weak symbols.  After SH &
      sh-mobile are converted, the weak symobols could be removed.

Tested on OMAP3.

Cc: Magnus Damm <magnus.damm@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/platform.c         |   35 +++++++++++++++++++++++++++++++++++
 include/linux/platform_device.h |    3 +++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 579906f..a01abf9 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -976,6 +976,41 @@ struct bus_type platform_bus_type = {
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
+/**
+ * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
+ *
+ * This function can be used by platform code to get the current
+ * set of dev_pm_ops functions used by the platform_bus_type.
+ */
+const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
+{
+	return platform_bus_type.pm;
+}
+
+/**
+ * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
+ *
+ * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
+ *
+ * Platform code can override the dev_pm_ops methods of
+ * platform_bus_type by using this function.  It is expected that
+ * platform code will first do a platform_bus_get_pm_ops(), then
+ * kmemdup it, then customize selected methods and pass a pointer to
+ * the new struct dev_pm_ops to this function.
+ *
+ * Since platform-specific code is customizing methods for *all*
+ * devices (not just platform-specific devices) it is expected that
+ * any custom overrides of these functions will keep existing behavior
+ * and simply extend it.  For example, any customization of the
+ * runtime PM methods should continue to call the pm_generic_*
+ * functions as the default ones do in addition to the
+ * platform-specific behavior.
+ */
+void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
+{
+	platform_bus_type.pm = pm;
+}
+
 int __init platform_bus_init(void)
 {
 	int error;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index d7ecad0..2e700ec 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
 					struct resource *res, unsigned int n_res,
 					const void *data, size_t size);
 
+extern const struct dev_pm_ops * platform_bus_get_pm_ops(void);
+extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm);
+
 /* early platform driver interface */
 struct early_platform_driver {
 	const char *class_str;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 07/31] add Packet hub driver for Topcliff Platform controller hub
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (5 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 06/31] driver core: platform_bus: allow runtime override of dev_pm_ops Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 08/31] pch_phub: fix build warnings Greg Kroah-Hartman
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Masayuki Ohtak, Greg Kroah-Hartman

From: Masayuki Ohtak <masa-korg@dsn.okisemi.com>

Packet hub driver of Topcliff PCH

Topcliff PCH is the platform controller hub that is going to be used in
Intel's upcoming general embedded platform. All IO peripherals in
Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is
a special converter device in Topcliff PCH that translate AMBA transactions
to PCI Express transactions and vice versa. Thus packet hub helps present
all IO peripherals in Topcliff PCH as PCIE devices to IA system.
Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in
SROM via sysfs interface.


Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/ABI/testing/sysfs-module |   12 +
 drivers/misc/Kconfig                   |   12 +
 drivers/misc/Makefile                  |    1 +
 drivers/misc/pch_phub.c                |  717 ++++++++++++++++++++++++++++++++
 4 files changed, 742 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-module
 create mode 100644 drivers/misc/pch_phub.c

diff --git a/Documentation/ABI/testing/sysfs-module b/Documentation/ABI/testing/sysfs-module
new file mode 100644
index 0000000..cfcec3b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-module
@@ -0,0 +1,12 @@
+What:		/sys/module/pch_phub/drivers/.../pch_mac
+Date:		August 2010
+KernelVersion:	2.6.35
+Contact:	masa-korg@dsn.okisemi.com
+Description:	Write/read GbE MAC address.
+
+What:		/sys/module/pch_phub/drivers/.../pch_firmware
+Date:		August 2010
+KernelVersion:	2.6.35
+Contact:	masa-korg@dsn.okisemi.com
+Description:	Write/read Option ROM data.
+
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b743312..6f46e27 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -390,6 +390,18 @@ config BMP085
 	  To compile this driver as a module, choose M here: the
 	  module will be called bmp085.
 
+config PCH_PHUB
+	tristate "PCH Packet Hub of Intel Topcliff"
+	depends on PCI
+	help
+	  This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
+	  Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded
+	  processor. The Topcliff has MAC address and Option ROM data in SROM.
+	  This driver can access MAC address and Option ROM data in SROM.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called pch_phub.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 42eab95..9f2986b 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -35,3 +35,4 @@ obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmw_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
+obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
new file mode 100644
index 0000000..ed56e4f
--- /dev/null
+++ b/drivers/misc/pch_phub.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/if_ether.h>
+#include <linux/ctype.h>
+
+#define PHUB_STATUS 0x00		/* Status Register offset */
+#define PHUB_CONTROL 0x04		/* Control Register offset */
+#define PHUB_TIMEOUT 0x05		/* Time out value for Status Register */
+#define PCH_PHUB_ROM_WRITE_ENABLE 0x01	/* Enabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_DISABLE 0x00	/* Disabling for writing ROM */
+#define PCH_PHUB_ROM_START_ADDR 0x14	/* ROM data area start address offset */
+
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
+#define PCI_DEVICE_ID_PCH1_PHUB 0x8801
+#define PCH_MINOR_NOS 1
+#define CLKCFG_CAN_50MHZ 0x12000000
+#define CLKCFG_CANCLK_MASK 0xFF000000
+
+/* SROM ACCESS Macro */
+#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
+
+/* Registers address offset */
+#define PCH_PHUB_ID_REG				0x0000
+#define PCH_PHUB_QUEUE_PRI_VAL_REG		0x0004
+#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG		0x0008
+#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG		0x000C
+#define PCH_PHUB_COMP_RESP_TIMEOUT_REG		0x0010
+#define PCH_PHUB_BUS_SLAVE_CONTROL_REG		0x0014
+#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG	0x0018
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0	0x0020
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1	0x0024
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2	0x0028
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3	0x002C
+#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE	0x0040
+#define CLKCFG_REG_OFFSET			0x500
+
+#define PCH_PHUB_OROM_SIZE 15360
+
+/**
+ * struct pch_phub_reg - PHUB register structure
+ * @phub_id_reg:			PHUB_ID register val
+ * @q_pri_val_reg:			QUEUE_PRI_VAL register val
+ * @rc_q_maxsize_reg:			RC_QUEUE_MAXSIZE register val
+ * @bri_q_maxsize_reg:			BRI_QUEUE_MAXSIZE register val
+ * @comp_resp_timeout_reg:		COMP_RESP_TIMEOUT register val
+ * @bus_slave_control_reg:		BUS_SLAVE_CONTROL_REG register val
+ * @deadlock_avoid_type_reg:		DEADLOCK_AVOID_TYPE register val
+ * @intpin_reg_wpermit_reg0:		INTPIN_REG_WPERMIT register 0 val
+ * @intpin_reg_wpermit_reg1:		INTPIN_REG_WPERMIT register 1 val
+ * @intpin_reg_wpermit_reg2:		INTPIN_REG_WPERMIT register 2 val
+ * @intpin_reg_wpermit_reg3:		INTPIN_REG_WPERMIT register 3 val
+ * @int_reduce_control_reg:		INT_REDUCE_CONTROL registers val
+ * @clkcfg_reg:				CLK CFG register val
+ * @pch_phub_base_address:		Register base address
+ * @pch_phub_extrom_base_address:	external rom base address
+ */
+struct pch_phub_reg {
+	u32 phub_id_reg;
+	u32 q_pri_val_reg;
+	u32 rc_q_maxsize_reg;
+	u32 bri_q_maxsize_reg;
+	u32 comp_resp_timeout_reg;
+	u32 bus_slave_control_reg;
+	u32 deadlock_avoid_type_reg;
+	u32 intpin_reg_wpermit_reg0;
+	u32 intpin_reg_wpermit_reg1;
+	u32 intpin_reg_wpermit_reg2;
+	u32 intpin_reg_wpermit_reg3;
+	u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
+	u32 clkcfg_reg;
+	void __iomem *pch_phub_base_address;
+	void __iomem *pch_phub_extrom_base_address;
+};
+
+/* SROM SPEC for MAC address assignment offset */
+static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
+
+static DEFINE_MUTEX(pch_phub_mutex);
+
+/**
+ * pch_phub_read_modify_write_reg() - Reading modifying and writing register
+ * @reg_addr_offset:	Register offset address value.
+ * @data:		Writing value.
+ * @mask:		Mask value.
+ */
+static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
+					   unsigned int reg_addr_offset,
+					   unsigned int data, unsigned int mask)
+{
+	void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
+	iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
+}
+
+/* pch_phub_save_reg_conf - saves register configuration */
+static void pch_phub_save_reg_conf(struct pci_dev *pdev)
+{
+	unsigned int i;
+	struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+
+	void __iomem *p = chip->pch_phub_base_address;
+
+	chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
+	chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+	chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	chip->comp_resp_timeout_reg =
+				ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	chip->bus_slave_control_reg =
+				ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	chip->deadlock_avoid_type_reg =
+				ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	chip->intpin_reg_wpermit_reg0 =
+				ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	chip->intpin_reg_wpermit_reg1 =
+				ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	chip->intpin_reg_wpermit_reg2 =
+				ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	chip->intpin_reg_wpermit_reg3 =
+				ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(&pdev->dev, "%s : "
+		"chip->phub_id_reg=%x, "
+		"chip->q_pri_val_reg=%x, "
+		"chip->rc_q_maxsize_reg=%x, "
+		"chip->bri_q_maxsize_reg=%x, "
+		"chip->comp_resp_timeout_reg=%x, "
+		"chip->bus_slave_control_reg=%x, "
+		"chip->deadlock_avoid_type_reg=%x, "
+		"chip->intpin_reg_wpermit_reg0=%x, "
+		"chip->intpin_reg_wpermit_reg1=%x, "
+		"chip->intpin_reg_wpermit_reg2=%x, "
+		"chip->intpin_reg_wpermit_reg3=%x\n", __func__,
+		chip->phub_id_reg,
+		chip->q_pri_val_reg,
+		chip->rc_q_maxsize_reg,
+		chip->bri_q_maxsize_reg,
+		chip->comp_resp_timeout_reg,
+		chip->bus_slave_control_reg,
+		chip->deadlock_avoid_type_reg,
+		chip->intpin_reg_wpermit_reg0,
+		chip->intpin_reg_wpermit_reg1,
+		chip->intpin_reg_wpermit_reg2,
+		chip->intpin_reg_wpermit_reg3);
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		chip->int_reduce_control_reg[i] =
+		    ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(&pdev->dev, "%s : "
+			"chip->int_reduce_control_reg[%d]=%x\n",
+			__func__, i, chip->int_reduce_control_reg[i]);
+	}
+	chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
+}
+
+/* pch_phub_restore_reg_conf - restore register configuration */
+static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
+{
+	unsigned int i;
+	struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+	void __iomem *p;
+	p = chip->pch_phub_base_address;
+
+	iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
+	iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+	iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	iowrite32(chip->comp_resp_timeout_reg,
+					p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	iowrite32(chip->bus_slave_control_reg,
+					p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	iowrite32(chip->deadlock_avoid_type_reg,
+					p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	iowrite32(chip->intpin_reg_wpermit_reg0,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	iowrite32(chip->intpin_reg_wpermit_reg1,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	iowrite32(chip->intpin_reg_wpermit_reg2,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	iowrite32(chip->intpin_reg_wpermit_reg3,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(&pdev->dev, "%s : "
+		"chip->phub_id_reg=%x, "
+		"chip->q_pri_val_reg=%x, "
+		"chip->rc_q_maxsize_reg=%x, "
+		"chip->bri_q_maxsize_reg=%x, "
+		"chip->comp_resp_timeout_reg=%x, "
+		"chip->bus_slave_control_reg=%x, "
+		"chip->deadlock_avoid_type_reg=%x, "
+		"chip->intpin_reg_wpermit_reg0=%x, "
+		"chip->intpin_reg_wpermit_reg1=%x, "
+		"chip->intpin_reg_wpermit_reg2=%x, "
+		"chip->intpin_reg_wpermit_reg3=%x\n", __func__,
+		chip->phub_id_reg,
+		chip->q_pri_val_reg,
+		chip->rc_q_maxsize_reg,
+		chip->bri_q_maxsize_reg,
+		chip->comp_resp_timeout_reg,
+		chip->bus_slave_control_reg,
+		chip->deadlock_avoid_type_reg,
+		chip->intpin_reg_wpermit_reg0,
+		chip->intpin_reg_wpermit_reg1,
+		chip->intpin_reg_wpermit_reg2,
+		chip->intpin_reg_wpermit_reg3);
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		iowrite32(chip->int_reduce_control_reg[i],
+			p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(&pdev->dev, "%s : "
+			"chip->int_reduce_control_reg[%d]=%x\n",
+			__func__, i, chip->int_reduce_control_reg[i]);
+	}
+
+	iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
+}
+
+/**
+ * pch_phub_read_serial_rom() - Reading Serial ROM
+ * @offset_address:	Serial ROM offset address to read.
+ * @data:		Read buffer for specified Serial ROM value.
+ */
+static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
+				     unsigned int offset_address, u8 *data)
+{
+	void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
+								offset_address;
+
+	*data = ioread8(mem_addr);
+}
+
+/**
+ * pch_phub_write_serial_rom() - Writing Serial ROM
+ * @offset_address:	Serial ROM offset address.
+ * @data:		Serial ROM value to write.
+ */
+static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
+				     unsigned int offset_address, u8 data)
+{
+	void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
+					(offset_address & PCH_WORD_ADDR_MASK);
+	int i;
+	unsigned int word_data;
+	unsigned int pos;
+	unsigned int mask;
+	pos = (offset_address % 4) * 8;
+	mask = ~(0xFF << pos);
+
+	iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
+			chip->pch_phub_extrom_base_address + PHUB_CONTROL);
+
+	word_data = ioread32(mem_addr);
+	iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
+
+	i = 0;
+	while (ioread8(chip->pch_phub_extrom_base_address +
+						PHUB_STATUS) != 0x00) {
+		msleep(1);
+		if (i == PHUB_TIMEOUT)
+			return -ETIMEDOUT;
+		i++;
+	}
+
+	iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
+			chip->pch_phub_extrom_base_address + PHUB_CONTROL);
+
+	return 0;
+}
+
+/**
+ * pch_phub_read_serial_rom_val() - Read Serial ROM value
+ * @offset_address:	Serial ROM address offset value.
+ * @data:		Serial ROM value to read.
+ */
+static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
+					 unsigned int offset_address, u8 *data)
+{
+	unsigned int mem_addr;
+
+	mem_addr = PCH_PHUB_ROM_START_ADDR +
+			pch_phub_mac_offset[offset_address];
+
+	pch_phub_read_serial_rom(chip, mem_addr, data);
+}
+
+/**
+ * pch_phub_write_serial_rom_val() - writing Serial ROM value
+ * @offset_address:	Serial ROM address offset value.
+ * @data:		Serial ROM value.
+ */
+static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
+					 unsigned int offset_address, u8 data)
+{
+	int retval;
+	unsigned int mem_addr;
+
+	mem_addr = PCH_PHUB_ROM_START_ADDR +
+			pch_phub_mac_offset[offset_address];
+
+	retval = pch_phub_write_serial_rom(chip, mem_addr, data);
+
+	return retval;
+}
+
+/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
+ * for Gigabit Ethernet MAC address
+ */
+static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
+{
+	int retval;
+
+	retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
+	retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
+	retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
+	retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
+	retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
+
+	return retval;
+}
+
+/**
+ * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
+ * @offset_address:	Gigabit Ethernet MAC address offset value.
+ * @data:		Buffer of the Gigabit Ethernet MAC address value.
+ */
+static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
+{
+	int i;
+	for (i = 0; i < ETH_ALEN; i++)
+		pch_phub_read_serial_rom_val(chip, i, &data[i]);
+}
+
+/**
+ * pch_phub_write_gbe_mac_addr() - Write MAC address
+ * @offset_address:	Gigabit Ethernet MAC address offset value.
+ * @data:		Gigabit Ethernet MAC address value.
+ */
+static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
+{
+	int retval;
+	int i;
+
+	retval = pch_phub_gbe_serial_rom_conf(chip);
+	if (retval)
+		return retval;
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
+		if (retval)
+			return retval;
+	}
+
+	return retval;
+}
+
+static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
+				 struct bin_attribute *attr, char *buf,
+				 loff_t off, size_t count)
+{
+	unsigned int rom_signature;
+	unsigned char rom_length;
+	unsigned int tmp;
+	unsigned int addr_offset;
+	unsigned int orom_size;
+	int ret;
+	int err;
+
+	struct pch_phub_reg *chip =
+		dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+	ret = mutex_lock_interruptible(&pch_phub_mutex);
+	if (ret) {
+		err = -ERESTARTSYS;
+		goto return_err_nomutex;
+	}
+
+	/* Get Rom signature */
+	pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
+	rom_signature &= 0xff;
+	pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
+	rom_signature |= (tmp & 0xff) << 8;
+	if (rom_signature == 0xAA55) {
+		pch_phub_read_serial_rom(chip, 0x82, &rom_length);
+		orom_size = rom_length * 512;
+		if (orom_size < off) {
+			addr_offset = 0;
+			goto return_ok;
+		}
+		if (orom_size < count) {
+			addr_offset = 0;
+			goto return_ok;
+		}
+
+		for (addr_offset = 0; addr_offset < count; addr_offset++) {
+			pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
+							 &buf[addr_offset]);
+		}
+	} else {
+		err = -ENODATA;
+		goto return_err;
+	}
+return_ok:
+	mutex_unlock(&pch_phub_mutex);
+	return addr_offset;
+
+return_err:
+	mutex_unlock(&pch_phub_mutex);
+return_err_nomutex:
+	return err;
+}
+
+static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
+				  struct bin_attribute *attr,
+				  char *buf, loff_t off, size_t count)
+{
+	int err;
+	unsigned int addr_offset;
+	int ret;
+	struct pch_phub_reg *chip =
+		dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+	ret = mutex_lock_interruptible(&pch_phub_mutex);
+	if (ret)
+		return -ERESTARTSYS;
+
+	if (off > PCH_PHUB_OROM_SIZE) {
+		addr_offset = 0;
+		goto return_ok;
+	}
+	if (count > PCH_PHUB_OROM_SIZE) {
+		addr_offset = 0;
+		goto return_ok;
+	}
+
+	for (addr_offset = 0; addr_offset < count; addr_offset++) {
+		if (PCH_PHUB_OROM_SIZE < off + addr_offset)
+			goto return_ok;
+
+		ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
+						       buf[addr_offset]);
+		if (ret) {
+			err = ret;
+			goto return_err;
+		}
+	}
+
+return_ok:
+	mutex_unlock(&pch_phub_mutex);
+	return addr_offset;
+
+return_err:
+	mutex_unlock(&pch_phub_mutex);
+	return err;
+}
+
+static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	u8 mac[8];
+	struct pch_phub_reg *chip = dev_get_drvdata(dev);
+
+	pch_phub_read_gbe_mac_addr(chip, mac);
+
+	return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	u8 mac[6];
+	struct pch_phub_reg *chip = dev_get_drvdata(dev);
+
+	if (count != 18)
+		return -EINVAL;
+
+	sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+		(u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
+		(u32 *)&mac[4], (u32 *)&mac[5]);
+
+	pch_phub_write_gbe_mac_addr(chip, mac);
+
+	return count;
+}
+
+static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
+
+static struct bin_attribute pch_bin_attr = {
+	.attr = {
+		.name = "pch_firmware",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = PCH_PHUB_OROM_SIZE + 1,
+	.read = pch_phub_bin_read,
+	.write = pch_phub_bin_write,
+};
+
+static int __devinit pch_phub_probe(struct pci_dev *pdev,
+				    const struct pci_device_id *id)
+{
+	int retval;
+
+	int ret;
+	unsigned int rom_size;
+	struct pch_phub_reg *chip;
+
+	chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_err(&pdev->dev,
+		"%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
+		goto err_pci_enable_dev;
+	}
+	dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
+		ret);
+
+	ret = pci_request_regions(pdev, KBUILD_MODNAME);
+	if (ret) {
+		dev_err(&pdev->dev,
+		"%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
+		goto err_req_regions;
+	}
+	dev_dbg(&pdev->dev, "%s : "
+		"pci_request_regions returns %d\n", __func__, ret);
+
+	chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
+
+
+	if (chip->pch_phub_base_address == 0) {
+		dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
+		ret = -ENOMEM;
+		goto err_pci_iomap;
+	}
+	dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
+		"in pch_phub_base_address variable is 0x%08x\n", __func__,
+		(unsigned int)chip->pch_phub_base_address);
+	chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
+
+	if (chip->pch_phub_extrom_base_address == 0) {
+		dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
+		ret = -ENOMEM;
+		goto err_pci_map;
+	}
+	dev_dbg(&pdev->dev, "%s : "
+		"pci_map_rom SUCCESS and value in "
+		"pch_phub_extrom_base_address variable is 0x%08x\n", __func__,
+		(unsigned int)chip->pch_phub_extrom_base_address);
+
+	pci_set_drvdata(pdev, chip);
+
+	retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+	if (retval)
+		goto err_sysfs_create;
+
+	retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+	if (retval)
+		goto exit_bin_attr;
+
+	pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET,
+					CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
+
+	/* set the prefech value */
+	iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
+	/* set the interrupt delay value */
+	iowrite32(0x25, chip->pch_phub_base_address + 0x44);
+
+	return 0;
+exit_bin_attr:
+	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+
+err_sysfs_create:
+	pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
+err_pci_map:
+	pci_iounmap(pdev, chip->pch_phub_base_address);
+err_pci_iomap:
+	pci_release_regions(pdev);
+err_req_regions:
+	pci_disable_device(pdev);
+err_pci_enable_dev:
+	kfree(chip);
+	dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
+	return ret;
+}
+
+static void __devexit pch_phub_remove(struct pci_dev *pdev)
+{
+	struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+
+	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+	sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+	pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
+	pci_iounmap(pdev, chip->pch_phub_base_address);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	kfree(chip);
+}
+
+#ifdef CONFIG_PM
+
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	pch_phub_save_reg_conf(pdev);
+	ret = pci_save_state(pdev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			" %s -pci_save_state returns %d\n", __func__, ret);
+		return ret;
+	}
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+static int pch_phub_resume(struct pci_dev *pdev)
+{
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_err(&pdev->dev,
+		"%s-pci_enable_device failed(ret=%d) ", __func__, ret);
+		return ret;
+	}
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	pch_phub_restore_reg_conf(pdev);
+
+	return 0;
+}
+#else
+#define pch_phub_suspend NULL
+#define pch_phub_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_device_id pch_phub_pcidev_id[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
+	{0,}
+};
+
+static struct pci_driver pch_phub_driver = {
+	.name = "pch_phub",
+	.id_table = pch_phub_pcidev_id,
+	.probe = pch_phub_probe,
+	.remove = __devexit_p(pch_phub_remove),
+	.suspend = pch_phub_suspend,
+	.resume = pch_phub_resume
+};
+
+static int __init pch_phub_pci_init(void)
+{
+	return pci_register_driver(&pch_phub_driver);
+}
+
+static void __exit pch_phub_pci_exit(void)
+{
+	pci_unregister_driver(&pch_phub_driver);
+}
+
+module_init(pch_phub_pci_init);
+module_exit(pch_phub_pci_exit);
+
+MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 08/31] pch_phub: fix build warnings
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (6 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 07/31] add Packet hub driver for Topcliff Platform controller hub Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 09/31] debugfs: mark me as the maintainer Greg Kroah-Hartman
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Masayuki Ohtake

This patch fixes up all of the build warnings for the pch_phub driver.

Cc: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/misc/pch_phub.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
index ed56e4f..744b804 100644
--- a/drivers/misc/pch_phub.c
+++ b/drivers/misc/pch_phub.c
@@ -546,7 +546,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
 	int retval;
 
 	int ret;
-	unsigned int rom_size;
+	ssize_t rom_size;
 	struct pch_phub_reg *chip;
 
 	chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
@@ -580,8 +580,8 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
 		goto err_pci_iomap;
 	}
 	dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
-		"in pch_phub_base_address variable is 0x%08x\n", __func__,
-		(unsigned int)chip->pch_phub_base_address);
+		"in pch_phub_base_address variable is %p\n", __func__,
+		chip->pch_phub_base_address);
 	chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
 
 	if (chip->pch_phub_extrom_base_address == 0) {
@@ -591,8 +591,8 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
 	}
 	dev_dbg(&pdev->dev, "%s : "
 		"pci_map_rom SUCCESS and value in "
-		"pch_phub_extrom_base_address variable is 0x%08x\n", __func__,
-		(unsigned int)chip->pch_phub_extrom_base_address);
+		"pch_phub_extrom_base_address variable is %p\n", __func__,
+		chip->pch_phub_extrom_base_address);
 
 	pci_set_drvdata(pdev, chip);
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 09/31] debugfs: mark me as the maintainer
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (7 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 08/31] pch_phub: fix build warnings Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 10/31] base/platform: Safe handling for NULL platform data and resources Greg Kroah-Hartman
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

Add DEBUGFS information to my MAINTAINERS entry as some people have
asked about this recently.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 MAINTAINERS |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f2a2b8e..22aa094 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2050,14 +2050,16 @@ F:	drivers/block/drbd/
 F:	lib/lru_cache.c
 F:	Documentation/blockdev/drbd/
 
-DRIVER CORE, KOBJECTS, AND SYSFS
+DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
 M:	Greg Kroah-Hartman <gregkh@suse.de>
 T:	quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
 S:	Supported
 F:	Documentation/kobject.txt
 F:	drivers/base/
 F:	fs/sysfs/
+F:	fs/debugfs/
 F:	include/linux/kobj*
+F:	include/linux/debugfs.h
 F:	lib/kobj*
 
 DRM DRIVERS
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 10/31] base/platform: Safe handling for NULL platform data and resources
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (8 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 09/31] debugfs: mark me as the maintainer Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 11/31] base/platform: Simplifications for NULL platform data/resources handling Greg Kroah-Hartman
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Anton Vorontsov, Greg Kroah-Hartman

From: Anton Vorontsov <cbouatmailru@gmail.com>

Some users of platform_device_add_{data,resources}() assume that
NULL data and resources will be handled specially, i.e. just ignored.

But the platform core ends up calling kmemdup(NULL, 0, ...), which
returns a non-NULL result (i.e. ZERO_SIZE_PTR), which causes drivers
to oops on a valid code, something like:

  if (platform_data)
  	stuff = platform_data->stuff;

This patch makes the platform core a bit more safe for such cases.

Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/platform.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index a01abf9..c794fec 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev,
 {
 	struct resource *r;
 
+	if (!res)
+		return 0;
+
 	r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
 	if (r) {
 		pdev->resource = r;
@@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
 int platform_device_add_data(struct platform_device *pdev, const void *data,
 			     size_t size)
 {
-	void *d = kmemdup(data, size, GFP_KERNEL);
+	void *d;
+
+	if (!data)
+		return 0;
 
+	d = kmemdup(data, size, GFP_KERNEL);
 	if (d) {
 		pdev->dev.platform_data = d;
 		return 0;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 11/31] base/platform: Simplifications for NULL platform data/resources handling
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (9 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 10/31] base/platform: Safe handling for NULL platform data and resources Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 12/31] driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices Greg Kroah-Hartman
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Anton Vorontsov, Greg Kroah-Hartman

From: Anton Vorontsov <cbouatmailru@gmail.com>

There's no need to explicitly check for data and resources being NULL,
as platform_device_add_{data,resources}() do this internally nowadays.

This makes the code more linear and less indented.

Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/platform.c |   32 ++++++++++++--------------------
 1 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c794fec..3966e62 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -380,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata(
 
 	pdev->dev.parent = parent;
 
-	if (res) {
-		ret = platform_device_add_resources(pdev, res, num);
-		if (ret)
-			goto err;
-	}
+	ret = platform_device_add_resources(pdev, res, num);
+	if (ret)
+		goto err;
 
-	if (data) {
-		ret = platform_device_add_data(pdev, data, size);
-		if (ret)
-			goto err;
-	}
+	ret = platform_device_add_data(pdev, data, size);
+	if (ret)
+		goto err;
 
 	ret = platform_device_add(pdev);
 	if (ret) {
@@ -537,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle(
 		goto err_out;
 	}
 
-	if (res) {
-		error = platform_device_add_resources(pdev, res, n_res);
-		if (error)
-			goto err_pdev_put;
-	}
+	error = platform_device_add_resources(pdev, res, n_res);
+	if (error)
+		goto err_pdev_put;
 
-	if (data) {
-		error = platform_device_add_data(pdev, data, size);
-		if (error)
-			goto err_pdev_put;
-	}
+	error = platform_device_add_data(pdev, data, size);
+	if (error)
+		goto err_pdev_put;
 
 	error = platform_device_add(pdev);
 	if (error)
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 12/31] driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (10 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 11/31] base/platform: Simplifications for NULL platform data/resources handling Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 13/31] SYSFS: Allow boot time switching between deprecated and modern sysfs layout Greg Kroah-Hartman
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: Kay Sievers, Jens Axboe, Stephen Hemminger, Eric W. Biederman,
	Alan Stern, James E.J. Bottomley, Andrew Morton,
	Alexey Kuznetsov, Randy Dunlap, Tejun Heo, David S. Miller,
	Jaroslav Kysela, Takashi Iwai, Ingo Molnar, Peter Zijlstra,
	David Howells, Greg Kroah-Hartman

From: Kay Sievers <kay.sievers@vrfy.org>

This patch removes the old CONFIG_SYSFS_DEPRECATED_V2 config option,
but it keeps the logic around to handle block devices in the old manner
as some people like to run new kernel versions on old (pre 2007/2008)
distros.

Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: "James E.J. Bottomley" <James.Bottomley@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/bus.c       |   22 -----
 drivers/base/class.c     |   19 -----
 drivers/base/core.c      |  194 ++++++----------------------------------------
 drivers/scsi/hosts.c     |    2 -
 drivers/scsi/scsi_scan.c |    2 -
 include/sound/core.h     |    6 --
 init/Kconfig             |   46 ++++-------
 sound/core/init.c        |   11 +--
 8 files changed, 43 insertions(+), 259 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index eb1b7fa..33c270a 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev)
 	}
 }
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-static int make_deprecated_bus_links(struct device *dev)
-{
-	return sysfs_create_link(&dev->kobj,
-				 &dev->bus->p->subsys.kobj, "bus");
-}
-
-static void remove_deprecated_bus_links(struct device *dev)
-{
-	sysfs_remove_link(&dev->kobj, "bus");
-}
-#else
-static inline int make_deprecated_bus_links(struct device *dev) { return 0; }
-static inline void remove_deprecated_bus_links(struct device *dev) { }
-#endif
-
 /**
  * bus_add_device - add device to bus
  * @dev: device being added
@@ -482,15 +466,10 @@ int bus_add_device(struct device *dev)
 				&dev->bus->p->subsys.kobj, "subsystem");
 		if (error)
 			goto out_subsys;
-		error = make_deprecated_bus_links(dev);
-		if (error)
-			goto out_deprecated;
 		klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
 	}
 	return 0;
 
-out_deprecated:
-	sysfs_remove_link(&dev->kobj, "subsystem");
 out_subsys:
 	sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
 out_id:
@@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev)
 {
 	if (dev->bus) {
 		sysfs_remove_link(&dev->kobj, "subsystem");
-		remove_deprecated_bus_links(dev);
 		sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
 				  dev_name(dev));
 		device_remove_attrs(dev->bus, dev);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8e231d0..1078969 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -276,25 +276,6 @@ void class_destroy(struct class *cls)
 	class_unregister(cls);
 }
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-char *make_class_name(const char *name, struct kobject *kobj)
-{
-	char *class_name;
-	int size;
-
-	size = strlen(name) + strlen(kobject_name(kobj)) + 2;
-
-	class_name = kmalloc(size, GFP_KERNEL);
-	if (!class_name)
-		return NULL;
-
-	strcpy(class_name, name);
-	strcat(class_name, ":");
-	strcat(class_name, kobject_name(kobj));
-	return class_name;
-}
-#endif
-
 /**
  * class_dev_iter_init - initialize class device iterator
  * @iter: class iterator to initialize
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d1b2c9a..6cf9069 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -203,37 +203,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
 	if (dev->driver)
 		add_uevent_var(env, "DRIVER=%s", dev->driver->name);
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (dev->class) {
-		struct device *parent = dev->parent;
-
-		/* find first bus device in parent chain */
-		while (parent && !parent->bus)
-			parent = parent->parent;
-		if (parent && parent->bus) {
-			const char *path;
-
-			path = kobject_get_path(&parent->kobj, GFP_KERNEL);
-			if (path) {
-				add_uevent_var(env, "PHYSDEVPATH=%s", path);
-				kfree(path);
-			}
-
-			add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
-
-			if (parent->driver)
-				add_uevent_var(env, "PHYSDEVDRIVER=%s",
-					       parent->driver->name);
-		}
-	} else if (dev->bus) {
-		add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
-
-		if (dev->driver)
-			add_uevent_var(env, "PHYSDEVDRIVER=%s",
-				       dev->driver->name);
-	}
-#endif
-
 	/* have the bus specific function add its stuff */
 	if (dev->bus && dev->bus->uevent) {
 		retval = dev->bus->uevent(dev, env);
@@ -578,24 +547,6 @@ void device_initialize(struct device *dev)
 	set_dev_node(dev, -1);
 }
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-static struct kobject *get_device_parent(struct device *dev,
-					 struct device *parent)
-{
-	/* class devices without a parent live in /sys/class/<classname>/ */
-	if (dev->class && (!parent || parent->class != dev->class))
-		return &dev->class->p->class_subsys.kobj;
-	/* all other devices keep their parent */
-	else if (parent)
-		return &parent->kobj;
-
-	return NULL;
-}
-
-static inline void cleanup_device_parent(struct device *dev) {}
-static inline void cleanup_glue_dir(struct device *dev,
-				    struct kobject *glue_dir) {}
-#else
 static struct kobject *virtual_device_parent(struct device *dev)
 {
 	static struct kobject *virtual_dir = NULL;
@@ -666,6 +617,14 @@ static struct kobject *get_device_parent(struct device *dev,
 		struct kobject *parent_kobj;
 		struct kobject *k;
 
+#ifdef CONFIG_SYSFS_DEPRECATED
+		/* block disks show up in /sys/block */
+		if (dev->class == &block_class) {
+			if (parent && parent->class == &block_class)
+				return &parent->kobj;
+			return &block_class.p->class_subsys.kobj;
+		}
+#endif
 		/*
 		 * If we have no parent, we live in "virtual".
 		 * Class-devices with a non class-device as parent, live
@@ -719,7 +678,6 @@ static void cleanup_device_parent(struct device *dev)
 {
 	cleanup_glue_dir(dev, dev->kobj.parent);
 }
-#endif
 
 static void setup_parent(struct device *dev, struct device *parent)
 {
@@ -742,70 +700,29 @@ static int device_add_class_symlinks(struct device *dev)
 	if (error)
 		goto out;
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	/* stacked class devices need a symlink in the class directory */
-	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
-	    device_is_not_partition(dev)) {
-		error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
-					  &dev->kobj, dev_name(dev));
-		if (error)
-			goto out_subsys;
-	}
-
 	if (dev->parent && device_is_not_partition(dev)) {
-		struct device *parent = dev->parent;
-		char *class_name;
-
-		/*
-		 * stacked class devices have the 'device' link
-		 * pointing to the bus device instead of the parent
-		 */
-		while (parent->class && !parent->bus && parent->parent)
-			parent = parent->parent;
-
-		error = sysfs_create_link(&dev->kobj,
-					  &parent->kobj,
+		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
 					  "device");
 		if (error)
-			goto out_busid;
-
-		class_name = make_class_name(dev->class->name,
-						&dev->kobj);
-		if (class_name)
-			error = sysfs_create_link(&dev->parent->kobj,
-						&dev->kobj, class_name);
-		kfree(class_name);
-		if (error)
-			goto out_device;
+			goto out_subsys;
 	}
-	return 0;
 
-out_device:
-	if (dev->parent && device_is_not_partition(dev))
-		sysfs_remove_link(&dev->kobj, "device");
-out_busid:
-	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
-	    device_is_not_partition(dev))
-		sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
-				  dev_name(dev));
-#else
+#ifdef CONFIG_SYSFS_DEPRECATED
+	/* /sys/block has directories and does not need symlinks */
+	if (dev->class == &block_class)
+		return 0;
+#endif
+
 	/* link in the class directory pointing to the device */
 	error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
 				  &dev->kobj, dev_name(dev));
 	if (error)
-		goto out_subsys;
+		goto out_device;
 
-	if (dev->parent && device_is_not_partition(dev)) {
-		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
-					  "device");
-		if (error)
-			goto out_busid;
-	}
 	return 0;
 
-out_busid:
-	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
-#endif
+out_device:
+	sysfs_remove_link(&dev->kobj, "device");
 
 out_subsys:
 	sysfs_remove_link(&dev->kobj, "subsystem");
@@ -818,30 +735,14 @@ static void device_remove_class_symlinks(struct device *dev)
 	if (!dev->class)
 		return;
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (dev->parent && device_is_not_partition(dev)) {
-		char *class_name;
-
-		class_name = make_class_name(dev->class->name, &dev->kobj);
-		if (class_name) {
-			sysfs_remove_link(&dev->parent->kobj, class_name);
-			kfree(class_name);
-		}
-		sysfs_remove_link(&dev->kobj, "device");
-	}
-
-	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
-	    device_is_not_partition(dev))
-		sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
-				  dev_name(dev));
-#else
 	if (dev->parent && device_is_not_partition(dev))
 		sysfs_remove_link(&dev->kobj, "device");
-
-	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
-#endif
-
 	sysfs_remove_link(&dev->kobj, "subsystem");
+#ifdef CONFIG_SYSFS_DEPRECATED
+	if (dev->class == &block_class)
+		return;
+#endif
+	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
 }
 
 /**
@@ -1613,41 +1514,23 @@ int device_rename(struct device *dev, const char *new_name)
 	pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev),
 		 __func__, new_name);
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if ((dev->class) && (dev->parent))
-		old_class_name = make_class_name(dev->class->name, &dev->kobj);
-#endif
-
 	old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
 	if (!old_device_name) {
 		error = -ENOMEM;
 		goto out;
 	}
 
-#ifndef CONFIG_SYSFS_DEPRECATED
 	if (dev->class) {
 		error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
 			&dev->kobj, old_device_name, new_name);
 		if (error)
 			goto out;
 	}
-#endif
+
 	error = kobject_rename(&dev->kobj, new_name);
 	if (error)
 		goto out;
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (old_class_name) {
-		new_class_name = make_class_name(dev->class->name, &dev->kobj);
-		if (new_class_name) {
-			error = sysfs_rename_link(&dev->parent->kobj,
-						  &dev->kobj,
-						  old_class_name,
-						  new_class_name);
-		}
-	}
-#endif
-
 out:
 	put_device(dev);
 
@@ -1664,40 +1547,13 @@ static int device_move_class_links(struct device *dev,
 				   struct device *new_parent)
 {
 	int error = 0;
-#ifdef CONFIG_SYSFS_DEPRECATED
-	char *class_name;
 
-	class_name = make_class_name(dev->class->name, &dev->kobj);
-	if (!class_name) {
-		error = -ENOMEM;
-		goto out;
-	}
-	if (old_parent) {
-		sysfs_remove_link(&dev->kobj, "device");
-		sysfs_remove_link(&old_parent->kobj, class_name);
-	}
-	if (new_parent) {
-		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
-					  "device");
-		if (error)
-			goto out;
-		error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
-					  class_name);
-		if (error)
-			sysfs_remove_link(&dev->kobj, "device");
-	} else
-		error = 0;
-out:
-	kfree(class_name);
-	return error;
-#else
 	if (old_parent)
 		sysfs_remove_link(&dev->kobj, "device");
 	if (new_parent)
 		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
 					  "device");
 	return error;
-#endif
 }
 
 /**
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 8a8f803..ba7f87a 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -411,9 +411,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 
 	device_initialize(&shost->shost_gendev);
 	dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
-#ifndef CONFIG_SYSFS_DEPRECATED
 	shost->shost_gendev.bus = &scsi_bus_type;
-#endif
 	shost->shost_gendev.type = &scsi_host_type;
 
 	device_initialize(&shost->shost_dev);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 3d0a1e6..087821f 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
 	starget->reap_ref = 1;
 	dev->parent = get_device(parent);
 	dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
-#ifndef CONFIG_SYSFS_DEPRECATED
 	dev->bus = &scsi_bus_type;
-#endif
 	dev->type = &scsi_target_type;
 	starget->id = id;
 	starget->channel = channel;
diff --git a/include/sound/core.h b/include/sound/core.h
index 89e0ac1..df26ebb 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -133,9 +133,7 @@ struct snd_card {
 	int free_on_last_close;		/* free in context of file_release */
 	wait_queue_head_t shutdown_sleep;
 	struct device *dev;		/* device assigned to this card */
-#ifndef CONFIG_SYSFS_DEPRECATED
 	struct device *card_dev;	/* cardX object for sysfs */
-#endif
 
 #ifdef CONFIG_PM
 	unsigned int power_state;	/* power state */
@@ -196,11 +194,7 @@ struct snd_minor {
 /* return a device pointer linked to each sound device as a parent */
 static inline struct device *snd_card_get_device_link(struct snd_card *card)
 {
-#ifdef CONFIG_SYSFS_DEPRECATED
-	return card ? card->dev : NULL;
-#else
 	return card ? card->card_dev : NULL;
-#endif
 }
 
 /* sound.c */
diff --git a/init/Kconfig b/init/Kconfig
index 2de5b1c..137609f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -656,40 +656,24 @@ config MM_OWNER
 	bool
 
 config SYSFS_DEPRECATED
-	bool
-
-config SYSFS_DEPRECATED_V2
 	bool "enable deprecated sysfs features to support old userspace tools"
 	depends on SYSFS
 	default n
-	select SYSFS_DEPRECATED
-	help
-	  This option switches the layout of sysfs to the deprecated
-	  version. Do not use it on recent distributions.
-
-	  The current sysfs layout features a unified device tree at
-	  /sys/devices/, which is able to express a hierarchy between
-	  class devices. If the deprecated option is set to Y, the
-	  unified device tree is split into a bus device tree at
-	  /sys/devices/ and several individual class device trees at
-	  /sys/class/. The class and bus devices will be connected by
-	  "<subsystem>:<name>" and the "device" links. The "block"
-	  class devices, will not show up in /sys/class/block/. Some
-	  subsystems will suppress the creation of some devices which
-	  depend on the unified device tree.
-
-	  This option is not a pure compatibility option that can
-	  be safely enabled on newer distributions. It will change the
-	  layout of sysfs to the non-extensible deprecated version,
-	  and disable some features, which can not be exported without
-	  confusing older userspace tools. Since 2007/2008 all major
-	  distributions do not enable this option, and ship no tools which
-	  depend on the deprecated layout or this option.
-
-	  If you are using a new kernel on an older distribution, or use
-	  older userspace tools, you might need to say Y here. Do not say Y,
-	  if the original kernel, that came with your distribution, has
-	  this option set to N.
+	help
+	  This option switches the layout of the "block" class devices, to not
+	  show up in /sys/class/block/, but only in /sys/block/.
+
+	  This option allows new kernels to run on old distributions and tools,
+	  which might get confused by /sys/class/block/. Since 2007/2008 all
+	  major distributions and tools handle this just fine.
+
+	  Recent distributions and userspace tools after 2009/2010 depend on
+	  the existence of /sys/class/block/, and will not work with this
+	  option enabled.
+
+	  Only if you are using a new kernel on an old distribution, you might
+	  need to say Y here. Never say Y, if the original kernel, that came
+	  with your distribution, has not set this option.
 
 config RELAY
 	bool "Kernel->user space relay support (formerly relayfs)"
diff --git a/sound/core/init.c b/sound/core/init.c
index ec4a50c..f7c3df8 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -395,12 +395,10 @@ int snd_card_disconnect(struct snd_card *card)
 		snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
 
 	snd_info_card_disconnect(card);
-#ifndef CONFIG_SYSFS_DEPRECATED
 	if (card->card_dev) {
 		device_unregister(card->card_dev);
 		card->card_dev = NULL;
 	}
-#endif
 #ifdef CONFIG_PM
 	wake_up(&card->power_sleep);
 #endif
@@ -573,7 +571,6 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
 }
 EXPORT_SYMBOL(snd_card_set_id);
 
-#ifndef CONFIG_SYSFS_DEPRECATED
 static ssize_t
 card_id_show_attr(struct device *dev,
 		  struct device_attribute *attr, char *buf)
@@ -630,7 +627,6 @@ card_number_show_attr(struct device *dev,
 
 static struct device_attribute card_number_attrs =
 	__ATTR(number, S_IRUGO, card_number_show_attr, NULL);
-#endif /* CONFIG_SYSFS_DEPRECATED */
 
 /**
  *  snd_card_register - register the soundcard
@@ -649,7 +645,7 @@ int snd_card_register(struct snd_card *card)
 
 	if (snd_BUG_ON(!card))
 		return -EINVAL;
-#ifndef CONFIG_SYSFS_DEPRECATED
+
 	if (!card->card_dev) {
 		card->card_dev = device_create(sound_class, card->dev,
 					       MKDEV(0, 0), card,
@@ -657,7 +653,7 @@ int snd_card_register(struct snd_card *card)
 		if (IS_ERR(card->card_dev))
 			card->card_dev = NULL;
 	}
-#endif
+
 	if ((err = snd_device_register_all(card)) < 0)
 		return err;
 	mutex_lock(&snd_card_mutex);
@@ -674,7 +670,6 @@ int snd_card_register(struct snd_card *card)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
 #endif
-#ifndef CONFIG_SYSFS_DEPRECATED
 	if (card->card_dev) {
 		err = device_create_file(card->card_dev, &card_id_attrs);
 		if (err < 0)
@@ -683,7 +678,7 @@ int snd_card_register(struct snd_card *card)
 		if (err < 0)
 			return err;
 	}
-#endif
+
 	return 0;
 }
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 13/31] SYSFS: Allow boot time switching between deprecated and modern sysfs layout
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (11 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 12/31] driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:24 ` [PATCH 14/31] uio: Fix lack of locking in init_uio_class Greg Kroah-Hartman
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andi Kleen, axboe, Kay Sievers, Greg Kroah-Hartman

From: Andi Kleen <ak@linux.intel.com>

I have some systems which need legacy sysfs due to old tools that are
making assumptions that a directory can never be a symlink to another
directory, and it's a big hazzle to compile separate kernels for them.

This patch turns CONFIG_SYSFS_DEPRECATED into a run time option
that can be switched on/off the kernel command line. This way
the same binary can be used in both cases with just a option
on the command line.

The old CONFIG_SYSFS_DEPRECATED_V2 option is still there to set
the default. I kept the weird name to not break existing
config files.

Also the compat code can be still completely disabled by undefining
CONFIG_SYSFS_DEPRECATED_SWITCH -- just the optimizer takes
care of this now instead of lots of ifdefs. This makes the code
look nicer.

v2: This is an updated version on top of Kay's patch to only
handle the block devices. I tested it on my old systems
and that seems to work.

Cc: axboe@kernel.dk
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/kernel-parameters.txt |    9 +++++++++
 block/genhd.c                       |    7 ++-----
 drivers/base/class.c                |    4 ++--
 drivers/base/core.c                 |   26 +++++++++++++++++---------
 fs/partitions/check.c               |   19 +++++++++----------
 include/linux/device.h              |    7 +++++++
 init/Kconfig                        |   26 ++++++++++++++++++++++----
 7 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 3d854c9..67fa3fd 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2365,6 +2365,15 @@ and is between 256 and 4096 characters. It is defined in the file
 
 	switches=	[HW,M68k]
 
+	sysfs.deprecated=0|1 [KNL]
+			Enable/disable old style sysfs layout for old udev
+			on older distributions. When this option is enabled
+			very new udev will not work anymore. When this option
+			is disabled (or CONFIG_SYSFS_DEPRECATED not compiled)
+			in older udev will not work anymore.
+			Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in
+			the kernel configuration.
+
 	sysrq_always_enabled
 			[KNL]
 			Ignore sysrq setting - this boot parameter will
diff --git a/block/genhd.c b/block/genhd.c
index 59a2db6..4e28a84 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -22,9 +22,7 @@
 #include "blk.h"
 
 static DEFINE_MUTEX(block_class_lock);
-#ifndef CONFIG_SYSFS_DEPRECATED
 struct kobject *block_depr;
-#endif
 
 /* for extended dynamic devt allocation, currently only one major is used */
 #define MAX_EXT_DEVT		(1 << MINORBITS)
@@ -803,10 +801,9 @@ static int __init genhd_device_init(void)
 
 	register_blkdev(BLOCK_EXT_MAJOR, "blkext");
 
-#ifndef CONFIG_SYSFS_DEPRECATED
 	/* create top-level block dir */
-	block_depr = kobject_create_and_add("block", NULL);
-#endif
+	if (!sysfs_deprecated)
+		block_depr = kobject_create_and_add("block", NULL);
 	return 0;
 }
 
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 1078969..9c63a56 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
 	if (!cls->dev_kobj)
 		cls->dev_kobj = sysfs_dev_char_kobj;
 
-#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
+#if defined(CONFIG_BLOCK)
 	/* let the block class directory show up in the root of sysfs */
-	if (cls != &block_class)
+	if (!sysfs_deprecated || cls != &block_class)
 		cp->class_subsys.kobj.kset = class_kset;
 #else
 	cp->class_subsys.kobj.kset = class_kset;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6cf9069..f7f906f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -26,6 +26,19 @@
 #include "base.h"
 #include "power/power.h"
 
+#ifdef CONFIG_SYSFS_DEPRECATED
+#ifdef CONFIG_SYSFS_DEPRECATED_V2
+long sysfs_deprecated = 1;
+#else
+long sysfs_deprecated = 0;
+#endif
+static __init int sysfs_deprecated_setup(char *arg)
+{
+	return strict_strtol(arg, 10, &sysfs_deprecated);
+}
+early_param("sysfs.deprecated", sysfs_deprecated_setup);
+#endif
+
 int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
 static struct kobject *dev_kobj;
@@ -617,14 +630,13 @@ static struct kobject *get_device_parent(struct device *dev,
 		struct kobject *parent_kobj;
 		struct kobject *k;
 
-#ifdef CONFIG_SYSFS_DEPRECATED
 		/* block disks show up in /sys/block */
-		if (dev->class == &block_class) {
+		if (sysfs_deprecated && dev->class == &block_class) {
 			if (parent && parent->class == &block_class)
 				return &parent->kobj;
 			return &block_class.p->class_subsys.kobj;
 		}
-#endif
+
 		/*
 		 * If we have no parent, we live in "virtual".
 		 * Class-devices with a non class-device as parent, live
@@ -707,11 +719,9 @@ static int device_add_class_symlinks(struct device *dev)
 			goto out_subsys;
 	}
 
-#ifdef CONFIG_SYSFS_DEPRECATED
 	/* /sys/block has directories and does not need symlinks */
-	if (dev->class == &block_class)
+	if (sysfs_deprecated && dev->class == &block_class)
 		return 0;
-#endif
 
 	/* link in the class directory pointing to the device */
 	error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
@@ -738,10 +748,8 @@ static void device_remove_class_symlinks(struct device *dev)
 	if (dev->parent && device_is_not_partition(dev))
 		sysfs_remove_link(&dev->kobj, "device");
 	sysfs_remove_link(&dev->kobj, "subsystem");
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (dev->class == &block_class)
+	if (sysfs_deprecated && dev->class == &block_class)
 		return;
-#endif
 	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
 }
 
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 79fbf3f..137bf97 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -513,14 +513,14 @@ void register_disk(struct gendisk *disk)
 
 	if (device_add(ddev))
 		return;
-#ifndef CONFIG_SYSFS_DEPRECATED
-	err = sysfs_create_link(block_depr, &ddev->kobj,
-				kobject_name(&ddev->kobj));
-	if (err) {
-		device_del(ddev);
-		return;
+	if (!sysfs_deprecated) {
+		err = sysfs_create_link(block_depr, &ddev->kobj,
+					kobject_name(&ddev->kobj));
+		if (err) {
+			device_del(ddev);
+			return;
+		}
 	}
-#endif
 	disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
 	disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
 
@@ -737,8 +737,7 @@ void del_gendisk(struct gendisk *disk)
 	kobject_put(disk->part0.holder_dir);
 	kobject_put(disk->slave_dir);
 	disk->driverfs_dev = NULL;
-#ifndef CONFIG_SYSFS_DEPRECATED
-	sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
-#endif
+	if (!sysfs_deprecated)
+		sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
 	device_del(disk_to_dev(disk));
 }
diff --git a/include/linux/device.h b/include/linux/device.h
index 516feca..dd48953 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -751,4 +751,11 @@ do {						     \
 	MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
 #define MODULE_ALIAS_CHARDEV_MAJOR(major) \
 	MODULE_ALIAS("char-major-" __stringify(major) "-*")
+
+#ifdef CONFIG_SYSFS_DEPRECATED
+extern long sysfs_deprecated;
+#else
+#define sysfs_deprecated 0
+#endif
+
 #endif /* _DEVICE_H_ */
diff --git a/init/Kconfig b/init/Kconfig
index 137609f..d742b6f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -660,8 +660,12 @@ config SYSFS_DEPRECATED
 	depends on SYSFS
 	default n
 	help
-	  This option switches the layout of the "block" class devices, to not
-	  show up in /sys/class/block/, but only in /sys/block/.
+	  This option adds code that switches the layout of the "block" class
+	  devices, to not show up in /sys/class/block/, but only in
+	  /sys/block/.
+
+	  This switch is only active when the sysfs.deprecated=1 boot option is
+	  passed or the SYSFS_DEPRECATED_V2 option is set.
 
 	  This option allows new kernels to run on old distributions and tools,
 	  which might get confused by /sys/class/block/. Since 2007/2008 all
@@ -672,8 +676,22 @@ config SYSFS_DEPRECATED
 	  option enabled.
 
 	  Only if you are using a new kernel on an old distribution, you might
-	  need to say Y here. Never say Y, if the original kernel, that came
-	  with your distribution, has not set this option.
+	  need to say Y here.
+
+config SYSFS_DEPRECATED_V2
+	bool "enabled deprecated sysfs features by default"
+	default n
+	depends on SYSFS
+	depends on SYSFS_DEPRECATED
+	help
+	  Enable deprecated sysfs by default.
+
+	  See the CONFIG_SYSFS_DEPRECATED option for more details about this
+	  option.
+
+	  Only if you are using a new kernel on an old distribution, you might
+	  need to say Y here. Even then, odds are you would not need it
+	  enabled, you can always pass the boot option if absolutely necessary.
 
 config RELAY
 	bool "Kernel->user space relay support (formerly relayfs)"
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 14/31] uio: Fix lack of locking in init_uio_class
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (12 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 13/31] SYSFS: Allow boot time switching between deprecated and modern sysfs layout Greg Kroah-Hartman
@ 2010-10-22 18:24 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 15/31] uio: Don't clear driver data Greg Kroah-Hartman
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Hans J. Koch, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

There is no locking in init_uio_class so multiple
drivers can race and create multiple uio classes.

Fix this by simplifying the code.   In particular always
register the uio class during module_init and make things
simpler.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio.c |   58 +++++++++++++---------------------------------------
 1 files changed, 15 insertions(+), 43 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index bff1afb..bc774cc 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -45,10 +45,7 @@ static DEFINE_IDR(uio_idr);
 static const struct file_operations uio_fops;
 
 /* UIO class infrastructure */
-static struct uio_class {
-	struct kref kref;
-	struct class *class;
-} *uio_class;
+static struct class *uio_class;
 
 /* Protect idr accesses */
 static DEFINE_MUTEX(minor_lock);
@@ -757,55 +754,35 @@ static void uio_major_cleanup(void)
 
 static int init_uio_class(void)
 {
-	int ret = 0;
-
-	if (uio_class != NULL) {
-		kref_get(&uio_class->kref);
-		goto exit;
-	}
+	struct class *class;
+	int ret;
 
 	/* This is the first time in here, set everything up properly */
 	ret = uio_major_init();
 	if (ret)
 		goto exit;
 
-	uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
-	if (!uio_class) {
-		ret = -ENOMEM;
-		goto err_kzalloc;
-	}
-
-	kref_init(&uio_class->kref);
-	uio_class->class = class_create(THIS_MODULE, "uio");
-	if (IS_ERR(uio_class->class)) {
-		ret = IS_ERR(uio_class->class);
+	class = class_create(THIS_MODULE, "uio");
+	if (IS_ERR(class)) {
+		ret = IS_ERR(class);
 		printk(KERN_ERR "class_create failed for uio\n");
 		goto err_class_create;
 	}
+	uio_class = class;
 	return 0;
 
 err_class_create:
-	kfree(uio_class);
-	uio_class = NULL;
-err_kzalloc:
 	uio_major_cleanup();
 exit:
 	return ret;
 }
 
-static void release_uio_class(struct kref *kref)
+static void release_uio_class(void)
 {
 	/* Ok, we cheat as we know we only have one uio_class */
-	class_destroy(uio_class->class);
-	kfree(uio_class);
-	uio_major_cleanup();
+	class_destroy(uio_class);
 	uio_class = NULL;
-}
-
-static void uio_class_destroy(void)
-{
-	if (uio_class)
-		kref_put(&uio_class->kref, release_uio_class);
+	uio_major_cleanup();
 }
 
 /**
@@ -828,10 +805,6 @@ int __uio_register_device(struct module *owner,
 
 	info->uio_dev = NULL;
 
-	ret = init_uio_class();
-	if (ret)
-		return ret;
-
 	idev = kzalloc(sizeof(*idev), GFP_KERNEL);
 	if (!idev) {
 		ret = -ENOMEM;
@@ -847,7 +820,7 @@ int __uio_register_device(struct module *owner,
 	if (ret)
 		goto err_get_minor;
 
-	idev->dev = device_create(uio_class->class, parent,
+	idev->dev = device_create(uio_class, parent,
 				  MKDEV(uio_major, idev->minor), idev,
 				  "uio%d", idev->minor);
 	if (IS_ERR(idev->dev)) {
@@ -874,13 +847,12 @@ int __uio_register_device(struct module *owner,
 err_request_irq:
 	uio_dev_del_attributes(idev);
 err_uio_dev_add_attributes:
-	device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+	device_destroy(uio_class, MKDEV(uio_major, idev->minor));
 err_device_create:
 	uio_free_minor(idev);
 err_get_minor:
 	kfree(idev);
 err_kzalloc:
-	uio_class_destroy();
 	return ret;
 }
 EXPORT_SYMBOL_GPL(__uio_register_device);
@@ -907,9 +879,8 @@ void uio_unregister_device(struct uio_info *info)
 	uio_dev_del_attributes(idev);
 
 	dev_set_drvdata(idev->dev, NULL);
-	device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
+	device_destroy(uio_class, MKDEV(uio_major, idev->minor));
 	kfree(idev);
-	uio_class_destroy();
 
 	return;
 }
@@ -917,11 +888,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device);
 
 static int __init uio_init(void)
 {
-	return 0;
+	return init_uio_class();
 }
 
 static void __exit uio_exit(void)
 {
+	release_uio_class();
 }
 
 module_init(uio_init)
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 15/31] uio: Don't clear driver data
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (13 preceding siblings ...)
  2010-10-22 18:24 ` [PATCH 14/31] uio: Fix lack of locking in init_uio_class Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 16/31] uio: Cleanup irq handling Greg Kroah-Hartman
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Hans J. Koch, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

Currently uio sets it's driver data to NULL just as it is unregistering
attributes.  sysfs maks the guaranatee that it will not call attributes
after device_destroy is called so this is unncessary and leads to lots
of unnecessary code in uio.c

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio.c |   17 +++--------------
 1 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index bc774cc..8132288 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -229,10 +229,7 @@ static ssize_t show_name(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
 	struct uio_device *idev = dev_get_drvdata(dev);
-	if (idev)
-		return sprintf(buf, "%s\n", idev->info->name);
-	else
-		return -ENODEV;
+	return sprintf(buf, "%s\n", idev->info->name);
 }
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
@@ -240,10 +237,7 @@ static ssize_t show_version(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
 	struct uio_device *idev = dev_get_drvdata(dev);
-	if (idev)
-		return sprintf(buf, "%s\n", idev->info->version);
-	else
-		return -ENODEV;
+	return sprintf(buf, "%s\n", idev->info->version);
 }
 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
@@ -251,11 +245,7 @@ static ssize_t show_event(struct device *dev,
 			  struct device_attribute *attr, char *buf)
 {
 	struct uio_device *idev = dev_get_drvdata(dev);
-	if (idev)
-		return sprintf(buf, "%u\n",
-				(unsigned int)atomic_read(&idev->event));
-	else
-		return -ENODEV;
+	return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
 }
 static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
 
@@ -878,7 +868,6 @@ void uio_unregister_device(struct uio_info *info)
 
 	uio_dev_del_attributes(idev);
 
-	dev_set_drvdata(idev->dev, NULL);
 	device_destroy(uio_class, MKDEV(uio_major, idev->minor));
 	kfree(idev);
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 16/31] uio: Cleanup irq handling.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (14 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 15/31] uio: Don't clear driver data Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 17/31] uio: Support 2^MINOR_BITS minors Greg Kroah-Hartman
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Hans J. Koch, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

Change the value of UIO_IRQ_NONE -2 to 0.  0 is well defined in the rest
of the kernel as the value to indicate an irq has not been assigned.

Update the calls to request_irq and free_irq to only ignore UIO_IRQ_NONE
and UIO_IRQ_CUSTOM allowing the rest of the kernel's possible irq
numbers to be used.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio.c          |   14 +++++++-------
 include/linux/uio_driver.h |    2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 8132288..0fd2cda 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -512,7 +512,7 @@ static unsigned int uio_poll(struct file *filep, poll_table *wait)
 	struct uio_listener *listener = filep->private_data;
 	struct uio_device *idev = listener->dev;
 
-	if (idev->info->irq == UIO_IRQ_NONE)
+	if (!idev->info->irq)
 		return -EIO;
 
 	poll_wait(filep, &idev->wait, wait);
@@ -530,7 +530,7 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
 	ssize_t retval;
 	s32 event_count;
 
-	if (idev->info->irq == UIO_IRQ_NONE)
+	if (!idev->info->irq)
 		return -EIO;
 
 	if (count != sizeof(s32))
@@ -578,7 +578,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf,
 	ssize_t retval;
 	s32 irq_on;
 
-	if (idev->info->irq == UIO_IRQ_NONE)
+	if (!idev->info->irq)
 		return -EIO;
 
 	if (count != sizeof(s32))
@@ -825,9 +825,9 @@ int __uio_register_device(struct module *owner,
 
 	info->uio_dev = idev;
 
-	if (idev->info->irq >= 0) {
-		ret = request_irq(idev->info->irq, uio_interrupt,
-				  idev->info->irq_flags, idev->info->name, idev);
+	if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
+		ret = request_irq(info->irq, uio_interrupt,
+				  info->irq_flags, info->name, idev);
 		if (ret)
 			goto err_request_irq;
 	}
@@ -863,7 +863,7 @@ void uio_unregister_device(struct uio_info *info)
 
 	uio_free_minor(idev);
 
-	if (info->irq >= 0)
+	if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
 		free_irq(info->irq, idev);
 
 	uio_dev_del_attributes(idev);
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
index 5dcc9ff..d6188e5 100644
--- a/include/linux/uio_driver.h
+++ b/include/linux/uio_driver.h
@@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_info *info);
 
 /* defines for uio_info->irq */
 #define UIO_IRQ_CUSTOM	-1
-#define UIO_IRQ_NONE	-2
+#define UIO_IRQ_NONE	0
 
 /* defines for uio_mem->memtype */
 #define UIO_MEM_NONE	0
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 17/31] uio: Support 2^MINOR_BITS minors
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (15 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 16/31] uio: Cleanup irq handling Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 18/31] uio: Statically allocate uio_class and use class .dev_attrs Greg Kroah-Hartman
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Hans J. Koch, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

register_chrdev limits uio devices to 256 minor numbers which causes
problems on one system I have with 384+ uio devices.  So instead set
UIO_MAX_DEVICES to the maximum number of minors and use
alloc_chrdev_region to reserve the uio minors.

The final result is that the code works the same but the uio driver now
supports any minor the idr allocator comes up with.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio.c |   43 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 0fd2cda..3d4d65b 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -23,9 +23,10 @@
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/kobject.h>
+#include <linux/cdev.h>
 #include <linux/uio_driver.h>
 
-#define UIO_MAX_DEVICES 255
+#define UIO_MAX_DEVICES		(1U << MINORBITS)
 
 struct uio_device {
 	struct module		*owner;
@@ -41,6 +42,7 @@ struct uio_device {
 };
 
 static int uio_major;
+static struct cdev *uio_cdev;
 static DEFINE_IDR(uio_idr);
 static const struct file_operations uio_fops;
 
@@ -731,15 +733,44 @@ static const struct file_operations uio_fops = {
 
 static int uio_major_init(void)
 {
-	uio_major = register_chrdev(0, "uio", &uio_fops);
-	if (uio_major < 0)
-		return uio_major;
-	return 0;
+	static const char name[] = "uio";
+	struct cdev *cdev = NULL;
+	dev_t uio_dev = 0;
+	int result;
+
+	result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name);
+	if (result)
+		goto out;
+
+	result = -ENOMEM;
+	cdev = cdev_alloc();
+	if (!cdev)
+		goto out_unregister;
+
+	cdev->owner = THIS_MODULE;
+	cdev->ops = &uio_fops;
+	kobject_set_name(&cdev->kobj, "%s", name);
+
+	result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES);
+	if (result)
+		goto out_put;
+
+	uio_major = MAJOR(uio_dev);
+	uio_cdev = cdev;
+	result = 0;
+out:
+	return result;
+out_put:
+	kobject_put(&cdev->kobj);
+out_unregister:
+	unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
+	goto out;
 }
 
 static void uio_major_cleanup(void)
 {
-	unregister_chrdev(uio_major, "uio");
+	unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
+	cdev_del(uio_cdev);
 }
 
 static int init_uio_class(void)
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 18/31] uio: Statically allocate uio_class and use class .dev_attrs.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (16 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 17/31] uio: Support 2^MINOR_BITS minors Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 19/31] FW_LOADER: fix kconfig dependency warning on HOTPLUG Greg Kroah-Hartman
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Hans J. Koch, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

Instead of adding uio class attributes manually after the uio device has
been created and we have sent a uevent to userspace, use the class
attribute mechanism.  This removes races and makes the code simpler.

At the same time don't bother to dynamically allocate a struct class for
uio, just declare one statically.  Less code is needed and it is easier
to set the class parameters.tune the class

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/uio/uio.c |   53 ++++++++++++++++++-----------------------------------
 1 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 3d4d65b..3fe9a9d 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -46,9 +46,6 @@ static struct cdev *uio_cdev;
 static DEFINE_IDR(uio_idr);
 static const struct file_operations uio_fops;
 
-/* UIO class infrastructure */
-static struct class *uio_class;
-
 /* Protect idr accesses */
 static DEFINE_MUTEX(minor_lock);
 
@@ -233,7 +230,6 @@ static ssize_t show_name(struct device *dev,
 	struct uio_device *idev = dev_get_drvdata(dev);
 	return sprintf(buf, "%s\n", idev->info->name);
 }
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
 static ssize_t show_version(struct device *dev,
 			    struct device_attribute *attr, char *buf)
@@ -241,7 +237,6 @@ static ssize_t show_version(struct device *dev,
 	struct uio_device *idev = dev_get_drvdata(dev);
 	return sprintf(buf, "%s\n", idev->info->version);
 }
-static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
 static ssize_t show_event(struct device *dev,
 			  struct device_attribute *attr, char *buf)
@@ -249,17 +244,18 @@ static ssize_t show_event(struct device *dev,
 	struct uio_device *idev = dev_get_drvdata(dev);
 	return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
 }
-static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
 
-static struct attribute *uio_attrs[] = {
-	&dev_attr_name.attr,
-	&dev_attr_version.attr,
-	&dev_attr_event.attr,
-	NULL,
+static struct device_attribute uio_class_attributes[] = {
+	__ATTR(name, S_IRUGO, show_name, NULL),
+	__ATTR(version, S_IRUGO, show_version, NULL),
+	__ATTR(event, S_IRUGO, show_event, NULL),
+	{}
 };
 
-static struct attribute_group uio_attr_grp = {
-	.attrs = uio_attrs,
+/* UIO class infrastructure */
+static struct class uio_class = {
+	.name = "uio",
+	.dev_attrs = uio_class_attributes,
 };
 
 /*
@@ -276,10 +272,6 @@ static int uio_dev_add_attributes(struct uio_device *idev)
 	struct uio_port *port;
 	struct uio_portio *portio;
 
-	ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
-	if (ret)
-		goto err_group;
-
 	for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
 		mem = &idev->info->mem[mi];
 		if (mem->size == 0)
@@ -347,8 +339,6 @@ err_map:
 		kobject_put(&map->kobj);
 	}
 	kobject_put(idev->map_dir);
-	sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
-err_group:
 	dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
 	return ret;
 }
@@ -374,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
 		kobject_put(&port->portio->kobj);
 	}
 	kobject_put(idev->portio_dir);
-
-	sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
 }
 
 static int uio_get_minor(struct uio_device *idev)
@@ -775,7 +763,6 @@ static void uio_major_cleanup(void)
 
 static int init_uio_class(void)
 {
-	struct class *class;
 	int ret;
 
 	/* This is the first time in here, set everything up properly */
@@ -783,16 +770,14 @@ static int init_uio_class(void)
 	if (ret)
 		goto exit;
 
-	class = class_create(THIS_MODULE, "uio");
-	if (IS_ERR(class)) {
-		ret = IS_ERR(class);
-		printk(KERN_ERR "class_create failed for uio\n");
-		goto err_class_create;
+	ret = class_register(&uio_class);
+	if (ret) {
+		printk(KERN_ERR "class_register failed for uio\n");
+		goto err_class_register;
 	}
-	uio_class = class;
 	return 0;
 
-err_class_create:
+err_class_register:
 	uio_major_cleanup();
 exit:
 	return ret;
@@ -800,9 +785,7 @@ exit:
 
 static void release_uio_class(void)
 {
-	/* Ok, we cheat as we know we only have one uio_class */
-	class_destroy(uio_class);
-	uio_class = NULL;
+	class_unregister(&uio_class);
 	uio_major_cleanup();
 }
 
@@ -841,7 +824,7 @@ int __uio_register_device(struct module *owner,
 	if (ret)
 		goto err_get_minor;
 
-	idev->dev = device_create(uio_class, parent,
+	idev->dev = device_create(&uio_class, parent,
 				  MKDEV(uio_major, idev->minor), idev,
 				  "uio%d", idev->minor);
 	if (IS_ERR(idev->dev)) {
@@ -868,7 +851,7 @@ int __uio_register_device(struct module *owner,
 err_request_irq:
 	uio_dev_del_attributes(idev);
 err_uio_dev_add_attributes:
-	device_destroy(uio_class, MKDEV(uio_major, idev->minor));
+	device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
 err_device_create:
 	uio_free_minor(idev);
 err_get_minor:
@@ -899,7 +882,7 @@ void uio_unregister_device(struct uio_info *info)
 
 	uio_dev_del_attributes(idev);
 
-	device_destroy(uio_class, MKDEV(uio_major, idev->minor));
+	device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
 	kfree(idev);
 
 	return;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 19/31] FW_LOADER: fix kconfig dependency warning on HOTPLUG
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (17 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 18/31] uio: Statically allocate uio_class and use class .dev_attrs Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 20/31] sysfs: Fail bin file mmap if vma close is implemented Greg Kroah-Hartman
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, Greg Kroah-Hartman

From: Randy Dunlap <randy.dunlap@oracle.com>

Fix kconfig dependency warning for FW_LOADER.

Lots of drivers select FW_LOADER without bothering to depend on
HOTPLUG and/or without selecting HOTPLUG.  A kernel builds fine
when FW_LOADER is enabled, whether HOTPLUG is enabled or not, and
a kernel config file (make oldconfig) is not changed by this patch.
(Yes, drivers/base/firmware_class.c uses interfaces from linux/kobject.h,
which does have some CONFIG_HOTPLUG dependencies, but this patch does
not change that.)

warning: (MICROCODE || MICROCODE_INTEL && MICROCODE || MICROCODE_AMD && MICROCODE || PCMCIA_LOAD_CIS && PCCARD && PCMCIA && EXPERIMENTAL || USB_IRDA && NET && IRDA && USB || BT_HCIBCM203X && NET && BT && USB || BT_HCIBFUSB && NET && BT && USB || BT_HCIBT3C && NET && BT && PCMCIA || BT_MRVL_SDIO && NET
...
!STAGING_EXCLUDE_BUILD && USB && (X86 || ARM) && WLAN || DRM_NOUVEAU && STAGING && !STAGING_EXCLUDE_BUILD && DRM && PCI || TI_ST && STAGING && !STAGING_EXCLUDE_BUILD && RFKILL || DELL_RBU && X86) selects FW_LOADER which has unmet direct dependencies (HOTPLUG)
(5200 byte line reduced a lot)

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index ef38aff..fd96345 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD
 
 config FW_LOADER
 	tristate "Userspace firmware loading support" if EMBEDDED
-	depends on HOTPLUG
 	default y
 	---help---
 	  This option is provided for the case where no in-kernel-tree modules
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 20/31] sysfs: Fail bin file mmap if vma close is implemented.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (18 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 19/31] FW_LOADER: fix kconfig dependency warning on HOTPLUG Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 21/31] sysfs: only access bin file vm_ops with the active lock Greg Kroah-Hartman
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

It is not reasonably possible to wrap vma->close().  To correctly
wrap close would imply calling close on any vmas that remain when
sysfs_remove_bin_file is called.  Finding the proper lists walking
them getting the locking right etc, requires deep knowledge of the
mm subsystem and as such would require assistence from the mm
subsystem to implement.  That assistence does not currently exist.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/sysfs/bin.c |   26 ++++++++------------------
 1 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 4e321f7..d31d7b7 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -190,23 +190,6 @@ static void bin_vma_open(struct vm_area_struct *vma)
 	sysfs_put_active(attr_sd);
 }
 
-static void bin_vma_close(struct vm_area_struct *vma)
-{
-	struct file *file = vma->vm_file;
-	struct bin_buffer *bb = file->private_data;
-	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-
-	if (!bb->vm_ops || !bb->vm_ops->close)
-		return;
-
-	if (!sysfs_get_active(attr_sd))
-		return;
-
-	bb->vm_ops->close(vma);
-
-	sysfs_put_active(attr_sd);
-}
-
 static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
 	struct file *file = vma->vm_file;
@@ -331,7 +314,6 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
 
 static const struct vm_operations_struct bin_vm_ops = {
 	.open		= bin_vma_open,
-	.close		= bin_vma_close,
 	.fault		= bin_fault,
 	.page_mkwrite	= bin_page_mkwrite,
 	.access		= bin_access,
@@ -377,6 +359,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
 	if (bb->mmapped && bb->vm_ops != vma->vm_ops)
 		goto out_put;
 
+	/*
+	 * It is not possible to successfully wrap close.
+	 * So error if someone is trying to use close.
+	 */
+	rc = -EINVAL;
+	if (vma->vm_ops && vma->vm_ops->close)
+		goto out_put;
+
 	rc = 0;
 	bb->mmapped = 1;
 	bb->vm_ops = vma->vm_ops;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 21/31] sysfs: only access bin file vm_ops with the active lock
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (19 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 20/31] sysfs: Fail bin file mmap if vma close is implemented Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 22/31] driver-core: base: change to new flag variable Greg Kroah-Hartman
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric W. Biederman, Greg Kroah-Hartman

From: Eric W. Biederman <ebiederm@aristanetworks.com>

bb->vm_ops is a cached copy of the vm_ops of the underlying
sysfs bin file, which means that after sysfs_bin_remove_file
completes it is only longer valid to deference bb->vm_ops.

So move all of the tests of bb->vm_ops inside of where
we hold the sysfs active lock.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/sysfs/bin.c |   42 ++++++++++++++++++++++++++----------------
 1 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index d31d7b7..a475983 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -179,13 +179,14 @@ static void bin_vma_open(struct vm_area_struct *vma)
 	struct bin_buffer *bb = file->private_data;
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 
-	if (!bb->vm_ops || !bb->vm_ops->open)
+	if (!bb->vm_ops)
 		return;
 
 	if (!sysfs_get_active(attr_sd))
 		return;
 
-	bb->vm_ops->open(vma);
+	if (bb->vm_ops->open)
+		bb->vm_ops->open(vma);
 
 	sysfs_put_active(attr_sd);
 }
@@ -197,13 +198,15 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 	int ret;
 
-	if (!bb->vm_ops || !bb->vm_ops->fault)
+	if (!bb->vm_ops)
 		return VM_FAULT_SIGBUS;
 
 	if (!sysfs_get_active(attr_sd))
 		return VM_FAULT_SIGBUS;
 
-	ret = bb->vm_ops->fault(vma, vmf);
+	ret = VM_FAULT_SIGBUS;
+	if (bb->vm_ops->fault)
+		ret = bb->vm_ops->fault(vma, vmf);
 
 	sysfs_put_active(attr_sd);
 	return ret;
@@ -219,13 +222,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 	if (!bb->vm_ops)
 		return VM_FAULT_SIGBUS;
 
-	if (!bb->vm_ops->page_mkwrite)
-		return 0;
-
 	if (!sysfs_get_active(attr_sd))
 		return VM_FAULT_SIGBUS;
 
-	ret = bb->vm_ops->page_mkwrite(vma, vmf);
+	ret = 0;
+	if (bb->vm_ops->page_mkwrite)
+		ret = bb->vm_ops->page_mkwrite(vma, vmf);
 
 	sysfs_put_active(attr_sd);
 	return ret;
@@ -239,13 +241,15 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 	int ret;
 
-	if (!bb->vm_ops || !bb->vm_ops->access)
+	if (!bb->vm_ops)
 		return -EINVAL;
 
 	if (!sysfs_get_active(attr_sd))
 		return -EINVAL;
 
-	ret = bb->vm_ops->access(vma, addr, buf, len, write);
+	ret = -EINVAL;
+	if (bb->vm_ops->access)
+		ret = bb->vm_ops->access(vma, addr, buf, len, write);
 
 	sysfs_put_active(attr_sd);
 	return ret;
@@ -259,13 +263,15 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 	int ret;
 
-	if (!bb->vm_ops || !bb->vm_ops->set_policy)
+	if (!bb->vm_ops)
 		return 0;
 
 	if (!sysfs_get_active(attr_sd))
 		return -EINVAL;
 
-	ret = bb->vm_ops->set_policy(vma, new);
+	ret = 0;
+	if (bb->vm_ops->set_policy)
+		ret = bb->vm_ops->set_policy(vma, new);
 
 	sysfs_put_active(attr_sd);
 	return ret;
@@ -279,13 +285,15 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 	struct mempolicy *pol;
 
-	if (!bb->vm_ops || !bb->vm_ops->get_policy)
+	if (!bb->vm_ops)
 		return vma->vm_policy;
 
 	if (!sysfs_get_active(attr_sd))
 		return vma->vm_policy;
 
-	pol = bb->vm_ops->get_policy(vma, addr);
+	pol = vma->vm_policy;
+	if (bb->vm_ops->get_policy)
+		pol = bb->vm_ops->get_policy(vma, addr);
 
 	sysfs_put_active(attr_sd);
 	return pol;
@@ -299,13 +307,15 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
 	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
 	int ret;
 
-	if (!bb->vm_ops || !bb->vm_ops->migrate)
+	if (!bb->vm_ops)
 		return 0;
 
 	if (!sysfs_get_active(attr_sd))
 		return 0;
 
-	ret = bb->vm_ops->migrate(vma, from, to, flags);
+	ret = 0;
+	if (bb->vm_ops->migrate)
+		ret = bb->vm_ops->migrate(vma, from, to, flags);
 
 	sysfs_put_active(attr_sd);
 	return ret;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 22/31] driver-core: base: change to new flag variable
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (20 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 21/31] sysfs: only access bin file vm_ops with the active lock Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 23/31] driver core: fix build for CONFIG_BLOCK not enabled Greg Kroah-Hartman
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: matt mooney, Greg Kroah-Hartman

From: matt mooney <mfm@muteddisk.com>

Replace EXTRA_CFLAGS with ccflags-y.

Signed-off-by: matt mooney <mfm@muteddisk.com>
Acked-by: WANG Cong <xiyou.wangcong@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/Makefile |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index c12c7f2..5f51c3b 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -19,7 +19,5 @@ obj-$(CONFIG_MODULES)	+= module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 
-ifeq ($(CONFIG_DEBUG_DRIVER),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 23/31] driver core: fix build for CONFIG_BLOCK not enabled
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (21 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 22/31] driver-core: base: change to new flag variable Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 24/31] kobject: Introduce kset_find_obj_hinted Greg Kroah-Hartman
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, Greg Kroah-Hartman

From: Randy Dunlap <randy.dunlap@oracle.com>

Fix build errors when CONFIG_BLOCK is not enabled:

drivers/base/core.c: In function 'get_device_parent':
drivers/base/core.c:634: error: 'block_class' undeclared (first use in this function)
drivers/base/core.c: In function 'device_add_class_symlinks':
drivers/base/core.c:723: error: 'block_class' undeclared (first use in this function)
drivers/base/core.c: In function 'device_remove_class_symlinks':
drivers/base/core.c:751: error: 'block_class' undeclared (first use in this function)

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index f7f906f..2cb49a9 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -630,12 +630,14 @@ static struct kobject *get_device_parent(struct device *dev,
 		struct kobject *parent_kobj;
 		struct kobject *k;
 
+#ifdef CONFIG_BLOCK
 		/* block disks show up in /sys/block */
 		if (sysfs_deprecated && dev->class == &block_class) {
 			if (parent && parent->class == &block_class)
 				return &parent->kobj;
 			return &block_class.p->class_subsys.kobj;
 		}
+#endif
 
 		/*
 		 * If we have no parent, we live in "virtual".
@@ -719,9 +721,11 @@ static int device_add_class_symlinks(struct device *dev)
 			goto out_subsys;
 	}
 
+#ifdef CONFIG_BLOCK
 	/* /sys/block has directories and does not need symlinks */
 	if (sysfs_deprecated && dev->class == &block_class)
 		return 0;
+#endif
 
 	/* link in the class directory pointing to the device */
 	error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
@@ -748,8 +752,10 @@ static void device_remove_class_symlinks(struct device *dev)
 	if (dev->parent && device_is_not_partition(dev))
 		sysfs_remove_link(&dev->kobj, "device");
 	sysfs_remove_link(&dev->kobj, "subsystem");
+#ifdef CONFIG_BLOCK
 	if (sysfs_deprecated && dev->class == &block_class)
 		return;
+#endif
 	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
 }
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 24/31] kobject: Introduce kset_find_obj_hinted.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (22 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 23/31] driver core: fix build for CONFIG_BLOCK not enabled Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 25/31] driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Greg Kroah-Hartman
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Robin Holt, Greg Kroah-Hartman

From: Robin Holt <holt@sgi.com>

One call chain getting to kset_find_obj is:
  link_mem_sections()
    find_mem_section()
      kset_find_obj()

This is done during boot.  The memory sections were added in a linearly
increasing order and link_mem_sections tends to utilize them in that
same linear order.

Introduce a kset_find_obj_hinted which is passed the result of the
previous kset_find_obj which it uses for a quick "is the next object
our desired object" check before falling back to the old behavior.

Signed-off-by: Robin Holt <holt@sgi.com>
To: Robert P. J. Day <rpjday@crashcourse.ca>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/kobject.h |    2 ++
 lib/kobject.c           |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 7950a37..8f6d121 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktype(struct kobject *kobj)
 }
 
 extern struct kobject *kset_find_obj(struct kset *, const char *);
+extern struct kobject *kset_find_obj_hinted(struct kset *, const char *,
+						struct kobject *);
 
 /* The global /sys/kernel/ kobject for people to chain off of */
 extern struct kobject *kernel_kobj;
diff --git a/lib/kobject.c b/lib/kobject.c
index f07c572..82dc34c 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -746,17 +746,56 @@ void kset_unregister(struct kset *k)
  */
 struct kobject *kset_find_obj(struct kset *kset, const char *name)
 {
+	return kset_find_obj_hinted(kset, name, NULL);
+}
+
+/**
+ * kset_find_obj_hinted - search for object in kset given a predecessor hint.
+ * @kset: kset we're looking in.
+ * @name: object's name.
+ * @hint: hint to possible object's predecessor.
+ *
+ * Check the hint's next object and if it is a match return it directly,
+ * otherwise, fall back to the behavior of kset_find_obj().  Either way
+ * a reference for the returned object is held and the reference on the
+ * hinted object is released.
+ */
+struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
+				     struct kobject *hint)
+{
 	struct kobject *k;
 	struct kobject *ret = NULL;
 
 	spin_lock(&kset->list_lock);
+
+	if (!hint)
+		goto slow_search;
+
+	/* end of list detection */
+	if (hint->entry.next == kset->list.next)
+		goto slow_search;
+
+	k = container_of(hint->entry.next, struct kobject, entry);
+	if (!kobject_name(k) || strcmp(kobject_name(k), name))
+		goto slow_search;
+
+	ret = kobject_get(k);
+	goto unlock_exit;
+
+slow_search:
 	list_for_each_entry(k, &kset->list, entry) {
 		if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
 			ret = kobject_get(k);
 			break;
 		}
 	}
+
+unlock_exit:
 	spin_unlock(&kset->list_lock);
+
+	if (hint)
+		kobject_put(hint);
+
 	return ret;
 }
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 25/31] driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (23 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 24/31] kobject: Introduce kset_find_obj_hinted Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 26/31] driver core: Convert link_mem_sections to use find_memory_block_hinted Greg Kroah-Hartman
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Robin Holt, Greg Kroah-Hartman

From: Robin Holt <holt@sgi.com>

Introduce a find_memory_block_hinted() which utilizes the
recently added kset_find_obj_hinted().

Signed-off-by: Robin Holt <holt@sgi.com>
To: Dave Hansen <haveblue@us.ibm.com>
To: Matt Tolentino <matthew.e.tolentino@intel.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/memory.c  |   28 ++++++++++++++++++----------
 include/linux/memory.h |    2 ++
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 933442f..a799440 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -468,28 +468,23 @@ static int add_memory_block(int nid, struct mem_section *section,
 	return ret;
 }
 
-/*
- * For now, we have a linear search to go find the appropriate
- * memory_block corresponding to a particular phys_index. If
- * this gets to be a real problem, we can always use a radix
- * tree or something here.
- *
- * This could be made generic for all sysdev classes.
- */
-struct memory_block *find_memory_block(struct mem_section *section)
+struct memory_block *find_memory_block_hinted(struct mem_section *section,
+					      struct memory_block *hint)
 {
 	struct kobject *kobj;
 	struct sys_device *sysdev;
 	struct memory_block *mem;
 	char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
 
+	kobj = hint ? &hint->sysdev.kobj : NULL;
+
 	/*
 	 * This only works because we know that section == sysdev->id
 	 * slightly redundant with sysdev_register()
 	 */
 	sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
 
-	kobj = kset_find_obj(&memory_sysdev_class.kset, name);
+	kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
 	if (!kobj)
 		return NULL;
 
@@ -499,6 +494,19 @@ struct memory_block *find_memory_block(struct mem_section *section)
 	return mem;
 }
 
+/*
+ * For now, we have a linear search to go find the appropriate
+ * memory_block corresponding to a particular phys_index. If
+ * this gets to be a real problem, we can always use a radix
+ * tree or something here.
+ *
+ * This could be made generic for all sysdev classes.
+ */
+struct memory_block *find_memory_block(struct mem_section *section)
+{
+	return find_memory_block_hinted(section, NULL);
+}
+
 int remove_memory_block(unsigned long node_id, struct mem_section *section,
 		int phys_device)
 {
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 85582e1..c4f3127 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -113,6 +113,8 @@ extern int memory_dev_init(void);
 extern int remove_memory_block(unsigned long, struct mem_section *, int);
 extern int memory_notify(unsigned long val, void *v);
 extern int memory_isolate_notify(unsigned long val, void *v);
+extern struct memory_block *find_memory_block_hinted(struct mem_section *,
+							struct memory_block *);
 extern struct memory_block *find_memory_block(struct mem_section *);
 #define CONFIG_MEM_BLOCK_SIZE	(PAGES_PER_SECTION<<PAGE_SHIFT)
 enum mem_add_context { BOOT, HOTPLUG };
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 26/31] driver core: Convert link_mem_sections to use find_memory_block_hinted.
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (24 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 25/31] driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 27/31] hpilo: Despecificate driver from iLO generation Greg Kroah-Hartman
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Robin Holt, Greg Kroah-Hartman

From: Robin Holt <holt@sgi.com>

Modify link_mem_sections() to pass in the previous mem_block as a hint to
locating the next mem_block.  Since they are typically added in order this
results in a massive saving in time during boot of a very large system.
For example, on a 16TB x86_64 machine, it reduced the total time spent
linking all node's memory sections from 1 hour, 27 minutes to 46 seconds.

Signed-off-by: Robin Holt <holt@sgi.com>
To: Gary Hade <garyhade@us.ibm.com>
To: Badari Pulavarty <pbadari@us.ibm.com>
To: Ingo Molnar <mingo@elte.hu>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/node.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/base/node.c b/drivers/base/node.c
index 2872e86..ee53558 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -409,25 +409,27 @@ static int link_mem_sections(int nid)
 	unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
 	unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
 	unsigned long pfn;
+	struct memory_block *mem_blk = NULL;
 	int err = 0;
 
 	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
 		unsigned long section_nr = pfn_to_section_nr(pfn);
 		struct mem_section *mem_sect;
-		struct memory_block *mem_blk;
 		int ret;
 
 		if (!present_section_nr(section_nr))
 			continue;
 		mem_sect = __nr_to_section(section_nr);
-		mem_blk = find_memory_block(mem_sect);
+		mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
 		ret = register_mem_sect_under_node(mem_blk, nid);
 		if (!err)
 			err = ret;
 
 		/* discard ref obtained in find_memory_block() */
-		kobject_put(&mem_blk->sysdev.kobj);
 	}
+
+	if (mem_blk)
+		kobject_put(&mem_blk->sysdev.kobj);
 	return err;
 }
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 27/31] hpilo: Despecificate driver from iLO generation
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (25 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 26/31] driver core: Convert link_mem_sections to use find_memory_block_hinted Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 28/31] Driver core: Move find_memory_block routine Greg Kroah-Hartman
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: dann frazier, Greg Kroah-Hartman

From: dann frazier <dannf@hp.com>

This driver supports iLO, iLO2 and iLO3. However, comments and Kconfig
reference only iLO and iLO2. Let's just call it "iLO" to avoid having to
update strings for each iLO generation. This is similar to the change made
to hpwdt in commit 36e3ff44cebd7e46756dec88f30c982bebefdab7.

Signed-off-by: dann frazier <dannf@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/misc/Kconfig |   10 +++++-----
 drivers/misc/hpilo.c |    2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6f46e27..db2fbe2 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -248,15 +248,15 @@ config CS5535_CLOCK_EVENT_SRC
 	  generic PIT, and are suitable for use as high-res timers.
 
 config HP_ILO
-	tristate "Channel interface driver for HP iLO/iLO2 processor"
+	tristate "Channel interface driver for the HP iLO processor"
 	depends on PCI
 	default n
 	help
 	  The channel interface driver allows applications to communicate
-	  with iLO/iLO2 management processors present on HP ProLiant
-	  servers.  Upon loading, the driver creates /dev/hpilo/dXccbN files,
-	  which can be used to gather data from the management processor,
-	  via read and write system calls.
+	  with iLO management processors present on HP ProLiant servers.
+	  Upon loading, the driver creates /dev/hpilo/dXccbN files, which
+	  can be used to gather data from the management processor, via
+	  read and write system calls.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called hpilo.
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 557a8c2..d4158ec 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -1,5 +1,5 @@
 /*
- * Driver for HP iLO/iLO2 management processor.
+ * Driver for the HP iLO management processor.
  *
  * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
  *	David Altobelli <david.altobelli@hp.com>
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 28/31] Driver core: Move find_memory_block routine
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (26 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 27/31] hpilo: Despecificate driver from iLO generation Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 29/31] Driver core: Add mutex for adding/removing memory blocks Greg Kroah-Hartman
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Nathan Fontenot, Greg Kroah-Hartman

From: Nathan Fontenot <nfont@austin.ibm.com>

Move the find_memory_block() routine up to avoid needing a forward
declaration in subsequent patches.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-By: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/memory.c |   66 ++++++++++++++++++++++++------------------------
 1 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index a799440..63c2560 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -435,39 +435,6 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
 	return 0;
 }
 
-static int add_memory_block(int nid, struct mem_section *section,
-			unsigned long state, enum mem_add_context context)
-{
-	struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	unsigned long start_pfn;
-	int ret = 0;
-
-	if (!mem)
-		return -ENOMEM;
-
-	mem->phys_index = __section_nr(section);
-	mem->state = state;
-	mutex_init(&mem->state_mutex);
-	start_pfn = section_nr_to_pfn(mem->phys_index);
-	mem->phys_device = arch_get_memory_phys_device(start_pfn);
-
-	ret = register_memory(mem, section);
-	if (!ret)
-		ret = mem_create_simple_file(mem, phys_index);
-	if (!ret)
-		ret = mem_create_simple_file(mem, state);
-	if (!ret)
-		ret = mem_create_simple_file(mem, phys_device);
-	if (!ret)
-		ret = mem_create_simple_file(mem, removable);
-	if (!ret) {
-		if (context == HOTPLUG)
-			ret = register_mem_sect_under_node(mem, nid);
-	}
-
-	return ret;
-}
-
 struct memory_block *find_memory_block_hinted(struct mem_section *section,
 					      struct memory_block *hint)
 {
@@ -507,6 +474,39 @@ struct memory_block *find_memory_block(struct mem_section *section)
 	return find_memory_block_hinted(section, NULL);
 }
 
+static int add_memory_block(int nid, struct mem_section *section,
+			unsigned long state, enum mem_add_context context)
+{
+	struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	unsigned long start_pfn;
+	int ret = 0;
+
+	if (!mem)
+		return -ENOMEM;
+
+	mem->phys_index = __section_nr(section);
+	mem->state = state;
+	mutex_init(&mem->state_mutex);
+	start_pfn = section_nr_to_pfn(mem->phys_index);
+	mem->phys_device = arch_get_memory_phys_device(start_pfn);
+
+	ret = register_memory(mem, section);
+	if (!ret)
+		ret = mem_create_simple_file(mem, phys_index);
+	if (!ret)
+		ret = mem_create_simple_file(mem, state);
+	if (!ret)
+		ret = mem_create_simple_file(mem, phys_device);
+	if (!ret)
+		ret = mem_create_simple_file(mem, removable);
+	if (!ret) {
+		if (context == HOTPLUG)
+			ret = register_mem_sect_under_node(mem, nid);
+	}
+
+	return ret;
+}
+
 int remove_memory_block(unsigned long node_id, struct mem_section *section,
 		int phys_device)
 {
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 29/31] Driver core: Add mutex for adding/removing memory blocks
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (27 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 28/31] Driver core: Move find_memory_block routine Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 30/31] Driver core: Add section count to memory_block struct Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 31/31] driver core: Display error codes when class suspend fails Greg Kroah-Hartman
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Nathan Fontenot, Greg Kroah-Hartman

From: Nathan Fontenot <nfont@austin.ibm.com>

Add a new mutex for use in adding and removing of memory blocks.  This
is needed to avoid any race conditions in which the same memory block could
be added and removed at the same time.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-By: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/memory.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 63c2560..5185bcf 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -27,6 +27,8 @@
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
+static DEFINE_MUTEX(mem_sysfs_mutex);
+
 #define MEMORY_CLASS_NAME	"memory"
 
 static struct sysdev_class memory_sysdev_class = {
@@ -484,6 +486,8 @@ static int add_memory_block(int nid, struct mem_section *section,
 	if (!mem)
 		return -ENOMEM;
 
+	mutex_lock(&mem_sysfs_mutex);
+
 	mem->phys_index = __section_nr(section);
 	mem->state = state;
 	mutex_init(&mem->state_mutex);
@@ -504,6 +508,7 @@ static int add_memory_block(int nid, struct mem_section *section,
 			ret = register_mem_sect_under_node(mem, nid);
 	}
 
+	mutex_unlock(&mem_sysfs_mutex);
 	return ret;
 }
 
@@ -512,6 +517,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
 {
 	struct memory_block *mem;
 
+	mutex_lock(&mem_sysfs_mutex);
 	mem = find_memory_block(section);
 	unregister_mem_sect_under_nodes(mem);
 	mem_remove_simple_file(mem, phys_index);
@@ -520,6 +526,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
 	mem_remove_simple_file(mem, removable);
 	unregister_memory(mem, section);
 
+	mutex_unlock(&mem_sysfs_mutex);
 	return 0;
 }
 
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 30/31] Driver core: Add section count to memory_block struct
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (28 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 29/31] Driver core: Add mutex for adding/removing memory blocks Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  2010-10-22 18:25 ` [PATCH 31/31] driver core: Display error codes when class suspend fails Greg Kroah-Hartman
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Nathan Fontenot, Greg Kroah-Hartman

From: Nathan Fontenot <nfont@austin.ibm.com>

Add a section count property to the memory_block struct to track the number
of memory sections that have been added/removed from a memory block. This
allows us to know when the last memory section of a memory block has been
removed so we can remove the memory block.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/memory.c  |   17 +++++++++++------
 include/linux/memory.h |    2 ++
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 5185bcf..cafeaaf 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -490,6 +490,7 @@ static int add_memory_block(int nid, struct mem_section *section,
 
 	mem->phys_index = __section_nr(section);
 	mem->state = state;
+	mem->section_count++;
 	mutex_init(&mem->state_mutex);
 	start_pfn = section_nr_to_pfn(mem->phys_index);
 	mem->phys_device = arch_get_memory_phys_device(start_pfn);
@@ -519,12 +520,16 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
 
 	mutex_lock(&mem_sysfs_mutex);
 	mem = find_memory_block(section);
-	unregister_mem_sect_under_nodes(mem);
-	mem_remove_simple_file(mem, phys_index);
-	mem_remove_simple_file(mem, state);
-	mem_remove_simple_file(mem, phys_device);
-	mem_remove_simple_file(mem, removable);
-	unregister_memory(mem, section);
+
+	mem->section_count--;
+	if (mem->section_count == 0) {
+		unregister_mem_sect_under_nodes(mem);
+		mem_remove_simple_file(mem, phys_index);
+		mem_remove_simple_file(mem, state);
+		mem_remove_simple_file(mem, phys_device);
+		mem_remove_simple_file(mem, removable);
+		unregister_memory(mem, section);
+	}
 
 	mutex_unlock(&mem_sysfs_mutex);
 	return 0;
diff --git a/include/linux/memory.h b/include/linux/memory.h
index c4f3127..06c1fa0 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -23,6 +23,8 @@
 struct memory_block {
 	unsigned long phys_index;
 	unsigned long state;
+	int section_count;
+
 	/*
 	 * This serializes all state change requests.  It isn't
 	 * held during creation because the control files are
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 31/31] driver core: Display error codes when class suspend fails
  2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
                   ` (29 preceding siblings ...)
  2010-10-22 18:25 ` [PATCH 30/31] Driver core: Add section count to memory_block struct Greg Kroah-Hartman
@ 2010-10-22 18:25 ` Greg Kroah-Hartman
  30 siblings, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2010-10-22 18:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Mark Brown, Greg Kroah-Hartman

From: Mark Brown <broonie@opensource.wolfsonmicro.com>

Aid diagnostics by printing the error code from failed suspends, which
doesn't otherwise seem to get displayed.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/sys.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 9354dc1..1667aaf 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -432,13 +432,13 @@ int sysdev_suspend(pm_message_t state)
 	/* resume current sysdev */
 cls_driver:
 	drv = NULL;
-	printk(KERN_ERR "Class suspend failed for %s\n",
-		kobject_name(&sysdev->kobj));
+	printk(KERN_ERR "Class suspend failed for %s: %d\n",
+		kobject_name(&sysdev->kobj), ret);
 
 aux_driver:
 	if (drv)
-		printk(KERN_ERR "Class driver suspend failed for %s\n",
-				kobject_name(&sysdev->kobj));
+		printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
+				kobject_name(&sysdev->kobj), ret);
 	list_for_each_entry(err_drv, &cls->drivers, entry) {
 		if (err_drv == drv)
 			break;
-- 
1.7.2


^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2010-10-22 18:32 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-22 17:51 [GIT PATCH] driver core merge for .37-rc1 Greg KH
2010-10-22 18:24 ` [PATCH 01/31] Dynamic Debug: Split out query string parsing/setup from proc_write Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 02/31] Dynamic Debug: Introduce ddebug_query= boot parameter Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 03/31] Dynamic Debug: Initialize dynamic debug earlier via arch_initcall Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 04/31] driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 05/31] uio: do not use PCI resources before pci_enable_device() Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 06/31] driver core: platform_bus: allow runtime override of dev_pm_ops Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 07/31] add Packet hub driver for Topcliff Platform controller hub Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 08/31] pch_phub: fix build warnings Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 09/31] debugfs: mark me as the maintainer Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 10/31] base/platform: Safe handling for NULL platform data and resources Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 11/31] base/platform: Simplifications for NULL platform data/resources handling Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 12/31] driver core: remove CONFIG_SYSFS_DEPRECATED_V2 but keep it for block devices Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 13/31] SYSFS: Allow boot time switching between deprecated and modern sysfs layout Greg Kroah-Hartman
2010-10-22 18:24 ` [PATCH 14/31] uio: Fix lack of locking in init_uio_class Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 15/31] uio: Don't clear driver data Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 16/31] uio: Cleanup irq handling Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 17/31] uio: Support 2^MINOR_BITS minors Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 18/31] uio: Statically allocate uio_class and use class .dev_attrs Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 19/31] FW_LOADER: fix kconfig dependency warning on HOTPLUG Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 20/31] sysfs: Fail bin file mmap if vma close is implemented Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 21/31] sysfs: only access bin file vm_ops with the active lock Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 22/31] driver-core: base: change to new flag variable Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 23/31] driver core: fix build for CONFIG_BLOCK not enabled Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 24/31] kobject: Introduce kset_find_obj_hinted Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 25/31] driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 26/31] driver core: Convert link_mem_sections to use find_memory_block_hinted Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 27/31] hpilo: Despecificate driver from iLO generation Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 28/31] Driver core: Move find_memory_block routine Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 29/31] Driver core: Add mutex for adding/removing memory blocks Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 30/31] Driver core: Add section count to memory_block struct Greg Kroah-Hartman
2010-10-22 18:25 ` [PATCH 31/31] driver core: Display error codes when class suspend fails Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome