From nobody Sat Feb 7 18:20:39 2026 Received: from mail-ua1-f48.google.com (mail-ua1-f48.google.com [209.85.222.48]) (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 8470B27464B; Fri, 9 May 2025 07:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776953; cv=none; b=DWEjtjCHeqhbiNoCo3yq6JU88/cZeCowVe45ZVbIUPzpPdqB+0h5PkPpDdh/ChQB1KD6R7OktRN0H52yNrFvbUJIN9vC5VGmGroathrp14WRx/0rD+ueGTqropKGUm43ZLfl8IuOX8wfV9GvXCkpTRmRssBUtJJty1FUtYFPpvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776953; c=relaxed/simple; bh=YCYqXKj8zBvvNVfNZMoHOsi2v4z3PSsjaVp9XyPor6s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=be9y6/pxSmlVVGIk/9yjoLFYlcbIgDg2q4aGSsQSeQLWWU0n23S90TTNGaJrsGQsmddlh/ZTIr1oGLX087EOipBSUBMf+gIfmgmW4YUh3wWm9WUU+6+1ORM2lZaUvk9uB6hYao4T0lA6dcBP0bNo9jgStg5LhL3TY4haiWWyvpY= 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=gY95asV8; arc=none smtp.client-ip=209.85.222.48 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="gY95asV8" Received: by mail-ua1-f48.google.com with SMTP id a1e0cc1a2514c-875b8e006f8so514904241.0; Fri, 09 May 2025 00:49:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746776950; x=1747381750; 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=+eBx27AMGCwqy5ZDp1gOClNdGcPujNcYWbgmiJhO5wI=; b=gY95asV8AfbplobYLJyjIIrySm0dOuLrNZYJPvcR1QP1ZJaSuVVXxOGuWUXqjkQuB3 JttdvtwyoMZgEtr8sIOMpRJjPFPluD36TFKAehfv0zIVsqfQ1epEFm8gxVGyAbwOkZng nJ5qSkFjC8dgqu0hKmwXCoDjn2uBVzW+sIKE2JtebXbs9mK2xu3Gj7DbEWjCAoMoFgmN I1zWWLTxhoi4x0y8riE/O8dKbVgst35p/kd3DOJ2zkIMiz6TcFIr48O7Apdd5v/ewney zKWN8BMBT1mx6YY2JuktLRoXo9Cyxb6QAwGR4HRYbqywhyAZy4HRmLfPSiliJzCXoZxw j6yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776950; x=1747381750; 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=+eBx27AMGCwqy5ZDp1gOClNdGcPujNcYWbgmiJhO5wI=; b=HzROCfukZ+31aoUbRnwy4vehcfzqUIiUDnDuBi5ToVCMz4QCrhOHKJraqyGHDEq3ut NMe50SnNedro25HYLIv+bNfxyRLccqNXCAf1IIdr9L9du4hvbMcTh+jlqDh+taIKhh+b yrv+ZBjhyfGET/XSat//y6fF7ZmTF41Zvd2SxP70lZkU3kf8AZ92NTM69jhKqpvmDVJ6 lgOQYzS9NLG+jx2IpTh6ZNxwI2Nzh2oZz729gx0kbMX2CYGxCwVLkOSipg1QjO5cSqSy kME7HJL/JVRbynqN+FXLfV9Rfl/tnn9sjTIuQPxIci5A1VUsA/RJZkN4u9hcgvBHq1v3 l44Q== X-Forwarded-Encrypted: i=1; AJvYcCWWd1mQ6+hIYVP7Op9tT2aG2F34sIEWjOg7YDBlR9cRdOdTPF9ubviSavtD6C2owMl02xLh6g3n9tPo81BNqnnt743B2A==@vger.kernel.org, AJvYcCXpQ6FIFZjgjPoUZ7tnN0lBI3x5RCTLQ7zZs6eA4qu0e5Z7X+eFsNhkGq7Ee/d+FJUgOiVEqS60lsCbHgw=@vger.kernel.org X-Gm-Message-State: AOJu0Yz8DXz//ZdAz9jDpVUCHGmJkAOCWgE+OCY6sqvuEVc1O2Vwtk4D AHOQxmrNyI+GX8M9n2Lp+00bYelQz0sSAswRpe0gXSfJR+Z+zxJgT8McvA== X-Gm-Gg: ASbGncuWEhxzPxRrGfRsMf4vb5T4OTS5pC28fVB7dXF+jPNQHBT44XQySBC6vRBbgs2 6Tv+pHCsfg/nBbmpEDRjowsL0EBp1JH9YKOk4ZgKsBJWTDL/t7eGcYImozrRBkxCuQXDuhrr4lG cyE2v2/F0bKZw/fqYuesVE/8j8cW2UII6gYF3fuvT+iB5oOybcXL4l9EOS62aqoqV73geHP9umu txFluoB3ysWiol948t6qqIjKKrEmGZDQ5bC5mYiR/FKks0aKUB3m7qTRNZgJ+cQXDkWsyttHDiI gDuMLiMxNFw3d4edRjcbhDiVZ4cyOBd8svpVqdYy X-Google-Smtp-Source: AGHT+IFyg2xmtOe/i3sQe/MqyF86NBYm8lH9pBZYHyw+Kbxgfnly1h69GDwzd1eYQB67ELiM/x/wmQ== X-Received: by 2002:a05:6102:5e97:b0:4da:e631:a472 with SMTP id ada2fe7eead31-4deed3e3410mr2179824137.20.1746776950293; Fri, 09 May 2025 00:49:10 -0700 (PDT) Received: from [192.168.1.26] ([181.91.133.137]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-879f62986f3sm678265241.33.2025.05.09.00.49.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 00:49:09 -0700 (PDT) From: Kurt Borja Date: Fri, 09 May 2025 04:48:33 -0300 Subject: [PATCH RFC 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: <20250509-fw-attrs-api-v1-1-258afed65bfa@gmail.com> References: <20250509-fw-attrs-api-v1-0-258afed65bfa@gmail.com> In-Reply-To: <20250509-fw-attrs-api-v1-0-258afed65bfa@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=8227; i=kuurtb@gmail.com; h=from:subject:message-id; bh=Vxr1YLgSfKtW1/Fz3hWql1pRw5necvJXVBfazYuQO4A=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBmym3OKToqlJe1sENPQZghUuWIiaTGzo2PD189TZj5i/ bCSv31CRykLgxgXg6yYIkt7wqJvj6Ly3vodCL0PM4eVCWQIAxenAExkpiwjw/eHm743xqUKXlvs +PKX05v/ex6rMb5fE7ZQKq/EOt3NSpmR4UZapUc3Z2+w//Q3/mEvH9lvTnW7LfVg3iQbvwsCqQU azAA= 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(). Signed-off-by: Thomas Wei=C3=9Fschuh Co-developed-by: Kurt Borja Signed-off-by: Kurt Borja Reviewed-by: Mario Limonciello --- drivers/platform/x86/firmware_attributes_class.c | 165 +++++++++++++++++++= ++++ drivers/platform/x86/firmware_attributes_class.h | 44 ++++++ 2 files changed, 209 insertions(+) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/pla= tform/x86/firmware_attributes_class.c index 736e96c186d9dc6d945517f090e9af903e93bbf4..58ab1495ba3bd449cfe17de2827= a57a0c5937788 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -2,7 +2,12 @@ =20 /* Firmware attributes class helper module */ =20 +#include +#include +#include #include +#include +#include #include "firmware_attributes_class.h" =20 const struct class firmware_attributes_class =3D { @@ -10,6 +15,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 +186,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 Sat Feb 7 18:20:39 2026 Received: from mail-vs1-f50.google.com (mail-vs1-f50.google.com [209.85.217.50]) (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 F347E27466A; Fri, 9 May 2025 07:49:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776963; cv=none; b=kvoA5oQ1jmRfzrA+OrXG1ATNa3/ha4BIxQZMX5g2uBYonfoUd/GA3CNakvJCkt/w2HTo22xsNbNl77zML1NwDs0xVW6mnbHQhR5/SRsG/WHaIUrNhDZprZfzUbRs+B0iI1oQ8ISOwhIvT6wFwNS/rKw9gW2uA0RWfgo5wXeC+sk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776963; c=relaxed/simple; bh=zqJFSCx7AUWfbriM3zIDxSBZnylClDLryW6FMC+feiA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hUwLsrTcgZtRuURUMb6iFgtMuH5cUM1Fci6TIWfozxyzrDrv9pakB6/LQ8OUzpAZ3JLA2N9zTve8d5uE+umhmZeAdDceSNeSHD9tb1N63MUTnay2rKuW7CoIiRcnD2M1bsN4H0/Ufu8XgWui1PbgRifvE/gHjgrePcGQLmWlNIQ= 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=I1F7EGgH; arc=none smtp.client-ip=209.85.217.50 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="I1F7EGgH" Received: by mail-vs1-f50.google.com with SMTP id ada2fe7eead31-4c4ecf86e8bso566861137.2; Fri, 09 May 2025 00:49:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746776955; x=1747381755; 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=I0Qr/Dx2Mpz9q6UxyEXOpqASgzXyh5bvBW29AbGoUfc=; b=I1F7EGgHvEgyLkvLUFXz+4oq7NFuIZ91/yxmw84bxy+gXMBZ2soupOuOyxryr3LtAz u5RwYvRF7mvEl2CW95BVj+Mgz38jagok64Ij9odBxPNYGCVQpkZ5VQHXbA8a8X7HxpC4 7Hs4xZYoFGFd64lObKEVfQMPUCGe6REJVchad60Ah3BGBdPK8TtxA8B+xo+oJ9K0Ge/W GqAa07dWo76IjM3EH3/hynL95As+Dx9R1OKFXHXIsW+qjzJIh9aE/0BBWoXTOAxkU3so wtqmN/gb7HQ+vR+mi/XyIuPH3Mboc7nxAw3F2rpRyH3+6uFjBA6iHdoLtS/jeVzdyuXf VbUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776955; x=1747381755; 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=I0Qr/Dx2Mpz9q6UxyEXOpqASgzXyh5bvBW29AbGoUfc=; b=em0MEer4d/gj/fWLjOicuo/0DGQyhMfAsrU7p28Lt4qawnFv1OBvyn5oWif6b7YLr/ wu10yEIpOtbTV7zSqp7dCM+n5TPwyn+yJfb58r5k57XDPmtGCj8GLalIslm1qW5+S9vn 6mRpAHXw52xeAggA9ddHaGdrmxqYDz2d5d3XHnCaIt0QqWuN68ThOKYFxb5ubwCBKNXs ugKqVkZmiyKTmEK0SfUdaAXqPnDiBG8nZCZThZ4cZcbNK0thIpUR55kdJO+Dwtdm5P2t g6DJ5dZyx/0C7eDWAFORDZ2H91DcWxdlEZqETkXDpFLB5oTOqs5LCvXyQ3Hl/DPSZS8J Tyxg== X-Forwarded-Encrypted: i=1; AJvYcCV6SlmHOtH53U2rB168UcVW3JC+b27BPBJQr1/+jdfN83RaUEDjrXxDMaeZqRgkGY5qsN7nfvkljJ4b1nU=@vger.kernel.org, AJvYcCWDV670Y+P0iUAFGFzML+AiB38Xr2wp3cdxrbxEVgqcGE/K8eQQMgQQEGTrxFSkjKYqmdCylWoegs8ByFQL1e6Dy44eNg==@vger.kernel.org X-Gm-Message-State: AOJu0YwzZrr8fVxwPd0pMIz2ga7y+u/lX+pph6dHqfgEPqbiX743WOME BYeZ1OFav7MHaB7UrN6YqLle7TTI1l4YS6ZpRh5kjh9T2s29M+nC X-Gm-Gg: ASbGncv6DI1iCYtHwTYZdNIapvY9k9lRUcBeXhg/lvhH+LNIW0oGKHqdAjC1olOsgbL 9RmckfDmKzDhg6Eo1wpESmYh8enh2Li5lOU73trA9f1BlQy/GBe2ehedLOX2igI6PDyGhwWYmrO p4rDIKEyQm5KwAP8DHm24I+41FzikelFvvQsWi91uygq7q1Rbm/X7PBECsAz65eXBGN3ygfSHTO V7ztr+RONvxMU/I1CpnROYFpjtw3dLj+JjhZN3bEsBZg+u5OFPhNm9CKhths5kaSQbzr13jqotj Gx8pkCIzVaZl2mLLhmzn0joESCXl/swpmVOJacoHyBMMhZwiSq8= X-Google-Smtp-Source: AGHT+IEvyGOw+PpFZVA8mGRWI3dO+d4jJXn8bisKljR4euFo6qCqbKdB/hbtVsIvlqf3IB3qeQE9og== X-Received: by 2002:a05:6102:8006:b0:4cb:5d6e:e6c8 with SMTP id ada2fe7eead31-4deed33c1abmr1928239137.9.1746776954585; Fri, 09 May 2025 00:49:14 -0700 (PDT) Received: from [192.168.1.26] ([181.91.133.137]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-879f62986f3sm678265241.33.2025.05.09.00.49.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 00:49:14 -0700 (PDT) From: Kurt Borja Date: Fri, 09 May 2025 04:48:34 -0300 Subject: [PATCH RFC 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: <20250509-fw-attrs-api-v1-2-258afed65bfa@gmail.com> References: <20250509-fw-attrs-api-v1-0-258afed65bfa@gmail.com> In-Reply-To: <20250509-fw-attrs-api-v1-0-258afed65bfa@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=19553; i=kuurtb@gmail.com; h=from:subject:message-id; bh=zqJFSCx7AUWfbriM3zIDxSBZnylClDLryW6FMC+feiA=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBmym3M0HZZXtt9y1i2f9eDeskjmpKigm+GLqr+9Y/mr+ fzT7nOfOkpZGMS4GGTFFFnaExZ9exSV99bvQOh9mDmsTCBDGLg4BWAiJpGMDM9l2gNquH9O23xD ++rhbRf29RiVWG/RY+q91eh9Iuql1iqG/1lTt8tP9T965CNvs6yooS/XabNkrj8suk7W8/yfzTx sxgYA 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 | 249 +++++++++++++++++++= +++- drivers/platform/x86/firmware_attributes_class.h | 228 +++++++++++++++++++= ++ 2 files changed, 474 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/pla= tform/x86/firmware_attributes_class.c index 58ab1495ba3bd449cfe17de2827a57a0c5937788..7cfb0f49f235728c7450a82a7e9= d00b8963d3dea 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -7,14 +7,233 @@ #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->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 char *str; + long int_val; + int ret; + + switch (config->type) { + case fwat_type_integer: + ret =3D config->ops->integer_read(dev, config->aux, &int_val); + if (ret) + return ret; + + return sysfs_emit(buf, "%ld\n", int_val); + case fwat_type_string: + ret =3D config->ops->string_read(dev, config->aux, &str); + if (ret) + return ret; + + return sysfs_emit(buf, "%s\n", str); + case fwat_type_enumeration: + ret =3D config->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; + long int_val; + int ret; + + switch (config->type) { + case fwat_type_integer: + ret =3D kstrtol(buf, 0, &int_val); + if (ret) + return ret; + + ret =3D config->ops->integer_write(dev, config->aux, int_val); + break; + case fwat_type_string: + ret =3D config->ops->string_write(dev, config->aux, buf); + break; + case fwat_type_enumeration: + ret =3D config->ops->enumeration_write(dev, config->aux, buf); + 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; + unsigned int index =3D 0; + + attrs =3D devm_kcalloc(dev, config->num_props + 3, sizeof(*attrs), GFP_KE= RNEL); + if (!attrs) + return NULL; + + /* + * Create optional attributes + */ + for (; index < config->num_props; index++) { + prop =3D config->props[index]; + attrs[index] =3D fwat_alloc_attr(dev, config, fwat_prop_labels[prop], + 0444, prop, fwat_property_show, NULL); + } + + /* + * Create mandatory attributes + */ + attrs[index++] =3D fwat_alloc_attr(dev, config, "type", 0444, 0, fwat_typ= e_show, NULL); + attrs[index++] =3D fwat_alloc_attr(dev, config, "current_value", 0644, 0, + fwat_current_value_show, fwat_current_value_store); + + 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) { @@ -61,6 +280,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 * @@ -72,8 +292,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; @@ -97,19 +319,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 @@ -125,6 +364,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); @@ -143,6 +384,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 * @@ -156,12 +398,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..f250875d785c3439682c43c693f= 98e1c20e9ff54 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,238 @@ 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 fwat_attr_ops - Operations for a firmware *attribute* + * @prop_read: Callback for retrieving each configured property of an attr= ibute. + * @integer_read: Callback for reading the current_value of an attribute of + * type *integer*. + * @integer_write: Callback for writing the current_value of an attribute = of + * type *integer*. + * @string_read: Callback for reading the current_value of an attribute of= type + * *string*. + * @string_write: Callback for writing the current_value of an attribute o= f type + * *string*. + * @enumeration_read: Callback for reading the current_value of an attribu= te of + * type *enumeration*. + * @enumeration_write: Callback for writing the current_value of an attrib= ute + * of type *enumeration*. + */ +struct fwat_attr_ops { + ssize_t (*prop_read)(struct device *dev, long aux, + enum fwat_property prop, const char *buf); + union { + struct { + int (*integer_read)(struct device *dev, long aux, + long *val); + int (*integer_write)(struct device *dev, long aux, + long val); + }; + struct { + int (*string_read)(struct device *dev, long aux, + const char **str); + int (*string_write)(struct device *dev, long aux, + const char *str); + }; + struct { + int (*enumeration_read)(struct device *dev, long aux, + const char **str); + int (*enumeration_write)(struct device *dev, long aux, + const char *str); + }; + }; +}; + +/** + * struct fwat_attr_config - Configuration for a single firmware *attribut= e* + * @name: Name of the sysfs group associated with this *attribute*. + * @type: Type of this *attribute*. + * @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; + enum fwat_attr_type type; + 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##_read =3D _name##_read, \ + ._type##_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 { \ + .prop_read =3D _name##_prop_read, \ + ._type##_read =3D _name##_read, \ + ._type##_write =3D _name##_write, \ + } + +/** + * FWAT_CONFIG() - Configuration pointer for a single firmware *attribute*. + * @_name: String name of this *attribute*. + * @_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, _type, _ops, _props, _num_props) \ + (&(const struct fwat_attr_config) { \ + .name =3D _name, \ + .type =3D fwat_type_##_type, \ + .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*. + * @_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, _type, _aux, _ops, _props, _num_props) \ + (&(const struct fwat_attr_config) { \ + .name =3D _name, \ + .type =3D fwat_type_##_type, \ + .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 Sat Feb 7 18:20:39 2026 Received: from mail-vk1-f179.google.com (mail-vk1-f179.google.com [209.85.221.179]) (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 81A7A26AA86; Fri, 9 May 2025 07:49:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776962; cv=none; b=UrsYOvrHif5V3Xfuus0C5dlfQRmbulfkwBc9NmHZJ+mQYgBlRPyS2h41EB+AspToBXyIc4AVRUZoAppJorVQPnFcly3hOTvKA1dG2fVdYkQI0a23IlXZf5SSHpf3X8jUSPpYRbmkvpfJQmbRvVB1jV8I4O2piy4t/Ub0p82PD/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776962; c=relaxed/simple; bh=0mI/bIClotmAIMEue5Uh6KbwoJ+g9tFgZQBd+jg7Spg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TsUZLbnO9LtLoiCQr5z5d4U03IVR7rZSX9Uv+N0Q1wOmErhIibmmtQDzc+fe+kRyt1sx36dZpQEFillMDxJV/FeI7dsV8HbqPqYXYaqFj+Ug8KPwekvtCUHQoKbr6T0pETIUpQPyOHdYU560F9HNiGugrrszF4kvSa4XWIAcrTI= 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=ScPJHkM7; arc=none smtp.client-ip=209.85.221.179 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="ScPJHkM7" Received: by mail-vk1-f179.google.com with SMTP id 71dfb90a1353d-523f670ca99so604730e0c.1; Fri, 09 May 2025 00:49:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746776959; x=1747381759; 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=E1RzP8Nae7C+98McQ5BCAJ1tDJLogzrgZIHRK1qrkfg=; b=ScPJHkM7HqMcWWbJw4DRDwIuHq1d7WO91CMBt1o6hsUyl6Xr6szh90kXVW/cbr6hb2 nyhGORoQjpK29yzGvPFf0Ld4PfDcNAuay4GmAO73zkl6BBFykC9yXorcsCYhqj9+hpce mpOhp5vTQVSEOD8JFX6lLJy7Hb+2p+92/jbGygcZ6TO/nXYhFLEjc6Om2G7ov4KcB0aq lZHycUfYu4Nce6NFU15MFjyDYPPb1n0/xC9CYJAJoSP4lLi8VIHyjkmlXflxunTs/sI+ rANwI4FJum7EhkE2LWPdtpZCiPYbwMDRUo35NWkYTE2PCqRORajhw4LmQUtSP+jL4Kcf U/7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776959; x=1747381759; 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=E1RzP8Nae7C+98McQ5BCAJ1tDJLogzrgZIHRK1qrkfg=; b=RHTIeHCKnB16KhAB+cVP9g9HSr85uDoZB9U2GUoXTRrGALCRFBgTj/xCXZi1xawKOo ByX7t0PJh1o9fh44mKYrehoJxtda1V6Vhm612Q7LCVjA7qrCZYBU5lEA2L+HCSeDPwcf 336MMeSGIfg2m7vaZw8BWImTEdORF29tLQGOCmXOknwNYviRqfNT6Brew+CkEttwq9tj hvrgvR3OJZ6wnmjdNLm0fCiE37RwU8HoHBdLDQZiT+9oS8ejr7mRkGu7xt/gyRcLUSMX PWQNhnzxkpqarV0fDO3chm/IBowom8QIXpaEWjVv8lrb61zZZgLlJaeBU2uFUV/+tnR9 KpBA== X-Forwarded-Encrypted: i=1; AJvYcCV1/1/IkDQj7PmfmcLjmp0NM+wo9OEosVmNA58QEX9eaXssa6znUXwXjTuh9ikUCTNyGlApBLmyJ4tXBvU=@vger.kernel.org, AJvYcCXSsZTayU+HjGV2lgNvM0zzL1NwHr3QrrmJ7wXv/1LuGhKJlDHJT0WZMs5rUKUa+W6FND8Xe42uIVjRvQOWLnr5XSzCgw==@vger.kernel.org X-Gm-Message-State: AOJu0YzNNcHNxEvBAdT0GX+cCnEGb8U2iGLK4ICI5lAtXtm8BUUjreFi NJ65A7SH1PV1mZ/bXumaJN5dPJP49EqM2+ArrLbIL3OQudg/t/HU X-Gm-Gg: ASbGnctrPHei/g8bCgh9EV72XrUawLUja96JZiZzXVwZyziyYVdC7kPRjPokQigl1F1 djWcJvoBExyPLV4JIE5NeaLhOEnThSRjbfi6AWmasHQ9ETZLSk5trHZtVgJgOo49uU+4pXq8NSC 6mvUYrnbIgV3QDEK7eQMCE5g3EWfUNaoBVwXeGG6jkPwnO8HsffkQcXGo5xCjTqow1vXCBb2r1M p8bi6x37SkMBwjQDRxtwOgCWvAkhKPJtNZoMr9mcba2LlSbSkHwufsex6Yes7gkSyF9LQMG5tSS 7UkFAy/oLTL/vMfrJNvwBPkncPOQr18RTxk/c0Rz X-Google-Smtp-Source: AGHT+IFdh3K8D/AsAmUV7aiJ3n2dUD0gZY0HWzhfepUoUEOQIyN3FiLcjdCcIyhy8JuMkPAR9vx0VQ== X-Received: by 2002:a05:6122:45a1:b0:520:af9c:c058 with SMTP id 71dfb90a1353d-52c53b7f396mr2104851e0c.5.1746776959286; Fri, 09 May 2025 00:49:19 -0700 (PDT) Received: from [192.168.1.26] ([181.91.133.137]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-879f62986f3sm678265241.33.2025.05.09.00.49.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 00:49:18 -0700 (PDT) From: Kurt Borja Date: Fri, 09 May 2025 04:48:35 -0300 Subject: [PATCH RFC 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: <20250509-fw-attrs-api-v1-3-258afed65bfa@gmail.com> References: <20250509-fw-attrs-api-v1-0-258afed65bfa@gmail.com> In-Reply-To: <20250509-fw-attrs-api-v1-0-258afed65bfa@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=4584; i=kuurtb@gmail.com; h=from:subject:message-id; bh=0mI/bIClotmAIMEue5Uh6KbwoJ+g9tFgZQBd+jg7Spg=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBmym3M+q23cdt2n5GiH9IwDKSIVq254Gy39UFHftOPro W/mn1pUO0pZGMS4GGTFFFnaExZ9exSV99bvQOh9mDmsTCBDGLg4BWAicyYx/C9acflwYQvLgtbl gS4zRbVTNH5EpOsv1nU8ftxH8J0h6xyG/5k8XUYbC65dTz1RuHlW1vNFqWLPztTGimoot18X6xU o4AUA 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 | 16 ++++++++++++= ++++ drivers/platform/x86/firmware_attributes_class.h | 11 +++++++++++ 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 7cfb0f49f235728c7450a82a7e9d00b8963d3dea..13b10a1209be726b00fa1ebad61= 48778e165101e 100644 --- a/drivers/platform/x86/firmware_attributes_class.c +++ b/drivers/platform/x86/firmware_attributes_class.c @@ -26,6 +26,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", }; @@ -72,6 +73,7 @@ fwat_current_value_show(struct device *dev, const struct = fwat_attribute *attr, c const struct fwat_attribute_ext *ext =3D to_fwat_attribute_ext(attr); const struct fwat_attr_config *config =3D ext->config; const char *str; + bool bool_val; long int_val; int ret; =20 @@ -82,6 +84,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: ret =3D config->ops->string_read(dev, config->aux, &str); if (ret) @@ -105,6 +113,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; + bool bool_val; long int_val; int ret; =20 @@ -116,6 +125,13 @@ fwat_current_value_store(struct device *dev, const str= uct fwat_attribute *attr, =20 ret =3D config->ops->integer_write(dev, config->aux, int_val); break; + case fwat_type_boolean: + ret =3D kstrtobool(buf, &bool_val); + if (ret) + return ret; + + ret =3D config->ops->boolean_write(dev, config->aux, bool_val); + break; case fwat_type_string: ret =3D config->ops->string_write(dev, config->aux, buf); break; diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/pla= tform/x86/firmware_attributes_class.h index f250875d785c3439682c43c693f98e1c20e9ff54..d95d2024b0d9630ee3750ec26e1= 8874965ec5cff 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, }; @@ -77,6 +78,10 @@ struct fwat_attr_config; * type *integer*. * @integer_write: Callback for writing the current_value of an attribute = of * type *integer*. + * @boolean_read: Callback for reading the current_value of an attribute o= f type + * *boolean*. + * @boolean_write: Callback for writing the current_value of an attribute = of + * type *boolean*. * @string_read: Callback for reading the current_value of an attribute of= type * *string*. * @string_write: Callback for writing the current_value of an attribute o= f type @@ -96,6 +101,12 @@ struct fwat_attr_ops { int (*integer_write)(struct device *dev, long aux, long val); }; + struct { + int (*boolean_read)(struct device *dev, long aux, + bool *val); + int (*boolean_write)(struct device *dev, long aux, + bool val); + }; struct { int (*string_read)(struct device *dev, long aux, const char **str); --=20 2.49.0 From nobody Sat Feb 7 18:20:39 2026 Received: from mail-vs1-f47.google.com (mail-vs1-f47.google.com [209.85.217.47]) (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 2DED22749EA; Fri, 9 May 2025 07:49:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776966; cv=none; b=CUDygamxvK1MVAaf/jIGQIsZ5B9cbw8NO8enqu260cSZO42ioQTziLzBzjcjUI38Inv5uW1ErZRZt1S6NHZL57HGenmQOv3krW7kunPvGkr9AKqbfXyfezOYmZYXfnkE4tzNv/G7iQ5rdIpEWKR4uR/G+PDa/geVynD5D033DFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776966; c=relaxed/simple; bh=ESzEa2XBYeCXCYfZ5PnQ+bede9o4BuhRrBkVwojeH30=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MusBt2zRi17XrdsQ18kwpH/MeVw68CdTfVVNQBoTtnAjPl5HkNA+EV+qUOGsSErAjCLfgKyu2aVAAEdc6ad0Y6MV6+tf5cKHUal7UfcV+TjSVcxai+clCfE3JTP5gFVV7bH45KU5SQ55gkvtJ8zux7MlPGXfNHDGGgfat2OHTOg= 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=g9/p8K8w; arc=none smtp.client-ip=209.85.217.47 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="g9/p8K8w" Received: by mail-vs1-f47.google.com with SMTP id ada2fe7eead31-4c34dcdaf88so611014137.2; Fri, 09 May 2025 00:49:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746776964; x=1747381764; 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=/phAatFkBAwQ5t8wNBWoDLE6oTpZIJwGQghZ3e9clt4=; b=g9/p8K8w0EHzKZ6KIQf6YD6Oi/pev1bNeuNpZuQ42oK8vfnpQNIOO4hGi+nAcezpBP GLMsgrZ0i+VjSRInf1FRVlmc40tbBToy+dAStiF9AUpe3lH57qkRUH2lV9Qsbw4gKJGf IUyznhx8kuk293bRsBIROrFIdyD0iBTlsA/FxipBFqKSSxz3OVEHqwIUFBL/JaeZA0xx fTQc5zRcElpB/tRJG2M4qGBxWv5sg4UxM4hAw09VAZXQFwtNQEUkG2hUwQFQHkEYUL65 0xl8XWOwzH2TUnrWlyQ0EcEs2+g4tOGzILH5ld2yMWUISoE3MIIFJD9ShrIQ9uIcLV8Z 5mMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776964; x=1747381764; 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=/phAatFkBAwQ5t8wNBWoDLE6oTpZIJwGQghZ3e9clt4=; b=OL7isJ2hDWWOBcvUFeKH+aHfYuYeTQ1GvpF6VtMovPxvcGL3q8mWTNFiPlipW0aVfa LlHNzAmiZUV6SHnQ8GcV5a93rn57uIBRSIMJQy6+B/hXWPR9J2gGR3A0f3UhiasoSkok W46AXPTo6nQEzeS2hoaoCCLpEN94TqNMQxlfeL0yQY1J1/pMgMSOmuHe5ikZT4xKdPb9 xqtOe+XE7tf3gj9Rf2FFd+E4NMLC6q5jhJbvaOSzHtZBJV4nSHrtlmUSqyQ9es/Z6ZJA cGDruS9wsvb6VdMQveMEHI9NCLEv32WwUJlclz+frk6Rq27sKSTF4uC+L2u2ECRROZt+ zyyw== X-Forwarded-Encrypted: i=1; AJvYcCWzsmmdPzJ5jXX0ITEtOllRwKT7KC8IaYsfDVh+zNczNautI8XmMyQw5DINfl3UiEuIU6pKMEK136ZooN0W/Cc+Jp1S0w==@vger.kernel.org, AJvYcCX6hj5CO4KC4KzWcB/TSng4sATPX0vF9ecVGGqLY69po71DidXAkaO/xd1aKQgjoZWRLcs2rtG6Fpxawgc=@vger.kernel.org X-Gm-Message-State: AOJu0YzcEhIPGKSEwm6bI13+Oe+x6IBM2pR7DG3eyxsuweEbPVgqpCUO LMaT0KAzSewj1P0pDdtOKDVHfV6upjEYAseMd61DBg/XSHdExnqQ X-Gm-Gg: ASbGnct///1XFkdc0751TFbQ+Em+owYI8LwnF1o1IWhGnBNmm8PpA7aYQfh5twMAN1U jkuFurZjx7eZZsm0QLYV7d6wUl4d3x4iZJGVk2KY5G2qyam7YYeytDnhW0IUjm74R+zktviArXV tLxwErPJN6F8ds4W9rAmRNsHYntQmDoPDVxRotXK3NrMAfFHOjVdX0NG5sq9GANbnZPrvx3WmxG +BHgAvpTvn0gTGAREoMVCeqztctl9i+WxPZ0LJeRTulrUwf1DjnhHEoNdSknKr54ZN5JI6hJX2E sice2o51DI3BEn46FfP2tjK8q8z6ETRSGaAhgezj X-Google-Smtp-Source: AGHT+IEV2wUxDT4UZ7wEWbIKRaAtnNbGm5X6GYvdQjajcMwDG6DRQ4uWU/Wuk+dtBnlr2TeUERl47A== X-Received: by 2002:a05:6102:8097:b0:4c1:774b:3f7a with SMTP id ada2fe7eead31-4deed3d4b5bmr1629019137.16.1746776963975; Fri, 09 May 2025 00:49:23 -0700 (PDT) Received: from [192.168.1.26] ([181.91.133.137]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-879f62986f3sm678265241.33.2025.05.09.00.49.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 00:49:23 -0700 (PDT) From: Kurt Borja Date: Fri, 09 May 2025 04:48:36 -0300 Subject: [PATCH RFC 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: <20250509-fw-attrs-api-v1-4-258afed65bfa@gmail.com> References: <20250509-fw-attrs-api-v1-0-258afed65bfa@gmail.com> In-Reply-To: <20250509-fw-attrs-api-v1-0-258afed65bfa@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=ESzEa2XBYeCXCYfZ5PnQ+bede9o4BuhRrBkVwojeH30=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBmym3PMjCYfYzsRI/P8btaEEz9+6Dhtf+182i3D3MPza qjgIp2rHaUsDGJcDLJiiiztCYu+PYrKe+t3IPQ+zBxWJpAhDFycAjCRtWsZGXaf5dzGZPla4MPP xKBwvuhH8nHFbrw+C7I1v9nNCTRkm87wP/bIu9JgTdWL/Sw/PuqfkXCT5d+/r8kl/FTQI/n3h2L V+QE= 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 f9417b4e9bafd1a4033bba2fdb4a4e6fb68cf219..c4adad420a8ffee7bc7624d3edc= 8ba36aec5cb40 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 Sat Feb 7 18:20:39 2026 Received: from mail-ua1-f42.google.com (mail-ua1-f42.google.com [209.85.222.42]) (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 8F11C2750E5; Fri, 9 May 2025 07:49:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776972; cv=none; b=BGz4OUFjqldaNcBLZ4G99vqrBuysguyeIfGgdYSbM4u5Kw1ZTwk/trGtKmLmMLtXVXWpsV6bRDS6goZit848N6gKbjyyVNHzXC4n47HjUG8iUxYkIislRPN/vl5AUlto11fn3FFC+dQnJH8FPHIhdqGlAkc92oxIlTpKPepi4hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746776972; c=relaxed/simple; bh=3tnx6riRAQeIrglRoMr6Z8s06MlFFv8TNLVSX+2GLAM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cYUnuhcqO5ecVG0uxzr6MWfbz1HwKWqsmiUgXD3Xeyzsr38PnqwBkxQvBjtQpRU5BKhXvj9LwpjitmPP0obdejxZlzYe7XQCbSt0BawGLq7zXOqEAnqtpiT8GAjTN88rmk3VJq0anUoclxG6Dr8e14rqzDxd/nuA2LDtDMfFYe0= 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=Q46kwQwe; arc=none smtp.client-ip=209.85.222.42 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="Q46kwQwe" Received: by mail-ua1-f42.google.com with SMTP id a1e0cc1a2514c-86d69774081so513630241.0; Fri, 09 May 2025 00:49:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746776968; x=1747381768; 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=g6s/805+g5ODaCP8r7aEFUxhD+7/pjJZZQYcqbKPPG0=; b=Q46kwQwenRgcTUwFhC3Q/0zfHwKlfV6jsnB9wcisjbSBvXxm+t7xUxtWiGGTZK9VaI O6Kp+yOF7ErOO0nh+2YSePzpz0bH6diHnhfXXUSj3HoSTOE2JZrqT2Zmit1HDhEty/qZ byl78uI0SpJJLuhK8W/Le/pSCSXbylSRrxd90uRVQprX7JV2JsFa+fJVjv7eQPbmeyYU a2cEnqsKIIO1qb4x7qf7sPlUXxg4HIqDguKeHl+afKmGl4OQysAan/g5f1CgZv0MPZpc 4vRHWTZsnVZ1pap3nsGOXt9qXWGIs4Ad5CvwrOrSCnSbR4fLL/gghCD4DEcnYPiUfRzG RUcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776968; x=1747381768; 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=g6s/805+g5ODaCP8r7aEFUxhD+7/pjJZZQYcqbKPPG0=; b=VGNap+GjlfbZJ99roCwPCmhXECkthlOOTvWkPnX0OCVi+sPpNR5RKJCnibF8Caimmb jC7wk9Mvwp1jqgoEioMSLaq/P3TVWNZsv7OwrUwvLQ55G3VkW2JwMnJZuDl2+PYDZBxE 73nKr/9QOaFbSlj4tAewLvB+2+qsnaqRIrjz7D1FOhX6JBsNCKIMIv4hc8YfYqK7pHWf 7iyapCfrDJeyQ9Ee4bFS69MtxIUo1W+XYFZiA14GxozELpeVUzJOw5TjAFA6SCrwoXPl S/3xybNJP/VCgu8Gye4XVcD/44O4/naHGLJx+2rnG6ASEFO0F8ODHT/paANqey5bi6Iv LVCA== X-Forwarded-Encrypted: i=1; AJvYcCUGNS7kEmsNruHu2VyLKS5yOzCCQwQ1IRNPN9ZJhwFvU/8Z8mqRldAtVc8hbmOr7oIN1lk7dmX0PLSGz0JHdHF1nYbrcQ==@vger.kernel.org, AJvYcCVzgmYJtQLsp2aq0GMpG1NOfisrycHOAl7vupfbA3N/dw7mpereysJZldACU7OemXCgm32upyBkMwZuPIk=@vger.kernel.org X-Gm-Message-State: AOJu0Yzbj/FpICsJyl2unnGkMpFjEsAkuNMNl2W4jE4TlFvWP9sJV9p3 fw1y9haXJIOiffMZYMkdiJd3odxrCI9ZxjkFL/Ij0jXIQ77aCdb4 X-Gm-Gg: ASbGncvtt85p0Xtq22eB4MKmXM8gOF4jvV+rxnrjr04pZ4DQfIlgQxTup6qUWYFLa/I hyTGXfEKpJTjFJuChC/DSE4bVuu2/c2j6FCqM7qFnrEavFvU6wBg0nhkEnCyjqXuI2bc5vmtL57 9+5LIkP4nFBkQxTKMhijuVv+A5ktXZ+dR4jwltQ6OpVNr7PtqSs0RyRGlCHMP0vF9oS95oDOzhu J0/kxaHbOuK4OUCUww0mtx1Ygl06LAwhDfVanJpK3XSm7NeNrepMX9TE/kIIe8GpFKPNWrVtK9d ezgdXvj4zHa0Izvl/RerNc0UNEnPG2PrO4PJDOtD X-Google-Smtp-Source: AGHT+IGuHXVEFiPliN8mTIFTGOgHCymHxlz2oF5wubFos1dR5K1wUCF1bmrubLebt0FboBApbB3PzA== X-Received: by 2002:a05:6102:15a0:b0:4c3:64be:5983 with SMTP id ada2fe7eead31-4deed3ee64emr2193937137.25.1746776968249; Fri, 09 May 2025 00:49:28 -0700 (PDT) Received: from [192.168.1.26] ([181.91.133.137]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-879f62986f3sm678265241.33.2025.05.09.00.49.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 May 2025 00:49:27 -0700 (PDT) From: Kurt Borja Date: Fri, 09 May 2025 04:48:37 -0300 Subject: [PATCH RFC 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: <20250509-fw-attrs-api-v1-5-258afed65bfa@gmail.com> References: <20250509-fw-attrs-api-v1-0-258afed65bfa@gmail.com> In-Reply-To: <20250509-fw-attrs-api-v1-0-258afed65bfa@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=11575; i=kuurtb@gmail.com; h=from:subject:message-id; bh=3tnx6riRAQeIrglRoMr6Z8s06MlFFv8TNLVSX+2GLAM=; b=owGbwMvMwCUmluBs8WX+lTTG02pJDBmym3MZrFTSNELjn/u/289cULB47wnPHxE7I14GOjTfE ol7JCjQUcrCIMbFICumyNKesOjbo6i8t34HQu/DzGFlAhvCxSkAE5lZwPDPWE3yanlu3aaa2aWN gosPXPQ52/ppouukMNbagIe8CcW7GBneLtdfePP+R77++jcLK57O2ajKtGPmXR7GFu/e7HOBJfV sAA== 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 | 299 ++++++++++++--------------= ---- 1 file changed, 114 insertions(+), 185 deletions(-) diff --git a/drivers/platform/x86/samsung-galaxybook.c b/drivers/platform/x= 86/samsung-galaxybook.c index 5878a351993eb05a4c5c2c75b4915d972ce9becc..4fe3601fa5d282e7f8ae0a9b7e9= 73da0998a5a72 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,146 @@ 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, bool *val) { - 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); + *val =3D value; + + 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, bool val) { - 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); + int 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, const char *buf) +{ + switch (prop) { + case FWAT_PROP_DISPLAY_NAME: + return sysfs_emit("%s\n", galaxybook_fwat_desc[aux]); + case FWAT_PROP_LANGUAGE_CODE: + return sysfs_emit("%s\n", GB_ATTR_LANGUAGE_CODE); + case FWAT_PROP_DEFAULT: + return sysfs_emit("%d\n", 0); + default: + return -EOPNOTSUPP; + } +} + +DEFINE_FWAT_OPS(galaxybook_fwat, boolean); + +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, +}; =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", boolean, + GB_ATTR_POWER_ON_LID_OPEN, + &galaxybook_fwat_ops, + galaxybook_fwat_props, + ARRAY_SIZE(galaxybook_fwat_props)), + FWAT_CONFIG_AUX("usb_charging", boolean, + GB_ATTR_USB_CHARGING, + &galaxybook_fwat_ops, + galaxybook_fwat_props, + ARRAY_SIZE(galaxybook_fwat_props)), + FWAT_CONFIG_AUX("block_recording", boolean, + 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 +1318,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