프로젝트를 봐야 한다.
http://kernelnewbies.org
그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저
-아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할수있는 도움이
-될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할수 있는 IRC 채널도
+아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할 수 있는 도움이
+될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할 수 있는 IRC 채널도
가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다.
웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들
것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가
드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은
회귀(역자주: 이전에는 존재하지 않았지만 새로운 기능추가나 변경으로 인해
- 생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이
+ 생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이
배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은
공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다.
- 새로운 -rc는 Linus가 현재 git tree가 테스트 하기에 충분히 안정된 상태에
- 의견
- 변경을 위한 요구
- 당위성을 위한 요구
- - 고요
+ - 침묵
기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의
패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고
가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상
어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은
협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면
-ì \81ì\96´ë\8f\84 ì\97¬ë\9f¬ë¶\84ì\9d\98 ê²\83ì\9d´ ê°\80ì¹\98ì\9e\88ë\8b¤ë\8a\94 ê²\83ì\9d\84 ì¤\91명하여야 한다. 잘못된 것도 여러분이
+ì \81ì\96´ë\8f\84 ì\97¬ë\9f¬ë¶\84ì\9d\98 ê²\83ì\9d´ ê°\80ì¹\98ì\9e\88ë\8b¤ë\8a\94 ê²\83ì\9d\84 ì¦\9d명하여야 한다. 잘못된 것도 여러분이
올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을
기억하라.
커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의
문제를 피하기 위한 목록이 있다.
여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 :
- - "ì\9d´ê²\83ì\9d\80 ì\97¬ë\9f¬ 문ì \9cë\93¤ì\9d\84 í\95´ê²¹합니다."
- - "ì\9d´ê²\83ì\9d\80 2000 ë\9d¼ì\9d¸ì\9d\98 ì½\94ë\93\9c를 ì \9cê±°í\95©니다."
+ - "ì\9d´ê²\83ì\9d\80 ì\97¬ë\9f¬ 문ì \9cë\93¤ì\9d\84 í\95´ê²°합니다."
+ - "ì\9d´ê²\83ì\9d\80 2000 ë\9d¼ì\9d¸ì\9d\98 ì½\94ë\93\9c를 ì¤\84ì\9e\85니다."
- "이것은 내가 말하려는 것에 관해 설명하는 패치입니다."
- - "나는 5개의 다른 아키텍쳐에서 그것을 테스트했슴으로..."
- - "ì\97¬ê¸°ì\97\90 ì\9d¼ë ¨ì\9d\98 ì\9e\91ì\9d\80 í\8c¨ì¹\98ë\93¤ì\9d´ ì\9e\88ì\8a´ì\9d\8c로..."
- - "이것은 일반적인 머신에서 성능을 향상시킴으로..."
+ - "나는 5개의 다른 아키텍쳐에서 그것을 테스트 했으므로..."
+ - "ì\97¬ê¸°ì\97\90 ì\9d¼ë ¨ì\9d\98 ì\9e\91ì\9d\80 í\8c¨ì¹\98ë\93¤ì\9d´ ì\9e\88ì\9c¼ë¯\80로..."
+ - "이것은 일반적인 머신에서 성능을 향상함으로..."
여러분들이 말할 때 피해야 할 좋지 않은 것들 :
- - "ì\9a°ë¦¬ë¥¼ ê·¸ê²\83ì\9d\84 AIT/ptx/Solarisì\97\90ì\84\9c ì\9d´ë\9f¬í\95\9c ë°©ë²\95ì\9c¼ë¡\9c í\96\88ë\8b¤. ê·¸ë\9f¬ë¯\80ë¡\9c ê·¸ê²\83ì\9d\80 ì¢\8bì\9d\80 ê²\83ì\9e\84ì\97\90 í\8b\80립없다..."
+ - "ì\9a°ë¦¬ë\8a\94 ê·¸ê²\83ì\9d\84 AIX/ptx/Solarisì\97\90ì\84\9c ì\9d´ë\9f¬í\95\9c ë°©ë²\95ì\9c¼ë¡\9c í\96\88ë\8b¤. ê·¸ë\9f¬ë¯\80ë¡\9c ê·¸ê²\83ì\9d\80 ì¢\8bì\9d\80 ê²\83ì\9e\84ì\97\90 í\8b\80림없다..."
- "나는 20년동안 이것을 해왔다. 그러므로..."
- "이것은 돈을 벌기위해 나의 회사가 필요로 하는 것이다."
- "이것은 우리의 엔터프라이즈 상품 라인을 위한 것이다."
- "여기에 나의 생각을 말하고 있는 1000 페이지 설계 문서가 있다."
- "나는 6달동안 이것을 했으니..."
- - "여기에 5000라인 짜리 패치가 있으니..."
+ - "여기에 5000 라인 짜리 패치가 있으니..."
- "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..."
- "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다."
또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들을 포함하는
패치들은 받아들여지지 않을 것이라는 점을 유념하라.
+
변경을 정당화해라
-----------------
---------------------------------
리눅스 커널 드라이버를 계속해서 메인 커널 트리에 반영하지 않고
-ì\9c ì§\80ë³´ì\88\98í\95\98ë ¤ê³ í\95\98ë\8a\94 ì\82¬ë¦\84들과 이 문제를 논의하게 되면 훨씬 더
+ì\9c ì§\80ë³´ì\88\98í\95\98ë ¤ê³ í\95\98ë\8a\94 ì\82¬ë\9e\8c들과 이 문제를 논의하게 되면 훨씬 더
"논란의 여지가 많은" 주제가 될 것이다.
리눅스 커널 개발은 끊임없이 빠른 속도로 이루어지고 있으며 결코
느슨해진 적이 없다. 커널 개발자들이 현재 인터페이스들에서 버그를
-발견하거나 무엇인가 할수 있는 더 좋은 방법을 찾게 되었다고 하자.
+발견하거나 무엇인가 할 수 있는 더 좋은 방법을 찾게 되었다고 하자.
그들이 발견한 것을 실행한다면 아마도 더 잘 동작하도록 현재 인터페이스들을
수정하게 될 것이다. 그들이 그런 일을 하게되면 함수 이름들은 변하게 되고,
구조체들은 늘어나거나 줄어들게 되고, 함수 파라미터들은 재작업될 것이다.
동작하는 것을 보장한다.
메인 커널 트리에 여러분의 드라이버를 반영하면 얻게 되는 장점들은 다음과 같다.
- - ê´\80리ì\9d\98 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다.
+ - ê´\80리ì\97\90 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다.
- 다른 개발자들이 여러분의 드라이버에 기능들을 추가 할 것이다.
- 다른 사람들은 여러분의 드라이버에 버그를 발견하고 수정할 것이다.
- 다른 사람들은 여러분의 드라이버의 개선점을 찾을 줄 것이다.
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support.
+ initially work for you.
config ATAGS_PROC
bool "Export atags in procfs"
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
config CRASH_DUMP
bool "kernel crash dumps"
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
config CRASH_DUMP
bool "Kernel crash dumps"
return len;
}
+static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill);
-static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr,
+static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr,
char *buf)
{
struct vpe *vpe = get_vpe(tclimit);
return sprintf(buf, "%d\n", vpe->ntcs);
}
-static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
+static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
struct vpe *vpe = get_vpe(tclimit);
out_einval:
return -EINVAL;
}
+static DEVICE_ATTR_RW(ntcs);
-static struct device_attribute vpe_class_attributes[] = {
- __ATTR(kill, S_IWUSR, NULL, store_kill),
- __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs),
- {}
+static struct attribute vpe_attrs[] = {
+ &dev_attr_kill.attr,
+ &dev_attr_ntcs.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(vpe);
static void vpe_device_release(struct device *cd)
{
.name = "vpe",
.owner = THIS_MODULE,
.dev_release = vpe_device_release,
- .dev_attrs = vpe_class_attributes,
+ .dev_groups = vpe_groups,
};
struct device vpe_device;
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
config CRASH_DUMP
bool "Build a kdump crash kernel"
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
config CRASH_DUMP
bool "kernel crash dumps (EXPERIMENTAL)"
#define topology_core_id(cpu) (cpu)
#define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask)
#define topology_thread_cpumask(cpu) cpumask_of(cpu)
-
-/* indicates that pointers to the topology struct cpumask maps are valid */
-#define arch_provides_topology_pointers yes
#endif
#endif /* _ASM_TILE_TOPOLOGY_H */
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
config CRASH_DUMP
bool "kernel crash dumps"
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
-
-/* indicates that pointers to the topology cpumask_t maps are valid */
-#define arch_provides_topology_pointers yes
#endif
static inline void arch_fix_phys_package_id(int num, u32 slot)
}
static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
-static ssize_t show_image(struct file *file, struct kobject *kobj,
+static ssize_t image_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t off, size_t count)
{
memcpy(buf, attr->private + off, count);
return count;
}
-static struct bin_attribute image_attr = {
- .attr = {
- .name = "image",
- .mode = S_IRUGO,
- },
- .read = show_image,
-};
+static BIN_ATTR_RO(image, 0); /* size gets filled in later */
static struct attribute *bgrt_attributes[] = {
&dev_attr_version.attr,
NULL,
};
+static struct bin_attribute *bgrt_bin_attributes[] = {
+ &bin_attr_image,
+ NULL,
+};
+
static struct attribute_group bgrt_attribute_group = {
.attrs = bgrt_attributes,
+ .bin_attrs = bgrt_bin_attributes,
};
static int __init bgrt_init(void)
if (!bgrt_image)
return -ENODEV;
- sysfs_bin_attr_init(&image_attr);
- image_attr.private = bgrt_image;
- image_attr.size = bgrt_image_size;
+ bin_attr_image.private = bgrt_image;
+ bin_attr_image.size = bgrt_image_size;
bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
if (!bgrt_kobj)
if (ret)
goto out_kobject;
- ret = sysfs_create_bin_file(bgrt_kobj, &image_attr);
- if (ret)
- goto out_group;
-
return 0;
-out_group:
- sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
out_kobject:
kobject_put(bgrt_kobj);
return ret;
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
+extern int driver_add_groups(struct device_driver *drv,
+ const struct attribute_group **groups);
+extern void driver_remove_groups(struct device_driver *drv,
+ const struct attribute_group **groups);
+
+extern int device_add_groups(struct device *dev,
+ const struct attribute_group **groups);
+extern void device_remove_groups(struct device *dev,
+ const struct attribute_group **groups);
+
extern char *make_class_name(const char *name, struct kobject *kobj);
extern int devres_release_all(struct device *dev);
#include <linux/init.h>
#include <linux/string.h>
#include <linux/mutex.h>
+#include <linux/sysfs.h>
#include "base.h"
#include "power/power.h"
static struct kset *bus_kset;
/* Manually detach a device from its associated driver. */
-static ssize_t driver_unbind(struct device_driver *drv,
- const char *buf, size_t count)
+static ssize_t unbind_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
struct bus_type *bus = bus_get(drv->bus);
struct device *dev;
bus_put(bus);
return err;
}
-static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
+static DRIVER_ATTR_WO(unbind);
/*
* Manually attach a device to a driver.
* Note: the driver must want to bind to the device,
* it is not possible to override the driver's id table.
*/
-static ssize_t driver_bind(struct device_driver *drv,
- const char *buf, size_t count)
+static ssize_t bind_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
struct bus_type *bus = bus_get(drv->bus);
struct device *dev;
bus_put(bus);
return err;
}
-static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
+static DRIVER_ATTR_WO(bind);
static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
{
if (!bus->dev_attrs)
return 0;
- for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
+ for (i = 0; bus->dev_attrs[i].attr.name; i++) {
error = device_create_file(dev, &bus->dev_attrs[i]);
if (error) {
while (--i >= 0)
int i;
if (bus->dev_attrs) {
- for (i = 0; attr_name(bus->dev_attrs[i]); i++)
+ for (i = 0; bus->dev_attrs[i].attr.name; i++)
device_remove_file(dev, &bus->dev_attrs[i]);
}
}
error = device_add_attrs(bus, dev);
if (error)
goto out_put;
+ error = device_add_groups(dev, bus->dev_groups);
+ if (error)
+ goto out_groups;
error = sysfs_create_link(&bus->p->devices_kset->kobj,
&dev->kobj, dev_name(dev));
if (error)
out_subsys:
sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
+out_groups:
+ device_remove_groups(dev, bus->dev_groups);
out_id:
device_remove_attrs(bus, dev);
out_put:
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
+ device_remove_groups(dev, dev->bus->dev_groups);
if (klist_node_attached(&dev->p->knode_bus))
klist_del(&dev->p->knode_bus);
int i;
if (bus->drv_attrs) {
- for (i = 0; attr_name(bus->drv_attrs[i]); i++) {
+ for (i = 0; bus->drv_attrs[i].attr.name; i++) {
error = driver_create_file(drv, &bus->drv_attrs[i]);
if (error)
goto err;
int i;
if (bus->drv_attrs) {
- for (i = 0; attr_name(bus->drv_attrs[i]); i++)
+ for (i = 0; bus->drv_attrs[i].attr.name; i++)
driver_remove_file(drv, &bus->drv_attrs[i]);
}
}
bus_remove_file(bus, &bus_attr_drivers_probe);
}
-static ssize_t driver_uevent_store(struct device_driver *drv,
- const char *buf, size_t count)
+static ssize_t uevent_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
enum kobject_action action;
kobject_uevent(&drv->p->kobj, action);
return count;
}
-static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
+static DRIVER_ATTR_WO(uevent);
/**
* bus_add_driver - Add a driver to the bus.
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
+ error = driver_add_groups(drv, bus->drv_groups);
+ if (error)
+ printk(KERN_ERR "%s: driver_create_groups(%s) failed\n",
+ __func__, drv->name);
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (!drv->suppress_bind_attrs)
remove_bind_files(drv);
driver_remove_attrs(drv->bus, drv);
+ driver_remove_groups(drv, drv->bus->drv_groups);
driver_remove_file(drv, &driver_attr_uevent);
klist_remove(&drv->p->knode_bus);
pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name);
int i;
if (bus->bus_attrs) {
- for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
+ for (i = 0; bus->bus_attrs[i].attr.name; i++) {
error = bus_create_file(bus, &bus->bus_attrs[i]);
if (error)
goto err;
int i;
if (bus->bus_attrs) {
- for (i = 0; attr_name(bus->bus_attrs[i]); i++)
+ for (i = 0; bus->bus_attrs[i].attr.name; i++)
bus_remove_file(bus, &bus->bus_attrs[i]);
}
}
+static int bus_add_groups(struct bus_type *bus,
+ const struct attribute_group **groups)
+{
+ return sysfs_create_groups(&bus->p->subsys.kobj, groups);
+}
+
+static void bus_remove_groups(struct bus_type *bus,
+ const struct attribute_group **groups)
+{
+ sysfs_remove_groups(&bus->p->subsys.kobj, groups);
+}
+
static void klist_devices_get(struct klist_node *n)
{
struct device_private *dev_prv = to_device_private_bus(n);
retval = bus_add_attrs(bus);
if (retval)
goto bus_attrs_fail;
+ retval = bus_add_groups(bus, bus->bus_groups);
+ if (retval)
+ goto bus_groups_fail;
pr_debug("bus: '%s': registered\n", bus->name);
return 0;
+bus_groups_fail:
+ bus_remove_attrs(bus);
bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
if (bus->dev_root)
device_unregister(bus->dev_root);
bus_remove_attrs(bus);
+ bus_remove_groups(bus, bus->bus_groups);
remove_probe_files(bus);
kset_unregister(bus->p->drivers_kset);
kset_unregister(bus->p->devices_kset);
int error = 0;
if (cls->class_attrs) {
- for (i = 0; attr_name(cls->class_attrs[i]); i++) {
+ for (i = 0; cls->class_attrs[i].attr.name; i++) {
error = class_create_file(cls, &cls->class_attrs[i]);
if (error)
goto error;
int i;
if (cls->class_attrs) {
- for (i = 0; attr_name(cls->class_attrs[i]); i++)
+ for (i = 0; cls->class_attrs[i].attr.name; i++)
class_remove_file(cls, &cls->class_attrs[i]);
}
}
#include <linux/async.h>
#include <linux/pm_runtime.h>
#include <linux/netdevice.h>
+#include <linux/sysfs.h>
#include "base.h"
#include "power/power.h"
#else
long sysfs_deprecated = 0;
#endif
-static __init int sysfs_deprecated_setup(char *arg)
+static int __init sysfs_deprecated_setup(char *arg)
{
- return strict_strtol(arg, 10, &sysfs_deprecated);
+ return kstrtol(arg, 10, &sysfs_deprecated);
}
early_param("sysfs.deprecated", sysfs_deprecated_setup);
#endif
.uevent = dev_uevent,
};
-static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
+static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct kobject *top_kobj;
return count;
}
-static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
+static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
enum kobject_action action;
dev_err(dev, "uevent: unknown action-string\n");
return count;
}
+static DEVICE_ATTR_RW(uevent);
-static struct device_attribute uevent_attr =
- __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
-
-static ssize_t show_online(struct device *dev, struct device_attribute *attr,
+static ssize_t online_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
bool val;
return sprintf(buf, "%u\n", val);
}
-static ssize_t store_online(struct device *dev, struct device_attribute *attr,
+static ssize_t online_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
bool val;
unlock_device_hotplug();
return ret < 0 ? ret : count;
}
-
-static struct device_attribute online_attr =
- __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
+static DEVICE_ATTR_RW(online);
static int device_add_attributes(struct device *dev,
struct device_attribute *attrs)
int i;
if (attrs) {
- for (i = 0; attr_name(attrs[i]); i++) {
+ for (i = 0; attrs[i].attr.name; i++) {
error = device_create_file(dev, &attrs[i]);
if (error)
break;
int i;
if (attrs)
- for (i = 0; attr_name(attrs[i]); i++)
+ for (i = 0; attrs[i].attr.name; i++)
device_remove_file(dev, &attrs[i]);
}
int i;
if (attrs) {
- for (i = 0; attr_name(attrs[i]); i++) {
+ for (i = 0; attrs[i].attr.name; i++) {
error = device_create_bin_file(dev, &attrs[i]);
if (error)
break;
int i;
if (attrs)
- for (i = 0; attr_name(attrs[i]); i++)
+ for (i = 0; attrs[i].attr.name; i++)
device_remove_bin_file(dev, &attrs[i]);
}
-static int device_add_groups(struct device *dev,
- const struct attribute_group **groups)
+int device_add_groups(struct device *dev, const struct attribute_group **groups)
{
- int error = 0;
- int i;
-
- if (groups) {
- for (i = 0; groups[i]; i++) {
- error = sysfs_create_group(&dev->kobj, groups[i]);
- if (error) {
- while (--i >= 0)
- sysfs_remove_group(&dev->kobj,
- groups[i]);
- break;
- }
- }
- }
- return error;
+ return sysfs_create_groups(&dev->kobj, groups);
}
-static void device_remove_groups(struct device *dev,
- const struct attribute_group **groups)
+void device_remove_groups(struct device *dev,
+ const struct attribute_group **groups)
{
- int i;
-
- if (groups)
- for (i = 0; groups[i]; i++)
- sysfs_remove_group(&dev->kobj, groups[i]);
+ sysfs_remove_groups(&dev->kobj, groups);
}
static int device_add_attrs(struct device *dev)
goto err_remove_type_groups;
if (device_supports_offline(dev) && !dev->offline_disabled) {
- error = device_create_file(dev, &online_attr);
+ error = device_create_file(dev, &dev_attr_online);
if (error)
goto err_remove_type_groups;
}
struct class *class = dev->class;
const struct device_type *type = dev->type;
- device_remove_file(dev, &online_attr);
+ device_remove_file(dev, &dev_attr_online);
device_remove_groups(dev, dev->groups);
if (type)
}
}
-
-static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
+static ssize_t dev_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return print_dev_t(buf, dev->devt);
}
-
-static struct device_attribute devt_attr =
- __ATTR(dev, S_IRUGO, show_dev, NULL);
+static DEVICE_ATTR_RO(dev);
/* /sys/devices/ */
struct kset *devices_kset;
return error;
}
+EXPORT_SYMBOL_GPL(device_create_file);
/**
* device_remove_file - remove sysfs attribute file.
if (dev)
sysfs_remove_file(&dev->kobj, &attr->attr);
}
+EXPORT_SYMBOL_GPL(device_remove_file);
/**
* device_create_bin_file - create sysfs binary attribute file for device.
device_pm_init(dev);
set_dev_node(dev, -1);
}
+EXPORT_SYMBOL_GPL(device_initialize);
struct kobject *virtual_device_parent(struct device *dev)
{
if (platform_notify)
platform_notify(dev);
- error = device_create_file(dev, &uevent_attr);
+ error = device_create_file(dev, &dev_attr_uevent);
if (error)
goto attrError;
if (MAJOR(dev->devt)) {
- error = device_create_file(dev, &devt_attr);
+ error = device_create_file(dev, &dev_attr_dev);
if (error)
goto ueventattrError;
device_remove_sys_dev_entry(dev);
devtattrError:
if (MAJOR(dev->devt))
- device_remove_file(dev, &devt_attr);
+ device_remove_file(dev, &dev_attr_dev);
ueventattrError:
- device_remove_file(dev, &uevent_attr);
+ device_remove_file(dev, &dev_attr_uevent);
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
dev->p = NULL;
goto done;
}
+EXPORT_SYMBOL_GPL(device_add);
/**
* device_register - register a device with the system.
device_initialize(dev);
return device_add(dev);
}
+EXPORT_SYMBOL_GPL(device_register);
/**
* get_device - increment reference count for device.
{
return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL;
}
+EXPORT_SYMBOL_GPL(get_device);
/**
* put_device - decrement reference count.
if (dev)
kobject_put(&dev->kobj);
}
+EXPORT_SYMBOL_GPL(put_device);
/**
* device_del - delete device from system.
if (MAJOR(dev->devt)) {
devtmpfs_delete_node(dev);
device_remove_sys_dev_entry(dev);
- device_remove_file(dev, &devt_attr);
+ device_remove_file(dev, &dev_attr_dev);
}
if (dev->class) {
device_remove_class_symlinks(dev);
klist_del(&dev->knode_class);
mutex_unlock(&dev->class->p->mutex);
}
- device_remove_file(dev, &uevent_attr);
+ device_remove_file(dev, &dev_attr_uevent);
device_remove_attrs(dev);
bus_remove_device(dev);
device_pm_remove(dev);
kobject_del(&dev->kobj);
put_device(parent);
}
+EXPORT_SYMBOL_GPL(device_del);
/**
* device_unregister - unregister device from system.
device_del(dev);
put_device(dev);
}
+EXPORT_SYMBOL_GPL(device_unregister);
static struct device *next_device(struct klist_iter *i)
{
klist_iter_exit(&i);
return error;
}
+EXPORT_SYMBOL_GPL(device_for_each_child);
/**
* device_find_child - device iterator for locating a particular device.
klist_iter_exit(&i);
return child;
}
+EXPORT_SYMBOL_GPL(device_find_child);
int __init devices_init(void)
{
return -ENOMEM;
}
-EXPORT_SYMBOL_GPL(device_for_each_child);
-EXPORT_SYMBOL_GPL(device_find_child);
-
-EXPORT_SYMBOL_GPL(device_initialize);
-EXPORT_SYMBOL_GPL(device_add);
-EXPORT_SYMBOL_GPL(device_register);
-
-EXPORT_SYMBOL_GPL(device_del);
-EXPORT_SYMBOL_GPL(device_unregister);
-EXPORT_SYMBOL_GPL(get_device);
-EXPORT_SYMBOL_GPL(put_device);
-
-EXPORT_SYMBOL_GPL(device_create_file);
-EXPORT_SYMBOL_GPL(device_remove_file);
-
static DEFINE_MUTEX(device_hotplug_lock);
void lock_device_hotplug(void)
struct cpu *cpu = container_of(dev, struct cpu, dev);
int cpuid = dev->id;
int from_nid, to_nid;
- int ret;
+ int ret = -ENODEV;
cpu_hotplug_driver_lock();
from_nid = cpu_to_node(cpuid);
+ if (from_nid == NUMA_NO_NODE)
+ goto out;
+
ret = cpu_up(cpuid);
/*
* When hot adding memory to memoryless node and enabling a cpu
if (from_nid != to_nid)
change_cpu_under_node(cpu, from_nid, to_nid);
+ out:
cpu_hotplug_driver_unlock();
return ret;
}
static DEFINE_MUTEX(cma_mutex);
-static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
+static int __init cma_activate_area(unsigned long base_pfn, unsigned long count)
{
unsigned long pfn = base_pfn;
unsigned i = count >> pageblock_order;
return 0;
}
-static __init struct cma *cma_create_area(unsigned long base_pfn,
+static struct cma * __init cma_create_area(unsigned long base_pfn,
unsigned long count)
{
int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/sysfs.h>
#include "base.h"
static struct device *next_device(struct klist_iter *i)
}
EXPORT_SYMBOL_GPL(driver_remove_file);
-static int driver_add_groups(struct device_driver *drv,
- const struct attribute_group **groups)
+int driver_add_groups(struct device_driver *drv,
+ const struct attribute_group **groups)
{
- int error = 0;
- int i;
-
- if (groups) {
- for (i = 0; groups[i]; i++) {
- error = sysfs_create_group(&drv->p->kobj, groups[i]);
- if (error) {
- while (--i >= 0)
- sysfs_remove_group(&drv->p->kobj,
- groups[i]);
- break;
- }
- }
- }
- return error;
+ return sysfs_create_groups(&drv->p->kobj, groups);
}
-static void driver_remove_groups(struct device_driver *drv,
- const struct attribute_group **groups)
+void driver_remove_groups(struct device_driver *drv,
+ const struct attribute_group **groups)
{
- int i;
-
- if (groups)
- for (i = 0; groups[i]; i++)
- sysfs_remove_group(&drv->p->kobj, groups[i]);
+ sysfs_remove_groups(&drv->p->kobj, groups);
}
/**
.notifier_call = fw_shutdown_notify,
};
-static ssize_t firmware_timeout_show(struct class *class,
- struct class_attribute *attr,
- char *buf)
+static ssize_t timeout_show(struct class *class, struct class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", loading_timeout);
}
*
* Note: zero means 'wait forever'.
**/
-static ssize_t firmware_timeout_store(struct class *class,
- struct class_attribute *attr,
- const char *buf, size_t count)
+static ssize_t timeout_store(struct class *class, struct class_attribute *attr,
+ const char *buf, size_t count)
{
loading_timeout = simple_strtol(buf, NULL, 10);
if (loading_timeout < 0)
}
static struct class_attribute firmware_class_attrs[] = {
- __ATTR(timeout, S_IWUSR | S_IRUGO,
- firmware_timeout_show, firmware_timeout_store),
+ __ATTR_RW(timeout),
__ATTR_NULL
};
goto err_del_dev;
}
+ mutex_lock(&fw_lock);
+ list_add(&buf->pending_list, &pending_fw_head);
+ mutex_unlock(&fw_lock);
+
retval = device_create_file(f_dev, &dev_attr_loading);
if (retval) {
+ mutex_lock(&fw_lock);
+ list_del_init(&buf->pending_list);
+ mutex_unlock(&fw_lock);
dev_err(f_dev, "%s: device_create_file failed\n", __func__);
goto err_del_bin_attr;
}
kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
}
- mutex_lock(&fw_lock);
- list_add(&buf->pending_list, &pending_fw_head);
- mutex_unlock(&fw_lock);
-
wait_for_completion(&buf->completion);
cancel_delayed_work_sync(&fw_priv->timeout_work);
#include <linux/capability.h>
#include <linux/device.h>
#include <linux/memory.h>
-#include <linux/kobject.h>
#include <linux/memory_hotplug.h>
#include <linux/mm.h>
#include <linux/mutex.h>
#define MEMORY_CLASS_NAME "memory"
+#define to_memory_block(dev) container_of(dev, struct memory_block, dev)
+
static int sections_per_block;
static inline int base_memory_block_id(int section_nr)
static void memory_block_release(struct device *dev)
{
- struct memory_block *mem = container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
kfree(mem);
}
static ssize_t show_mem_start_phys_index(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct memory_block *mem =
- container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
unsigned long phys_index;
phys_index = mem->start_section_nr / sections_per_block;
static ssize_t show_mem_end_phys_index(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct memory_block *mem =
- container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
unsigned long phys_index;
phys_index = mem->end_section_nr / sections_per_block;
{
unsigned long i, pfn;
int ret = 1;
- struct memory_block *mem =
- container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
for (i = 0; i < sections_per_block; i++) {
if (!present_section_nr(mem->start_section_nr + i))
static ssize_t show_mem_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct memory_block *mem =
- container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
ssize_t len = 0;
/*
return ret;
}
-static int __memory_block_change_state(struct memory_block *mem,
- unsigned long to_state, unsigned long from_state_req,
- int online_type)
+static int memory_block_change_state(struct memory_block *mem,
+ unsigned long to_state, unsigned long from_state_req)
{
int ret = 0;
if (to_state == MEM_OFFLINE)
mem->state = MEM_GOING_OFFLINE;
- ret = memory_block_action(mem->start_section_nr, to_state, online_type);
+ ret = memory_block_action(mem->start_section_nr, to_state,
+ mem->online_type);
+
mem->state = ret ? from_state_req : to_state;
+
return ret;
}
+/* The device lock serializes operations on memory_subsys_[online|offline] */
static int memory_subsys_online(struct device *dev)
{
- struct memory_block *mem = container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
int ret;
- mutex_lock(&mem->state_mutex);
-
- ret = mem->state == MEM_ONLINE ? 0 :
- __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE,
- ONLINE_KEEP);
+ if (mem->state == MEM_ONLINE)
+ return 0;
- mutex_unlock(&mem->state_mutex);
- return ret;
-}
-
-static int memory_subsys_offline(struct device *dev)
-{
- struct memory_block *mem = container_of(dev, struct memory_block, dev);
- int ret;
+ /*
+ * If we are called from store_mem_state(), online_type will be
+ * set >= 0 Otherwise we were called from the device online
+ * attribute and need to set the online_type.
+ */
+ if (mem->online_type < 0)
+ mem->online_type = ONLINE_KEEP;
- mutex_lock(&mem->state_mutex);
+ ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
- ret = mem->state == MEM_OFFLINE ? 0 :
- __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
+ /* clear online_type */
+ mem->online_type = -1;
- mutex_unlock(&mem->state_mutex);
return ret;
}
-static int __memory_block_change_state_uevent(struct memory_block *mem,
- unsigned long to_state, unsigned long from_state_req,
- int online_type)
-{
- int ret = __memory_block_change_state(mem, to_state, from_state_req,
- online_type);
- if (!ret) {
- switch (mem->state) {
- case MEM_OFFLINE:
- kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
- break;
- case MEM_ONLINE:
- kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
- break;
- default:
- break;
- }
- }
- return ret;
-}
-
-static int memory_block_change_state(struct memory_block *mem,
- unsigned long to_state, unsigned long from_state_req,
- int online_type)
+static int memory_subsys_offline(struct device *dev)
{
- int ret;
+ struct memory_block *mem = to_memory_block(dev);
- mutex_lock(&mem->state_mutex);
- ret = __memory_block_change_state_uevent(mem, to_state, from_state_req,
- online_type);
- mutex_unlock(&mem->state_mutex);
+ if (mem->state == MEM_OFFLINE)
+ return 0;
- return ret;
+ return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
}
+
static ssize_t
store_mem_state(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct memory_block *mem;
- bool offline;
- int ret = -EINVAL;
-
- mem = container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
+ int ret, online_type;
lock_device_hotplug();
- if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
- offline = false;
- ret = memory_block_change_state(mem, MEM_ONLINE,
- MEM_OFFLINE, ONLINE_KERNEL);
- } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) {
- offline = false;
- ret = memory_block_change_state(mem, MEM_ONLINE,
- MEM_OFFLINE, ONLINE_MOVABLE);
- } else if (!strncmp(buf, "online", min_t(int, count, 6))) {
- offline = false;
- ret = memory_block_change_state(mem, MEM_ONLINE,
- MEM_OFFLINE, ONLINE_KEEP);
- } else if(!strncmp(buf, "offline", min_t(int, count, 7))) {
- offline = true;
- ret = memory_block_change_state(mem, MEM_OFFLINE,
- MEM_ONLINE, -1);
+ if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
+ online_type = ONLINE_KERNEL;
+ else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
+ online_type = ONLINE_MOVABLE;
+ else if (!strncmp(buf, "online", min_t(int, count, 6)))
+ online_type = ONLINE_KEEP;
+ else if (!strncmp(buf, "offline", min_t(int, count, 7)))
+ online_type = -1;
+ else
+ return -EINVAL;
+
+ switch (online_type) {
+ case ONLINE_KERNEL:
+ case ONLINE_MOVABLE:
+ case ONLINE_KEEP:
+ /*
+ * mem->online_type is not protected so there can be a
+ * race here. However, when racing online, the first
+ * will succeed and the second will just return as the
+ * block will already be online. The online type
+ * could be either one, but that is expected.
+ */
+ mem->online_type = online_type;
+ ret = device_online(&mem->dev);
+ break;
+ case -1:
+ ret = device_offline(&mem->dev);
+ break;
+ default:
+ ret = -EINVAL; /* should never happen */
}
- if (!ret)
- dev->offline = offline;
unlock_device_hotplug();
static ssize_t show_phys_device(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct memory_block *mem =
- container_of(dev, struct memory_block, dev);
+ struct memory_block *mem = to_memory_block(dev);
return sprintf(buf, "%d\n", mem->phys_device);
}
u64 pfn;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (strict_strtoull(buf, 0, &pfn) < 0)
+ if (kstrtoull(buf, 0, &pfn) < 0)
return -EINVAL;
pfn >>= PAGE_SHIFT;
if (!pfn_valid(pfn))
u64 pfn;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (strict_strtoull(buf, 0, &pfn) < 0)
+ if (kstrtoull(buf, 0, &pfn) < 0)
return -EINVAL;
pfn >>= PAGE_SHIFT;
ret = memory_failure(pfn, 0, 0);
put_device(&hint->dev);
if (!dev)
return NULL;
- return container_of(dev, struct memory_block, dev);
+ return to_memory_block(dev);
}
/*
static
int register_memory(struct memory_block *memory)
{
- int error;
-
memory->dev.bus = &memory_subsys;
memory->dev.id = memory->start_section_nr / sections_per_block;
memory->dev.release = memory_block_release;
memory->dev.groups = memory_memblk_attr_groups;
memory->dev.offline = memory->state == MEM_OFFLINE;
- error = device_register(&memory->dev);
- return error;
+ return device_register(&memory->dev);
}
static int init_memory_block(struct memory_block **memory,
mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
mem->state = state;
mem->section_count++;
- mutex_init(&mem->state_mutex);
start_pfn = section_nr_to_pfn(mem->start_section_nr);
mem->phys_device = arch_get_memory_phys_device(start_pfn);
return ret;
}
-static int add_memory_section(int nid, struct mem_section *section,
- struct memory_block **mem_p,
- unsigned long state, enum mem_add_context context)
+static int add_memory_block(int base_section_nr)
{
- struct memory_block *mem = NULL;
- int scn_nr = __section_nr(section);
- int ret = 0;
-
- mutex_lock(&mem_sysfs_mutex);
-
- if (context == BOOT) {
- /* same memory block ? */
- if (mem_p && *mem_p)
- if (scn_nr >= (*mem_p)->start_section_nr &&
- scn_nr <= (*mem_p)->end_section_nr) {
- mem = *mem_p;
- kobject_get(&mem->dev.kobj);
- }
- } else
- mem = find_memory_block(section);
-
- if (mem) {
- mem->section_count++;
- kobject_put(&mem->dev.kobj);
- } else {
- ret = init_memory_block(&mem, section, state);
- /* store memory_block pointer for next loop */
- if (!ret && context == BOOT)
- if (mem_p)
- *mem_p = mem;
- }
+ struct memory_block *mem;
+ int i, ret, section_count = 0, section_nr;
- if (!ret) {
- if (context == HOTPLUG &&
- mem->section_count == sections_per_block)
- ret = register_mem_sect_under_node(mem, nid);
+ for (i = base_section_nr;
+ (i < base_section_nr + sections_per_block) && i < NR_MEM_SECTIONS;
+ i++) {
+ if (!present_section_nr(i))
+ continue;
+ if (section_count == 0)
+ section_nr = i;
+ section_count++;
}
- mutex_unlock(&mem_sysfs_mutex);
- return ret;
+ if (section_count == 0)
+ return 0;
+ ret = init_memory_block(&mem, __nr_to_section(section_nr), MEM_ONLINE);
+ if (ret)
+ return ret;
+ mem->section_count = section_count;
+ return 0;
}
+
/*
* need an interface for the VM to add new memory regions,
* but without onlining it.
*/
int register_new_memory(int nid, struct mem_section *section)
{
- return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG);
+ int ret = 0;
+ struct memory_block *mem;
+
+ mutex_lock(&mem_sysfs_mutex);
+
+ mem = find_memory_block(section);
+ if (mem) {
+ mem->section_count++;
+ put_device(&mem->dev);
+ } else {
+ ret = init_memory_block(&mem, section, MEM_OFFLINE);
+ if (ret)
+ goto out;
+ }
+
+ if (mem->section_count == sections_per_block)
+ ret = register_mem_sect_under_node(mem, nid);
+out:
+ mutex_unlock(&mem_sysfs_mutex);
+ return ret;
}
#ifdef CONFIG_MEMORY_HOTREMOVE
BUG_ON(memory->dev.bus != &memory_subsys);
/* drop the ref. we got in remove_memory_block() */
- kobject_put(&memory->dev.kobj);
+ put_device(&memory->dev);
device_unregister(&memory->dev);
}
if (mem->section_count == 0)
unregister_memory(mem);
else
- kobject_put(&mem->dev.kobj);
+ put_device(&mem->dev);
mutex_unlock(&mem_sysfs_mutex);
return 0;
int ret;
int err;
unsigned long block_sz;
- struct memory_block *mem = NULL;
ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
if (ret)
* Create entries for memory sections that were found
* during boot and have been initialized
*/
- for (i = 0; i < NR_MEM_SECTIONS; i++) {
- if (!present_section_nr(i))
- continue;
- /* don't need to reuse memory_block if only one per block */
- err = add_memory_section(0, __nr_to_section(i),
- (sections_per_block == 1) ? NULL : &mem,
- MEM_ONLINE,
- BOOT);
+ mutex_lock(&mem_sysfs_mutex);
+ for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) {
+ err = add_memory_block(i);
if (!ret)
ret = err;
}
+ mutex_unlock(&mem_sysfs_mutex);
out:
if (ret)
return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
+static DEVICE_ATTR_RO(modalias);
-static struct device_attribute platform_dev_attrs[] = {
- __ATTR_RO(modalias),
- __ATTR_NULL,
+static struct attribute *platform_dev_attrs[] = {
+ &dev_attr_modalias.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(platform_dev);
static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct bus_type platform_bus_type = {
.name = "platform",
- .dev_attrs = platform_dev_attrs,
+ .dev_groups = platform_dev_groups,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
* @epdrv: early platform driver structure
* @id: id to match against
*/
-static __init struct platform_device *
+static struct platform_device * __init
early_platform_match(struct early_platform_driver *epdrv, int id)
{
struct platform_device *pd;
* @epdrv: early platform driver structure
* @id: return true if id or above exists
*/
-static __init int early_platform_left(struct early_platform_driver *epdrv,
+static int __init early_platform_left(struct early_platform_driver *epdrv,
int id)
{
struct platform_device *pd;
if (!dev->power.use_autosuspend)
return -EIO;
- if (strict_strtol(buf, 10, &delay) != 0 || delay != (int) delay)
+ if (kstrtol(buf, 10, &delay) != 0 || delay != (int) delay)
return -EINVAL;
device_lock(dev);
reg = simple_strtoul(start, &start, 16);
while (*start == ' ')
start++;
- if (strict_strtoul(start, 16, &value))
+ if (kstrtoul(start, 16, &value))
return -EINVAL;
/* Userspace has been fiddling around behind the kernel's back */
}
#endif
-#ifdef arch_provides_topology_pointers
-#define define_siblings_show_map(name) \
-static ssize_t show_##name(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- unsigned int cpu = dev->id; \
- return show_cpumap(0, topology_##name(cpu), buf); \
-}
-
-#define define_siblings_show_list(name) \
-static ssize_t show_##name##_list(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- unsigned int cpu = dev->id; \
- return show_cpumap(1, topology_##name(cpu), buf); \
-}
-
-#else
#define define_siblings_show_map(name) \
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
return show_cpumap(1, topology_##name(dev->id), buf); \
}
-#endif
#define define_siblings_show_func(name) \
define_siblings_show_map(name); define_siblings_show_list(name)
static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
static void rbd_spec_put(struct rbd_spec *spec);
-static struct bus_attribute rbd_bus_attrs[] = {
- __ATTR(add, S_IWUSR, NULL, rbd_add),
- __ATTR(remove, S_IWUSR, NULL, rbd_remove),
- __ATTR_NULL
+static BUS_ATTR(add, S_IWUSR, NULL, rbd_add);
+static BUS_ATTR(remove, S_IWUSR, NULL, rbd_remove);
+
+static struct attribute *rbd_bus_attrs[] = {
+ &bus_attr_add.attr,
+ &bus_attr_remove.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(rbd_bus);
static struct bus_type rbd_bus_type = {
.name = "rbd",
- .bus_attrs = rbd_bus_attrs,
+ .bus_groups = rbd_bus_groups,
};
static void rbd_root_dev_release(struct device *dev)
struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", bsr_dev->bsr_bytes);
}
+static DEVICE_ATTR_RO(bsr_size);
static ssize_t
bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf)
struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", bsr_dev->bsr_stride);
}
+static DEVICE_ATTR_RO(bsr_stride);
static ssize_t
-bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf)
+bsr_length_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
return sprintf(buf, "%llu\n", bsr_dev->bsr_len);
}
+static DEVICE_ATTR_RO(bsr_length);
-static struct device_attribute bsr_dev_attrs[] = {
- __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL),
- __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL),
- __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL),
- __ATTR_NULL
+static struct attribute *bsr_dev_attrs[] = {
+ &dev_attr_bsr_size.attr,
+ &dev_attr_bsr_stride.attr,
+ &dev_attr_bsr_length.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(bsr_dev);
static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
{
ret = PTR_ERR(bsr_class);
goto out_err_1;
}
- bsr_class->dev_attrs = bsr_dev_attrs;
+ bsr_class->dev_groups = bsr_dev_groups;
ret = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
bsr_major = MAJOR(bsr_dev);
return fixed_size_llseek(file, offset, origin, srom->total_size);
}
-static ssize_t total_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t total_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct srom_dev *srom = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", srom->total_size);
}
+static DEVICE_ATTR_RO(total_size);
-static ssize_t sector_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t sector_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct srom_dev *srom = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", srom->sector_size);
}
+static DEVICE_ATTR_RO(sector_size);
-static ssize_t page_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t page_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct srom_dev *srom = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", srom->page_size);
}
+static DEVICE_ATTR_RO(page_size);
-static struct device_attribute srom_dev_attrs[] = {
- __ATTR(total_size, S_IRUGO, total_show, NULL),
- __ATTR(sector_size, S_IRUGO, sector_show, NULL),
- __ATTR(page_size, S_IRUGO, page_show, NULL),
- __ATTR_NULL
+static struct attribute *srom_dev_attrs[] = {
+ &dev_attr_total_size.attr,
+ &dev_attr_sector_size.attr,
+ &dev_attr_page_size.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(srom_dev);
static char *srom_devnode(struct device *dev, umode_t *mode)
{
result = PTR_ERR(srom_class);
goto fail_cdev;
}
- srom_class->dev_attrs = srom_dev_attrs;
+ srom_class->dev_groups = srom_dev_groups;
srom_class->devnode = srom_devnode;
/* Do per-partition initialization */
}
EXPORT_SYMBOL(devfreq_remove_governor);
-static ssize_t show_governor(struct device *dev,
+static ssize_t governor_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
if (!to_devfreq(dev)->governor)
return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}
-static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
+static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct devfreq *df = to_devfreq(dev);
ret = count;
return ret;
}
-static ssize_t show_available_governors(struct device *d,
- struct device_attribute *attr,
- char *buf)
+static DEVICE_ATTR_RW(governor);
+
+static ssize_t available_governors_show(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct devfreq_governor *tmp_governor;
ssize_t count = 0;
return count;
}
+static DEVICE_ATTR_RO(available_governors);
-static ssize_t show_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
unsigned long freq;
struct devfreq *devfreq = to_devfreq(dev);
return sprintf(buf, "%lu\n", devfreq->previous_freq);
}
+static DEVICE_ATTR_RO(cur_freq);
-static ssize_t show_target_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t target_freq_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq);
}
+static DEVICE_ATTR_RO(target_freq);
-static ssize_t show_polling_interval(struct device *dev,
+static ssize_t polling_interval_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms);
}
-static ssize_t store_polling_interval(struct device *dev,
+static ssize_t polling_interval_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return ret;
}
+static DEVICE_ATTR_RW(polling_interval);
-static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
+static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct devfreq *df = to_devfreq(dev);
return ret;
}
-static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr,
+static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq);
}
-static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr,
+static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct devfreq *df = to_devfreq(dev);
mutex_unlock(&df->lock);
return ret;
}
+static DEVICE_ATTR_RW(min_freq);
-static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr,
+static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
}
+static DEVICE_ATTR_RW(max_freq);
-static ssize_t show_available_freqs(struct device *d,
- struct device_attribute *attr,
- char *buf)
+static ssize_t available_frequencies_show(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct devfreq *df = to_devfreq(d);
struct device *dev = df->dev.parent;
return count;
}
+static DEVICE_ATTR_RO(available_frequencies);
-static ssize_t show_trans_table(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t trans_stat_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct devfreq *devfreq = to_devfreq(dev);
ssize_t len;
devfreq->total_trans);
return len;
}
-
-static struct device_attribute devfreq_attrs[] = {
- __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
- __ATTR(available_governors, S_IRUGO, show_available_governors, NULL),
- __ATTR(cur_freq, S_IRUGO, show_freq, NULL),
- __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL),
- __ATTR(target_freq, S_IRUGO, show_target_freq, NULL),
- __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval,
- store_polling_interval),
- __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq),
- __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq),
- __ATTR(trans_stat, S_IRUGO, show_trans_table, NULL),
- { },
+static DEVICE_ATTR_RO(trans_stat);
+
+static struct attribute *devfreq_attrs[] = {
+ &dev_attr_governor.attr,
+ &dev_attr_available_governors.attr,
+ &dev_attr_cur_freq.attr,
+ &dev_attr_available_frequencies.attr,
+ &dev_attr_target_freq.attr,
+ &dev_attr_polling_interval.attr,
+ &dev_attr_min_freq.attr,
+ &dev_attr_max_freq.attr,
+ &dev_attr_trans_stat.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(devfreq);
static int __init devfreq_init(void)
{
pr_err("%s: couldn't create workqueue\n", __FILE__);
return PTR_ERR(devfreq_wq);
}
- devfreq_class->dev_attrs = devfreq_attrs;
+ devfreq_class->dev_groups = devfreq_groups;
return 0;
}
return chan_dev->chan;
}
-static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t memcpy_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct dma_chan *chan;
unsigned long count = 0;
return err;
}
+static DEVICE_ATTR_RO(memcpy_count);
-static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t bytes_transferred_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct dma_chan *chan;
unsigned long count = 0;
return err;
}
+static DEVICE_ATTR_RO(bytes_transferred);
-static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t in_use_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct dma_chan *chan;
int err;
return err;
}
+static DEVICE_ATTR_RO(in_use);
-static struct device_attribute dma_attrs[] = {
- __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL),
- __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL),
- __ATTR(in_use, S_IRUGO, show_in_use, NULL),
- __ATTR_NULL
+static struct attribute *dma_dev_attrs[] = {
+ &dev_attr_memcpy_count.attr,
+ &dev_attr_bytes_transferred.attr,
+ &dev_attr_in_use.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(dma_dev);
static void chan_dev_release(struct device *dev)
{
static struct class dma_devclass = {
.name = "dma",
- .dev_attrs = dma_attrs,
+ .dev_groups = dma_dev_groups,
.dev_release = chan_dev_release,
};
return count;
}
+static DEVICE_ATTR_RW(state);
static ssize_t name_show(struct device *dev, struct device_attribute *attr,
char *buf)
return sprintf(buf, "%s\n", dev_name(edev->dev));
}
+static DEVICE_ATTR_RO(name);
static ssize_t cable_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
}
EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
-static struct device_attribute extcon_attrs[] = {
- __ATTR(state, S_IRUGO | S_IWUSR, state_show, state_store),
- __ATTR_RO(name),
- __ATTR_NULL,
+static struct attribute *extcon_attrs[] = {
+ &dev_attr_state.attr,
+ &dev_attr_name.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(extcon);
static int create_extcon_class(void)
{
extcon_class = class_create(THIS_MODULE, "extcon");
if (IS_ERR(extcon_class))
return PTR_ERR(extcon_class);
- extcon_class->dev_attrs = extcon_attrs;
+ extcon_class->dev_groups = extcon_groups;
#if defined(CONFIG_ANDROID)
switch_class = class_compat_register("switch");
static struct attribute_group dcdbas_attr_group = {
.attrs = dcdbas_dev_attrs,
+ .bin_attrs = dcdbas_bin_attrs,
};
static int dcdbas_probe(struct platform_device *dev)
{
- int i, error;
+ int error;
host_control_action = HC_ACTION_NONE;
host_control_smi_type = HC_SMITYPE_NONE;
if (error)
return error;
- for (i = 0; dcdbas_bin_attrs[i]; i++) {
- error = sysfs_create_bin_file(&dev->dev.kobj,
- dcdbas_bin_attrs[i]);
- if (error) {
- while (--i >= 0)
- sysfs_remove_bin_file(&dev->dev.kobj,
- dcdbas_bin_attrs[i]);
- sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
- return error;
- }
- }
-
register_reboot_notifier(&dcdbas_reboot_nb);
dev_info(&dev->dev, "%s (version %s)\n",
static int dcdbas_remove(struct platform_device *dev)
{
- int i;
-
unregister_reboot_notifier(&dcdbas_reboot_nb);
- for (i = 0; dcdbas_bin_attrs[i]; i++)
- sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]);
sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
return 0;
return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
+static DEVICE_ATTR_RO(modalias);
-static struct device_attribute hid_dev_attrs[] = {
- __ATTR_RO(modalias),
- __ATTR_NULL,
+static struct attribute *hid_dev_attrs[] = {
+ &dev_attr_modalias.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(hid_dev);
static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
{
static struct bus_type hid_bus_type = {
.name = "hid",
- .dev_attrs = hid_dev_attrs,
+ .dev_groups = hid_dev_groups,
.match = hid_bus_match,
.probe = hid_device_probe,
.remove = hid_device_remove,
return size;
}
+static DEVICE_ATTR(mode_key, 0660,
+ arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key);
static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
struct device_attribute *attr, char *buf)
return size;
}
+static DEVICE_ATTR(key_mask, 0660,
+ arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask);
/* retval is 1-5 on success, < 0 on error */
static int arvo_get_actual_profile(struct usb_device *usb_dev)
mutex_unlock(&arvo->arvo_lock);
return retval;
}
+static DEVICE_ATTR(actual_profile, 0660,
+ arvo_sysfs_show_actual_profile,
+ arvo_sysfs_set_actual_profile);
static ssize_t arvo_sysfs_write(struct file *fp,
struct kobject *kobj, void const *buf,
return arvo_sysfs_write(fp, kobj, buf, off, count,
sizeof(struct arvo_button), ARVO_COMMAND_BUTTON);
}
+static BIN_ATTR(button, 0220, NULL, arvo_sysfs_write_button,
+ sizeof(struct arvo_button));
static ssize_t arvo_sysfs_read_info(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
return arvo_sysfs_read(fp, kobj, buf, off, count,
sizeof(struct arvo_info), ARVO_COMMAND_INFO);
}
+static BIN_ATTR(info, 0440, arvo_sysfs_read_info, NULL,
+ sizeof(struct arvo_info));
+
+static struct attribute *arvo_attrs[] = {
+ &dev_attr_mode_key.attr,
+ &dev_attr_key_mask.attr,
+ &dev_attr_actual_profile.attr,
+ NULL,
+};
+static struct bin_attribute *arvo_bin_attributes[] = {
+ &bin_attr_button,
+ &bin_attr_info,
+ NULL,
+};
-static struct device_attribute arvo_attributes[] = {
- __ATTR(mode_key, 0660,
- arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key),
- __ATTR(key_mask, 0660,
- arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask),
- __ATTR(actual_profile, 0660,
- arvo_sysfs_show_actual_profile,
- arvo_sysfs_set_actual_profile),
- __ATTR_NULL
+static const struct attribute_group arvo_group = {
+ .attrs = arvo_attrs,
+ .bin_attrs = arvo_bin_attributes,
};
-static struct bin_attribute arvo_bin_attributes[] = {
- {
- .attr = { .name = "button", .mode = 0220 },
- .size = sizeof(struct arvo_button),
- .write = arvo_sysfs_write_button
- },
- {
- .attr = { .name = "info", .mode = 0440 },
- .size = sizeof(struct arvo_info),
- .read = arvo_sysfs_read_info
- },
- __ATTR_NULL
+static const struct attribute_group *arvo_groups[] = {
+ &arvo_group,
+ NULL,
};
static int arvo_init_arvo_device_struct(struct usb_device *usb_dev,
arvo_class = class_create(THIS_MODULE, "arvo");
if (IS_ERR(arvo_class))
return PTR_ERR(arvo_class);
- arvo_class->dev_attrs = arvo_attributes;
- arvo_class->dev_bin_attrs = arvo_bin_attributes;
+ arvo_class->dev_groups = arvo_groups;
retval = hid_register_driver(&arvo_driver);
if (retval)
return size;
}
+static DEVICE_ATTR(actual_profile, 0660, isku_sysfs_show_actual_profile,
+ isku_sysfs_set_actual_profile);
-static struct device_attribute isku_attributes[] = {
- __ATTR(actual_profile, 0660,
- isku_sysfs_show_actual_profile,
- isku_sysfs_set_actual_profile),
- __ATTR_NULL
+static struct attribute *isku_attrs[] = {
+ &dev_attr_actual_profile.attr,
+ NULL,
};
static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj,
ISKU_SYSFS_W(thingy, THINGY)
#define ISKU_BIN_ATTR_RW(thingy, THINGY) \
-{ \
+ISKU_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = ISKU_SIZE_ ## THINGY, \
.read = isku_sysfs_read_ ## thingy, \
}
#define ISKU_BIN_ATTR_R(thingy, THINGY) \
-{ \
+ISKU_SYSFS_R(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0440 }, \
.size = ISKU_SIZE_ ## THINGY, \
.read = isku_sysfs_read_ ## thingy, \
}
#define ISKU_BIN_ATTR_W(thingy, THINGY) \
-{ \
+ISKU_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = ISKU_SIZE_ ## THINGY, \
.write = isku_sysfs_write_ ## thingy \
}
-ISKU_SYSFS_RW(macro, MACRO)
-ISKU_SYSFS_RW(keys_function, KEYS_FUNCTION)
-ISKU_SYSFS_RW(keys_easyzone, KEYS_EASYZONE)
-ISKU_SYSFS_RW(keys_media, KEYS_MEDIA)
-ISKU_SYSFS_RW(keys_thumbster, KEYS_THUMBSTER)
-ISKU_SYSFS_RW(keys_macro, KEYS_MACRO)
-ISKU_SYSFS_RW(keys_capslock, KEYS_CAPSLOCK)
-ISKU_SYSFS_RW(light, LIGHT)
-ISKU_SYSFS_RW(key_mask, KEY_MASK)
-ISKU_SYSFS_RW(last_set, LAST_SET)
-ISKU_SYSFS_W(talk, TALK)
-ISKU_SYSFS_W(talkfx, TALKFX)
-ISKU_SYSFS_R(info, INFO)
-ISKU_SYSFS_W(control, CONTROL)
-ISKU_SYSFS_W(reset, RESET)
-
-static struct bin_attribute isku_bin_attributes[] = {
- ISKU_BIN_ATTR_RW(macro, MACRO),
- ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION),
- ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE),
- ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA),
- ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER),
- ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO),
- ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK),
- ISKU_BIN_ATTR_RW(light, LIGHT),
- ISKU_BIN_ATTR_RW(key_mask, KEY_MASK),
- ISKU_BIN_ATTR_RW(last_set, LAST_SET),
- ISKU_BIN_ATTR_W(talk, TALK),
- ISKU_BIN_ATTR_W(talkfx, TALKFX),
- ISKU_BIN_ATTR_R(info, INFO),
- ISKU_BIN_ATTR_W(control, CONTROL),
- ISKU_BIN_ATTR_W(reset, RESET),
- __ATTR_NULL
+ISKU_BIN_ATTR_RW(macro, MACRO);
+ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION);
+ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE);
+ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA);
+ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER);
+ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO);
+ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK);
+ISKU_BIN_ATTR_RW(light, LIGHT);
+ISKU_BIN_ATTR_RW(key_mask, KEY_MASK);
+ISKU_BIN_ATTR_RW(last_set, LAST_SET);
+ISKU_BIN_ATTR_W(talk, TALK);
+ISKU_BIN_ATTR_W(talkfx, TALKFX);
+ISKU_BIN_ATTR_W(control, CONTROL);
+ISKU_BIN_ATTR_W(reset, RESET);
+ISKU_BIN_ATTR_R(info, INFO);
+
+static struct bin_attribute *isku_bin_attributes[] = {
+ &bin_attr_macro,
+ &bin_attr_keys_function,
+ &bin_attr_keys_easyzone,
+ &bin_attr_keys_media,
+ &bin_attr_keys_thumbster,
+ &bin_attr_keys_macro,
+ &bin_attr_keys_capslock,
+ &bin_attr_light,
+ &bin_attr_key_mask,
+ &bin_attr_last_set,
+ &bin_attr_talk,
+ &bin_attr_talkfx,
+ &bin_attr_control,
+ &bin_attr_reset,
+ &bin_attr_info,
+ NULL,
+};
+
+static const struct attribute_group isku_group = {
+ .attrs = isku_attrs,
+ .bin_attrs = isku_bin_attributes,
+};
+
+static const struct attribute_group *isku_groups[] = {
+ &isku_group,
+ NULL,
};
static int isku_init_isku_device_struct(struct usb_device *usb_dev,
isku_class = class_create(THIS_MODULE, "isku");
if (IS_ERR(isku_class))
return PTR_ERR(isku_class);
- isku_class->dev_attrs = isku_attributes;
- isku_class->dev_bin_attrs = isku_bin_attributes;
+ isku_class->dev_groups = isku_groups;
retval = hid_register_driver(&isku_driver);
if (retval)
return sizeof(struct kone_settings);
}
+static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
+ kone_sysfs_write_settings, sizeof(struct kone_settings));
static ssize_t kone_sysfs_read_profilex(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr,
return sizeof(struct kone_profile);
}
+#define PROFILE_ATTR(number) \
+static struct bin_attribute bin_attr_profile##number = { \
+ .attr = { .name = "profile##number", .mode = 0660 }, \
+ .size = sizeof(struct kone_profile), \
+ .read = kone_sysfs_read_profilex, \
+ .write = kone_sysfs_write_profilex, \
+ .private = &profile_numbers[number-1], \
+};
+PROFILE_ATTR(1);
+PROFILE_ATTR(2);
+PROFILE_ATTR(3);
+PROFILE_ATTR(4);
+PROFILE_ATTR(5);
static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
}
+static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
}
+static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
/* weight is read each time, since we don't get informed when it's changed */
static ssize_t kone_sysfs_show_weight(struct device *dev,
return retval;
return snprintf(buf, PAGE_SIZE, "%d\n", weight);
}
+static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
}
+static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
+ NULL);
static ssize_t kone_sysfs_show_tcu(struct device *dev,
struct device_attribute *attr, char *buf)
mutex_unlock(&kone->kone_lock);
return retval;
}
+static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
struct device_attribute *attr, char *buf)
mutex_unlock(&kone->kone_lock);
return size;
}
+static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
+ kone_sysfs_set_startup_profile);
-static struct device_attribute kone_attributes[] = {
+static struct attribute *kone_attrs[] = {
/*
* Read actual dpi settings.
* Returns raw value for further processing. Refer to enum
* kone_polling_rates to get real value.
*/
- __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL),
- __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL),
+ &dev_attr_actual_dpi.attr,
+ &dev_attr_actual_profile.attr,
/*
* The mouse can be equipped with one of four supplied weights from 5
* by software. Refer to enum kone_weights to get corresponding real
* weight.
*/
- __ATTR(weight, 0440, kone_sysfs_show_weight, NULL),
+ &dev_attr_weight.attr,
/*
* Prints firmware version stored in mouse as integer.
* to get the real version number the decimal point has to be shifted 2
* positions to the left. E.g. a value of 138 means 1.38.
*/
- __ATTR(firmware_version, 0440,
- kone_sysfs_show_firmware_version, NULL),
+ &dev_attr_firmware_version.attr,
/*
* Prints state of Tracking Control Unit as number where 0 = off and
* 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
* activates the tcu
*/
- __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu),
+ &dev_attr_tcu.attr,
/* Prints and takes the number of the profile the mouse starts with */
- __ATTR(startup_profile, 0660,
- kone_sysfs_show_startup_profile,
- kone_sysfs_set_startup_profile),
- __ATTR_NULL
+ &dev_attr_startup_profile.attr,
+ NULL,
+};
+
+static struct bin_attribute *kone_bin_attributes[] = {
+ &bin_attr_settings,
+ &bin_attr_profile1,
+ &bin_attr_profile2,
+ &bin_attr_profile3,
+ &bin_attr_profile4,
+ &bin_attr_profile5,
+ NULL,
+};
+
+static const struct attribute_group kone_group = {
+ .attrs = kone_attrs,
+ .bin_attrs = kone_bin_attributes,
};
-static struct bin_attribute kone_bin_attributes[] = {
- {
- .attr = { .name = "settings", .mode = 0660 },
- .size = sizeof(struct kone_settings),
- .read = kone_sysfs_read_settings,
- .write = kone_sysfs_write_settings
- },
- {
- .attr = { .name = "profile1", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
+static const struct attribute_group *kone_groups[] = {
+ &kone_group,
+ NULL,
};
static int kone_init_kone_device_struct(struct usb_device *usb_dev,
kone_class = class_create(THIS_MODULE, "kone");
if (IS_ERR(kone_class))
return PTR_ERR(kone_class);
- kone_class->dev_attrs = kone_attributes;
- kone_class->dev_bin_attrs = kone_bin_attributes;
+ kone_class->dev_groups = kone_groups;
retval = hid_register_driver(&kone_driver);
if (retval)
KONEPLUS_SYSFS_R(thingy, THINGY)
#define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
-{ \
+KONEPLUS_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = KONEPLUS_SIZE_ ## THINGY, \
.read = koneplus_sysfs_read_ ## thingy, \
}
#define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
-{ \
+KONEPLUS_SYSFS_R(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0440 }, \
.size = KONEPLUS_SIZE_ ## THINGY, \
.read = koneplus_sysfs_read_ ## thingy, \
}
#define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
-{ \
+KONEPLUS_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = KONEPLUS_SIZE_ ## THINGY, \
.write = koneplus_sysfs_write_ ## thingy \
}
-
-KONEPLUS_SYSFS_W(control, CONTROL)
-KONEPLUS_SYSFS_RW(info, INFO)
-KONEPLUS_SYSFS_W(talk, TALK)
-KONEPLUS_SYSFS_W(macro, MACRO)
-KONEPLUS_SYSFS_RW(sensor, SENSOR)
-KONEPLUS_SYSFS_RW(tcu, TCU)
-KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE)
-KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
-KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL);
+KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK);
+KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO);
+KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE);
+KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO);
+KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR);
+KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU);
+KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
+KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
KONEPLUS_COMMAND_PROFILE_BUTTONS);
}
+#define PROFILE_ATTR(number) \
+static struct bin_attribute bin_attr_profile##number##_settings = { \
+ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+ .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \
+ .read = koneplus_sysfs_read_profilex_settings, \
+ .private = &profile_numbers[number-1], \
+}; \
+static struct bin_attribute bin_attr_profile##number##_buttons = { \
+ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
+ .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \
+ .read = koneplus_sysfs_read_profilex_buttons, \
+ .private = &profile_numbers[number-1], \
+};
+PROFILE_ATTR(1);
+PROFILE_ATTR(2);
+PROFILE_ATTR(3);
+PROFILE_ATTR(4);
+PROFILE_ATTR(5);
+
static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
return size;
}
+static DEVICE_ATTR(actual_profile, 0660,
+ koneplus_sysfs_show_actual_profile,
+ koneplus_sysfs_set_actual_profile);
+static DEVICE_ATTR(startup_profile, 0660,
+ koneplus_sysfs_show_actual_profile,
+ koneplus_sysfs_set_actual_profile);
static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
}
+static DEVICE_ATTR(firmware_version, 0440,
+ koneplus_sysfs_show_firmware_version, NULL);
+
+static struct attribute *koneplus_attrs[] = {
+ &dev_attr_actual_profile.attr,
+ &dev_attr_startup_profile.attr,
+ &dev_attr_firmware_version.attr,
+ NULL,
+};
+
+static struct bin_attribute *koneplus_bin_attributes[] = {
+ &bin_attr_control,
+ &bin_attr_talk,
+ &bin_attr_macro,
+ &bin_attr_tcu_image,
+ &bin_attr_info,
+ &bin_attr_sensor,
+ &bin_attr_tcu,
+ &bin_attr_profile_settings,
+ &bin_attr_profile_buttons,
+ &bin_attr_profile1_settings,
+ &bin_attr_profile2_settings,
+ &bin_attr_profile3_settings,
+ &bin_attr_profile4_settings,
+ &bin_attr_profile5_settings,
+ &bin_attr_profile1_buttons,
+ &bin_attr_profile2_buttons,
+ &bin_attr_profile3_buttons,
+ &bin_attr_profile4_buttons,
+ &bin_attr_profile5_buttons,
+ NULL,
+};
-static struct device_attribute koneplus_attributes[] = {
- __ATTR(actual_profile, 0660,
- koneplus_sysfs_show_actual_profile,
- koneplus_sysfs_set_actual_profile),
- __ATTR(startup_profile, 0660,
- koneplus_sysfs_show_actual_profile,
- koneplus_sysfs_set_actual_profile),
- __ATTR(firmware_version, 0440,
- koneplus_sysfs_show_firmware_version, NULL),
- __ATTR_NULL
+static const struct attribute_group koneplus_group = {
+ .attrs = koneplus_attrs,
+ .bin_attrs = koneplus_bin_attributes,
};
-static struct bin_attribute koneplus_bin_attributes[] = {
- KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
- KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO),
- KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK),
- KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO),
- KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR),
- KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU),
- KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
- KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
- KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
+static const struct attribute_group *koneplus_groups[] = {
+ &koneplus_group,
+ NULL,
};
static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
koneplus_class = class_create(THIS_MODULE, "koneplus");
if (IS_ERR(koneplus_class))
return PTR_ERR(koneplus_class);
- koneplus_class->dev_attrs = koneplus_attributes;
- koneplus_class->dev_bin_attrs = koneplus_bin_attributes;
+ koneplus_class->dev_groups = koneplus_groups;
retval = hid_register_driver(&koneplus_driver);
if (retval)
KONEPURE_SYSFS_R(thingy, THINGY)
#define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \
-{ \
+KONEPURE_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = KONEPURE_SIZE_ ## THINGY, \
.read = konepure_sysfs_read_ ## thingy, \
}
#define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \
-{ \
+KONEPURE_SYSFS_R(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0440 }, \
.size = KONEPURE_SIZE_ ## THINGY, \
.read = konepure_sysfs_read_ ## thingy, \
}
#define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \
-{ \
+KONEPURE_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = KONEPURE_SIZE_ ## THINGY, \
.write = konepure_sysfs_write_ ## thingy \
}
-KONEPURE_SYSFS_RW(actual_profile, ACTUAL_PROFILE)
-KONEPURE_SYSFS_W(control, CONTROL)
-KONEPURE_SYSFS_RW(info, INFO)
-KONEPURE_SYSFS_W(talk, TALK)
-KONEPURE_SYSFS_W(macro, MACRO)
-KONEPURE_SYSFS_RW(sensor, SENSOR)
-KONEPURE_SYSFS_RW(tcu, TCU)
-KONEPURE_SYSFS_R(tcu_image, TCU_IMAGE)
-KONEPURE_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
-KONEPURE_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
-
-static struct bin_attribute konepure_bin_attributes[] = {
- KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE),
- KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL),
- KONEPURE_BIN_ATTRIBUTE_RW(info, INFO),
- KONEPURE_BIN_ATTRIBUTE_W(talk, TALK),
- KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO),
- KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR),
- KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU),
- KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
- KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
- KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
- __ATTR_NULL
+KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE);
+KONEPURE_BIN_ATTRIBUTE_RW(info, INFO);
+KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR);
+KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU);
+KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
+KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
+KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL);
+KONEPURE_BIN_ATTRIBUTE_W(talk, TALK);
+KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO);
+KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE);
+
+static struct bin_attribute *konepure_bin_attributes[] = {
+ &bin_attr_actual_profile,
+ &bin_attr_info,
+ &bin_attr_sensor,
+ &bin_attr_tcu,
+ &bin_attr_profile_settings,
+ &bin_attr_profile_buttons,
+ &bin_attr_control,
+ &bin_attr_talk,
+ &bin_attr_macro,
+ &bin_attr_tcu_image,
+ NULL,
+};
+
+static const struct attribute_group konepure_group = {
+ .bin_attrs = konepure_bin_attributes,
+};
+
+static const struct attribute_group *konepure_groups[] = {
+ &konepure_group,
+ NULL,
};
+
static int konepure_init_konepure_device_struct(struct usb_device *usb_dev,
struct konepure_device *konepure)
{
konepure_class = class_create(THIS_MODULE, "konepure");
if (IS_ERR(konepure_class))
return PTR_ERR(konepure_class);
- konepure_class->dev_bin_attrs = konepure_bin_attributes;
+ konepure_class->dev_groups = konepure_groups;
retval = hid_register_driver(&konepure_driver);
if (retval)
KOVAPLUS_SYSFS_R(thingy, THINGY)
#define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
-{ \
+KOVAPLUS_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = KOVAPLUS_SIZE_ ## THINGY, \
.read = kovaplus_sysfs_read_ ## thingy, \
.write = kovaplus_sysfs_write_ ## thingy \
}
-#define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
-{ \
- .attr = { .name = #thingy, .mode = 0440 }, \
- .size = KOVAPLUS_SIZE_ ## THINGY, \
- .read = kovaplus_sysfs_read_ ## thingy, \
-}
-
#define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
-{ \
+KOVAPLUS_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = KOVAPLUS_SIZE_ ## THINGY, \
.write = kovaplus_sysfs_write_ ## thingy \
}
-
-KOVAPLUS_SYSFS_W(control, CONTROL)
-KOVAPLUS_SYSFS_RW(info, INFO)
-KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
-KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL);
+KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO);
+KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
+KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
KOVAPLUS_COMMAND_PROFILE_BUTTONS);
}
+#define PROFILE_ATTR(number) \
+static struct bin_attribute bin_attr_profile##number##_settings = { \
+ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+ .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \
+ .read = kovaplus_sysfs_read_profilex_settings, \
+ .private = &profile_numbers[number-1], \
+}; \
+static struct bin_attribute bin_attr_profile##number##_buttons = { \
+ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
+ .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \
+ .read = kovaplus_sysfs_read_profilex_buttons, \
+ .private = &profile_numbers[number-1], \
+};
+PROFILE_ATTR(1);
+PROFILE_ATTR(2);
+PROFILE_ATTR(3);
+PROFILE_ATTR(4);
+PROFILE_ATTR(5);
+
static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
return size;
}
+static DEVICE_ATTR(actual_profile, 0660,
+ kovaplus_sysfs_show_actual_profile,
+ kovaplus_sysfs_set_actual_profile);
static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_cpi);
}
+static DEVICE_ATTR(actual_cpi, 0440, kovaplus_sysfs_show_actual_cpi, NULL);
static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_x_sensitivity);
}
+static DEVICE_ATTR(actual_sensitivity_x, 0440,
+ kovaplus_sysfs_show_actual_sensitivity_x, NULL);
static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_y_sensitivity);
}
+static DEVICE_ATTR(actual_sensitivity_y, 0440,
+ kovaplus_sysfs_show_actual_sensitivity_y, NULL);
static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
}
+static DEVICE_ATTR(firmware_version, 0440,
+ kovaplus_sysfs_show_firmware_version, NULL);
+
+static struct attribute *kovaplus_attrs[] = {
+ &dev_attr_actual_cpi.attr,
+ &dev_attr_firmware_version.attr,
+ &dev_attr_actual_profile.attr,
+ &dev_attr_actual_sensitivity_x.attr,
+ &dev_attr_actual_sensitivity_y.attr,
+ NULL,
+};
+
+static struct bin_attribute *kovaplus_bin_attributes[] = {
+ &bin_attr_control,
+ &bin_attr_info,
+ &bin_attr_profile_settings,
+ &bin_attr_profile_buttons,
+ &bin_attr_profile1_settings,
+ &bin_attr_profile2_settings,
+ &bin_attr_profile3_settings,
+ &bin_attr_profile4_settings,
+ &bin_attr_profile5_settings,
+ &bin_attr_profile1_buttons,
+ &bin_attr_profile2_buttons,
+ &bin_attr_profile3_buttons,
+ &bin_attr_profile4_buttons,
+ &bin_attr_profile5_buttons,
+ NULL,
+};
-static struct device_attribute kovaplus_attributes[] = {
- __ATTR(actual_cpi, 0440,
- kovaplus_sysfs_show_actual_cpi, NULL),
- __ATTR(firmware_version, 0440,
- kovaplus_sysfs_show_firmware_version, NULL),
- __ATTR(actual_profile, 0660,
- kovaplus_sysfs_show_actual_profile,
- kovaplus_sysfs_set_actual_profile),
- __ATTR(actual_sensitivity_x, 0440,
- kovaplus_sysfs_show_actual_sensitivity_x, NULL),
- __ATTR(actual_sensitivity_y, 0440,
- kovaplus_sysfs_show_actual_sensitivity_y, NULL),
- __ATTR_NULL
+static const struct attribute_group kovaplus_group = {
+ .attrs = kovaplus_attrs,
+ .bin_attrs = kovaplus_bin_attributes,
};
-static struct bin_attribute kovaplus_bin_attributes[] = {
- KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
- KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO),
- KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
- KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
+static const struct attribute_group *kovaplus_groups[] = {
+ &kovaplus_group,
+ NULL,
};
static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev,
kovaplus_class = class_create(THIS_MODULE, "kovaplus");
if (IS_ERR(kovaplus_class))
return PTR_ERR(kovaplus_class);
- kovaplus_class->dev_attrs = kovaplus_attributes;
- kovaplus_class->dev_bin_attrs = kovaplus_bin_attributes;
+ kovaplus_class->dev_groups = kovaplus_groups;
retval = hid_register_driver(&kovaplus_driver);
if (retval)
PYRA_SYSFS_R(thingy, THINGY)
#define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
-{ \
+PYRA_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = PYRA_SIZE_ ## THINGY, \
.read = pyra_sysfs_read_ ## thingy, \
}
#define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
-{ \
+PYRA_SYSFS_R(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0440 }, \
.size = PYRA_SIZE_ ## THINGY, \
.read = pyra_sysfs_read_ ## thingy, \
}
#define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
-{ \
+PYRA_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = PYRA_SIZE_ ## THINGY, \
.write = pyra_sysfs_write_ ## thingy \
}
-PYRA_SYSFS_W(control, CONTROL)
-PYRA_SYSFS_RW(info, INFO)
-PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
-PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
-PYRA_SYSFS_R(settings, SETTINGS)
+PYRA_BIN_ATTRIBUTE_W(control, CONTROL);
+PYRA_BIN_ATTRIBUTE_RW(info, INFO);
+PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
+PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
PYRA_COMMAND_PROFILE_BUTTONS);
}
+#define PROFILE_ATTR(number) \
+static struct bin_attribute bin_attr_profile##number##_settings = { \
+ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+ .size = PYRA_SIZE_PROFILE_SETTINGS, \
+ .read = pyra_sysfs_read_profilex_settings, \
+ .private = &profile_numbers[number-1], \
+}; \
+static struct bin_attribute bin_attr_profile##number##_buttons = { \
+ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
+ .size = PYRA_SIZE_PROFILE_BUTTONS, \
+ .read = pyra_sysfs_read_profilex_buttons, \
+ .private = &profile_numbers[number-1], \
+};
+PROFILE_ATTR(1);
+PROFILE_ATTR(2);
+PROFILE_ATTR(3);
+PROFILE_ATTR(4);
+PROFILE_ATTR(5);
+
static ssize_t pyra_sysfs_write_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
return PYRA_SIZE_SETTINGS;
}
+PYRA_SYSFS_R(settings, SETTINGS);
+static struct bin_attribute bin_attr_settings =
+ __BIN_ATTR(settings, (S_IWUSR | S_IRUGO),
+ pyra_sysfs_read_settings, pyra_sysfs_write_settings,
+ PYRA_SIZE_SETTINGS);
static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
struct device_attribute *attr, char *buf)
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
}
+static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
}
+static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
+static DEVICE_ATTR(startup_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
}
+static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version,
+ NULL);
+
+static struct attribute *pyra_attrs[] = {
+ &dev_attr_actual_cpi.attr,
+ &dev_attr_actual_profile.attr,
+ &dev_attr_firmware_version.attr,
+ &dev_attr_startup_profile.attr,
+ NULL,
+};
+
+static struct bin_attribute *pyra_bin_attributes[] = {
+ &bin_attr_control,
+ &bin_attr_info,
+ &bin_attr_profile_settings,
+ &bin_attr_profile_buttons,
+ &bin_attr_settings,
+ &bin_attr_profile1_settings,
+ &bin_attr_profile2_settings,
+ &bin_attr_profile3_settings,
+ &bin_attr_profile4_settings,
+ &bin_attr_profile5_settings,
+ &bin_attr_profile1_buttons,
+ &bin_attr_profile2_buttons,
+ &bin_attr_profile3_buttons,
+ &bin_attr_profile4_buttons,
+ &bin_attr_profile5_buttons,
+ NULL,
+};
-static struct device_attribute pyra_attributes[] = {
- __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL),
- __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL),
- __ATTR(firmware_version, 0440,
- pyra_sysfs_show_firmware_version, NULL),
- __ATTR(startup_profile, 0440,
- pyra_sysfs_show_actual_profile, NULL),
- __ATTR_NULL
+static const struct attribute_group pyra_group = {
+ .attrs = pyra_attrs,
+ .bin_attrs = pyra_bin_attributes,
};
-static struct bin_attribute pyra_bin_attributes[] = {
- PYRA_BIN_ATTRIBUTE_W(control, CONTROL),
- PYRA_BIN_ATTRIBUTE_RW(info, INFO),
- PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
- PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
- PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS),
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_SETTINGS,
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_SETTINGS,
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_SETTINGS,
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_SETTINGS,
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_SETTINGS,
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_BUTTONS,
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_BUTTONS,
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_BUTTONS,
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_BUTTONS,
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = PYRA_SIZE_PROFILE_BUTTONS,
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
+static const struct attribute_group *pyra_groups[] = {
+ &pyra_group,
+ NULL,
};
static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
pyra_class = class_create(THIS_MODULE, "pyra");
if (IS_ERR(pyra_class))
return PTR_ERR(pyra_class);
- pyra_class->dev_attrs = pyra_attributes;
- pyra_class->dev_bin_attrs = pyra_bin_attributes;
+ pyra_class->dev_groups = pyra_groups;
retval = hid_register_driver(&pyra_driver);
if (retval)
SAVU_SYSFS_R(thingy, THINGY)
#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
-{ \
+SAVU_SYSFS_RW(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0660 }, \
.size = SAVU_SIZE_ ## THINGY, \
.read = savu_sysfs_read_ ## thingy, \
.write = savu_sysfs_write_ ## thingy \
}
-#define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \
-{ \
- .attr = { .name = #thingy, .mode = 0440 }, \
- .size = SAVU_SIZE_ ## THINGY, \
- .read = savu_sysfs_read_ ## thingy, \
-}
-
#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
-{ \
+SAVU_SYSFS_W(thingy, THINGY); \
+static struct bin_attribute bin_attr_##thingy = { \
.attr = { .name = #thingy, .mode = 0220 }, \
.size = SAVU_SIZE_ ## THINGY, \
.write = savu_sysfs_write_ ## thingy \
}
-SAVU_SYSFS_W(control, CONTROL)
-SAVU_SYSFS_RW(profile, PROFILE)
-SAVU_SYSFS_RW(general, GENERAL)
-SAVU_SYSFS_RW(buttons, BUTTONS)
-SAVU_SYSFS_RW(macro, MACRO)
-SAVU_SYSFS_RW(info, INFO)
-SAVU_SYSFS_RW(sensor, SENSOR)
-
-static struct bin_attribute savu_bin_attributes[] = {
- SAVU_BIN_ATTRIBUTE_W(control, CONTROL),
- SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE),
- SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
- SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
- SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
- SAVU_BIN_ATTRIBUTE_RW(info, INFO),
- SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR),
- __ATTR_NULL
+SAVU_BIN_ATTRIBUTE_W(control, CONTROL);
+SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE);
+SAVU_BIN_ATTRIBUTE_RW(general, GENERAL);
+SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS);
+SAVU_BIN_ATTRIBUTE_RW(macro, MACRO);
+SAVU_BIN_ATTRIBUTE_RW(info, INFO);
+SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR);
+
+static struct bin_attribute *savu_bin_attributes[] = {
+ &bin_attr_control,
+ &bin_attr_profile,
+ &bin_attr_general,
+ &bin_attr_buttons,
+ &bin_attr_macro,
+ &bin_attr_info,
+ &bin_attr_sensor,
+ NULL,
+};
+
+static const struct attribute_group savu_group = {
+ .bin_attrs = savu_bin_attributes,
+};
+
+static const struct attribute_group *savu_groups[] = {
+ &savu_group,
+ NULL,
};
static int savu_init_savu_device_struct(struct usb_device *usb_dev,
savu_class = class_create(THIS_MODULE, "savu");
if (IS_ERR(savu_class))
return PTR_ERR(savu_class);
- savu_class->dev_bin_attrs = savu_bin_attributes;
+ savu_class->dev_groups = savu_groups;
retval = hid_register_driver(&savu_driver);
if (retval)
* Gameport driver operations
*/
-static ssize_t gameport_driver_show_description(struct device_driver *drv, char *buf)
+static ssize_t description_show(struct device_driver *drv, char *buf)
{
struct gameport_driver *driver = to_gameport_driver(drv);
return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
+static DRIVER_ATTR_RO(description);
-static struct driver_attribute gameport_driver_attrs[] = {
- __ATTR(description, S_IRUGO, gameport_driver_show_description, NULL),
- __ATTR_NULL
+static struct attribute *gameport_driver_attrs[] = {
+ &driver_attr_description.attr,
+ NULL
};
+ATTRIBUTE_GROUPS(gameport_driver);
static int gameport_driver_probe(struct device *dev)
{
static struct bus_type gameport_bus = {
.name = "gameport",
.dev_attrs = gameport_device_attrs,
- .drv_attrs = gameport_driver_attrs,
+ .drv_groups = gameport_driver_groups,
.match = gameport_bus_match,
.probe = gameport_driver_probe,
.remove = gameport_driver_remove,
* Serio driver operations
*/
-static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf)
+static ssize_t description_show(struct device_driver *drv, char *buf)
{
struct serio_driver *driver = to_serio_driver(drv);
return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
+static DRIVER_ATTR_RO(description);
-static ssize_t serio_driver_show_bind_mode(struct device_driver *drv, char *buf)
+static ssize_t bind_mode_show(struct device_driver *drv, char *buf)
{
struct serio_driver *serio_drv = to_serio_driver(drv);
return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto");
}
-static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char *buf, size_t count)
+static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count)
{
struct serio_driver *serio_drv = to_serio_driver(drv);
int retval;
return retval;
}
+static DRIVER_ATTR_RW(bind_mode);
-
-static struct driver_attribute serio_driver_attrs[] = {
- __ATTR(description, S_IRUGO, serio_driver_show_description, NULL),
- __ATTR(bind_mode, S_IWUSR | S_IRUGO,
- serio_driver_show_bind_mode, serio_driver_set_bind_mode),
- __ATTR_NULL
+static struct attribute *serio_driver_attrs[] = {
+ &driver_attr_description.attr,
+ &driver_attr_bind_mode.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(serio_driver);
static int serio_driver_probe(struct device *dev)
{
static struct bus_type serio_bus = {
.name = "serio",
.dev_attrs = serio_device_attrs,
- .drv_attrs = serio_driver_attrs,
+ .drv_groups = serio_driver_groups,
.match = serio_bus_match,
.uevent = serio_uevent,
.probe = serio_driver_probe,
/* nothing to do: the device is part of its parent's data structure */
}
-static ssize_t _show_id(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
return -ENODEV;
return sprintf(buf, "%d\n", mdev->id);
}
+static DEVICE_ATTR_RO(id);
-static ssize_t _show_nrbchan(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t nrbchan_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
return -ENODEV;
return sprintf(buf, "%d\n", mdev->nrbchan);
}
+static DEVICE_ATTR_RO(nrbchan);
-static ssize_t _show_d_protocols(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t d_protocols_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Dprotocols);
}
+static DEVICE_ATTR_RO(d_protocols);
-static ssize_t _show_b_protocols(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t b_protocols_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
}
+static DEVICE_ATTR_RO(b_protocols);
-static ssize_t _show_protocol(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t protocol_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
return -ENODEV;
return sprintf(buf, "%d\n", mdev->D.protocol);
}
+static DEVICE_ATTR_RO(protocol);
-static ssize_t _show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
strcpy(buf, dev_name(dev));
return strlen(buf);
}
+static DEVICE_ATTR_RO(name);
#if 0 /* hangs */
-static ssize_t _set_name(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t name_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int err = 0;
char *out = kmalloc(count + 1, GFP_KERNEL);
return (err < 0) ? err : count;
}
+static DEVICE_ATTR_RW(name);
#endif
-static ssize_t _show_channelmap(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t channelmap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
char *bp = buf;
return bp - buf;
}
-
-static struct device_attribute mISDN_dev_attrs[] = {
- __ATTR(id, S_IRUGO, _show_id, NULL),
- __ATTR(d_protocols, S_IRUGO, _show_d_protocols, NULL),
- __ATTR(b_protocols, S_IRUGO, _show_b_protocols, NULL),
- __ATTR(protocol, S_IRUGO, _show_protocol, NULL),
- __ATTR(channelmap, S_IRUGO, _show_channelmap, NULL),
- __ATTR(nrbchan, S_IRUGO, _show_nrbchan, NULL),
- __ATTR(name, S_IRUGO, _show_name, NULL),
-/* __ATTR(name, S_IRUGO | S_IWUSR, _show_name, _set_name), */
- {}
+static DEVICE_ATTR_RO(channelmap);
+
+static struct attribute *mISDN_attrs[] = {
+ &dev_attr_id.attr,
+ &dev_attr_d_protocols.attr,
+ &dev_attr_b_protocols.attr,
+ &dev_attr_protocol.attr,
+ &dev_attr_channelmap.attr,
+ &dev_attr_nrbchan.attr,
+ &dev_attr_name.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(mISDN);
static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env)
{
.name = "mISDN",
.owner = THIS_MODULE,
.dev_uevent = mISDN_uevent,
- .dev_attrs = mISDN_dev_attrs,
+ .dev_groups = mISDN_groups,
.dev_release = mISDN_dev_release,
.class_release = mISDN_class_release,
};
led_cdev->brightness = led_cdev->brightness_get(led_cdev);
}
-static ssize_t led_brightness_show(struct device *dev,
+static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", led_cdev->brightness);
}
-static ssize_t led_brightness_store(struct device *dev,
+static ssize_t brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return size;
}
+static DEVICE_ATTR_RW(brightness);
static ssize_t led_max_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
return sprintf(buf, "%u\n", led_cdev->max_brightness);
}
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
-static struct device_attribute led_class_attrs[] = {
- __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
- __ATTR(max_brightness, 0444, led_max_brightness_show, NULL),
#ifdef CONFIG_LEDS_TRIGGERS
- __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
+static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+static struct attribute *led_trigger_attrs[] = {
+ &dev_attr_trigger.attr,
+ NULL,
+};
+static const struct attribute_group led_trigger_group = {
+ .attrs = led_trigger_attrs,
+};
+#endif
+
+static struct attribute *led_class_attrs[] = {
+ &dev_attr_brightness.attr,
+ &dev_attr_max_brightness.attr,
+ NULL,
+};
+
+static const struct attribute_group led_group = {
+ .attrs = led_class_attrs,
+};
+
+static const struct attribute_group *led_groups[] = {
+ &led_group,
+#ifdef CONFIG_LEDS_TRIGGERS
+ &led_trigger_group,
#endif
- __ATTR_NULL,
+ NULL,
};
static void led_timer_function(unsigned long data)
if (IS_ERR(leds_class))
return PTR_ERR(leds_class);
leds_class->pm = &leds_class_dev_pm_ops;
- leds_class->dev_attrs = led_class_attrs;
+ leds_class->dev_groups = led_groups;
return 0;
}
* sysfs stuff
*/
-static ssize_t show_index(struct device *cd,
- struct device_attribute *attr, char *buf)
+static ssize_t index_show(struct device *cd,
+ struct device_attribute *attr, char *buf)
{
struct video_device *vdev = to_video_device(cd);
return sprintf(buf, "%i\n", vdev->index);
}
+static DEVICE_ATTR_RO(index);
-static ssize_t show_debug(struct device *cd,
- struct device_attribute *attr, char *buf)
+static ssize_t debug_show(struct device *cd,
+ struct device_attribute *attr, char *buf)
{
struct video_device *vdev = to_video_device(cd);
return sprintf(buf, "%i\n", vdev->debug);
}
-static ssize_t set_debug(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
+static ssize_t debug_store(struct device *cd, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct video_device *vdev = to_video_device(cd);
int res = 0;
vdev->debug = value;
return len;
}
+static DEVICE_ATTR_RW(debug);
-static ssize_t show_name(struct device *cd,
+static ssize_t name_show(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev = to_video_device(cd);
return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
}
+static DEVICE_ATTR_RO(name);
-static struct device_attribute video_device_attrs[] = {
- __ATTR(name, S_IRUGO, show_name, NULL),
- __ATTR(debug, 0644, show_debug, set_debug),
- __ATTR(index, S_IRUGO, show_index, NULL),
- __ATTR_NULL
+static struct attribute *video_device_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_debug.attr,
+ &dev_attr_index.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(video_device);
/*
* Active devices
static struct class video_class = {
.name = VIDEO_NAME,
- .dev_attrs = video_device_attrs,
+ .dev_groups = video_device_groups,
};
struct video_device *video_devdata(struct file *file)
return sprintf(buf, "%s\n", c2dev->name);
}
+static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
static ssize_t c2port_show_flash_blocks_num(struct device *dev,
struct device_attribute *attr, char *buf)
return sprintf(buf, "%d\n", ops->blocks_num);
}
+static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
static ssize_t c2port_show_flash_block_size(struct device *dev,
struct device_attribute *attr, char *buf)
return sprintf(buf, "%d\n", ops->block_size);
}
+static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
static ssize_t c2port_show_flash_size(struct device *dev,
struct device_attribute *attr, char *buf)
return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
}
+static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
-static ssize_t c2port_show_access(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t access_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct c2port_device *c2dev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", c2dev->access);
}
-static ssize_t c2port_store_access(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t access_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct c2port_device *c2dev = dev_get_drvdata(dev);
struct c2port_ops *ops = c2dev->ops;
return count;
}
+static DEVICE_ATTR_RW(access);
static ssize_t c2port_store_reset(struct device *dev,
struct device_attribute *attr,
return count;
}
+static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
{
return ret;
}
+static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
{
return ret;
}
+static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
static ssize_t c2port_show_flash_access(struct device *dev,
struct device_attribute *attr, char *buf)
return count;
}
+static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
+ c2port_store_flash_access);
static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
{
return count;
}
+static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
char *buffer, loff_t offset, size_t count)
return ret;
}
+/* size is computed at run-time */
+static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
+ c2port_write_flash_data, 0);
/*
* Class attributes
*/
+static struct attribute *c2port_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_flash_blocks_num.attr,
+ &dev_attr_flash_block_size.attr,
+ &dev_attr_flash_size.attr,
+ &dev_attr_access.attr,
+ &dev_attr_reset.attr,
+ &dev_attr_dev_id.attr,
+ &dev_attr_rev_id.attr,
+ &dev_attr_flash_access.attr,
+ &dev_attr_flash_erase.attr,
+ NULL,
+};
-static struct device_attribute c2port_attrs[] = {
- __ATTR(name, 0444, c2port_show_name, NULL),
- __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL),
- __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL),
- __ATTR(flash_size, 0444, c2port_show_flash_size, NULL),
- __ATTR(access, 0644, c2port_show_access, c2port_store_access),
- __ATTR(reset, 0200, NULL, c2port_store_reset),
- __ATTR(dev_id, 0444, c2port_show_dev_id, NULL),
- __ATTR(rev_id, 0444, c2port_show_rev_id, NULL),
-
- __ATTR(flash_access, 0644, c2port_show_flash_access,
- c2port_store_flash_access),
- __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase),
- __ATTR_NULL,
+static struct bin_attribute *c2port_bin_attrs[] = {
+ &bin_attr_flash_data,
+ NULL,
};
-static struct bin_attribute c2port_bin_attrs = {
- .attr = {
- .name = "flash_data",
- .mode = 0644
- },
- .read = c2port_read_flash_data,
- .write = c2port_write_flash_data,
- /* .size is computed at run-time */
+static const struct attribute_group c2port_group = {
+ .attrs = c2port_attrs,
+ .bin_attrs = c2port_bin_attrs,
+};
+
+static const struct attribute_group *c2port_groups[] = {
+ &c2port_group,
+ NULL,
};
/*
goto error_idr_alloc;
c2dev->id = ret;
+ bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
+
c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
"c2port%d", c2dev->id);
if (unlikely(IS_ERR(c2dev->dev))) {
c2dev->ops = ops;
mutex_init(&c2dev->mutex);
- /* Create binary file */
- c2port_bin_attrs.size = ops->blocks_num * ops->block_size;
- ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs);
- if (unlikely(ret))
- goto error_device_create_bin_file;
-
/* By default C2 port access is off */
c2dev->access = c2dev->flash_access = 0;
ops->access(c2dev, 0);
return c2dev;
-error_device_create_bin_file:
- device_destroy(c2port_class, 0);
-
error_device_create:
spin_lock_irq(&c2port_idr_lock);
idr_remove(&c2port_idr, c2dev->id);
dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
- device_remove_bin_file(c2dev->dev, &c2port_bin_attrs);
spin_lock_irq(&c2port_idr_lock);
idr_remove(&c2port_idr, c2dev->id);
spin_unlock_irq(&c2port_idr_lock);
printk(KERN_ERR "c2port: failed to allocate class\n");
return PTR_ERR(c2port_class);
}
- c2port_class->dev_attrs = c2port_attrs;
+ c2port_class->dev_groups = c2port_groups;
return 0;
}
put_device(dev->parent);
}
-static const struct attribute_group *enclosure_groups[];
+static const struct attribute_group *enclosure_component_groups[];
/**
* enclosure_component_register - add a particular component to an enclosure
dev_set_name(cdev, "%u", number);
cdev->release = enclosure_component_release;
- cdev->groups = enclosure_groups;
+ cdev->groups = enclosure_component_groups;
err = device_register(cdev);
if (err) {
* sysfs pieces below
*/
-static ssize_t enclosure_show_components(struct device *cdev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t components_show(struct device *cdev,
+ struct device_attribute *attr, char *buf)
{
struct enclosure_device *edev = to_enclosure_device(cdev);
return snprintf(buf, 40, "%d\n", edev->components);
}
+static DEVICE_ATTR_RO(components);
-static struct device_attribute enclosure_attrs[] = {
- __ATTR(components, S_IRUGO, enclosure_show_components, NULL),
- __ATTR_NULL
+static struct attribute *enclosure_class_attrs[] = {
+ &dev_attr_components.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(enclosure_class);
static struct class enclosure_class = {
.name = "enclosure",
.owner = THIS_MODULE,
.dev_release = enclosure_release,
- .dev_attrs = enclosure_attrs,
+ .dev_groups = enclosure_class_groups,
};
static const char *const enclosure_status [] = {
&dev_attr_type.attr,
NULL
};
-
-static struct attribute_group enclosure_group = {
- .attrs = enclosure_component_attrs,
-};
-
-static const struct attribute_group *enclosure_groups[] = {
- &enclosure_group,
- NULL
-};
+ATTRIBUTE_GROUPS(enclosure_component);
static int __init enclosure_init(void)
{
return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
+static DEVICE_ATTR_RO(modalias);
-static struct device_attribute mei_cl_dev_attrs[] = {
- __ATTR_RO(modalias),
- __ATTR_NULL,
+static struct attribute *mei_cl_dev_attrs[] = {
+ &dev_attr_modalias.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(mei_cl_dev);
static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
{
static struct bus_type mei_cl_bus_type = {
.name = "mei",
- .dev_attrs = mei_cl_dev_attrs,
+ .dev_groups = mei_cl_dev_groups,
.match = mei_cl_device_match,
.probe = mei_cl_device_probe,
.remove = mei_cl_device_remove,
if (IS_ERR(plat_dev))
return NULL;
- for (i = 0; attr_name(niu_parent_attributes[i]); i++) {
+ for (i = 0; niu_parent_attributes[i].attr.name; i++) {
int err = device_create_file(&plat_dev->dev,
&niu_parent_attributes[i]);
if (err)
return sprintf(buf, "wmi:%s\n", guid_string);
}
+static DEVICE_ATTR_RO(modalias);
-static struct device_attribute wmi_dev_attrs[] = {
- __ATTR_RO(modalias),
- __ATTR_NULL
+static struct attribute *wmi_attrs[] = {
+ &dev_attr_modalias.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(wmi);
static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
.name = "wmi",
.dev_release = wmi_dev_free,
.dev_uevent = wmi_dev_uevent,
- .dev_attrs = wmi_dev_attrs,
+ .dev_groups = wmi_groups,
};
static int wmi_create_device(const struct guid_block *gblock,
pr_err("failed to allocate class\n");
return PTR_ERR(pps_class);
}
- pps_class->dev_attrs = pps_attrs;
+ pps_class->dev_groups = pps_groups;
err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps");
if (err < 0) {
* Attribute functions
*/
-static ssize_t pps_show_assert(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t assert_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
(long long) pps->assert_tu.sec, pps->assert_tu.nsec,
pps->assert_sequence);
}
+static DEVICE_ATTR_RO(assert);
-static ssize_t pps_show_clear(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t clear_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
(long long) pps->clear_tu.sec, pps->clear_tu.nsec,
pps->clear_sequence);
}
+static DEVICE_ATTR_RO(clear);
-static ssize_t pps_show_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
return sprintf(buf, "%4x\n", pps->info.mode);
}
+static DEVICE_ATTR_RO(mode);
-static ssize_t pps_show_echo(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t echo_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", !!pps->info.echo);
}
+static DEVICE_ATTR_RO(echo);
-static ssize_t pps_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", pps->info.name);
}
+static DEVICE_ATTR_RO(name);
-static ssize_t pps_show_path(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t path_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct pps_device *pps = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", pps->info.path);
}
+static DEVICE_ATTR_RO(path);
+
+static struct attribute *pps_attrs[] = {
+ &dev_attr_assert.attr,
+ &dev_attr_clear.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_echo.attr,
+ &dev_attr_name.attr,
+ &dev_attr_path.attr,
+ NULL,
+};
+
+static const struct attribute_group pps_group = {
+ .attrs = pps_attrs,
+};
-struct device_attribute pps_attrs[] = {
- __ATTR(assert, S_IRUGO, pps_show_assert, NULL),
- __ATTR(clear, S_IRUGO, pps_show_clear, NULL),
- __ATTR(mode, S_IRUGO, pps_show_mode, NULL),
- __ATTR(echo, S_IRUGO, pps_show_echo, NULL),
- __ATTR(name, S_IRUGO, pps_show_name, NULL),
- __ATTR(path, S_IRUGO, pps_show_path, NULL),
- __ATTR_NULL,
+const struct attribute_group *pps_groups[] = {
+ &pps_group,
+ NULL,
};
goto no_region;
}
- ptp_class->dev_attrs = ptp_dev_attrs;
+ ptp_class->dev_groups = ptp_groups;
pr_info("PTP clock support registered\n");
return 0;
* see ptp_sysfs.c
*/
-extern struct device_attribute ptp_dev_attrs[];
+extern const struct attribute_group *ptp_groups[];
int ptp_cleanup_sysfs(struct ptp_clock *ptp);
struct ptp_clock *ptp = dev_get_drvdata(dev);
return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name);
}
+static DEVICE_ATTR(clock_name, 0444, clock_name_show, NULL);
-#define PTP_SHOW_INT(name) \
-static ssize_t name##_show(struct device *dev, \
+#define PTP_SHOW_INT(name, var) \
+static ssize_t var##_show(struct device *dev, \
struct device_attribute *attr, char *page) \
{ \
struct ptp_clock *ptp = dev_get_drvdata(dev); \
- return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->name); \
-}
-
-PTP_SHOW_INT(max_adj);
-PTP_SHOW_INT(n_alarm);
-PTP_SHOW_INT(n_ext_ts);
-PTP_SHOW_INT(n_per_out);
-PTP_SHOW_INT(pps);
+ return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var); \
+} \
+static DEVICE_ATTR(name, 0444, var##_show, NULL);
+
+PTP_SHOW_INT(max_adjustment, max_adj);
+PTP_SHOW_INT(n_alarms, n_alarm);
+PTP_SHOW_INT(n_external_timestamps, n_ext_ts);
+PTP_SHOW_INT(n_periodic_outputs, n_per_out);
+PTP_SHOW_INT(pps_available, pps);
+
+static struct attribute *ptp_attrs[] = {
+ &dev_attr_clock_name.attr,
+ &dev_attr_max_adjustment.attr,
+ &dev_attr_n_alarms.attr,
+ &dev_attr_n_external_timestamps.attr,
+ &dev_attr_n_periodic_outputs.attr,
+ &dev_attr_pps_available.attr,
+ NULL,
+};
-#define PTP_RO_ATTR(_var, _name) { \
- .attr = { .name = __stringify(_name), .mode = 0444 }, \
- .show = _var##_show, \
-}
+static const struct attribute_group ptp_group = {
+ .attrs = ptp_attrs,
+};
-struct device_attribute ptp_dev_attrs[] = {
- PTP_RO_ATTR(clock_name, clock_name),
- PTP_RO_ATTR(max_adj, max_adjustment),
- PTP_RO_ATTR(n_alarm, n_alarms),
- PTP_RO_ATTR(n_ext_ts, n_external_timestamps),
- PTP_RO_ATTR(n_per_out, n_periodic_outputs),
- PTP_RO_ATTR(pps, pps_available),
- __ATTR_NULL,
+const struct attribute_group *ptp_groups[] = {
+ &ptp_group,
+ NULL,
};
+
static ssize_t extts_enable_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
*/
static ssize_t
-rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr,
- char *buf)
+name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", to_rtc_device(dev)->name);
}
+static DEVICE_ATTR_RO(name);
static ssize_t
-rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr,
- char *buf)
+date_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t retval;
struct rtc_time tm;
return retval;
}
+static DEVICE_ATTR_RO(date);
static ssize_t
-rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr,
- char *buf)
+time_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t retval;
struct rtc_time tm;
return retval;
}
+static DEVICE_ATTR_RO(time);
static ssize_t
-rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
- char *buf)
+since_epoch_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t retval;
struct rtc_time tm;
return retval;
}
+static DEVICE_ATTR_RO(since_epoch);
static ssize_t
-rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr,
- char *buf)
+max_user_freq_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
}
static ssize_t
-rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
+max_user_freq_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t n)
{
struct rtc_device *rtc = to_rtc_device(dev);
return n;
}
+static DEVICE_ATTR_RW(max_user_freq);
/**
* rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
* boot or resume event.
*/
static ssize_t
-rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
- char *buf)
+hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)
{
#ifdef CONFIG_RTC_HCTOSYS_DEVICE
if (rtc_hctosys_ret == 0 &&
#endif
return sprintf(buf, "0\n");
}
-
-static struct device_attribute rtc_attrs[] = {
- __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
- __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
- __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
- __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
- __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,
- rtc_sysfs_set_max_user_freq),
- __ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL),
- { },
+static DEVICE_ATTR_RO(hctosys);
+
+static struct attribute *rtc_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_date.attr,
+ &dev_attr_time.attr,
+ &dev_attr_since_epoch.attr,
+ &dev_attr_max_user_freq.attr,
+ &dev_attr_hctosys.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(rtc);
static ssize_t
rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr,
void __init rtc_sysfs_init(struct class *rtc_class)
{
- rtc_class->dev_attrs = rtc_attrs;
+ rtc_class->dev_groups = rtc_groups;
}
class_dev);
return sprintf(buf, "%s\n", ould->odi.osdname);
}
+static DEVICE_ATTR_RO(osdname);
static ssize_t systemid_show(struct device *dev, struct device_attribute *attr,
char *buf)
memcpy(buf, ould->odi.systemid, ould->odi.systemid_len);
return ould->odi.systemid_len;
}
+static DEVICE_ATTR_RO(systemid);
-static struct device_attribute osd_uld_attrs[] = {
- __ATTR(osdname, S_IRUGO, osdname_show, NULL),
- __ATTR(systemid, S_IRUGO, systemid_show, NULL),
- __ATTR_NULL,
+static struct attribute *osd_uld_attrs[] = {
+ &dev_attr_osdname.attr,
+ &dev_attr_systemid.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(osd_uld);
static struct class osd_uld_class = {
.owner = THIS_MODULE,
.name = "scsi_osd",
- .dev_attrs = osd_uld_attrs,
+ .dev_groups = osd_uld_groups,
};
/*
/* sysfs attribute files */
-static ssize_t show_max_read_buffer_kb(struct device *csdev,
+static ssize_t max_read_buffer_kb_show(struct device *csdev,
struct device_attribute *attr, char *buf)
{
unsigned int minor = MINOR(csdev->devt);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_max_read_buffer_kb(struct device *csdev,
+static ssize_t max_read_buffer_kb_store(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return err ? err : count;
}
+static DEVICE_ATTR_RW(max_read_buffer_kb);
-static ssize_t show_read_buffer_kb(struct device *csdev,
+static ssize_t read_buffer_kb_show(struct device *csdev,
struct device_attribute *attr, char *buf)
{
unsigned int minor = MINOR(csdev->devt);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_read_buffer_kb(struct device *csdev,
+static ssize_t read_buffer_kb_store(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return err ? err : count;
}
+static DEVICE_ATTR_RW(read_buffer_kb);
-static ssize_t show_max_write_buffer_kb(struct device *csdev,
+static ssize_t max_write_buffer_kb_show(struct device *csdev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_max_write_buffer_kb(struct device *csdev,
+static ssize_t max_write_buffer_kb_store(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return err ? err : count;
}
+static DEVICE_ATTR_RW(max_write_buffer_kb);
-static ssize_t show_write_buffer_kb(struct device *csdev,
+static ssize_t write_buffer_kb_show(struct device *csdev,
struct device_attribute *attr, char *buf)
{
unsigned int minor = MINOR(csdev->devt);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_write_buffer_kb(struct device *csdev,
+static ssize_t write_buffer_kb_store(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return err ? err : count;
}
+static DEVICE_ATTR_RW(write_buffer_kb);
-static struct device_attribute comedi_dev_attrs[] = {
- __ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR,
- show_max_read_buffer_kb, store_max_read_buffer_kb),
- __ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP,
- show_read_buffer_kb, store_read_buffer_kb),
- __ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR,
- show_max_write_buffer_kb, store_max_write_buffer_kb),
- __ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP,
- show_write_buffer_kb, store_write_buffer_kb),
- __ATTR_NULL
+static struct attribute *comedi_dev_attrs[] = {
+ &dev_attr_max_read_buffer_kb.attr,
+ &dev_attr_read_buffer_kb.attr,
+ &dev_attr_max_write_buffer_kb.attr,
+ &dev_attr_write_buffer_kb.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(comedi_dev);
static void comedi_set_subdevice_runflags(struct comedi_subdevice *s,
unsigned mask, unsigned bits)
return PTR_ERR(comedi_class);
}
- comedi_class->dev_attrs = comedi_dev_attrs;
+ comedi_class->dev_groups = comedi_dev_groups;
/* XXX requires /proc interface */
comedi_proc_init();
.default_attrs = portio_attrs,
};
-static ssize_t show_name(struct device *dev,
+static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", idev->info->name);
}
+static DEVICE_ATTR_RO(name);
-static ssize_t show_version(struct device *dev,
+static ssize_t version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", idev->info->version);
}
+static DEVICE_ATTR_RO(version);
-static ssize_t show_event(struct device *dev,
+static ssize_t event_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct uio_device *idev = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
}
+static DEVICE_ATTR_RO(event);
-static struct device_attribute uio_class_attributes[] = {
- __ATTR(name, S_IRUGO, show_name, NULL),
- __ATTR(version, S_IRUGO, show_version, NULL),
- __ATTR(event, S_IRUGO, show_event, NULL),
- {}
+static struct attribute *uio_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_version.attr,
+ &dev_attr_event.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(uio);
/* UIO class infrastructure */
static struct class uio_class = {
.name = "uio",
- .dev_attrs = uio_class_attributes,
+ .dev_groups = uio_groups,
};
/*
return retval;
}
-static ssize_t store_new_id(struct device_driver *driver,
+static ssize_t new_id_store(struct device_driver *driver,
const char *buf, size_t count)
{
struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
return retval;
}
-static ssize_t show_dynids(struct device_driver *driver, char *buf)
+static ssize_t new_id_show(struct device_driver *driver, char *buf)
{
struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
return usb_show_dynids(&usb_drv->dynids, buf);
}
+static DRIVER_ATTR_RW(new_id);
-static struct driver_attribute drv_attrs[] = {
- __ATTR(new_id, S_IRUGO | S_IWUSR, show_dynids, store_new_id),
- __ATTR_NULL,
+static struct attribute *usb_serial_drv_attrs[] = {
+ &driver_attr_new_id.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(usb_serial_drv);
static void free_dynids(struct usb_serial_driver *drv)
{
.match = usb_serial_device_match,
.probe = usb_serial_device_probe,
.remove = usb_serial_device_remove,
- .drv_attrs = drv_attrs,
+ .drv_groups = usb_serial_drv_groups,
};
int usb_serial_bus_register(struct usb_serial_driver *driver)
sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness");
}
-static ssize_t backlight_show_power(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t bl_power_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct backlight_device *bd = to_backlight_device(dev);
return sprintf(buf, "%d\n", bd->props.power);
}
-static ssize_t backlight_store_power(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int rc;
struct backlight_device *bd = to_backlight_device(dev);
return rc;
}
+static DEVICE_ATTR_RW(bl_power);
-static ssize_t backlight_show_brightness(struct device *dev,
+static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct backlight_device *bd = to_backlight_device(dev);
return sprintf(buf, "%d\n", bd->props.brightness);
}
-static ssize_t backlight_store_brightness(struct device *dev,
+static ssize_t brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc;
return rc;
}
+static DEVICE_ATTR_RW(brightness);
-static ssize_t backlight_show_type(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t type_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct backlight_device *bd = to_backlight_device(dev);
return sprintf(buf, "%s\n", backlight_types[bd->props.type]);
}
+static DEVICE_ATTR_RO(type);
-static ssize_t backlight_show_max_brightness(struct device *dev,
+static ssize_t max_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct backlight_device *bd = to_backlight_device(dev);
return sprintf(buf, "%d\n", bd->props.max_brightness);
}
+static DEVICE_ATTR_RO(max_brightness);
-static ssize_t backlight_show_actual_brightness(struct device *dev,
+static ssize_t actual_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int rc = -ENXIO;
return rc;
}
+static DEVICE_ATTR_RO(actual_brightness);
static struct class *backlight_class;
kfree(bd);
}
-static struct device_attribute bl_device_attributes[] = {
- __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power),
- __ATTR(brightness, 0644, backlight_show_brightness,
- backlight_store_brightness),
- __ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
- NULL),
- __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
- __ATTR(type, 0444, backlight_show_type, NULL),
- __ATTR_NULL,
+static struct attribute *bl_device_attrs[] = {
+ &dev_attr_bl_power.attr,
+ &dev_attr_brightness.attr,
+ &dev_attr_actual_brightness.attr,
+ &dev_attr_max_brightness.attr,
+ &dev_attr_type.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(bl_device);
/**
* backlight_force_update - tell the backlight subsystem that hardware state
return PTR_ERR(backlight_class);
}
- backlight_class->dev_attrs = bl_device_attributes;
+ backlight_class->dev_groups = bl_device_groups;
backlight_class->pm = &backlight_class_dev_pm_ops;
return 0;
}
}
#endif /* CONFIG_FB */
-static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
+static ssize_t lcd_power_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
int rc;
return rc;
}
-static ssize_t lcd_store_power(struct device *dev,
+static ssize_t lcd_power_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc;
return rc;
}
+static DEVICE_ATTR_RW(lcd_power);
-static ssize_t lcd_show_contrast(struct device *dev,
+static ssize_t contrast_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int rc = -ENXIO;
return rc;
}
-static ssize_t lcd_store_contrast(struct device *dev,
+static ssize_t contrast_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc;
return rc;
}
+static DEVICE_ATTR_RW(contrast);
-static ssize_t lcd_show_max_contrast(struct device *dev,
+static ssize_t max_contrast_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lcd_device *ld = to_lcd_device(dev);
return sprintf(buf, "%d\n", ld->props.max_contrast);
}
+static DEVICE_ATTR_RO(max_contrast);
static struct class *lcd_class;
kfree(ld);
}
-static struct device_attribute lcd_device_attributes[] = {
- __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power),
- __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
- __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
- __ATTR_NULL,
+static struct attribute *lcd_device_attrs[] = {
+ &dev_attr_lcd_power.attr,
+ &dev_attr_contrast.attr,
+ &dev_attr_max_contrast.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(lcd_device);
/**
* lcd_device_register - register a new object of lcd_device class.
return PTR_ERR(lcd_class);
}
- lcd_class->dev_attrs = lcd_device_attributes;
+ lcd_class->dev_groups = lcd_device_groups;
return 0;
}
return 1;
}
-static ssize_t w1_f29_read_state(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t state_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
}
-static ssize_t w1_f29_read_output(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t output_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
W1_F29_REG_OUTPUT_LATCH_STATE, buf);
}
-static ssize_t w1_f29_read_activity(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t activity_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
}
-static ssize_t w1_f29_read_cond_search_mask(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
}
-static ssize_t w1_f29_read_cond_search_polarity(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t cond_search_polarity_read(struct file *filp,
+ struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
{
if (count != 1 || off != 0)
return -EFAULT;
W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
}
-static ssize_t w1_f29_read_status_control(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
if (count != 1 || off != 0)
return -EFAULT;
W1_F29_REG_CONTROL_AND_STATUS, buf);
}
-
-
-
-static ssize_t w1_f29_write_output(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t output_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
u8 w1_buf[3];
/**
* Writing to the activity file resets the activity latches.
*/
-static ssize_t w1_f29_write_activity(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t activity_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
unsigned int retries = W1_F29_RETRIES;
return -EIO;
}
-static ssize_t w1_f29_write_status_control(
- struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf,
- loff_t off,
- size_t count)
+static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
u8 w1_buf[4];
return res;
}
-static struct bin_attribute w1_f29_sysfs_bin_files[] = {
- {
- .attr = {
- .name = "state",
- .mode = S_IRUGO,
- },
- .size = 1,
- .read = w1_f29_read_state,
- },
- {
- .attr = {
- .name = "output",
- .mode = S_IRUGO | S_IWUSR | S_IWGRP,
- },
- .size = 1,
- .read = w1_f29_read_output,
- .write = w1_f29_write_output,
- },
- {
- .attr = {
- .name = "activity",
- .mode = S_IRUGO,
- },
- .size = 1,
- .read = w1_f29_read_activity,
- .write = w1_f29_write_activity,
- },
- {
- .attr = {
- .name = "cond_search_mask",
- .mode = S_IRUGO,
- },
- .size = 1,
- .read = w1_f29_read_cond_search_mask,
- },
- {
- .attr = {
- .name = "cond_search_polarity",
- .mode = S_IRUGO,
- },
- .size = 1,
- .read = w1_f29_read_cond_search_polarity,
- },
- {
- .attr = {
- .name = "status_control",
- .mode = S_IRUGO | S_IWUSR | S_IWGRP,
- },
- .size = 1,
- .read = w1_f29_read_status_control,
- .write = w1_f29_write_status_control,
- }
+static BIN_ATTR_RO(state, 1);
+static BIN_ATTR_RW(output, 1);
+static BIN_ATTR_RW(activity, 1);
+static BIN_ATTR_RO(cond_search_mask, 1);
+static BIN_ATTR_RO(cond_search_polarity, 1);
+static BIN_ATTR_RW(status_control, 1);
+
+static struct bin_attribute *w1_f29_bin_attrs[] = {
+ &bin_attr_state,
+ &bin_attr_output,
+ &bin_attr_activity,
+ &bin_attr_cond_search_mask,
+ &bin_attr_cond_search_polarity,
+ &bin_attr_status_control,
+ NULL,
};
-static int w1_f29_add_slave(struct w1_slave *sl)
-{
- int err = 0;
- int i;
-
- err = w1_f29_disable_test_mode(sl);
- if (err)
- return err;
-
- for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i)
- err = sysfs_create_bin_file(
- &sl->dev.kobj,
- &(w1_f29_sysfs_bin_files[i]));
- if (err)
- while (--i >= 0)
- sysfs_remove_bin_file(&sl->dev.kobj,
- &(w1_f29_sysfs_bin_files[i]));
- return err;
-}
+static const struct attribute_group w1_f29_group = {
+ .bin_attrs = w1_f29_bin_attrs,
+};
-static void w1_f29_remove_slave(struct w1_slave *sl)
-{
- int i;
- for (i = ARRAY_SIZE(w1_f29_sysfs_bin_files) - 1; i >= 0; --i)
- sysfs_remove_bin_file(&sl->dev.kobj,
- &(w1_f29_sysfs_bin_files[i]));
-}
+static const struct attribute_group *w1_f29_groups[] = {
+ &w1_f29_group,
+ NULL,
+};
static struct w1_family_ops w1_f29_fops = {
- .add_slave = w1_f29_add_slave,
- .remove_slave = w1_f29_remove_slave,
+ .add_slave = w1_f29_disable_test_mode,
+ .groups = w1_f29_groups,
};
static struct w1_family w1_family_29 = {
#define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A
#define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA
-static ssize_t w1_f3a_read_state(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t state_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
dev_dbg(&sl->dev,
return 1;
}
-static ssize_t w1_f3a_write_output(
- struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static BIN_ATTR_RO(state, 1);
+
+static ssize_t output_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
u8 w1_buf[3];
return -EIO;
}
-#define NB_SYSFS_BIN_FILES 2
-static struct bin_attribute w1_f3a_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
- {
- .attr = {
- .name = "state",
- .mode = S_IRUGO,
- },
- .size = 1,
- .read = w1_f3a_read_state,
- },
- {
- .attr = {
- .name = "output",
- .mode = S_IRUGO | S_IWUSR | S_IWGRP,
- },
- .size = 1,
- .write = w1_f3a_write_output,
- }
+static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1);
+
+static struct bin_attribute *w1_f3a_bin_attrs[] = {
+ &bin_attr_state,
+ &bin_attr_output,
+ NULL,
};
-static int w1_f3a_add_slave(struct w1_slave *sl)
-{
- int err = 0;
- int i;
-
- for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
- err = sysfs_create_bin_file(
- &sl->dev.kobj,
- &(w1_f3a_sysfs_bin_files[i]));
- if (err)
- while (--i >= 0)
- sysfs_remove_bin_file(&sl->dev.kobj,
- &(w1_f3a_sysfs_bin_files[i]));
- return err;
-}
+static const struct attribute_group w1_f3a_group = {
+ .bin_attrs = w1_f3a_bin_attrs,
+};
-static void w1_f3a_remove_slave(struct w1_slave *sl)
-{
- int i;
- for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i)
- sysfs_remove_bin_file(&sl->dev.kobj,
- &(w1_f3a_sysfs_bin_files[i]));
-}
+static const struct attribute_group *w1_f3a_groups[] = {
+ &w1_f3a_group,
+ NULL,
+};
static struct w1_family_ops w1_f3a_fops = {
- .add_slave = w1_f3a_add_slave,
- .remove_slave = w1_f3a_remove_slave,
+ .groups = w1_f3a_groups,
};
static struct w1_family w1_family_3a = {
#define COUNTER_COUNT 4
#define READ_BYTE_COUNT 42
-static ssize_t w1_counter_read(struct device *device,
- struct device_attribute *attr, char *buf);
-
-static struct device_attribute w1_counter_attr =
- __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL);
-
-static ssize_t w1_counter_read(struct device *device,
- struct device_attribute *attr, char *out_buf)
+static ssize_t w1_slave_show(struct device *device,
+ struct device_attribute *attr, char *out_buf)
{
struct w1_slave *sl = dev_to_w1_slave(device);
struct w1_master *dev = sl->master;
return PAGE_SIZE - c;
}
-static int w1_f1d_add_slave(struct w1_slave *sl)
-{
- return device_create_file(&sl->dev, &w1_counter_attr);
-}
+static DEVICE_ATTR_RO(w1_slave);
-static void w1_f1d_remove_slave(struct w1_slave *sl)
-{
- device_remove_file(&sl->dev, &w1_counter_attr);
-}
+static struct attribute *w1_f1d_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(w1_f1d);
static struct w1_family_ops w1_f1d_fops = {
- .add_slave = w1_f1d_add_slave,
- .remove_slave = w1_f1d_remove_slave,
+ .groups = w1_f1d_groups,
};
static struct w1_family w1_family_1d = {
return -1;
}
-static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
int todo = count;
return 0;
}
-static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
int addr, len;
return count;
}
-static struct bin_attribute w1_f2d_bin_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = W1_F2D_EEPROM_SIZE,
- .read = w1_f2d_read_bin,
- .write = w1_f2d_write_bin,
+static BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE);
+
+static struct bin_attribute *w1_f2d_bin_attrs[] = {
+ &bin_attr_eeprom,
+ NULL,
};
-static int w1_f2d_add_slave(struct w1_slave *sl)
-{
- return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
-}
+static const struct attribute_group w1_f2d_group = {
+ .bin_attrs = w1_f2d_bin_attrs,
+};
-static void w1_f2d_remove_slave(struct w1_slave *sl)
-{
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
-}
+static const struct attribute_group *w1_f2d_groups[] = {
+ &w1_f2d_group,
+ NULL,
+};
static struct w1_family_ops w1_f2d_fops = {
- .add_slave = w1_f2d_add_slave,
- .remove_slave = w1_f2d_remove_slave,
+ .groups = w1_f2d_groups,
};
static struct w1_family w1_family_2d = {
}
#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
-static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
return 0;
}
-static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
int addr, len, idx;
return count;
}
-static struct bin_attribute w1_f23_bin_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = W1_EEPROM_SIZE,
- .read = w1_f23_read_bin,
- .write = w1_f23_write_bin,
+static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
+
+static struct bin_attribute *w1_f23_bin_attributes[] = {
+ &bin_attr_eeprom,
+ NULL,
+};
+
+static const struct attribute_group w1_f23_group = {
+ .bin_attrs = w1_f23_bin_attributes,
+};
+
+static const struct attribute_group *w1_f23_groups[] = {
+ &w1_f23_group,
+ NULL,
};
static int w1_f23_add_slave(struct w1_slave *sl)
{
- int err;
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
struct w1_f23_data *data;
sl->family_data = data;
#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
-
- err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
-
-#ifdef CONFIG_W1_SLAVE_DS2433_CRC
- if (err)
- kfree(data);
-#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
-
- return err;
+ return 0;
}
static void w1_f23_remove_slave(struct w1_slave *sl)
kfree(sl->family_data);
sl->family_data = NULL;
#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
}
static struct w1_family_ops w1_f23_fops = {
.add_slave = w1_f23_add_slave,
.remove_slave = w1_f23_remove_slave,
+ .groups = w1_f23_groups,
};
static struct w1_family w1_family_23 = {
return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA);
}
-static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct device *dev = container_of(kobj, struct device, kobj);
return w1_ds2760_read(dev, buf, off, count);
}
-static struct bin_attribute w1_ds2760_bin_attr = {
- .attr = {
- .name = "w1_slave",
- .mode = S_IRUGO,
- },
- .size = DS2760_DATA_SIZE,
- .read = w1_ds2760_read_bin,
+static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE);
+
+static struct bin_attribute *w1_ds2760_bin_attrs[] = {
+ &bin_attr_w1_slave,
+ NULL,
+};
+
+static const struct attribute_group w1_ds2760_group = {
+ .bin_attrs = w1_ds2760_bin_attrs,
+};
+
+static const struct attribute_group *w1_ds2760_groups[] = {
+ &w1_ds2760_group,
+ NULL,
};
static DEFINE_IDA(bat_ida);
if (ret)
goto pdev_add_failed;
- ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
- if (ret)
- goto bin_attr_failed;
-
dev_set_drvdata(&sl->dev, pdev);
goto success;
-bin_attr_failed:
- platform_device_del(pdev);
pdev_add_failed:
platform_device_put(pdev);
pdev_alloc_failed:
platform_device_unregister(pdev);
ida_simple_remove(&bat_ida, id);
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
}
static struct w1_family_ops w1_ds2760_fops = {
.add_slave = w1_ds2760_add_slave,
.remove_slave = w1_ds2760_remove_slave,
+ .groups = w1_ds2760_groups,
};
static struct w1_family w1_ds2760_family = {
}
EXPORT_SYMBOL(w1_ds2780_eeprom_cmd);
-static ssize_t w1_ds2780_read_bin(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct device *dev = container_of(kobj, struct device, kobj);
return w1_ds2780_io(dev, buf, off, count, 0);
}
-static struct bin_attribute w1_ds2780_bin_attr = {
- .attr = {
- .name = "w1_slave",
- .mode = S_IRUGO,
- },
- .size = DS2780_DATA_SIZE,
- .read = w1_ds2780_read_bin,
+static BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE);
+
+static struct bin_attribute *w1_ds2780_bin_attrs[] = {
+ &bin_attr_w1_slave,
+ NULL,
+};
+
+static const struct attribute_group w1_ds2780_group = {
+ .bin_attrs = w1_ds2780_bin_attrs,
+};
+
+static const struct attribute_group *w1_ds2780_groups[] = {
+ &w1_ds2780_group,
+ NULL,
};
static DEFINE_IDA(bat_ida);
if (ret)
goto pdev_add_failed;
- ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr);
- if (ret)
- goto bin_attr_failed;
-
dev_set_drvdata(&sl->dev, pdev);
return 0;
-bin_attr_failed:
- platform_device_del(pdev);
pdev_add_failed:
platform_device_put(pdev);
pdev_alloc_failed:
platform_device_unregister(pdev);
ida_simple_remove(&bat_ida, id);
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr);
}
static struct w1_family_ops w1_ds2780_fops = {
.add_slave = w1_ds2780_add_slave,
.remove_slave = w1_ds2780_remove_slave,
+ .groups = w1_ds2780_groups,
};
static struct w1_family w1_ds2780_family = {
}
EXPORT_SYMBOL(w1_ds2781_eeprom_cmd);
-static ssize_t w1_ds2781_read_bin(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct device *dev = container_of(kobj, struct device, kobj);
return w1_ds2781_io(dev, buf, off, count, 0);
}
-static struct bin_attribute w1_ds2781_bin_attr = {
- .attr = {
- .name = "w1_slave",
- .mode = S_IRUGO,
- },
- .size = DS2781_DATA_SIZE,
- .read = w1_ds2781_read_bin,
+static BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE);
+
+static struct bin_attribute *w1_ds2781_bin_attrs[] = {
+ &bin_attr_w1_slave,
+ NULL,
+};
+
+static const struct attribute_group w1_ds2781_group = {
+ .bin_attrs = w1_ds2781_bin_attrs,
+};
+
+static const struct attribute_group *w1_ds2781_groups[] = {
+ &w1_ds2781_group,
+ NULL,
};
static DEFINE_IDA(bat_ida);
if (ret)
goto pdev_add_failed;
- ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr);
- if (ret)
- goto bin_attr_failed;
-
dev_set_drvdata(&sl->dev, pdev);
return 0;
-bin_attr_failed:
- platform_device_del(pdev);
pdev_add_failed:
platform_device_put(pdev);
pdev_alloc_failed:
platform_device_unregister(pdev);
ida_simple_remove(&bat_ida, id);
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr);
}
static struct w1_family_ops w1_ds2781_fops = {
.add_slave = w1_ds2781_add_slave,
.remove_slave = w1_ds2781_remove_slave,
+ .groups = w1_ds2781_groups,
};
static struct w1_family w1_ds2781_family = {
return w1_read_block(sl->master, data, len);
}
-static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
struct w1_f1C_data *data = sl->family_data;
return 0;
}
-static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
return count;
}
-static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
+
+static ssize_t pio_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
return ret;
}
-static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t pio_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
return count;
}
-static ssize_t w1_f1C_show_crccheck(struct device *dev,
- struct device_attribute *attr, char *buf)
+static BIN_ATTR_RW(pio, 1);
+
+static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
if (put_user(w1_enable_crccheck + 0x30, buf))
return -EFAULT;
return sizeof(w1_enable_crccheck);
}
-static ssize_t w1_f1C_store_crccheck(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
char val;
return sizeof(w1_enable_crccheck);
}
-#define NB_SYSFS_BIN_FILES 2
-static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = {
- {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = W1_EEPROM_SIZE,
- .read = w1_f1C_read_bin,
- .write = w1_f1C_write_bin,
- },
- {
- .attr = {
- .name = "pio",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = 1,
- .read = w1_f1C_read_pio,
- .write = w1_f1C_write_pio,
- }
+static DEVICE_ATTR_RW(crccheck);
+
+static struct attribute *w1_f1C_attrs[] = {
+ &dev_attr_crccheck.attr,
+ NULL,
};
-static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO,
- w1_f1C_show_crccheck, w1_f1C_store_crccheck);
+static struct bin_attribute *w1_f1C_bin_attrs[] = {
+ &bin_attr_eeprom,
+ &bin_attr_pio,
+ NULL,
+};
+
+static const struct attribute_group w1_f1C_group = {
+ .attrs = w1_f1C_attrs,
+ .bin_attrs = w1_f1C_bin_attrs,
+};
+
+static const struct attribute_group *w1_f1C_groups[] = {
+ &w1_f1C_group,
+ NULL,
+};
static int w1_f1C_add_slave(struct w1_slave *sl)
{
- int err = 0;
- int i;
struct w1_f1C_data *data = NULL;
if (w1_enable_crccheck) {
sl->family_data = data;
}
- /* create binary sysfs attributes */
- for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
- err = sysfs_create_bin_file(
- &sl->dev.kobj, &(w1_f1C_bin_attr[i]));
-
- if (!err) {
- /* create device attributes */
- err = device_create_file(&sl->dev, &dev_attr_crccheck);
- }
-
- if (err) {
- /* remove binary sysfs attributes */
- for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
- sysfs_remove_bin_file(
- &sl->dev.kobj, &(w1_f1C_bin_attr[i]));
-
- kfree(data);
- }
-
- return err;
+ return 0;
}
static void w1_f1C_remove_slave(struct w1_slave *sl)
{
- int i;
-
kfree(sl->family_data);
sl->family_data = NULL;
-
- /* remove device attributes */
- device_remove_file(&sl->dev, &dev_attr_crccheck);
-
- /* remove binary sysfs attributes */
- for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
- sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i]));
}
static struct w1_family_ops w1_f1C_fops = {
.add_slave = w1_f1C_add_slave,
.remove_slave = w1_f1C_remove_slave,
+ .groups = w1_f1C_groups,
};
static struct w1_family w1_family_1C = {
module_param_named(strong_pullup, w1_strong_pullup, int, 0);
-static ssize_t w1_therm_read(struct device *device,
+static ssize_t w1_slave_show(struct device *device,
struct device_attribute *attr, char *buf);
-static struct device_attribute w1_therm_attr =
- __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
+static DEVICE_ATTR_RO(w1_slave);
-static int w1_therm_add_slave(struct w1_slave *sl)
-{
- return device_create_file(&sl->dev, &w1_therm_attr);
-}
-
-static void w1_therm_remove_slave(struct w1_slave *sl)
-{
- device_remove_file(&sl->dev, &w1_therm_attr);
-}
+static struct attribute *w1_therm_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(w1_therm);
static struct w1_family_ops w1_therm_fops = {
- .add_slave = w1_therm_add_slave,
- .remove_slave = w1_therm_remove_slave,
+ .groups = w1_therm_groups,
};
static struct w1_family w1_therm_family_DS18S20 = {
}
-static ssize_t w1_therm_read(struct device *device,
+static ssize_t w1_slave_show(struct device *device,
struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = dev_to_w1_slave(device);
complete(&sl->released);
}
-static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = dev_to_w1_slave(dev);
return sprintf(buf, "%s\n", sl->name);
}
+static DEVICE_ATTR_RO(name);
-static ssize_t w1_slave_read_id(struct device *dev,
+static ssize_t id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = dev_to_w1_slave(dev);
memcpy(buf, (u8 *)&sl->reg_num, count);
return count;
}
+static DEVICE_ATTR_RO(id);
-static struct device_attribute w1_slave_attr_name =
- __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
-static struct device_attribute w1_slave_attr_id =
- __ATTR(id, S_IRUGO, w1_slave_read_id, NULL);
+static struct attribute *w1_slave_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_id.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(w1_slave);
/* Default family */
-static ssize_t w1_default_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t rw_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
return count;
}
-static ssize_t w1_default_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t rw_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off,
+ size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
return count;
}
-static struct bin_attribute w1_default_attr = {
- .attr = {
- .name = "rw",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = PAGE_SIZE,
- .read = w1_default_read,
- .write = w1_default_write,
+static BIN_ATTR_RW(rw, PAGE_SIZE);
+
+static struct bin_attribute *w1_slave_bin_attrs[] = {
+ &bin_attr_rw,
+ NULL,
};
-static int w1_default_add_slave(struct w1_slave *sl)
-{
- return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr);
-}
+static const struct attribute_group w1_slave_default_group = {
+ .bin_attrs = w1_slave_bin_attrs,
+};
-static void w1_default_remove_slave(struct w1_slave *sl)
-{
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr);
-}
+static const struct attribute_group *w1_slave_default_groups[] = {
+ &w1_slave_default_group,
+ NULL,
+};
static struct w1_family_ops w1_default_fops = {
- .add_slave = w1_default_add_slave,
- .remove_slave = w1_default_remove_slave,
+ .groups = w1_slave_default_groups,
};
static struct w1_family w1_default_family = {
return err;
}
+/*
+ * Handle sysfs file creation and removal here, before userspace is told that
+ * the device is added / removed from the system
+ */
+static int w1_bus_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+ struct w1_slave *sl;
+ struct w1_family_ops *fops;
+ int err;
+
+ /*
+ * Only care about slave devices at the moment. Yes, we should use a
+ * separate "type" for this, but for now, look at the release function
+ * to know which type it is...
+ */
+ if (dev->release != w1_slave_release)
+ return 0;
+
+ sl = dev_to_w1_slave(dev);
+ fops = sl->family->fops;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ /* if the family driver needs to initialize something... */
+ if (fops->add_slave) {
+ err = fops->add_slave(sl);
+ if (err < 0) {
+ dev_err(&sl->dev,
+ "add_slave() call failed. err=%d\n",
+ err);
+ return err;
+ }
+ }
+ if (fops->groups) {
+ err = sysfs_create_groups(&sl->dev.kobj, fops->groups);
+ if (err) {
+ dev_err(&sl->dev,
+ "sysfs group creation failed. err=%d\n",
+ err);
+ return err;
+ }
+ }
+
+ break;
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (fops->remove_slave)
+ sl->family->fops->remove_slave(sl);
+ if (fops->groups)
+ sysfs_remove_groups(&sl->dev.kobj, fops->groups);
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block w1_bus_nb = {
+ .notifier_call = w1_bus_notify,
+};
+
static int __w1_attach_slave_device(struct w1_slave *sl)
{
int err;
sl->dev.driver = &w1_slave_driver;
sl->dev.bus = &w1_bus_type;
sl->dev.release = &w1_slave_release;
+ sl->dev.groups = w1_slave_groups;
dev_set_name(&sl->dev, "%02x-%012llx",
(unsigned int) sl->reg_num.family,
return err;
}
- /* Create "name" entry */
- err = device_create_file(&sl->dev, &w1_slave_attr_name);
- if (err < 0) {
- dev_err(&sl->dev,
- "sysfs file creation for [%s] failed. err=%d\n",
- dev_name(&sl->dev), err);
- goto out_unreg;
- }
-
- /* Create "id" entry */
- err = device_create_file(&sl->dev, &w1_slave_attr_id);
- if (err < 0) {
- dev_err(&sl->dev,
- "sysfs file creation for [%s] failed. err=%d\n",
- dev_name(&sl->dev), err);
- goto out_rem1;
- }
- /* if the family driver needs to initialize something... */
- if (sl->family->fops && sl->family->fops->add_slave &&
- ((err = sl->family->fops->add_slave(sl)) < 0)) {
- dev_err(&sl->dev,
- "sysfs file creation for [%s] failed. err=%d\n",
- dev_name(&sl->dev), err);
- goto out_rem2;
- }
+ dev_set_uevent_suppress(&sl->dev, false);
+ kobject_uevent(&sl->dev.kobj, KOBJ_ADD);
list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
return 0;
-
-out_rem2:
- device_remove_file(&sl->dev, &w1_slave_attr_id);
-out_rem1:
- device_remove_file(&sl->dev, &w1_slave_attr_name);
-out_unreg:
- device_unregister(&sl->dev);
- return err;
}
static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
list_del(&sl->w1_slave_entry);
- if (sl->family->fops && sl->family->fops->remove_slave)
- sl->family->fops->remove_slave(sl);
-
memset(&msg, 0, sizeof(msg));
memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id));
msg.type = W1_SLAVE_REMOVE;
w1_netlink_send(sl->master, &msg);
- device_remove_file(&sl->dev, &w1_slave_attr_id);
- device_remove_file(&sl->dev, &w1_slave_attr_name);
device_unregister(&sl->dev);
wait_for_completion(&sl->released);
goto err_out_exit_init;
}
+ retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb);
+ if (retval)
+ goto err_out_bus_unregister;
+
retval = driver_register(&w1_master_driver);
if (retval) {
printk(KERN_ERR
{
int (* add_slave)(struct w1_slave *);
void (* remove_slave)(struct w1_slave *);
+ const struct attribute_group **groups;
};
struct w1_family
return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting));
}
+static DEVICE_ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL);
static ssize_t cuse_class_abort_store(struct device *dev,
struct device_attribute *attr,
fuse_abort_conn(&cc->fc);
return count;
}
+static DEVICE_ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store);
-static struct device_attribute cuse_class_dev_attrs[] = {
- __ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL),
- __ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store),
- { }
+static struct attribute *cuse_class_dev_attrs[] = {
+ &dev_attr_waiting.attr,
+ &dev_attr_abort.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(cuse_class_dev);
static struct miscdevice cuse_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
if (IS_ERR(cuse_class))
return PTR_ERR(cuse_class);
- cuse_class->dev_attrs = cuse_class_dev_attrs;
+ cuse_class->dev_groups = cuse_class_dev_groups;
rc = misc_register(&cuse_miscdev);
if (rc) {
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/mm.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "sysfs.h"
return rc;
}
-static int open(struct inode * inode, struct file * file)
+static int open(struct inode *inode, struct file *file)
{
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
return error;
}
-static int release(struct inode * inode, struct file * file)
+static int release(struct inode *inode, struct file *file)
{
struct bin_buffer *bb = file->private_data;
* @kobj: object.
* @attr: attribute descriptor.
*/
-
int sysfs_create_bin_file(struct kobject *kobj,
const struct bin_attribute *attr)
{
return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
}
-
+EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
/**
* sysfs_remove_bin_file - remove binary file for object.
* @kobj: object.
* @attr: attribute descriptor.
*/
-
void sysfs_remove_bin_file(struct kobject *kobj,
const struct bin_attribute *attr)
{
sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
}
-
-EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
unsigned int len = strlen(name);
while (len--)
hash = partial_name_hash(*name++, hash);
- hash = ( end_name_hash(hash) ^ hash_ptr( (void *)ns, 31 ) );
+ hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
hash &= 0x7fffffffU;
/* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
if (hash < 1)
spin_unlock(&sysfs_ino_lock);
}
-void release_sysfs_dirent(struct sysfs_dirent * sd)
+void release_sysfs_dirent(struct sysfs_dirent *sd)
{
struct sysfs_dirent *parent_sd;
if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) {
WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
- sysfs_ns_type(acxt->parent_sd)? "required": "invalid",
+ sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid",
acxt->parent_sd->s_name, sd->s_name);
return -EINVAL;
}
if (!!sysfs_ns_type(parent_sd) != !!ns) {
WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
- sysfs_ns_type(parent_sd)? "required": "invalid",
+ sysfs_ns_type(parent_sd) ? "required" : "invalid",
parent_sd->s_name, name);
return NULL;
}
enum kobj_ns_type type, const void *ns, const char *name,
struct sysfs_dirent **p_sd)
{
- umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+ umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
int rc;
/**
* sysfs_create_dir - create a directory for an object.
- * @kobj: object we're creating directory for.
+ * @kobj: object we're creating directory for.
*/
-int sysfs_create_dir(struct kobject * kobj)
+int sysfs_create_dir(struct kobject *kobj)
{
enum kobj_ns_type type;
struct sysfs_dirent *parent_sd, *sd;
return error;
}
-static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
- unsigned int flags)
+static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
+ unsigned int flags)
{
struct dentry *ret = NULL;
struct dentry *parent = dentry->d_parent;
* what used to be sysfs_rmdir() below, instead of calling separately.
*/
-void sysfs_remove_dir(struct kobject * kobj)
+void sysfs_remove_dir(struct kobject *kobj)
{
struct sysfs_dirent *sd = kobj->sd;
sd->s_name = new_name;
}
- /* Move to the appropriate place in the appropriate directories rbtree. */
+ /*
+ * Move to the appropriate place in the appropriate directories rbtree.
+ */
sysfs_unlink_sibling(sd);
sysfs_get(new_parent_sd);
sysfs_put(sd->s_parent);
struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
{
pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
- if (pos) do {
- struct rb_node *node = rb_next(&pos->s_rb);
- if (!node)
- pos = NULL;
- else
- pos = to_sysfs_dirent(node);
- } while (pos && pos->s_ns != ns);
+ if (pos)
+ do {
+ struct rb_node *node = rb_next(&pos->s_rb);
+ if (!node)
+ pos = NULL;
+ else
+ pos = to_sysfs_dirent(node);
+ } while (pos && pos->s_ns != ns);
return pos;
}
static int sysfs_readdir(struct file *file, struct dir_context *ctx)
{
struct dentry *dentry = file->f_path.dentry;
- struct sysfs_dirent * parent_sd = dentry->d_fsdata;
+ struct sysfs_dirent *parent_sd = dentry->d_fsdata;
struct sysfs_dirent *pos = file->private_data;
enum kobj_ns_type type;
const void *ns;
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/limits.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "sysfs.h"
struct sysfs_buffer {
size_t count;
loff_t pos;
- char * page;
- const struct sysfs_ops * ops;
+ char *page;
+ const struct sysfs_ops *ops;
struct mutex mutex;
int needs_read_fill;
int event;
* @buffer: data buffer for file.
*
* Allocate @buffer->page, if it hasn't been already, then call the
- * kobject's show() method to fill the buffer with this attribute's
- * data.
+ * kobject's show() method to fill the buffer with this attribute's
+ * data.
* This is called only once, on the file's first read unless an error
* is returned.
*/
-static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
+static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- const struct sysfs_ops * ops = buffer->ops;
+ const struct sysfs_ops *ops = buffer->ops;
int ret = 0;
ssize_t count;
}
/**
- * sysfs_read_file - read an attribute.
+ * sysfs_read_file - read an attribute.
* @file: file pointer.
* @buf: buffer to fill.
* @count: number of bytes to read.
static ssize_t
sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
- struct sysfs_buffer * buffer = file->private_data;
+ struct sysfs_buffer *buffer = file->private_data;
ssize_t retval = 0;
mutex_lock(&buffer->mutex);
if (buffer->needs_read_fill || *ppos == 0) {
- retval = fill_read_buffer(file->f_path.dentry,buffer);
+ retval = fill_read_buffer(file->f_path.dentry, buffer);
if (retval)
goto out;
}
* Allocate @buffer->page if it hasn't been already, then
* copy the user-supplied buffer into it.
*/
-
-static int
-fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t count)
+static int fill_write_buffer(struct sysfs_buffer *buffer,
+ const char __user *buf, size_t count)
{
int error;
if (count >= PAGE_SIZE)
count = PAGE_SIZE - 1;
- error = copy_from_user(buffer->page,buf,count);
+ error = copy_from_user(buffer->page, buf, count);
buffer->needs_read_fill = 1;
/* if buf is assumed to contain a string, terminate it by \0,
so e.g. sscanf() can scan the string easily */
* @count: number of bytes
*
* Get the correct pointers for the kobject and the attribute we're
- * dealing with, then call the store() method for the attribute,
+ * dealing with, then call the store() method for the attribute,
* passing the buffer that we acquired in fill_write_buffer().
*/
-
-static int
-flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
+static int flush_write_buffer(struct dentry *dentry,
+ struct sysfs_buffer *buffer, size_t count)
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- const struct sysfs_ops * ops = buffer->ops;
+ const struct sysfs_ops *ops = buffer->ops;
int rc;
/* need attr_sd for attr and ops, its parent for kobj */
* then push it to the kobject in flush_write_buffer().
* There is no easy way for us to know if userspace is only doing a partial
* write, so we don't support them. We expect the entire buffer to come
- * on the first write.
+ * on the first write.
* Hint: if you're writing a value, first read the file, modify only the
- * the value you're changing, then write entire buffer back.
+ * the value you're changing, then write entire buffer back.
*/
-
-static ssize_t
-sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+static ssize_t sysfs_write_file(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
{
- struct sysfs_buffer * buffer = file->private_data;
+ struct sysfs_buffer *buffer = file->private_data;
ssize_t len;
mutex_lock(&buffer->mutex);
if (kobj->ktype && kobj->ktype->sysfs_ops)
ops = kobj->ktype->sysfs_ops;
else {
- WARN(1, KERN_ERR "missing sysfs attribute operations for "
- "kobject: %s\n", kobject_name(kobj));
+ WARN(1, KERN_ERR
+ "missing sysfs attribute operations for kobject: %s\n",
+ kobject_name(kobj));
goto err_out;
}
/* File needs write support.
- * The inode's perms must say it's ok,
+ * The inode's perms must say it's ok,
* and we must have a store method.
*/
if (file->f_mode & FMODE_WRITE) {
*/
static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
{
- struct sysfs_buffer * buffer = filp->private_data;
+ struct sysfs_buffer *buffer = filp->private_data;
struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
struct sysfs_open_dirent *od = attr_sd->s_attr.open;
ns = ops->namespace(kobj, attr);
out:
if (err) {
- WARN(1, KERN_ERR "missing sysfs namespace attribute operation for "
- "kobject: %s\n", kobject_name(kobj));
+ WARN(1, KERN_ERR
+ "missing sysfs namespace attribute operation for kobject: %s\n",
+ kobject_name(kobj));
}
*pns = ns;
return err;
/**
* sysfs_create_file - create an attribute file for an object.
- * @kobj: object we're creating for.
+ * @kobj: object we're creating for.
* @attr: attribute descriptor.
*/
-
-int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
+int sysfs_create_file(struct kobject *kobj, const struct attribute *attr)
{
BUG_ON(!kobj || !kobj->sd || !attr);
return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
}
+EXPORT_SYMBOL_GPL(sysfs_create_file);
int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
{
sysfs_remove_file(kobj, ptr[i]);
return err;
}
+EXPORT_SYMBOL_GPL(sysfs_create_files);
/**
* sysfs_add_file_to_group - add an attribute file to a pre-existing group.
}
EXPORT_SYMBOL_GPL(sysfs_chmod_file);
-
/**
* sysfs_remove_file - remove an object attribute.
* @kobj: object we're acting for.
*
* Hash the attribute name and kill the victim.
*/
-
-void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
+void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
{
const void *ns;
sysfs_hash_and_remove(kobj->sd, ns, attr->name);
}
+EXPORT_SYMBOL_GPL(sysfs_remove_file);
-void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
+void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
{
int i;
for (i = 0; ptr[i]; i++)
sysfs_remove_file(kobj, ptr[i]);
}
+EXPORT_SYMBOL_GPL(sysfs_remove_files);
/**
* sysfs_remove_file_from_group - remove an attribute file from a group.
return 0;
}
EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
-
-
-EXPORT_SYMBOL_GPL(sysfs_create_file);
-EXPORT_SYMBOL_GPL(sysfs_remove_file);
-EXPORT_SYMBOL_GPL(sysfs_remove_files);
-EXPORT_SYMBOL_GPL(sysfs_create_files);
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
+ * Copyright (c) 2013 Greg Kroah-Hartman
+ * Copyright (c) 2013 The Linux Foundation
*
- * This file is released undert the GPL v2.
+ * This file is released undert the GPL v2.
*
*/
static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
const struct attribute_group *grp)
{
- struct attribute *const* attr;
- struct bin_attribute *const* bin_attr;
+ struct attribute *const *attr;
+ struct bin_attribute *const *bin_attr;
if (grp->attrs)
for (attr = grp->attrs; *attr; attr++)
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
const struct attribute_group *grp, int update)
{
- struct attribute *const* attr;
- struct bin_attribute *const* bin_attr;
+ struct attribute *const *attr;
+ struct bin_attribute *const *bin_attr;
int error = 0, i;
if (grp->attrs) {
{
return internal_create_group(kobj, 0, grp);
}
+EXPORT_SYMBOL_GPL(sysfs_create_group);
+
+/**
+ * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups
+ * @kobj: The kobject to create the group on
+ * @groups: The attribute groups to create, NULL terminated
+ *
+ * This function creates a bunch of attribute groups. If an error occurs when
+ * creating a group, all previously created groups will be removed, unwinding
+ * everything back to the original state when this function was called.
+ * It will explicitly warn and error if any of the attribute files being
+ * created already exist.
+ *
+ * Returns 0 on success or error code from sysfs_create_group on error.
+ */
+int sysfs_create_groups(struct kobject *kobj,
+ const struct attribute_group **groups)
+{
+ int error = 0;
+ int i;
+
+ if (!groups)
+ return 0;
+
+ for (i = 0; groups[i]; i++) {
+ error = sysfs_create_group(kobj, groups[i]);
+ if (error) {
+ while (--i >= 0)
+ sysfs_remove_group(kobj, groups[i]);
+ break;
+ }
+ }
+ return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_create_groups);
/**
* sysfs_update_group - given a directory kobject, update an attribute group
{
return internal_create_group(kobj, 1, grp);
}
+EXPORT_SYMBOL_GPL(sysfs_update_group);
-
-
-void sysfs_remove_group(struct kobject * kobj,
- const struct attribute_group * grp)
+/**
+ * sysfs_remove_group: remove a group from a kobject
+ * @kobj: kobject to remove the group from
+ * @grp: group to remove
+ *
+ * This function removes a group of attributes from a kobject. The attributes
+ * previously have to have been created for this group, otherwise it will fail.
+ */
+void sysfs_remove_group(struct kobject *kobj,
+ const struct attribute_group *grp)
{
struct sysfs_dirent *dir_sd = kobj->sd;
struct sysfs_dirent *sd;
if (grp->name) {
sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
if (!sd) {
- WARN(!sd, KERN_WARNING "sysfs group %p not found for "
- "kobject '%s'\n", grp, kobject_name(kobj));
+ WARN(!sd, KERN_WARNING
+ "sysfs group %p not found for kobject '%s'\n",
+ grp, kobject_name(kobj));
return;
}
} else
sysfs_put(sd);
}
+EXPORT_SYMBOL_GPL(sysfs_remove_group);
+
+/**
+ * sysfs_remove_groups - remove a list of groups
+ *
+ * @kobj: The kobject for the groups to be removed from
+ * @groups: NULL terminated list of groups to be removed
+ *
+ * If groups is not NULL, remove the specified groups from the kobject.
+ */
+void sysfs_remove_groups(struct kobject *kobj,
+ const struct attribute_group **groups)
+{
+ int i;
+
+ if (!groups)
+ return;
+ for (i = 0; groups[i]; i++)
+ sysfs_remove_group(kobj, groups[i]);
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_groups);
/**
* sysfs_merge_group - merge files into a pre-existing attribute group.
}
}
EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
-
-EXPORT_SYMBOL_GPL(sysfs_create_group);
-EXPORT_SYMBOL_GPL(sysfs_update_group);
-EXPORT_SYMBOL_GPL(sysfs_remove_group);
* Please see Documentation/filesystems/sysfs.txt for more information.
*/
-#undef DEBUG
+#undef DEBUG
#include <linux/pagemap.h>
#include <linux/namei.h>
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
};
-static const struct inode_operations sysfs_inode_operations ={
+static const struct inode_operations sysfs_inode_operations = {
.permission = sysfs_permission,
.setattr = sysfs_setattr,
.getattr = sysfs_getattr,
return attrs;
}
-int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
+int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
{
struct sysfs_inode_attrs *sd_attrs;
struct iattr *iattrs;
return error;
}
-static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len)
+static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata,
+ u32 *secdata_len)
{
struct sysfs_inode_attrs *iattrs;
void *old_secdata;
return error;
}
-static inline void set_default_inode_attr(struct inode * inode, umode_t mode)
+static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
{
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
}
-static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
+static inline void set_inode_attr(struct inode *inode, struct iattr *iattr)
{
inode->i_uid = iattr->ia_uid;
inode->i_gid = iattr->ia_gid;
set_nlink(inode, sd->s_dir.subdirs + 2);
}
-int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
{
struct sysfs_dirent *sd = dentry->d_fsdata;
struct inode *inode = dentry->d_inode;
* RETURNS:
* Pointer to allocated inode on success, NULL on failure.
*/
-struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
+struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
{
struct inode *inode;
sysfs_put(sd);
}
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name)
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
+ const char *name)
{
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
/* instantiate and link root dentry */
root = d_make_root(inode);
if (!root) {
- pr_debug("%s: could not get root dentry!\n",__func__);
+ pr_debug("%s: could not get root dentry!\n", __func__);
return -ENOMEM;
}
root->d_fsdata = &sysfs_root;
{
return sysfs_do_create_link(kobj, target, name, 1);
}
+EXPORT_SYMBOL_GPL(sysfs_create_link);
/**
* sysfs_create_link_nowarn - create symlink between two objects.
* @kobj: object we're acting for.
* @name: name of the symlink to remove.
*/
-
-void sysfs_remove_link(struct kobject * kobj, const char * name)
+void sysfs_remove_link(struct kobject *kobj, const char *name)
{
struct sysfs_dirent *parent_sd = NULL;
sysfs_hash_and_remove(parent_sd, NULL, name);
}
+EXPORT_SYMBOL_GPL(sysfs_remove_link);
/**
* sysfs_rename_link - rename symlink in object's directory.
sysfs_put(sd);
return result;
}
+EXPORT_SYMBOL_GPL(sysfs_rename_link);
static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
struct sysfs_dirent *target_sd, char *path)
return 0;
}
-static int sysfs_getlink(struct dentry *dentry, char * path)
+static int sysfs_getlink(struct dentry *dentry, char *path)
{
struct sysfs_dirent *sd = dentry->d_fsdata;
struct sysfs_dirent *parent_sd = sd->s_parent;
int error = -ENOMEM;
unsigned long page = get_zeroed_page(GFP_KERNEL);
if (page) {
- error = sysfs_getlink(dentry, (char *) page);
+ error = sysfs_getlink(dentry, (char *) page);
if (error < 0)
free_page((unsigned long)page);
}
return NULL;
}
-static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd,
+ void *cookie)
{
char *page = nd_get_link(nd);
if (!IS_ERR(page))
.getattr = sysfs_getattr,
.permission = sysfs_permission,
};
-
-
-EXPORT_SYMBOL_GPL(sysfs_create_link);
-EXPORT_SYMBOL_GPL(sysfs_remove_link);
-EXPORT_SYMBOL_GPL(sysfs_rename_link);
};
unsigned short s_flags;
- umode_t s_mode;
+ umode_t s_mode;
unsigned int s_ino;
struct sysfs_inode_attrs *s_iattr;
};
key = &attr->skey; \
\
lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
-} while(0)
+} while (0)
#else
-#define sysfs_dirent_init_lockdep(sd) do {} while(0)
+#define sysfs_dirent_init_lockdep(sd) do {} while (0)
#endif
/*
struct sysfs_dirent **p_sd);
void sysfs_remove_subdir(struct sysfs_dirent *sd);
-int sysfs_rename(struct sysfs_dirent *sd,
- struct sysfs_dirent *new_parent_sd, const void *ns, const char *new_name);
+int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
+ const void *ns, const char *new_name);
static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
{
int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
int sysfs_permission(struct inode *inode, int mask);
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
-int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
+int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat);
int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
- size_t size, int flags);
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name);
+ size_t size, int flags);
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
+ const char *name);
int sysfs_inode_init(void);
/*
return ERR_PTR(-ENODEV);
}
+static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode,
+ struct dentry *parent,
+ u64 *value)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
struct dentry *parent,
size_t *value)
* @bus_attrs: Default attributes of the bus.
* @dev_attrs: Default attributes of the devices on the bus.
* @drv_attrs: Default attributes of the device drivers on the bus.
+ * @bus_groups: Default attributes of the bus.
+ * @dev_groups: Default attributes of the devices on the bus.
+ * @drv_groups: Default attributes of the device drivers on the bus.
* @match: Called, perhaps multiple times, whenever a new device or driver
* is added for this bus. It should return a nonzero value if the
* given device can be handled by the given driver.
const char *name;
const char *dev_name;
struct device *dev_root;
- struct bus_attribute *bus_attrs;
- struct device_attribute *dev_attrs;
- struct driver_attribute *drv_attrs;
+ struct bus_attribute *bus_attrs; /* use bus_groups instead */
+ struct device_attribute *dev_attrs; /* use dev_groups instead */
+ struct driver_attribute *drv_attrs; /* use drv_groups instead */
+ const struct attribute_group **bus_groups;
+ const struct attribute_group **dev_groups;
+ const struct attribute_group **drv_groups;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
struct driver_attribute driver_attr_##_name = __ATTR_RW(_name)
#define DRIVER_ATTR_RO(_name) \
struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
+#define DRIVER_ATTR_WO(_name) \
+ struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
extern int __must_check driver_create_file(struct device_driver *driver,
const struct driver_attribute *attr);
struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
#define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
+#define DEVICE_ATTR_WO(_name) \
+ struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/atomic.h>
+#include <linux/workqueue.h>
#define UEVENT_HELPER_PATH_LEN 256
#define UEVENT_NUM_ENVP 32 /* number of env pointers */
struct kobj_type *ktype;
struct sysfs_dirent *sd;
struct kref kref;
+#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
+ struct delayed_work release;
+#endif
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
struct memory_block {
unsigned long start_section_nr;
unsigned long end_section_nr;
- unsigned long state;
- int section_count;
-
- /*
- * This serializes all state change requests. It isn't
- * held during creation because the control files are
- * created long after the critical areas during
- * initialization.
- */
- struct mutex state_mutex;
+ unsigned long state; /* serialized by the dev->lock */
+ int section_count; /* serialized by mem_sysfs_mutex */
+ int online_type; /* for passing data to online routine */
int phys_device; /* to which fru does this belong? */
void *hw; /* optional pointer to fw/hw data */
int (*phys_callback)(struct memory_block *);
struct memory_block *);
extern struct memory_block *find_memory_block(struct mem_section *);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
-enum mem_add_context { BOOT, HOTPLUG };
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
#ifdef CONFIG_MEMORY_HOTPLUG
* Global variables
*/
-extern struct device_attribute pps_attrs[];
+extern const struct attribute_group *pps_groups[];
/*
* Internal functions.
static struct lock_class_key __key; \
\
(attr)->key = &__key; \
-} while(0)
+} while (0)
#else
-#define sysfs_attr_init(attr) do {} while(0)
+#define sysfs_attr_init(attr) do {} while (0)
#endif
struct attribute_group {
* for examples..
*/
-#define __ATTR(_name,_mode,_show,_store) { \
+#define __ATTR(_name, _mode, _show, _store) { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
.show = _name##_show, \
}
+#define __ATTR_WO(_name) { \
+ .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \
+ .store = _name##_store, \
+}
+
#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
_name##_show, _name##_store)
}; \
__ATTRIBUTE_GROUPS(_name)
-#define attr_name(_attr) (_attr).attr.name
-
struct file;
struct vm_area_struct;
void *private;
ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
- ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *,
+ ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
struct vm_area_struct *vma);
#define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \
(S_IWUSR | S_IRUGO), _name##_read, \
- _name##_write)
+ _name##_write, _size)
#define __BIN_ATTR_NULL __ATTR_NULL
struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
struct sysfs_ops {
- ssize_t (*show)(struct kobject *, struct attribute *,char *);
- ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
+ ssize_t (*show)(struct kobject *, struct attribute *, char *);
+ ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
const void *(*namespace)(struct kobject *, const struct attribute *);
};
int __must_check sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp);
+int __must_check sysfs_create_groups(struct kobject *kobj,
+ const struct attribute_group **groups);
int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp);
void sysfs_remove_group(struct kobject *kobj,
const struct attribute_group *grp);
+void sysfs_remove_groups(struct kobject *kobj,
+ const struct attribute_group **groups);
int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
void sysfs_remove_file_from_group(struct kobject *kobj,
return 0;
}
+static inline int sysfs_create_groups(struct kobject *kobj,
+ const struct attribute_group **groups)
+{
+ return 0;
+}
+
static inline int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp)
{
{
}
+static inline void sysfs_remove_groups(struct kobject *kobj,
+ const struct attribute_group **groups)
+{
+}
+
static inline int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group)
{
return wq_dev->wq;
}
-static ssize_t wq_per_cpu_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t per_cpu_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct workqueue_struct *wq = dev_to_wq(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)!(wq->flags & WQ_UNBOUND));
}
+static DEVICE_ATTR_RO(per_cpu);
-static ssize_t wq_max_active_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t max_active_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct workqueue_struct *wq = dev_to_wq(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", wq->saved_max_active);
}
-static ssize_t wq_max_active_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t max_active_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
{
struct workqueue_struct *wq = dev_to_wq(dev);
int val;
workqueue_set_max_active(wq, val);
return count;
}
+static DEVICE_ATTR_RW(max_active);
-static struct device_attribute wq_sysfs_attrs[] = {
- __ATTR(per_cpu, 0444, wq_per_cpu_show, NULL),
- __ATTR(max_active, 0644, wq_max_active_show, wq_max_active_store),
- __ATTR_NULL,
+static struct attribute *wq_sysfs_attrs[] = {
+ &dev_attr_per_cpu.attr,
+ &dev_attr_max_active.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(wq_sysfs);
static ssize_t wq_pool_ids_show(struct device *dev,
struct device_attribute *attr, char *buf)
static struct bus_type wq_subsys = {
.name = "workqueue",
- .dev_attrs = wq_sysfs_attrs,
+ .dev_groups = wq_sysfs_groups,
};
static int __init wq_sysfs_init(void)
If you say Y here, some extra kobject debugging messages will be sent
to the syslog.
+config DEBUG_KOBJECT_RELEASE
+ bool "kobject release debugging"
+ depends on DEBUG_KERNEL
+ help
+ kobjects are reference counted objects. This means that their
+ last reference count put is not predictable, and the kobject can
+ live on past the point at which a driver decides to drop it's
+ initial reference to the kobject gained on allocation. An
+ example of this would be a struct device which has just been
+ unregistered.
+
+ However, some buggy drivers assume that after such an operation,
+ the memory backing the kobject can be immediately freed. This
+ goes completely against the principles of a refcounted object.
+
+ If you say Y here, the kernel will delay the release of kobjects
+ on the last reference count to improve the visibility of this
+ kind of kobject release bug.
+
config HAVE_DEBUG_BUGVERBOSE
bool
struct ddebug_query *query, const char *modname)
{
unsigned int i;
- int rc;
+ int rc = 0;
/* check we have an even number of words */
if (nwords % 2 != 0) {
struct kobj_type *t = get_ktype(kobj);
const char *name = kobj->name;
- pr_debug("kobject: '%s' (%p): %s\n",
- kobject_name(kobj), kobj, __func__);
+ pr_debug("kobject: '%s' (%p): %s, parent %p\n",
+ kobject_name(kobj), kobj, __func__, kobj->parent);
if (t && !t->release)
pr_debug("kobject: '%s' (%p): does not have a release() "
}
}
+#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
+static void kobject_delayed_cleanup(struct work_struct *work)
+{
+ kobject_cleanup(container_of(to_delayed_work(work),
+ struct kobject, release));
+}
+#endif
+
static void kobject_release(struct kref *kref)
{
- kobject_cleanup(container_of(kref, struct kobject, kref));
+ struct kobject *kobj = container_of(kref, struct kobject, kref);
+#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
+ pr_debug("kobject: '%s' (%p): %s, parent %p (delayed)\n",
+ kobject_name(kobj), kobj, __func__, kobj->parent);
+ INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
+ schedule_delayed_work(&kobj->release, HZ);
+#else
+ kobject_cleanup(kobj);
+#endif
}
/**
struct backing_dev_info *bdi = dev_get_drvdata(dev); \
\
return snprintf(page, PAGE_SIZE-1, "%lld\n", (long long)expr); \
-}
+} \
+static DEVICE_ATTR_RW(name);
BDI_SHOW(read_ahead_kb, K(bdi->ra_pages))
return snprintf(page, PAGE_SIZE-1, "%d\n",
bdi_cap_stable_pages_required(bdi) ? 1 : 0);
}
+static DEVICE_ATTR_RO(stable_pages_required);
-static struct device_attribute bdi_dev_attrs[] = {
- __ATTR_RW(read_ahead_kb),
- __ATTR_RW(min_ratio),
- __ATTR_RW(max_ratio),
- __ATTR_RO(stable_pages_required),
- __ATTR_NULL,
+static struct attribute *bdi_dev_attrs[] = {
+ &dev_attr_read_ahead_kb.attr,
+ &dev_attr_min_ratio.attr,
+ &dev_attr_max_ratio.attr,
+ &dev_attr_stable_pages_required.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(bdi_dev);
static __init int bdi_class_init(void)
{
if (IS_ERR(bdi_class))
return PTR_ERR(bdi_class);
- bdi_class->dev_attrs = bdi_dev_attrs;
+ bdi_class->dev_groups = bdi_dev_groups;
bdi_debug_init();
return 0;
}
{ \
return sprintf(buf, format_string, net->field); \
} \
-static ssize_t show_##field(struct device *dev, \
+static ssize_t field##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
return netdev_show(dev, attr, buf, format_##field); \
-}
+} \
+
+#define NETDEVICE_SHOW_RO(field, format_string) \
+NETDEVICE_SHOW(field, format_string); \
+static DEVICE_ATTR_RO(field)
+#define NETDEVICE_SHOW_RW(field, format_string) \
+NETDEVICE_SHOW(field, format_string); \
+static DEVICE_ATTR_RW(field)
/* use same locking and permission rules as SIF* ioctl's */
static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
return ret;
}
-NETDEVICE_SHOW(dev_id, fmt_hex);
-NETDEVICE_SHOW(addr_assign_type, fmt_dec);
-NETDEVICE_SHOW(addr_len, fmt_dec);
-NETDEVICE_SHOW(iflink, fmt_dec);
-NETDEVICE_SHOW(ifindex, fmt_dec);
-NETDEVICE_SHOW(type, fmt_dec);
-NETDEVICE_SHOW(link_mode, fmt_dec);
+NETDEVICE_SHOW_RO(dev_id, fmt_hex);
+NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec);
+NETDEVICE_SHOW_RO(addr_len, fmt_dec);
+NETDEVICE_SHOW_RO(iflink, fmt_dec);
+NETDEVICE_SHOW_RO(ifindex, fmt_dec);
+NETDEVICE_SHOW_RO(type, fmt_dec);
+NETDEVICE_SHOW_RO(link_mode, fmt_dec);
/* use same locking rules as GIFHWADDR ioctl's */
-static ssize_t show_address(struct device *dev, struct device_attribute *attr,
+static ssize_t address_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct net_device *net = to_net_dev(dev);
read_unlock(&dev_base_lock);
return ret;
}
+static DEVICE_ATTR_RO(address);
-static ssize_t show_broadcast(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t broadcast_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct net_device *net = to_net_dev(dev);
if (dev_isalive(net))
return sysfs_format_mac(buf, net->broadcast, net->addr_len);
return -EINVAL;
}
+static DEVICE_ATTR_RO(broadcast);
static int change_carrier(struct net_device *net, unsigned long new_carrier)
{
return dev_change_carrier(net, (bool) new_carrier);
}
-static ssize_t store_carrier(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t len)
+static ssize_t carrier_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
return netdev_store(dev, attr, buf, len, change_carrier);
}
-static ssize_t show_carrier(struct device *dev,
+static ssize_t carrier_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct net_device *netdev = to_net_dev(dev);
}
return -EINVAL;
}
+static DEVICE_ATTR_RW(carrier);
-static ssize_t show_speed(struct device *dev,
+static ssize_t speed_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct net_device *netdev = to_net_dev(dev);
rtnl_unlock();
return ret;
}
+static DEVICE_ATTR_RO(speed);
-static ssize_t show_duplex(struct device *dev,
+static ssize_t duplex_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct net_device *netdev = to_net_dev(dev);
rtnl_unlock();
return ret;
}
+static DEVICE_ATTR_RO(duplex);
-static ssize_t show_dormant(struct device *dev,
+static ssize_t dormant_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct net_device *netdev = to_net_dev(dev);
return -EINVAL;
}
+static DEVICE_ATTR_RO(dormant);
static const char *const operstates[] = {
"unknown",
"up"
};
-static ssize_t show_operstate(struct device *dev,
+static ssize_t operstate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct net_device *netdev = to_net_dev(dev);
return sprintf(buf, "%s\n", operstates[operstate]);
}
+static DEVICE_ATTR_RO(operstate);
/* read-write attributes */
-NETDEVICE_SHOW(mtu, fmt_dec);
static int change_mtu(struct net_device *net, unsigned long new_mtu)
{
return dev_set_mtu(net, (int) new_mtu);
}
-static ssize_t store_mtu(struct device *dev, struct device_attribute *attr,
+static ssize_t mtu_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
return netdev_store(dev, attr, buf, len, change_mtu);
}
-
-NETDEVICE_SHOW(flags, fmt_hex);
+NETDEVICE_SHOW_RW(mtu, fmt_dec);
static int change_flags(struct net_device *net, unsigned long new_flags)
{
return dev_change_flags(net, (unsigned int) new_flags);
}
-static ssize_t store_flags(struct device *dev, struct device_attribute *attr,
+static ssize_t flags_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
return netdev_store(dev, attr, buf, len, change_flags);
}
-
-NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
+NETDEVICE_SHOW_RW(flags, fmt_hex);
static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
{
return 0;
}
-static ssize_t store_tx_queue_len(struct device *dev,
+static ssize_t tx_queue_len_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
return netdev_store(dev, attr, buf, len, change_tx_queue_len);
}
+NETDEVICE_SHOW_RW(tx_queue_len, fmt_ulong);
-static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
+static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
struct net_device *netdev = to_net_dev(dev);
return ret < 0 ? ret : len;
}
-static ssize_t show_ifalias(struct device *dev,
+static ssize_t ifalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct net_device *netdev = to_net_dev(dev);
rtnl_unlock();
return ret;
}
-
-NETDEVICE_SHOW(group, fmt_dec);
+static DEVICE_ATTR_RW(ifalias);
static int change_group(struct net_device *net, unsigned long new_group)
{
return 0;
}
-static ssize_t store_group(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t len)
+static ssize_t group_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
return netdev_store(dev, attr, buf, len, change_group);
}
-
-static struct device_attribute net_class_attributes[] = {
- __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL),
- __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
- __ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
- __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
- __ATTR(iflink, S_IRUGO, show_iflink, NULL),
- __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
- __ATTR(type, S_IRUGO, show_type, NULL),
- __ATTR(link_mode, S_IRUGO, show_link_mode, NULL),
- __ATTR(address, S_IRUGO, show_address, NULL),
- __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
- __ATTR(carrier, S_IRUGO | S_IWUSR, show_carrier, store_carrier),
- __ATTR(speed, S_IRUGO, show_speed, NULL),
- __ATTR(duplex, S_IRUGO, show_duplex, NULL),
- __ATTR(dormant, S_IRUGO, show_dormant, NULL),
- __ATTR(operstate, S_IRUGO, show_operstate, NULL),
- __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
- __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags),
- __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
- store_tx_queue_len),
- __ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group),
- {}
+NETDEVICE_SHOW(group, fmt_dec);
+static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store);
+
+static struct attribute *net_class_attrs[] = {
+ &dev_attr_netdev_group.attr,
+ &dev_attr_type.attr,
+ &dev_attr_dev_id.attr,
+ &dev_attr_iflink.attr,
+ &dev_attr_ifindex.attr,
+ &dev_attr_addr_assign_type.attr,
+ &dev_attr_addr_len.attr,
+ &dev_attr_link_mode.attr,
+ &dev_attr_address.attr,
+ &dev_attr_broadcast.attr,
+ &dev_attr_speed.attr,
+ &dev_attr_duplex.attr,
+ &dev_attr_dormant.attr,
+ &dev_attr_operstate.attr,
+ &dev_attr_ifalias.attr,
+ &dev_attr_carrier.attr,
+ &dev_attr_mtu.attr,
+ &dev_attr_flags.attr,
+ &dev_attr_tx_queue_len.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(net_class);
/* Show a given an attribute in the statistics group */
static ssize_t netstat_show(const struct device *d,
/* generate a read-only statistics attribute */
#define NETSTAT_ENTRY(name) \
-static ssize_t show_##name(struct device *d, \
+static ssize_t name##_show(struct device *d, \
struct device_attribute *attr, char *buf) \
{ \
return netstat_show(d, attr, buf, \
offsetof(struct rtnl_link_stats64, name)); \
} \
-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static DEVICE_ATTR_RO(name)
NETSTAT_ENTRY(rx_packets);
NETSTAT_ENTRY(tx_packets);
.attrs = wireless_attrs,
};
#endif
+
+#else /* CONFIG_SYSFS */
+#define net_class_groups NULL
#endif /* CONFIG_SYSFS */
#ifdef CONFIG_RPS
static struct class net_class = {
.name = "net",
.dev_release = netdev_release,
-#ifdef CONFIG_SYSFS
- .dev_attrs = net_class_attributes,
-#endif /* CONFIG_SYSFS */
+ .dev_groups = net_class_groups,
.dev_uevent = netdev_uevent,
.ns_type = &net_ns_type_operations,
.namespace = net_namespace,
ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
mutex_unlock(&phy->pib_lock); \
return ret; \
-}
+} \
+static DEVICE_ATTR_RO(name);
#define MASTER_SHOW(field, format_string) \
MASTER_SHOW_COMPLEX(field, format_string, phy->field)
mutex_unlock(&phy->pib_lock);
return len;
}
-
-static struct device_attribute pmib_attrs[] = {
- __ATTR_RO(current_channel),
- __ATTR_RO(current_page),
- __ATTR_RO(channels_supported),
- __ATTR_RO(transmit_power),
- __ATTR_RO(cca_mode),
- {},
+static DEVICE_ATTR_RO(channels_supported);
+
+static struct attribute *pmib_attrs[] = {
+ &dev_attr_current_channel.attr,
+ &dev_attr_current_page.attr,
+ &dev_attr_channels_supported.attr,
+ &dev_attr_transmit_power.attr,
+ &dev_attr_cca_mode.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(pmib);
static void wpan_phy_release(struct device *d)
{
static struct class wpan_phy_class = {
.name = "ieee802154",
.dev_release = wpan_phy_release,
- .dev_attrs = pmib_attrs,
+ .dev_groups = pmib_groups,
};
static DEFINE_MUTEX(wpan_phy_mutex);
}
EXPORT_SYMBOL(rfkill_set_states);
-static ssize_t rfkill_name_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%s\n", rfkill->name);
}
+static DEVICE_ATTR_RO(name);
static const char *rfkill_get_type_str(enum rfkill_type type)
{
}
}
-static ssize_t rfkill_type_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t type_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
}
+static DEVICE_ATTR_RO(type);
-static ssize_t rfkill_idx_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t index_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%d\n", rfkill->idx);
}
+static DEVICE_ATTR_RO(index);
-static ssize_t rfkill_persistent_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t persistent_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%d\n", rfkill->persistent);
}
+static DEVICE_ATTR_RO(persistent);
-static ssize_t rfkill_hard_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t hard_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 );
}
+static DEVICE_ATTR_RO(hard);
-static ssize_t rfkill_soft_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t soft_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 );
}
-static ssize_t rfkill_soft_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t soft_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct rfkill *rfkill = to_rfkill(dev);
unsigned long state;
return count;
}
+static DEVICE_ATTR_RW(soft);
static u8 user_state_from_blocked(unsigned long state)
{
return RFKILL_USER_STATE_UNBLOCKED;
}
-static ssize_t rfkill_state_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state));
}
-static ssize_t rfkill_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t state_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct rfkill *rfkill = to_rfkill(dev);
unsigned long state;
return count;
}
+static DEVICE_ATTR_RW(state);
-static ssize_t rfkill_claim_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t claim_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", 0);
}
-
-static ssize_t rfkill_claim_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return -EOPNOTSUPP;
-}
-
-static struct device_attribute rfkill_dev_attrs[] = {
- __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
- __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
- __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),
- __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL),
- __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
- __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
- __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store),
- __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL),
- __ATTR_NULL
+static DEVICE_ATTR_RO(claim);
+
+static struct attribute *rfkill_dev_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_type.attr,
+ &dev_attr_index.attr,
+ &dev_attr_persistent.attr,
+ &dev_attr_state.attr,
+ &dev_attr_claim.attr,
+ &dev_attr_soft.attr,
+ &dev_attr_hard.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(rfkill_dev);
static void rfkill_release(struct device *dev)
{
static struct class rfkill_class = {
.name = "rfkill",
.dev_release = rfkill_release,
- .dev_attrs = rfkill_dev_attrs,
+ .dev_groups = rfkill_dev_groups,
.dev_uevent = rfkill_dev_uevent,
.suspend = rfkill_suspend,
.resume = rfkill_resume,
char *buf) \
{ \
return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
-}
+} \
+static DEVICE_ATTR_RO(name)
SHOW_FMT(index, "%d", wiphy_idx);
SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
}
-
+static DEVICE_ATTR_RO(name);
static ssize_t addresses_show(struct device *dev,
struct device_attribute *attr,
return buf - start;
}
-
-static struct device_attribute ieee80211_dev_attrs[] = {
- __ATTR_RO(index),
- __ATTR_RO(macaddress),
- __ATTR_RO(address_mask),
- __ATTR_RO(addresses),
- __ATTR_RO(name),
- {}
+static DEVICE_ATTR_RO(addresses);
+
+static struct attribute *ieee80211_attrs[] = {
+ &dev_attr_index.attr,
+ &dev_attr_macaddress.attr,
+ &dev_attr_address_mask.attr,
+ &dev_attr_addresses.attr,
+ &dev_attr_name.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(ieee80211);
static void wiphy_dev_release(struct device *dev)
{
.name = "ieee80211",
.owner = THIS_MODULE,
.dev_release = wiphy_dev_release,
- .dev_attrs = ieee80211_dev_attrs,
+ .dev_groups = ieee80211_groups,
.dev_uevent = wiphy_uevent,
#ifdef CONFIG_PM
.suspend = wiphy_suspend,