Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thu, Feb 28, 2013 at 10:53:21PM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki > > USB uses the .find_bridge() callback from struct acpi_bus_type > incorrectly, because as a result of the way it is used by USB every > device in the system that doesn't have a bus type or parent is > passed to usb_acpi_find_device() for inspection. > > What USB actually needs, though, is to call usb_acpi_find_device() > for USB ports that don't have a bus type defined, but have > usb_port_device_type as their device type, as well as for USB > devices. > > To fix that replace the struct bus_type pointer in struct > acpi_bus_type used for matching devices to specific subsystems > with a .match() callback to be used for this purpose and update > the users of struct acpi_bus_type, including USB, accordingly. > Define the .match() callback routine for USB, usb_acpi_bus_match(), > in such a way that it will cover both USB devices and USB ports > and remove the now redundant .find_bridge() callback pointer from > usb_acpi_bus. > > Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thursday, February 28, 2013 02:29:56 PM Yinghai Lu wrote: > On Thu, Feb 28, 2013 at 1:53 PM, Rafael J. Wysocki wrote: > > From: Rafael J. Wysocki > > > > USB uses the .find_bridge() callback from struct acpi_bus_type > > incorrectly, because as a result of the way it is used by USB every > > device in the system that doesn't have a bus type or parent is > > passed to usb_acpi_find_device() for inspection. > > > > What USB actually needs, though, is to call usb_acpi_find_device() > > for USB ports that don't have a bus type defined, but have > > usb_port_device_type as their device type, as well as for USB > > devices. > > > > To fix that replace the struct bus_type pointer in struct > > acpi_bus_type used for matching devices to specific subsystems > > with a .match() callback to be used for this purpose and update > > the users of struct acpi_bus_type, including USB, accordingly. > > Define the .match() callback routine for USB, usb_acpi_bus_match(), > > in such a way that it will cover both USB devices and USB ports > > and remove the now redundant .find_bridge() callback pointer from > > usb_acpi_bus. > > > > Signed-off-by: Rafael J. Wysocki > > --- > > drivers/acpi/glue.c | 39 +-- > > drivers/ata/libata-acpi.c |1 + > > drivers/pci/pci-acpi.c |8 +++- > > drivers/pnp/pnpacpi/core.c |8 +++- > > drivers/scsi/scsi_lib.c |7 ++- > > drivers/usb/core/usb-acpi.c |9 +++-- > > include/acpi/acpi_bus.h |3 ++- > > 7 files changed, 43 insertions(+), 32 deletions(-) > > > > Index: linux-pm/include/acpi/acpi_bus.h > > === > > --- linux-pm.orig/include/acpi/acpi_bus.h > > +++ linux-pm/include/acpi/acpi_bus.h > > @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device > > */ > > struct acpi_bus_type { > > struct list_head list; > > - struct bus_type *bus; > > + const char *name; > > + bool (*match)(struct device *dev); > > /* For general devices under the bus */ > > int (*find_device) (struct device *, acpi_handle *); > > /* For bridges, such as PCI root bridge, IDE controller */ > > Index: linux-pm/drivers/acpi/glue.c > > === > > --- linux-pm.orig/drivers/acpi/glue.c > > +++ linux-pm/drivers/acpi/glue.c > > @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b > > { > > if (acpi_disabled) > > return -ENODEV; > > - if (type && type->bus && type->find_device) { > > + if (type && type->match && type->find_device) { > > down_write(_type_sem); > > list_add_tail(>list, _type_list); > > up_write(_type_sem); > > - printk(KERN_INFO PREFIX "bus type %s registered\n", > > - type->bus->name); > > + printk(KERN_INFO PREFIX "bus type %s registered\n", > > type->name); > > return 0; > > } > > return -ENODEV; > > @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi > > down_write(_type_sem); > > list_del_init(>list); > > up_write(_type_sem); > > - printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", > > - type->bus->name); > > + printk(KERN_INFO PREFIX "bus type %s unregistered\n", > > + type->name); > > return 0; > > } > > return -ENODEV; > > } > > EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); > > > > -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) > > +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) > > { > > struct acpi_bus_type *tmp, *ret = NULL; > > > > - if (!type) > > - return NULL; > > - > > down_read(_type_sem); > > list_for_each_entry(tmp, _type_list, list) { > > - if (tmp->bus == type) { > > + if (tmp->match(dev)) { > > ret = tmp; > > break; > > } > > @@ -261,26 +257,17 @@ err: > > > > static int acpi_platform_notify(struct device *dev) > > { > > - struct acpi_bus_type *type; > > + struct acpi_bus_type *type = acpi_get_bus_type(dev); > > acpi_handle handle; > > int ret; > > > > ret = acpi_bind_one(dev, NULL); > > - if (ret && (!dev->bus || !dev->parent)) { > > - /* bridge devices genernally haven't bus or parent */ > > - ret = acpi_find_bridge_device(dev, ); > > - if (!ret) { > > - ret = acpi_bind_one(dev, handle); > > - if (ret) > > - goto out; > > - } > > - } > > - > > - type = acpi_get_bus_type(dev->bus); > > if (ret) { > > -
Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thu, Feb 28, 2013 at 1:53 PM, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki > > USB uses the .find_bridge() callback from struct acpi_bus_type > incorrectly, because as a result of the way it is used by USB every > device in the system that doesn't have a bus type or parent is > passed to usb_acpi_find_device() for inspection. > > What USB actually needs, though, is to call usb_acpi_find_device() > for USB ports that don't have a bus type defined, but have > usb_port_device_type as their device type, as well as for USB > devices. > > To fix that replace the struct bus_type pointer in struct > acpi_bus_type used for matching devices to specific subsystems > with a .match() callback to be used for this purpose and update > the users of struct acpi_bus_type, including USB, accordingly. > Define the .match() callback routine for USB, usb_acpi_bus_match(), > in such a way that it will cover both USB devices and USB ports > and remove the now redundant .find_bridge() callback pointer from > usb_acpi_bus. > > Signed-off-by: Rafael J. Wysocki > --- > drivers/acpi/glue.c | 39 +-- > drivers/ata/libata-acpi.c |1 + > drivers/pci/pci-acpi.c |8 +++- > drivers/pnp/pnpacpi/core.c |8 +++- > drivers/scsi/scsi_lib.c |7 ++- > drivers/usb/core/usb-acpi.c |9 +++-- > include/acpi/acpi_bus.h |3 ++- > 7 files changed, 43 insertions(+), 32 deletions(-) > > Index: linux-pm/include/acpi/acpi_bus.h > === > --- linux-pm.orig/include/acpi/acpi_bus.h > +++ linux-pm/include/acpi/acpi_bus.h > @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device > */ > struct acpi_bus_type { > struct list_head list; > - struct bus_type *bus; > + const char *name; > + bool (*match)(struct device *dev); > /* For general devices under the bus */ > int (*find_device) (struct device *, acpi_handle *); > /* For bridges, such as PCI root bridge, IDE controller */ > Index: linux-pm/drivers/acpi/glue.c > === > --- linux-pm.orig/drivers/acpi/glue.c > +++ linux-pm/drivers/acpi/glue.c > @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b > { > if (acpi_disabled) > return -ENODEV; > - if (type && type->bus && type->find_device) { > + if (type && type->match && type->find_device) { > down_write(_type_sem); > list_add_tail(>list, _type_list); > up_write(_type_sem); > - printk(KERN_INFO PREFIX "bus type %s registered\n", > - type->bus->name); > + printk(KERN_INFO PREFIX "bus type %s registered\n", > type->name); > return 0; > } > return -ENODEV; > @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi > down_write(_type_sem); > list_del_init(>list); > up_write(_type_sem); > - printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", > - type->bus->name); > + printk(KERN_INFO PREFIX "bus type %s unregistered\n", > + type->name); > return 0; > } > return -ENODEV; > } > EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); > > -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) > +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) > { > struct acpi_bus_type *tmp, *ret = NULL; > > - if (!type) > - return NULL; > - > down_read(_type_sem); > list_for_each_entry(tmp, _type_list, list) { > - if (tmp->bus == type) { > + if (tmp->match(dev)) { > ret = tmp; > break; > } > @@ -261,26 +257,17 @@ err: > > static int acpi_platform_notify(struct device *dev) > { > - struct acpi_bus_type *type; > + struct acpi_bus_type *type = acpi_get_bus_type(dev); > acpi_handle handle; > int ret; > > ret = acpi_bind_one(dev, NULL); > - if (ret && (!dev->bus || !dev->parent)) { > - /* bridge devices genernally haven't bus or parent */ > - ret = acpi_find_bridge_device(dev, ); > - if (!ret) { > - ret = acpi_bind_one(dev, handle); > - if (ret) > - goto out; > - } > - } > - > - type = acpi_get_bus_type(dev->bus); > if (ret) { > - if (!type || !type->find_device) { > - DBG("No ACPI bus support for %s\n", dev_name(dev)); > - ret = -EINVAL; > + if (!type) { > + ret = acpi_find_bridge_device(dev, ); > + if (!ret) >
[PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
From: Rafael J. Wysocki USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/glue.c | 39 +-- drivers/ata/libata-acpi.c |1 + drivers/pci/pci-acpi.c |8 +++- drivers/pnp/pnpacpi/core.c |8 +++- drivers/scsi/scsi_lib.c |7 ++- drivers/usb/core/usb-acpi.c |9 +++-- include/acpi/acpi_bus.h |3 ++- 7 files changed, 43 insertions(+), 32 deletions(-) Index: linux-pm/include/acpi/acpi_bus.h === --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device */ struct acpi_bus_type { struct list_head list; - struct bus_type *bus; + const char *name; + bool (*match)(struct device *dev); /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ Index: linux-pm/drivers/acpi/glue.c === --- linux-pm.orig/drivers/acpi/glue.c +++ linux-pm/drivers/acpi/glue.c @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b { if (acpi_disabled) return -ENODEV; - if (type && type->bus && type->find_device) { + if (type && type->match && type->find_device) { down_write(_type_sem); list_add_tail(>list, _type_list); up_write(_type_sem); - printk(KERN_INFO PREFIX "bus type %s registered\n", - type->bus->name); + printk(KERN_INFO PREFIX "bus type %s registered\n", type->name); return 0; } return -ENODEV; @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi down_write(_type_sem); list_del_init(>list); up_write(_type_sem); - printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", - type->bus->name); + printk(KERN_INFO PREFIX "bus type %s unregistered\n", + type->name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(_type_sem); list_for_each_entry(tmp, _type_list, list) { - if (tmp->bus == type) { + if (tmp->match(dev)) { ret = tmp; break; } @@ -261,26 +257,17 @@ err: static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type; + struct acpi_bus_type *type = acpi_get_bus_type(dev); acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret && (!dev->bus || !dev->parent)) { - /* bridge devices genernally haven't bus or parent */ - ret = acpi_find_bridge_device(dev, ); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } - } - - type = acpi_get_bus_type(dev->bus); if (ret) { - if (!type || !type->find_device) { - DBG("No ACPI bus support for %s\n", dev_name(dev)); - ret = -EINVAL; + if (!type) { + ret = acpi_find_bridge_device(dev, ); + if (!ret) + ret = acpi_bind_one(dev, handle); + goto out; } @@ -316,7 +303,7 @@ static int acpi_platform_notify_remove(s { struct acpi_bus_type *type; - type = acpi_get_bus_type(dev->bus); + type =
[PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
From: Rafael J. Wysocki rafael.j.wyso...@intel.com USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com --- drivers/acpi/glue.c | 39 +-- drivers/ata/libata-acpi.c |1 + drivers/pci/pci-acpi.c |8 +++- drivers/pnp/pnpacpi/core.c |8 +++- drivers/scsi/scsi_lib.c |7 ++- drivers/usb/core/usb-acpi.c |9 +++-- include/acpi/acpi_bus.h |3 ++- 7 files changed, 43 insertions(+), 32 deletions(-) Index: linux-pm/include/acpi/acpi_bus.h === --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device */ struct acpi_bus_type { struct list_head list; - struct bus_type *bus; + const char *name; + bool (*match)(struct device *dev); /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ Index: linux-pm/drivers/acpi/glue.c === --- linux-pm.orig/drivers/acpi/glue.c +++ linux-pm/drivers/acpi/glue.c @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b { if (acpi_disabled) return -ENODEV; - if (type type-bus type-find_device) { + if (type type-match type-find_device) { down_write(bus_type_sem); list_add_tail(type-list, bus_type_list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX bus type %s registered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s registered\n, type-name); return 0; } return -ENODEV; @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi down_write(bus_type_sem); list_del_init(type-list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX ACPI bus type %s unregistered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s unregistered\n, + type-name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(bus_type_sem); list_for_each_entry(tmp, bus_type_list, list) { - if (tmp-bus == type) { + if (tmp-match(dev)) { ret = tmp; break; } @@ -261,26 +257,17 @@ err: static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type; + struct acpi_bus_type *type = acpi_get_bus_type(dev); acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret (!dev-bus || !dev-parent)) { - /* bridge devices genernally haven't bus or parent */ - ret = acpi_find_bridge_device(dev, handle); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } - } - - type = acpi_get_bus_type(dev-bus); if (ret) { - if (!type || !type-find_device) { - DBG(No ACPI bus support for %s\n, dev_name(dev)); - ret = -EINVAL; + if (!type) { + ret = acpi_find_bridge_device(dev, handle); + if (!ret) + ret = acpi_bind_one(dev, handle); + goto out; } @@ -316,7 +303,7 @@ static int acpi_platform_notify_remove(s { struct acpi_bus_type *type; - type
Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thu, Feb 28, 2013 at 1:53 PM, Rafael J. Wysocki r...@sisk.pl wrote: From: Rafael J. Wysocki rafael.j.wyso...@intel.com USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com --- drivers/acpi/glue.c | 39 +-- drivers/ata/libata-acpi.c |1 + drivers/pci/pci-acpi.c |8 +++- drivers/pnp/pnpacpi/core.c |8 +++- drivers/scsi/scsi_lib.c |7 ++- drivers/usb/core/usb-acpi.c |9 +++-- include/acpi/acpi_bus.h |3 ++- 7 files changed, 43 insertions(+), 32 deletions(-) Index: linux-pm/include/acpi/acpi_bus.h === --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device */ struct acpi_bus_type { struct list_head list; - struct bus_type *bus; + const char *name; + bool (*match)(struct device *dev); /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ Index: linux-pm/drivers/acpi/glue.c === --- linux-pm.orig/drivers/acpi/glue.c +++ linux-pm/drivers/acpi/glue.c @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b { if (acpi_disabled) return -ENODEV; - if (type type-bus type-find_device) { + if (type type-match type-find_device) { down_write(bus_type_sem); list_add_tail(type-list, bus_type_list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX bus type %s registered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s registered\n, type-name); return 0; } return -ENODEV; @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi down_write(bus_type_sem); list_del_init(type-list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX ACPI bus type %s unregistered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s unregistered\n, + type-name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(bus_type_sem); list_for_each_entry(tmp, bus_type_list, list) { - if (tmp-bus == type) { + if (tmp-match(dev)) { ret = tmp; break; } @@ -261,26 +257,17 @@ err: static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type; + struct acpi_bus_type *type = acpi_get_bus_type(dev); acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret (!dev-bus || !dev-parent)) { - /* bridge devices genernally haven't bus or parent */ - ret = acpi_find_bridge_device(dev, handle); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } - } - - type = acpi_get_bus_type(dev-bus); if (ret) { - if (!type || !type-find_device) { - DBG(No ACPI bus support for %s\n, dev_name(dev)); - ret = -EINVAL; + if (!type) { + ret = acpi_find_bridge_device(dev, handle); + if (!ret) + ret =
Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thursday, February 28, 2013 02:29:56 PM Yinghai Lu wrote: On Thu, Feb 28, 2013 at 1:53 PM, Rafael J. Wysocki r...@sisk.pl wrote: From: Rafael J. Wysocki rafael.j.wyso...@intel.com USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com --- drivers/acpi/glue.c | 39 +-- drivers/ata/libata-acpi.c |1 + drivers/pci/pci-acpi.c |8 +++- drivers/pnp/pnpacpi/core.c |8 +++- drivers/scsi/scsi_lib.c |7 ++- drivers/usb/core/usb-acpi.c |9 +++-- include/acpi/acpi_bus.h |3 ++- 7 files changed, 43 insertions(+), 32 deletions(-) Index: linux-pm/include/acpi/acpi_bus.h === --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device */ struct acpi_bus_type { struct list_head list; - struct bus_type *bus; + const char *name; + bool (*match)(struct device *dev); /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ Index: linux-pm/drivers/acpi/glue.c === --- linux-pm.orig/drivers/acpi/glue.c +++ linux-pm/drivers/acpi/glue.c @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_b { if (acpi_disabled) return -ENODEV; - if (type type-bus type-find_device) { + if (type type-match type-find_device) { down_write(bus_type_sem); list_add_tail(type-list, bus_type_list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX bus type %s registered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s registered\n, type-name); return 0; } return -ENODEV; @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi down_write(bus_type_sem); list_del_init(type-list); up_write(bus_type_sem); - printk(KERN_INFO PREFIX ACPI bus type %s unregistered\n, - type-bus-name); + printk(KERN_INFO PREFIX bus type %s unregistered\n, + type-name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(bus_type_sem); list_for_each_entry(tmp, bus_type_list, list) { - if (tmp-bus == type) { + if (tmp-match(dev)) { ret = tmp; break; } @@ -261,26 +257,17 @@ err: static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type; + struct acpi_bus_type *type = acpi_get_bus_type(dev); acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret (!dev-bus || !dev-parent)) { - /* bridge devices genernally haven't bus or parent */ - ret = acpi_find_bridge_device(dev, handle); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } - } - - type = acpi_get_bus_type(dev-bus); if (ret) { - if (!type || !type-find_device) { - DBG(No ACPI bus support for %s\n, dev_name(dev)); - ret = -EINVAL; +
Re: [PATCH 1/2] ACPI / glue: Add .match() callback to struct acpi_bus_type
On Thu, Feb 28, 2013 at 10:53:21PM +0100, Rafael J. Wysocki wrote: From: Rafael J. Wysocki rafael.j.wyso...@intel.com USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com Acked-by: Greg Kroah-Hartman gre...@linuxfoundation.org -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/