LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v2 0/3] Convert Hyper-V code to use the pnp layer
@ 2015-03-03 22:14 Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 1/3] drivers:pnp Add support for descendants claiming memory address space Jake Oshins
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jake Oshins @ 2015-03-03 22:14 UTC (permalink / raw)
  To: gregkh, kys, linux-kernel, devel, olaf, apw, vkuznets, rjw, arjan
  Cc: Jake Oshins

This set of patches changes the way that drivers in a Hyper-V VM find the
memory-mapped I/O space that they need.  The Hyper-V BIOS and UEFI
implementations expose a couple of large regions of MMIO space to the guests
using the ACPI namespace, with the expectation that the guest OS will subdivide
those regions for each of the paravirtual devices that require some.  The
firmware itself does not pick the specific regions for each device.

The old Hyper-V code that this patch set replaces found that region by directly
examining the ACPI namespace and exporting one of the ranges for use by a
single frame buffer driver.  This worked, so long as there was only one client
driver instance that wanted address space.

In order to allow multiple clients to each pick a region of memory-mapped I/O
space, the first patch adds a few wrapper functions in the kernel's pnp layer
which allow address space requests ("options") for drivers which are descendants
of the busses that the pnp layer already understands.  This ensures that 
descendants can make requests for MMIO space which don't conflict with "aunts"
and "uncles" in the device tree.  (Hyper-V VMs can have PCI devices which need
to claim from the space address space.)

The second patch converts hv_vmbus and all the related Hyper-V drivers to use
the pnp layer.  The third patch removes the older code which examined the ACPI
namespace directly.

Jake Oshins (3):
  drivers:pnp Add support for descendants claiming memory address space
  drivers:hv Convert VMBus and its descendants to PnP
  drivers:hv Remove old MMIO management code

 drivers/hid/hid-hyperv.c              |   6 +-
 drivers/hv/channel_mgmt.c             |   5 +-
 drivers/hv/hyperv_vmbus.h             |   1 +
 drivers/hv/vmbus_drv.c                | 145 +++++++++++++++-------------------
 drivers/input/serio/hyperv-keyboard.c |  24 +++---
 drivers/net/hyperv/netvsc.c           |   5 +-
 drivers/net/hyperv/netvsc_drv.c       |   4 +-
 drivers/net/hyperv/rndis_filter.c     |   4 +-
 drivers/pnp/Makefile                  |   2 +-
 drivers/pnp/base.h                    |   2 +
 drivers/pnp/core.c                    |   1 +
 drivers/pnp/descendant.c              | 117 +++++++++++++++++++++++++++
 drivers/scsi/storvsc_drv.c            |   2 +-
 drivers/video/fbdev/hyperv_fb.c       |  29 +++----
 include/linux/hyperv.h                |  17 ++--
 include/linux/pnp.h                   |  23 ++++++
 16 files changed, 261 insertions(+), 126 deletions(-)
 create mode 100644 drivers/pnp/descendant.c

-- 
1.9.1


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

* [PATCH v2 1/3] drivers:pnp Add support for descendants claiming memory address space
  2015-03-03 22:14 [PATCH v2 0/3] Convert Hyper-V code to use the pnp layer Jake Oshins
@ 2015-03-03 22:14 ` Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 2/3] drivers:hv Convert VMBus and its descendants to PnP Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 3/3] drivers:hv Remove old MMIO management code Jake Oshins
  2 siblings, 0 replies; 4+ messages in thread
From: Jake Oshins @ 2015-03-03 22:14 UTC (permalink / raw)
  To: gregkh, kys, linux-kernel, devel, olaf, apw, vkuznets, rjw, arjan
  Cc: Jake Oshins

This patch adds the concept of "descendant" device to the pnp layer, one which
can claim memory mapped I/O space from the same regions of address space that
its "aunts" and "uncles" are claiming from.  This is more or less analogous to
a device on an ISA bus that needs address space, but needs to avoid claiming
any regions that are in use by PCI devices which are peers of the PCI to ISA
bridge.

This is done in support of changes in the Hyper-V-related drivers, but nothing
in this patch is specific to Hyper-V, except in that it doesn't seem to be
needed for anything else.


Signed-off-by: Jake Oshins <jakeo@microsoft.com>
---
 drivers/pnp/Makefile     |   2 +-
 drivers/pnp/base.h       |   2 +
 drivers/pnp/core.c       |   1 +
 drivers/pnp/descendant.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pnp.h      |  23 ++++++++++
 5 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pnp/descendant.c

diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile
index bfba893..de315f9 100644
--- a/drivers/pnp/Makefile
+++ b/drivers/pnp/Makefile
@@ -4,7 +4,7 @@
 
 obj-y		:= pnp.o
 
-pnp-y		:= core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o
+pnp-y		:= core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o descendant.o
 
 obj-$(CONFIG_PNPACPI)		+= pnpacpi/
 obj-$(CONFIG_PNPBIOS)		+= pnpbios/
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index c8873b0..0b86437 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -175,6 +175,8 @@ struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
 					  resource_size_t start,
 					  resource_size_t end);
 
+int __init pnpdescendant_init(void);
+
 extern int pnp_debug;
 
 #if defined(CONFIG_PNP_DEBUG_MESSAGES)
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index cb6ce42..fc32912 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -212,6 +212,7 @@ void __pnp_remove_device(struct pnp_dev *dev)
 
 static int __init pnp_init(void)
 {
+	pnpdescendant_init();
 	return bus_register(&pnp_bus_type);
 }
 
diff --git a/drivers/pnp/descendant.c b/drivers/pnp/descendant.c
new file mode 100644
index 0000000..c25e40b
--- /dev/null
+++ b/drivers/pnp/descendant.c
@@ -0,0 +1,117 @@
+/*
+ * descendant.c - Resource management for devices which are descendants
+ * (children or grandchildren of) devices which directly allocate resources,
+ * i.e. devices enumerated by ACPI, PCI, PCMCIA, ISAPNP or PNPBIOS
+ *
+ * Copyright (C) 2015 Microsoft
+ *      Jake Oshins <jakeo@microsoft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pnp.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include "base.h"
+
+int descendant_get_resources(struct pnp_dev *dev)
+{
+	return 0;
+}
+
+int descendant_set_resources(struct pnp_dev *dev)
+{
+	return 0;
+}
+
+int descendant_disable_resources(struct pnp_dev *dev)
+{
+	return 0;
+}
+
+struct pnp_protocol descendant_protocol = {
+	.name	 = "Plug and Play descendants",
+	.get	 = descendant_get_resources,
+	.set	 = descendant_set_resources,
+	.disable = descendant_disable_resources,
+};
+
+/*
+ * This adds an option to the descendant device for memory address space.
+*/
+int pnp_descendant_memory_option(struct pnp_dev *dev, resource_size_t min,
+				 resource_size_t max, resource_size_t alignment,
+				 resource_size_t size, unsigned char flags)
+{
+	return pnp_register_mem_resource(dev, 0, min, max, alignment, size,
+					 flags);
+}
+EXPORT_SYMBOL(pnp_descendant_memory_option);
+
+/*
+ * This creates an entry in the plug-and-play layer for this device, which
+ * is a descendant of a device already in the plug-and-play layer.
+*/
+int pnp_add_descendant(struct pnp_dev *dev)
+{
+	int error;
+
+	error = pnp_add_device(dev);
+	if (error) {
+		put_device(&dev->dev);
+		return error;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(pnp_add_descendant);
+
+void pnp_remove_descendant(struct pnp_dev *dev)
+{
+	__pnp_remove_device(dev);
+}
+EXPORT_SYMBOL(pnp_remove_descendant);
+
+int __init pnpdescendant_init(void)
+{
+	return pnp_register_protocol(&descendant_protocol);
+}
+
+struct pnp_dev *alloc_pnp_descendant(const char *pnpid)
+{
+	struct pnp_dev *dev;
+
+	dev = pnp_alloc_dev(&descendant_protocol, 0, pnpid);
+
+	if (!dev)
+		return NULL;
+
+	pnp_init_resources(dev);
+	dev->capabilities |= PNP_CONFIGURABLE;
+	dev->capabilities |= PNP_READ;
+	dev->capabilities |= PNP_WRITE;
+	dev->capabilities |= PNP_DISABLE;
+	dev->capabilities |= PNP_REMOVABLE;
+
+	return dev;
+}
+EXPORT_SYMBOL(alloc_pnp_descendant);
+
+void free_pnp_descendant(struct pnp_dev *dev)
+{
+	kfree(dev);
+}
+EXPORT_SYMBOL(free_pnp_descendant);
+
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 6512e9c..269a7af 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -477,6 +477,15 @@ int compare_pnp_id(struct pnp_id *pos, const char *id);
 int pnp_register_driver(struct pnp_driver *drv);
 void pnp_unregister_driver(struct pnp_driver *drv);
 
+/* descendant support */
+struct pnp_dev *alloc_pnp_descendant(const char *pnpid);
+void free_pnp_descendant(struct pnp_dev *dev);
+int pnp_add_descendant(struct pnp_dev *dev);
+void pnp_remove_descendant(struct pnp_dev *dev);
+int pnp_descendant_memory_option(struct pnp_dev *dev, resource_size_t min,
+				 resource_size_t max, resource_size_t alignment,
+				 resource_size_t size, unsigned char flags);
+
 #else
 
 /* device management */
@@ -508,6 +517,20 @@ static inline int compare_pnp_id(struct pnp_id *pos, const char *id) { return -E
 static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
 static inline void pnp_unregister_driver(struct pnp_driver *drv) { }
 
+/* descendant support */
+static inline struct pnp_dev *alloc_pnp_descendant(const char *pnpid)
+{ return NULL; }
+static inline void free_pnp_descendant(struct pnp_dev *dev) { }
+static inline int pnp_add_descendant(struct pnp_dev *dev) { return -ENODEV; }
+static inline void pnp_remove_descendant(struct pnp_dev *dev) { }
+static inline int pnp_descendant_memory_option(struct pnp_dev *dev,
+					       resource_size_t min,
+					       resource_size_t max,
+					       resource_size_t alignment,
+					       resource_size_t size,
+					       unsigned char flags)
+{ return -ENODEV; }
+
 #endif /* CONFIG_PNP */
 
 #endif /* _LINUX_PNP_H */
-- 
1.9.1


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

* [PATCH v2 2/3] drivers:hv Convert VMBus and its descendants to PnP
  2015-03-03 22:14 [PATCH v2 0/3] Convert Hyper-V code to use the pnp layer Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 1/3] drivers:pnp Add support for descendants claiming memory address space Jake Oshins
@ 2015-03-03 22:14 ` Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 3/3] drivers:hv Remove old MMIO management code Jake Oshins
  2 siblings, 0 replies; 4+ messages in thread
From: Jake Oshins @ 2015-03-03 22:14 UTC (permalink / raw)
  To: gregkh, kys, linux-kernel, devel, olaf, apw, vkuznets, rjw, arjan
  Cc: Jake Oshins

This patch makes hv_vmbus and the devices that it discovers use the pnp layer,
so that address space claims made by these devices will hook into the regions
of address space exposed by ACPI, which already hooks into the pnp layer.

Previous feedback from Dan Carpenter has been incorporated.  (Thank you.)

Signed-off-by: Jake Oshins <jakeo@microsoft.com>
---
 drivers/hid/hid-hyperv.c              |   6 +-
 drivers/hv/channel_mgmt.c             |   5 +-
 drivers/hv/hyperv_vmbus.h             |   1 +
 drivers/hv/vmbus_drv.c                | 117 ++++++++++++++++++----------------
 drivers/input/serio/hyperv-keyboard.c |  24 +++----
 drivers/net/hyperv/netvsc.c           |   5 +-
 drivers/net/hyperv/netvsc_drv.c       |   4 +-
 drivers/net/hyperv/rndis_filter.c     |   4 +-
 drivers/scsi/storvsc_drv.c            |   2 +-
 drivers/video/fbdev/hyperv_fb.c       |  29 +++++----
 include/linux/hyperv.h                |  15 +++--
 11 files changed, 115 insertions(+), 97 deletions(-)

diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index 6039f07..0cf9105 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -309,7 +309,7 @@ static void mousevsc_on_receive(struct hv_device *device,
 		hid_input_report(input_dev->hid_device, HID_INPUT_REPORT,
 				 input_dev->input_buf, len, 1);
 
-		pm_wakeup_event(&input_dev->device->device, 0);
+		pm_wakeup_event(&input_dev->device->pnp_dev->dev, 0);
 
 		break;
 	default:
@@ -552,7 +552,7 @@ static int mousevsc_probe(struct hv_device *device,
 		goto probe_err2;
 	}
 
-	device_init_wakeup(&device->device, true);
+	device_init_wakeup(&device->pnp_dev->dev, true);
 
 	input_dev->connected = true;
 	input_dev->init_complete = true;
@@ -576,7 +576,7 @@ static int mousevsc_remove(struct hv_device *dev)
 {
 	struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
 
-	device_init_wakeup(&dev->device, false);
+	device_init_wakeup(&dev->pnp_dev->dev, false);
 	vmbus_close(dev->channel);
 	hid_hw_stop(input_dev->hid_device);
 	hid_destroy_device(input_dev->hid_device);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 3736f71..fcb1be8 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -218,8 +218,8 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
 	struct vmbus_channel_relid_released msg;
 	struct device *dev;
 
-	if (channel->device_obj) {
-		dev = get_device(&channel->device_obj->device);
+	if (channel->device_obj && channel->device_obj->pnp_dev) {
+		dev = get_device(&channel->device_obj->pnp_dev->dev);
 		if (dev) {
 			vmbus_device_unregister(channel->device_obj);
 			put_device(dev);
@@ -359,6 +359,7 @@ static void vmbus_process_offer(struct work_struct *work)
 	newchannel->device_obj = vmbus_device_create(
 		&newchannel->offermsg.offer.if_type,
 		&newchannel->offermsg.offer.if_instance,
+		newchannel->offermsg.offer.mmio_megabytes,
 		newchannel);
 	if (!newchannel->device_obj)
 		goto err_free_chan;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 44b1c94..73b9bc0 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -676,6 +676,7 @@ extern struct vmbus_connection vmbus_connection;
 
 struct hv_device *vmbus_device_create(const uuid_le *type,
 				      const uuid_le *instance,
+				      u16 mmio_mb,
 				      struct vmbus_channel *channel);
 
 int vmbus_device_register(struct hv_device *child_device_obj);
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f518b8d7..7783f4c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -487,6 +487,13 @@ static int vmbus_probe(struct device *child_device)
 	struct hv_device *dev = device_to_hv_device(child_device);
 	const struct hv_vmbus_device_id *dev_id;
 
+	ret = pnp_activate_dev(dev->pnp_dev);
+	if (ret) {
+		pr_err("Unable to activate child device %s\n",
+		       dev_name(&dev->pnp_dev->dev));
+		return ret;
+	}
+
 	dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
 	if (drv->probe) {
 		ret = drv->probe(dev, dev_id);
@@ -510,6 +517,8 @@ static int vmbus_remove(struct device *child_device)
 	struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
 	struct hv_device *dev = device_to_hv_device(child_device);
 
+	pnp_disable_dev(dev->pnp_dev);
+
 	if (drv->remove)
 		drv->remove(dev);
 	else
@@ -549,8 +558,10 @@ static void vmbus_device_release(struct device *device)
 {
 	struct hv_device *hv_dev = device_to_hv_device(device);
 
-	kfree(hv_dev);
+	if (hv_dev->pnp_dev)
+		free_pnp_descendant(hv_dev->pnp_dev);
 
+	kfree(hv_dev);
 }
 
 /* The one and only one */
@@ -579,34 +590,6 @@ static void vmbus_onmessage_work(struct work_struct *work)
 	kfree(ctx);
 }
 
-static void hv_process_timer_expiration(struct hv_message *msg, int cpu)
-{
-	struct clock_event_device *dev = hv_context.clk_evt[cpu];
-
-	if (dev->event_handler)
-		dev->event_handler(dev);
-
-	msg->header.message_type = HVMSG_NONE;
-
-	/*
-	 * Make sure the write to MessageType (ie set to
-	 * HVMSG_NONE) happens before we read the
-	 * MessagePending and EOMing. Otherwise, the EOMing
-	 * will not deliver any more messages since there is
-	 * no empty slot
-	 */
-	mb();
-
-	if (msg->header.message_flags.msg_pending) {
-		/*
-		 * This will cause message queue rescan to
-		 * possibly deliver another msg from the
-		 * hypervisor
-		 */
-		wrmsrl(HV_X64_MSR_EOM, 0);
-	}
-}
-
 static void vmbus_on_msg_dpc(unsigned long data)
 {
 	int cpu = smp_processor_id();
@@ -696,12 +679,8 @@ static void vmbus_isr(void)
 	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Check if there are actual msgs to be processed */
-	if (msg->header.message_type != HVMSG_NONE) {
-		if (msg->header.message_type == HVMSG_TIMER_EXPIRED)
-			hv_process_timer_expiration(msg, cpu);
-		else
-			tasklet_schedule(&msg_dpc);
-	}
+	if (msg->header.message_type != HVMSG_NONE)
+		tasklet_schedule(&msg_dpc);
 }
 
 /*
@@ -814,6 +793,7 @@ EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
  */
 struct hv_device *vmbus_device_create(const uuid_le *type,
 				      const uuid_le *instance,
+				      u16 mmio_mb,
 				      struct vmbus_channel *channel)
 {
 	struct hv_device *child_device_obj;
@@ -825,6 +805,7 @@ struct hv_device *vmbus_device_create(const uuid_le *type,
 	}
 
 	child_device_obj->channel = channel;
+	child_device_obj->mmio_mb = mmio_mb;
 	memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
 	memcpy(&child_device_obj->dev_instance, instance,
 	       sizeof(uuid_le));
@@ -838,28 +819,54 @@ struct hv_device *vmbus_device_create(const uuid_le *type,
  */
 int vmbus_device_register(struct hv_device *child_device_obj)
 {
-	int ret = 0;
-
+	int ret;
+	char device_id[40];
+	resource_size_t bytes = child_device_obj->mmio_mb * 0x100000;
 	static atomic_t device_num = ATOMIC_INIT(0);
 
-	dev_set_name(&child_device_obj->device, "vmbus_0_%d",
+
+	sprintf(device_id, "{%pUl}", child_device_obj->dev_instance.b);
+	child_device_obj->pnp_dev = alloc_pnp_descendant(device_id);
+	if (!child_device_obj->pnp_dev)
+		return -ENOMEM;
+
+	dev_set_name(&child_device_obj->pnp_dev->dev, "vmbus_0_%d",
 		     atomic_inc_return(&device_num));
 
-	child_device_obj->device.bus = &hv_bus;
-	child_device_obj->device.parent = &hv_acpi_dev->dev;
-	child_device_obj->device.release = vmbus_device_release;
+	child_device_obj->pnp_dev->data = child_device_obj;
+	child_device_obj->pnp_dev->dev.bus = &hv_bus;
+	child_device_obj->pnp_dev->dev.parent = &hv_acpi_dev->dev;
+	child_device_obj->pnp_dev->dev.release = vmbus_device_release;
 
-	/*
-	 * Register with the LDM. This will kick off the driver/device
-	 * binding...which will eventually call vmbus_match() and vmbus_probe()
-	 */
-	ret = device_register(&child_device_obj->device);
+	if (bytes) {
+		/*
+		 * Add a memory option that is aligned on the length.  All VMBus
+		 * channels can tolerate their memory regions going above
+		 * the 32-bit line.
+		 */
+		ret = pnp_descendant_memory_option(child_device_obj->pnp_dev,
+						   (u64)0x100000000,
+						   (u64)(-1),
+						   bytes,
+						   bytes,
+						   IORESOURCE_MEM_WRITEABLE);
+		if (ret)
+			goto err_free_des;
+	}
 
-	if (ret)
-		pr_err("Unable to register child device\n");
-	else
-		pr_debug("child device %s registered\n",
-			dev_name(&child_device_obj->device));
+	ret = pnp_add_descendant(child_device_obj->pnp_dev);
+	if (ret) {
+		pr_err("Unable to register child device %s\n",
+		       dev_name(&child_device_obj->pnp_dev->dev));
+		goto err_free_des;
+	}
+
+	pr_debug("child device %s registered\n",
+		 dev_name(&child_device_obj->pnp_dev->dev));
+	return 0;
+
+err_free_des:
+	free_pnp_descendant(child_device_obj->pnp_dev);
 
 	return ret;
 }
@@ -870,14 +877,14 @@ int vmbus_device_register(struct hv_device *child_device_obj)
  */
 void vmbus_device_unregister(struct hv_device *device_obj)
 {
-	pr_debug("child device %s unregistered\n",
-		dev_name(&device_obj->device));
-
 	/*
 	 * Kick off the process of unregistering the device.
 	 * This will call vmbus_remove() and eventually vmbus_device_release()
 	 */
-	device_unregister(&device_obj->device);
+	pnp_remove_descendant(device_obj->pnp_dev);
+
+	pr_debug("child device %s unregistered\n",
+		 dev_name(&device_obj->pnp_dev->dev));
 }
 
 
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index e74e5d6..0115e23 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -124,7 +124,7 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
 		 * goes away).
 		 */
 		if (msg_length < sizeof(struct synth_kbd_protocol_response)) {
-			dev_err(&hv_dev->device,
+			dev_err(&hv_dev->pnp_dev->dev,
 				"Illegal protocol response packet (len: %d)\n",
 				msg_length);
 			break;
@@ -143,7 +143,7 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
 		 * goes away).
 		 */
 		if (msg_length < sizeof(struct  synth_kbd_keystroke)) {
-			dev_err(&hv_dev->device,
+			dev_err(&hv_dev->pnp_dev->dev,
 				"Illegal keyboard event packet (len: %d)\n",
 				msg_length);
 			break;
@@ -177,12 +177,12 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
 		 * state because the Enter-UP can trigger a wakeup at once.
 		 */
 		if (!(info & IS_BREAK))
-			pm_wakeup_event(&hv_dev->device, 0);
+			pm_wakeup_event(&hv_dev->pnp_dev->dev, 0);
 
 		break;
 
 	default:
-		dev_err(&hv_dev->device,
+		dev_err(&hv_dev->pnp_dev->dev,
 			"unhandled message type %d\n", msg_type);
 	}
 }
@@ -225,7 +225,7 @@ static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,
 			 * Drop the packet and hope
 			 * the problem magically goes away.
 			 */
-			dev_err(&hv_dev->device,
+			dev_err(&hv_dev->pnp_dev->dev,
 				"Illegal packet (type: %d, tid: %llx, size: %d)\n",
 				desc->type, req_id, msg_sz);
 			break;
@@ -236,7 +236,7 @@ static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,
 		break;
 
 	default:
-		dev_err(&hv_dev->device,
+		dev_err(&hv_dev->pnp_dev->dev,
 			"unhandled packet type %d, tid %llx len %d\n",
 			desc->type, req_id, bytes_recvd);
 		break;
@@ -309,7 +309,7 @@ static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev)
 	response = &kbd_dev->protocol_resp;
 	proto_status = __le32_to_cpu(response->proto_status);
 	if (!(proto_status & PROTOCOL_ACCEPTED)) {
-		dev_err(&hv_dev->device,
+		dev_err(&hv_dev->pnp_dev->dev,
 			"synth_kbd protocol request failed (version %d)\n",
 		        SYNTH_KBD_VERSION);
 		return -ENODEV;
@@ -360,12 +360,12 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
 	init_completion(&kbd_dev->wait_event);
 	hv_set_drvdata(hv_dev, kbd_dev);
 
-	hv_serio->dev.parent  = &hv_dev->device;
+	hv_serio->dev.parent  = &hv_dev->pnp_dev->dev;
 	hv_serio->id.type = SERIO_8042_XL;
 	hv_serio->port_data = kbd_dev;
-	strlcpy(hv_serio->name, dev_name(&hv_dev->device),
+	strlcpy(hv_serio->name, dev_name(&hv_dev->pnp_dev->dev),
 		sizeof(hv_serio->name));
-	strlcpy(hv_serio->phys, dev_name(&hv_dev->device),
+	strlcpy(hv_serio->phys, dev_name(&hv_dev->pnp_dev->dev),
 		sizeof(hv_serio->phys));
 
 	hv_serio->start = hv_kbd_start;
@@ -386,7 +386,7 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
 
 	serio_register_port(kbd_dev->hv_serio);
 
-	device_init_wakeup(&hv_dev->device, true);
+	device_init_wakeup(&hv_dev->pnp_dev->dev, true);
 
 	return 0;
 
@@ -402,7 +402,7 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
 {
 	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
 
-	device_init_wakeup(&hv_dev->device, false);
+	device_init_wakeup(&hv_dev->pnp_dev->dev, false);
 	serio_unregister_port(kbd_dev->hv_serio);
 	vmbus_close(hv_dev->channel);
 	kfree(kbd_dev);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 208eb05..00ecfba 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -379,7 +379,8 @@ static int netvsc_init_buf(struct hv_device *device)
 	net_device->send_section_cnt =
 		net_device->send_buf_size/net_device->send_section_size;
 
-	dev_info(&device->device, "Send section size: %d, Section count:%d\n",
+	dev_info(&device->pnp_dev->dev,
+		 "Send section size: %d, Section count:%d\n",
 		 net_device->send_section_size, net_device->send_section_cnt);
 
 	/* Setup state for managing the send buffer. */
@@ -557,7 +558,7 @@ int netvsc_device_remove(struct hv_device *device)
 	 * At this point, no one should be accessing net_device
 	 * except in here
 	 */
-	dev_notice(&device->device, "net device safe to remove\n");
+	dev_notice(&device->pnp_dev->dev, "net device safe to remove\n");
 
 	/* Now, we can close the channel safely */
 	vmbus_close(device->channel);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index a06bd66..63f76ec4 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -867,7 +867,7 @@ static int netvsc_probe(struct hv_device *dev,
 			NETIF_F_IP_CSUM | NETIF_F_TSO;
 
 	net->ethtool_ops = &ethtool_ops;
-	SET_NETDEV_DEV(net, &dev->device);
+	SET_NETDEV_DEV(net, &dev->pnp_dev->dev);
 
 	/* Notify the netvsc driver of the new device */
 	device_info.ring_size = ring_size;
@@ -906,7 +906,7 @@ static int netvsc_remove(struct hv_device *dev)
 	net = net_device->ndev;
 
 	if (net == NULL) {
-		dev_err(&dev->device, "No net device to remove\n");
+		dev_err(&dev->pnp_dev->dev, "No net device to remove\n");
 		return 0;
 	}
 
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index ca81de0..958d24d3 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1080,7 +1080,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 
 	device_info->link_state = rndis_device->link_state;
 
-	dev_info(&dev->device, "Device MAC %pM link state %s\n",
+	dev_info(&dev->pnp_dev->dev, "Device MAC %pM link state %s\n",
 		 rndis_device->hw_mac_adr,
 		 device_info->link_state ? "down" : "up");
 
@@ -1105,7 +1105,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 					 NETVSC_PACKET_SIZE);
 	if (!net_device->sub_cb_buf) {
 		net_device->num_chn = 1;
-		dev_info(&dev->device, "No memory for subchannels.\n");
+		dev_info(&dev->pnp_dev->dev, "No memory for subchannels.\n");
 		goto out;
 	}
 
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..1f15a26b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1781,7 +1781,7 @@ static int storvsc_probe(struct hv_device *device,
 	host->max_cmd_len = STORVSC_MAX_CMD_LEN;
 
 	/* Register the HBA and start the scsi bus scan */
-	ret = scsi_add_host(host, &device->device);
+	ret = scsi_add_host(host, &device->pnp_dev->dev);
 	if (ret != 0)
 		goto err_out2;
 
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 4254336..161157e 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -675,26 +675,22 @@ static void hvfb_get_option(struct fb_info *info)
 
 
 /* Get framebuffer memory from Hyper-V video pci space */
-static int hvfb_getmem(struct fb_info *info)
+static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
 {
 	struct hvfb_par *par = info->par;
 	struct pci_dev *pdev  = NULL;
 	void __iomem *fb_virt;
+	struct resource *res;
 	int gen2vm = efi_enabled(EFI_BOOT);
 	int ret;
 
-	par->mem.name = KBUILD_MODNAME;
-	par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 	if (gen2vm) {
-		ret = allocate_resource(&hyperv_mmio, &par->mem,
-					screen_fb_size,
-					0, -1,
-					screen_fb_size,
-					NULL, NULL);
-		if (ret != 0) {
-			pr_err("Unable to allocate framebuffer memory\n");
+		res = pnp_get_resource(hdev->pnp_dev, IORESOURCE_MEM, 0);
+		if (!res) {
+			pr_err("Unable to fetch FB claim\n");
 			return -ENODEV;
 		}
+		par->mem = *res;
 	} else {
 		pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
 			      PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
@@ -707,6 +703,8 @@ static int hvfb_getmem(struct fb_info *info)
 		    pci_resource_len(pdev, 0) < screen_fb_size)
 			goto err1;
 
+		par->mem.name = KBUILD_MODNAME;
+		par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 		par->mem.end = pci_resource_end(pdev, 0);
 		par->mem.start = par->mem.end - screen_fb_size + 1;
 		ret = request_resource(&pdev->resource[0], &par->mem);
@@ -747,7 +745,8 @@ static int hvfb_getmem(struct fb_info *info)
 err3:
 	iounmap(fb_virt);
 err2:
-	release_resource(&par->mem);
+	if (!gen2vm)
+		release_resource(&par->mem);
 err1:
 	if (!gen2vm)
 		pci_dev_put(pdev);
@@ -759,9 +758,11 @@ err1:
 static void hvfb_putmem(struct fb_info *info)
 {
 	struct hvfb_par *par = info->par;
+	int gen2vm = efi_enabled(EFI_BOOT);
 
 	iounmap(info->screen_base);
-	release_resource(&par->mem);
+	if (!gen2vm)
+		release_resource(&par->mem);
 }
 
 
@@ -772,7 +773,7 @@ static int hvfb_probe(struct hv_device *hdev,
 	struct hvfb_par *par;
 	int ret;
 
-	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
+	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->pnp_dev->dev);
 	if (!info) {
 		pr_err("No memory for framebuffer info\n");
 		return -ENOMEM;
@@ -792,7 +793,7 @@ static int hvfb_probe(struct hv_device *hdev,
 		goto error1;
 	}
 
-	ret = hvfb_getmem(info);
+	ret = hvfb_getmem(hdev, info);
 	if (ret) {
 		pr_err("No memory for framebuffer\n");
 		goto error2;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 5a2ba67..796cc32 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -35,6 +35,7 @@
 #include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/pnp.h>
 
 
 #define MAX_PAGE_BUFFER_COUNT				32
@@ -928,7 +929,11 @@ struct hv_device {
 	/* the device instance id of this device */
 	uuid_le dev_instance;
 
-	struct device device;
+	/* the amount of memory address space that should be
+	   reserved for this channel, in megabytes */
+	u16 mmio_mb;
+
+	struct pnp_dev *pnp_dev;
 
 	struct vmbus_channel *channel;
 };
@@ -936,7 +941,9 @@ struct hv_device {
 
 static inline struct hv_device *device_to_hv_device(struct device *d)
 {
-	return container_of(d, struct hv_device, device);
+	struct pnp_dev *pnp_dev = container_of(d, struct pnp_dev, dev);
+
+	return (struct hv_device *)(pnp_dev->data);
 }
 
 static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
@@ -946,12 +953,12 @@ static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
 
 static inline void hv_set_drvdata(struct hv_device *dev, void *data)
 {
-	dev_set_drvdata(&dev->device, data);
+	dev_set_drvdata(&dev->pnp_dev->dev, data);
 }
 
 static inline void *hv_get_drvdata(struct hv_device *dev)
 {
-	return dev_get_drvdata(&dev->device);
+	return dev_get_drvdata(&dev->pnp_dev->dev);
 }
 
 /* Vmbus interface */
-- 
1.9.1


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

* [PATCH v2 3/3] drivers:hv Remove old MMIO management code
  2015-03-03 22:14 [PATCH v2 0/3] Convert Hyper-V code to use the pnp layer Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 1/3] drivers:pnp Add support for descendants claiming memory address space Jake Oshins
  2015-03-03 22:14 ` [PATCH v2 2/3] drivers:hv Convert VMBus and its descendants to PnP Jake Oshins
@ 2015-03-03 22:14 ` Jake Oshins
  2 siblings, 0 replies; 4+ messages in thread
From: Jake Oshins @ 2015-03-03 22:14 UTC (permalink / raw)
  To: gregkh, kys, linux-kernel, devel, olaf, apw, vkuznets, rjw, arjan
  Cc: Jake Oshins

This patch removes the now-redundant code which examined the ACPI namespace
directly for memory-mapped I/O regions for its children.

Signed-off-by: Jake Oshins <jakeo@microsoft.com>
---
 drivers/hv/vmbus_drv.c | 28 ++--------------------------
 include/linux/hyperv.h |  2 --
 2 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 7783f4c..193a362 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -44,12 +44,6 @@ static struct tasklet_struct msg_dpc;
 static struct completion probe_event;
 static int irq;
 
-struct resource hyperv_mmio = {
-	.name  = "hyperv mmio",
-	.flags = IORESOURCE_MEM,
-};
-EXPORT_SYMBOL_GPL(hyperv_mmio);
-
 static int vmbus_exists(void)
 {
 	if (hv_acpi_dev == NULL)
@@ -899,11 +893,6 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
 	case ACPI_RESOURCE_TYPE_IRQ:
 		irq = res->data.irq.interrupts[0];
 		break;
-
-	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		hyperv_mmio.start = res->data.address64.address.minimum;
-		hyperv_mmio.end = res->data.address64.address.maximum;
-		break;
 	}
 
 	return AE_OK;
@@ -917,24 +906,11 @@ static int vmbus_acpi_add(struct acpi_device *device)
 	hv_acpi_dev = device;
 
 	result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-					vmbus_walk_resources, NULL);
+				     vmbus_walk_resources, NULL);
 
 	if (ACPI_FAILURE(result))
 		goto acpi_walk_err;
-	/*
-	 * The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
-	 * has the mmio ranges. Get that.
-	 */
-	if (device->parent) {
-		result = acpi_walk_resources(device->parent->handle,
-					METHOD_NAME__CRS,
-					vmbus_walk_resources, NULL);
-
-		if (ACPI_FAILURE(result))
-			goto acpi_walk_err;
-		if (hyperv_mmio.start && hyperv_mmio.end)
-			request_resource(&iomem_resource, &hyperv_mmio);
-	}
+
 	ret_val = 0;
 
 acpi_walk_err:
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 796cc32..993ea5f 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1221,8 +1221,6 @@ int hv_vss_init(struct hv_util_service *);
 void hv_vss_deinit(void);
 void hv_vss_onchannelcallback(void *);
 
-extern struct resource hyperv_mmio;
-
 /*
  * Negotiated version with the Host.
  */
-- 
1.9.1


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

end of thread, other threads:[~2015-03-03 20:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-03 22:14 [PATCH v2 0/3] Convert Hyper-V code to use the pnp layer Jake Oshins
2015-03-03 22:14 ` [PATCH v2 1/3] drivers:pnp Add support for descendants claiming memory address space Jake Oshins
2015-03-03 22:14 ` [PATCH v2 2/3] drivers:hv Convert VMBus and its descendants to PnP Jake Oshins
2015-03-03 22:14 ` [PATCH v2 3/3] drivers:hv Remove old MMIO management code Jake Oshins

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).