From nobody Fri Dec 19 17:16:20 2025 Received: from mail-vk1-f177.google.com (mail-vk1-f177.google.com [209.85.221.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05BD11DF25D; Sat, 17 May 2025 08:52:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471931; cv=none; b=pL+000tLwjbruSK457zQo8e5dTBBcLZ4kxqx/+E2GXFuSjQS1cybIhMelRHVgKu4Ob/1wNF2wILb+gpSAPx+zrUdyVsonycKL3lBiUVgnFbMf6Z5yWKXhTos2+808n9JXN0YOmsnOm+l15CilxNBQqpqeGgNZ1p3l/IOcFN/ajw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471931; c=relaxed/simple; bh=75ZDl0sGCv0SWzsXoZgaGiv9+9aMgRhElnW5gGizokY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=F7lmk9gXnjx4batPZhwK26iwccB8veYeKLdFvuPriT798QDpinVcJk6vMHGlzAbDdsrzuzpcXeQ4IdG0/Dut8F9ZXnkm1teScy91/b4uFp5pITjEfeB1AuR0QolriEVeCiJl+cMBXA8dVQ8ajUgrtf5plTE0zQCICnFb3R1E2oM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BB2WTmiY; arc=none smtp.client-ip=209.85.221.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BB2WTmiY" Received: by mail-vk1-f177.google.com with SMTP id 71dfb90a1353d-5240a432462so1821800e0c.1; Sat, 17 May 2025 01:52:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747471929; x=1748076729; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=cUrdN074hiEwflDk+I/k00uBo8y8f88hJd62syL580w=; b=BB2WTmiYEl3ufU3tHkf2LjBzWoQUBP0HjiqU5erkXqGXghp3mjcIA8j3m4uwxCOE/j A0+GZRBUAOYhX41NqwM6zWWS2ZeQkGfV53fCgdkuWfJg19SOGXe7fJeWxo6OxZLIrrDz UQZhA/OJPEEACKA9ekcF3OCO9E3WXIKzrJ7W/mTG9kYZ3xhYw//xSkFRtyMOBebzB0hx MyZpruMs7eh4pwteOe067GztBQ7/ihPUTyO3ravlTi/dXIxzR3tlxmh3uiKeDA/UybJA ETZHEgJIbJ+nWaTutGz6ZccO/epOkEVCC+bCc2mF0RKQdrmGi9qDLKQWpQegkt76XK3M NnvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747471929; x=1748076729; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cUrdN074hiEwflDk+I/k00uBo8y8f88hJd62syL580w=; b=Wdr83UM4Y0OkbMdF+nuPd/4E5XAyM5a+A7+aH+b74hDiCTR4daavO3J/aI0gHWZre/ /J9VfwmZcNahdv6VDPSiHI7jxW4hbT5TZmsI8aEQ17mLhLjy1Q9D77k14zZgka5+LJRt woTecsqrcMmpJ+d0C2MNm2sBbuDzagG9sXd19fH3yd7pUB3CtHefxSG9xZzpWrKxrg36 KI08zKEr2efmHbFtnAU+Ejflb3EHRpngEBGcF9+tBPG1/ZHTTGkptgfrOhS7N27pxEaE aTWd5hv2ZCOJcCvC9J1THiTWkuE6x/eVwsiQ8bSOBVzPBR/tFFqth1heBXQ3lc1rqIPP pA7Q== X-Forwarded-Encrypted: i=1; AJvYcCVyt7sOX+MFELdi3TGIEljrTlEvjhR9Q6olRoFsABtGyiP+OKeee0dUoW9jTZSmab9ssZuqvkU8WESYeqPHdOIl5K5flQ==@vger.kernel.org, AJvYcCWV474Bl0JLUqr/f5WR4v55hUSD/hJEDX5xztULv0oh9nJwnODkagklTXQsZ816w/cB1XkF6dnMdOC+yUM=@vger.kernel.org X-Gm-Message-State: AOJu0YwpXI6h5Fk0G5kyJoh7qnRZOSwSwes9oRVQyl2px7ARHuPGbDBt CiNLfUKNaJfyYkqIbggcJNhjR3oGAxoaBLJ5A1v5SF85FL97L4LkEXQu X-Gm-Gg: ASbGnctncInS4XdUciVTWBw9oOVYU4+OX8hgvu2XMrbwHCYj+aFXeuBK18nG2OsW9mq 0aaCtOt5qCndWdOnzI9fI8l59QkxvlCDBbVtgVjROnkf1/MSK4CEnpVDjJ8l6cnZaWkeA4mRx2h iwO+LlaYY2wXCt4KnkZDagRUeJTjhszUrh+MRml7qDpE81xRYJKpPBdHZtflcBSrQliwuegHA6t 2wvbhryBsiLWfOrIBRkh6b9no5Gq6QMYhOckY2uli+FrSpd+/9rvkYCP3aKLvOV4UYT6KE9lwZo oej9R7KAzwOvCZyrNSr/4IQ/F+7H4tF5z0syeCIVmHeToVchOA== X-Google-Smtp-Source: AGHT+IGekttsnjR4yfZC6e53wSmQkWD8O76qt/LKyjUcjuwTzYobLODD+5oaXhqxFQVqMxFWF3O6HA== X-Received: by 2002:a05:6122:2104:b0:527:67d9:100d with SMTP id 71dfb90a1353d-52dbb5b963cmr5214659e0c.4.1747471928671; Sat, 17 May 2025 01:52:08 -0700 (PDT) Received: from [192.168.1.26] ([181.85.227.70]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-52dba9405adsm3455812e0c.11.2025.05.17.01.52.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 May 2025 01:52:08 -0700 (PDT) From: Kurt Borja Date: Sat, 17 May 2025 05:51:36 -0300 Subject: [PATCH v2 1/5] platform/x86: firmware_attributes_class: Add device initialization methods Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250517-fw-attrs-api-v2-1-fa1ab045a01c@gmail.com> References: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> In-Reply-To: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> To: Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Joshua Grisham , Mark Pearson , Armin Wolf , Mario Limonciello Cc: Antheas Kapenekakis , "Derek J. Clark" , Prasanth Ksr , Jorge Lopez , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Dell.Client.Kernel@dell.com, Kurt Borja X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8315; i=kuurtb@gmail.com; h=from:subject:message-id; bh=yRUATjMViscKiiFkHj3mgMrluIU4SerksyxB4/Vxmus=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBkafnr76s0MV1Zeju687fri/9fkxmTprZ1q+3SnBseaf muvrPjaUcrCIMbFICumyNKesOjbo6i8t34HQu/DzGFlAhnCwMUpABOZuYDhv/8W3eirGd/zIs1P Fe0NOfDiJMPW7FmrjFX2X+9TmvNvpScjQ4uc17UjB/6+eFaV++muWxKbBNPVC7elrOvVXSQMQqv 9GAE= X-Developer-Key: i=kuurtb@gmail.com; a=openpgp; fpr=54D3BE170AEF777983C3C63B57E3B6585920A69A From: Thomas Wei=C3=9Fschuh Currently each user of firmware_attributes_class has to manually set up kobjects, devices, etc. Provide this infrastructure out-of-the-box through the newly introduced fwat_device_register(). Reviewed-by: Mario Limonciello Signed-off-by: Thomas Wei=C3=9Fschuh Co-developed-by: Kurt Borja Signed-off-by: Kurt Borja --- drivers/platform/x86/firmware_attributes_class.c | 166 +++++++++++++++++++= ++++ drivers/platform/x86/firmware_attributes_class.h | 44 ++++++ 2 files changed, 210 insertions(+) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/pla= tform/x86/firmware_attributes_class.c index 736e96c186d9dc6d945517f090e9af903e93bbf4..e2dcf2781513b5b033b019780d3= e28115e83a1a5 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -2,7 +2,13 @@ =20 /* Firmware attributes class helper module */ =20 +#include +#include +#include +#include #include +#include +#include #include "firmware_attributes_class.h" =20 const struct class firmware_attributes_class =3D { @@ -10,6 +16,164 @@ const struct class firmware_attributes_class =3D { }; EXPORT_SYMBOL_GPL(firmware_attributes_class); =20 +static ssize_t fwat_attrs_kobj_show(struct kobject *kobj, struct attribute= *attr, + char *buf) +{ + const struct fwat_attribute *fattr =3D to_fwat_attribute(attr); + struct fwat_device *fadev =3D to_fwat_device(kobj); + + if (!fattr->show) + return -ENOENT; + + return fattr->show(fadev->dev, fattr, buf); +} + +static ssize_t fwat_attrs_kobj_store(struct kobject *kobj, struct attribut= e *attr, + const char *buf, size_t count) +{ + const struct fwat_attribute *fattr =3D to_fwat_attribute(attr); + struct fwat_device *fadev =3D to_fwat_device(kobj); + + if (!fattr->store) + return -ENOENT; + + return fattr->store(fadev->dev, fattr, buf, count); +} + +static const struct sysfs_ops fwat_attrs_kobj_ops =3D { + .show =3D fwat_attrs_kobj_show, + .store =3D fwat_attrs_kobj_store, +}; + +static void fwat_attrs_kobj_release(struct kobject *kobj) +{ + struct fwat_device *fadev =3D to_fwat_device(kobj); + + kfree(fadev); +} + +static const struct kobj_type fwat_attrs_ktype =3D { + .sysfs_ops =3D &fwat_attrs_kobj_ops, + .release =3D fwat_attrs_kobj_release, +}; + +/** + * fwat_device_register - Create and register a firmware-attributes class + * device + * @parent: Parent device + * @name: Name of the class device + * @data: Drvdata of the class device + * @groups: Sysfs groups for the custom `fwat_attrs_ktype` kobj_type + * + * NOTE: @groups are attached to the .attrs_kobj of the new fwat_device wh= ich + * has a custom ktype, which makes use of `struct fwat_attribute` to embed + * attributes. + * + * Return: pointer to the new fwat_device on success, ERR_PTR on failure + */ +struct fwat_device * +fwat_device_register(struct device *parent, const char *name, void *data, + const struct attribute_group **groups) +{ + struct fwat_device *fadev; + struct device *dev; + int ret; + + if (!parent || !name) + return ERR_PTR(-EINVAL); + + fadev =3D kzalloc(sizeof(*fadev), GFP_KERNEL); + if (!fadev) + return ERR_PTR(-ENOMEM); + + dev =3D device_create(&firmware_attributes_class, parent, MKDEV(0, 0), + data, "%s", name); + if (IS_ERR(dev)) { + kfree(fadev); + return ERR_CAST(dev); + } + + ret =3D kobject_init_and_add(&fadev->attrs_kobj, &fwat_attrs_ktype, &dev-= >kobj, + "attributes"); + if (ret) + goto out_kobj_put; + + if (groups) { + ret =3D sysfs_create_groups(&fadev->attrs_kobj, groups); + if (ret) + goto out_kobj_unregister; + } + + fadev->dev =3D dev; + fadev->groups =3D groups; + + kobject_uevent(&fadev->attrs_kobj, KOBJ_ADD); + + return fadev; + +out_kobj_unregister: + kobject_del(&fadev->attrs_kobj); + +out_kobj_put: + kobject_put(&fadev->attrs_kobj); + device_unregister(dev); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(fwat_device_register); + +void fwat_device_unregister(struct fwat_device *fwadev) +{ + if (fwadev->groups) + sysfs_remove_groups(&fwadev->attrs_kobj, fwadev->groups); + kobject_del(&fwadev->attrs_kobj); + kobject_put(&fwadev->attrs_kobj); + device_unregister(fwadev->dev); +} +EXPORT_SYMBOL_GPL(fwat_device_unregister); + +static void devm_fwat_device_release(void *data) +{ + struct fwat_device *fadev =3D data; + + fwat_device_unregister(fadev); +} + +/** + * devm_fwat_device_register - Create and register a firmware-attributes c= lass + * device + * @parent: Parent device + * @name: Name of the class device + * @data: Drvdata of the class device + * @groups: Sysfs groups for the custom `fwat_attrs_ktype` kobj_type + * + * Device managed version of fwat_device_register(). + * + * NOTE: @groups are attached to the .attrs_kobj of the new fwat_device wh= ich + * has a custom ktype, which makes use of `struct fwat_attribute` to embed + * attributes. + * + * Return: pointer to the new fwat_device on success, ERR_PTR on failure + */ +struct fwat_device * +devm_fwat_device_register(struct device *parent, const char *name, void *d= ata, + const struct attribute_group **groups) +{ + struct fwat_device *fadev; + int ret; + + fadev =3D fwat_device_register(parent, name, data, groups); + if (IS_ERR(fadev)) + return fadev; + + ret =3D devm_add_action_or_reset(parent, devm_fwat_device_release, fadev); + if (ret) + return ERR_PTR(ret); + + return fadev; +} +EXPORT_SYMBOL_GPL(devm_fwat_device_register); + static __init int fw_attributes_class_init(void) { return class_register(&firmware_attributes_class); @@ -23,5 +187,7 @@ static __exit void fw_attributes_class_exit(void) module_exit(fw_attributes_class_exit); =20 MODULE_AUTHOR("Mark Pearson "); +MODULE_AUTHOR("Thomas Wei=C3=9Fschuh "); +MODULE_AUTHOR("Kurt Borja "); MODULE_DESCRIPTION("Firmware attributes class helper module"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/pla= tform/x86/firmware_attributes_class.h index d27abe54fcf9812a2f0868eec5426bbc8e7eb21c..ad94bf91e5af30a2b8feb9abf22= 4ee6f0d17600a 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -5,8 +5,52 @@ #ifndef FW_ATTR_CLASS_H #define FW_ATTR_CLASS_H =20 +#include +#include #include +#include +#include =20 extern const struct class firmware_attributes_class; =20 +/** + * struct fwat_device - The firmware-attributes device + * @dev: The class device. + * @attrs_kobj: The "attributes" root kobject. + * @groups: Sysfs groups attached to the @attrs_kobj. + */ +struct fwat_device { + struct device *dev; + struct kobject attrs_kobj; + const struct attribute_group **groups; +}; + +#define to_fwat_device(_k) container_of_const(_k, struct fwat_device, attr= s_kobj) + +/** + * struct fwat_attribute - The firmware-attributes's custom attribute + * @attr: Embedded struct attribute. + * @show: Show method called by the "attributes" kobject's ktype. + * @store: Store method called by the "attributes" kobject's ktype. + */ +struct fwat_attribute { + struct attribute attr; + ssize_t (*show)(struct device *dev, const struct fwat_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, const struct fwat_attribute *attr, + const char *buf, size_t count); +}; + +#define to_fwat_attribute(_a) container_of_const(_a, struct fwat_attribute= , attr) + +struct fwat_device * __must_check +fwat_device_register(struct device *parent, const char *name, void *data, + const struct attribute_group **groups); + +void fwat_device_unregister(struct fwat_device *fwadev); + +struct fwat_device * __must_check +devm_fwat_device_register(struct device *parent, const char *name, void *d= ata, + const struct attribute_group **groups); + #endif /* FW_ATTR_CLASS_H */ --=20 2.49.0 From nobody Fri Dec 19 17:16:20 2025 Received: from mail-vk1-f180.google.com (mail-vk1-f180.google.com [209.85.221.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0BBB1DF749; Sat, 17 May 2025 08:52:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471937; cv=none; b=lRkYCOsrpb/vjpjGVI7LTfL+2WlmNcGvGhQ3MB1ugg3V2XtDE001uaXu4DhQooogTO2HvMgXXKC/MQBmtItJyvIdZOlSM2H0YnA4941KRGtC3OGkh+qznXby0xh9cqi8YfQyeQSCIl4+a9nQzBwntvx8xgcXLHlrgicbFKhTYxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471937; c=relaxed/simple; bh=v10ccQwiKauEsWWKcKaDIKd+NhV01PoUJeGo+T42gvE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=awudvg+wraEj4bOw3pBbpxEUlmiOyzdQSdbrSioOIQ2sEJt3YHgt88aX8WIo9FvJh2GGYkyUSqkhbbh1hbZxXqOWV+33EiID+KYXVlmJDQZkdO52Ra0naLb2CjF8H2n6cuviRRN4zxwkempyNLdSSMD+GmgmdVuEx3Qtb+bMRTg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Q/i1kbRo; arc=none smtp.client-ip=209.85.221.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Q/i1kbRo" Received: by mail-vk1-f180.google.com with SMTP id 71dfb90a1353d-52403e39a23so1636027e0c.2; Sat, 17 May 2025 01:52:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747471933; x=1748076733; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=0ArP9b/wyiV+t5knMSQpx52Kzo2+Ytjhthg01f0Li34=; b=Q/i1kbRoOnPCuxuWokvQuI1zMhdQEjByMdwx3Z7WzAAIoXzRIosw06nF9mdiglvnc1 jGs6gU5B/go+7KfrbVCZeO6rwiy1MY24zC1fTvVb6U9iv6KwPuUzpnRn4s/WecWFu5Jd eJyTs5hMHa1O2r/7G14jRDo8c+/L/0cCIDpucOya5aKRPF7BLv0zCppcky7wohZ+S+tO bfPSgKQ3mlkBDRgZjPTDMswY2vEn2PmmUGc69xw8uTLcp58aY12sH8RX/KXRlDAQjZVy /RtsGL0NYs4Y1AjX+F2dcv1dELdFYq8CZPLNqzcPziqxxz5kjQHHHkuhKgQ/OmSyjiVU oMNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747471933; x=1748076733; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0ArP9b/wyiV+t5knMSQpx52Kzo2+Ytjhthg01f0Li34=; b=dAtBYN8rNjS7eK02EvlmGB+BcgCczTf5orSYuGu536bf6weE6JzRsLl3wsIJC0OBF1 qYVivFKqqxK9DXqGSJ5eFMvhbtTylx4ddnqmxHIshVbCWiGRuDqfhzGvoksCNm5XISxR SPiNbPg5ubVPQbFRoFAnul67a5usb5DZxfX6u+8922hngFt+PGVs3jv5QSF9d0blCCqH XCW7O1nar1W7OdfKzW+3Kcxb9FYvcSqlRU3dBzrtW3bDI1ORD2WK+hscu0UWDqL5a518 DeTeCOLoq1UdrOfMuz+x0INFGGmUrqrIFFePT+gbZwM7hlZhYw+G30CRRbCu/k5K1ZOf jAgw== X-Forwarded-Encrypted: i=1; AJvYcCU6BBOkRDzeHXQmdRp8hH3YRtVAbyWA7Blk3K1ukKAOwI1FwnlJK/wikiK6ixIzHUc3KgEkyx8ggNVYJoy87XCTdSz0zQ==@vger.kernel.org, AJvYcCU9MMA1QAgNprdSlhdSuP8Qtu95aAYewT+CJqN+7NtOYmuUeDDDja+1bsQuC7q61GMeb53H2ONB2sEexFA=@vger.kernel.org X-Gm-Message-State: AOJu0YzfP3xHyMM4TEVTTjyVRBxgpF5EyaM8OO8faX6BIWaH5fQzaeFl b977C74gq6wie9zrgx8MvWj38sFyHdLVcOk/18SkC6c5pEuu04MqnrmD X-Gm-Gg: ASbGncv/3T+V92hJdX23RW7eKoZRLCH9XbWSPLkcZsqnNyIb2eCFEVdhu7GKJ1ErE5d wDrewmLkPGTfMljwpEp9inXrphFVtgKFIw7GpIrjsneTafLxqAd7syM5Lvg430oCAA81WUr+B2/ uQMqGdT+Lrd0s7ppBR2OoWa4+C0My7OGmE6bV58oujFFKj1mr7aAoM5bntgYopVTq4rkiRPSRiY trUBc/MjAiPm47/HeH0zy7TVS4NDXQdkhT8nV9tyDcDc4CJJsse1kqj8IrZE4vl+FOY4+W552a2 7jWcoPdUtD2uVZPtBtJ5MGpL+pnHqf+OX59aqS2ecVp582yX2g== X-Google-Smtp-Source: AGHT+IFrqn7Sfxbw5x2+Uoh0tCSUzZuNY5btBPRdSu2uQFo+Rp3RlYC9mfrg8R93MhJyLSclJZRSQg== X-Received: by 2002:a05:6122:1d48:b0:526:2210:5b68 with SMTP id 71dfb90a1353d-52dba80aa18mr7609873e0c.4.1747471933256; Sat, 17 May 2025 01:52:13 -0700 (PDT) Received: from [192.168.1.26] ([181.85.227.70]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-52dba9405adsm3455812e0c.11.2025.05.17.01.52.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 May 2025 01:52:12 -0700 (PDT) From: Kurt Borja Date: Sat, 17 May 2025 05:51:37 -0300 Subject: [PATCH v2 2/5] platform/x86: firmware_attributes_class: Add a high level API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250517-fw-attrs-api-v2-2-fa1ab045a01c@gmail.com> References: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> In-Reply-To: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> To: Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Joshua Grisham , Mark Pearson , Armin Wolf , Mario Limonciello Cc: Antheas Kapenekakis , "Derek J. Clark" , Prasanth Ksr , Jorge Lopez , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Dell.Client.Kernel@dell.com, Kurt Borja X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=19584; i=kuurtb@gmail.com; h=from:subject:message-id; bh=v10ccQwiKauEsWWKcKaDIKd+NhV01PoUJeGo+T42gvE=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBkafvqWgpWKVz4lTS/ffaPmh072tGlhH9nNW9/F8x7M3 M+scCW3o5SFQYyLQVZMkaU9YdG3R1F5b/0OhN6HmcPKBDKEgYtTACaSkcLwTzkx65bxZtYlzLfT TC8djLt1JK1NZcPqq3GrK66El3zhCmNkmBgl4mryKa/n77PF+rr/e78KBL/xDWj100h67GOqrXq AAwA= X-Developer-Key: i=kuurtb@gmail.com; a=openpgp; fpr=54D3BE170AEF777983C3C63B57E3B6585920A69A Add an attribute configuration mechanism through the newly introduced `struct fwat_dev_config`, which makes use of other documented structs and callbacks. This API aims to be simple, yet flexible. In order to accomplish this, the following features were taken into account: * Ability to statically define attributes * Custom read/write callbacks for each attribute type * Ability to map attributes to numbers in order to differentiate them in callbacks (`aux` number) * Ability to reuse read/write callbacks in different attributes * Ability to reuse property selection in different attributes * Optional visibility callback for dynamic attribute visibility Signed-off-by: Kurt Borja --- drivers/platform/x86/firmware_attributes_class.c | 275 +++++++++++++++++++= +++- drivers/platform/x86/firmware_attributes_class.h | 224 ++++++++++++++++++ 2 files changed, 496 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/pla= tform/x86/firmware_attributes_class.c index e2dcf2781513b5b033b019780d3e28115e83a1a5..29401b81b25b9bb1332dbe56ead= f96ff81e91c2f 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -8,14 +8,259 @@ #include #include #include +#include #include #include "firmware_attributes_class.h" =20 +#define to_fwat_attribute_ext(_a) container_of_const(_a, struct fwat_attri= bute_ext, attr) + +struct fwat_attribute_ext { + struct fwat_attribute attr; + enum fwat_property prop; + const struct fwat_attr_config *config; +}; + const struct class firmware_attributes_class =3D { .name =3D "firmware-attributes", }; EXPORT_SYMBOL_GPL(firmware_attributes_class); =20 +static const char * const fwat_type_labels[] =3D { + [fwat_type_integer] =3D "integer", + [fwat_type_string] =3D "string", + [fwat_type_enumeration] =3D "enumeration", +}; + +static const char * const fwat_prop_labels[] =3D { + [FWAT_PROP_DISPLAY_NAME] =3D "display_name", + [FWAT_PROP_LANGUAGE_CODE] =3D "display_name_language_code", + [FWAT_PROP_DEFAULT] =3D "default", + + [FWAT_INT_PROP_MIN] =3D "min_value", + [FWAT_INT_PROP_MAX] =3D "max_value", + [FWAT_INT_PROP_INCREMENT] =3D "scalar_increment", + + [FWAT_STR_PROP_MIN] =3D "min_length", + [FWAT_STR_PROP_MAX] =3D "max_length", + + [FWAT_ENUM_PROP_POSSIBLE_VALUES] =3D "possible_values", +}; + +static ssize_t +fwat_type_show(struct device *dev, const struct fwat_attribute *attr, char= *buf) +{ + const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); + const struct fwat_attr_config *config =3D ext->config; + + return sysfs_emit(buf, "%s\n", fwat_type_labels[config->ops->type]); +} + +static ssize_t +fwat_property_show(struct device *dev, const struct fwat_attribute *attr, = char *buf) +{ + const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); + const struct fwat_attr_config *config =3D ext->config; + + if (!config->ops->prop_read) + return -EOPNOTSUPP; + + return config->ops->prop_read(dev, config->aux, ext->prop, buf); +} + +static ssize_t +fwat_current_value_show(struct device *dev, const struct fwat_attribute *a= ttr, char *buf) +{ + const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); + const struct fwat_attr_config *config =3D ext->config; + const struct fwat_attr_ops *ops =3D config->ops; + const char *str; + long int_val; + int ret; + + switch (ops->type) { + case fwat_type_integer: + if (!ops->integer.read) + return -EOPNOTSUPP; + + ret =3D ops->integer.read(dev, config->aux, &int_val); + if (ret) + return ret; + + return sysfs_emit(buf, "%ld\n", int_val); + case fwat_type_string: + if (!ops->string.read) + return -EOPNOTSUPP; + + ret =3D ops->string.read(dev, config->aux, &str); + if (ret) + return ret; + + return sysfs_emit(buf, "%s\n", str); + case fwat_type_enumeration: + if (!ops->enumeration.read) + return -EOPNOTSUPP; + + ret =3D ops->enumeration.read(dev, config->aux, &str); + if (ret) + return ret; + + return sysfs_emit(buf, "%s\n", str); + default: + return -EOPNOTSUPP; + } +} + +static ssize_t +fwat_current_value_store(struct device *dev, const struct fwat_attribute *= attr, + const char *buf, size_t count) +{ + const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); + const struct fwat_attr_config *config =3D ext->config; + const struct fwat_attr_ops *ops =3D config->ops; + long int_val; + int ret; + + switch (ops->type) { + case fwat_type_integer: + if (!ops->integer.write) + return -EOPNOTSUPP; + + ret =3D kstrtol(buf, 0, &int_val); + if (ret) + return ret; + + ret =3D ops->integer.write(dev, config->aux, int_val); + break; + case fwat_type_string: + if (!ops->string.write) + return -EOPNOTSUPP; + + ret =3D ops->string.write(dev, config->aux, buf, count); + break; + case fwat_type_enumeration: + if (!ops->enumeration.write) + return -EOPNOTSUPP; + + ret =3D ops->enumeration.write(dev, config->aux, buf, count); + break; + default: + return -EOPNOTSUPP; + } + + return ret ? ret : count; +} + +static struct attribute * +fwat_alloc_attr(struct device *dev, const struct fwat_attr_config *config, + const char *attr_name, umode_t mode, enum fwat_property prop, + ssize_t (*show)(struct device *dev, const struct fwat_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, const struct fwat_attribute *attr, + const char *buf, size_t count)) +{ + struct fwat_attribute_ext *fattr; + + fattr =3D devm_kzalloc(dev, sizeof(*fattr), GFP_KERNEL); + if (!fattr) + return NULL; + + fattr->attr.attr.name =3D attr_name; + fattr->attr.attr.mode =3D mode; + fattr->attr.show =3D show; + fattr->attr.store =3D store; + fattr->prop =3D prop; + fattr->config =3D config; + sysfs_attr_init(&fattr->attr.attr); + + return &fattr->attr.attr; +} + +static struct attribute ** +fwat_create_attrs(struct device *dev, const struct fwat_attr_config *confi= g) +{ + struct attribute **attrs; + enum fwat_property prop; + struct attribute *attr; + unsigned int index =3D 0; + + attrs =3D devm_kcalloc(dev, config->num_props + 3, sizeof(*attrs), GFP_KE= RNEL); + if (!attrs) + return NULL; + + /* Optional attributes */ + for (; index < config->num_props; index++) { + prop =3D config->props[index]; + attr =3D fwat_alloc_attr(dev, config, fwat_prop_labels[prop], + 0444, prop, fwat_property_show, NULL); + if (!attr) + return NULL; + attrs[index] =3D attr; + } + + /* Mandatory attributes */ + attr =3D fwat_alloc_attr(dev, config, "type", 0444, 0, fwat_type_show, NU= LL); + if (!attr) + return NULL; + attrs[index++] =3D attr; + attr =3D fwat_alloc_attr(dev, config, "current_value", config->mode, 0, + fwat_current_value_show, fwat_current_value_store); + if (!attr) + return NULL; + attrs[index++] =3D attr; + + return attrs; +} + +static const struct attribute_group * +fwat_create_group(struct device *dev, const struct fwat_attr_config *confi= g) +{ + struct attribute_group *group; + struct attribute **attrs; + + group =3D devm_kzalloc(dev, sizeof(*group), GFP_KERNEL); + if (!group) + return NULL; + + attrs =3D fwat_create_attrs(dev, config); + if (!attrs) + return NULL; + + group->name =3D config->name; + group->attrs =3D attrs; + + return group; +} + +static const struct attribute_group ** +fwat_create_auto_groups(struct device *dev, const struct fwat_dev_config *= config) +{ + const struct attribute_group **groups; + const struct attribute_group *grp; + unsigned int index =3D 0; + size_t ngroups =3D 0; + + while (config->attrs_config[ngroups]) + ngroups++; + + groups =3D devm_kcalloc(dev, ngroups + 1, sizeof(*groups), GFP_KERNEL); + if (!groups) + return NULL; + + for (unsigned int i =3D 0; i < ngroups; i++) { + if (config->is_visible && + !config->is_visible(dev, config->attrs_config[i])) + continue; + + grp =3D fwat_create_group(dev, config->attrs_config[i]); + if (!grp) + return NULL; + + groups[index++] =3D grp; + } + + return groups; +} + static ssize_t fwat_attrs_kobj_show(struct kobject *kobj, struct attribute= *attr, char *buf) { @@ -62,6 +307,7 @@ static const struct kobj_type fwat_attrs_ktype =3D { * device * @parent: Parent device * @name: Name of the class device + * @config: Device configuration * @data: Drvdata of the class device * @groups: Sysfs groups for the custom `fwat_attrs_ktype` kobj_type * @@ -73,8 +319,10 @@ static const struct kobj_type fwat_attrs_ktype =3D { */ struct fwat_device * fwat_device_register(struct device *parent, const char *name, void *data, + const struct fwat_dev_config *config, const struct attribute_group **groups) { + const struct attribute_group **auto_groups; struct fwat_device *fadev; struct device *dev; int ret; @@ -98,19 +346,36 @@ fwat_device_register(struct device *parent, const char= *name, void *data, if (ret) goto out_kobj_put; =20 - if (groups) { - ret =3D sysfs_create_groups(&fadev->attrs_kobj, groups); + if (config) { + auto_groups =3D fwat_create_auto_groups(dev, config); + if (!auto_groups) { + ret =3D -ENOMEM; + goto out_kobj_unregister; + } + + ret =3D sysfs_create_groups(&fadev->attrs_kobj, auto_groups); if (ret) goto out_kobj_unregister; } =20 + if (groups) { + ret =3D sysfs_create_groups(&fadev->attrs_kobj, groups); + if (ret) + goto out_remove_auto_groups; + } + fadev->dev =3D dev; fadev->groups =3D groups; + fadev->auto_groups =3D groups; =20 kobject_uevent(&fadev->attrs_kobj, KOBJ_ADD); =20 return fadev; =20 +out_remove_auto_groups: + if (config) + sysfs_remove_groups(&fadev->attrs_kobj, auto_groups); + out_kobj_unregister: kobject_del(&fadev->attrs_kobj); =20 @@ -126,6 +391,8 @@ void fwat_device_unregister(struct fwat_device *fwadev) { if (fwadev->groups) sysfs_remove_groups(&fwadev->attrs_kobj, fwadev->groups); + if (fwadev->auto_groups) + sysfs_remove_groups(&fwadev->attrs_kobj, fwadev->auto_groups); kobject_del(&fwadev->attrs_kobj); kobject_put(&fwadev->attrs_kobj); device_unregister(fwadev->dev); @@ -144,6 +411,7 @@ static void devm_fwat_device_release(void *data) * device * @parent: Parent device * @name: Name of the class device + * @config: Device configuration * @data: Drvdata of the class device * @groups: Sysfs groups for the custom `fwat_attrs_ktype` kobj_type * @@ -157,12 +425,13 @@ static void devm_fwat_device_release(void *data) */ struct fwat_device * devm_fwat_device_register(struct device *parent, const char *name, void *d= ata, + const struct fwat_dev_config *config, const struct attribute_group **groups) { struct fwat_device *fadev; int ret; =20 - fadev =3D fwat_device_register(parent, name, data, groups); + fadev =3D fwat_device_register(parent, name, data, config, groups); if (IS_ERR(fadev)) return fadev; =20 diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/pla= tform/x86/firmware_attributes_class.h index ad94bf91e5af30a2b8feb9abf224ee6f0d17600a..3a13c69ca6a0f993cf7c6bfae6e= 43f1eeaa002ab 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -18,11 +18,14 @@ extern const struct class firmware_attributes_class; * @dev: The class device. * @attrs_kobj: The "attributes" root kobject. * @groups: Sysfs groups attached to the @attrs_kobj. + * @auto_groups: Sysgs groups generated from &struct fwat_attr_config atta= ched. + * to the @attrs_kobj */ struct fwat_device { struct device *dev; struct kobject attrs_kobj; const struct attribute_group **groups; + const struct attribute_group **auto_groups; }; =20 #define to_fwat_device(_k) container_of_const(_k, struct fwat_device, attr= s_kobj) @@ -30,6 +33,7 @@ struct fwat_device { /** * struct fwat_attribute - The firmware-attributes's custom attribute * @attr: Embedded struct attribute. + * @aux: Auxiliary number defined by the user. * @show: Show method called by the "attributes" kobject's ktype. * @store: Store method called by the "attributes" kobject's ktype. */ @@ -43,14 +47,234 @@ struct fwat_attribute { =20 #define to_fwat_attribute(_a) container_of_const(_a, struct fwat_attribute= , attr) =20 +enum fwat_attr_type { + fwat_type_integer, + fwat_type_string, + fwat_type_enumeration, +}; + +enum fwat_property { + FWAT_PROP_DISPLAY_NAME, + FWAT_PROP_LANGUAGE_CODE, + FWAT_PROP_DEFAULT, + + FWAT_INT_PROP_MIN, + FWAT_INT_PROP_MAX, + FWAT_INT_PROP_INCREMENT, + + FWAT_STR_PROP_MIN, + FWAT_STR_PROP_MAX, + + FWAT_ENUM_PROP_POSSIBLE_VALUES, +}; + +struct fwat_attr_config; + +struct long_ops { + int (*read)(struct device *dev, long aux, long *val); + int (*write)(struct device *dev, long aux, long val); +}; + +struct str_ops { + int (*read)(struct device *dev, long aux, const char **str); + int (*write)(struct device *dev, long aux, const char *str, size_t count); +}; + +/** + * struct fwat_attr_ops - Operations for a firmware *attribute* + * @type: Type of callbacks. + * @prop_read: Callback for retrieving each configured property of an attr= ibute. + * @integer: Integer type callbacks. + * @string: String type callbacks. + * @enumeration: Enumeration type callbacks. + */ +struct fwat_attr_ops { + enum fwat_attr_type type; + ssize_t (*prop_read)(struct device *dev, long aux, + enum fwat_property prop, char *buf); + union { + struct long_ops integer; + struct str_ops string; + struct str_ops enumeration; + }; +}; + +/** + * struct fwat_attr_config - Configuration for a single firmware *attribut= e* + * @name: Name of the sysfs group associated with this *attribute*. + * @mode: Mode assigned to current_value + * @aux: Auxiliary number defined by the user, which will be passed to + * read/write callbacks. + * @ops: Operations for this *attribute*. + * @props: Array of properties of this *attribute*. + * @num_props: Size of the props array. + */ +struct fwat_attr_config { + const char *name; + umode_t mode; + long aux; + const struct fwat_attr_ops *ops; + const enum fwat_property *props; + size_t num_props; +}; + +/** + * DEFINE_SIMPLE_FWAT_OPS() - Define static &struct fwat_attr_ops for a si= mple + * *attribute* with no properties, i.e. No + * &fwat_attr_ops.read_prop callback + * @_name: Prefix of the `read` and `write` callbacks. + * @_type: Firmware *attribute* type. + * + * Example: + * + * static int example_read(...) {...} + * static int example_write(...) {...} + * + * DEFINE_SIMPLE_FWAT_OPS(example, ...); + */ +#define DEFINE_SIMPLE_FWAT_OPS(_name, _type) \ + static const struct fwat_attr_ops _name##_ops =3D { \ + .type =3D fwat_type_##_type, \ + ._type =3D { \ + .read =3D _name##_read, \ + .write =3D _name##_write, \ + } \ + } + +/** + * DEFINE_FWAT_OPS() - Define static &struct fwat_attr_ops with all callba= cks. + * @_name: Prefix of the `read` and `write` callbacks. + * @_type: Firmware *attribute* type. + * + * Example: + * + * static int example_read(...) {...} + * static int example_write(...) {...} + * static int example_prop_read(...) {...} + * + * DEFINE_FWAT_OPS(example, ...); + */ +#define DEFINE_FWAT_OPS(_name, _type) \ + static const struct fwat_attr_ops _name##_ops =3D { \ + .type =3D fwat_type_##_type, \ + .prop_read =3D _name##_prop_read, \ + ._type =3D { \ + .read =3D _name##_read, \ + .write =3D _name##_write, \ + } \ + } + +/** + * FWAT_CONFIG() - Configuration pointer for a single firmware *attribute*. + * @_name: String name of this *attribute*. + * @_mode: Mode assigned to current_value + * @_type: Firmware *attribute* type. + * @_ops: Pointer to &struct fwat_attr_ops. + * @_props: Pointer to a enum fwat_property array. + * @_num_props: Size of the @_props array. + * + * This is a convenience macro to quickly construct a &struct fwat_attr_co= nfig + * array, which will be passed to &struct fwat_dev_config. + * + * Example: + * + * static int example_read(...) {...} + * static int example_write(...) {...} + * static int example_prop_read(...) {...} + * + * DEFINE_FWAT_OPS(example, ...); + * + * static const enum fwat_property props[] =3D {...}; + * + * static const struct fwat_attr_config * const attrs_config[] =3D { + * FWAT_CONFIG(example, ..., &example_fwat_ops, props, + * ARRAY_SIZE(props)), + * ... + * NULL + * }; + * + * static const struct fwat_dev_config fdev_config =3D { + * .attrs_config =3D attrs_config, + * ... + * } + */ +#define FWAT_CONFIG(_name, _mode, _ops, _props, _num_props) \ + (&(const struct fwat_attr_config) { \ + .name =3D _name, \ + .mode =3D _mode, \ + .ops =3D _ops, \ + .num_props =3D _num_props, \ + .props =3D _props, \ + }) + +/** + * FWAT_CONFIG_AUX() - Configuration pointer for a single firmware *attrib= ute* + * with an auxiliary number defined by the user + * @_name: String name of this *attribute*. + * @_mode: Mode assigned to current_value + * @_type: Firmware *attribute* type. + * @_aux: Auxiliary number defined by the user. + * @_ops: Pointer to &struct fwat_attr_ops. + * @_props: Pointer to a enum fwat_property array. + * @_num_props: Size of the @_props array. + * + * This is a convenience macro to quickly construct a &struct fwat_attr_co= nfig + * array, which will be passed to &struct fwat_dev_config. + * + * Example: + * + * static int example_read(...) {...} + * static int example_write(...) {...} + * static int example_prop_read(...) {...} + * + * DEFINE_FWAT_OPS(example, ...); + * + * static const enum fwat_property props[] =3D {...}; + * + * static const struct fwat_attr_config * const config[] =3D { + * FWAT_CONFIG_AUX(example, ..., n, &example_fwat_ops, props, + * ARRAY_SIZE(props)), + * ... + * NULL + * }; + * + * static const struct fwat_dev_config fdev_config =3D { + * .attrs_config =3D attrs_config, + * ... + * } + */ +#define FWAT_CONFIG_AUX(_name, _mode, _aux, _ops, _props, _num_props) \ + (&(const struct fwat_attr_config) { \ + .name =3D _name, \ + .mode =3D _mode, \ + .aux =3D _aux, \ + .ops =3D _ops, \ + .num_props =3D _num_props, \ + .props =3D _props, \ + }) + +/** + * struct fwat_dev_config - Configuration for this devices's + * &fwat_device.auto_groups + * @attrs_config: NULL terminated &struct fwat_attr_config array. + * @is_visible: Optional visibility callback to determine the visibility + * of each auto_group. + */ +struct fwat_dev_config { + const struct fwat_attr_config *const *attrs_config; + bool (*is_visible)(struct device *dev, const struct fwat_attr_config *con= fig); +}; + struct fwat_device * __must_check fwat_device_register(struct device *parent, const char *name, void *data, + const struct fwat_dev_config *config, const struct attribute_group **groups); =20 void fwat_device_unregister(struct fwat_device *fwadev); =20 struct fwat_device * __must_check devm_fwat_device_register(struct device *parent, const char *name, void *d= ata, + const struct fwat_dev_config *config, const struct attribute_group **groups); =20 #endif /* FW_ATTR_CLASS_H */ --=20 2.49.0 From nobody Fri Dec 19 17:16:20 2025 Received: from mail-vk1-f175.google.com (mail-vk1-f175.google.com [209.85.221.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA7411DF97D; Sat, 17 May 2025 08:52:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471940; cv=none; b=U5mu5oGMSsNcSBS5byabrAoRDU4ZIlTKK4BTsOAirMDZAzcPUw7glwN6qZoefU2AEeQ7EfVUrM0swpqorZieZ7dXUTqn4ZsVDvnv0rV4AgFbbgojkqn7o7UybX+wXSLZRcN1L6bFVuEphFkqRNeuOeSDNiEmm0e31Tj8SfPM6/0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471940; c=relaxed/simple; bh=rmQRwhQBhuVXzEdWrxu6DgGpJ/TFjWXuQ+dIpPlVohk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=U4bRvJ44H6ZaYLvbtJUi1bBIDsIxj8xrVYk959I6p6MNLE+JfR1MEMk1K5BTLmkmCCfRPH88xAgfLdyhhlIfStLy1wxXVNWLJPoQDsqIRTlP3Ltuq1CDKEXYKzwwqA09q9fE2Y/5W9u/rAiPU2J5W+lJ+MSnj//clkxcF/dYbNQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UneHCoBP; arc=none smtp.client-ip=209.85.221.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UneHCoBP" Received: by mail-vk1-f175.google.com with SMTP id 71dfb90a1353d-52446b21cfdso934943e0c.1; Sat, 17 May 2025 01:52:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747471937; x=1748076737; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=qccBuuWpvwsgM8Jc+gDFmCX6IMSyESybM5/OV7jtB+0=; b=UneHCoBPT5tdHfFK+JquMmD4Rpco7CnynnOKQE1mL8MuUzKHs4mVCDrdiEOjULEZYt LYxHfreHmcL2iFPOLTgvLt3Ml4mYlej/2OxlKNPtS5JObEDeB1GNBvmwp44h2C2bvjeh qdtnbidSYTnfKUfSwQ5LFzUQ3XjqWlaE99hrAIAR8YhDTgJThi5jGYugk/GGGemPNyVR hJlOfn4FfuQKVPdy7LtV1vN3lPZL11UpP5fk/7sxtZyy/jtWfagyWFCwlpSCw8gZTKbG py+ROQ1F/1jYo0NbLf5ugDtXfQxbDyMCODkzpaT4HMMk6126wNhmi5+rQZesOzn696fC eADA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747471937; x=1748076737; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qccBuuWpvwsgM8Jc+gDFmCX6IMSyESybM5/OV7jtB+0=; b=ctW95QUHiNXFfB+gfeiXfFrzA9daXS/9OkUn42AFxbFP5ZxaqeDP7R9Q18O4uzID+v FPADBqv5voUC/7LNqq1e88485H7cNn5/eJMTKz3ga9LVm5bkodlOSFCFfttziS9Oxvz6 S1+FOryxCmmvfVsQXzuecpwxZBHvEl55vFYTEnxSNIXdNIrAj0wBwPpSDWp7u/3MlYMY u45JQO1s/5fucEqqD+wb57xbsYvR7KpXbs3d5szibpUznahGGLqyA2eEW5YceclOo9zO PxpL9/2DyWdmrPDrSkkT3qIAls9luIUqs3BFq9wbrNQV6Q/ppJ4jnRa80zrIc4yJl7i6 2/ug== X-Forwarded-Encrypted: i=1; AJvYcCVhK9DUed7WkyvvbDn8aY2lhVJtb0FXJKLnQmh5FLjfpSAJMdOhGHYXwdrW9xgGewmC1XdH0rXYQWuU0to=@vger.kernel.org, AJvYcCWAU9ndizfpro0eWFsZgDKXyo5hF7bDqEaQoW9e152m90RKdpSirSbX1VWrUPKRgjPV1NP9XE5m4yqNcWh1z13rdHwbSg==@vger.kernel.org X-Gm-Message-State: AOJu0YyW7gpY1S+y+rChPKAsiUiuAKnsqdRa6qRPIkKz3uqGrNtVcJZi vn4hMO3Zpb88f5yfJM4xy1JI7VgxWWIU62P31chwHYfmB7A88+oy7npI X-Gm-Gg: ASbGnctkuuLfMyiwQL7RlDd1oR0JGt+vUgmrp1/AOaj+xPb0dhY6Se5MSm+P2XT67LN P3DK11ILAfxQVMNaG/5SbGL1FlzuNpmdq7YUEtrCSM0f31my0Tbv5lTnbThM1fI7e53tj2Ccd/X b3C5nL3OUuHM4ZaMkC5UPKjrpE7EXs+UcKqhAptaXD1W5wRv0oEKYvKxiRQkWGHpIp0U6duCbam D4vkmyP+Ab0G7qDUbwyxcZL57oHqsgjoOUmPavjZW40zSgCPeOmra+re3E+ZSpzXwafAJ5FLcn3 yNtfkfgKhGLQwu2qQ+8c5xTJNVzo0jDmqZxnJ2/uioj1eKa3Ww== X-Google-Smtp-Source: AGHT+IGp6hPOh6NJySLw2Ewyl+wfIspmsXg3vEzw48m59injigVXszENJYTCD0nB94sqN7ZRcfAaYQ== X-Received: by 2002:a05:6122:8c0f:b0:520:3536:feb5 with SMTP id 71dfb90a1353d-52dba97c622mr7276344e0c.11.1747471937443; Sat, 17 May 2025 01:52:17 -0700 (PDT) Received: from [192.168.1.26] ([181.85.227.70]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-52dba9405adsm3455812e0c.11.2025.05.17.01.52.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 May 2025 01:52:17 -0700 (PDT) From: Kurt Borja Date: Sat, 17 May 2025 05:51:38 -0300 Subject: [PATCH v2 3/5] platform/x86: firmware_attributes_class: Add a boolean type Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250517-fw-attrs-api-v2-3-fa1ab045a01c@gmail.com> References: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> In-Reply-To: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> To: Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Joshua Grisham , Mark Pearson , Armin Wolf , Mario Limonciello Cc: Antheas Kapenekakis , "Derek J. Clark" , Prasanth Ksr , Jorge Lopez , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Dell.Client.Kernel@dell.com, Kurt Borja X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4422; i=kuurtb@gmail.com; h=from:subject:message-id; bh=rmQRwhQBhuVXzEdWrxu6DgGpJ/TFjWXuQ+dIpPlVohk=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBkafvrHTlQayQs+/d03p3uugLOnfGjKpzn2Esw+tXYvv uw4VhjcUcrCIMbFICumyNKesOjbo6i8t34HQu/DzGFlAhnCwMUpABOZ3c3wV7hje0VYblaeRdEN Bs4PK5m5fy+Obp9XYhYg7ML/sKl9GiND12NJa0uPX5N8PfPDZixn1J5psPJocfgKD49y3UmTf8m zAQA= X-Developer-Key: i=kuurtb@gmail.com; a=openpgp; fpr=54D3BE170AEF777983C3C63B57E3B6585920A69A Add a `boolean` attribute type to prevent the use of the `enumeration` type for this simple specification. Signed-off-by: Kurt Borja --- .../ABI/testing/sysfs-class-firmware-attributes | 1 + drivers/platform/x86/firmware_attributes_class.c | 19 +++++++++++++++= ++++ drivers/platform/x86/firmware_attributes_class.h | 8 ++++++++ 3 files changed, 28 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-firmware-attributes b/Do= cumentation/ABI/testing/sysfs-class-firmware-attributes index 2713efa509b465a39bf014180794bf487e5b42d6..dc117e694416aed3f1f7ba0ebb1= d0c23337b2298 100644 --- a/Documentation/ABI/testing/sysfs-class-firmware-attributes +++ b/Documentation/ABI/testing/sysfs-class-firmware-attributes @@ -21,6 +21,7 @@ Description: - enumeration: a set of pre-defined valid values - integer: a range of numerical values - string + - bool =20 HP specific types ----------------- diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/pla= tform/x86/firmware_attributes_class.c index 29401b81b25b9bb1332dbe56eadf96ff81e91c2f..6ff38b3be98bc8705ac29ce0afc= 11d5a4604dc8e 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -27,6 +27,7 @@ EXPORT_SYMBOL_GPL(firmware_attributes_class); =20 static const char * const fwat_type_labels[] =3D { [fwat_type_integer] =3D "integer", + [fwat_type_boolean] =3D "boolean", [fwat_type_string] =3D "string", [fwat_type_enumeration] =3D "enumeration", }; @@ -74,6 +75,7 @@ fwat_current_value_show(struct device *dev, const struct = fwat_attribute *attr, c const struct fwat_attr_config *config =3D ext->config; const struct fwat_attr_ops *ops =3D config->ops; const char *str; + bool bool_val; long int_val; int ret; =20 @@ -87,6 +89,12 @@ fwat_current_value_show(struct device *dev, const struct= fwat_attribute *attr, c return ret; =20 return sysfs_emit(buf, "%ld\n", int_val); + case fwat_type_boolean: + ret =3D config->ops->boolean.read(dev, config->aux, &bool_val); + if (ret) + return ret; + + return sysfs_emit(buf, "%u\n", bool_val); case fwat_type_string: if (!ops->string.read) return -EOPNOTSUPP; @@ -117,6 +125,7 @@ fwat_current_value_store(struct device *dev, const stru= ct fwat_attribute *attr, const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); const struct fwat_attr_config *config =3D ext->config; const struct fwat_attr_ops *ops =3D config->ops; + bool bool_val; long int_val; int ret; =20 @@ -131,6 +140,16 @@ fwat_current_value_store(struct device *dev, const str= uct fwat_attribute *attr, =20 ret =3D ops->integer.write(dev, config->aux, int_val); break; + case fwat_type_boolean: + if (!ops->boolean.write) + return -EOPNOTSUPP; + + ret =3D kstrtobool(buf, &bool_val); + if (ret) + return ret; + + ret =3D ops->boolean.write(dev, config->aux, bool_val); + break; case fwat_type_string: if (!ops->string.write) return -EOPNOTSUPP; diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/pla= tform/x86/firmware_attributes_class.h index 3a13c69ca6a0f993cf7c6bfae6e43f1eeaa002ab..b823d05d76e91efa40cd3623687= b57c664176073 100644 --- a/drivers/platform/x86/firmware_attributes_class.h +++ b/drivers/platform/x86/firmware_attributes_class.h @@ -49,6 +49,7 @@ struct fwat_attribute { =20 enum fwat_attr_type { fwat_type_integer, + fwat_type_boolean, fwat_type_string, fwat_type_enumeration, }; @@ -80,11 +81,17 @@ struct str_ops { int (*write)(struct device *dev, long aux, const char *str, size_t count); }; =20 +struct bool_ops { + int (*read)(struct device *dev, long aux, bool *val); + int (*write)(struct device *dev, long aux, bool val); +}; + /** * struct fwat_attr_ops - Operations for a firmware *attribute* * @type: Type of callbacks. * @prop_read: Callback for retrieving each configured property of an attr= ibute. * @integer: Integer type callbacks. + * @boolean: Boolean type callbacks. * @string: String type callbacks. * @enumeration: Enumeration type callbacks. */ @@ -94,6 +101,7 @@ struct fwat_attr_ops { enum fwat_property prop, char *buf); union { struct long_ops integer; + struct bool_ops boolean; struct str_ops string; struct str_ops enumeration; }; --=20 2.49.0 From nobody Fri Dec 19 17:16:20 2025 Received: from mail-vk1-f181.google.com (mail-vk1-f181.google.com [209.85.221.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 391FB1DF271; Sat, 17 May 2025 08:52:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471954; cv=none; b=RsaB+3zR6q1HuIidHQHKJADeB25WL0UYKh3uLM+PRob0px1NxCbp5qhgE75U+NlJkZ1hP7Mdi5GohtwMfpdukXuD2vujJZommZhBRBGRH5zT98NjjCdu0ddVnl535qol5Z8U67SoxvoeKODBQ4eS+x5UOdwt/x93lpdtDtjgQps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471954; c=relaxed/simple; bh=qbGX0vY8ua1yjyX4gKrkjXd8FS4pqHM2ZzBMCrO0vV8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nCxwJMA/SFZvtI117NlL6moEDyRIN5rW8RLIuj5qRUCG/1dFZfVXff2nMAJZubqnzyUynt/qtjQaSZMTk8I3FH24Yv0UlzeoLfz6aNsmlo5eGuqFwixORred6kNS4xveSWkVc5ci2+DRDW8eehJzc9cLXM3Wt3ToFlKJFqKYh3Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CwNSwy3k; arc=none smtp.client-ip=209.85.221.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CwNSwy3k" Received: by mail-vk1-f181.google.com with SMTP id 71dfb90a1353d-52410fb2afeso1773049e0c.3; Sat, 17 May 2025 01:52:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747471952; x=1748076752; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=iNsWbQeM3Ef5H0Pf+40JMXz6QJMor+ntR9ZNUEK2L3U=; b=CwNSwy3k19CuI5vv1GriPUs+ReW0xJkzNNrPH9YeJz28Rc+rRI+B1PHt1Pn2h6uO4Z iBkPqbHmmrLIuP9tLbOjlycpGV2wnRJjv1lzSQcnoJbnPyCeD4myUungx8ChL99/rYa0 YHNMfZUc08Mj0Hdsdu6qbZgzxFKfW8W8o/YmxuyQe4b047wFqxrJeByIquO8K5nIwJ0U JPzN0kNYB122pn47wYjgHkFcOLlTNGQE7S0SKIEaQUJDco7y6/iYoKJnxWq4tn6nNxJg 0akos/Mu2NhiLzEJc6nI40lNcQBWyWh+hArO0BHz7ze/WH0uOlsT0uxcd6aQ7Gi7qOjQ MIPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747471952; x=1748076752; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iNsWbQeM3Ef5H0Pf+40JMXz6QJMor+ntR9ZNUEK2L3U=; b=jJ369RNtLGL0Hd3bGnRnRgFAzWz3Tz/zYLnL2MHMHQI32WHHgLOI9jeUkIid/pPvCR LxBkGUzzlXRyR6oklxmCfMNiTEA7V4dMsogVLVNzTDfwzEAiWeb3IJNR5y6NTva/0kmN guzZsbvRa2KvtkvNRh7uy8CQ8UNXFQNefaDswQEBNcDN+YxbpMNb6jPbXsZfg1E1BEnD BCLrsoX99Ez7z7hHYINcwGAa0Op3giGqlbTcZgwq8lP/MsoGquGv41qlwBNHhDUM1pm5 et2ffZ+G7xXsUvWwq2Zrdn0z+DFxinOqv9YDxD0jKK4QBYeSEllEZlsVHVpdKp/0jjw2 UBzQ== X-Forwarded-Encrypted: i=1; AJvYcCW6mC6SQbmIJ+olhYvFPWaw0WTLj+QGZTxiSFsO8vfj5Y9nPJBs0XRjAMt+zz/LIm4egFvN9/2RnZ7NUHI=@vger.kernel.org, AJvYcCWeZ06dOxFXJQHXUpJFe6wS3otlu32m0gnuvxFDg7bKyuLGPCtjr4CPDVcONe+7EvaqRqYrB607F397cnkE2+qKue1efg==@vger.kernel.org X-Gm-Message-State: AOJu0YxU10DFJRgaPpWIUucucJz0SqT/8y3Ny6m3RpwXpWIHVQR9Bosq jlTMkA5/hXKihVnXWMaHpzz1ht15b0kbRCMY6MZPRytPSYgHR1DXXlnO4YbhLA== X-Gm-Gg: ASbGnctE4JebL0wOx/wgR8nbp/AXO5P0Wy/hZmFjz3SX0ex10i7pTAs5Z5Z9E4ZLz6d FIrVQBluqCRXQTQnOhkgcfFAPhxuh/JbUfx2Bq4bfDqAoiIicpqfq+xNTsdN6ShWAIXPE/7RNZz ChzweieSG6lbn2g9C6E5zdFAPQ3a5WhC2L2IFiVud+dj+d8mI2aXwtnhA0Vyfyoopf4c1W22+P7 1s4jhy5gFBgMkWlzROaFIHe4evO2IfAjTDoHlsJNv6mQH2uPs9P+Qh2ePkoTer1v++2xUSNfGkX nRrytFyeFWzwJIptQijl8x9oxMZBqwt4maANEOKnlAnibIHYhg== X-Google-Smtp-Source: AGHT+IGP8LQww2xigb+BfZQUHdyFE9Gg6EhJtQK/HkUNyGB1GnpKuO2Nk5syCihGsKnFwLYIJg3K9A== X-Received: by 2002:a05:6122:46a7:b0:52a:863f:78dd with SMTP id 71dfb90a1353d-52dba91e5a2mr7834990e0c.6.1747471941735; Sat, 17 May 2025 01:52:21 -0700 (PDT) Received: from [192.168.1.26] ([181.85.227.70]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-52dba9405adsm3455812e0c.11.2025.05.17.01.52.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 May 2025 01:52:21 -0700 (PDT) From: Kurt Borja Date: Sat, 17 May 2025 05:51:39 -0300 Subject: [PATCH v2 4/5] MAINTAINERS: Add FIRMWARE ATTRIBUTES CLASS entry Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250517-fw-attrs-api-v2-4-fa1ab045a01c@gmail.com> References: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> In-Reply-To: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> To: Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Joshua Grisham , Mark Pearson , Armin Wolf , Mario Limonciello Cc: Antheas Kapenekakis , "Derek J. Clark" , Prasanth Ksr , Jorge Lopez , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Dell.Client.Kernel@dell.com, Kurt Borja X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=827; i=kuurtb@gmail.com; h=from:subject:message-id; bh=qbGX0vY8ua1yjyX4gKrkjXd8FS4pqHM2ZzBMCrO0vV8=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBkafvqOa+p1zpWc+sAv8/Ewe8ryiB/Pfst3+8zdphK1g +9o8u61HaUsDGJcDLJiiiztCYu+PYrKe+t3IPQ+zBxWJpAhDFycAjCR28cZ/nvNcuiamKQSFHvO bXH9w4OhtlmtTBn9WvccGdceeKN/8QHD/9IaK2XWq+Ycabt3KE5WqzEMKbA496fvM8dFQV0vI49 9fAA= X-Developer-Key: i=kuurtb@gmail.com; a=openpgp; fpr=54D3BE170AEF777983C3C63B57E3B6585920A69A Add entry for the FIRMWARE ATTRIBUTES CLASS. Signed-off-by: Kurt Borja --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index cfb3b51cec83d96e969c5b3be791948cb9d60bb9..48509d4da8b132f61ff2d5f90e1= 21bf94ee30e24 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9190,6 +9190,13 @@ F: include/linux/firewire.h F: include/uapi/linux/firewire*.h F: tools/firewire/ =20 +FIRMWARE ATTRIBUTES CLASS +M: Kurt Borja +L: platform-driver-x86@vger.kernel.org +S: Maintained +F: drivers/platform/x86/firmware_attributes_class.* +K: (devm_)?fwat_device_(un)?register + FIRMWARE FRAMEWORK FOR ARMV8-A M: Sudeep Holla L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) --=20 2.49.0 From nobody Fri Dec 19 17:16:20 2025 Received: from mail-vk1-f173.google.com (mail-vk1-f173.google.com [209.85.221.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2FEA1DEFDA; Sat, 17 May 2025 08:52:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471949; cv=none; b=sa8mcDqq2O18yGuDB7ylSDoOUH6+OHqfEVe30yff8nKaiUrJi3SJczB03eHVuHr0Lwwmq/EE4tz/cPy7skCje4dyFqXGG6Sx4yrkPfBVLG7DyDkimSR6SV3Xwn1HTIWxfUO3TYsbZchis6eQctCN25avQUedkBAGpaUVVRx5HPA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747471949; c=relaxed/simple; bh=5fWdlkwBhh2VysR3vGzbRF+lq4S0g74Mggb2Qpm7QeQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N0MW0cBhVvS/MrVH4v9xEuAJCsPNCMVwaJny/k0T+X8vGCi8MWOSTbUbBmHxrXdH7HaoHoJ976Z+aBnjPnywoxEI8lun9mbzVLYnvRIGK8mGYT8qAQZSqYDHq5nN1lL05z+VaHNcBDs54nAo6um4I3VJUrMvaRUKGirDAnPcNPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KIi+znEw; arc=none smtp.client-ip=209.85.221.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KIi+znEw" Received: by mail-vk1-f173.google.com with SMTP id 71dfb90a1353d-52c8849d7a5so1005393e0c.0; Sat, 17 May 2025 01:52:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747471946; x=1748076746; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=aVXvDi5+Ff0T/Ic/az84hkliZguJhkKjrGAsxpJ7wpk=; b=KIi+znEw8XWygRpv2So4rwzi2f/Pd4Byk0fiB+3X/dETH/QmZYgynFW9htQBUoF7iF Ur4ZT1KCrBwFmcsz9Caws9j3WYGpmcKU/RmTHVyI4jg2IYSvRL5b6xw29QOCEE7dYavS 4la6KAfVyV35oZpcKFk8z3Fs2zKPwtSxpH4J6NzHU97Bbh3dqXVsGhUDfcZ99l+frVPH q/Ny5G2kEPMgHBywXioaBIfc7hUE4IxzuvrBXVq7FFunI0Wg0Q0Cj0jcjQDtDtOBasWw aXwqZQdSoGlmSfSFkIvi7rXDKKjWff4CWfADGNOo2mToB41ArMxtw5CQ6s+OR+03y1++ FOSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747471946; x=1748076746; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aVXvDi5+Ff0T/Ic/az84hkliZguJhkKjrGAsxpJ7wpk=; b=iMosLjtsJ2EtP7kLbjYdzxsBn8QEE3hRMHMlFxYOMC/VinQZdSZtqifgGRUcYUpYlp qrnxA46EzQygSyXDkyQuJd3lumGVkVma8hFSIe6RbOWwDYEt4rPmA3aQE1C/NqOlFnJ5 Cbw8E51fM58aQG1uOvG9Aozj2Ti+C5pxD0yqwLYUhnUf22GG7iuYLlEPHNymwbLIuwsI +pic+fouIq3QFWNyCzDokbM9POIw3rbdv1ZXcQAZfqPND7j62DoCtjq3GNNLgeJv/TmK myMtCpMH00bvsAohPyezybqC2ODhGde4D3SQ++cYN86KFa2RIVh1eIAGfhStlppOdI5i T8cg== X-Forwarded-Encrypted: i=1; AJvYcCU7Xt4ae+so6H+ypOmTmXD63FlLT55YO1RoBsWjq5+Orqr6KEVn1umUKerBewH0UkgmgWy1hpDmOvZBqRYSPJd8QvSfHQ==@vger.kernel.org, AJvYcCUgtruXxyuW+wuh+RbwDXnkmdxV4iuxFSUwQ94acEOg27KWpAiwu7ROR8Nx16ZycZFD5Nf3NnGW8dKSCRk=@vger.kernel.org X-Gm-Message-State: AOJu0YwxoMKvVRLmQ+ZL3c1ZF7TCKK7VNM5Mky+lpxU6K3MweIvBlIEk wkT2olT7Lt/dRWNBwIU+gkpv4uwe73/MYNWDlL9OiIuuYto3yhIUtP54n0lquw== X-Gm-Gg: ASbGncuCCMGM1TdnOTwCeY8kSYZdHGZ3+csydHM/cTX8THheobtnWn9TfvWTfVOajEw ztm3L8H66sibko6XVa1GJvqVBQEH3D0Brwl5xcZzu4kdvdCksvZABQs86vBR1yRDqru2SrLLHd7 vDuwzrgNYfboHHxwkfU7qWSpHhDm71NFSvZwuvw9NpeIAX2b7uAaXNJFHAgOpmZiAkpf5pF4bnZ Ng6PmWYhdc078TrlGpv442A7XOCJTQpgkSXMDrRMFTFLK6l5T/slnQzeusm0YvLi/McW1ECgsex HNdwTbA+ga7jJ6ERfujFrtrIWFB1Gx+GwG1BIT6oZnvCyLaMeA== X-Google-Smtp-Source: AGHT+IHolgOgY/LKg3X1KhcyCcZVqJss2/wGhxz+pRT8wvHUT20mSEBAdJUpZLdWjvZBR2Q1nDzX3Q== X-Received: by 2002:a05:6122:1d48:b0:529:1a6a:cd48 with SMTP id 71dfb90a1353d-52dba964347mr7859500e0c.6.1747471946319; Sat, 17 May 2025 01:52:26 -0700 (PDT) Received: from [192.168.1.26] ([181.85.227.70]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-52dba9405adsm3455812e0c.11.2025.05.17.01.52.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 May 2025 01:52:25 -0700 (PDT) From: Kurt Borja Date: Sat, 17 May 2025 05:51:40 -0300 Subject: [PATCH v2 5/5] platform/x86: samsung-galaxybook: Transition to new firmware_attributes API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250517-fw-attrs-api-v2-5-fa1ab045a01c@gmail.com> References: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> In-Reply-To: <20250517-fw-attrs-api-v2-0-fa1ab045a01c@gmail.com> To: Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Joshua Grisham , Mark Pearson , Armin Wolf , Mario Limonciello Cc: Antheas Kapenekakis , "Derek J. Clark" , Prasanth Ksr , Jorge Lopez , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Dell.Client.Kernel@dell.com, Kurt Borja X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=11814; i=kuurtb@gmail.com; h=from:subject:message-id; bh=5fWdlkwBhh2VysR3vGzbRF+lq4S0g74Mggb2Qpm7QeQ=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBkafvrl767cXsLivPno+ZNej65/NNi+8Hml3um7UU2Xq 4Tntx7821HKwiDGxSArpsjSnrDo26OovLd+B0Lvw8xhZQIZwsDFKQATEY9g+CtQ/T7P2t6OyT/u mGPyyvPzi9zVd05fPKnxtsnKGbItnw8wMnz8H/E5fkHv21tzC29f7o8qUjVZqhe1+ccesVmTZyh 9fM0FAA== X-Developer-Key: i=kuurtb@gmail.com; a=openpgp; fpr=54D3BE170AEF777983C3C63B57E3B6585920A69A Transition to new firmware_attributes API and replace `enumeration` types with the simpler `boolean` type. Signed-off-by: Kurt Borja --- drivers/platform/x86/samsung-galaxybook.c | 308 ++++++++++++--------------= ---- 1 file changed, 123 insertions(+), 185 deletions(-) diff --git a/drivers/platform/x86/samsung-galaxybook.c b/drivers/platform/x= 86/samsung-galaxybook.c index 5878a351993eb05a4c5c2c75b4915d972ce9becc..c69ac4b240ca2acb37ba751853c= e33e10a91ebb3 100644 --- a/drivers/platform/x86/samsung-galaxybook.c +++ b/drivers/platform/x86/samsung-galaxybook.c @@ -36,8 +36,6 @@ struct samsung_galaxybook { struct platform_device *platform; struct acpi_device *acpi; =20 - struct device *fw_attrs_dev; - struct kset *fw_attrs_kset; /* block in case firmware attributes are updated in multiple threads */ struct mutex fw_attr_lock; =20 @@ -66,13 +64,7 @@ enum galaxybook_fw_attr_id { GB_ATTR_BLOCK_RECORDING, }; =20 -static const char * const galaxybook_fw_attr_name[] =3D { - [GB_ATTR_POWER_ON_LID_OPEN] =3D "power_on_lid_open", - [GB_ATTR_USB_CHARGING] =3D "usb_charging", - [GB_ATTR_BLOCK_RECORDING] =3D "block_recording", -}; - -static const char * const galaxybook_fw_attr_desc[] =3D { +static const char * const galaxybook_fwat_desc[] =3D { [GB_ATTR_POWER_ON_LID_OPEN] =3D "Power On Lid Open", [GB_ATTR_USB_CHARGING] =3D "USB Charging", [GB_ATTR_BLOCK_RECORDING] =3D "Block Recording", @@ -908,209 +900,155 @@ static int galaxybook_block_recording_init(struct s= amsung_galaxybook *galaxybook =20 /* Firmware Attributes setup */ =20 -static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr= , char *buf) +static int galaxybook_fwat_read(struct device *dev, long aux, const char *= *str) { - return sysfs_emit(buf, "enumeration\n"); -} - -static struct kobj_attribute fw_attr_type =3D __ATTR_RO(type); - -static ssize_t default_value_show(struct kobject *kobj, struct kobj_attrib= ute *attr, char *buf) -{ - return sysfs_emit(buf, "0\n"); -} - -static struct kobj_attribute fw_attr_default_value =3D __ATTR_RO(default_v= alue); - -static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attr= ibute *attr, char *buf) -{ - return sysfs_emit(buf, "0;1\n"); -} - -static struct kobj_attribute fw_attr_possible_values =3D __ATTR_RO(possibl= e_values); - -static ssize_t display_name_language_code_show(struct kobject *kobj, struc= t kobj_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", GB_ATTR_LANGUAGE_CODE); -} - -static struct kobj_attribute fw_attr_display_name_language_code =3D - __ATTR_RO(display_name_language_code); - -static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribu= te *attr, char *buf) -{ - struct galaxybook_fw_attr *fw_attr =3D - container_of(attr, struct galaxybook_fw_attr, display_name); - - return sysfs_emit(buf, "%s\n", galaxybook_fw_attr_desc[fw_attr->fw_attr_i= d]); -} - -static ssize_t current_value_show(struct kobject *kobj, struct kobj_attrib= ute *attr, char *buf) -{ - struct galaxybook_fw_attr *fw_attr =3D - container_of(attr, struct galaxybook_fw_attr, current_value); + struct samsung_galaxybook *galaxybook =3D dev_get_drvdata(dev); bool value; int err; =20 - err =3D fw_attr->get_value(fw_attr->galaxybook, &value); + switch (aux) { + case GB_ATTR_POWER_ON_LID_OPEN: + err =3D power_on_lid_open_acpi_get(galaxybook, &value); + break; + case GB_ATTR_USB_CHARGING: + err =3D usb_charging_acpi_get(galaxybook, &value); + break; + case GB_ATTR_BLOCK_RECORDING: + err =3D block_recording_acpi_get(galaxybook, &value); + break; + default: + return -EOPNOTSUPP; + } + if (err) return err; =20 - return sysfs_emit(buf, "%u\n", value); + *str =3D value ? "1" : "0"; + + return 0; } =20 -static ssize_t current_value_store(struct kobject *kobj, struct kobj_attri= bute *attr, - const char *buf, size_t count) +static int galaxybook_fwat_write(struct device *dev, long aux, const char = *str, + size_t count) { - struct galaxybook_fw_attr *fw_attr =3D - container_of(attr, struct galaxybook_fw_attr, current_value); - struct samsung_galaxybook *galaxybook =3D fw_attr->galaxybook; + struct samsung_galaxybook *galaxybook =3D dev_get_drvdata(dev); + bool val; + int err; + + err =3D kstrtobool(str, &val); + if (err) + return err; + + switch (aux) { + case GB_ATTR_POWER_ON_LID_OPEN: + err =3D power_on_lid_open_acpi_set(galaxybook, val); + break; + case GB_ATTR_USB_CHARGING: + err =3D usb_charging_acpi_set(galaxybook, val); + break; + case GB_ATTR_BLOCK_RECORDING: + err =3D block_recording_acpi_set(galaxybook, val); + break; + default: + return -EOPNOTSUPP; + } + + return err; +} + +static ssize_t galaxybook_fwat_prop_read(struct device *dev, long aux, + enum fwat_property prop, char *buf) +{ + switch (prop) { + case FWAT_PROP_DISPLAY_NAME: + return sysfs_emit(buf, "%s\n", galaxybook_fwat_desc[aux]); + case FWAT_PROP_LANGUAGE_CODE: + return sysfs_emit(buf, "%s\n", GB_ATTR_LANGUAGE_CODE); + case FWAT_PROP_DEFAULT: + return sysfs_emit(buf, "%d\n", 0); + case FWAT_ENUM_PROP_POSSIBLE_VALUES: + return sysfs_emit(buf, "0;1\n"); + default: + return -EOPNOTSUPP; + } +} + +DEFINE_FWAT_OPS(galaxybook_fwat, enumeration); + +static bool galaxybook_fwat_is_visible(struct device *dev, + const struct fwat_attr_config *config) +{ + struct samsung_galaxybook *galaxybook =3D dev_get_drvdata(dev); bool value; int err; =20 - if (!count) - return -EINVAL; + switch (config->aux) { + case GB_ATTR_POWER_ON_LID_OPEN: + err =3D power_on_lid_open_acpi_get(galaxybook, &value); + break; + case GB_ATTR_USB_CHARGING: + err =3D usb_charging_acpi_get(galaxybook, &value); + break; + case GB_ATTR_BLOCK_RECORDING: + return galaxybook->has_block_recording; + default: + return false; + } =20 - err =3D kstrtobool(buf, &value); - if (err) - return err; - - guard(mutex)(&galaxybook->fw_attr_lock); - - err =3D fw_attr->set_value(galaxybook, value); - if (err) - return err; - - return count; + return !err; } =20 -#define NUM_FW_ATTR_ENUM_ATTRS 6 +static const enum fwat_property galaxybook_fwat_props[] =3D { + FWAT_PROP_DISPLAY_NAME, + FWAT_PROP_LANGUAGE_CODE, + FWAT_PROP_DEFAULT, + FWAT_ENUM_PROP_POSSIBLE_VALUES, +}; =20 -static int galaxybook_fw_attr_init(struct samsung_galaxybook *galaxybook, - const enum galaxybook_fw_attr_id fw_attr_id, - int (*get_value)(struct samsung_galaxybook *galaxybook, - bool *value), - int (*set_value)(struct samsung_galaxybook *galaxybook, - const bool value)) +static const struct fwat_attr_config * const galaxybook_fwat_config[] =3D { + FWAT_CONFIG_AUX("power_on_lid_open", 0644, + GB_ATTR_POWER_ON_LID_OPEN, + &galaxybook_fwat_ops, + galaxybook_fwat_props, + ARRAY_SIZE(galaxybook_fwat_props)), + FWAT_CONFIG_AUX("usb_charging", 0644, + GB_ATTR_USB_CHARGING, + &galaxybook_fwat_ops, + galaxybook_fwat_props, + ARRAY_SIZE(galaxybook_fwat_props)), + FWAT_CONFIG_AUX("block_recording", 0644, + GB_ATTR_BLOCK_RECORDING, + &galaxybook_fwat_ops, + galaxybook_fwat_props, + ARRAY_SIZE(galaxybook_fwat_props)), + NULL +}; + +static const struct fwat_dev_config galaxybook_fwat_dev_config =3D { + .attrs_config =3D galaxybook_fwat_config, + .is_visible =3D galaxybook_fwat_is_visible, +}; + +static int galaxybook_fwat_init(struct samsung_galaxybook *galaxybook) { - struct galaxybook_fw_attr *fw_attr; - struct attribute **attrs; - - fw_attr =3D devm_kzalloc(&galaxybook->platform->dev, sizeof(*fw_attr), GF= P_KERNEL); - if (!fw_attr) - return -ENOMEM; - - attrs =3D devm_kcalloc(&galaxybook->platform->dev, NUM_FW_ATTR_ENUM_ATTRS= + 1, - sizeof(*attrs), GFP_KERNEL); - if (!attrs) - return -ENOMEM; - - attrs[0] =3D &fw_attr_type.attr; - attrs[1] =3D &fw_attr_default_value.attr; - attrs[2] =3D &fw_attr_possible_values.attr; - attrs[3] =3D &fw_attr_display_name_language_code.attr; - - sysfs_attr_init(&fw_attr->display_name.attr); - fw_attr->display_name.attr.name =3D "display_name"; - fw_attr->display_name.attr.mode =3D 0444; - fw_attr->display_name.show =3D display_name_show; - attrs[4] =3D &fw_attr->display_name.attr; - - sysfs_attr_init(&fw_attr->current_value.attr); - fw_attr->current_value.attr.name =3D "current_value"; - fw_attr->current_value.attr.mode =3D 0644; - fw_attr->current_value.show =3D current_value_show; - fw_attr->current_value.store =3D current_value_store; - attrs[5] =3D &fw_attr->current_value.attr; - - attrs[6] =3D NULL; - - fw_attr->galaxybook =3D galaxybook; - fw_attr->fw_attr_id =3D fw_attr_id; - fw_attr->attr_group.name =3D galaxybook_fw_attr_name[fw_attr_id]; - fw_attr->attr_group.attrs =3D attrs; - fw_attr->get_value =3D get_value; - fw_attr->set_value =3D set_value; - - return sysfs_create_group(&galaxybook->fw_attrs_kset->kobj, &fw_attr->att= r_group); -} - -static void galaxybook_kset_unregister(void *data) -{ - struct kset *kset =3D data; - - kset_unregister(kset); -} - -static void galaxybook_fw_attrs_dev_unregister(void *data) -{ - struct device *fw_attrs_dev =3D data; - - device_unregister(fw_attrs_dev); -} - -static int galaxybook_fw_attrs_init(struct samsung_galaxybook *galaxybook) -{ - bool value; + struct fwat_device *fwdev; int err; =20 err =3D devm_mutex_init(&galaxybook->platform->dev, &galaxybook->fw_attr_= lock); if (err) return err; =20 - galaxybook->fw_attrs_dev =3D device_create(&firmware_attributes_class, NU= LL, MKDEV(0, 0), - NULL, "%s", DRIVER_NAME); - if (IS_ERR(galaxybook->fw_attrs_dev)) - return PTR_ERR(galaxybook->fw_attrs_dev); - - err =3D devm_add_action_or_reset(&galaxybook->platform->dev, - galaxybook_fw_attrs_dev_unregister, - galaxybook->fw_attrs_dev); - if (err) - return err; - - galaxybook->fw_attrs_kset =3D kset_create_and_add("attributes", NULL, - &galaxybook->fw_attrs_dev->kobj); - if (!galaxybook->fw_attrs_kset) - return -ENOMEM; - err =3D devm_add_action_or_reset(&galaxybook->platform->dev, - galaxybook_kset_unregister, galaxybook->fw_attrs_kset); - if (err) - return err; - - err =3D power_on_lid_open_acpi_get(galaxybook, &value); - if (!err) { - err =3D galaxybook_fw_attr_init(galaxybook, - GB_ATTR_POWER_ON_LID_OPEN, - &power_on_lid_open_acpi_get, - &power_on_lid_open_acpi_set); - if (err) - return err; - } - - err =3D usb_charging_acpi_get(galaxybook, &value); - if (!err) { - err =3D galaxybook_fw_attr_init(galaxybook, - GB_ATTR_USB_CHARGING, - &usb_charging_acpi_get, - &usb_charging_acpi_set); - if (err) - return err; - } - err =3D galaxybook_block_recording_init(galaxybook); - if (err =3D=3D GB_NOT_SUPPORTED) - return 0; - else if (err) + if (!err) + galaxybook->has_block_recording =3D true; + else if (err !=3D GB_NOT_SUPPORTED) return err; =20 - galaxybook->has_block_recording =3D true; + fwdev =3D devm_fwat_device_register(&galaxybook->platform->dev, + "samsung-galaxybook", galaxybook, + &galaxybook_fwat_dev_config, NULL); =20 - return galaxybook_fw_attr_init(galaxybook, - GB_ATTR_BLOCK_RECORDING, - &block_recording_acpi_get, - &block_recording_acpi_set); + return PTR_ERR_OR_ZERO(fwdev); } =20 /* @@ -1389,7 +1327,7 @@ static int galaxybook_probe(struct platform_device *p= dev) return dev_err_probe(&galaxybook->platform->dev, err, "failed to initialize kbd_backlight\n"); =20 - err =3D galaxybook_fw_attrs_init(galaxybook); + err =3D galaxybook_fwat_init(galaxybook); if (err) return dev_err_probe(&galaxybook->platform->dev, err, "failed to initialize firmware-attributes\n"); --=20 2.49.0