Merge tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Sep 2013 18:37:15 +0000 (11:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Sep 2013 18:37:15 +0000 (11:37 -0700)
Pull driver core patches from Greg KH:
 "Here's the big driver core pull request for 3.12-rc1.

  Lots of tiny changes here fixing up the way sysfs attributes are
  created, to try to make drivers simpler, and fix a whole class race
  conditions with creations of device attributes after the device was
  announced to userspace.

  All the various pieces are acked by the different subsystem
  maintainers"

* tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (119 commits)
  firmware loader: fix pending_fw_head list corruption
  drivers/base/memory.c: introduce help macro to_memory_block
  dynamic debug: line queries failing due to uninitialized local variable
  sysfs: sysfs_create_groups returns a value.
  debugfs: provide debugfs_create_x64() when disabled
  rbd: convert bus code to use bus_groups
  firmware: dcdbas: use binary attribute groups
  sysfs: add sysfs_create/remove_groups for when SYSFS is not enabled
  driver core: add #include <linux/sysfs.h> to core files.
  HID: convert bus code to use dev_groups
  Input: serio: convert bus code to use drv_groups
  Input: gameport: convert bus code to use drv_groups
  driver core: firmware: use __ATTR_RW()
  driver core: core: use DEVICE_ATTR_RO
  driver core: bus: use DRIVER_ATTR_WO()
  driver core: create write-only attribute macros for devices and drivers
  sysfs: create __ATTR_WO()
  driver-core: platform: convert bus code to use dev_groups
  workqueue: convert bus code to use dev_groups
  MEI: convert bus code to use dev_groups
  ...

99 files changed:
Documentation/ko_KR/HOWTO
Documentation/ko_KR/stable_api_nonsense.txt
arch/arm/Kconfig
arch/ia64/Kconfig
arch/mips/Kconfig
arch/mips/kernel/vpe.c
arch/powerpc/Kconfig
arch/sh/Kconfig
arch/tile/include/asm/topology.h
arch/x86/Kconfig
arch/x86/include/asm/topology.h
drivers/acpi/bgrt.c
drivers/base/base.h
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/cpu.c
drivers/base/dma-contiguous.c
drivers/base/driver.c
drivers/base/firmware_class.c
drivers/base/memory.c
drivers/base/platform.c
drivers/base/power/sysfs.c
drivers/base/regmap/regmap-debugfs.c
drivers/base/topology.c
drivers/block/rbd.c
drivers/char/bsr.c
drivers/char/tile-srom.c
drivers/devfreq/devfreq.c
drivers/dma/dmaengine.c
drivers/extcon/extcon-class.c
drivers/firmware/dcdbas.c
drivers/hid/hid-core.c
drivers/hid/hid-roccat-arvo.c
drivers/hid/hid-roccat-isku.c
drivers/hid/hid-roccat-kone.c
drivers/hid/hid-roccat-koneplus.c
drivers/hid/hid-roccat-konepure.c
drivers/hid/hid-roccat-kovaplus.c
drivers/hid/hid-roccat-pyra.c
drivers/hid/hid-roccat-savu.c
drivers/input/gameport/gameport.c
drivers/input/serio/serio.c
drivers/isdn/mISDN/core.c
drivers/leds/led-class.c
drivers/media/v4l2-core/v4l2-dev.c
drivers/misc/c2port/core.c
drivers/misc/enclosure.c
drivers/misc/mei/bus.c
drivers/net/ethernet/sun/niu.c
drivers/platform/x86/wmi.c
drivers/pps/pps.c
drivers/pps/sysfs.c
drivers/ptp/ptp_clock.c
drivers/ptp/ptp_private.h
drivers/ptp/ptp_sysfs.c
drivers/rtc/rtc-sysfs.c
drivers/scsi/osd/osd_uld.c
drivers/staging/comedi/comedi_fops.c
drivers/uio/uio.c
drivers/usb/serial/bus.c
drivers/video/backlight/backlight.c
drivers/video/backlight/lcd.c
drivers/w1/slaves/w1_ds2408.c
drivers/w1/slaves/w1_ds2413.c
drivers/w1/slaves/w1_ds2423.c
drivers/w1/slaves/w1_ds2431.c
drivers/w1/slaves/w1_ds2433.c
drivers/w1/slaves/w1_ds2760.c
drivers/w1/slaves/w1_ds2780.c
drivers/w1/slaves/w1_ds2781.c
drivers/w1/slaves/w1_ds28e04.c
drivers/w1/slaves/w1_therm.c
drivers/w1/w1.c
drivers/w1/w1_family.h
fs/fuse/cuse.c
fs/sysfs/bin.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/inode.c
fs/sysfs/mount.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/linux/debugfs.h
include/linux/device.h
include/linux/kobject.h
include/linux/memory.h
include/linux/pps_kernel.h
include/linux/sysfs.h
kernel/workqueue.c
lib/Kconfig.debug
lib/dynamic_debug.c
lib/kobject.c
mm/backing-dev.c
net/core/net-sysfs.c
net/ieee802154/wpan-class.c
net/rfkill/core.c
net/wireless/sysfs.c

index 2f48f20..680e646 100644 (file)
@@ -182,8 +182,8 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H
 프로젝트를 봐야 한다.
     http://kernelnewbies.org
 그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저
-아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할있는 도움이
-될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할수 있는 IRC 채널도
+아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할 수 있는 도움이
+될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할 수 있는 IRC 채널도
 가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다.
 
 웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들
@@ -245,7 +245,7 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H
     것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가
     드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은
     회귀(역자주: 이전에는 존재하지 않았지만 새로운 기능추가나 변경으로 인해
-               생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이
+    생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이
     배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은
     공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다.
   - 새로운 -rc는 Linus가 현재 git tree가 테스트 하기에 충분히 안정된 상태에
@@ -455,7 +455,7 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메
  - 의견
  - 변경을 위한 요구
  - 당위성을 위한 요구
- - 고요
+ - 침묵
 
 기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의
 패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고
@@ -472,7 +472,7 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메
 가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상
 어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은
 협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면
-ì \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명하여야 한다. 잘못된 것도 여러분이
 올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을
 기억하라.
 
@@ -488,21 +488,21 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메
 커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의
 문제를 피하기 위한 목록이 있다.
   여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 :
-    - "ì\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 라인 짜리 패치가 있으니..."
     - "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..."
     - "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다."
 
@@ -574,6 +574,7 @@ Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅
 또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들을 포함하는
 패치들은 받아들여지지 않을 것이라는 점을 유념하라.
 
+
 변경을 정당화해라
 -----------------
 
index 8f2b0e1..51f85ad 100644 (file)
@@ -106,12 +106,12 @@ Greg Kroah-Hartman <greg@kroah.com>
 ---------------------------------
 
 리눅스 커널 드라이버를 계속해서 메인 커널 트리에 반영하지 않고
\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들과 이 문제를 논의하게 되면 훨씬 더
 "논란의 여지가 많은" 주제가 될 것이다.
 
 리눅스 커널 개발은 끊임없이 빠른 속도로 이루어지고 있으며 결코
 느슨해진 적이 없다. 커널 개발자들이 현재 인터페이스들에서 버그를
-발견하거나 무엇인가 할수 있는 더 좋은 방법을 찾게 되었다고 하자.
+발견하거나 무엇인가 할 수 있는 더 좋은 방법을 찾게 되었다고 하자.
 그들이 발견한 것을 실행한다면 아마도 더 잘 동작하도록 현재 인터페이스들을
 수정하게 될 것이다. 그들이 그런 일을 하게되면 함수 이름들은 변하게 되고,
 구조체들은 늘어나거나 줄어들게 되고, 함수 파라미터들은 재작업될 것이다.
@@ -174,7 +174,7 @@ GPL을 따르는 배포 드라이버에 관해 얘기하고 있다는 것을 상
 동작하는 것을 보장한다.
 
 메인 커널 트리에 여러분의 드라이버를 반영하면 얻게 되는 장점들은 다음과 같다.
-   - ê´\80리ì\9d\98 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다.
+   - ê´\80리ì\97\90 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다.
    - 다른 개발자들이 여러분의 드라이버에 기능들을 추가 할 것이다.
    - 다른 사람들은 여러분의 드라이버에 버그를 발견하고 수정할 것이다.
    - 다른 사람들은 여러분의 드라이버의 개선점을 찾을 줄 것이다.
index 43594d5..cd5c1c9 100644 (file)
@@ -2064,8 +2064,7 @@ config KEXEC
 
          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"
index 5a768ad..b36370d 100644 (file)
@@ -565,9 +565,9 @@ config KEXEC
 
          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"
index e12764c..dccd7ce 100644 (file)
@@ -2305,9 +2305,9 @@ config KEXEC
 
          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"
index 1765bab..faf84c5 100644 (file)
@@ -1335,8 +1335,9 @@ static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
 
        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);
@@ -1344,7 +1345,7 @@ static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr,
        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);
@@ -1365,12 +1366,14 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
 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)
 {
@@ -1381,7 +1384,7 @@ struct class vpe_class = {
        .name = "vpe",
        .owner = THIS_MODULE,
        .dev_release = vpe_device_release,
-       .dev_attrs = vpe_class_attributes,
+       .dev_groups = vpe_groups,
 };
 
 struct device vpe_device;
index 9cf5981..5aecda0 100644 (file)
@@ -369,9 +369,9 @@ config KEXEC
 
          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"
index 1020dd8..1018ed3 100644 (file)
@@ -643,9 +643,9 @@ config KEXEC
 
          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)"
index d5e86c9..d15c0d8 100644 (file)
@@ -89,9 +89,6 @@ static inline const struct cpumask *cpumask_of_node(int node)
 #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 */
index 67e0074..2745737 100644 (file)
@@ -1628,9 +1628,9 @@ config KEXEC
 
          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"
index 095b215..d35f24e 100644 (file)
@@ -124,9 +124,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu);
 #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)
index be60399..a83e3c6 100644 (file)
@@ -51,20 +51,14 @@ static ssize_t show_yoffset(struct device *dev,
 }
 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,
@@ -75,8 +69,14 @@ static struct attribute *bgrt_attributes[] = {
        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)
@@ -86,9 +86,8 @@ 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)
@@ -98,14 +97,8 @@ static int __init bgrt_init(void)
        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;
index b8bdfe6..2cbc677 100644 (file)
@@ -119,6 +119,16 @@ static inline int driver_match_device(struct device_driver *drv,
        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);
index d414331..4c289ab 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include "base.h"
 #include "power/power.h"
 
@@ -165,8 +166,8 @@ static const struct kset_uevent_ops bus_uevent_ops = {
 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;
@@ -185,15 +186,15 @@ static ssize_t driver_unbind(struct device_driver *drv,
        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;
@@ -221,7 +222,7 @@ static ssize_t driver_bind(struct device_driver *drv,
        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)
 {
@@ -460,7 +461,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev)
        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)
@@ -476,7 +477,7 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev)
        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]);
        }
 }
@@ -499,6 +500,9 @@ int bus_add_device(struct device *dev)
                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)
@@ -513,6 +517,8 @@ int bus_add_device(struct device *dev)
 
 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:
@@ -575,6 +581,7 @@ void bus_remove_device(struct device *dev)
        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);
 
@@ -590,7 +597,7 @@ static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv)
        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;
@@ -610,7 +617,7 @@ static void driver_remove_attrs(struct bus_type *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++)
                        driver_remove_file(drv, &bus->drv_attrs[i]);
        }
 }
@@ -659,8 +666,8 @@ static void remove_probe_files(struct bus_type *bus)
        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;
 
@@ -668,7 +675,7 @@ static ssize_t driver_uevent_store(struct device_driver *drv,
                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.
@@ -719,6 +726,10 @@ int bus_add_driver(struct device_driver *drv)
                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);
@@ -756,6 +767,7 @@ void bus_remove_driver(struct device_driver *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);
@@ -846,7 +858,7 @@ static int bus_add_attrs(struct bus_type *bus)
        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;
@@ -865,11 +877,23 @@ static void bus_remove_attrs(struct bus_type *bus)
        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);
@@ -962,10 +986,15 @@ int bus_register(struct bus_type *bus)
        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:
@@ -996,6 +1025,7 @@ void bus_unregister(struct bus_type *bus)
        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);
index 3ce8454..8b7818b 100644 (file)
@@ -135,7 +135,7 @@ static int add_class_attrs(struct class *cls)
        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;
@@ -154,7 +154,7 @@ static void remove_class_attrs(struct class *cls)
        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]);
        }
 }
index 8856d74..c7b0925 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/async.h>
 #include <linux/pm_runtime.h>
 #include <linux/netdevice.h>
+#include <linux/sysfs.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -36,9 +37,9 @@ long sysfs_deprecated = 1;
 #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
@@ -345,7 +346,7 @@ static const struct kset_uevent_ops device_uevent_ops = {
        .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;
@@ -388,7 +389,7 @@ out:
        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;
@@ -399,11 +400,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
                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;
@@ -414,7 +413,7 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr,
        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;
@@ -429,9 +428,7 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr,
        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)
@@ -440,7 +437,7 @@ static int device_add_attributes(struct device *dev,
        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;
@@ -458,7 +455,7 @@ static void device_remove_attributes(struct device *dev,
        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]);
 }
 
@@ -469,7 +466,7 @@ static int device_add_bin_attributes(struct device *dev,
        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;
@@ -487,38 +484,19 @@ static void device_remove_bin_attributes(struct device *dev,
        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)
@@ -550,7 +528,7 @@ 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;
        }
@@ -578,7 +556,7 @@ static void device_remove_attrs(struct device *dev)
        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)
@@ -591,15 +569,12 @@ static void device_remove_attrs(struct device *dev)
        }
 }
 
-
-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;
@@ -626,6 +601,7 @@ int device_create_file(struct device *dev,
 
        return error;
 }
+EXPORT_SYMBOL_GPL(device_create_file);
 
 /**
  * device_remove_file - remove sysfs attribute file.
@@ -638,6 +614,7 @@ void device_remove_file(struct device *dev,
        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.
@@ -748,6 +725,7 @@ void device_initialize(struct device *dev)
        device_pm_init(dev);
        set_dev_node(dev, -1);
 }
+EXPORT_SYMBOL_GPL(device_initialize);
 
 struct kobject *virtual_device_parent(struct device *dev)
 {
@@ -1100,12 +1078,12 @@ int device_add(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;
 
@@ -1172,9 +1150,9 @@ done:
                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);
@@ -1187,6 +1165,7 @@ name_error:
        dev->p = NULL;
        goto done;
 }
+EXPORT_SYMBOL_GPL(device_add);
 
 /**
  * device_register - register a device with the system.
@@ -1211,6 +1190,7 @@ int device_register(struct device *dev)
        device_initialize(dev);
        return device_add(dev);
 }
+EXPORT_SYMBOL_GPL(device_register);
 
 /**
  * get_device - increment reference count for device.
@@ -1224,6 +1204,7 @@ struct device *get_device(struct device *dev)
 {
        return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL;
 }
+EXPORT_SYMBOL_GPL(get_device);
 
 /**
  * put_device - decrement reference count.
@@ -1235,6 +1216,7 @@ void put_device(struct device *dev)
        if (dev)
                kobject_put(&dev->kobj);
 }
+EXPORT_SYMBOL_GPL(put_device);
 
 /**
  * device_del - delete device from system.
@@ -1266,7 +1248,7 @@ void device_del(struct device *dev)
        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);
@@ -1281,7 +1263,7 @@ void device_del(struct device *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);
@@ -1297,6 +1279,7 @@ void device_del(struct device *dev)
        kobject_del(&dev->kobj);
        put_device(parent);
 }
+EXPORT_SYMBOL_GPL(device_del);
 
 /**
  * device_unregister - unregister device from system.
@@ -1315,6 +1298,7 @@ void device_unregister(struct device *dev)
        device_del(dev);
        put_device(dev);
 }
+EXPORT_SYMBOL_GPL(device_unregister);
 
 static struct device *next_device(struct klist_iter *i)
 {
@@ -1403,6 +1387,7 @@ int device_for_each_child(struct device *parent, void *data,
        klist_iter_exit(&i);
        return error;
 }
+EXPORT_SYMBOL_GPL(device_for_each_child);
 
 /**
  * device_find_child - device iterator for locating a particular device.
@@ -1437,6 +1422,7 @@ struct device *device_find_child(struct device *parent, void *data,
        klist_iter_exit(&i);
        return child;
 }
+EXPORT_SYMBOL_GPL(device_find_child);
 
 int __init devices_init(void)
 {
@@ -1464,21 +1450,6 @@ 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)
index 4c358bc..6bfaaca 100644 (file)
@@ -43,11 +43,14 @@ static int __ref cpu_subsys_online(struct device *dev)
        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
@@ -57,6 +60,7 @@ static int __ref cpu_subsys_online(struct device *dev)
        if (from_nid != to_nid)
                change_cpu_under_node(cpu, from_nid, to_nid);
 
+ out:
        cpu_hotplug_driver_unlock();
        return ret;
 }
index 0ca5442..6c9cdaa 100644 (file)
@@ -134,7 +134,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
 
 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;
@@ -156,7 +156,7 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
        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);
index 974e301..9e29943 100644 (file)
@@ -15,6 +15,7 @@
 #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)
@@ -123,34 +124,16 @@ void driver_remove_file(struct device_driver *drv,
 }
 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);
 }
 
 /**
index a439602..10a4467 100644 (file)
@@ -486,9 +486,8 @@ static struct notifier_block fw_shutdown_nb = {
        .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);
 }
@@ -506,9 +505,8 @@ static ssize_t firmware_timeout_show(struct class *class,
  *
  *     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)
@@ -518,8 +516,7 @@ static ssize_t firmware_timeout_store(struct class *class,
 }
 
 static struct class_attribute firmware_class_attrs[] = {
-       __ATTR(timeout, S_IWUSR | S_IRUGO,
-               firmware_timeout_show, firmware_timeout_store),
+       __ATTR_RW(timeout),
        __ATTR_NULL
 };
 
@@ -868,8 +865,15 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
                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;
        }
@@ -884,10 +888,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
                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);
index ec386ee..1c61762 100644 (file)
@@ -16,7 +16,6 @@
 #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>
@@ -30,6 +29,8 @@ static DEFINE_MUTEX(mem_sysfs_mutex);
 
 #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)
@@ -77,7 +78,7 @@ EXPORT_SYMBOL(unregister_memory_isolate_notifier);
 
 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);
 }
@@ -110,8 +111,7 @@ static unsigned long get_memory_block_size(void)
 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;
@@ -121,8 +121,7 @@ static ssize_t show_mem_start_phys_index(struct device *dev,
 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;
@@ -137,8 +136,7 @@ static ssize_t show_mem_removable(struct device *dev,
 {
        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))
@@ -156,8 +154,7 @@ static ssize_t show_mem_removable(struct device *dev,
 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;
 
        /*
@@ -263,9 +260,8 @@ memory_block_action(unsigned long phys_index, unsigned long action, int online_t
        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;
 
@@ -275,105 +271,89 @@ static int __memory_block_change_state(struct memory_block *mem,
        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();
 
@@ -394,8 +374,7 @@ store_mem_state(struct device *dev,
 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);
 }
 
@@ -471,7 +450,7 @@ store_soft_offline_page(struct device *dev,
        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))
@@ -490,7 +469,7 @@ store_hard_offline_page(struct device *dev,
        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);
@@ -527,7 +506,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section,
                put_device(&hint->dev);
        if (!dev)
                return NULL;
-       return container_of(dev, struct memory_block, dev);
+       return to_memory_block(dev);
 }
 
 /*
@@ -567,16 +546,13 @@ static const struct attribute_group *memory_memblk_attr_groups[] = {
 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,
@@ -597,7 +573,6 @@ 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);
 
@@ -607,55 +582,57 @@ static int init_memory_block(struct memory_block **memory,
        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
@@ -665,7 +642,7 @@ unregister_memory(struct memory_block *memory)
        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);
 }
 
@@ -682,7 +659,7 @@ static int remove_memory_block(unsigned long node_id,
        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;
@@ -735,7 +712,6 @@ int __init memory_dev_init(void)
        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)
@@ -748,17 +724,13 @@ int __init memory_dev_init(void)
         * 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)
index 3c3197a..4f8bef3 100644 (file)
@@ -672,11 +672,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 
        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)
 {
@@ -893,7 +895,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = {
 
 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,
@@ -1054,7 +1056,7 @@ void __init early_platform_driver_register_all(char *class_str)
  * @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;
@@ -1072,7 +1074,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
  * @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;
index a53ebd2..03e089a 100644 (file)
@@ -206,7 +206,7 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev,
        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);
index 6c2652a..de11eca 100644 (file)
@@ -281,7 +281,7 @@ static ssize_t regmap_map_write_file(struct file *file,
        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 */
index 2f5919e..94ffee3 100644 (file)
@@ -62,25 +62,6 @@ static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf)
 }
 #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)    \
@@ -95,7 +76,6 @@ static ssize_t show_##name##_list(struct device *dev,                 \
 {                                                                      \
        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)
index 4ad2ad9..191cd17 100644 (file)
@@ -397,15 +397,19 @@ static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
 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)
index 9746705..0671e45 100644 (file)
@@ -95,6 +95,7 @@ bsr_size_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_bytes);
 }
+static DEVICE_ATTR_RO(bsr_size);
 
 static ssize_t
 bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -102,20 +103,23 @@ 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)
 {
@@ -308,7 +312,7 @@ static int __init bsr_init(void)
                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);
index 7faeb1c..ae82933 100644 (file)
@@ -279,33 +279,37 @@ loff_t srom_llseek(struct file *file, loff_t offset, int origin)
        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)
 {
@@ -418,7 +422,7 @@ static int srom_init(void)
                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 */
index e94e619..c99c00d 100644 (file)
@@ -703,7 +703,7 @@ err_out:
 }
 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)
@@ -712,7 +712,7 @@ static ssize_t show_governor(struct device *dev,
        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);
@@ -754,9 +754,11 @@ out:
                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;
@@ -775,9 +777,10 @@ static ssize_t show_available_governors(struct device *d,
 
        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);
@@ -788,20 +791,22 @@ static ssize_t show_freq(struct device *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)
 {
@@ -821,8 +826,9 @@ static ssize_t store_polling_interval(struct device *dev,
 
        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);
@@ -849,13 +855,13 @@ unlock:
        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);
@@ -881,16 +887,18 @@ unlock:
        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;
@@ -918,9 +926,10 @@ static ssize_t show_available_freqs(struct device *d,
 
        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;
@@ -959,20 +968,21 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
                                        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)
 {
@@ -988,7 +998,7 @@ 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;
 }
index 9e56745..99af4db 100644 (file)
@@ -87,7 +87,8 @@ static struct dma_chan *dev_to_dma_chan(struct device *dev)
        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;
@@ -106,9 +107,10 @@ static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *at
 
        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;
@@ -127,8 +129,10 @@ static ssize_t show_bytes_transferred(struct device *dev, struct device_attribut
 
        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;
@@ -143,13 +147,15 @@ static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, ch
 
        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)
 {
@@ -167,7 +173,7 @@ 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,
 };
 
index 1446152..148382f 100644 (file)
@@ -148,6 +148,7 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr,
 
        return count;
 }
+static DEVICE_ATTR_RW(state);
 
 static ssize_t name_show(struct device *dev, struct device_attribute *attr,
                char *buf)
@@ -163,6 +164,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
 
        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)
@@ -527,11 +529,12 @@ int extcon_unregister_notifier(struct extcon_dev *edev,
 }
 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)
 {
@@ -539,7 +542,7 @@ 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");
index 8e77c02..ff080ee 100644 (file)
@@ -535,11 +535,12 @@ static struct attribute *dcdbas_dev_attrs[] = {
 
 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;
@@ -555,18 +556,6 @@ static int dcdbas_probe(struct platform_device *dev)
        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",
@@ -577,11 +566,7 @@ static int dcdbas_probe(struct platform_device *dev)
 
 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;
index 36668d1..b8f1c77 100644 (file)
@@ -1917,11 +1917,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 
        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)
 {
@@ -1949,7 +1951,7 @@ 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,
index 327f9b8..eed7f52 100644 (file)
@@ -75,6 +75,8 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
 
        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)
@@ -123,6 +125,8 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
 
        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)
@@ -179,6 +183,9 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *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,
@@ -230,6 +237,8 @@ static ssize_t arvo_sysfs_write_button(struct file *fp,
        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,
@@ -238,31 +247,30 @@ static ssize_t arvo_sysfs_read_info(struct file *fp,
        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,
@@ -430,8 +438,7 @@ static int __init arvo_init(void)
        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)
index 8023751..b7a4e10 100644 (file)
@@ -109,12 +109,12 @@ static ssize_t isku_sysfs_set_actual_profile(struct device *dev,
 
        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,
@@ -184,7 +184,8 @@ ISKU_SYSFS_R(thingy, THINGY) \
 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, \
@@ -192,52 +193,64 @@ ISKU_SYSFS_W(thingy, 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,
@@ -427,8 +440,7 @@ static int __init isku_init(void)
        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)
index 7fae070..6e614a8 100644 (file)
@@ -324,6 +324,8 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
 
        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,
@@ -378,6 +380,19 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp,
 
        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)
@@ -386,6 +401,7 @@ static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
                        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)
@@ -394,6 +410,7 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
                        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,
@@ -416,6 +433,7 @@ 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)
@@ -424,6 +442,8 @@ static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
                        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)
@@ -524,6 +544,7 @@ exit_unlock:
        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)
@@ -570,15 +591,17 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
        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
@@ -587,7 +610,7 @@ static struct device_attribute kone_attributes[] = {
         * 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.
@@ -595,66 +618,38 @@ static struct device_attribute kone_attributes[] = {
         * 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,
@@ -891,8 +886,7 @@ static int __init kone_init(void)
        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)
index 6a48fa3..db4d8b6 100644 (file)
@@ -156,7 +156,8 @@ KONEPLUS_SYSFS_W(thingy, THINGY) \
 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, \
@@ -164,28 +165,29 @@ KONEPLUS_SYSFS_R(thingy, 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,
@@ -225,6 +227,25 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
                        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)
 {
@@ -274,6 +295,12 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
 
        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)
@@ -293,90 +320,47 @@ static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
 
        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,
@@ -572,8 +556,7 @@ static int __init koneplus_init(void)
        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)
index c79d0b0..fa02b1f 100644 (file)
@@ -94,7 +94,8 @@ KONEPURE_SYSFS_W(thingy, THINGY) \
 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, \
@@ -102,44 +103,56 @@ KONEPURE_SYSFS_R(thingy, 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)
 {
@@ -282,7 +295,7 @@ static int __init konepure_init(void)
        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)
index b8b3778..8a0f299 100644 (file)
@@ -197,31 +197,25 @@ KOVAPLUS_SYSFS_W(thingy, THINGY) \
 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,
@@ -261,6 +255,25 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
                        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)
 {
@@ -310,6 +323,9 @@ static ssize_t kovaplus_sysfs_set_actual_profile(struct device *dev,
 
        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)
@@ -318,6 +334,7 @@ static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev,
                        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)
@@ -326,6 +343,8 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev,
                        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)
@@ -334,6 +353,8 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev,
                        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)
@@ -353,88 +374,44 @@ static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
 
        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,
@@ -662,8 +639,7 @@ static int __init kovaplus_init(void)
        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)
index d4f1e3b..5a6dbbe 100644 (file)
@@ -156,7 +156,8 @@ PYRA_SYSFS_W(thingy, THINGY) \
 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, \
@@ -164,24 +165,25 @@ PYRA_SYSFS_R(thingy, 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,
@@ -221,6 +223,25 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
                        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)
@@ -258,6 +279,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
        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)
@@ -266,6 +292,7 @@ static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
                        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)
@@ -282,6 +309,8 @@ static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
 
        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)
@@ -301,84 +330,44 @@ static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
 
        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,
@@ -600,8 +589,7 @@ static int __init pyra_init(void)
        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)
index 31747a2..0332267 100644 (file)
@@ -94,44 +94,48 @@ SAVU_SYSFS_W(thingy, THINGY) \
 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,
@@ -294,7 +298,7 @@ static int __init savu_init(void)
        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)
index da739d9..922a7fe 100644 (file)
@@ -639,16 +639,18 @@ EXPORT_SYMBOL(gameport_unregister_port);
  * 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)
 {
@@ -749,7 +751,7 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv)
 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,
index 25fc597..2b56855 100644 (file)
@@ -732,19 +732,20 @@ EXPORT_SYMBOL(serio_unregister_child_port);
  * 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;
@@ -760,14 +761,14 @@ static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char
 
        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)
 {
@@ -996,7 +997,7 @@ EXPORT_SYMBOL(serio_interrupt);
 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,
index da30c5c..faf5054 100644 (file)
@@ -37,8 +37,8 @@ static void mISDN_dev_release(struct device *dev)
        /* 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);
 
@@ -46,9 +46,10 @@ static ssize_t _show_id(struct device *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);
 
@@ -56,9 +57,10 @@ static ssize_t _show_nrbchan(struct device *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);
 
@@ -66,9 +68,10 @@ static ssize_t _show_d_protocols(struct device *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);
 
@@ -76,9 +79,10 @@ static ssize_t _show_b_protocols(struct device *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);
 
@@ -86,17 +90,19 @@ static ssize_t _show_protocol(struct device *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);
@@ -113,10 +119,11 @@ static ssize_t _set_name(struct device *dev, struct device_attribute *attr,
 
        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;
@@ -127,18 +134,19 @@ static ssize_t _show_channelmap(struct device *dev,
 
        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)
 {
@@ -162,7 +170,7 @@ static struct class mISDN_class = {
        .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,
 };
index 4336e37..f37d63c 100644 (file)
@@ -29,7 +29,7 @@ static void led_update_brightness(struct led_classdev *led_cdev)
                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);
@@ -40,7 +40,7 @@ static ssize_t led_brightness_show(struct device *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);
@@ -57,6 +57,7 @@ static ssize_t led_brightness_store(struct device *dev,
 
        return size;
 }
+static DEVICE_ATTR_RW(brightness);
 
 static ssize_t led_max_brightness_show(struct device *dev,
                struct device_attribute *attr, char *buf)
@@ -65,14 +66,35 @@ static ssize_t led_max_brightness_show(struct device *dev,
 
        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)
@@ -258,7 +280,7 @@ static int __init leds_init(void)
        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;
 }
 
index c8859d6..b0f49b0 100644 (file)
  *     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;
@@ -68,21 +69,24 @@ static ssize_t set_debug(struct device *cd, struct device_attribute *attr,
        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
@@ -217,7 +221,7 @@ static void v4l2_device_release(struct device *cd)
 
 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)
index f32550a..464419b 100644 (file)
@@ -311,6 +311,7 @@ static ssize_t c2port_show_name(struct device *dev,
 
        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)
@@ -320,6 +321,7 @@ static ssize_t c2port_show_flash_blocks_num(struct device *dev,
 
        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)
@@ -329,6 +331,7 @@ static ssize_t c2port_show_flash_block_size(struct device *dev,
 
        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)
@@ -338,18 +341,18 @@ static ssize_t c2port_show_flash_size(struct device *dev,
 
        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;
@@ -375,6 +378,7 @@ static ssize_t c2port_store_access(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR_RW(access);
 
 static ssize_t c2port_store_reset(struct device *dev,
                                struct device_attribute *attr,
@@ -395,6 +399,7 @@ static ssize_t c2port_store_reset(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
 
 static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
 {
@@ -431,6 +436,7 @@ static ssize_t c2port_show_dev_id(struct device *dev,
 
        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)
 {
@@ -467,6 +473,7 @@ static ssize_t c2port_show_rev_id(struct device *dev,
 
        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)
@@ -536,6 +543,8 @@ static ssize_t c2port_store_flash_access(struct device *dev,
 
        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)
 {
@@ -616,6 +625,7 @@ static ssize_t c2port_store_flash_erase(struct 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)
@@ -846,35 +856,40 @@ static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
 
        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,
 };
 
 /*
@@ -907,6 +922,8 @@ struct c2port_device *c2port_device_register(char *name,
                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))) {
@@ -919,12 +936,6 @@ struct c2port_device *c2port_device_register(char *name,
        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);
@@ -937,9 +948,6 @@ struct c2port_device *c2port_device_register(char *name,
 
        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);
@@ -959,7 +967,6 @@ void c2port_device_unregister(struct c2port_device *c2dev)
 
        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);
@@ -984,7 +991,7 @@ static int __init c2port_init(void)
                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;
 }
index 00e5fca..0e8df41 100644 (file)
@@ -239,7 +239,7 @@ static void enclosure_component_release(struct device *dev)
        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
@@ -282,7 +282,7 @@ enclosure_component_register(struct enclosure_device *edev,
                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) {
@@ -365,25 +365,26 @@ EXPORT_SYMBOL_GPL(enclosure_remove_device);
  * 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 [] = {
@@ -536,15 +537,7 @@ static struct attribute *enclosure_component_attrs[] = {
        &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)
 {
index a150a42..6d0282c 100644 (file)
@@ -108,11 +108,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 
        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)
 {
@@ -124,7 +126,7 @@ 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,
index fa32240..52b2adf 100644 (file)
@@ -9478,7 +9478,7 @@ static struct niu_parent *niu_new_parent(struct niu *np,
        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)
index b13344c..6e02c95 100644 (file)
@@ -693,11 +693,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
        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)
 {
@@ -732,7 +734,7 @@ static struct class wmi_class = {
        .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,
index 7173e3a..2f07cd6 100644 (file)
@@ -406,7 +406,7 @@ static int __init pps_init(void)
                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) {
index ef0978c..aefb75d 100644 (file)
@@ -29,8 +29,8 @@
  * 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);
 
@@ -41,9 +41,10 @@ static ssize_t pps_show_assert(struct device *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);
 
@@ -54,45 +55,59 @@ static ssize_t pps_show_clear(struct device *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,
 };
index 4a8c388..a8319b2 100644 (file)
@@ -330,7 +330,7 @@ static int __init ptp_init(void)
                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;
 
index 69d3207..df03f2e 100644 (file)
@@ -84,7 +84,7 @@ uint ptp_poll(struct posix_clock *pc,
  * 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);
 
index 2f93926..13ec531 100644 (file)
@@ -27,36 +27,43 @@ static ssize_t clock_name_show(struct device *dev,
        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)
index 4b26f86..babd43b 100644 (file)
  */
 
 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;
@@ -46,10 +45,10 @@ rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr,
 
        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;
@@ -62,10 +61,10 @@ rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr,
 
        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;
@@ -79,16 +78,16 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
 
        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);
@@ -101,6 +100,7 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
 
        return n;
 }
+static DEVICE_ATTR_RW(max_user_freq);
 
 /**
  * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
@@ -109,8 +109,7 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
  * 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 &&
@@ -121,17 +120,18 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
 #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,
@@ -261,5 +261,5 @@ void rtc_sysfs_del_device(struct rtc_device *rtc)
 
 void __init rtc_sysfs_init(struct class *rtc_class)
 {
-       rtc_class->dev_attrs = rtc_attrs;
+       rtc_class->dev_groups = rtc_groups;
 }
index 9d86947..e1d9a4c 100644 (file)
@@ -107,6 +107,7 @@ static ssize_t osdname_show(struct device *dev, struct device_attribute *attr,
                                                   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)
@@ -117,17 +118,19 @@ static ssize_t systemid_show(struct device *dev, struct device_attribute *attr,
        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,
 };
 
 /*
index f4a197b..6d50e30 100644 (file)
@@ -262,7 +262,7 @@ static int resize_async_buffer(struct comedi_device *dev,
 
 /* 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);
@@ -283,7 +283,7 @@ static ssize_t show_max_read_buffer_kb(struct device *csdev,
        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)
 {
@@ -314,8 +314,9 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev,
 
        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);
@@ -336,7 +337,7 @@ static ssize_t show_read_buffer_kb(struct device *csdev,
        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)
 {
@@ -367,8 +368,9 @@ static ssize_t store_read_buffer_kb(struct device *csdev,
 
        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)
 {
@@ -390,7 +392,7 @@ static ssize_t show_max_write_buffer_kb(struct device *csdev,
        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)
 {
@@ -421,8 +423,9 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev,
 
        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);
@@ -443,7 +446,7 @@ static ssize_t show_write_buffer_kb(struct device *csdev,
        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)
 {
@@ -474,18 +477,16 @@ static ssize_t store_write_buffer_kb(struct device *csdev,
 
        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)
@@ -2564,7 +2565,7 @@ static int __init comedi_init(void)
                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();
index 8abe78c..ba47563 100644 (file)
@@ -223,38 +223,42 @@ static struct kobj_type portio_attr_type = {
        .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,
 };
 
 /*
index 0ce51f2..6335490 100644 (file)
@@ -121,7 +121,7 @@ static int usb_serial_device_remove(struct device *dev)
        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);
@@ -134,17 +134,19 @@ static ssize_t store_new_id(struct device_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)
 {
@@ -163,7 +165,7 @@ struct bus_type usb_serial_bus_type = {
        .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)
index 3fccb6d..94a403a 100644 (file)
@@ -103,16 +103,16 @@ static void backlight_generate_event(struct backlight_device *bd,
        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);
@@ -136,8 +136,9 @@ static ssize_t backlight_store_power(struct 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);
@@ -145,7 +146,7 @@ static ssize_t backlight_show_brightness(struct 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;
@@ -175,24 +176,27 @@ static ssize_t backlight_store_brightness(struct device *dev,
 
        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;
@@ -205,6 +209,7 @@ static ssize_t backlight_show_actual_brightness(struct device *dev,
 
        return rc;
 }
+static DEVICE_ATTR_RO(actual_brightness);
 
 static struct class *backlight_class;
 
@@ -247,16 +252,15 @@ static void bl_device_release(struct device *dev)
        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
@@ -493,7 +497,7 @@ static int __init backlight_class_init(void)
                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;
 }
index 41964a7..93cf15e 100644 (file)
@@ -89,7 +89,7 @@ static inline void lcd_unregister_fb(struct lcd_device *ld)
 }
 #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;
@@ -105,7 +105,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
        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;
@@ -128,8 +128,9 @@ static ssize_t lcd_store_power(struct device *dev,
 
        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;
@@ -143,7 +144,7 @@ static ssize_t lcd_show_contrast(struct device *dev,
        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;
@@ -166,14 +167,16 @@ static ssize_t lcd_store_contrast(struct device *dev,
 
        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;
 
@@ -183,12 +186,13 @@ static void lcd_device_release(struct device *dev)
        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.
@@ -344,7 +348,7 @@ static int __init lcd_class_init(void)
                return PTR_ERR(lcd_class);
        }
 
-       lcd_class->dev_attrs = lcd_device_attributes;
+       lcd_class->dev_groups = lcd_device_groups;
        return 0;
 }
 
index cb8a8e5..7dfa0e1 100644 (file)
@@ -72,10 +72,9 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
        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",
@@ -85,10 +84,9 @@ static ssize_t w1_f29_read_state(
        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",
@@ -99,10 +97,9 @@ static ssize_t w1_f29_read_output(
                                         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",
@@ -113,10 +110,9 @@ static ssize_t w1_f29_read_activity(
                                         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",
@@ -127,10 +123,10 @@ static ssize_t w1_f29_read_cond_search_mask(
                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;
@@ -138,10 +134,9 @@ static ssize_t w1_f29_read_cond_search_polarity(
                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;
@@ -149,13 +144,9 @@ static ssize_t w1_f29_read_status_control(
                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];
@@ -224,10 +215,9 @@ error:
 /**
  * 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;
@@ -255,13 +245,9 @@ error:
        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];
@@ -330,91 +316,35 @@ out:
        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 = {
index 8593777..ee28fc1 100644 (file)
@@ -30,10 +30,9 @@ MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413));
 #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,
@@ -66,10 +65,11 @@ static ssize_t w1_f3a_read_state(
                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];
@@ -110,53 +110,25 @@ error:
        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 = {
index 7f86aec..7e41b7d 100644 (file)
 #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;
@@ -128,19 +122,16 @@ static ssize_t w1_counter_read(struct device *device,
        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 = {
index cef8605..9c4ff9d 100644 (file)
@@ -96,9 +96,9 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf)
        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;
@@ -202,9 +202,9 @@ retry:
        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;
@@ -264,29 +264,24 @@ out_up:
        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 = {
index 10cc1b6..72319a9 100644 (file)
@@ -93,9 +93,9 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
 }
 #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
@@ -207,9 +207,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
        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;
@@ -257,19 +257,24 @@ out_up:
        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;
 
@@ -279,15 +284,7 @@ static int w1_f23_add_slave(struct w1_slave *sl)
        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)
@@ -296,12 +293,12 @@ 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 = {
index 93719d2..65f90dc 100644 (file)
@@ -97,21 +97,28 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr)
        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);
@@ -139,16 +146,10 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
        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:
@@ -165,12 +166,12 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl)
 
        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 = {
index 0cd7a27..50e85f7 100644 (file)
@@ -89,22 +89,28 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd)
 }
 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);
@@ -132,16 +138,10 @@ static int w1_ds2780_add_slave(struct w1_slave *sl)
        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:
@@ -157,12 +157,12 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl)
 
        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 = {
index 1aba8e4..1eb98fb 100644 (file)
@@ -87,22 +87,28 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd)
 }
 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);
@@ -130,16 +136,10 @@ static int w1_ds2781_add_slave(struct w1_slave *sl)
        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:
@@ -155,12 +155,12 @@ static void w1_ds2781_remove_slave(struct w1_slave *sl)
 
        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 = {
index cd30a6d..365d6df 100644 (file)
@@ -118,9 +118,9 @@ static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
        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;
@@ -226,9 +226,9 @@ static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *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);
@@ -280,9 +280,11 @@ out_up:
        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);
@@ -299,9 +301,9 @@ static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *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);
@@ -339,8 +341,10 @@ static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *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;
@@ -348,9 +352,8 @@ static ssize_t w1_f1C_show_crccheck(struct device *dev,
        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;
 
@@ -371,35 +374,31 @@ static ssize_t w1_f1C_store_crccheck(struct device *dev,
        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) {
@@ -409,46 +408,19 @@ static int w1_f1C_add_slave(struct w1_slave *sl)
                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 = {
index 8978360..8b5ff33 100644 (file)
@@ -59,25 +59,19 @@ static int w1_strong_pullup = 1;
 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 = {
@@ -178,7 +172,7 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid)
 }
 
 
-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);
index 0459df8..22013ca 100644 (file)
@@ -96,14 +96,15 @@ static void w1_slave_release(struct device *dev)
        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);
@@ -112,17 +113,20 @@ static ssize_t w1_slave_read_id(struct device *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);
 
@@ -139,9 +143,9 @@ out_up:
        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);
 
@@ -151,29 +155,24 @@ static ssize_t w1_default_read(struct file *filp, struct kobject *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 = {
@@ -587,6 +586,66 @@ end:
        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;
@@ -595,6 +654,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
        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,
@@ -615,44 +675,13 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
                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)
@@ -723,16 +752,11 @@ void w1_slave_detach(struct w1_slave *sl)
 
        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);
@@ -1017,6 +1041,10 @@ static int __init w1_init(void)
                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
index 625dd08..4ad0e81 100644 (file)
@@ -52,6 +52,7 @@ struct w1_family_ops
 {
        int  (* add_slave)(struct w1_slave *);
        void (* remove_slave)(struct w1_slave *);
+       const struct attribute_group **groups;
 };
 
 struct w1_family
index aef34b1..adbfd66 100644 (file)
@@ -568,6 +568,7 @@ static ssize_t cuse_class_waiting_show(struct device *dev,
 
        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,
@@ -578,12 +579,14 @@ static ssize_t cuse_class_abort_store(struct device *dev,
        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,
@@ -609,7 +612,7 @@ static int __init cuse_init(void)
        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) {
index 15c68f9..c590cab 100644 (file)
@@ -22,8 +22,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "sysfs.h"
 
@@ -391,7 +390,7 @@ out_unlock:
        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;
@@ -435,7 +434,7 @@ static int open(struct inode * inode, struct file * file)
        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;
 
@@ -481,7 +480,6 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd)
  *     @kobj:  object.
  *     @attr:  attribute descriptor.
  */
-
 int sysfs_create_bin_file(struct kobject *kobj,
                          const struct bin_attribute *attr)
 {
@@ -489,19 +487,16 @@ int sysfs_create_bin_file(struct kobject *kobj,
 
        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);
index e068e74..99ec5b4 100644 (file)
@@ -46,7 +46,7 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name)
        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)
@@ -258,7 +258,7 @@ static void sysfs_free_ino(unsigned int ino)
        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;
 
@@ -451,7 +451,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *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;
        }
@@ -619,7 +619,7 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
 
        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;
        }
@@ -674,7 +674,7 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
        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;
@@ -735,9 +735,9 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
 
 /**
  *     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;
@@ -764,8 +764,8 @@ int sysfs_create_dir(struct kobject * kobj)
        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;
@@ -857,7 +857,7 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
  *     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;
 
@@ -896,7 +896,9 @@ int sysfs_rename(struct sysfs_dirent *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);
@@ -988,20 +990,21 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
        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;
index d2bb7ed..15ef5eb 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/limits.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "sysfs.h"
 
@@ -45,8 +45,8 @@ struct sysfs_open_dirent {
 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;
@@ -59,16 +59,16 @@ struct sysfs_buffer {
  *     @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;
 
@@ -106,7 +106,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
 }
 
 /**
- *     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.
@@ -127,12 +127,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
 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;
        }
@@ -154,9 +154,8 @@ 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;
 
@@ -167,7 +166,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
 
        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 */
@@ -183,16 +182,15 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
  *     @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 */
@@ -219,15 +217,14 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
  *     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);
@@ -339,13 +336,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
        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) {
@@ -420,7 +418,7 @@ static int sysfs_release(struct inode *inode, struct file *filp)
  */
 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;
 
@@ -518,8 +516,9 @@ static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
        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;
@@ -566,17 +565,17 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
 
 /**
  *     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)
 {
@@ -590,6 +589,7 @@ 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.
@@ -654,7 +654,6 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
-
 /**
  *     sysfs_remove_file - remove an object attribute.
  *     @kobj:  object we're acting for.
@@ -662,8 +661,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
  *
  *     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;
 
@@ -672,13 +670,15 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 
        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.
@@ -793,9 +793,3 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
        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);
index 09a1a25..5f92cd2 100644 (file)
@@ -3,8 +3,10 @@
  *
  * 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.
  *
  */
 
@@ -19,8 +21,8 @@
 static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
                         const struct attribute_group *grp)
 {
-       struct attribute *constattr;
-       struct bin_attribute *constbin_attr;
+       struct attribute *const *attr;
+       struct bin_attribute *const *bin_attr;
 
        if (grp->attrs)
                for (attr = grp->attrs; *attr; attr++)
@@ -33,8 +35,8 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
 static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
                        const struct attribute_group *grp, int update)
 {
-       struct attribute *constattr;
-       struct bin_attribute *constbin_attr;
+       struct attribute *const *attr;
+       struct bin_attribute *const *bin_attr;
        int error = 0, i;
 
        if (grp->attrs) {
@@ -129,6 +131,41 @@ int sysfs_create_group(struct kobject *kobj,
 {
        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
@@ -152,11 +189,18 @@ int sysfs_update_group(struct kobject *kobj,
 {
        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;
@@ -164,8 +208,9 @@ void sysfs_remove_group(struct kobject * kobj,
        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
@@ -177,6 +222,27 @@ void sysfs_remove_group(struct kobject * kobj,
 
        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.
@@ -273,7 +339,3 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
        }
 }
 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);
index 3e2837a..963f910 100644 (file)
@@ -10,7 +10,7 @@
  * Please see Documentation/filesystems/sysfs.txt for more information.
  */
 
-#undef DEBUG 
+#undef DEBUG
 
 #include <linux/pagemap.h>
 #include <linux/namei.h>
@@ -36,7 +36,7 @@ static struct backing_dev_info sysfs_backing_dev_info = {
        .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,
@@ -67,7 +67,7 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
        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;
@@ -128,7 +128,8 @@ out:
        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;
@@ -186,13 +187,13 @@ out:
        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;
@@ -220,7 +221,8 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
                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;
@@ -285,7 +287,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *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;
 
@@ -312,7 +314,8 @@ void sysfs_evict_inode(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;
index afd8327..fd7ce7a 100644 (file)
@@ -64,7 +64,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
        /* 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;
index 8c940df..2dd4507 100644 (file)
@@ -125,6 +125,7 @@ int sysfs_create_link(struct kobject *kobj, struct kobject *target,
 {
        return sysfs_do_create_link(kobj, target, name, 1);
 }
+EXPORT_SYMBOL_GPL(sysfs_create_link);
 
 /**
  *     sysfs_create_link_nowarn - create symlink between two objects.
@@ -166,8 +167,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
  *     @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;
 
@@ -178,6 +178,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
 
        sysfs_hash_and_remove(parent_sd, NULL, name);
 }
+EXPORT_SYMBOL_GPL(sysfs_remove_link);
 
 /**
  *     sysfs_rename_link - rename symlink in object's directory.
@@ -223,6 +224,7 @@ out:
        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)
@@ -276,7 +278,7 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
        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;
@@ -295,7 +297,7 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        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);
        }
@@ -303,7 +305,8 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        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))
@@ -319,8 +322,3 @@ const struct inode_operations sysfs_symlink_inode_operations = {
        .getattr        = sysfs_getattr,
        .permission     = sysfs_permission,
 };
-
-
-EXPORT_SYMBOL_GPL(sysfs_create_link);
-EXPORT_SYMBOL_GPL(sysfs_remove_link);
-EXPORT_SYMBOL_GPL(sysfs_rename_link);
index d1e4043..b6deca3 100644 (file)
@@ -78,7 +78,7 @@ struct sysfs_dirent {
        };
 
        unsigned short          s_flags;
-       umode_t                 s_mode;
+       umode_t                 s_mode;
        unsigned int            s_ino;
        struct sysfs_inode_attrs *s_iattr;
 };
@@ -123,9 +123,9 @@ do {                                                                \
                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
 
 /*
@@ -186,8 +186,8 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
                        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)
 {
@@ -214,10 +214,12 @@ void sysfs_evict_inode(struct inode *inode);
 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);
 
 /*
index d68b4ea..263489d 100644 (file)
@@ -192,6 +192,13 @@ static inline struct dentry *debugfs_create_x32(const char *name, umode_t mode,
        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)
index 7d960d5..389becc 100644 (file)
@@ -66,6 +66,9 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * @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.
@@ -103,9 +106,12 @@ struct bus_type {
        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);
@@ -271,6 +277,8 @@ struct driver_attribute {
        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);
@@ -528,6 +536,8 @@ ssize_t device_store_bool(struct device *dev, struct device_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) }
index 939b112..de6dcbc 100644 (file)
@@ -26,6 +26,7 @@
 #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 */
@@ -65,6 +66,9 @@ struct kobject {
        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;
index 85c31a8..9a6bbf7 100644 (file)
 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 *);
@@ -125,7 +118,6 @@ extern struct memory_block *find_memory_block_hinted(struct mem_section *,
                                                        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
index 7db3eb9..1d2cd21 100644 (file)
@@ -80,7 +80,7 @@ struct pps_device {
  * Global variables
  */
 
-extern struct device_attribute pps_attrs[];
+extern const struct attribute_group *pps_groups[];
 
 /*
  * Internal functions.
index 9e8a9b5..11baec7 100644 (file)
@@ -51,9 +51,9 @@ do {                                                  \
        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 {
@@ -69,7 +69,7 @@ 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,                                               \
@@ -80,6 +80,11 @@ struct attribute_group {
        .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)
 
@@ -108,8 +113,6 @@ static const struct attribute_group _name##_group = {               \
 };                                                             \
 __ATTRIBUTE_GROUPS(_name)
 
-#define attr_name(_attr) (_attr).attr.name
-
 struct file;
 struct vm_area_struct;
 
@@ -119,7 +122,7 @@ struct bin_attribute {
        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);
@@ -153,7 +156,7 @@ struct bin_attribute {
 
 #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
 
@@ -168,8 +171,8 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size)
 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 *);
 };
 
@@ -215,10 +218,14 @@ void sysfs_delete_link(struct kobject *dir, struct kobject *targ,
 
 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,
@@ -343,6 +350,12 @@ static inline int sysfs_create_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)
 {
@@ -354,6 +367,11 @@ static inline void sysfs_remove_group(struct kobject *kobj,
 {
 }
 
+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)
 {
index e93f7b9..5f8ee91 100644 (file)
@@ -3095,25 +3095,26 @@ static struct workqueue_struct *dev_to_wq(struct device *dev)
        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;
@@ -3124,12 +3125,14 @@ static ssize_t wq_max_active_store(struct device *dev,
        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)
@@ -3279,7 +3282,7 @@ static struct device_attribute wq_sysfs_unbound_attrs[] = {
 
 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)
index 1501aa5..444e1c1 100644 (file)
@@ -981,6 +981,25 @@ config DEBUG_KOBJECT
          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
 
index 99fec3a..c37aeac 100644 (file)
@@ -309,7 +309,7 @@ static int ddebug_parse_query(char *words[], int nwords,
                        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) {
index 4a1f33d..1d46c15 100644 (file)
@@ -545,8 +545,8 @@ static void kobject_cleanup(struct kobject *kobj)
        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() "
@@ -580,9 +580,25 @@ static void kobject_cleanup(struct kobject *kobj)
        }
 }
 
+#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
 }
 
 /**
index e04454c..37d9edc 100644 (file)
@@ -180,7 +180,8 @@ static ssize_t name##_show(struct device *dev,                              \
        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))
 
@@ -231,14 +232,16 @@ static ssize_t stable_pages_required_show(struct device *dev,
        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)
 {
@@ -246,7 +249,7 @@ 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;
 }
index 981fed3..707c313 100644 (file)
@@ -60,12 +60,19 @@ static ssize_t format_##field(const struct net_device *net, char *buf)      \
 {                                                                      \
        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,
@@ -96,16 +103,16 @@ 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);
@@ -117,15 +124,17 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr,
        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)
 {
@@ -134,13 +143,13 @@ 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);
@@ -149,8 +158,9 @@ static ssize_t show_carrier(struct device *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);
@@ -167,8 +177,9 @@ static ssize_t show_speed(struct device *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);
@@ -198,8 +209,9 @@ static ssize_t show_duplex(struct device *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);
@@ -209,6 +221,7 @@ static ssize_t show_dormant(struct device *dev,
 
        return -EINVAL;
 }
+static DEVICE_ATTR_RO(dormant);
 
 static const char *const operstates[] = {
        "unknown",
@@ -220,7 +233,7 @@ static const char *const operstates[] = {
        "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);
@@ -237,35 +250,33 @@ static ssize_t show_operstate(struct device *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)
 {
@@ -273,7 +284,7 @@ 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)
 {
@@ -282,8 +293,9 @@ static ssize_t store_tx_queue_len(struct device *dev,
 
        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);
@@ -306,7 +318,7 @@ static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
        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);
@@ -319,8 +331,7 @@ static ssize_t show_ifalias(struct device *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)
 {
@@ -328,35 +339,37 @@ 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,
@@ -382,13 +395,13 @@ 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);
@@ -457,6 +470,9 @@ static struct attribute_group wireless_group = {
        .attrs = wireless_attrs,
 };
 #endif
+
+#else /* CONFIG_SYSFS */
+#define net_class_groups       NULL
 #endif /* CONFIG_SYSFS */
 
 #ifdef CONFIG_RPS
@@ -1229,9 +1245,7 @@ static const void *net_namespace(struct device *d)
 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,
index 13571ea..ef56ab5 100644 (file)
@@ -36,7 +36,8 @@ static ssize_t name ## _show(struct device *dev,                      \
        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)
@@ -66,15 +67,17 @@ static ssize_t channels_supported_show(struct device *dev,
        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)
 {
@@ -85,7 +88,7 @@ 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);
index 1cec5e4..1bacc10 100644 (file)
@@ -576,14 +576,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
 }
 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)
 {
@@ -611,54 +611,52 @@ 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;
@@ -680,6 +678,7 @@ static ssize_t rfkill_soft_store(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR_RW(soft);
 
 static u8 user_state_from_blocked(unsigned long state)
 {
@@ -691,18 +690,16 @@ 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;
@@ -725,32 +722,27 @@ static ssize_t rfkill_state_store(struct device *dev,
 
        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)
 {
@@ -830,7 +822,7 @@ static int rfkill_resume(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,
index a23253e..9ee6bc1 100644 (file)
@@ -30,7 +30,8 @@ static ssize_t name ## _show(struct device *dev,                      \
                              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);
@@ -42,7 +43,7 @@ static ssize_t name_show(struct device *dev,
        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,
@@ -60,15 +61,17 @@ static ssize_t addresses_show(struct device *dev,
 
        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)
 {
@@ -146,7 +149,7 @@ struct class ieee80211_class = {
        .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,