From patchwork Thu Mar 26 19:13:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suravee Suthikulpanit X-Patchwork-Id: 455187 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id C38A6140079 for ; Fri, 27 Mar 2015 06:14:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752839AbbCZTO0 (ORCPT ); Thu, 26 Mar 2015 15:14:26 -0400 Received: from mail-bl2on0110.outbound.protection.outlook.com ([65.55.169.110]:3088 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752831AbbCZTNh (ORCPT ); Thu, 26 Mar 2015 15:13:37 -0400 X-Greylist: delayed 16512 seconds by postgrey-1.27 at vger.kernel.org; Thu, 26 Mar 2015 15:13:37 EDT Received: from BN1PR02CA0027.namprd02.prod.outlook.com (10.141.56.27) by BY1PR0201MB0888.namprd02.prod.outlook.com (25.160.193.142) with Microsoft SMTP Server (TLS) id 15.1.118.21; Thu, 26 Mar 2015 19:13:35 +0000 Received: from BL2FFO11FD026.protection.gbl (2a01:111:f400:7c09::137) by BN1PR02CA0027.outlook.office365.com (2a01:111:e400:2a::27) with Microsoft SMTP Server (TLS) id 15.1.125.19 via Frontend Transport; Thu, 26 Mar 2015 19:13:34 +0000 Received: from atltwp02.amd.com ([165.204.84.222]) by BL2FFO11FD026.mail.protection.outlook.com ([10.173.161.105]) with Microsoft SMTP Server id 15.1.130.10 via Frontend Transport; Thu, 26 Mar 2015 19:13:34 +0000 X-WSS-ID: 0NLU2QI-08-6HS-02 X-M-MSG: Received: from satlvexedge01.amd.com (satlvexedge01.amd.com [10.177.96.28]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by atltwp02.amd.com (Axway MailGate 5.3.1) with ESMTPS id 238AED16028; Thu, 26 Mar 2015 14:13:29 -0500 (CDT) Received: from SATLEXDAG03.amd.com (10.181.40.7) by satlvexedge01.amd.com (10.177.96.28) with Microsoft SMTP Server (TLS) id 14.3.195.1; Thu, 26 Mar 2015 14:13:42 -0500 Received: from ssuthiku-fedora-lt.amd.com (10.180.168.240) by satlexdag03.amd.com (10.181.40.7) with Microsoft SMTP Server id 14.3.195.1; Thu, 26 Mar 2015 15:13:30 -0400 From: Suravee Suthikulpanit To: , , , , CC: , , , , , , , , , , , , "Suravee Suthikulpanit" Subject: [V7 PATCH 2/3] ACPI / scan: Add support for ACPI _CLS device matching Date: Thu, 26 Mar 2015 14:13:14 -0500 Message-ID: <1427397195-15273-3-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1427397195-15273-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1427397195-15273-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is 165.204.84.222) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; intel.com; dkim=none (message not signed) header.d=none; X-Forefront-Antispam-Report: CIP:165.204.84.222; CTRY:US; IPV:NLI; EFV:NLI; BMV:1; SFV:NSPM; SFS:(10019020)(6009001)(428002)(189002)(199003)(2950100001)(19580395003)(48376002)(77096005)(101416001)(92566002)(36756003)(19580405001)(50466002)(87936001)(86362001)(575784001)(76176999)(50226001)(50986999)(53416004)(2201001)(47776003)(229853001)(77156002)(46102003)(105586002)(62966003); DIR:OUT; SFP:1102; SCL:1; SRVR:BY1PR0201MB0888; H:atltwp02.amd.com; FPR:; SPF:None; MLV:sfv; MX:1; A:1; LANG:en; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0201MB0888; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5002010)(5005006); SRVR:BY1PR0201MB0888; BCL:0; PCL:0; RULEID:; SRVR:BY1PR0201MB0888; X-Forefront-PRVS: 0527DFA348 X-OriginatorOrg: amd4.onmicrosoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Mar 2015 19:13:34.1038 (UTC) X-MS-Exchange-CrossTenant-Id: fde4dada-be84-483f-92cc-e026cbee8e96 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fde4dada-be84-483f-92cc-e026cbee8e96; Ip=[165.204.84.222]; Helo=[atltwp02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR0201MB0888 Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org Device drivers typically use ACPI _HIDs/_CIDs listed in struct device_driver acpi_match_table to match devices. However, for generic drivers, we do not want to list _HID for all supported devices. Also, certain classes of devices do not have _CID (e.g. SATA, USB). Instead, we can leverage ACPI _CLS, which specifies PCI-defined class code (i.e. base-class, subclass and programming interface). This patch adds support for matching ACPI devices using the _CLS method. To support loadable module, current design uses _HID or _CID to match device's modalias. With the new way of matching with _CLS this would requires modification to the current ACPI modalias key to include _CLS. This patch appends PCI-defined class-code to the existing ACPI modalias as following. acpi::::..::: E.g: # cat /sys/devices/platform/AMDI0600:00/modalias acpi:AMDI0600:010601: where bb is th base-class code, ss is te sub-class code, and pp is the programming interface code Since there would not be _HID/_CID in the ACPI matching table of the driver, this patch adds a field to acpi_device_id to specify the matching _CLS. static const struct acpi_device_id ahci_acpi_match[] = { { ACPI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff) }, {}, }; In this case, the corresponded entry in modules.alias file would be: alias acpi*:010601:* ahci_platform Acked-by: Mika Westerberg Reviewed-by: Hanjun Guo Signed-off-by: Suravee Suthikulpanit --- drivers/acpi/scan.c | 36 ++++++++++++++++++++++++++++++++---- include/acpi/acnames.h | 1 + include/acpi/actypes.h | 4 +++- include/linux/acpi.h | 13 +++++++++++++ include/linux/mod_devicetable.h | 2 ++ scripts/mod/devicetable-offsets.c | 2 ++ scripts/mod/file2alias.c | 32 ++++++++++++++++++++++++++++++-- 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 52a62aa..3320ee2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -895,6 +895,29 @@ static void acpi_device_remove_files(struct acpi_device *dev) ACPI Bus operations -------------------------------------------------------------------------- */ +static bool __acpi_match_device_cls(const struct acpi_device_id *id, + struct acpi_hardware_id *hwid) +{ + int i, msk, byte_shift; + char buf[3]; + + if (!id->cls) + return false; + + /* Apply class-code bitmask, before checking each class-code byte */ + for (i = 1; i <= 3; i++) { + byte_shift = 8 * (3 - i); + msk = (id->cls_msk >> byte_shift) & 0xFF; + if (!msk) + continue; + + sprintf(buf, "%02x", (id->cls >> byte_shift) & msk); + if (strncmp(buf, &hwid->id[(i - 1) * 2], 2)) + return false; + } + return true; +} + static const struct acpi_device_id *__acpi_match_device( struct acpi_device *device, const struct acpi_device_id *ids) { @@ -908,11 +931,14 @@ static const struct acpi_device_id *__acpi_match_device( if (!device->status.present) return NULL; - for (id = ids; id->id[0]; id++) - list_for_each_entry(hwid, &device->pnp.ids, list) - if (!strcmp((char *) id->id, hwid->id)) + for (id = ids; id->id[0] || id->cls; id++) { + list_for_each_entry(hwid, &device->pnp.ids, list) { + if (id->id[0] && !strcmp((char *) id->id, hwid->id)) return id; - + else if (__acpi_match_device_cls(id, hwid)) + return id; + } + } return NULL; } @@ -2005,6 +2031,8 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, if (info->valid & ACPI_VALID_UID) pnp->unique_id = kstrdup(info->unique_id.string, GFP_KERNEL); + if (info->valid & ACPI_VALID_CLS) + acpi_add_id(pnp, info->cls.string); kfree(info); diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 273de70..b52c0dc 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -51,6 +51,7 @@ #define METHOD_NAME__BBN "_BBN" #define METHOD_NAME__CBA "_CBA" #define METHOD_NAME__CID "_CID" +#define METHOD_NAME__CLS "_CLS" #define METHOD_NAME__CRS "_CRS" #define METHOD_NAME__DDN "_DDN" #define METHOD_NAME__HID "_HID" diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index b034f10..ab3dac8 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1148,7 +1148,7 @@ struct acpi_device_info { u32 name; /* ACPI object Name */ acpi_object_type type; /* ACPI object Type */ u8 param_count; /* If a method, required parameter count */ - u8 valid; /* Indicates which optional fields are valid */ + u16 valid; /* Indicates which optional fields are valid */ u8 flags; /* Miscellaneous info */ u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ @@ -1157,6 +1157,7 @@ struct acpi_device_info { struct acpi_pnp_device_id hardware_id; /* _HID value */ struct acpi_pnp_device_id unique_id; /* _UID value */ struct acpi_pnp_device_id subsystem_id; /* _SUB value */ + struct acpi_pnp_device_id cls; /* _CLS value */ struct acpi_pnp_device_id_list compatible_id_list; /* _CID list */ }; @@ -1174,6 +1175,7 @@ struct acpi_device_info { #define ACPI_VALID_CID 0x20 #define ACPI_VALID_SXDS 0x40 #define ACPI_VALID_SXWS 0x80 +#define ACPI_VALID_CLS 0x100 /* Flags for _STA return value (current_status above) */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index de4e86f..e4fdce5 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -57,6 +57,19 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) #define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) +/** + * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with + * the PCI-defined class-code information + * + * @_cls : the class, subclass, prog-if triple for this device + * @_msk : the class mask for this device + * + * This macro is used to create a struct acpi_device_id that matches a + * specific PCI class. The .id and .driver_data fields will be left + * initialized with the default value. + */ +#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk), + static inline void acpi_preset_companion(struct device *dev, struct acpi_device *parent, u64 addr) { diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index e530533..2ed31b8 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -189,6 +189,8 @@ struct css_device_id { struct acpi_device_id { __u8 id[ACPI_ID_LEN]; kernel_ulong_t driver_data; + __u32 cls; + __u32 cls_msk; }; #define PNP_ID_LEN 8 diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index f282516..8987160 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -63,6 +63,8 @@ int main(void) DEVID(acpi_device_id); DEVID_FIELD(acpi_device_id, id); + DEVID_FIELD(acpi_device_id, cls); + DEVID_FIELD(acpi_device_id, cls_msk); DEVID(pnp_device_id); DEVID_FIELD(pnp_device_id, id); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index e614ef6..704d597 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -511,12 +511,40 @@ static int do_serio_entry(const char *filename, } ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry); -/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ +/* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or + * "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if) + * + * NOTE: Each driver should use one of the following : _HID, _CIDs + * or _CLS. Also, bb, ss, and pp can be substituted with ?? + * as don't care byte. + */ static int do_acpi_entry(const char *filename, void *symval, char *alias) { DEF_FIELD_ADDR(symval, acpi_device_id, id); - sprintf(alias, "acpi*:%s:*", *id); + DEF_FIELD_ADDR(symval, acpi_device_id, cls); + DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk); + + if (id && strlen((const char *)*id)) + sprintf(alias, "acpi*:%s:*", *id); + else if (cls) { + int i, byte_shift, cnt = 0; + unsigned int msk; + + sprintf(&alias[cnt], "acpi*:"); + cnt = 6; + for (i = 1; i <= 3; i++) { + byte_shift = 8 * (3-i); + msk = (*cls_msk >> byte_shift) & 0xFF; + if (msk) + sprintf(&alias[cnt], "%02x", + (*cls >> byte_shift) & 0xFF); + else + sprintf(&alias[cnt], "??"); + cnt += 2; + } + sprintf(&alias[cnt], ":*"); + } return 1; } ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);