From patchwork Wed Sep 15 20:16:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 183362 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8FKIYkt022806 for ; Wed, 15 Sep 2010 20:18:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754080Ab0IOUSc (ORCPT ); Wed, 15 Sep 2010 16:18:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42498 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754030Ab0IOUSb (ORCPT ); Wed, 15 Sep 2010 16:18:31 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8FKGO52032730 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 15 Sep 2010 16:16:24 -0400 Received: from cavan.codon.org.uk ([10.3.113.16]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8FKGNhg015423 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Wed, 15 Sep 2010 16:16:24 -0400 Received: from nat-pool-rdu.redhat.com ([66.187.233.202] helo=localhost.localdomain) by cavan.codon.org.uk with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1OvyOs-0008KC-0O; Wed, 15 Sep 2010 21:16:14 +0100 From: Matthew Garrett To: linux-acpi@vger.kernel.org Cc: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, lenb@kernel.org, James.Bottomley@suse.de, jgarzik@pobox.com, Matthew Garrett Subject: [PATCHv2] acpi: Add support for linking docks to the objects they contain Date: Wed, 15 Sep 2010 16:16:21 -0400 Message-Id: <1284581781-3396-1-git-send-email-mjg@redhat.com> In-Reply-To: <20100915130504.099bbeb6.randy.dunlap@oracle.com> References: <20100915130504.099bbeb6.randy.dunlap@oracle.com> X-SA-Do-Not-Run: Yes X-SA-Exim-Connect-IP: 66.187.233.202 X-SA-Exim-Mail-From: mjg@redhat.com X-SA-Exim-Scanned: No (on cavan.codon.org.uk); SAEximRunCond expanded to false X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 15 Sep 2010 20:18:35 +0000 (UTC) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3fe29e9..6578015 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -276,6 +276,84 @@ int is_dock_device(acpi_handle handle) EXPORT_SYMBOL_GPL(is_dock_device); /** + * dock_link_device - link a device from the dock + * @handle: acpi handle of the potentially dependent device + */ +struct device **dock_link_device(acpi_handle handle) +{ + struct device *dev = acpi_get_physical_device(handle); + struct dock_station *dock_station; + int ret, dock = 0; + struct device **devices; + + devices = kmalloc(dock_station_count * sizeof(struct device *), + GFP_KERNEL); + + if (!dev) + return NULL; + + if (is_dock(handle)) { + put_device(dev); + return NULL; + } + + list_for_each_entry(dock_station, &dock_stations, sibling) { + if (find_dock_dependent_device(dock_station, handle)) { + ret = sysfs_create_link(&dock_station->dock_device->dev.kobj, + &dev->kobj, dev_name(dev)); + WARN_ON(ret); + devices[dock] = &dock_station->dock_device->dev; + dock++; + } + } + if (!dock) + put_device(dev); + + devices[dock] = NULL; + return devices; +} +EXPORT_SYMBOL_GPL(dock_link_device); + +/** + * dock_unlink_device - unlink a device from the dock + * @handle: acpi handle of the potentially dependent device + */ +struct device **dock_unlink_device(acpi_handle handle) +{ + struct device *dev = acpi_get_physical_device(handle); + struct dock_station *dock_station; + int dock = 0; + struct device **devices = + kmalloc(dock_station_count * sizeof(struct device *), + GFP_KERNEL); + + if (!dev) + return NULL; + + if (is_dock(handle)) { + put_device(dev); + return NULL; + } + + list_for_each_entry(dock_station, &dock_stations, sibling) { + if (find_dock_dependent_device(dock_station, handle)) { + sysfs_remove_link(&dock_station->dock_device->dev.kobj, + dev_name(dev)); + devices[dock] = &dock_station->dock_device->dev; + dock++; + } + } + /* An extra reference has been held while the link existed */ + if (dock) + put_device(dev); + + put_device(dev); + devices[dock] = NULL; + return devices; +} +EXPORT_SYMBOL_GPL(dock_unlink_device); + +/** * dock_present - see if the dock station is present. * @ds: the dock station * diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 23d78b4..59774b5 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -133,6 +133,8 @@ extern int register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, void *context); extern void unregister_hotplug_dock_device(acpi_handle handle); +extern struct device **dock_link_device(acpi_handle handle); +extern struct device **dock_unlink_device(acpi_handle handle); #else static inline int is_dock_device(acpi_handle handle) { @@ -154,6 +156,14 @@ static inline int register_hotplug_dock_device(acpi_handle handle, static inline void unregister_hotplug_dock_device(acpi_handle handle) { } +static inline struct device **dock_link_device(acpi_handle handle) +{ + return NULL; +} +static inline struct device **dock_unlink_device(acpi_handle handle) +{ + return NULL; +} #endif #endif /*__ACPI_DRIVERS_H__*/